@pixodesk/svg-animator-core 1.0.39 → 1.0.41

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
@@ -50,38 +50,25 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
50
50
  // src/index.ts
51
51
  var index_exports = {};
52
52
  __export(index_exports, {
53
- BASELINE_PLAYER_VERSION: () => BASELINE_PLAYER_VERSION,
54
- COLOR_ATTR_NAMES: () => COLOR_ATTR_NAMES,
55
- CSS_ONLY_STYLE_PROPS: () => CSS_ONLY_STYLE_PROPS,
56
- DEFAULT_DURATION_MS: () => DEFAULT_DURATION_MS,
57
- DISALLOWED_SVG_TAGS_LOWER: () => DISALLOWED_SVG_TAGS_LOWER,
58
- INTERNAL_ATTRS: () => INTERNAL_ATTRS,
59
- LOOP_JUMP_SHIFT_MS: () => LOOP_JUMP_SHIFT_MS,
60
- MISSING_GLYPH_CLASS_NAME: () => MISSING_GLYPH_CLASS_NAME,
61
- PCT_BASED_ATTR_NAMES: () => PCT_BASED_ATTR_NAMES,
62
- PLAYER_WIRE_STEPS: () => PLAYER_WIRE_STEPS,
63
- PLAYER_WIRE_VERSION: () => PLAYER_WIRE_VERSION,
64
- PX_ANIM_ATTR_NAME: () => PX_ANIM_ATTR_NAME,
65
- PX_ANIM_SRC_ATTR_NAME: () => PX_ANIM_SRC_ATTR_NAME,
66
- PX_PLAYER_SCHEMA_VERSION: () => PX_PLAYER_SCHEMA_VERSION,
67
53
  PX_RATE_REJECTED: () => PX_RATE_REJECTED,
68
54
  PX_TRANSFORM_PART_KEYS: () => PX_TRANSFORM_PART_KEYS,
69
55
  PX_TRIGGER_DEFAULTS: () => PX_TRIGGER_DEFAULTS,
70
- PX_UNKNOWN_KEY_ERROR: () => PX_UNKNOWN_KEY_ERROR,
56
+ PX_WIRE_BASELINE_VERSION: () => PX_WIRE_BASELINE_VERSION,
57
+ PX_WIRE_SCHEMA_VERSION: () => PX_WIRE_SCHEMA_VERSION,
58
+ PX_WIRE_STEPS: () => PX_WIRE_STEPS,
59
+ PX_WIRE_VERSION: () => PX_WIRE_VERSION,
60
+ PX_WIRE_VERSION_KEY: () => PX_WIRE_VERSION_KEY,
71
61
  PxAlongPathMode: () => PxAlongPathMode,
72
62
  PxAnimatedSvgDocumentSchema: () => PxAnimatedSvgDocumentSchema,
73
- PxAnimationDefinitionSchema: () => PxAnimationDefinitionSchema,
74
63
  PxAnimatorConfigSchema: () => PxAnimatorConfigSchema,
75
64
  PxAttrValueSchema: () => PxAttrValueSchema,
76
65
  PxBezierPathSchema: () => PxBezierPathSchema,
77
- PxBindingSchema: () => PxBindingSchema,
78
66
  PxClipPathEffectSchema: () => PxClipPathEffectSchema,
79
67
  PxCloneEffectSchema: () => PxCloneEffectSchema,
80
68
  PxCloneWithout: () => PxCloneWithout,
81
69
  PxControlMode: () => PxControlMode,
82
- PxDefsSchema: () => PxDefsSchema,
70
+ PxDefinitionsSchema: () => PxDefinitionsSchema,
83
71
  PxDiagnosticKind: () => PxDiagnosticKind,
84
- PxEasingOrRefSchema: () => PxEasingOrRefSchema,
85
72
  PxEffectsSchema: () => PxEffectsSchema,
86
73
  PxElementAnimationSchema: () => PxElementAnimationSchema,
87
74
  PxFillGradientEffectSchema: () => PxFillGradientEffectSchema,
@@ -98,7 +85,7 @@ __export(index_exports, {
98
85
  PxLoopSchema: () => PxLoopSchema,
99
86
  PxMaskType: () => PxMaskType,
100
87
  PxMaskedByEffectSchema: () => PxMaskedByEffectSchema,
101
- PxNodeBase: () => PxNodeBase,
88
+ PxNodeBaseSchema: () => PxNodeBaseSchema,
102
89
  PxNodeSchema: () => PxNodeSchema,
103
90
  PxOutAction: () => PxOutAction,
104
91
  PxPathOverflow: () => PxPathOverflow,
@@ -115,693 +102,129 @@ __export(index_exports, {
115
102
  PxScrollSchema: () => PxScrollSchema,
116
103
  PxScrollSource: () => PxScrollSource,
117
104
  PxStartOn: () => PxStartOn,
118
- PxStrokeGradientEffectSchema: () => PxStrokeGradientEffectSchema,
119
105
  PxStrokeTrimEffectSchema: () => PxStrokeTrimEffectSchema,
120
106
  PxStrokeTrimSubPaths: () => PxStrokeTrimSubPaths,
121
- PxSvgNodeExtra: () => PxSvgNodeExtra,
107
+ PxSvgNodeRootSchema: () => PxSvgNodeRootSchema,
122
108
  PxTextEffectSchema: () => PxTextEffectSchema,
123
109
  PxTextPathEffectSchema: () => PxTextPathEffectSchema,
124
110
  PxTextPathMethod: () => PxTextPathMethod,
125
111
  PxTextPathSpacing: () => PxTextPathSpacing,
126
112
  PxTimelineEngine: () => PxTimelineEngine,
127
- PxTimelineEngineExtra: () => PxTimelineEngineExtra,
128
- PxTimelinePinSchema: () => PxTimelinePinSchema,
113
+ PxTimelineEngineSetting: () => PxTimelineEngineSetting,
129
114
  PxTimelineSchema: () => PxTimelineSchema,
130
115
  PxTransformByEffectSchema: () => PxTransformByEffectSchema,
131
116
  PxTransformPartsSchema: () => PxTransformPartsSchema,
132
117
  PxTransformValueSchema: () => PxTransformValueSchema,
133
118
  PxTriggerSchema: () => PxTriggerSchema,
134
119
  PxUnits: () => PxUnits,
135
- STYLE_ATTR_NAMES: () => STYLE_ATTR_NAMES,
136
- TEXT_CONTENT_ATTR: () => TEXT_CONTENT_ATTR,
137
- TRANSFORM_FN_NAMES: () => TRANSFORM_FN_NAMES,
138
- WIRE_VERSION_KEY: () => WIRE_VERSION_KEY,
139
- WireStepKind: () => WireStepKind,
140
- WireVersionRelation: () => WireVersionRelation,
120
+ PxWireStepKind: () => PxWireStepKind,
121
+ PxWireVersionRelation: () => PxWireVersionRelation,
141
122
  applyAnimatorConfig: () => applyAnimatorConfig,
142
- applyPlayerEffects: () => applyPlayerEffects,
143
123
  applyWireSteps: () => applyWireSteps,
144
- applyWireStepsDown: () => applyWireStepsDown,
145
- bezierToSvgPath: () => bezierToSvgPath,
146
124
  calcAnimationValues: () => calcAnimationValues,
147
- camelCaseToKebabWordIfNeeded: () => camelCaseToKebabWordIfNeeded,
148
- clamp: () => clamp,
149
125
  clampSeekMs: () => clampSeekMs,
150
- collectSampleTimes: () => collectSampleTimes,
151
126
  compareWireVersion: () => compareWireVersion,
152
- composeTransformParts: () => composeTransformParts,
153
127
  controlModeTakesOverTrigger: () => controlModeTakesOverTrigger,
154
- convertPlayerDocument: () => convertPlayerDocument,
155
- createBasicFrameLoopAnimator: () => createBasicFrameLoopAnimator,
156
- createDiagnostics: () => createDiagnostics,
157
- createPathSampler: () => createPathSampler,
128
+ convertWireDocument: () => convertWireDocument,
129
+ createAdapterAnimator: () => createAdapterAnimator,
158
130
  createRunClock: () => createRunClock,
159
- cubicBezier: () => cubicBezier,
160
- deepClone: () => deepClone,
161
131
  describeSchema: () => describeSchema,
162
132
  diagnoseDocument: () => diagnoseDocument,
163
- diffFieldUniverse: () => diffFieldUniverse,
164
- diffInEffect: () => diffInEffect,
165
- downgradePlayerDocument: () => downgradePlayerDocument,
166
- evaluateMotionPathSegment: () => evaluateMotionPathSegment,
167
- extendedPathForBrowser: () => extendedPathForBrowser,
133
+ downgradeWireDocument: () => downgradeWireDocument,
168
134
  flattenAnimatorTimeline: () => flattenAnimatorTimeline,
169
135
  foldTimelineOverride: () => foldTimelineOverride,
170
136
  formatWireVersion: () => formatWireVersion,
171
137
  generateNewIds: () => generateNewIds,
172
- generateUniqueId: () => generateUniqueId,
173
138
  getAnimatorConfig: () => getAnimatorConfig,
174
139
  getBindings: () => getBindings,
175
140
  getChildren: () => getChildren,
176
- getDefs: () => getDefs,
177
- getNormalizedBindings: () => getNormalizedBindings,
178
- getNormalizedProps: () => getNormalizedProps,
179
- interpolateBeziers: () => interpolateBeziers,
180
- interpolateValue: () => interpolateValue,
141
+ getDefinitions: () => getDefinitions,
181
142
  isNativeForced: () => isNativeForced,
182
- isPxElementFileFormat: () => isPxElementFileFormat,
183
- isPxElementFileFormatDeep: () => isPxElementFileFormatDeep,
184
- isScrollTimeline: () => isScrollTimeline,
143
+ isPxDocument: () => isPxDocument,
185
144
  isValidPlaybackRate: () => isValidPlaybackRate,
186
- jsonElementFactory: () => jsonElementFactory,
187
- kebabToCamelCaseWord: () => kebabToCamelCaseWord,
188
- kfEasing: () => kfEasing,
189
- kfTangentIn: () => kfTangentIn,
190
- kfTangentOut: () => kfTangentOut,
191
- kfTime: () => kfTime,
192
- kfValue: () => kfValue,
193
- layoutGlyphTextChars: () => layoutGlyphTextChars,
145
+ isValidPxDocument: () => isValidPxDocument,
194
146
  materializeAllInTree: () => materializeAllInTree,
195
- materializeAnimatedUseInstances: () => materializeAnimatedUseInstances,
196
- materializeGlyphText: () => materializeGlyphText,
197
- materializeGlyphTextAlongPath: () => materializeGlyphTextAlongPath,
198
- materializeGlyphTextHorizontal: () => materializeGlyphTextHorizontal,
199
- materializeInternalLoopsInPropAnim: () => materializeInternalLoopsInPropAnim,
200
- materializeInternalLoopsInTree: () => materializeInternalLoopsInTree,
201
- materializeMotionPathInPropAnim: () => materializeMotionPathInPropAnim,
202
- materializeMotionPathsInTree: () => materializeMotionPathsInTree,
147
+ materializeNodeEffects: () => materializeNodeEffects,
203
148
  mayUseNativeScrollTimeline: () => mayUseNativeScrollTimeline,
204
149
  mergeAnimatorConfig: () => mergeAnimatorConfig,
205
- mergeStaticTransformIntoAnimDef: () => mergeStaticTransformIntoAnimDef,
206
150
  nestAnimatorTimeline: () => nestAnimatorTimeline,
207
- parseTransformParts: () => parseTransformParts,
151
+ normalizeBindings: () => normalizeBindings,
208
152
  parseWireVersion: () => parseWireVersion,
209
- planSchemaRelease: () => planSchemaRelease,
210
153
  progressSpanMs: () => progressSpanMs,
211
154
  progressToTimeMs: () => progressToTimeMs,
212
- propAnimIsMotionPath: () => propAnimIsMotionPath,
213
155
  px: () => px,
214
156
  readWireVersion: () => readWireVersion,
215
- releaseLogProblems: () => releaseLogProblems,
216
- reportDocumentDiagnostics: () => reportDocumentDiagnostics,
217
157
  resolveControlMode: () => resolveControlMode,
218
- resolveStyle: () => resolveStyle,
219
158
  resolveTimelineEngine: () => resolveTimelineEngine,
220
159
  resolveTrigger: () => resolveTrigger,
221
- reverseEasing: () => reverseEasing,
222
- sanitizeAttributeValue: () => sanitizeAttributeValue,
223
- schemaFieldUniverse: () => schemaFieldUniverse,
224
160
  schemaKeys: () => schemaKeys,
225
- scrollOffsetProgress: () => scrollOffsetProgress,
226
- scrollPhaseInterval: () => scrollPhaseInterval,
227
- scrollResolveAxis: () => scrollResolveAxis,
228
- scrollTotalDurationMs: () => scrollTotalDurationMs,
229
- scrollViewProgress: () => scrollViewProgress,
230
161
  seekCeilingMs: () => seekCeilingMs,
231
- shiftAnimatable: () => shiftAnimatable,
232
- splitEasing: () => splitEasing,
233
- subdivideCubicBezier: () => subdivideCubicBezier,
234
162
  timeToProgress: () => timeToProgress,
235
- toRGBA: () => toRGBA,
163
+ toDomProps: () => toDomProps,
236
164
  validateDocument: () => validateDocument,
237
165
  validateNodeEffects: () => validateNodeEffects,
238
- versionAdvice: () => versionAdvice,
239
- visualModelAt: () => visualModelAt
166
+ wireVersionAdvice: () => wireVersionAdvice
240
167
  });
241
168
  module.exports = __toCommonJS(index_exports);
242
169
 
243
- // src/util/PxAnimatorUtil.ts
244
- function bezierToSvgPath(path, forceCurves = false) {
245
- var _a2, _b, _c, _d;
246
- const v = path.v;
247
- const i = path.i;
248
- const o = path.o;
249
- const c = path.c;
250
- if (!v.length) return "";
251
- const d = [];
252
- const len = v.length;
253
- d.push("M" + v[0][0] + "," + v[0][1]);
254
- for (let idx = 1; idx < len; idx++) {
255
- const prevV = v[idx - 1];
256
- const prevO = (_a2 = o == null ? void 0 : o[idx - 1]) != null ? _a2 : prevV;
257
- const currI = (_b = i == null ? void 0 : i[idx]) != null ? _b : v[idx];
258
- const currV = v[idx];
259
- const isLine = !forceCurves && (prevO[0] === prevV[0] && prevO[1] === prevV[1]) && (currI[0] === currV[0] && currI[1] === currV[1]);
260
- if (isLine) {
261
- d.push("L" + currV[0] + "," + currV[1]);
262
- } else {
263
- d.push("C" + prevO[0] + "," + prevO[1] + "," + currI[0] + "," + currI[1] + "," + currV[0] + "," + currV[1]);
264
- }
265
- }
266
- if (c && len > 0) {
267
- const lastV = v[len - 1];
268
- const lastO = (_c = o == null ? void 0 : o[len - 1]) != null ? _c : lastV;
269
- const firstI = (_d = i == null ? void 0 : i[0]) != null ? _d : v[0];
270
- const firstV = v[0];
271
- const isLine = !forceCurves && (lastO[0] === lastV[0] && lastO[1] === lastV[1]) && (firstI[0] === firstV[0] && firstI[1] === firstV[1]);
272
- if (!isLine) {
273
- d.push("C" + lastO[0] + "," + lastO[1] + "," + firstI[0] + "," + firstI[1] + "," + firstV[0] + "," + firstV[1]);
274
- }
275
- d.push("z");
170
+ // src/schema/PxSchema.ts
171
+ var PX_UNKNOWN_KEY_ERROR = "unexpected extra key";
172
+ function pathStr(path) {
173
+ if (!path.length) return ".";
174
+ let result = "";
175
+ for (const seg of path) {
176
+ if (seg.startsWith("[")) result += seg;
177
+ else result += (result ? "." : "") + seg;
276
178
  }
277
- return d.join("");
278
- }
279
- function interpolateNum(a, b, t) {
280
- return a + (b - a) * t;
179
+ return result;
281
180
  }
282
- function interpolateVec(a, b, t) {
283
- const res = [];
284
- const count = Math.max(a.length, b.length);
285
- for (let i = 0; i < count; i++) {
286
- res[i] = interpolateNum(a[i] || 0, b[i] || 0, t);
181
+ var Base = class {
182
+ _canSanitize(raw) {
183
+ return this.isValid(raw);
287
184
  }
288
- return res;
289
- }
290
- function interpolateColor(a, b, t) {
291
- return [
292
- interpolateNum(a[0] || 0, b[0] || 0, t),
293
- interpolateNum(a[1] || 0, b[1] || 0, t),
294
- interpolateNum(a[2] || 0, b[2] || 0, t),
295
- interpolateNum(a[3] === void 0 ? 1 : a[3], b[3] === void 0 ? 1 : b[3], t)
296
- ];
297
- }
298
- function interpolateBeziers(paths1, paths2, progress) {
299
- const count = Math.max(paths1.length, paths2.length);
300
- const res = [];
301
- for (let i = 0; i < count; i++) {
302
- res.push(interpolateBezier(paths1[i], paths2[i], progress));
185
+ optional() {
186
+ return new Optional(this);
303
187
  }
304
- return res;
305
- }
306
- function interpolateBezier(path1, path2, progress) {
307
- var _a2, _b, _c, _d, _e, _f, _g, _h, _i;
308
- if (!path1 || !path2) return path1 || path2 || { v: [] };
309
- const t = Math.min(Math.max(progress, 0), 1);
310
- const len = Math.min(path1.v.length, path2.v.length);
311
- const v = [];
312
- const i = [];
313
- const o = [];
314
- for (let idx = 0; idx < len; idx++) {
315
- const v1 = path1.v[idx];
316
- const v2 = path2.v[idx];
317
- v.push(interpolateVec(v1, v2, t));
318
- const i1 = (_b = (_a2 = path1.i) == null ? void 0 : _a2[idx]) != null ? _b : v1;
319
- const i2 = (_d = (_c = path2.i) == null ? void 0 : _c[idx]) != null ? _d : v2;
320
- i.push(interpolateVec(i1, i2, t));
321
- const o1 = (_f = (_e = path1.o) == null ? void 0 : _e[idx]) != null ? _f : v1;
322
- const o2 = (_h = (_g = path2.o) == null ? void 0 : _g[idx]) != null ? _h : v2;
323
- o.push(interpolateVec(o1, o2, t));
188
+ };
189
+ var Optional = class extends Base {
190
+ constructor(inner) {
191
+ super();
192
+ this.inner = inner;
193
+ this._default = void 0;
324
194
  }
325
- return { v, i: i.length ? i : void 0, o: o.length ? o : void 0, c: (_i = path1.c) != null ? _i : path2.c };
326
- }
327
- function remap(value, inMin, inMax, outMin, outMax) {
328
- if (inMax === inMin) return outMin;
329
- const t = (value - inMin) / (inMax - inMin);
330
- return outMin + t * (outMax - outMin);
331
- }
332
- function solveCubicBezierX(p1x, p2x, x) {
333
- if (x <= 0) return 0;
334
- if (x >= 1) return 1;
335
- const cx = 3 * p1x;
336
- const bx = 3 * (p2x - p1x) - cx;
337
- const ax = 1 - cx - bx;
338
- function sampleX(t) {
339
- return ((ax * t + bx) * t + cx) * t;
195
+ sanitize(raw) {
196
+ if (raw === void 0 || raw === null) return void 0;
197
+ return this.inner._canSanitize(raw) ? this.inner.sanitize(raw) : void 0;
340
198
  }
341
- function sampleDX(t) {
342
- return (3 * ax * t + 2 * bx) * t + cx;
199
+ isValid(raw, ctx, path) {
200
+ if (raw === void 0 || raw === null) return true;
201
+ return this.inner.isValid(raw, ctx, path);
343
202
  }
344
- let t2 = x;
345
- let t0 = 0;
346
- let t1 = 1;
347
- for (let i = 0; i < 8; i++) {
348
- const x2 = sampleX(t2) - x;
349
- if (Math.abs(x2) < 1e-6) return t2;
350
- const d2 = sampleDX(t2);
351
- if (Math.abs(d2) < 1e-6) break;
352
- t2 -= x2 / d2;
203
+ _canSanitize(raw) {
204
+ return raw === void 0 || raw === null || this.inner._canSanitize(raw);
353
205
  }
354
- t2 = x;
355
- while (t0 < t1) {
356
- const x2 = sampleX(t2);
357
- if (Math.abs(x2 - x) < 1e-6) return t2;
358
- if (x > x2) t0 = t2;
359
- else t1 = t2;
360
- t2 = (t1 + t0) / 2;
206
+ };
207
+ var Str = class extends Base {
208
+ constructor(_default = "") {
209
+ super();
210
+ this._default = _default;
361
211
  }
362
- return t2;
363
- }
364
- function cubicBezier(easing) {
365
- const [p1x, p1y, p2x, p2y] = easing;
366
- const cy = 3 * p1y;
367
- const by = 3 * (p2y - p1y) - cy;
368
- const ay = 1 - cy - by;
369
- function sampleCurveY(t) {
370
- return ((ay * t + by) * t + cy) * t;
212
+ sanitize(raw) {
213
+ return typeof raw === "string" ? raw : this._default;
371
214
  }
372
- return function(x) {
373
- return sampleCurveY(solveCubicBezierX(p1x, p2x, x));
374
- };
375
- }
376
- function lerp2(a, b, t) {
377
- return [a[0] + (b[0] - a[0]) * t, a[1] + (b[1] - a[1]) * t];
378
- }
379
- function subdivideCubicBezier(p0, p1, p2, p3, t) {
380
- const q0 = lerp2(p0, p1, t);
381
- const q1 = lerp2(p1, p2, t);
382
- const q2 = lerp2(p2, p3, t);
383
- const r0 = lerp2(q0, q1, t);
384
- const r1 = lerp2(q1, q2, t);
385
- const s = lerp2(r0, r1, t);
386
- return {
387
- left: [p0, q0, r0, s],
388
- right: [s, r1, q2, p3]
389
- };
390
- }
391
- function splitEasing(easing, xFraction) {
392
- if (!easing) return { left: void 0, right: void 0 };
393
- if (xFraction <= 0) return { left: void 0, right: easing };
394
- if (xFraction >= 1) return { left: easing, right: void 0 };
395
- const [x1, y1, x2, y2] = easing;
396
- const t = solveCubicBezierX(x1, x2, xFraction);
397
- const p0 = [0, 0];
398
- const p1 = [x1, y1];
399
- const p2 = [x2, y2];
400
- const p3 = [1, 1];
401
- const { left, right } = subdivideCubicBezier(p0, p1, p2, p3, t);
402
- const sx = left[3][0];
403
- const sy = left[3][1];
404
- let leftEasing;
405
- if (sx > 1e-9 && Math.abs(sy) > 1e-9) {
406
- leftEasing = [
407
- left[1][0] / sx,
408
- left[1][1] / sy,
409
- left[2][0] / sx,
410
- left[2][1] / sy
411
- ];
215
+ isValid(raw, ctx, path) {
216
+ if (typeof raw === "string") return true;
217
+ ctx == null ? void 0 : ctx.errors.push(pathStr(path != null ? path : []) + ": expected string, got " + typeof raw);
218
+ return false;
412
219
  }
413
- let rightEasing;
414
- const rx = 1 - sx;
415
- const ry = 1 - sy;
416
- if (rx > 1e-9 && Math.abs(ry) > 1e-9) {
417
- rightEasing = [
418
- (right[1][0] - sx) / rx,
419
- (right[1][1] - sy) / ry,
420
- (right[2][0] - sx) / rx,
421
- (right[2][1] - sy) / ry
422
- ];
220
+ };
221
+ var Num = class extends Base {
222
+ constructor(_default = 0) {
223
+ super();
224
+ this._default = _default;
423
225
  }
424
- return { left: leftEasing, right: rightEasing };
425
- }
426
- function reverseEasing(easing) {
427
- if (!easing) return void 0;
428
- return [1 - easing[2], 1 - easing[3], 1 - easing[0], 1 - easing[1]];
429
- }
430
- function toRGBA(color) {
431
- const r = Math.round(color[0] * 255);
432
- const g = Math.round(color[1] * 255);
433
- const b = Math.round(color[2] * 255);
434
- return color.length === 4 ? "rgba(" + r + "," + g + "," + b + "," + color[3] + ")" : "rgb(" + r + "," + g + "," + b + ")";
435
- }
436
- function parseRgba(s) {
437
- var _a2;
438
- const inner = (_a2 = s.match(/rgba?\((.*)\)/)) == null ? void 0 : _a2[1];
439
- if (!inner) throw new Error("Invalid rgb/rgba format");
440
- const parts = inner.split(",").map((v) => +v.trim());
441
- return [parts[0] / 255, parts[1] / 255, parts[2] / 255, ...parts[3] !== void 0 ? [parts[3]] : []];
442
- }
443
- function parseHex(s) {
444
- const hex = s.slice(1);
445
- const isShort = hex.length <= 4;
446
- const r = isShort ? hex[0] + hex[0] : hex.slice(0, 2);
447
- const g = isShort ? hex[1] + hex[1] : hex.slice(2, 4);
448
- const b = isShort ? hex[2] + hex[2] : hex.slice(4, 6);
449
- const a = hex.length === 4 ? hex[3] + hex[3] : hex.length === 8 ? hex.slice(6, 8) : null;
450
- const result = [
451
- parseInt(r, 16) / 255,
452
- parseInt(g, 16) / 255,
453
- parseInt(b, 16) / 255
454
- ];
455
- if (a !== null) {
456
- result.push(parseInt(a, 16) / 255);
457
- }
458
- return result;
459
- }
460
- function parseColor(s) {
461
- if (!s) return void 0;
462
- if (Array.isArray(s)) return s;
463
- if (typeof s !== "string") return void 0;
464
- if (s.startsWith("#")) {
465
- return parseHex(s);
466
- } else if (s.startsWith("rgb")) {
467
- return parseRgba(s);
468
- } else {
469
- console.warn("Unsupported color format: " + s);
470
- }
471
- return void 0;
472
- }
473
- var COLOR_ATTR_NAMES = /* @__PURE__ */ new Set(["color", "fill", "flood-color", "lighting-color", "stop-color", "stroke"]);
474
- var TRANSFORM_FN_NAMES = /* @__PURE__ */ new Set(["translate", "rotate", "scale", "skew"]);
475
- var PCT_BASED_ATTR_NAMES = /* @__PURE__ */ new Set(["offset-distance", "offsetDistance"]);
476
- function composeTransformParts(parts, opts) {
477
- var _a2;
478
- if (!parts) return "";
479
- const withUnits = (_a2 = opts == null ? void 0 : opts.withUnits) != null ? _a2 : true;
480
- const segs = [];
481
- const t = parts.translate;
482
- const o = parts.origin;
483
- const r = parts.rotate;
484
- const k = parts.skew;
485
- const s = parts.scale;
486
- const tu = withUnits ? "px" : "";
487
- const ru = withUnits ? "deg" : "";
488
- if (t) segs.push("translate(" + t[0] + tu + "," + t[1] + tu + ")");
489
- if (o) segs.push("translate(" + o[0] + tu + "," + o[1] + tu + ")");
490
- if (r !== void 0 && r !== null) segs.push("rotate(" + r + ru + ")");
491
- if (k !== void 0 && k !== null) segs.push("skewX(" + k + ru + ")");
492
- if (s) segs.push("scale(" + s[0] + "," + s[1] + ")");
493
- if (o) segs.push("translate(" + -o[0] + tu + "," + -o[1] + tu + ")");
494
- return segs.join("");
495
- }
496
- function parseTransformParts(str2) {
497
- var _a2, _b;
498
- if (!str2 || typeof str2 !== "string") return void 0;
499
- const out = {};
500
- const re = /([a-zA-Z]+)\s*\(([^)]*)\)/g;
501
- const order = ["translate", "rotate", "skewX", "scale"];
502
- let lastIdx = -1;
503
- let m;
504
- while ((m = re.exec(str2)) !== null) {
505
- const fn = m[1];
506
- const idx = order.indexOf(fn);
507
- if (idx < 0 || idx <= lastIdx) return void 0;
508
- lastIdx = idx;
509
- const nums = m[2].split(/[\s,]+/).filter(Boolean).map(Number);
510
- if (nums.some((n) => Number.isNaN(n))) return void 0;
511
- if (fn === "translate") {
512
- if (nums.length < 1 || nums.length > 2) return void 0;
513
- out.translate = [nums[0], (_a2 = nums[1]) != null ? _a2 : 0];
514
- } else if (fn === "rotate") {
515
- if (nums.length !== 1) return void 0;
516
- out.rotate = nums[0];
517
- } else if (fn === "skewX") {
518
- if (nums.length !== 1) return void 0;
519
- out.skew = nums[0];
520
- } else {
521
- if (nums.length < 1 || nums.length > 2) return void 0;
522
- out.scale = [nums[0], (_b = nums[1]) != null ? _b : nums[0]];
523
- }
524
- }
525
- if (str2.replace(/([a-zA-Z]+)\s*\(([^)]*)\)/g, "").replace(/[\s,]/g, "").length) return void 0;
526
- return Object.keys(out).length ? out : void 0;
527
- }
528
- var STYLE_ATTR_NAMES = /* @__PURE__ */ new Set(["offset-distance", "offsetDistance"]);
529
- var DEFAULT_DURATION_MS = 1e3;
530
- function kebabToCamelCaseWord(kebab) {
531
- return kebab.includes("-") ? kebab.replace(/-([a-z])/g, (_, letter) => letter.toUpperCase()) : kebab;
532
- }
533
- function isCamelCaseWord(word) {
534
- return !word.includes("-") && /[a-z][A-Z]/.test(word);
535
- }
536
- var SVG_CAMEL_CASE_ATTRS = /* @__PURE__ */ new Set([
537
- // Transform/positioning
538
- "viewBox",
539
- "preserveAspectRatio",
540
- // Gradient
541
- "gradientUnits",
542
- "gradientTransform",
543
- "spreadMethod",
544
- // Pattern
545
- "patternUnits",
546
- "patternContentUnits",
547
- "patternTransform",
548
- // Clipping/masking
549
- "clipPathUnits",
550
- "maskUnits",
551
- "maskContentUnits",
552
- // Marker (SVG spec keeps these camelCase, like viewBox)
553
- "markerUnits",
554
- "markerWidth",
555
- "markerHeight",
556
- "refX",
557
- "refY",
558
- // Text
559
- "textLength",
560
- "lengthAdjust",
561
- "startOffset",
562
- // Filter
563
- "filterUnits",
564
- "primitiveUnits",
565
- "tableValues",
566
- // feFuncR/G/B/A transfer table (type="table")
567
- "stdDeviation",
568
- "baseFrequency",
569
- "numOctaves",
570
- "surfaceScale",
571
- "diffuseConstant",
572
- "specularConstant",
573
- "specularExponent",
574
- "kernelMatrix",
575
- "kernelUnitLength",
576
- "edgeMode",
577
- "preserveAlpha",
578
- "targetX",
579
- "targetY"
580
- // // Animation
581
- // 'attributeName',
582
- // 'attributeType',
583
- // 'calcMode',
584
- // 'keyTimes',
585
- // 'keySplines',
586
- // 'repeatCount',
587
- // 'repeatDur'
588
- ]);
589
- function camelCaseToKebabWordIfNeeded(camel) {
590
- return SVG_CAMEL_CASE_ATTRS.has(camel) ? camel : camel.replace(/([a-z0-9])([A-Z])/g, "$1-$2").toLowerCase();
591
- }
592
- function clamp(value, min, max) {
593
- return Math.max(min, Math.min(value, max));
594
- }
595
- function bezier2D_pointAt(P0, P1, P2, P3, t) {
596
- if (t <= 0) return [P0[0], P0[1]];
597
- if (t >= 1) return [P3[0], P3[1]];
598
- const u = 1 - t;
599
- const u2 = u * u;
600
- const u3 = u2 * u;
601
- const t2 = t * t;
602
- const t3 = t2 * t;
603
- const w0 = u3;
604
- const w1 = 3 * t * u2;
605
- const w2 = 3 * t2 * u;
606
- const w3 = t3;
607
- return [
608
- w0 * P0[0] + w1 * P1[0] + w2 * P2[0] + w3 * P3[0],
609
- w0 * P0[1] + w1 * P1[1] + w2 * P2[1] + w3 * P3[1]
610
- ];
611
- }
612
- var BEZIER_T_NUDGE = 1e-4;
613
- function bezier2D_derivativeAt(P0, P1, P2, P3, t) {
614
- const result = _bezier2D_derivativeAtRaw(P0, P1, P2, P3, t);
615
- if (result[0] === 0 && result[1] === 0) {
616
- const nudgedT = t < 0.5 ? t + BEZIER_T_NUDGE : t - BEZIER_T_NUDGE;
617
- return _bezier2D_derivativeAtRaw(P0, P1, P2, P3, nudgedT);
618
- }
619
- return result;
620
- }
621
- function _bezier2D_derivativeAtRaw(P0, P1, P2, P3, t) {
622
- const u = 1 - t;
623
- const a = 3 * u * u;
624
- const b = 6 * t * u;
625
- const c = 3 * t * t;
626
- return [
627
- a * (P1[0] - P0[0]) + b * (P2[0] - P1[0]) + c * (P3[0] - P2[0]),
628
- a * (P1[1] - P0[1]) + b * (P2[1] - P1[1]) + c * (P3[1] - P2[1])
629
- ];
630
- }
631
- function bezier2D_arcLengthLUT(P0, P1, P2, P3, steps = 100) {
632
- const n = steps + 1;
633
- const ts = new Float64Array(n);
634
- const ds = new Float64Array(n);
635
- let prev = bezier2D_pointAt(P0, P1, P2, P3, 0);
636
- ts[0] = 0;
637
- ds[0] = 0;
638
- let cum = 0;
639
- for (let i = 1; i < n; i++) {
640
- const t = i / steps;
641
- const cur = bezier2D_pointAt(P0, P1, P2, P3, t);
642
- const dx = cur[0] - prev[0];
643
- const dy = cur[1] - prev[1];
644
- cum += Math.sqrt(dx * dx + dy * dy);
645
- ts[i] = t;
646
- ds[i] = cum;
647
- prev = cur;
648
- }
649
- return { ts, ds };
650
- }
651
- function bezier2D_tForDistance(lut, distance) {
652
- const { ts, ds } = lut;
653
- const last = ds.length - 1;
654
- if (distance <= 0) return ts[0];
655
- if (distance >= ds[last]) return ts[last];
656
- let lo = 1;
657
- let hi = last;
658
- while (lo < hi) {
659
- const mid = lo + hi >>> 1;
660
- if (ds[mid] < distance) lo = mid + 1;
661
- else hi = mid;
662
- }
663
- const dPrev = ds[hi - 1];
664
- const dCur = ds[hi];
665
- const span = dCur - dPrev;
666
- const frac = span > 0 ? (distance - dPrev) / span : 0;
667
- return ts[hi - 1] + frac * (ts[hi] - ts[hi - 1]);
668
- }
669
- function bezier2D_arcAtT(lut, t) {
670
- const { ts, ds } = lut;
671
- const last = ts.length - 1;
672
- if (t <= ts[0]) return ds[0];
673
- if (t >= ts[last]) return ds[last];
674
- let lo = 1, hi = last;
675
- while (lo < hi) {
676
- const mid = lo + hi >>> 1;
677
- if (ts[mid] < t) lo = mid + 1;
678
- else hi = mid;
679
- }
680
- const tPrev = ts[hi - 1];
681
- const span = ts[hi] - tPrev;
682
- const frac = span > 0 ? (t - tPrev) / span : 0;
683
- return ds[hi - 1] + frac * (ds[hi] - ds[hi - 1]);
684
- }
685
- function invertEasing(easing) {
686
- if (!easing) return (y) => y;
687
- const flipped = [easing[1], easing[0], easing[3], easing[2]];
688
- return cubicBezier(flipped);
689
- }
690
-
691
- // src/playback/PxScrollMath.ts
692
- function isScrollTimeline(config) {
693
- return (config == null ? void 0 : config.timelineSource) === "scroll";
694
- }
695
- function scrollTotalDurationMs(config) {
696
- const duration = typeof (config == null ? void 0 : config.duration) === "number" && config.duration > 0 ? config.duration : DEFAULT_DURATION_MS;
697
- const iterations = typeof (config == null ? void 0 : config.iterations) === "number" && config.iterations > 0 ? config.iterations : 1;
698
- return duration * iterations;
699
- }
700
- function scrollPhaseInterval(phase, subjectSize, scrollportSize) {
701
- const s = subjectSize, vp = scrollportSize;
702
- switch (phase) {
703
- case "cover":
704
- return [0, s + vp];
705
- case "entry":
706
- return [0, Math.min(s, vp)];
707
- case "contain":
708
- return [Math.min(s, vp), Math.max(s, vp)];
709
- case "exit":
710
- return [Math.max(s, vp), s + vp];
711
- case "entry-crossing":
712
- return [0, s];
713
- case "exit-crossing":
714
- return [vp, s + vp];
715
- }
716
- }
717
- var DEFAULT_PHASE = "cover";
718
- function resolveRangePointU(point, defaultFraction, subjectSize, scrollportSize) {
719
- var _a2;
720
- const [u0, u1] = scrollPhaseInterval((_a2 = point == null ? void 0 : point.phase) != null ? _a2 : DEFAULT_PHASE, subjectSize, scrollportSize);
721
- const fraction = typeof (point == null ? void 0 : point.fraction) === "number" ? point.fraction : defaultFraction;
722
- return u0 + fraction * (u1 - u0);
723
- }
724
- function scrollViewProgress(subjectStart, subjectSize, scrollportSize, range) {
725
- const u = scrollportSize - subjectStart;
726
- const uStart = resolveRangePointU(range == null ? void 0 : range.start, 0, subjectSize, scrollportSize);
727
- const uEnd = resolveRangePointU(range == null ? void 0 : range.end, 1, subjectSize, scrollportSize);
728
- if (uEnd <= uStart) return u >= uEnd ? 1 : 0;
729
- return clamp((u - uStart) / (uEnd - uStart), 0, 1);
730
- }
731
- function scrollOffsetProgress(offset, maxOffset, range) {
732
- var _a2, _b;
733
- const raw = maxOffset > 0 ? clamp(offset / maxOffset, 0, 1) : 1;
734
- const start = typeof ((_a2 = range == null ? void 0 : range.start) == null ? void 0 : _a2.fraction) === "number" ? range.start.fraction : 0;
735
- const end = typeof ((_b = range == null ? void 0 : range.end) == null ? void 0 : _b.fraction) === "number" ? range.end.fraction : 1;
736
- if (end <= start) return raw >= end ? 1 : 0;
737
- return clamp((raw - start) / (end - start), 0, 1);
738
- }
739
- function scrollResolveAxis(axis, writingMode) {
740
- const a = axis != null ? axis : "block";
741
- if (a === "x" || a === "y") return a;
742
- const vertical = !!writingMode && writingMode.startsWith("vertical");
743
- if (a === "inline") return vertical ? "y" : "x";
744
- return vertical ? "x" : "y";
745
- }
746
-
747
- // src/schema/PxSchema.ts
748
- var PX_UNKNOWN_KEY_ERROR = "unexpected extra key";
749
- function pathStr(path) {
750
- if (!path.length) return ".";
751
- let result = "";
752
- for (const seg of path) {
753
- if (seg.startsWith("[")) result += seg;
754
- else result += (result ? "." : "") + seg;
755
- }
756
- return result;
757
- }
758
- var Base = class {
759
- _canSanitize(raw) {
760
- return this.isValid(raw);
761
- }
762
- optional() {
763
- return new Optional(this);
764
- }
765
- };
766
- var Optional = class extends Base {
767
- constructor(inner) {
768
- super();
769
- this.inner = inner;
770
- this._default = void 0;
771
- }
772
- sanitize(raw) {
773
- if (raw === void 0 || raw === null) return void 0;
774
- return this.inner._canSanitize(raw) ? this.inner.sanitize(raw) : void 0;
775
- }
776
- isValid(raw, ctx, path) {
777
- if (raw === void 0 || raw === null) return true;
778
- return this.inner.isValid(raw, ctx, path);
779
- }
780
- _canSanitize(raw) {
781
- return raw === void 0 || raw === null || this.inner._canSanitize(raw);
782
- }
783
- };
784
- var Str = class extends Base {
785
- constructor(_default = "") {
786
- super();
787
- this._default = _default;
788
- }
789
- sanitize(raw) {
790
- return typeof raw === "string" ? raw : this._default;
791
- }
792
- isValid(raw, ctx, path) {
793
- if (typeof raw === "string") return true;
794
- ctx == null ? void 0 : ctx.errors.push(pathStr(path != null ? path : []) + ": expected string, got " + typeof raw);
795
- return false;
796
- }
797
- };
798
- var Num = class extends Base {
799
- constructor(_default = 0) {
800
- super();
801
- this._default = _default;
802
- }
803
- sanitize(raw) {
804
- return typeof raw === "number" && isFinite(raw) ? raw : this._default;
226
+ sanitize(raw) {
227
+ return typeof raw === "number" && isFinite(raw) ? raw : this._default;
805
228
  }
806
229
  isValid(raw, ctx, path) {
807
230
  if (typeof raw === "number" && isFinite(raw)) return true;
@@ -1258,7 +681,7 @@ var px = {
1258
681
  * The base can be the result of px.object() or px.openObject() — anything with a _shape property.
1259
682
  *
1260
683
  * @example
1261
- * const PxSvgNodeSchema = px.extendedObject(PxNodeBase, { width: px.number().optional() });
684
+ * const PxSvgNodeSchema = px.extendedObject(PxNodeBaseSchema, { width: px.number().optional() });
1262
685
  */
1263
686
  extendedObject: (base, extra) => new Obj(__spreadValues(__spreadValues({}, base._shape), extra)),
1264
687
  /** Array whose unrecoverable items are filtered out. Default: []. */
@@ -1276,20 +699,20 @@ var px = {
1276
699
  };
1277
700
 
1278
701
  // src/version/PxSchemaVersion.ts
1279
- var PX_PLAYER_SCHEMA_VERSION = "1.1";
702
+ var PX_WIRE_SCHEMA_VERSION = "1.1";
1280
703
 
1281
704
  // src/version/PxWireVersion.ts
1282
- var WIRE_VERSION_KEY = "version";
705
+ var PX_WIRE_VERSION_KEY = "version";
1283
706
  var ANIMATOR_KEY = "animator";
1284
707
  var META_KEY = "meta";
1285
- var WireVersionRelation = /* @__PURE__ */ ((WireVersionRelation2) => {
1286
- WireVersionRelation2["unstamped"] = "unstamped";
1287
- WireVersionRelation2["same"] = "same";
1288
- WireVersionRelation2["older"] = "older";
1289
- WireVersionRelation2["newer"] = "newer";
1290
- WireVersionRelation2["otherGeneration"] = "otherGeneration";
1291
- return WireVersionRelation2;
1292
- })(WireVersionRelation || {});
708
+ var PxWireVersionRelation = /* @__PURE__ */ ((PxWireVersionRelation2) => {
709
+ PxWireVersionRelation2["unstamped"] = "unstamped";
710
+ PxWireVersionRelation2["same"] = "same";
711
+ PxWireVersionRelation2["older"] = "older";
712
+ PxWireVersionRelation2["newer"] = "newer";
713
+ PxWireVersionRelation2["otherGeneration"] = "otherGeneration";
714
+ return PxWireVersionRelation2;
715
+ })(PxWireVersionRelation || {});
1293
716
  var VERSION_RE = /^(\d+)\.(\d+)(?:\.(\d+))?$/;
1294
717
  function parseWireVersion(raw) {
1295
718
  if (typeof raw !== "string") return void 0;
@@ -1301,7 +724,7 @@ function formatWireVersion(v) {
1301
724
  return v.a + "." + v.b + "." + v.c;
1302
725
  }
1303
726
  var _a;
1304
- var PLAYER_WIRE_VERSION = (_a = parseWireVersion(PX_PLAYER_SCHEMA_VERSION)) != null ? _a : { a: 1, b: 1, c: 0 };
727
+ var PX_WIRE_VERSION = (_a = parseWireVersion(PX_WIRE_SCHEMA_VERSION)) != null ? _a : { a: 1, b: 1, c: 0 };
1305
728
  function getAnimatorBlock(doc) {
1306
729
  if (!doc || typeof doc !== "object") return void 0;
1307
730
  const atRoot = readObjectProp(doc, ANIMATOR_KEY);
@@ -1315,7 +738,7 @@ function readObjectProp(obj, key) {
1315
738
  }
1316
739
  function readWireVersion(doc) {
1317
740
  const animator = getAnimatorBlock(doc);
1318
- return animator ? parseWireVersion(animator[WIRE_VERSION_KEY]) : void 0;
741
+ return animator ? parseWireVersion(animator[PX_WIRE_VERSION_KEY]) : void 0;
1319
742
  }
1320
743
  function compareWireVersion(file, mine, readerReadsEditorPart) {
1321
744
  if (!file) return "unstamped" /* unstamped */;
@@ -1324,7 +747,7 @@ function compareWireVersion(file, mine, readerReadsEditorPart) {
1324
747
  if (!readerReadsEditorPart || file.c === mine.c) return "same" /* same */;
1325
748
  return file.c > mine.c ? "newer" /* newer */ : "older" /* older */;
1326
749
  }
1327
- function versionAdvice(relation, file, mine, isPlayer) {
750
+ function wireVersionAdvice(relation, file, mine, isPlayer) {
1328
751
  if (!file) return void 0;
1329
752
  const target = isPlayer ? "player" : "editor";
1330
753
  const gap = "written for schema " + formatWireVersion(file) + ", this " + target + " reads " + formatWireVersion(mine);
@@ -1339,13 +762,13 @@ function versionAdvice(relation, file, mine, isPlayer) {
1339
762
  return void 0;
1340
763
  }
1341
764
  }
1342
- var WireStepKind = /* @__PURE__ */ ((WireStepKind2) => {
1343
- WireStepKind2["additive"] = "additive";
1344
- WireStepKind2["converted"] = "converted";
1345
- return WireStepKind2;
1346
- })(WireStepKind || {});
1347
- var BASELINE_PLAYER_VERSION = "1.1";
1348
- var PLAYER_WIRE_STEPS = [];
765
+ var PxWireStepKind = /* @__PURE__ */ ((PxWireStepKind2) => {
766
+ PxWireStepKind2["additive"] = "additive";
767
+ PxWireStepKind2["converted"] = "converted";
768
+ return PxWireStepKind2;
769
+ })(PxWireStepKind || {});
770
+ var PX_WIRE_BASELINE_VERSION = "1.1";
771
+ var PX_WIRE_STEPS = [];
1349
772
  function applyWireSteps(doc, cfg) {
1350
773
  const from = readWireVersion(doc);
1351
774
  const relation = compareWireVersion(from, cfg.target, cfg.readerReadsEditorPart);
@@ -1355,7 +778,7 @@ function applyWireSteps(doc, cfg) {
1355
778
  from,
1356
779
  relation,
1357
780
  applied: [],
1358
- advice: versionAdvice(relation, from, cfg.target, !cfg.readerReadsEditorPart)
781
+ advice: wireVersionAdvice(relation, from, cfg.target, !cfg.readerReadsEditorPart)
1359
782
  };
1360
783
  }
1361
784
  const due = [];
@@ -1381,10 +804,10 @@ function applyWireSteps(doc, cfg) {
1381
804
  stampVersion(target, cfg.target, cfg.readerReadsEditorPart);
1382
805
  return { doc: target, from, relation, applied };
1383
806
  }
1384
- function convertPlayerDocument(doc) {
807
+ function convertWireDocument(doc) {
1385
808
  return applyWireSteps(doc, {
1386
- steps: PLAYER_WIRE_STEPS,
1387
- target: PLAYER_WIRE_VERSION,
809
+ steps: PX_WIRE_STEPS,
810
+ target: PX_WIRE_VERSION,
1388
811
  readerReadsEditorPart: false
1389
812
  });
1390
813
  }
@@ -1395,8 +818,8 @@ function clonePlain(value) {
1395
818
  function stampVersion(doc, target, readerReadsEditorPart) {
1396
819
  const animator = getAnimatorBlock(doc);
1397
820
  if (!animator) return;
1398
- const previous = parseWireVersion(animator[WIRE_VERSION_KEY]);
1399
- animator[WIRE_VERSION_KEY] = formatWireVersion({
821
+ const previous = parseWireVersion(animator[PX_WIRE_VERSION_KEY]);
822
+ animator[PX_WIRE_VERSION_KEY] = formatWireVersion({
1400
823
  a: target.a,
1401
824
  b: target.b,
1402
825
  c: readerReadsEditorPart ? target.c : previous ? previous.c : 0
@@ -1451,131 +874,8 @@ function applyWireStepsDown(doc, cfg) {
1451
874
  stampVersion(target, cfg.target, cfg.readerReadsEditorPart);
1452
875
  return { ok: true, doc: target, applied };
1453
876
  }
1454
- function downgradePlayerDocument(doc, target) {
1455
- return applyWireStepsDown(doc, { steps: PLAYER_WIRE_STEPS, target, readerReadsEditorPart: false });
1456
- }
1457
-
1458
- // src/version/PxSchemaFieldUniverse.ts
1459
- function schemaFieldUniverse(root) {
1460
- const fields = /* @__PURE__ */ new Set();
1461
- const enumerated = /* @__PURE__ */ new Set();
1462
- const queue = [{ schema: root, path: "" }];
1463
- while (queue.length) {
1464
- const { schema, path } = queue.shift();
1465
- const d = describeSchema(schema);
1466
- switch (d.kind) {
1467
- case "shape": {
1468
- if (enumerated.has(schema)) break;
1469
- enumerated.add(schema);
1470
- for (const key of Object.keys(d.shape)) {
1471
- const id = path ? path + "." + key : key;
1472
- fields.add(id);
1473
- queue.push({ schema: d.shape[key], path: id });
1474
- }
1475
- if (d.openValue) queue.push({ schema: d.openValue, path: path + "{*}" });
1476
- break;
1477
- }
1478
- case "optional":
1479
- queue.push({ schema: d.inner, path });
1480
- break;
1481
- case "array":
1482
- queue.push({ schema: d.item, path: path + "[]" });
1483
- break;
1484
- case "lazy":
1485
- queue.push({ schema: d.resolved, path });
1486
- break;
1487
- case "record":
1488
- queue.push({ schema: d.value, path: path + "{*}" });
1489
- break;
1490
- case "union":
1491
- d.members.forEach((member, i) => queue.push({ schema: member, path: path + "|" + i }));
1492
- break;
1493
- case "discriminatedUnion":
1494
- for (const member of d.members) queue.push({ schema: member, path: path + "|" + discriminantOf(member, d.key) });
1495
- break;
1496
- default:
1497
- break;
1498
- }
1499
- }
1500
- return [...fields].sort();
1501
- }
1502
- function discriminantOf(member, key) {
1503
- const d = describeSchema(member);
1504
- if (d.kind !== "shape") return "?";
1505
- const keySchema = d.shape[key];
1506
- if (keySchema === void 0) return "?";
1507
- const kd = describeSchema(keySchema);
1508
- return String((kd.kind === "optional" ? kd.inner : keySchema)._default);
1509
- }
1510
-
1511
- // src/version/PxSchemaRelease.ts
1512
- function diffFieldUniverse(previous, current) {
1513
- const prev = new Set(previous);
1514
- const cur = new Set(current);
1515
- return {
1516
- added: current.filter((k) => !prev.has(k)).sort(),
1517
- removed: previous.filter((k) => !cur.has(k)).sort()
1518
- };
1519
- }
1520
- function planSchemaRelease(p) {
1521
- const changed = p.added.length > 0 || p.removed.length > 0;
1522
- const last = parseWireVersion(p.lastReleased);
1523
- const declared = parseWireVersion(p.declared);
1524
- if (!last || !declared) return { changed, refuse: "Unparseable version: " + p.lastReleased + " / " + p.declared + "." };
1525
- const requiredVersion = last.a + "." + (last.b + 1);
1526
- if (!changed) {
1527
- if (declared.b === last.b && declared.a === last.a) return { changed };
1528
- const step2 = p.steps.find((s) => s.to === p.declared);
1529
- return step2 ? { changed, requiredVersion: p.declared } : { changed, refuse: "The version moved to " + p.declared + " with no key change and no step explaining it." };
1530
- }
1531
- const requiredKind = p.removed.length ? "converted" /* converted */ : "additive" /* additive */;
1532
- const summary = p.added.length + " key(s) added, " + p.removed.length + " removed";
1533
- if (declared.a !== last.a || declared.b !== last.b + 1) {
1534
- return {
1535
- changed,
1536
- requiredKind,
1537
- requiredVersion,
1538
- refuse: "The player schema changed (" + summary + ") but PX_PLAYER_SCHEMA_VERSION is " + p.declared + ". Set it to " + requiredVersion + " and add the PLAYER_WIRE_STEPS entry."
1539
- };
1540
- }
1541
- const step = p.steps.find((s) => s.to === p.declared);
1542
- if (!step) {
1543
- return { changed, requiredKind, requiredVersion, refuse: "No PLAYER_WIRE_STEPS entry reaches " + p.declared + "." };
1544
- }
1545
- if (requiredKind === "converted" /* converted */ && step.kind !== "converted" /* converted */) {
1546
- return {
1547
- changed,
1548
- requiredKind,
1549
- requiredVersion,
1550
- refuse: "Keys were REMOVED (" + p.removed.join(", ") + "), which is never additive \u2014 the " + p.declared + " step must be `converted`, with an up()."
1551
- };
1552
- }
1553
- return { changed, requiredKind, requiredVersion };
1554
- }
1555
- function releaseLogProblems(releases, steps, declared, baseline) {
1556
- const problems = [];
1557
- if (!releases.length) return ["The release log is empty."];
1558
- if (!releases[0].baseline || releases[0].version !== baseline) {
1559
- problems.push("The first release must be the baseline " + baseline + ".");
1560
- }
1561
- for (let i = 1; i < releases.length; i++) {
1562
- const prev = parseWireVersion(releases[i - 1].version);
1563
- const cur = parseWireVersion(releases[i].version);
1564
- if (!prev || !cur || cur.a !== prev.a || cur.b !== prev.b + 1) {
1565
- problems.push("Release " + releases[i].version + " does not follow " + releases[i - 1].version + " by one `b` step.");
1566
- }
1567
- if (releases[i].date < releases[i - 1].date) problems.push("Release " + releases[i].version + " is dated before its predecessor.");
1568
- const step = steps.find((s) => s.to === releases[i].version);
1569
- if (!step) problems.push("Release " + releases[i].version + " has no PLAYER_WIRE_STEPS entry.");
1570
- else if (releases[i].removed.length && step.kind !== "converted" /* converted */) {
1571
- problems.push("Release " + releases[i].version + " removed keys, but its step is not `converted`.");
1572
- }
1573
- }
1574
- const latest = releases[releases.length - 1].version;
1575
- if (latest !== declared) {
1576
- problems.push("PX_PLAYER_SCHEMA_VERSION is " + declared + " but the last release record is " + latest + " \u2014 a bump needs its changelog entry (run scripts/schema-release.mjs --apply).");
1577
- }
1578
- return problems;
877
+ function downgradeWireDocument(doc, target) {
878
+ return applyWireStepsDown(doc, { steps: PX_WIRE_STEPS, target, readerReadsEditorPart: false });
1579
879
  }
1580
880
 
1581
881
  // src/format/PxAnimatorConstants.ts
@@ -1591,8 +891,6 @@ var PxPlaybackDirection = {
1591
891
  alternate: "alternate",
1592
892
  alternateReverse: "alternate-reverse"
1593
893
  };
1594
- var PX_ANIM_SRC_ATTR_NAME = "data-px-animation-src";
1595
- var PX_ANIM_ATTR_NAME = "_px_animator";
1596
894
  var PxStartOn = {
1597
895
  load: "load",
1598
896
  mouseOver: "mouseOver",
@@ -1655,17 +953,17 @@ var PxTimelineEngine = {
1655
953
  native: "native",
1656
954
  js: "js"
1657
955
  };
1658
- var PxTimelineEngineExtra = __spreadProps(__spreadValues({}, PxTimelineEngine), {
956
+ var PxTimelineEngineSetting = __spreadProps(__spreadValues({}, PxTimelineEngine), {
1659
957
  auto: "auto"
1660
958
  });
1661
959
  function resolveTimelineEngine(engine) {
1662
- return engine === PxTimelineEngineExtra.js ? PxTimelineEngine.js : PxTimelineEngine.native;
960
+ return engine === PxTimelineEngineSetting.js ? PxTimelineEngine.js : PxTimelineEngine.native;
1663
961
  }
1664
962
  function isNativeForced(engine) {
1665
- return engine === PxTimelineEngineExtra.native;
963
+ return engine === PxTimelineEngineSetting.native;
1666
964
  }
1667
965
  function mayUseNativeScrollTimeline(engine) {
1668
- return engine !== PxTimelineEngineExtra.js;
966
+ return engine !== PxTimelineEngineSetting.js;
1669
967
  }
1670
968
  var PX_TRIGGER_DEFAULTS = {
1671
969
  startOn: "load",
@@ -1757,7 +1055,7 @@ var PxStrokeTrimSubPaths = {
1757
1055
  separate: "separate",
1758
1056
  combined: "combined"
1759
1057
  };
1760
- var TEXT_CONTENT_ATTR = "textContent";
1058
+ var PX_TEXT_CONTENT_ATTR = "textContent";
1761
1059
  var CLASS_ATTR = "class";
1762
1060
  var TRANSFORM_ATTR = "transform";
1763
1061
  var OFFSET_DISTANCE_ATTR = "offsetDistance";
@@ -1768,7 +1066,7 @@ var INTERNAL_ATTRS = /* @__PURE__ */ new Set([
1768
1066
  "meta",
1769
1067
  "animate",
1770
1068
  "effects",
1771
- TEXT_CONTENT_ATTR
1069
+ PX_TEXT_CONTENT_ATTR
1772
1070
  ]);
1773
1071
  var TRANSFORM_PART = {
1774
1072
  translate: "translate",
@@ -1791,11 +1089,11 @@ var PxGradientType = {
1791
1089
  linear: "linear",
1792
1090
  radial: "radial"
1793
1091
  };
1794
- function isPxElementFileFormat(fileJson) {
1795
- if (!(fileJson && typeof fileJson === "object" && !Array.isArray(fileJson))) {
1092
+ function isPxDocument(doc) {
1093
+ if (!(doc && typeof doc === "object" && !Array.isArray(doc))) {
1796
1094
  return false;
1797
1095
  }
1798
- return fileJson.type === "svg";
1096
+ return doc.type === "svg";
1799
1097
  }
1800
1098
  function getAnimatorConfig(doc) {
1801
1099
  var _a2;
@@ -1922,7 +1220,7 @@ function nestAnimatorTimeline(cfg) {
1922
1220
  if (fill !== void 0) timeline.fillMode = fill;
1923
1221
  return Object.keys(timeline).length > 0 ? __spreadProps(__spreadValues({}, shared), { timeline }) : shared;
1924
1222
  }
1925
- function getDefs(doc) {
1223
+ function getDefinitions(doc) {
1926
1224
  var _a2;
1927
1225
  if (!doc) return void 0;
1928
1226
  return (_a2 = getAnimatorConfig(doc)) == null ? void 0 : _a2.definitions;
@@ -1930,9 +1228,7 @@ function getDefs(doc) {
1930
1228
  function getBindings(doc) {
1931
1229
  var _a2;
1932
1230
  if (!doc) return void 0;
1933
- const animateById = (_a2 = getAnimatorConfig(doc)) == null ? void 0 : _a2.animateById;
1934
- if (!animateById) return void 0;
1935
- return Object.entries(animateById).map(([id, anim]) => ({ id: id.startsWith("#") ? id.slice(1) : id, animate: anim }));
1231
+ return (_a2 = getAnimatorConfig(doc)) == null ? void 0 : _a2.bindings;
1936
1232
  }
1937
1233
  function getChildren(doc) {
1938
1234
  return doc == null ? void 0 : doc.children;
@@ -1970,20 +1266,20 @@ var PxKeyframeSchema = implementsInterface()(px.object({
1970
1266
  // its internal COPY-PASTE payload, which never validates against this schema.)
1971
1267
  }));
1972
1268
  var anyKf = (kf) => kf;
1973
- var kfTime = (kf) => {
1269
+ var keyframeTime = (kf) => {
1974
1270
  var _a2, _b;
1975
1271
  return (_b = (_a2 = anyKf(kf).time) != null ? _a2 : anyKf(kf).t) != null ? _b : 0;
1976
1272
  };
1977
- var kfValue = (kf) => {
1273
+ var keyframeValue = (kf) => {
1978
1274
  var _a2;
1979
1275
  return (_a2 = anyKf(kf).value) != null ? _a2 : anyKf(kf).v;
1980
1276
  };
1981
- var kfEasing = (kf) => {
1277
+ var keyframeEasing = (kf) => {
1982
1278
  var _a2;
1983
1279
  return (_a2 = anyKf(kf).easing) != null ? _a2 : anyKf(kf).e;
1984
1280
  };
1985
- var kfTangentIn = (kf) => anyKf(kf).tangentIn;
1986
- var kfTangentOut = (kf) => anyKf(kf).tangentOut;
1281
+ var keyframeTangentIn = (kf) => anyKf(kf).tangentIn;
1282
+ var keyframeTangentOut = (kf) => anyKf(kf).tangentOut;
1987
1283
  var PxLoopSchema = implementsInterface()(px.object({
1988
1284
  segmentCount: px.number().optional(),
1989
1285
  repeatAt: px.enum([PxLoopRepeatAt.start, PxLoopRepeatAt.end]).optional(),
@@ -2037,12 +1333,9 @@ var PxGlyphFontSchema = implementsInterface()(px.object({
2037
1333
  unitsPerEm: px.number(),
2038
1334
  glyphs: px.record(PxGlyphSchema)
2039
1335
  }));
2040
- var PxDefsSchema = implementsInterface()(px.object({
1336
+ var PxDefinitionsSchema = implementsInterface()(px.object({
2041
1337
  easings: px.record(px.tuple([px.number(), px.number(), px.number(), px.number()])).optional(),
2042
1338
  animations: px.record(PxAnimationDefinitionSchema).optional(),
2043
- // Review §2.6: the schema now matches the declared type — a style preset is a flat
2044
- // record of string|number attribute values, nothing nested.
2045
- styles: px.record(px.record(px.union([px.string(), px.number()]))).optional(),
2046
1339
  fonts: px.record(PxGlyphFontSchema).optional()
2047
1340
  }));
2048
1341
  var PxScrollRangePointSchema = implementsInterface()(px.object({
@@ -2078,7 +1371,7 @@ var PxTimelinePinSchema = implementsInterface()(px.object({
2078
1371
  offset: px.number().optional(),
2079
1372
  distance: px.number().optional()
2080
1373
  }));
2081
- var PxTimelineEngineSchema = px.enum([PxTimelineEngineExtra.auto, PxTimelineEngineExtra.native, PxTimelineEngineExtra.js]).optional();
1374
+ var PxTimelineEngineSchema = px.enum([PxTimelineEngineSetting.auto, PxTimelineEngineSetting.native, PxTimelineEngineSetting.js]).optional();
2082
1375
  var PxTimeTimelineSchema = implementsInterface()(px.object({
2083
1376
  type: px.literal("time").optional(),
2084
1377
  engine: PxTimelineEngineSchema,
@@ -2123,22 +1416,22 @@ var PxTimelineSchema = px.discriminatedUnion("type", [
2123
1416
  PxScrollTimelineSchema,
2124
1417
  PxViewTimelineSchema
2125
1418
  ]);
1419
+ var PxBindingSchema = implementsInterface()(px.object({
1420
+ target: px.string(),
1421
+ animateWith: px.array(px.string())
1422
+ }));
2126
1423
  var PxAnimatorConfigSchema = implementsInterface()(px.object({
2127
1424
  // (`mode`, `duration` and `frameRate` live INSIDE `timeline` on the wire — §2.8; they exist
2128
1425
  // at this level only on the runtime view, like the rest of the playback dynamics.)
2129
1426
  // THE spelling of "what advances progress" — clock / scroll / view (review §2.1).
2130
1427
  timeline: PxTimelineSchema.optional(),
2131
- definitions: PxDefsSchema.optional(),
2132
- animateById: px.record(PxElementAnimationSchema).optional(),
1428
+ definitions: PxDefinitionsSchema.optional(),
1429
+ bindings: px.array(PxBindingSchema).optional(),
2133
1430
  debugGlobalName: px.string().optional(),
2134
1431
  // Declared HERE because this is a closed object: an undeclared key would be stripped by
2135
1432
  // `sanitize` and flagged by strict validation on our own files.
2136
1433
  version: px.string().optional()
2137
1434
  }));
2138
- var PxBindingSchema = implementsInterface()(px.object({
2139
- id: px.string(),
2140
- animate: PxElementAnimationSchema
2141
- }));
2142
1435
  var PxAttrValueSchema = px.union([
2143
1436
  px.string(),
2144
1437
  px.number(),
@@ -2221,7 +1514,7 @@ var PxAnimatableGradientStopsSchema = px.union([
2221
1514
  PxPropertyAnimationSchema
2222
1515
  ]);
2223
1516
  var PxFillGradientEffectSchema = implementsInterface()(px.object({
2224
- // Contextual kind — the `type` convention, see `PxNodeBase.type`.
1517
+ // Contextual kind — the `type` convention, see `PxNodeBaseSchema.type`.
2225
1518
  type: px.enum([PxGradientType.linear, PxGradientType.radial]),
2226
1519
  start: PxAnimatableVec2Schema.optional(),
2227
1520
  end: PxAnimatableVec2Schema.optional(),
@@ -2258,11 +1551,11 @@ var PxEffectsSchema = implementsInterface()(px.object({
2258
1551
  textPath: PxTextPathEffectSchema.optional(),
2259
1552
  text: PxTextEffectSchema.optional()
2260
1553
  }));
2261
- function validateNodeEffects(root, opts) {
1554
+ function validateNodeEffects(root, options) {
2262
1555
  const warnings = [];
2263
1556
  const walk = (node, path) => {
2264
1557
  if (node && node.effects) {
2265
- const ctx = { errors: [], warnings: [], strict: !!(opts == null ? void 0 : opts.strict) };
1558
+ const ctx = { errors: [], warnings: [], strict: !!(options == null ? void 0 : options.strict) };
2266
1559
  const ok = PxEffectsSchema.isValid(node.effects, ctx, [path + ".effects"]);
2267
1560
  if (!ok) {
2268
1561
  for (const err of ctx.errors) warnings.push(err);
@@ -2308,303 +1601,680 @@ function validateEasingRefs(root, easings) {
2308
1601
  const problem = path + '.easing: "' + easing + '" names no entry in animator.definitions.easings \u2014 it will play linear';
2309
1602
  if (!problems.includes(problem)) problems.push(problem);
2310
1603
  }
2311
- for (const [key, value] of Object.entries(node)) {
2312
- if (key === "easing") continue;
2313
- if (value && typeof value === "object") walk(value, path + "." + key);
1604
+ for (const [key, value] of Object.entries(node)) {
1605
+ if (key === "easing") continue;
1606
+ if (value && typeof value === "object") walk(value, path + "." + key);
1607
+ }
1608
+ };
1609
+ walk(root, "root");
1610
+ return problems;
1611
+ }
1612
+ function validateVersionStamp(doc) {
1613
+ var _a2;
1614
+ const version = (_a2 = getAnimatorConfig(doc)) == null ? void 0 : _a2.version;
1615
+ if (version === void 0) return [];
1616
+ if (parseWireVersion(version) !== void 0) return [];
1617
+ return ["root.animator.version: " + JSON.stringify(version) + ' is not a version stamp ("a.b" or "a.b.c") \u2014 it reads as unstamped'];
1618
+ }
1619
+ function validateDocument(doc, options) {
1620
+ var _a2;
1621
+ const strict = (options == null ? void 0 : options.strict) !== false;
1622
+ const ctx = { errors: [], warnings: [], strict };
1623
+ const problems = PxAnimatedSvgDocumentSchema.isValid(doc, ctx, ["root"]) ? [] : [...ctx.errors];
1624
+ if (doc && typeof doc === "object") {
1625
+ for (const w of validateNodeEffects(doc, { strict })) {
1626
+ if (!problems.includes(w)) problems.push(w);
1627
+ }
1628
+ const defs = (_a2 = getAnimatorConfig(doc)) == null ? void 0 : _a2.definitions;
1629
+ for (const w of validateGlyphFontRefs(doc, defs == null ? void 0 : defs.fonts)) {
1630
+ if (!problems.includes(w)) problems.push(w);
1631
+ }
1632
+ for (const w of validateEasingRefs(doc, defs == null ? void 0 : defs.easings)) {
1633
+ if (!problems.includes(w)) problems.push(w);
1634
+ }
1635
+ for (const w of validateVersionStamp(doc)) {
1636
+ if (!problems.includes(w)) problems.push(w);
1637
+ }
1638
+ }
1639
+ return problems;
1640
+ }
1641
+ var PxNodeBaseSchema = px.openObject({
1642
+ // CONVENTION (SCHEMA-DESIGN R1 / issues N4): `type` is the ONE word for "what
1643
+ // kind of thing is this", discriminated by its CARRIER — here the node TAG
1644
+ // (`rect`, `text`), and inside a sub-object that object's kind (`fillGradient.type`,
1645
+ // `fillGradient.type`, editor `preset.type`). Each sits in its own object, so
1646
+ // the carrier disambiguates completely; synonyms (`cloneKind`, `presetShape`)
1647
+ // would add words that all mean "type" and still need the carrier to read.
1648
+ // Guarding a `type` SLOT against a wrong VALUE is the job of strict enums
1649
+ // (issues V3), never of distinct key names.
1650
+ type: px.string(),
1651
+ // The escape hatch for elements that carry a REAL `type` attribute — `<feTurbulence
1652
+ // type="fractalNoise">`, `<feFuncR type="table">`, `<feColorMatrix type="saturate">`.
1653
+ // `type` is taken by the tag name, so the attribute travels here and the renderer puts
1654
+ // it back (`PxAnimatorDOM.renderNode`, `PxRnRender`). Declared here — not merely
1655
+ // documented — because a wire key that is not in a schema is invisible to the
1656
+ // minifier's reserve list and gets renamed (dev-docs/plans/minification-boundary.md §1.1).
1657
+ domType: px.string().optional(),
1658
+ // Text content of a `<text>` / `<tspan>`. Declared, so a non-string value is a schema error
1659
+ // and the minifier reserves the key; `text` is NOT an alias for it and is not read anywhere.
1660
+ textContent: px.string().optional(),
1661
+ id: px.string().optional(),
1662
+ meta: px.any().optional(),
1663
+ // Player-effects bucket emitted by the Editor's lightweight design format.
1664
+ // Consumed and removed by `materializeNodeEffects` before any other normalization
1665
+ // (see `createAnimatorImpl`), so downstream code never sees it.
1666
+ effects: PxEffectsSchema.optional(),
1667
+ // `PxElementAnimation` (not just `PxAnimationDefinition`) — accepts
1668
+ // string ref / array of refs / inline definition / mixed array; mirrors
1669
+ // `node.animate` values and what `processNode` resolves at runtime.
1670
+ animate: PxElementAnimationSchema.optional(),
1671
+ style: px.record(px.union([px.string(), px.number()])).optional()
1672
+ }, PxAttrValueSchema);
1673
+ var PxNodeSchema = px.openObject(__spreadProps(__spreadValues({}, PxNodeBaseSchema._shape), {
1674
+ children: px.lazy(() => px.array(PxNodeSchema), []).optional()
1675
+ }), PxAttrValueSchema);
1676
+ var PxSvgNodeRootSchema = px.object({
1677
+ // `"100%"` and other SVG length strings are legal here — a number-only slot rejected
1678
+ // real documents (e.g. apple-store-look-14-main.json) at the root <svg>.
1679
+ width: px.union([px.number(), px.string()]).optional(),
1680
+ height: px.union([px.number(), px.string()]).optional(),
1681
+ viewBox: px.string().optional(),
1682
+ animator: PxAnimatorConfigSchema.optional()
1683
+ });
1684
+ var PxAnimatedSvgDocumentSchema = px.openObject(__spreadProps(__spreadValues(__spreadValues({}, PxNodeBaseSchema._shape), PxSvgNodeRootSchema._shape), {
1685
+ type: px.literal("svg"),
1686
+ // override string → literal to require 'svg'
1687
+ children: px.array(PxNodeSchema).optional()
1688
+ }), PxAttrValueSchema);
1689
+ var PxBezierPathSchema = implementsInterface()(px.object({
1690
+ v: px.array(px.array(px.number())),
1691
+ i: px.array(px.array(px.number())).optional(),
1692
+ o: px.array(px.array(px.number())).optional(),
1693
+ c: px.boolean().optional()
1694
+ }));
1695
+ function isValidPxDocument(doc) {
1696
+ const errors = validateDocument(doc, { strict: false });
1697
+ return { valid: errors.length === 0, errors };
1698
+ }
1699
+
1700
+ // src/util/PxIdUtil.ts
1701
+ var _idCounter = 0;
1702
+ function generateUniqueId() {
1703
+ const timestamp = Date.now().toString(36);
1704
+ const counter = (++_idCounter).toString(36);
1705
+ const random = Math.random().toString(36).substring(2, 6);
1706
+ return "_px_" + timestamp + counter + random;
1707
+ }
1708
+ function deepClone(value) {
1709
+ if (value === null || typeof value !== "object") return value;
1710
+ if (Array.isArray(value)) return value.map((item) => deepClone(item));
1711
+ const obj = value;
1712
+ const cloned = {};
1713
+ for (const key of Object.keys(obj)) {
1714
+ cloned[key] = deepClone(obj[key]);
1715
+ }
1716
+ return cloned;
1717
+ }
1718
+ function generateNewIds(doc) {
1719
+ var _a2;
1720
+ const cloned = deepClone(doc);
1721
+ const idMap = /* @__PURE__ */ new Map();
1722
+ const hashRefAttrs = /* @__PURE__ */ new Set(["href", "xlink:href"]);
1723
+ const urlRefAttrs = /* @__PURE__ */ new Set([
1724
+ "fill",
1725
+ "stroke",
1726
+ "clip-path",
1727
+ "clipPath",
1728
+ "mask",
1729
+ "marker",
1730
+ "marker-start",
1731
+ "marker-mid",
1732
+ "marker-end",
1733
+ "filter",
1734
+ "flood-color",
1735
+ "lighting-color"
1736
+ ]);
1737
+ const directIdRefAttrs = /* @__PURE__ */ new Set(["targetId", "boundElementId"]);
1738
+ const isEffectSourceRef = (key, parentKey) => key === "source" && (parentKey === "maskedBy" || parentKey === "clone");
1739
+ function collectIds(node) {
1740
+ if (!node || typeof node !== "object") return;
1741
+ if (node.id && typeof node.id === "string") {
1742
+ const oldId = node.id;
1743
+ const newId = generateUniqueId();
1744
+ idMap.set(oldId, newId);
1745
+ node.id = newId;
1746
+ } else if (node.animate) {
1747
+ node.id = generateUniqueId();
1748
+ }
1749
+ if (Array.isArray(node.children)) {
1750
+ for (const child of node.children) {
1751
+ collectIds(child);
1752
+ }
1753
+ }
1754
+ }
1755
+ function updateRefs(node, parentKey) {
1756
+ if (!node || typeof node !== "object") return;
1757
+ for (const [key, value] of Object.entries(node)) {
1758
+ if (key === "children") {
1759
+ if (Array.isArray(value)) {
1760
+ for (const child of value) {
1761
+ updateRefs(child);
1762
+ }
1763
+ }
1764
+ continue;
1765
+ }
1766
+ if (typeof value === "string") {
1767
+ if (hashRefAttrs.has(key) && value.startsWith("#")) {
1768
+ const oldId = value.slice(1);
1769
+ const newId = idMap.get(oldId);
1770
+ if (newId) {
1771
+ node[key] = "#" + newId;
1772
+ }
1773
+ } else if (urlRefAttrs.has(key)) {
1774
+ node[key] = replaceUrlRefs(value, idMap);
1775
+ } else if (directIdRefAttrs.has(key) || isEffectSourceRef(key, parentKey)) {
1776
+ const hasHash = value.startsWith("#");
1777
+ const newId = idMap.get(hasHash ? value.slice(1) : value);
1778
+ if (newId) {
1779
+ node[key] = hasHash ? "#" + newId : newId;
1780
+ }
1781
+ } else if (value.includes("url(#")) {
1782
+ node[key] = replaceUrlRefs(value, idMap);
1783
+ }
1784
+ } else if (key === "style" && typeof value === "object" && value !== null) {
1785
+ for (const [styleProp, styleValue] of Object.entries(value)) {
1786
+ if (typeof styleValue === "string") {
1787
+ value[styleProp] = replaceUrlRefs(styleValue, idMap);
1788
+ }
1789
+ }
1790
+ } else if (typeof value === "object" && value !== null) {
1791
+ updateRefs(value, key);
1792
+ }
1793
+ }
1794
+ }
1795
+ collectIds(cloned);
1796
+ updateRefs(cloned);
1797
+ const docBindings = (_a2 = cloned.animator) == null ? void 0 : _a2.bindings;
1798
+ if (Array.isArray(docBindings)) {
1799
+ const updatedBindings = docBindings.map((binding) => {
1800
+ var _a3;
1801
+ const hashed = binding.target.startsWith("#");
1802
+ const id = hashed ? binding.target.slice(1) : binding.target;
1803
+ const newId = (_a3 = idMap.get(id)) != null ? _a3 : id;
1804
+ return __spreadProps(__spreadValues({}, binding), { target: hashed ? "#" + newId : newId });
1805
+ });
1806
+ cloned.animator = __spreadProps(__spreadValues({}, cloned.animator), { bindings: updatedBindings });
1807
+ }
1808
+ return cloned;
1809
+ }
1810
+ function replaceUrlRefs(value, idMap) {
1811
+ return value.replace(/url\(#([^)]+)\)/g, (match, oldId) => {
1812
+ const newId = idMap.get(oldId);
1813
+ return newId ? "url(#" + newId + ")" : match;
1814
+ });
1815
+ }
1816
+
1817
+ // src/util/PxAnimatorUtil.ts
1818
+ function bezierToSvgPath(path, forceCurves = false) {
1819
+ var _a2, _b, _c, _d;
1820
+ const v = path.v;
1821
+ const i = path.i;
1822
+ const o = path.o;
1823
+ const c = path.c;
1824
+ if (!v.length) return "";
1825
+ const d = [];
1826
+ const len = v.length;
1827
+ d.push("M" + v[0][0] + "," + v[0][1]);
1828
+ for (let idx = 1; idx < len; idx++) {
1829
+ const prevV = v[idx - 1];
1830
+ const prevO = (_a2 = o == null ? void 0 : o[idx - 1]) != null ? _a2 : prevV;
1831
+ const currI = (_b = i == null ? void 0 : i[idx]) != null ? _b : v[idx];
1832
+ const currV = v[idx];
1833
+ const isLine = !forceCurves && (prevO[0] === prevV[0] && prevO[1] === prevV[1]) && (currI[0] === currV[0] && currI[1] === currV[1]);
1834
+ if (isLine) {
1835
+ d.push("L" + currV[0] + "," + currV[1]);
1836
+ } else {
1837
+ d.push("C" + prevO[0] + "," + prevO[1] + "," + currI[0] + "," + currI[1] + "," + currV[0] + "," + currV[1]);
1838
+ }
1839
+ }
1840
+ if (c && len > 0) {
1841
+ const lastV = v[len - 1];
1842
+ const lastO = (_c = o == null ? void 0 : o[len - 1]) != null ? _c : lastV;
1843
+ const firstI = (_d = i == null ? void 0 : i[0]) != null ? _d : v[0];
1844
+ const firstV = v[0];
1845
+ const isLine = !forceCurves && (lastO[0] === lastV[0] && lastO[1] === lastV[1]) && (firstI[0] === firstV[0] && firstI[1] === firstV[1]);
1846
+ if (!isLine) {
1847
+ d.push("C" + lastO[0] + "," + lastO[1] + "," + firstI[0] + "," + firstI[1] + "," + firstV[0] + "," + firstV[1]);
2314
1848
  }
1849
+ d.push("z");
1850
+ }
1851
+ return d.join("");
1852
+ }
1853
+ function interpolateNum(a, b, t) {
1854
+ return a + (b - a) * t;
1855
+ }
1856
+ function interpolateVec(a, b, t) {
1857
+ const res = [];
1858
+ const count = Math.max(a.length, b.length);
1859
+ for (let i = 0; i < count; i++) {
1860
+ res[i] = interpolateNum(a[i] || 0, b[i] || 0, t);
1861
+ }
1862
+ return res;
1863
+ }
1864
+ function interpolateColor(a, b, t) {
1865
+ return [
1866
+ interpolateNum(a[0] || 0, b[0] || 0, t),
1867
+ interpolateNum(a[1] || 0, b[1] || 0, t),
1868
+ interpolateNum(a[2] || 0, b[2] || 0, t),
1869
+ interpolateNum(a[3] === void 0 ? 1 : a[3], b[3] === void 0 ? 1 : b[3], t)
1870
+ ];
1871
+ }
1872
+ function interpolateBeziers(paths1, paths2, progress) {
1873
+ const count = Math.max(paths1.length, paths2.length);
1874
+ const res = [];
1875
+ for (let i = 0; i < count; i++) {
1876
+ res.push(interpolateBezier(paths1[i], paths2[i], progress));
1877
+ }
1878
+ return res;
1879
+ }
1880
+ function interpolateBezier(path1, path2, progress) {
1881
+ var _a2, _b, _c, _d, _e, _f, _g, _h, _i;
1882
+ if (!path1 || !path2) return path1 || path2 || { v: [] };
1883
+ const t = Math.min(Math.max(progress, 0), 1);
1884
+ const len = Math.min(path1.v.length, path2.v.length);
1885
+ const v = [];
1886
+ const i = [];
1887
+ const o = [];
1888
+ for (let idx = 0; idx < len; idx++) {
1889
+ const v1 = path1.v[idx];
1890
+ const v2 = path2.v[idx];
1891
+ v.push(interpolateVec(v1, v2, t));
1892
+ const i1 = (_b = (_a2 = path1.i) == null ? void 0 : _a2[idx]) != null ? _b : v1;
1893
+ const i2 = (_d = (_c = path2.i) == null ? void 0 : _c[idx]) != null ? _d : v2;
1894
+ i.push(interpolateVec(i1, i2, t));
1895
+ const o1 = (_f = (_e = path1.o) == null ? void 0 : _e[idx]) != null ? _f : v1;
1896
+ const o2 = (_h = (_g = path2.o) == null ? void 0 : _g[idx]) != null ? _h : v2;
1897
+ o.push(interpolateVec(o1, o2, t));
1898
+ }
1899
+ return { v, i: i.length ? i : void 0, o: o.length ? o : void 0, c: (_i = path1.c) != null ? _i : path2.c };
1900
+ }
1901
+ function remap(value, inMin, inMax, outMin, outMax) {
1902
+ if (inMax === inMin) return outMin;
1903
+ const t = (value - inMin) / (inMax - inMin);
1904
+ return outMin + t * (outMax - outMin);
1905
+ }
1906
+ function solveCubicBezierX(p1x, p2x, x) {
1907
+ if (x <= 0) return 0;
1908
+ if (x >= 1) return 1;
1909
+ const cx = 3 * p1x;
1910
+ const bx = 3 * (p2x - p1x) - cx;
1911
+ const ax = 1 - cx - bx;
1912
+ function sampleX(t) {
1913
+ return ((ax * t + bx) * t + cx) * t;
1914
+ }
1915
+ function sampleDX(t) {
1916
+ return (3 * ax * t + 2 * bx) * t + cx;
1917
+ }
1918
+ let t2 = x;
1919
+ let t0 = 0;
1920
+ let t1 = 1;
1921
+ for (let i = 0; i < 8; i++) {
1922
+ const x2 = sampleX(t2) - x;
1923
+ if (Math.abs(x2) < 1e-6) return t2;
1924
+ const d2 = sampleDX(t2);
1925
+ if (Math.abs(d2) < 1e-6) break;
1926
+ t2 -= x2 / d2;
1927
+ }
1928
+ t2 = x;
1929
+ while (t0 < t1) {
1930
+ const x2 = sampleX(t2);
1931
+ if (Math.abs(x2 - x) < 1e-6) return t2;
1932
+ if (x > x2) t0 = t2;
1933
+ else t1 = t2;
1934
+ t2 = (t1 + t0) / 2;
1935
+ }
1936
+ return t2;
1937
+ }
1938
+ function cubicBezier(easing) {
1939
+ const [p1x, p1y, p2x, p2y] = easing;
1940
+ const cy = 3 * p1y;
1941
+ const by = 3 * (p2y - p1y) - cy;
1942
+ const ay = 1 - cy - by;
1943
+ function sampleCurveY(t) {
1944
+ return ((ay * t + by) * t + cy) * t;
1945
+ }
1946
+ return function(x) {
1947
+ return sampleCurveY(solveCubicBezierX(p1x, p2x, x));
2315
1948
  };
2316
- walk(root, "root");
2317
- return problems;
2318
1949
  }
2319
- function validateVersionStamp(doc) {
2320
- var _a2;
2321
- const version = (_a2 = getAnimatorConfig(doc)) == null ? void 0 : _a2.version;
2322
- if (version === void 0) return [];
2323
- if (parseWireVersion(version) !== void 0) return [];
2324
- return ["root.animator.version: " + JSON.stringify(version) + ' is not a version stamp ("a.b" or "a.b.c") \u2014 it reads as unstamped'];
1950
+ function lerp2(a, b, t) {
1951
+ return [a[0] + (b[0] - a[0]) * t, a[1] + (b[1] - a[1]) * t];
2325
1952
  }
2326
- function validateDocument(doc, opts) {
2327
- var _a2;
2328
- const strict = (opts == null ? void 0 : opts.strict) !== false;
2329
- const ctx = { errors: [], warnings: [], strict };
2330
- const problems = PxAnimatedSvgDocumentSchema.isValid(doc, ctx, ["root"]) ? [] : [...ctx.errors];
2331
- if (doc && typeof doc === "object") {
2332
- for (const w of validateNodeEffects(doc, { strict })) {
2333
- if (!problems.includes(w)) problems.push(w);
2334
- }
2335
- const defs = (_a2 = getAnimatorConfig(doc)) == null ? void 0 : _a2.definitions;
2336
- for (const w of validateGlyphFontRefs(doc, defs == null ? void 0 : defs.fonts)) {
2337
- if (!problems.includes(w)) problems.push(w);
2338
- }
2339
- for (const w of validateEasingRefs(doc, defs == null ? void 0 : defs.easings)) {
2340
- if (!problems.includes(w)) problems.push(w);
2341
- }
2342
- for (const w of validateVersionStamp(doc)) {
2343
- if (!problems.includes(w)) problems.push(w);
2344
- }
1953
+ function subdivideCubicBezier(p0, p1, p2, p3, t) {
1954
+ const q0 = lerp2(p0, p1, t);
1955
+ const q1 = lerp2(p1, p2, t);
1956
+ const q2 = lerp2(p2, p3, t);
1957
+ const r0 = lerp2(q0, q1, t);
1958
+ const r1 = lerp2(q1, q2, t);
1959
+ const s = lerp2(r0, r1, t);
1960
+ return {
1961
+ left: [p0, q0, r0, s],
1962
+ right: [s, r1, q2, p3]
1963
+ };
1964
+ }
1965
+ function splitEasing(easing, xFraction) {
1966
+ if (!easing) return { left: void 0, right: void 0 };
1967
+ if (xFraction <= 0) return { left: void 0, right: easing };
1968
+ if (xFraction >= 1) return { left: easing, right: void 0 };
1969
+ const [x1, y1, x2, y2] = easing;
1970
+ const t = solveCubicBezierX(x1, x2, xFraction);
1971
+ const p0 = [0, 0];
1972
+ const p1 = [x1, y1];
1973
+ const p2 = [x2, y2];
1974
+ const p3 = [1, 1];
1975
+ const { left, right } = subdivideCubicBezier(p0, p1, p2, p3, t);
1976
+ const sx = left[3][0];
1977
+ const sy = left[3][1];
1978
+ let leftEasing;
1979
+ if (sx > 1e-9 && Math.abs(sy) > 1e-9) {
1980
+ leftEasing = [
1981
+ left[1][0] / sx,
1982
+ left[1][1] / sy,
1983
+ left[2][0] / sx,
1984
+ left[2][1] / sy
1985
+ ];
2345
1986
  }
2346
- return problems;
1987
+ let rightEasing;
1988
+ const rx = 1 - sx;
1989
+ const ry = 1 - sy;
1990
+ if (rx > 1e-9 && Math.abs(ry) > 1e-9) {
1991
+ rightEasing = [
1992
+ (right[1][0] - sx) / rx,
1993
+ (right[1][1] - sy) / ry,
1994
+ (right[2][0] - sx) / rx,
1995
+ (right[2][1] - sy) / ry
1996
+ ];
1997
+ }
1998
+ return { left: leftEasing, right: rightEasing };
2347
1999
  }
2348
- var PxNodeBase = px.openObject({
2349
- // CONVENTION (SCHEMA-DESIGN R1 / issues N4): `type` is the ONE word for "what
2350
- // kind of thing is this", discriminated by its CARRIER — here the node TAG
2351
- // (`rect`, `text`), and inside a sub-object that object's kind (`fillGradient.type`,
2352
- // `fillGradient.type`, editor `preset.type`). Each sits in its own object, so
2353
- // the carrier disambiguates completely; synonyms (`cloneKind`, `presetShape`)
2354
- // would add words that all mean "type" and still need the carrier to read.
2355
- // Guarding a `type` SLOT against a wrong VALUE is the job of strict enums
2356
- // (issues V3), never of distinct key names.
2357
- type: px.string(),
2358
- // The escape hatch for elements that carry a REAL `type` attribute — `<feTurbulence
2359
- // type="fractalNoise">`, `<feFuncR type="table">`, `<feColorMatrix type="saturate">`.
2360
- // `type` is taken by the tag name, so the attribute travels here and the renderer puts
2361
- // it back (`PxAnimatorDOM.renderNode`, `PxRnRender`). Declared here — not merely
2362
- // documented — because a wire key that is not in a schema is invisible to the
2363
- // minifier's reserve list and gets renamed (MINIFICATION-BOUNDARY-PLAN.md §1.1).
2364
- domType: px.string().optional(),
2365
- // Text content of a `<text>` / `<tspan>`. Declared, so a non-string value is a schema error
2366
- // and the minifier reserves the key; `text` is NOT an alias for it and is not read anywhere.
2367
- textContent: px.string().optional(),
2368
- id: px.string().optional(),
2369
- meta: px.any().optional(),
2370
- // Player-effects bucket emitted by the Editor's lightweight design format.
2371
- // Consumed and removed by `applyPlayerEffects` before any other normalization
2372
- // (see `createAnimatorImpl`), so downstream code never sees it.
2373
- effects: PxEffectsSchema.optional(),
2374
- // `PxElementAnimation` (not just `PxAnimationDefinition`) — accepts
2375
- // string ref / array of refs / inline definition / mixed array; mirrors
2376
- // `animator.animateById` map values and what `processNode` resolves at runtime.
2377
- animate: PxElementAnimationSchema.optional(),
2378
- style: px.union([px.string(), px.record(px.union([px.string(), px.number()]))]).optional()
2379
- }, PxAttrValueSchema);
2380
- var PxNodeSchema = px.openObject(__spreadProps(__spreadValues({}, PxNodeBase._shape), {
2381
- children: px.lazy(() => px.array(PxNodeSchema), []).optional()
2382
- }), PxAttrValueSchema);
2383
- var PxSvgNodeExtra = px.object({
2384
- // `"100%"` and other SVG length strings are legal here — a number-only slot rejected
2385
- // real documents (e.g. apple-store-look-14-main.json) at the root <svg>.
2386
- width: px.union([px.number(), px.string()]).optional(),
2387
- height: px.union([px.number(), px.string()]).optional(),
2388
- viewBox: px.string().optional(),
2389
- animator: PxAnimatorConfigSchema.optional()
2390
- });
2391
- var PxAnimatedSvgDocumentSchema = px.openObject(__spreadProps(__spreadValues(__spreadValues({}, PxNodeBase._shape), PxSvgNodeExtra._shape), {
2392
- type: px.literal("svg"),
2393
- // override string → literal to require 'svg'
2394
- children: px.array(PxNodeSchema).optional()
2395
- }), PxAttrValueSchema);
2396
- var PxBezierPathSchema = implementsInterface()(px.object({
2397
- v: px.array(px.array(px.number())),
2398
- i: px.array(px.array(px.number())).optional(),
2399
- o: px.array(px.array(px.number())).optional(),
2400
- c: px.boolean().optional()
2401
- }));
2402
- function isPxElementFileFormatDeep(fileJson) {
2403
- const errors = validateDocument(fileJson, { strict: false });
2404
- return { valid: errors.length === 0, errors };
2000
+ function reverseEasing(easing) {
2001
+ if (!easing) return void 0;
2002
+ return [1 - easing[2], 1 - easing[3], 1 - easing[0], 1 - easing[1]];
2405
2003
  }
2406
-
2407
- // src/util/PxIdUtil.ts
2408
- var _idCounter = 0;
2409
- function generateUniqueId() {
2410
- const timestamp = Date.now().toString(36);
2411
- const counter = (++_idCounter).toString(36);
2412
- const random = Math.random().toString(36).substring(2, 6);
2413
- return "_px_" + timestamp + counter + random;
2004
+ function toRGBA(color) {
2005
+ const r = Math.round(color[0] * 255);
2006
+ const g = Math.round(color[1] * 255);
2007
+ const b = Math.round(color[2] * 255);
2008
+ return color.length === 4 ? "rgba(" + r + "," + g + "," + b + "," + color[3] + ")" : "rgb(" + r + "," + g + "," + b + ")";
2009
+ }
2010
+ function parseRgba(s) {
2011
+ var _a2;
2012
+ const inner = (_a2 = s.match(/rgba?\((.*)\)/)) == null ? void 0 : _a2[1];
2013
+ if (!inner) throw new Error("Invalid rgb/rgba format");
2014
+ const parts = inner.split(",").map((v) => +v.trim());
2015
+ return [parts[0] / 255, parts[1] / 255, parts[2] / 255, ...parts[3] !== void 0 ? [parts[3]] : []];
2016
+ }
2017
+ function parseHex(s) {
2018
+ const hex = s.slice(1);
2019
+ const isShort = hex.length <= 4;
2020
+ const r = isShort ? hex[0] + hex[0] : hex.slice(0, 2);
2021
+ const g = isShort ? hex[1] + hex[1] : hex.slice(2, 4);
2022
+ const b = isShort ? hex[2] + hex[2] : hex.slice(4, 6);
2023
+ const a = hex.length === 4 ? hex[3] + hex[3] : hex.length === 8 ? hex.slice(6, 8) : null;
2024
+ const result = [
2025
+ parseInt(r, 16) / 255,
2026
+ parseInt(g, 16) / 255,
2027
+ parseInt(b, 16) / 255
2028
+ ];
2029
+ if (a !== null) {
2030
+ result.push(parseInt(a, 16) / 255);
2031
+ }
2032
+ return result;
2414
2033
  }
2415
- function deepClone(value) {
2416
- if (value === null || typeof value !== "object") return value;
2417
- if (Array.isArray(value)) return value.map((item) => deepClone(item));
2418
- const obj = value;
2419
- const cloned = {};
2420
- for (const key of Object.keys(obj)) {
2421
- cloned[key] = deepClone(obj[key]);
2034
+ function parseColor(s) {
2035
+ if (!s) return void 0;
2036
+ if (Array.isArray(s)) return s;
2037
+ if (typeof s !== "string") return void 0;
2038
+ if (s.startsWith("#")) {
2039
+ return parseHex(s);
2040
+ } else if (s.startsWith("rgb")) {
2041
+ return parseRgba(s);
2042
+ } else {
2043
+ console.warn("Unsupported color format: " + s);
2422
2044
  }
2423
- return cloned;
2045
+ return void 0;
2424
2046
  }
2425
- function generateNewIds(doc) {
2047
+ var PX_COLOR_ATTR_NAMES = /* @__PURE__ */ new Set(["color", "fill", "flood-color", "lighting-color", "stop-color", "stroke"]);
2048
+ var PX_TRANSFORM_FN_NAMES = /* @__PURE__ */ new Set(["translate", "rotate", "scale", "skew"]);
2049
+ var PX_PCT_BASED_ATTR_NAMES = /* @__PURE__ */ new Set(["offset-distance", "offsetDistance"]);
2050
+ function composeTransformParts(parts, opts) {
2051
+ var _a2;
2052
+ if (!parts) return "";
2053
+ const withUnits = (_a2 = opts == null ? void 0 : opts.withUnits) != null ? _a2 : true;
2054
+ const segs = [];
2055
+ const t = parts.translate;
2056
+ const o = parts.origin;
2057
+ const r = parts.rotate;
2058
+ const k = parts.skew;
2059
+ const s = parts.scale;
2060
+ const tu = withUnits ? "px" : "";
2061
+ const ru = withUnits ? "deg" : "";
2062
+ if (t) segs.push("translate(" + t[0] + tu + "," + t[1] + tu + ")");
2063
+ if (o) segs.push("translate(" + o[0] + tu + "," + o[1] + tu + ")");
2064
+ if (r !== void 0 && r !== null) segs.push("rotate(" + r + ru + ")");
2065
+ if (k !== void 0 && k !== null) segs.push("skewX(" + k + ru + ")");
2066
+ if (s) segs.push("scale(" + s[0] + "," + s[1] + ")");
2067
+ if (o) segs.push("translate(" + -o[0] + tu + "," + -o[1] + tu + ")");
2068
+ return segs.join("");
2069
+ }
2070
+ function parseTransformParts(str2) {
2426
2071
  var _a2, _b;
2427
- const cloned = deepClone(doc);
2428
- const idMap = /* @__PURE__ */ new Map();
2429
- const hashRefAttrs = /* @__PURE__ */ new Set(["href", "xlink:href"]);
2430
- const urlRefAttrs = /* @__PURE__ */ new Set([
2431
- "fill",
2432
- "stroke",
2433
- "clip-path",
2434
- "clipPath",
2435
- "mask",
2436
- "marker",
2437
- "marker-start",
2438
- "marker-mid",
2439
- "marker-end",
2440
- "filter",
2441
- "flood-color",
2442
- "lighting-color"
2443
- ]);
2444
- const directIdRefAttrs = /* @__PURE__ */ new Set(["targetId", "boundElementId"]);
2445
- const isEffectSourceRef = (key, parentKey) => key === "source" && (parentKey === "maskedBy" || parentKey === "clone");
2446
- function collectIds(node) {
2447
- if (!node || typeof node !== "object") return;
2448
- if (node.id && typeof node.id === "string") {
2449
- const oldId = node.id;
2450
- const newId = generateUniqueId();
2451
- idMap.set(oldId, newId);
2452
- node.id = newId;
2453
- } else if (node.animate) {
2454
- node.id = generateUniqueId();
2455
- }
2456
- if (Array.isArray(node.children)) {
2457
- for (const child of node.children) {
2458
- collectIds(child);
2459
- }
2460
- }
2461
- }
2462
- function updateRefs(node, parentKey) {
2463
- if (!node || typeof node !== "object") return;
2464
- for (const [key, value] of Object.entries(node)) {
2465
- if (key === "children") {
2466
- if (Array.isArray(value)) {
2467
- for (const child of value) {
2468
- updateRefs(child);
2469
- }
2470
- }
2471
- continue;
2472
- }
2473
- if (typeof value === "string") {
2474
- if (hashRefAttrs.has(key) && value.startsWith("#")) {
2475
- const oldId = value.slice(1);
2476
- const newId = idMap.get(oldId);
2477
- if (newId) {
2478
- node[key] = "#" + newId;
2479
- }
2480
- } else if (urlRefAttrs.has(key)) {
2481
- node[key] = replaceUrlRefs(value, idMap);
2482
- } else if (directIdRefAttrs.has(key) || isEffectSourceRef(key, parentKey)) {
2483
- const hasHash = value.startsWith("#");
2484
- const newId = idMap.get(hasHash ? value.slice(1) : value);
2485
- if (newId) {
2486
- node[key] = hasHash ? "#" + newId : newId;
2487
- }
2488
- } else if (value.includes("url(#")) {
2489
- node[key] = replaceUrlRefs(value, idMap);
2490
- }
2491
- } else if (key === "style" && typeof value === "object" && value !== null) {
2492
- for (const [styleProp, styleValue] of Object.entries(value)) {
2493
- if (typeof styleValue === "string") {
2494
- value[styleProp] = replaceUrlRefs(styleValue, idMap);
2495
- }
2496
- }
2497
- } else if (typeof value === "object" && value !== null) {
2498
- updateRefs(value, key);
2499
- }
2500
- }
2501
- }
2502
- collectIds(cloned);
2503
- updateRefs(cloned);
2504
- const docAnimate = (_a2 = cloned.animator) == null ? void 0 : _a2.animateById;
2505
- if (docAnimate && typeof docAnimate === "object") {
2506
- const updatedAnimate = {};
2507
- for (const [key, anim] of Object.entries(docAnimate)) {
2508
- const hashed = key.startsWith("#");
2509
- const id = hashed ? key.slice(1) : key;
2510
- const newId = (_b = idMap.get(id)) != null ? _b : id;
2511
- updatedAnimate[hashed ? "#" + newId : newId] = anim;
2072
+ if (!str2 || typeof str2 !== "string") return void 0;
2073
+ const out = {};
2074
+ const re = /([a-zA-Z]+)\s*\(([^)]*)\)/g;
2075
+ const order = ["translate", "rotate", "skewX", "scale"];
2076
+ let lastIdx = -1;
2077
+ let m;
2078
+ while ((m = re.exec(str2)) !== null) {
2079
+ const fn = m[1];
2080
+ const idx = order.indexOf(fn);
2081
+ if (idx < 0 || idx <= lastIdx) return void 0;
2082
+ lastIdx = idx;
2083
+ const nums = m[2].split(/[\s,]+/).filter(Boolean).map(Number);
2084
+ if (nums.some((n) => Number.isNaN(n))) return void 0;
2085
+ if (fn === "translate") {
2086
+ if (nums.length < 1 || nums.length > 2) return void 0;
2087
+ out.translate = [nums[0], (_a2 = nums[1]) != null ? _a2 : 0];
2088
+ } else if (fn === "rotate") {
2089
+ if (nums.length !== 1) return void 0;
2090
+ out.rotate = nums[0];
2091
+ } else if (fn === "skewX") {
2092
+ if (nums.length !== 1) return void 0;
2093
+ out.skew = nums[0];
2094
+ } else {
2095
+ if (nums.length < 1 || nums.length > 2) return void 0;
2096
+ out.scale = [nums[0], (_b = nums[1]) != null ? _b : nums[0]];
2512
2097
  }
2513
- cloned.animator = __spreadProps(__spreadValues({}, cloned.animator), { animateById: updatedAnimate });
2514
2098
  }
2515
- return cloned;
2099
+ if (str2.replace(/([a-zA-Z]+)\s*\(([^)]*)\)/g, "").replace(/[\s,]/g, "").length) return void 0;
2100
+ return Object.keys(out).length ? out : void 0;
2516
2101
  }
2517
- function replaceUrlRefs(value, idMap) {
2518
- return value.replace(/url\(#([^)]+)\)/g, (match, oldId) => {
2519
- const newId = idMap.get(oldId);
2520
- return newId ? "url(#" + newId + ")" : match;
2521
- });
2102
+ var PX_DEFAULT_DURATION_MS = 1e3;
2103
+ function kebabToCamelCaseWord(kebab) {
2104
+ return kebab.includes("-") ? kebab.replace(/-([a-z])/g, (_, letter) => letter.toUpperCase()) : kebab;
2522
2105
  }
2523
-
2524
- // src/util/PxNodeProps.ts
2525
- var DISALLOWED_SVG_TAGS_LOWER = /* @__PURE__ */ new Set([
2526
- "script",
2527
- "foreignobject"
2528
- ]);
2529
- var URL_VALUE_ATTRS_LOWER = /* @__PURE__ */ new Set([
2530
- "href",
2531
- // <use>, <image>
2532
- "xlink:href",
2533
- // legacy <use>
2534
- "src",
2535
- // <image>
2536
- "filter",
2537
- // url(#filterId)
2538
- "clippath",
2539
- // clip-path="url(#…)"
2540
- "mask",
2541
- // url(#maskId)
2542
- "markerstart",
2543
- // marker-start="url(#…)"
2544
- "markermid",
2545
- // marker-mid="url(#…)"
2546
- "markerend"
2547
- // marker-end="url(#…)"
2106
+ function isCamelCaseWord(word) {
2107
+ return !word.includes("-") && /[a-z][A-Z]/.test(word);
2108
+ }
2109
+ var SVG_CAMEL_CASE_ATTRS = /* @__PURE__ */ new Set([
2110
+ // Transform/positioning
2111
+ "viewBox",
2112
+ "preserveAspectRatio",
2113
+ // Gradient
2114
+ "gradientUnits",
2115
+ "gradientTransform",
2116
+ "spreadMethod",
2117
+ // Pattern
2118
+ "patternUnits",
2119
+ "patternContentUnits",
2120
+ "patternTransform",
2121
+ // Clipping/masking
2122
+ "clipPathUnits",
2123
+ "maskUnits",
2124
+ "maskContentUnits",
2125
+ // Marker (SVG spec keeps these camelCase, like viewBox)
2126
+ "markerUnits",
2127
+ "markerWidth",
2128
+ "markerHeight",
2129
+ "refX",
2130
+ "refY",
2131
+ // Text
2132
+ "textLength",
2133
+ "lengthAdjust",
2134
+ "startOffset",
2135
+ // Filter
2136
+ "filterUnits",
2137
+ "primitiveUnits",
2138
+ "tableValues",
2139
+ // feFuncR/G/B/A transfer table (type="table")
2140
+ "stdDeviation",
2141
+ "baseFrequency",
2142
+ "numOctaves",
2143
+ "surfaceScale",
2144
+ "diffuseConstant",
2145
+ "specularConstant",
2146
+ "specularExponent",
2147
+ "kernelMatrix",
2148
+ "kernelUnitLength",
2149
+ "edgeMode",
2150
+ "preserveAlpha",
2151
+ "targetX",
2152
+ "targetY"
2153
+ // // Animation
2154
+ // 'attributeName',
2155
+ // 'attributeType',
2156
+ // 'calcMode',
2157
+ // 'keyTimes',
2158
+ // 'keySplines',
2159
+ // 'repeatCount',
2160
+ // 'repeatDur'
2548
2161
  ]);
2549
- var IMAGE_REF_ATTRS_LOWER = /* @__PURE__ */ new Set(["href", "xlink:href", "src"]);
2550
- var CSS_ONLY_STYLE_PROPS = /* @__PURE__ */ new Set(["mixBlendMode", "isolation"]);
2551
- var DATA_RASTER_IMAGE_RE = /^data:image\/(?:png|jpe?g|gif|webp|bmp);base64,/i;
2552
- var DATA_SVG_IMAGE_RE = /^data:image\/svg\+xml(?:;[^,]*)?,/i;
2553
- var DATA_IMAGE_BASE64_PAYLOAD_RE = /^data:image\/[^;,]*;base64,([A-Za-z0-9+/]{8})/i;
2554
- var BASE64_RASTER_MAGICS = ["iVBORw0K", "/9j/", "R0lGOD", "UklGR", "Qk"];
2555
- function isContentSniffedRasterImage(str2) {
2556
- const m = DATA_IMAGE_BASE64_PAYLOAD_RE.exec(str2);
2557
- return !!m && BASE64_RASTER_MAGICS.some((magic) => m[1].startsWith(magic));
2558
- }
2559
- function isDangerousAttrName(nameLower) {
2560
- if (nameLower.startsWith("on")) return true;
2561
- return false;
2162
+ function camelCaseToKebabWordIfNeeded(camel) {
2163
+ return SVG_CAMEL_CASE_ATTRS.has(camel) ? camel : camel.replace(/([a-z0-9])([A-Z])/g, "$1-$2").toLowerCase();
2562
2164
  }
2563
- function sanitizeAttributeValue(name, value) {
2564
- const nameLower = name.toLowerCase();
2565
- if (isDangerousAttrName(nameLower)) {
2566
- console.warn("Attribute blocked (event handler / dangerous): ", nameLower);
2567
- return void 0;
2165
+ function clamp(value, min, max) {
2166
+ return Math.max(min, Math.min(value, max));
2167
+ }
2168
+ function bezier2D_pointAt(P0, P1, P2, P3, t) {
2169
+ if (t <= 0) return [P0[0], P0[1]];
2170
+ if (t >= 1) return [P3[0], P3[1]];
2171
+ const u = 1 - t;
2172
+ const u2 = u * u;
2173
+ const u3 = u2 * u;
2174
+ const t2 = t * t;
2175
+ const t3 = t2 * t;
2176
+ const w0 = u3;
2177
+ const w1 = 3 * t * u2;
2178
+ const w2 = 3 * t2 * u;
2179
+ const w3 = t3;
2180
+ return [
2181
+ w0 * P0[0] + w1 * P1[0] + w2 * P2[0] + w3 * P3[0],
2182
+ w0 * P0[1] + w1 * P1[1] + w2 * P2[1] + w3 * P3[1]
2183
+ ];
2184
+ }
2185
+ var BEZIER_T_NUDGE = 1e-4;
2186
+ function bezier2D_derivativeAt(P0, P1, P2, P3, t) {
2187
+ const result = _bezier2D_derivativeAtRaw(P0, P1, P2, P3, t);
2188
+ if (result[0] === 0 && result[1] === 0) {
2189
+ const nudgedT = t < 0.5 ? t + BEZIER_T_NUDGE : t - BEZIER_T_NUDGE;
2190
+ return _bezier2D_derivativeAtRaw(P0, P1, P2, P3, nudgedT);
2568
2191
  }
2569
- if (nameLower === "fill" || nameLower === "stroke" || nameLower === "stopcolor") {
2570
- const str2 = String(value);
2571
- if (str2.includes("url(") && !/^url\(#[^)]+\)$/.test(str2)) {
2572
- console.warn('Attribute "' + nameLower + '" blocked: url() must be internal url(#id), got:', value);
2573
- return void 0;
2574
- }
2575
- return value;
2192
+ return result;
2193
+ }
2194
+ function _bezier2D_derivativeAtRaw(P0, P1, P2, P3, t) {
2195
+ const u = 1 - t;
2196
+ const a = 3 * u * u;
2197
+ const b = 6 * t * u;
2198
+ const c = 3 * t * t;
2199
+ return [
2200
+ a * (P1[0] - P0[0]) + b * (P2[0] - P1[0]) + c * (P3[0] - P2[0]),
2201
+ a * (P1[1] - P0[1]) + b * (P2[1] - P1[1]) + c * (P3[1] - P2[1])
2202
+ ];
2203
+ }
2204
+ function bezier2D_arcLengthLUT(P0, P1, P2, P3, steps = 100) {
2205
+ const n = steps + 1;
2206
+ const ts = new Float64Array(n);
2207
+ const ds = new Float64Array(n);
2208
+ let prev = bezier2D_pointAt(P0, P1, P2, P3, 0);
2209
+ ts[0] = 0;
2210
+ ds[0] = 0;
2211
+ let cum = 0;
2212
+ for (let i = 1; i < n; i++) {
2213
+ const t = i / steps;
2214
+ const cur = bezier2D_pointAt(P0, P1, P2, P3, t);
2215
+ const dx = cur[0] - prev[0];
2216
+ const dy = cur[1] - prev[1];
2217
+ cum += Math.sqrt(dx * dx + dy * dy);
2218
+ ts[i] = t;
2219
+ ds[i] = cum;
2220
+ prev = cur;
2576
2221
  }
2577
- if (URL_VALUE_ATTRS_LOWER.has(nameLower)) {
2578
- const str2 = String(value);
2579
- if (str2.startsWith("#")) return value;
2580
- if (/^url\(#[^)]+\)$/.test(str2)) return value;
2581
- if (IMAGE_REF_ATTRS_LOWER.has(nameLower) && (DATA_RASTER_IMAGE_RE.test(str2) || DATA_SVG_IMAGE_RE.test(str2) || isContentSniffedRasterImage(str2))) return value;
2582
- console.warn('Attribute "' + nameLower + '" blocked: must be #id, url(#id), or data:image/\u2026 URI, got:', value);
2583
- return void 0;
2222
+ return { ts, ds };
2223
+ }
2224
+ function bezier2D_tForDistance(lut, distance) {
2225
+ const { ts, ds } = lut;
2226
+ const last = ds.length - 1;
2227
+ if (distance <= 0) return ts[0];
2228
+ if (distance >= ds[last]) return ts[last];
2229
+ let lo = 1;
2230
+ let hi = last;
2231
+ while (lo < hi) {
2232
+ const mid = lo + hi >>> 1;
2233
+ if (ds[mid] < distance) lo = mid + 1;
2234
+ else hi = mid;
2584
2235
  }
2585
- return value;
2236
+ const dPrev = ds[hi - 1];
2237
+ const dCur = ds[hi];
2238
+ const span = dCur - dPrev;
2239
+ const frac = span > 0 ? (distance - dPrev) / span : 0;
2240
+ return ts[hi - 1] + frac * (ts[hi] - ts[hi - 1]);
2586
2241
  }
2587
- function resolveStyle(style, defs) {
2588
- var _a2;
2589
- if (!style) return void 0;
2590
- if (typeof style === "string") {
2591
- return (_a2 = defs == null ? void 0 : defs.styles) == null ? void 0 : _a2[style];
2242
+ function bezier2D_arcAtT(lut, t) {
2243
+ const { ts, ds } = lut;
2244
+ const last = ts.length - 1;
2245
+ if (t <= ts[0]) return ds[0];
2246
+ if (t >= ts[last]) return ds[last];
2247
+ let lo = 1, hi = last;
2248
+ while (lo < hi) {
2249
+ const mid = lo + hi >>> 1;
2250
+ if (ts[mid] < t) lo = mid + 1;
2251
+ else hi = mid;
2592
2252
  }
2593
- return style;
2253
+ const tPrev = ts[hi - 1];
2254
+ const span = ts[hi] - tPrev;
2255
+ const frac = span > 0 ? (t - tPrev) / span : 0;
2256
+ return ds[hi - 1] + frac * (ds[hi] - ds[hi - 1]);
2257
+ }
2258
+ function invertEasing(easing) {
2259
+ if (!easing) return (y) => y;
2260
+ const flipped = [easing[1], easing[0], easing[3], easing[2]];
2261
+ return cubicBezier(flipped);
2594
2262
  }
2595
- function getNormalizedProps(props) {
2263
+
2264
+ // src/util/PxNodeProps.ts
2265
+ function toDomProps(props) {
2596
2266
  const propsCopy = {};
2597
2267
  for (const rawKey of Object.keys(props)) {
2598
2268
  const key = kebabToCamelCaseWord(rawKey);
2599
2269
  if (INTERNAL_ATTRS.has(key)) continue;
2600
2270
  if (key === "style") continue;
2601
2271
  let value = props[rawKey];
2602
- if (COLOR_ATTR_NAMES.has(key) && Array.isArray(value)) {
2272
+ if (PX_COLOR_ATTR_NAMES.has(key) && Array.isArray(value)) {
2603
2273
  propsCopy[key] = toRGBA(value);
2604
2274
  } else if (key === "transform" && value !== null && typeof value === "object" && !Array.isArray(value) && !value.keyframes) {
2605
2275
  const parts = value.value && typeof value.value === "object" ? value.value : value;
2606
2276
  propsCopy[TRANSFORM_ATTR] = composeTransformParts(parts, { withUnits: false });
2607
- } else if (TRANSFORM_FN_NAMES.has(key)) {
2277
+ } else if (PX_TRANSFORM_FN_NAMES.has(key)) {
2608
2278
  if (Array.isArray(value)) {
2609
2279
  if (key === "translate") value = value.map((v) => v + "px");
2610
2280
  value = value.join(",");
@@ -2622,7 +2292,7 @@ function getNormalizedProps(props) {
2622
2292
 
2623
2293
  // src/materialize/PxMotionPath.ts
2624
2294
  function getKfTranslate(kf) {
2625
- const v = kfValue(kf);
2295
+ const v = keyframeValue(kf);
2626
2296
  if (!v) return void 0;
2627
2297
  if (Array.isArray(v) && v.length >= 2 && typeof v[0] === "number" && typeof v[1] === "number") {
2628
2298
  return [v[0], v[1]];
@@ -2632,17 +2302,17 @@ function getKfTranslate(kf) {
2632
2302
  return void 0;
2633
2303
  }
2634
2304
  function getKfTime(kf) {
2635
- return kfTime(kf);
2305
+ return keyframeTime(kf);
2636
2306
  }
2637
2307
  function getKfEasing(kf) {
2638
- return kfEasing(kf);
2308
+ return keyframeEasing(kf);
2639
2309
  }
2640
2310
  function propAnimIsMotionPath(anim) {
2641
2311
  const kfs = anim.keyframes;
2642
2312
  if (!Array.isArray(kfs)) return false;
2643
2313
  if (anim.autoOrient) return true;
2644
2314
  for (const kf of kfs) {
2645
- if (kfTangentIn(kf) || kfTangentOut(kf)) return true;
2315
+ if (keyframeTangentIn(kf) || keyframeTangentOut(kf)) return true;
2646
2316
  }
2647
2317
  return false;
2648
2318
  }
@@ -2651,8 +2321,8 @@ function getSegmentCache(prevKf, nextKf, prevPos, nextPos) {
2651
2321
  let byNext = _segmentCache.get(prevKf);
2652
2322
  const existing = byNext == null ? void 0 : byNext.get(nextKf);
2653
2323
  if (existing) return existing;
2654
- const to = kfTangentOut(prevKf);
2655
- const ti = kfTangentIn(nextKf);
2324
+ const to = keyframeTangentOut(prevKf);
2325
+ const ti = keyframeTangentIn(nextKf);
2656
2326
  const P1 = [prevPos[0] + (to ? to[0] : 0), prevPos[1] + (to ? to[1] : 0)];
2657
2327
  const P2 = [nextPos[0] + (ti ? ti[0] : 0), nextPos[1] + (ti ? ti[1] : 0)];
2658
2328
  const lut = bezier2D_arcLengthLUT(prevPos, P1, P2, nextPos);
@@ -2745,7 +2415,7 @@ function materializeMotionPathInPropAnim(anim, opts) {
2745
2415
  function unwrapAutoOrientRotations(kfs) {
2746
2416
  let prev;
2747
2417
  for (const kf of kfs) {
2748
- const v = kfValue(kf);
2418
+ const v = keyframeValue(kf);
2749
2419
  if (!v || typeof v.rotate !== "number") continue;
2750
2420
  if (prev === void 0) {
2751
2421
  prev = v.rotate;
@@ -2762,7 +2432,7 @@ function makeOutKf(time, value) {
2762
2432
  return { t: time, v: value };
2763
2433
  }
2764
2434
  function getKfValueParts(kf) {
2765
- const v = kfValue(kf);
2435
+ const v = keyframeValue(kf);
2766
2436
  if (!v || typeof v !== "object" || Array.isArray(v)) return void 0;
2767
2437
  return v;
2768
2438
  }
@@ -2824,7 +2494,7 @@ function wrappedAngleDelta(a, b) {
2824
2494
  }
2825
2495
  function insertSharpCornerStepKfIfNeeded(out, prevKf, nextKf, prevPos, nextPos, rotationTol) {
2826
2496
  const lastKf = out[out.length - 1];
2827
- const lastV = kfValue(lastKf);
2497
+ const lastV = keyframeValue(lastKf);
2828
2498
  const prevExit = lastV == null ? void 0 : lastV.rotate;
2829
2499
  if (typeof prevExit !== "number") return;
2830
2500
  const boundaryV = getKfValueParts(prevKf);
@@ -3006,7 +2676,7 @@ function walkAndMaterialize(node, opts) {
3006
2676
  }
3007
2677
 
3008
2678
  // src/animation/PxDefinitions.ts
3009
- var LOOP_JUMP_SHIFT_MS = 1;
2679
+ var PX_LOOP_JUMP_SHIFT_MS = 1;
3010
2680
  function deepEqualValue(a, b) {
3011
2681
  if (a === b) return true;
3012
2682
  if (typeof a !== typeof b || a === null || b === null || typeof a !== "object") return false;
@@ -3182,7 +2852,7 @@ function interpolateValue(propName, a, b, t) {
3182
2852
  const bPaths = (_b = b == null ? void 0 : b.paths) != null ? _b : Array.isArray(b) ? b : [];
3183
2853
  return { paths: interpolateBeziers(aPaths, bPaths, t) };
3184
2854
  }
3185
- if (COLOR_ATTR_NAMES.has(propName)) {
2855
+ if (PX_COLOR_ATTR_NAMES.has(propName)) {
3186
2856
  return interpolateColor(a || [0, 0, 0, 1], b || [0, 0, 0, 1], t);
3187
2857
  }
3188
2858
  if (propName === "transform" && typeof a === "object" && a !== null && !Array.isArray(a) && typeof b === "object" && b !== null && !Array.isArray(b)) {
@@ -3191,7 +2861,7 @@ function interpolateValue(propName, a, b, t) {
3191
2861
  if (propName === "rotate" && typeof a === "number" && typeof b === "number") {
3192
2862
  return interpolateNum(a, b, t);
3193
2863
  }
3194
- if (TRANSFORM_FN_NAMES.has(propName) || propName === "stroke-dasharray" || propName === "strokeDasharray") {
2864
+ if (PX_TRANSFORM_FN_NAMES.has(propName) || propName === "stroke-dasharray" || propName === "strokeDasharray") {
3195
2865
  return interpolateVec(a || [], b || [], t);
3196
2866
  }
3197
2867
  return interpolateNum(+(a || 0), +(b || 0), t);
@@ -3243,8 +2913,8 @@ function expandLoopKeyframes(propName, keyframes, loop, duration) {
3243
2913
  relT: (kf.t - segStartT) / segDuration,
3244
2914
  v: kf.v,
3245
2915
  e: kf.e,
3246
- tangentIn: kfTangentIn(kf),
3247
- tangentOut: kfTangentOut(kf)
2916
+ tangentIn: keyframeTangentIn(kf),
2917
+ tangentOut: keyframeTangentOut(kf)
3248
2918
  }));
3249
2919
  const fullReps = Math.floor(fillDuration / segDuration);
3250
2920
  const remainder = fillDuration - fullReps * segDuration;
@@ -3310,7 +2980,7 @@ function expandLoopKeyframes(propName, keyframes, loop, duration) {
3310
2980
  }
3311
2981
  }
3312
2982
  const pushed = {
3313
- t: repStart + entry.relT * segDuration + (isBoundary ? LOOP_JUMP_SHIFT_MS : 0),
2983
+ t: repStart + entry.relT * segDuration + (isBoundary ? PX_LOOP_JUMP_SHIFT_MS : 0),
3314
2984
  v: entry.v,
3315
2985
  e: i < entries.length - 1 ? entry.e : void 0
3316
2986
  };
@@ -3397,14 +3067,14 @@ function normalizeKeyframes(propName, propAnim, duration, defs) {
3397
3067
  const keyframes = propAnim.keyframes || [];
3398
3068
  const normalized = [];
3399
3069
  for (const kf of keyframes) {
3400
- const timePct = kfTime(kf);
3401
- let value = kfValue(kf);
3402
- const easing = kfEasing(kf);
3070
+ const timePct = keyframeTime(kf);
3071
+ let value = keyframeValue(kf);
3072
+ const easing = keyframeEasing(kf);
3403
3073
  if (propName === "d") {
3404
3074
  value = normalizePathValue(value);
3405
3075
  }
3406
3076
  const propNameKebab = isCamelCaseWord(propName) ? camelCaseToKebabWordIfNeeded(propName) : propName;
3407
- if (COLOR_ATTR_NAMES.has(propNameKebab)) {
3077
+ if (PX_COLOR_ATTR_NAMES.has(propNameKebab)) {
3408
3078
  value = (_a2 = parseColor(value)) != null ? _a2 : value;
3409
3079
  }
3410
3080
  const normKf = {
@@ -3412,8 +3082,8 @@ function normalizeKeyframes(propName, propAnim, duration, defs) {
3412
3082
  v: value,
3413
3083
  e: resolveEasing(easing, defs)
3414
3084
  };
3415
- const tIn = kfTangentIn(kf);
3416
- const tOut = kfTangentOut(kf);
3085
+ const tIn = keyframeTangentIn(kf);
3086
+ const tOut = keyframeTangentOut(kf);
3417
3087
  if (tIn) normKf.tangentIn = tIn;
3418
3088
  if (tOut) normKf.tangentOut = tOut;
3419
3089
  normalized.push(normKf);
@@ -3445,17 +3115,17 @@ function materializeInternalLoopsInPropAnim(propName, propAnim, duration) {
3445
3115
  const rawKfs = propAnim.keyframes;
3446
3116
  if (!Array.isArray(rawKfs) || rawKfs.length < 2) return propAnim;
3447
3117
  const propNameKebab = isCamelCaseWord(propName) ? camelCaseToKebabWordIfNeeded(propName) : propName;
3448
- const isColor = COLOR_ATTR_NAMES.has(propNameKebab);
3118
+ const isColor = PX_COLOR_ATTR_NAMES.has(propNameKebab);
3449
3119
  const kfs = rawKfs.map((kf) => {
3450
3120
  var _a2;
3451
- const t = kfTime(kf);
3452
- let v = kfValue(kf);
3121
+ const t = keyframeTime(kf);
3122
+ let v = keyframeValue(kf);
3453
3123
  if (propName === "d") v = normalizePathValue(v);
3454
3124
  if (isColor) v = (_a2 = parseColor(v)) != null ? _a2 : v;
3455
- const e = kfEasing(kf);
3125
+ const e = keyframeEasing(kf);
3456
3126
  const out2 = { t, v, e };
3457
- const tIn = kfTangentIn(kf);
3458
- const tOut = kfTangentOut(kf);
3127
+ const tIn = keyframeTangentIn(kf);
3128
+ const tOut = keyframeTangentOut(kf);
3459
3129
  if (tIn) out2.tangentIn = tIn;
3460
3130
  if (tOut) out2.tangentOut = tOut;
3461
3131
  return out2;
@@ -3520,7 +3190,7 @@ function mergeStaticTransformIntoAnimDef(animDef, staticTransform) {
3520
3190
  }
3521
3191
  return animDef;
3522
3192
  }
3523
- const channels = Object.keys(animDef).filter((k) => TRANSFORM_FN_NAMES.has(k));
3193
+ const channels = Object.keys(animDef).filter((k) => PX_TRANSFORM_FN_NAMES.has(k));
3524
3194
  if (channels.length !== 1) return animDef;
3525
3195
  const ch = channels[0];
3526
3196
  const chAnim = animDef[ch];
@@ -3549,14 +3219,12 @@ function normalizeAnimationDefinition(animDef, duration, defs, engine = PxTimeli
3549
3219
  }
3550
3220
  return normalized;
3551
3221
  }
3552
- function getNormalizedBindings(doc, engine = PxTimelineEngine.native) {
3222
+ function normalizeBindings(doc, engine = PxTimelineEngine.native) {
3553
3223
  const animatorConfig = getAnimatorConfig(doc) || {};
3554
- const defs = getDefs(doc);
3224
+ const defs = getDefinitions(doc);
3555
3225
  const duration = animatorConfig.duration || 1e3;
3556
3226
  const bindings = [];
3557
- const processAnimation = (id, animate, staticTransform) => {
3558
- if (!animate) return null;
3559
- const animDefs = resolveElementAnimation(animate, defs);
3227
+ const processAnimation = (id, animDefs, staticTransform) => {
3560
3228
  if (animDefs.length === 0) return null;
3561
3229
  const merged = mergeStaticTransformIntoAnimDef(mergeAnimationDefinitions(animDefs), staticTransform);
3562
3230
  const normalizedAnim = normalizeAnimationDefinition(merged, duration, defs, engine);
@@ -3569,7 +3237,9 @@ function getNormalizedBindings(doc, engine = PxTimelineEngine.native) {
3569
3237
  const docBindings = getBindings(doc);
3570
3238
  if (docBindings) {
3571
3239
  for (const binding of docBindings) {
3572
- const normalized = processAnimation(binding.id, binding.animate);
3240
+ const id = binding.target.startsWith("#") ? binding.target.slice(1) : binding.target;
3241
+ const animDefs = binding.animateWith.map((name) => resolveAnimation(name, defs)).filter((d) => !!d);
3242
+ const normalized = processAnimation(id, animDefs);
3573
3243
  if (normalized) bindings.push(normalized);
3574
3244
  }
3575
3245
  }
@@ -3578,7 +3248,7 @@ function getNormalizedBindings(doc, engine = PxTimelineEngine.native) {
3578
3248
  if (inlineAnim && Object.keys(inlineAnim).length > 0) {
3579
3249
  const nodeId = node.id || generateElementId();
3580
3250
  node.id = nodeId;
3581
- const normalized = processAnimation(nodeId, inlineAnim, node.transform);
3251
+ const normalized = processAnimation(nodeId, resolveElementAnimation(inlineAnim, defs), node.transform);
3582
3252
  if (normalized) bindings.push(normalized);
3583
3253
  }
3584
3254
  if (node.children) {
@@ -3621,7 +3291,7 @@ function calcPropertyValue(propName, propAnim, progress) {
3621
3291
  const { prevKf, nextKf } = getKeyframesPair(keyframes, progress);
3622
3292
  let localProgress = prevKf === nextKf ? 0 : remap(progress, (_a2 = prevKf.t) != null ? _a2 : 0, (_b = nextKf.t) != null ? _b : 0, 0, 1);
3623
3293
  localProgress = clamp(localProgress, 0, 1);
3624
- const easing = kfEasing(prevKf);
3294
+ const easing = keyframeEasing(prevKf);
3625
3295
  if (easing && Array.isArray(easing)) {
3626
3296
  try {
3627
3297
  localProgress = cubicBezier(easing)(localProgress);
@@ -3640,7 +3310,7 @@ function calcPropertyValue(propName, propAnim, progress) {
3640
3310
  nextPaths,
3641
3311
  localProgress
3642
3312
  ).map((bz) => bezierToSvgPath(bz)).join("");
3643
- } else if (COLOR_ATTR_NAMES.has(cssAttrName)) {
3313
+ } else if (PX_COLOR_ATTR_NAMES.has(cssAttrName)) {
3644
3314
  cssValue = toRGBA(interpolateColor(
3645
3315
  prevV || [0, 0, 0, 1],
3646
3316
  nextV || [0, 0, 0, 1],
@@ -3680,273 +3350,61 @@ function calcPropertyValue(propName, propAnim, progress) {
3680
3350
  nextKf,
3681
3351
  [+prevTr[0], +prevTr[1]],
3682
3352
  [+nextTr[0], +nextTr[1]],
3683
- localProgress,
3684
- !!propAnim.autoOrient
3685
- );
3686
- partsResult.translate = [sample.translate[0], sample.translate[1]];
3687
- if (sample.rotateDeg !== void 0) partsResult.rotate = sample.rotateDeg;
3688
- }
3689
- }
3690
- cssValue = composeTransformParts(partsResult, { withUnits: false });
3691
- cssAttrName = "transform";
3692
- } else if (cssAttrName === "translate") {
3693
- const v = interpolateVec(
3694
- prevV || [0, 0],
3695
- nextV || [0, 0],
3696
- localProgress
3697
- );
3698
- cssValue = "translate(" + v.join(",") + ")";
3699
- cssAttrName = "transform";
3700
- } else if (cssAttrName === "rotate") {
3701
- const v = interpolateNum(
3702
- +(prevV || 0),
3703
- +(nextV || 0),
3704
- localProgress
3705
- );
3706
- cssValue = "rotate(" + v + ")";
3707
- cssAttrName = "transform";
3708
- } else if (cssAttrName === "scale") {
3709
- const v = interpolateVec(
3710
- prevV || [1, 1],
3711
- nextV || [1, 1],
3712
- localProgress
3713
- );
3714
- cssValue = "scale(" + v.join(",") + ")";
3715
- cssAttrName = "transform";
3716
- } else {
3717
- const num2 = interpolateNum(
3718
- +(prevV || 0),
3719
- +(nextV || 0),
3720
- localProgress
3721
- );
3722
- cssValue = num2;
3723
- }
3724
- if (PCT_BASED_ATTR_NAMES.has(cssAttrName) && typeof cssValue === "number") {
3725
- cssValue = cssValue * 100 + "%";
3726
- }
3727
- return { k: cssAttrName, v: cssValue === null ? "" : "" + cssValue };
3728
- }
3729
- function calcAnimationValues(animDef, progress) {
3730
- const result = {};
3731
- for (const [propName, propAnim] of Object.entries(animDef)) {
3732
- const computed = calcPropertyValue(propName, propAnim, progress);
3733
- if (computed) {
3734
- result[computed.k] = computed.v;
3735
- }
3736
- }
3737
- return result;
3738
- }
3739
-
3740
- // src/util/PxNodeCloneUtil.ts
3741
- function deepClonePxNode(value) {
3742
- if (value === null || typeof value !== "object") return value;
3743
- if (Array.isArray(value)) return value.map(deepClonePxNode);
3744
- const out = {};
3745
- for (const k of Object.keys(value)) out[k] = deepClonePxNode(value[k]);
3746
- return out;
3747
- }
3748
- function regenerateIdsAndRewriteRefs(root, genId3) {
3749
- const oldToNew = /* @__PURE__ */ new Map();
3750
- const walkAssign = (n) => {
3751
- var _a2;
3752
- if (typeof n.id === "string") {
3753
- const newId = genId3();
3754
- oldToNew.set(n.id, newId);
3755
- n.id = newId;
3756
- }
3757
- (_a2 = n.children) == null ? void 0 : _a2.forEach(walkAssign);
3758
- };
3759
- walkAssign(root);
3760
- const rewriteUrl = (s) => s.replace(/url\(#([^)]+)\)/g, (m, oldId) => {
3761
- const newId = oldToNew.get(oldId);
3762
- return newId ? "url(#" + newId + ")" : m;
3763
- });
3764
- const walkRewrite = (n) => {
3765
- var _a2;
3766
- if (typeof n.href === "string" && n.href.startsWith("#")) {
3767
- const newId = oldToNew.get(n.href.slice(1));
3768
- if (newId) n.href = "#" + newId;
3769
- }
3770
- for (const k of Object.keys(n)) {
3771
- if (k === "children" || k === "effects" || k === "meta" || k === "animate" || k === "href" || k === "id") continue;
3772
- const v = n[k];
3773
- if (typeof v === "string" && v.indexOf("url(#") !== -1) {
3774
- n[k] = rewriteUrl(v);
3775
- }
3776
- }
3777
- (_a2 = n.children) == null ? void 0 : _a2.forEach(walkRewrite);
3778
- };
3779
- walkRewrite(root);
3780
- return oldToNew;
3781
- }
3782
- function toFiniteNum(v) {
3783
- const n = typeof v === "number" ? v : typeof v === "string" ? parseFloat(v) : NaN;
3784
- return Number.isFinite(n) ? n : 0;
3785
- }
3786
- function applyUseOffsetToG(gNode) {
3787
- var _a2;
3788
- const x = toFiniteNum(gNode.x);
3789
- const y = toFiniteNum(gNode.y);
3790
- delete gNode.x;
3791
- delete gNode.y;
3792
- if (!x && !y) return gNode;
3793
- const offset = "translate(" + x + "," + y + ")";
3794
- const carriesTransform = gNode.transform !== void 0 || gNode.animate !== void 0;
3795
- if (carriesTransform) {
3796
- const inner = { type: "g", transform: offset, children: (_a2 = gNode.children) != null ? _a2 : [] };
3797
- gNode.children = [inner];
3798
- } else {
3799
- gNode.transform = offset;
3800
- }
3801
- return gNode;
3802
- }
3803
-
3804
- // src/materialize/PxAnimatorUseMaterializer.ts
3805
- function materializeAnimatedUseInstances(root) {
3806
- var _a2;
3807
- const idMap = buildIdMap(root);
3808
- const animatedIds = computeAnimatedSubtreeIds(root, idMap);
3809
- if (animatedIds.size === 0) return root;
3810
- let idCounter = 0;
3811
- const genId3 = () => "_lw_use_mat_" + ++idCounter;
3812
- const rootViewport = readRootViewport(root);
3813
- const defsCollector = [];
3814
- const walked = walkAndMaterialize2(root, idMap, animatedIds, genId3, defsCollector, rootViewport);
3815
- if (defsCollector.length === 0) return walked;
3816
- const defsNode = { type: "defs", children: defsCollector };
3817
- const newChildren = [...(_a2 = walked.children) != null ? _a2 : [], defsNode];
3818
- return __spreadProps(__spreadValues({}, walked), { children: newChildren });
3819
- }
3820
- function readRootViewport(root) {
3821
- const vb = parseViewBox(root.viewBox);
3822
- if (vb) return [vb[2], vb[3]];
3823
- const w = numericAttr(root.width);
3824
- const h = numericAttr(root.height);
3825
- if (w !== void 0 && h !== void 0) return [w, h];
3826
- return [1, 1];
3827
- }
3828
- function numericAttr(v) {
3829
- if (typeof v === "number") return v;
3830
- if (typeof v === "string") {
3831
- const n = parseFloat(v);
3832
- return Number.isFinite(n) ? n : void 0;
3833
- }
3834
- return void 0;
3835
- }
3836
- function buildIdMap(root) {
3837
- const map = /* @__PURE__ */ new Map();
3838
- const visit = (n) => {
3839
- var _a2;
3840
- if (typeof n.id === "string") map.set(n.id, n);
3841
- (_a2 = n.children) == null ? void 0 : _a2.forEach(visit);
3842
- };
3843
- visit(root);
3844
- return map;
3845
- }
3846
- function computeAnimatedSubtreeIds(root, idMap) {
3847
- const cache = /* @__PURE__ */ new WeakMap();
3848
- const result = /* @__PURE__ */ new Set();
3849
- const hasAnim = (n, visiting) => {
3850
- const cached = cache.get(n);
3851
- if (cached !== void 0) return cached;
3852
- if (visiting.has(n)) return false;
3853
- visiting.add(n);
3854
- let r = false;
3855
- if (n.animate && typeof n.animate === "object" && !Array.isArray(n.animate)) {
3856
- for (const _ in n.animate) {
3857
- r = true;
3858
- break;
3859
- }
3860
- }
3861
- if (!r && n.children) {
3862
- for (const ch of n.children) {
3863
- if (hasAnim(ch, visiting)) {
3864
- r = true;
3865
- break;
3866
- }
3353
+ localProgress,
3354
+ !!propAnim.autoOrient
3355
+ );
3356
+ partsResult.translate = [sample.translate[0], sample.translate[1]];
3357
+ if (sample.rotateDeg !== void 0) partsResult.rotate = sample.rotateDeg;
3867
3358
  }
3868
3359
  }
3869
- if (!r && n.type === "use" && typeof n.href === "string") {
3870
- const targetId = stripHash(n.href);
3871
- const target = targetId ? idMap.get(targetId) : void 0;
3872
- if (target) r = hasAnim(target, visiting);
3873
- }
3874
- visiting.delete(n);
3875
- cache.set(n, r);
3876
- return r;
3877
- };
3878
- for (const [id, node] of idMap) {
3879
- if (hasAnim(node, /* @__PURE__ */ new Set())) result.add(id);
3360
+ cssValue = composeTransformParts(partsResult, { withUnits: false });
3361
+ cssAttrName = "transform";
3362
+ } else if (cssAttrName === "translate") {
3363
+ const v = interpolateVec(
3364
+ prevV || [0, 0],
3365
+ nextV || [0, 0],
3366
+ localProgress
3367
+ );
3368
+ cssValue = "translate(" + v.join(",") + ")";
3369
+ cssAttrName = "transform";
3370
+ } else if (cssAttrName === "rotate") {
3371
+ const v = interpolateNum(
3372
+ +(prevV || 0),
3373
+ +(nextV || 0),
3374
+ localProgress
3375
+ );
3376
+ cssValue = "rotate(" + v + ")";
3377
+ cssAttrName = "transform";
3378
+ } else if (cssAttrName === "scale") {
3379
+ const v = interpolateVec(
3380
+ prevV || [1, 1],
3381
+ nextV || [1, 1],
3382
+ localProgress
3383
+ );
3384
+ cssValue = "scale(" + v.join(",") + ")";
3385
+ cssAttrName = "transform";
3386
+ } else {
3387
+ const num = interpolateNum(
3388
+ +(prevV || 0),
3389
+ +(nextV || 0),
3390
+ localProgress
3391
+ );
3392
+ cssValue = num;
3880
3393
  }
3881
- return result;
3882
- }
3883
- function stripHash(href) {
3884
- if (typeof href !== "string") return void 0;
3885
- return href.startsWith("#") ? href.slice(1) : href;
3886
- }
3887
- function materializeOneUse(useNode, target, idMap, animatedIds, genId3, defsCollector, rootViewport) {
3888
- var _a2, _b, _c, _d;
3889
- const clone2 = deepClonePxNode(target);
3890
- regenerateIdsAndRewriteRefs(clone2, genId3);
3891
- const symbolViewBox = clone2.type === "symbol" ? parseViewBox(clone2.viewBox) : void 0;
3892
- const useW = (_b = (_a2 = numericAttr(useNode.width)) != null ? _a2 : symbolViewBox == null ? void 0 : symbolViewBox[2]) != null ? _b : rootViewport[0];
3893
- const useH = (_d = (_c = numericAttr(useNode.height)) != null ? _c : symbolViewBox == null ? void 0 : symbolViewBox[3]) != null ? _d : rootViewport[1];
3894
- const rewrittenClone = clone2.type === "symbol" ? rewriteSymbolRootToGroup(clone2, genId3, defsCollector, useW, useH) : clone2;
3895
- const materializedClone = walkAndMaterialize2(rewrittenClone, idMap, animatedIds, genId3, defsCollector, rootViewport);
3896
- const newNode = __spreadProps(__spreadValues({}, useNode), { type: "g", children: [materializedClone] });
3897
- delete newNode.href;
3898
- delete newNode.width;
3899
- delete newNode.height;
3900
- return applyUseOffsetToG(newNode);
3901
- }
3902
- function rewriteSymbolRootToGroup(symbolNode, genId3, defsCollector, useW, useH) {
3903
- const viewBox = parseViewBox(symbolNode.viewBox);
3904
- const g = __spreadProps(__spreadValues({}, symbolNode), { type: "g" });
3905
- delete g.viewBox;
3906
- delete g.preserveAspectRatio;
3907
- delete g.width;
3908
- delete g.height;
3909
- if (!viewBox) return g;
3910
- const [vbX, vbY, vbW, vbH] = viewBox;
3911
- const scale = vbW > 0 && vbH > 0 ? Math.min(useW / vbW, useH / vbH) : 1;
3912
- const xOff = (useW - vbW * scale) / 2;
3913
- const yOff = (useH - vbH * scale) / 2;
3914
- const parts = [];
3915
- if (xOff !== 0 || yOff !== 0) parts.push("translate(" + xOff + "," + yOff + ")");
3916
- if (scale !== 1) parts.push("scale(" + scale + ")");
3917
- if (vbX !== 0 || vbY !== 0) parts.push("translate(" + -vbX + "," + -vbY + ")");
3918
- if (parts.length) g.transform = parts.join("");
3919
- const clipId = genId3();
3920
- defsCollector.push({
3921
- type: "clipPath",
3922
- id: clipId,
3923
- children: [{ type: "rect", x: vbX, y: vbY, width: vbW, height: vbH }]
3924
- });
3925
- g.clipPath = "url(#" + clipId + ")";
3926
- return g;
3927
- }
3928
- function parseViewBox(v) {
3929
- if (typeof v !== "string") return void 0;
3930
- const parts = v.trim().split(/[\s,]+/).map(Number);
3931
- if (parts.length < 4 || parts.some((n) => !Number.isFinite(n))) return void 0;
3932
- return [parts[0], parts[1], parts[2], parts[3]];
3394
+ if (PX_PCT_BASED_ATTR_NAMES.has(cssAttrName) && typeof cssValue === "number") {
3395
+ cssValue = cssValue * 100 + "%";
3396
+ }
3397
+ return { k: cssAttrName, v: cssValue === null ? "" : "" + cssValue };
3933
3398
  }
3934
- function walkAndMaterialize2(node, idMap, animatedIds, genId3, defsCollector, rootViewport) {
3935
- if (node.type === "use" && typeof node.href === "string") {
3936
- const targetId = stripHash(node.href);
3937
- if (targetId && animatedIds.has(targetId)) {
3938
- const target = idMap.get(targetId);
3939
- if (target) return materializeOneUse(node, target, idMap, animatedIds, genId3, defsCollector, rootViewport);
3399
+ function calcAnimationValues(animDef, progress) {
3400
+ const result = {};
3401
+ for (const [propName, propAnim] of Object.entries(animDef)) {
3402
+ const computed = calcPropertyValue(propName, propAnim, progress);
3403
+ if (computed) {
3404
+ result[computed.k] = computed.v;
3940
3405
  }
3941
3406
  }
3942
- if (!node.children) return node;
3943
- let changed = false;
3944
- const newChildren = node.children.map((ch) => {
3945
- const m = walkAndMaterialize2(ch, idMap, animatedIds, genId3, defsCollector, rootViewport);
3946
- if (m !== ch) changed = true;
3947
- return m;
3948
- });
3949
- return changed ? __spreadProps(__spreadValues({}, node), { children: newChildren }) : node;
3407
+ return result;
3950
3408
  }
3951
3409
 
3952
3410
  // src/effects/shared/transformParts.ts
@@ -4117,11 +3575,75 @@ function wrapOrigin(inner, raw, invert) {
4117
3575
  return inner;
4118
3576
  }
4119
3577
 
3578
+ // src/util/PxNodeCloneUtil.ts
3579
+ function deepClonePxNode(value) {
3580
+ if (value === null || typeof value !== "object") return value;
3581
+ if (Array.isArray(value)) return value.map(deepClonePxNode);
3582
+ const out = {};
3583
+ for (const k of Object.keys(value)) out[k] = deepClonePxNode(value[k]);
3584
+ return out;
3585
+ }
3586
+ function regenerateIdsAndRewriteRefs(root, genId3) {
3587
+ const oldToNew = /* @__PURE__ */ new Map();
3588
+ const walkAssign = (n) => {
3589
+ var _a2;
3590
+ if (typeof n.id === "string") {
3591
+ const newId = genId3();
3592
+ oldToNew.set(n.id, newId);
3593
+ n.id = newId;
3594
+ }
3595
+ (_a2 = n.children) == null ? void 0 : _a2.forEach(walkAssign);
3596
+ };
3597
+ walkAssign(root);
3598
+ const rewriteUrl = (s) => s.replace(/url\(#([^)]+)\)/g, (m, oldId) => {
3599
+ const newId = oldToNew.get(oldId);
3600
+ return newId ? "url(#" + newId + ")" : m;
3601
+ });
3602
+ const walkRewrite = (n) => {
3603
+ var _a2;
3604
+ if (typeof n.href === "string" && n.href.startsWith("#")) {
3605
+ const newId = oldToNew.get(n.href.slice(1));
3606
+ if (newId) n.href = "#" + newId;
3607
+ }
3608
+ for (const k of Object.keys(n)) {
3609
+ if (k === "children" || k === "effects" || k === "meta" || k === "animate" || k === "href" || k === "id") continue;
3610
+ const v = n[k];
3611
+ if (typeof v === "string" && v.indexOf("url(#") !== -1) {
3612
+ n[k] = rewriteUrl(v);
3613
+ }
3614
+ }
3615
+ (_a2 = n.children) == null ? void 0 : _a2.forEach(walkRewrite);
3616
+ };
3617
+ walkRewrite(root);
3618
+ return oldToNew;
3619
+ }
3620
+ function toFiniteNum(v) {
3621
+ const n = typeof v === "number" ? v : typeof v === "string" ? parseFloat(v) : NaN;
3622
+ return Number.isFinite(n) ? n : 0;
3623
+ }
3624
+ function applyUseOffsetToG(gNode) {
3625
+ var _a2;
3626
+ const x = toFiniteNum(gNode.x);
3627
+ const y = toFiniteNum(gNode.y);
3628
+ delete gNode.x;
3629
+ delete gNode.y;
3630
+ if (!x && !y) return gNode;
3631
+ const offset = "translate(" + x + "," + y + ")";
3632
+ const carriesTransform = gNode.transform !== void 0 || gNode.animate !== void 0;
3633
+ if (carriesTransform) {
3634
+ const inner = { type: "g", transform: offset, children: (_a2 = gNode.children) != null ? _a2 : [] };
3635
+ gNode.children = [inner];
3636
+ } else {
3637
+ gNode.transform = offset;
3638
+ }
3639
+ return gNode;
3640
+ }
3641
+
4120
3642
  // src/effects/shared/util.ts
4121
3643
  function genId(ctx, prefix) {
4122
3644
  return "_lw_" + prefix + "_" + ctx.nextId++;
4123
3645
  }
4124
- function stripHash2(href) {
3646
+ function stripHash(href) {
4125
3647
  return typeof href === "string" ? href.replace(/^#/, "") : void 0;
4126
3648
  }
4127
3649
  function indexById(node, map) {
@@ -4143,7 +3665,7 @@ function regenerateIdsInClone(root, ctx) {
4143
3665
  function identifyContentRefTargets(node, ctx, allocator) {
4144
3666
  var _a2, _b, _c;
4145
3667
  if (node.type === "use" && ((_b = (_a2 = node.effects) == null ? void 0 : _a2.clone) == null ? void 0 : _b.without) === "translate") {
4146
- const sourceId = stripHash2(node.effects.clone.source);
3668
+ const sourceId = stripHash(node.effects.clone.source);
4147
3669
  if (typeof sourceId === "string" && sourceId && !ctx.contentRefInnerIds.has(sourceId)) {
4148
3670
  ctx.contentRefInnerIds.set(sourceId, allocator(sourceId));
4149
3671
  }
@@ -4434,11 +3956,11 @@ function buildStopChildren(stops, ctx) {
4434
3956
  const loopFromSource = read.loop;
4435
3957
  let stopCount = 0;
4436
3958
  for (const kf of kfs) {
4437
- const v = kfValue(kf);
3959
+ const v = keyframeValue(kf);
4438
3960
  if (Array.isArray(v) && v.length > stopCount) stopCount = v.length;
4439
3961
  }
4440
3962
  if (!stopCount) return [];
4441
- const firstKfValue = kfValue(kfs[0]);
3963
+ const firstKfValue = keyframeValue(kfs[0]);
4442
3964
  const baselineStops = [];
4443
3965
  for (let i = 0; i < stopCount; i++) {
4444
3966
  const s = (_b = (_a2 = firstKfValue == null ? void 0 : firstKfValue[i]) != null ? _a2 : prevDefinedStop(kfs, 0, i)) != null ? _b : { offset: i / Math.max(1, stopCount - 1), color: "#000000" };
@@ -4459,11 +3981,11 @@ function animatedStopNode(baseline, kfs, stopIdx, _ctx, loop) {
4459
3981
  const offsetKfs = [];
4460
3982
  let offsetVaries = false;
4461
3983
  for (const kf of kfs) {
4462
- const t = kfTime(kf);
4463
- const arr = kfValue(kf);
3984
+ const t = keyframeTime(kf);
3985
+ const arr = keyframeValue(kf);
4464
3986
  const sliced = (_a2 = arr == null ? void 0 : arr[stopIdx]) != null ? _a2 : prevDefinedStop(kfs, kfs.indexOf(kf), stopIdx);
4465
3987
  if (!sliced) continue;
4466
- const easing = kfEasing(kf);
3988
+ const easing = keyframeEasing(kf);
4467
3989
  const colorOut = { time: t, value: sliced.color };
4468
3990
  if (easing !== void 0) colorOut.easing = easing;
4469
3991
  colorKfs.push(colorOut);
@@ -4491,11 +4013,11 @@ function animatedStopNode(baseline, kfs, stopIdx, _ctx, loop) {
4491
4013
  }
4492
4014
  function prevDefinedStop(kfs, fromIdx, stopIdx) {
4493
4015
  for (let i = fromIdx; i >= 0; i--) {
4494
- const arr = kfValue(kfs[i]);
4016
+ const arr = keyframeValue(kfs[i]);
4495
4017
  if (arr == null ? void 0 : arr[stopIdx]) return arr[stopIdx];
4496
4018
  }
4497
4019
  for (let i = fromIdx + 1; i < kfs.length; i++) {
4498
- const arr = kfValue(kfs[i]);
4020
+ const arr = keyframeValue(kfs[i]);
4499
4021
  if (arr == null ? void 0 : arr[stopIdx]) return arr[stopIdx];
4500
4022
  }
4501
4023
  return void 0;
@@ -4532,7 +4054,7 @@ function pathString(v) {
4532
4054
  // src/effects/clipping/maskedByEffect.ts
4533
4055
  function applyMaskedByEffect(node, fx, transformBy, ctx) {
4534
4056
  if (!fx) return node;
4535
- const sourceId = stripHash2(fx.source);
4057
+ const sourceId = stripHash(fx.source);
4536
4058
  if (!sourceId) {
4537
4059
  ctx.errors.push("maskedBy.source missing \u2014 cannot build mask");
4538
4060
  return node;
@@ -4809,7 +4331,7 @@ function collectMaskAncestorChains(root, ctx) {
4809
4331
  const interestingNodes = /* @__PURE__ */ new Set();
4810
4332
  const collectInterestingNodes = (n) => {
4811
4333
  var _a2, _b;
4812
- const maskSourceId = stripHash2((_b = (_a2 = n.effects) == null ? void 0 : _a2.maskedBy) == null ? void 0 : _b.source);
4334
+ const maskSourceId = stripHash((_b = (_a2 = n.effects) == null ? void 0 : _a2.maskedBy) == null ? void 0 : _b.source);
4813
4335
  if (typeof maskSourceId === "string") {
4814
4336
  interestingNodes.add(n);
4815
4337
  const sourceNode = ctx.idMap.get(maskSourceId);
@@ -4889,7 +4411,7 @@ function parseTranslateOnlyFromString(s, ctx) {
4889
4411
  // src/effects/reference/refEffect.ts
4890
4412
  function applyRefHref(node, clone2, ctx) {
4891
4413
  if (!clone2) return;
4892
- const sourceId = stripHash2(clone2.source);
4414
+ const sourceId = stripHash(clone2.source);
4893
4415
  if (!sourceId) {
4894
4416
  if (clone2.without === PxCloneWithout.translate) ctx.errors.push("clone: content ref missing `source`");
4895
4417
  return;
@@ -5035,7 +4557,7 @@ function applyAllRetimeEffects(root, ctx) {
5035
4557
  if (!n) return;
5036
4558
  if (n !== site && readCloneRetime(n)) count++;
5037
4559
  if (n.type === "use" && n.href) {
5038
- const id = stripHash2(n.href);
4560
+ const id = stripHash(n.href);
5039
4561
  if (id && !visited.has(id)) {
5040
4562
  visited.add(id);
5041
4563
  walk(ctx.idMap.get(id));
@@ -5043,7 +4565,7 @@ function applyAllRetimeEffects(root, ctx) {
5043
4565
  }
5044
4566
  (_a2 = n.children) == null ? void 0 : _a2.forEach(walk);
5045
4567
  };
5046
- const rootId = stripHash2(site.href);
4568
+ const rootId = stripHash(site.href);
5047
4569
  if (rootId) {
5048
4570
  visited.add(rootId);
5049
4571
  walk(ctx.idMap.get(rootId));
@@ -5064,7 +4586,7 @@ function applyAllRetimeEffects(root, ctx) {
5064
4586
  }
5065
4587
  }
5066
4588
  function materializeRetime(useNode, retime, ctx) {
5067
- const targetId = stripHash2(useNode.href);
4589
+ const targetId = stripHash(useNode.href);
5068
4590
  if (!targetId) {
5069
4591
  ctx.errors.push("retime: <use> has no href to follow");
5070
4592
  return;
@@ -5101,7 +4623,7 @@ function buildChainClone(targetId, accum, ctx, chain) {
5101
4623
  }
5102
4624
  clearCloneRetime(cloneNode);
5103
4625
  if (target.type === "use" && target.href) {
5104
- const subId = stripHash2(target.href);
4626
+ const subId = stripHash(target.href);
5105
4627
  if (subId) {
5106
4628
  const innerRetime = readCloneRetime(target);
5107
4629
  const subAccum = innerRetime ? concatRetime(asRetime(innerRetime), accum) : accum;
@@ -5122,7 +4644,7 @@ function materializeNestedRetimeUses(node, accum, ctx, chain, parentTargetId) {
5122
4644
  var _a2;
5123
4645
  const retime = readCloneRetime(n);
5124
4646
  if (n.type === "use" && retime && n.href) {
5125
- const subId = stripHash2(n.href);
4647
+ const subId = stripHash(n.href);
5126
4648
  if (subId) {
5127
4649
  const subAccum = concatRetime(asRetime(retime), accum);
5128
4650
  const subChain = new Set(chain);
@@ -5181,7 +4703,7 @@ function parseCubics(d) {
5181
4703
  let pcx = 0, pcy = 0;
5182
4704
  let pqx = 0, pqy = 0;
5183
4705
  let prevCmd = "";
5184
- const num2 = () => parseFloat(tokens[i++]);
4706
+ const num = () => parseFloat(tokens[i++]);
5185
4707
  const push = (P1, P2, P3) => {
5186
4708
  const P0 = [cx, cy];
5187
4709
  const lut = bezier2D_arcLengthLUT(P0, P1, P2, P3, LUT_STEPS);
@@ -5210,7 +4732,7 @@ function parseCubics(d) {
5210
4732
  continue;
5211
4733
  }
5212
4734
  if (U === "M") {
5213
- const x = num2() + (rel ? cx : 0), y = num2() + (rel ? cy : 0);
4735
+ const x = num() + (rel ? cx : 0), y = num() + (rel ? cy : 0);
5214
4736
  cx = x;
5215
4737
  cy = y;
5216
4738
  sx = x;
@@ -5219,29 +4741,29 @@ function parseCubics(d) {
5219
4741
  continue;
5220
4742
  }
5221
4743
  if (U === "L") {
5222
- pushLine(num2() + (rel ? cx : 0), num2() + (rel ? cy : 0));
4744
+ pushLine(num() + (rel ? cx : 0), num() + (rel ? cy : 0));
5223
4745
  } else if (U === "H") {
5224
- pushLine(num2() + (rel ? cx : 0), cy);
4746
+ pushLine(num() + (rel ? cx : 0), cy);
5225
4747
  } else if (U === "V") {
5226
- pushLine(cx, num2() + (rel ? cy : 0));
4748
+ pushLine(cx, num() + (rel ? cy : 0));
5227
4749
  } else if (U === "C") {
5228
- const p1 = [num2() + (rel ? cx : 0), num2() + (rel ? cy : 0)];
5229
- const p2 = [num2() + (rel ? cx : 0), num2() + (rel ? cy : 0)];
5230
- const p3 = [num2() + (rel ? cx : 0), num2() + (rel ? cy : 0)];
4750
+ const p1 = [num() + (rel ? cx : 0), num() + (rel ? cy : 0)];
4751
+ const p2 = [num() + (rel ? cx : 0), num() + (rel ? cy : 0)];
4752
+ const p3 = [num() + (rel ? cx : 0), num() + (rel ? cy : 0)];
5231
4753
  pcx = p2[0];
5232
4754
  pcy = p2[1];
5233
4755
  push(p1, p2, p3);
5234
4756
  } else if (U === "S") {
5235
4757
  const smooth = prevCmd.toUpperCase() === "C" || prevCmd.toUpperCase() === "S";
5236
4758
  const p1 = smooth ? [2 * cx - pcx, 2 * cy - pcy] : [cx, cy];
5237
- const p2 = [num2() + (rel ? cx : 0), num2() + (rel ? cy : 0)];
5238
- const p3 = [num2() + (rel ? cx : 0), num2() + (rel ? cy : 0)];
4759
+ const p2 = [num() + (rel ? cx : 0), num() + (rel ? cy : 0)];
4760
+ const p3 = [num() + (rel ? cx : 0), num() + (rel ? cy : 0)];
5239
4761
  pcx = p2[0];
5240
4762
  pcy = p2[1];
5241
4763
  push(p1, p2, p3);
5242
4764
  } else if (U === "Q") {
5243
- const qc = [num2() + (rel ? cx : 0), num2() + (rel ? cy : 0)];
5244
- const p3 = [num2() + (rel ? cx : 0), num2() + (rel ? cy : 0)];
4765
+ const qc = [num() + (rel ? cx : 0), num() + (rel ? cy : 0)];
4766
+ const p3 = [num() + (rel ? cx : 0), num() + (rel ? cy : 0)];
5245
4767
  pqx = qc[0];
5246
4768
  pqy = qc[1];
5247
4769
  const { P1, P2 } = quadToCubic([cx, cy], qc, p3);
@@ -5249,14 +4771,14 @@ function parseCubics(d) {
5249
4771
  } else if (U === "T") {
5250
4772
  const smooth = prevCmd.toUpperCase() === "Q" || prevCmd.toUpperCase() === "T";
5251
4773
  const qc = smooth ? [2 * cx - pqx, 2 * cy - pqy] : [cx, cy];
5252
- const p3 = [num2() + (rel ? cx : 0), num2() + (rel ? cy : 0)];
4774
+ const p3 = [num() + (rel ? cx : 0), num() + (rel ? cy : 0)];
5253
4775
  pqx = qc[0];
5254
4776
  pqy = qc[1];
5255
4777
  const { P1, P2 } = quadToCubic([cx, cy], qc, p3);
5256
4778
  push(P1, P2, p3);
5257
4779
  } else if (U === "A") {
5258
4780
  i += 5;
5259
- pushLine(num2() + (rel ? cx : 0), num2() + (rel ? cy : 0));
4781
+ pushLine(num() + (rel ? cx : 0), num() + (rel ? cy : 0));
5260
4782
  } else {
5261
4783
  i++;
5262
4784
  continue;
@@ -5432,20 +4954,20 @@ function transformPathData(d, m, decimals = 2) {
5432
4954
  while ((match = TOKEN_RE.exec(d)) !== null) tokens.push(match[0]);
5433
4955
  let out = "";
5434
4956
  let i = 0;
5435
- const num2 = () => parseFloat(tokens[i++]);
4957
+ const num = () => parseFloat(tokens[i++]);
5436
4958
  while (i < tokens.length) {
5437
4959
  const cmd = tokens[i++];
5438
4960
  if (cmd === "M" || cmd === "L") {
5439
- const [x, y] = apply(m, num2(), num2());
4961
+ const [x, y] = apply(m, num(), num());
5440
4962
  out += cmd + pack([x, y], decimals);
5441
4963
  } else if (cmd === "C") {
5442
- const [x1, y1] = apply(m, num2(), num2());
5443
- const [x2, y2] = apply(m, num2(), num2());
5444
- const [x, y] = apply(m, num2(), num2());
4964
+ const [x1, y1] = apply(m, num(), num());
4965
+ const [x2, y2] = apply(m, num(), num());
4966
+ const [x, y] = apply(m, num(), num());
5445
4967
  out += "C" + pack([x1, y1, x2, y2, x, y], decimals);
5446
4968
  } else if (cmd === "Q") {
5447
- const [x1, y1] = apply(m, num2(), num2());
5448
- const [x, y] = apply(m, num2(), num2());
4969
+ const [x1, y1] = apply(m, num(), num());
4970
+ const [x, y] = apply(m, num(), num());
5449
4971
  out += "Q" + pack([x1, y1, x, y], decimals);
5450
4972
  } else if (cmd === "Z" || cmd === "z") {
5451
4973
  out += "Z";
@@ -5476,7 +4998,7 @@ var TEXT_ATTR_KEYS = [
5476
4998
  "stroke",
5477
4999
  "strokeWidth",
5478
5000
  "effects",
5479
- TEXT_CONTENT_ATTR,
5001
+ PX_TEXT_CONTENT_ATTR,
5480
5002
  "xml:space"
5481
5003
  ];
5482
5004
  var PAINT_STATIC_KEYS = [
@@ -5512,7 +5034,7 @@ function paintAnimateOf(node) {
5512
5034
  }
5513
5035
  return out;
5514
5036
  }
5515
- function resolveStyle2(node, parent) {
5037
+ function resolveStyle(node, parent) {
5516
5038
  var _a2, _b, _c, _d, _e, _f, _g, _h, _i, _j;
5517
5039
  const isTextRoot = node.type === "text";
5518
5040
  const nodeStyle = node.style;
@@ -5575,86 +5097,22 @@ var MISSING_GLYPH_ADVANCE_EM = 0.6;
5575
5097
  var MISSING_GLYPH_CLASS_NAME = "px-missing-glyph";
5576
5098
  function missingGlyphBoxEm(advanceEm, ascentEm) {
5577
5099
  if (advanceEm <= 0 || ascentEm <= 0) return "";
5578
- const inset = 0.08;
5579
- const x0 = advanceEm * inset, x1 = advanceEm * (1 - inset);
5580
- const y1 = -ascentEm * (1 - inset);
5581
- const bw = x1 - x0, bh = -y1;
5582
- const t = Math.max(1, Math.min(bw, bh) * 0.12);
5583
- const outer = "M" + x0 + " 0L" + x1 + " 0L" + x1 + " " + y1 + "L" + x0 + " " + y1 + "Z";
5584
- if (bw <= 2 * t || bh <= 2 * t) return outer;
5585
- const ix0 = x0 + t, ix1 = x1 - t, iyb = -t, iyt = y1 + t;
5586
- return outer + "M" + ix0 + " " + iyb + "L" + ix0 + " " + iyt + "L" + ix1 + " " + iyt + "L" + ix1 + " " + iyb + "Z";
5587
- }
5588
- function materializeGlyphTextHorizontal(node, opts) {
5589
- var _a2, _b, _c;
5590
- const { glyphs, create = jsonElementFactory, warnings } = opts;
5591
- const soleFont = soleFontOf(glyphs);
5592
- const pen = { x: (_a2 = parseLen(node.x)) != null ? _a2 : 0, y: (_b = parseLen(node.y)) != null ? _b : 0 };
5593
- const placements = [];
5594
- const lines = [{ start: pen.x, end: pen.x }];
5595
- let line = 0;
5596
- const renderChars = (content, s) => {
5597
- var _a3;
5598
- const gf = glyphFontFor(s, glyphs, soleFont, warnings);
5599
- const upm = (gf == null ? void 0 : gf.unitsPerEm) || 1e3;
5600
- const scale = s.fontSize / upm;
5601
- const ascentEm = (_a3 = gf == null ? void 0 : gf.ascent) != null ? _a3 : 0.9 * upm;
5602
- const paint = paintOf(s);
5603
- for (let i = 0; i < content.length; i++) {
5604
- const ch = content.charAt(i);
5605
- const g = gf == null ? void 0 : gf.glyphs[ch];
5606
- if (g && g.pathData) {
5607
- placements.push({ glyphD: g.pathData, m: [scale, 0, 0, scale, pen.x, pen.y], paint, line, x: pen.x, y: pen.y, scale });
5608
- pen.x += g.width * scale;
5609
- } else if (/\S/.test(ch)) {
5610
- const advEm = g && g.width > 0 ? g.width : MISSING_GLYPH_ADVANCE_EM * upm;
5611
- placements.push({ glyphD: missingGlyphBoxEm(advEm, ascentEm), m: [scale, 0, 0, scale, pen.x, pen.y], paint, isMissing: true, line, x: pen.x, y: pen.y, scale });
5612
- pen.x += advEm * scale;
5613
- } else {
5614
- pen.x += (g ? g.width : 0) * scale;
5615
- }
5616
- pen.x += s.letterSpacing + (ch === " " ? s.wordSpacing : 0);
5617
- lines[line].end = pen.x;
5618
- }
5619
- };
5620
- const walk = (el, parentStyle) => {
5621
- var _a3, _b2, _c2;
5622
- const s = resolveStyle2(el, parentStyle);
5623
- const x = parseLen(el.x);
5624
- const y = parseLen(el.y);
5625
- if (x !== void 0) {
5626
- pen.x = x;
5627
- line = lines.length;
5628
- lines.push({ start: pen.x, end: pen.x });
5629
- }
5630
- if (y !== void 0) pen.y = y;
5631
- pen.x += (_a3 = parseLen(el.dx)) != null ? _a3 : 0;
5632
- pen.y += (_b2 = parseLen(el.dy)) != null ? _b2 : 0;
5633
- const content = str(el[TEXT_CONTENT_ATTR]);
5634
- if (content && !((_c2 = el.children) == null ? void 0 : _c2.length)) renderChars(content, s);
5635
- if (el.children) for (const ch of el.children) walk(ch, s);
5636
- };
5637
- const rootStyle = rootStyleOf(node);
5638
- if (node.children) for (const ch of node.children) walk(ch, rootStyle);
5639
- const rootContent = str(node[TEXT_CONTENT_ATTR]);
5640
- if (rootContent && !((_c = node.children) == null ? void 0 : _c.length)) renderChars(rootContent, rootStyle);
5641
- const anchor = str(node.textAnchor);
5642
- if (anchor === "middle" || anchor === "end") {
5643
- for (const p of placements) {
5644
- const w = lines[p.line].end - lines[p.line].start;
5645
- const shift = anchor === "middle" ? -w / 2 : -w;
5646
- p.m = [p.scale, 0, 0, p.scale, p.x + shift, p.y];
5647
- }
5648
- }
5649
- return toGroup(node, buildPaths(placements, create, warnings), create);
5100
+ const inset = 0.08;
5101
+ const x0 = advanceEm * inset, x1 = advanceEm * (1 - inset);
5102
+ const y1 = -ascentEm * (1 - inset);
5103
+ const bw = x1 - x0, bh = -y1;
5104
+ const t = Math.max(1, Math.min(bw, bh) * 0.12);
5105
+ const outer = "M" + x0 + " 0L" + x1 + " 0L" + x1 + " " + y1 + "L" + x0 + " " + y1 + "Z";
5106
+ if (bw <= 2 * t || bh <= 2 * t) return outer;
5107
+ const ix0 = x0 + t, ix1 = x1 - t, iyb = -t, iyt = y1 + t;
5108
+ return outer + "M" + ix0 + " " + iyb + "L" + ix0 + " " + iyt + "L" + ix1 + " " + iyt + "L" + ix1 + " " + iyb + "Z";
5650
5109
  }
5651
- function layoutGlyphTextChars(node, opts) {
5652
- var _a2, _b, _c, _d, _e;
5653
- if ((_a2 = opts.alongPath) == null ? void 0 : _a2.pathD) return layoutGlyphTextCharsAlongPath(node, opts.alongPath.pathD, opts);
5654
- const { glyphs, warnings } = opts;
5110
+ function materializeGlyphTextHorizontal(node, opts) {
5111
+ var _a2, _b, _c;
5112
+ const { glyphs, create = jsonElementFactory, warnings } = opts;
5655
5113
  const soleFont = soleFontOf(glyphs);
5656
- const pen = { x: (_b = parseLen(node.x)) != null ? _b : 0, y: (_c = parseLen(node.y)) != null ? _c : 0 };
5657
- const boxes = [];
5114
+ const pen = { x: (_a2 = parseLen(node.x)) != null ? _a2 : 0, y: (_b = parseLen(node.y)) != null ? _b : 0 };
5115
+ const placements = [];
5658
5116
  const lines = [{ start: pen.x, end: pen.x }];
5659
5117
  let line = 0;
5660
5118
  const renderChars = (content, s) => {
@@ -5662,19 +5120,28 @@ function layoutGlyphTextChars(node, opts) {
5662
5120
  const gf = glyphFontFor(s, glyphs, soleFont, warnings);
5663
5121
  const upm = (gf == null ? void 0 : gf.unitsPerEm) || 1e3;
5664
5122
  const scale = s.fontSize / upm;
5665
- const ascent = ((_a3 = gf == null ? void 0 : gf.ascent) != null ? _a3 : 0.9 * upm) * scale;
5123
+ const ascentEm = (_a3 = gf == null ? void 0 : gf.ascent) != null ? _a3 : 0.9 * upm;
5124
+ const paint = paintOf(s);
5666
5125
  for (let i = 0; i < content.length; i++) {
5667
5126
  const ch = content.charAt(i);
5668
5127
  const g = gf == null ? void 0 : gf.glyphs[ch];
5669
- const advance = (g ? g.width : 0) * scale + s.letterSpacing + (ch === " " ? s.wordSpacing : 0);
5670
- boxes.push({ x: pen.x, y: pen.y, width: advance, ascent, fontSize: s.fontSize, line });
5671
- pen.x += advance;
5128
+ if (g && g.pathData) {
5129
+ placements.push({ glyphD: g.pathData, m: [scale, 0, 0, scale, pen.x, pen.y], paint, line, x: pen.x, y: pen.y, scale });
5130
+ pen.x += g.width * scale;
5131
+ } else if (/\S/.test(ch)) {
5132
+ const advEm = g && g.width > 0 ? g.width : MISSING_GLYPH_ADVANCE_EM * upm;
5133
+ placements.push({ glyphD: missingGlyphBoxEm(advEm, ascentEm), m: [scale, 0, 0, scale, pen.x, pen.y], paint, isMissing: true, line, x: pen.x, y: pen.y, scale });
5134
+ pen.x += advEm * scale;
5135
+ } else {
5136
+ pen.x += (g ? g.width : 0) * scale;
5137
+ }
5138
+ pen.x += s.letterSpacing + (ch === " " ? s.wordSpacing : 0);
5672
5139
  lines[line].end = pen.x;
5673
5140
  }
5674
5141
  };
5675
5142
  const walk = (el, parentStyle) => {
5676
5143
  var _a3, _b2, _c2;
5677
- const s = resolveStyle2(el, parentStyle);
5144
+ const s = resolveStyle(el, parentStyle);
5678
5145
  const x = parseLen(el.x);
5679
5146
  const y = parseLen(el.y);
5680
5147
  if (x !== void 0) {
@@ -5685,104 +5152,31 @@ function layoutGlyphTextChars(node, opts) {
5685
5152
  if (y !== void 0) pen.y = y;
5686
5153
  pen.x += (_a3 = parseLen(el.dx)) != null ? _a3 : 0;
5687
5154
  pen.y += (_b2 = parseLen(el.dy)) != null ? _b2 : 0;
5688
- const content = str(el[TEXT_CONTENT_ATTR]);
5155
+ const content = str(el[PX_TEXT_CONTENT_ATTR]);
5689
5156
  if (content && !((_c2 = el.children) == null ? void 0 : _c2.length)) renderChars(content, s);
5690
5157
  if (el.children) for (const ch of el.children) walk(ch, s);
5691
5158
  };
5692
5159
  const rootStyle = rootStyleOf(node);
5693
- if (node.children) for (const ch of node.children) {
5694
- const before = boxes.length;
5695
- walk(ch, rootStyle);
5696
- if (boxes.length === before) {
5697
- const s = resolveStyle2(ch, rootStyle);
5698
- const gf = glyphFontFor(s, glyphs, soleFont);
5699
- const upm = (gf == null ? void 0 : gf.unitsPerEm) || 1e3;
5700
- boxes.push({ x: pen.x, y: pen.y, width: 0, ascent: ((_d = gf == null ? void 0 : gf.ascent) != null ? _d : 0.9 * upm) * (s.fontSize / upm), fontSize: s.fontSize, line });
5701
- }
5702
- }
5703
- const rootContent = str(node[TEXT_CONTENT_ATTR]);
5704
- if (rootContent && !((_e = node.children) == null ? void 0 : _e.length)) renderChars(rootContent, rootStyle);
5160
+ if (node.children) for (const ch of node.children) walk(ch, rootStyle);
5161
+ const rootContent = str(node[PX_TEXT_CONTENT_ATTR]);
5162
+ if (rootContent && !((_c = node.children) == null ? void 0 : _c.length)) renderChars(rootContent, rootStyle);
5705
5163
  const anchor = str(node.textAnchor);
5706
5164
  if (anchor === "middle" || anchor === "end") {
5707
- for (const b of boxes) {
5708
- const w = lines[b.line].end - lines[b.line].start;
5709
- b.x += anchor === "middle" ? -w / 2 : -w;
5165
+ for (const p of placements) {
5166
+ const w = lines[p.line].end - lines[p.line].start;
5167
+ const shift = anchor === "middle" ? -w / 2 : -w;
5168
+ p.m = [p.scale, 0, 0, p.scale, p.x + shift, p.y];
5710
5169
  }
5711
5170
  }
5712
- return boxes.map((_f) => {
5713
- var _g = _f, { line: _l } = _g, b = __objRest(_g, ["line"]);
5714
- return b;
5715
- });
5716
- }
5717
- function layoutGlyphTextCharsAlongPath(node, pathD, opts) {
5718
- var _a2, _b;
5719
- const { glyphs, warnings, alongPath } = opts;
5720
- const sampler = createPathSampler(pathD);
5721
- if (!sampler) {
5722
- warnings == null ? void 0 : warnings.push("textGlyphs: unparsable along-path geometry (caret)");
5723
- return [];
5724
- }
5725
- const soleFont = soleFontOf(glyphs);
5726
- const chars = [];
5727
- let adv = 0;
5728
- const walk = (el, parentStyle) => {
5729
- var _a3, _b2;
5730
- const s = resolveStyle2(el, parentStyle);
5731
- const content = str(el[TEXT_CONTENT_ATTR]);
5732
- if (content && !((_a3 = el.children) == null ? void 0 : _a3.length)) {
5733
- const gf = glyphFontFor(s, glyphs, soleFont, warnings);
5734
- const upm = (gf == null ? void 0 : gf.unitsPerEm) || 1e3;
5735
- const scale = s.fontSize / upm;
5736
- const ascent = ((_b2 = gf == null ? void 0 : gf.ascent) != null ? _b2 : 0.9 * upm) * scale;
5737
- for (let i = 0; i < content.length; i++) {
5738
- const ch = content.charAt(i);
5739
- const g = gf == null ? void 0 : gf.glyphs[ch];
5740
- const glyphW = (g ? g.width : 0) * scale;
5741
- const advance = glyphW + s.letterSpacing + (ch === " " ? s.wordSpacing : 0);
5742
- chars.push({ advStart: adv, advEnd: adv + advance, glyphW, ascent, fontSize: s.fontSize });
5743
- adv += advance;
5744
- }
5745
- }
5746
- if (el.children) for (const ch of el.children) walk(ch, s);
5747
- };
5748
- walk(node, rootStyleOf(node));
5749
- const width = adv;
5750
- const tlr = readAnimatable(alongPath == null ? void 0 : alongPath.textLength);
5751
- const tlv = tlr.kind === "animated" /* Animated */ ? Number((_a2 = tlr.keyframes[0]) == null ? void 0 : _a2.value) || 0 : tlr.kind === "static" /* Static */ ? Number(tlr.value) || 0 : 0;
5752
- const k = tlv > 0 && width > 0 ? tlv / width : 1;
5753
- const so = readAnimatable(alongPath == null ? void 0 : alongPath.startOffset);
5754
- const { along: alongOffset, perp } = alongPathNodeOffsets(node);
5755
- const base = alongOffset + (so.kind === "animated" /* Animated */ ? Number((_b = so.keyframes[0]) == null ? void 0 : _b.value) || 0 : so.kind === "static" /* Static */ ? Number(so.value) || 0 : 0);
5756
- const withPerp = (p) => ({
5757
- x: p.x - perp * Math.sin(p.angle),
5758
- y: p.y + perp * Math.cos(p.angle),
5759
- angle: p.angle
5760
- });
5761
- return chars.map((c) => {
5762
- const dStart = base + c.advStart * k;
5763
- const dEnd = base + c.advEnd * k;
5764
- const p0 = withPerp(sampler.sampleAtDistance(dStart));
5765
- const p1 = withPerp(sampler.sampleAtDistance(dEnd));
5766
- const glyphMid = sampler.sampleAtDistance(base + (c.advStart + c.glyphW / 2) * k);
5767
- return {
5768
- x: p0.x,
5769
- y: p0.y,
5770
- width: c.advEnd - c.advStart,
5771
- ascent: c.ascent,
5772
- fontSize: c.fontSize,
5773
- endX: p1.x,
5774
- endY: p1.y,
5775
- rotation: glyphMid.angle * 180 / Math.PI
5776
- };
5777
- });
5171
+ return toGroup(node, buildPaths(placements, create, warnings), create);
5778
5172
  }
5779
5173
  function collectAlongPathCells(node, glyphs, soleFont, warnings) {
5780
5174
  const cells = [];
5781
5175
  let adv = 0;
5782
5176
  const walk = (el, parentStyle) => {
5783
5177
  var _a2, _b;
5784
- const s = resolveStyle2(el, parentStyle);
5785
- const content = str(el[TEXT_CONTENT_ATTR]);
5178
+ const s = resolveStyle(el, parentStyle);
5179
+ const content = str(el[PX_TEXT_CONTENT_ATTR]);
5786
5180
  if (content && !((_a2 = el.children) == null ? void 0 : _a2.length)) {
5787
5181
  const gf = glyphFontFor(s, glyphs, soleFont, warnings);
5788
5182
  if (gf) {
@@ -5997,10 +5391,6 @@ function toGroup(node, children, create) {
5997
5391
  }
5998
5392
  return create("g", gProps, children);
5999
5393
  }
6000
- function materializeGlyphText(node, opts) {
6001
- if (opts.alongPath) return materializeGlyphTextAlongPath(node, opts.alongPath.pathD, opts.alongPath.startOffset, opts, opts.alongPath.textLength, opts.alongPath.pathOverflow);
6002
- return materializeGlyphTextHorizontal(node, opts);
6003
- }
6004
5394
  function applyTextGlyphsEffect(node, fx, ctx) {
6005
5395
  if (!(fx == null ? void 0 : fx.useGlyphs)) return node;
6006
5396
  if (!ctx.glyphs) {
@@ -6157,7 +5547,7 @@ function readScalarValues(r) {
6157
5547
  if (r.kind === "static" /* Static */) return [r.value];
6158
5548
  const out = [];
6159
5549
  for (const kf of r.keyframes) {
6160
- const v = kfValue(kf);
5550
+ const v = keyframeValue(kf);
6161
5551
  if (typeof v === "number") out.push(v);
6162
5552
  }
6163
5553
  return out;
@@ -6168,9 +5558,9 @@ function computeAnimAttr(read, map) {
6168
5558
  return {
6169
5559
  kind: "animated" /* Animated */,
6170
5560
  keyframes: read.keyframes.map((kf) => ({
6171
- time: kfTime(kf),
6172
- value: map(kfValue(kf)),
6173
- easing: kfEasing(kf)
5561
+ time: keyframeTime(kf),
5562
+ value: map(keyframeValue(kf)),
5563
+ easing: keyframeEasing(kf)
6174
5564
  })),
6175
5565
  loop: read.loop
6176
5566
  };
@@ -6188,7 +5578,7 @@ function computeOpacityFromRange(rangeRead) {
6188
5578
  let anyHide = false;
6189
5579
  let allHide = true;
6190
5580
  for (const kf of kfs) {
6191
- if (hide(kfValue(kf))) anyHide = true;
5581
+ if (hide(keyframeValue(kf))) anyHide = true;
6192
5582
  else allHide = false;
6193
5583
  }
6194
5584
  if (!anyHide) return void 0;
@@ -6198,10 +5588,10 @@ function computeOpacityFromRange(rangeRead) {
6198
5588
  const kf = kfs[i];
6199
5589
  const prevKf = i > 0 ? kfs[i - 1] : void 0;
6200
5590
  const nextKf = i < kfs.length - 1 ? kfs[i + 1] : void 0;
6201
- const t = kfTime(kf);
6202
- const thisHide = hide(kfValue(kf));
6203
- const prevHide = prevKf ? thisHide && hide(kfValue(prevKf)) : thisHide;
6204
- const nextHide = nextKf ? thisHide && hide(kfValue(nextKf)) : thisHide;
5591
+ const t = keyframeTime(kf);
5592
+ const thisHide = hide(keyframeValue(kf));
5593
+ const prevHide = prevKf ? thisHide && hide(keyframeValue(prevKf)) : thisHide;
5594
+ const nextHide = nextKf ? thisHide && hide(keyframeValue(nextKf)) : thisHide;
6205
5595
  if (prevHide && !nextHide) {
6206
5596
  out.push({ time: t, value: 0 });
6207
5597
  out.push({ time: t + OPACITY_STEP_MS, value: 1 });
@@ -6217,9 +5607,9 @@ function readRangeWithCrossings(raw) {
6217
5607
  const r = readAnimatable(raw);
6218
5608
  if (r.kind !== "animated" /* Animated */) return r;
6219
5609
  const kfs = r.keyframes.map((kf) => ({
6220
- time: kfTime(kf),
6221
- value: kfValue(kf),
6222
- easing: kfEasing(kf)
5610
+ time: keyframeTime(kf),
5611
+ value: keyframeValue(kf),
5612
+ easing: keyframeEasing(kf)
6223
5613
  }));
6224
5614
  const hasReverse = kfs.some((kf) => kf.value[0] > kf.value[1]);
6225
5615
  if (!hasReverse) {
@@ -6347,7 +5737,7 @@ function shapeToPathD(node) {
6347
5737
  }
6348
5738
 
6349
5739
  // src/effects/PlayerEffectsUtil.ts
6350
- function applyPlayerEffects(root) {
5740
+ function materializeNodeEffects(root) {
6351
5741
  var _a2, _b;
6352
5742
  const ctx = {
6353
5743
  defs: [],
@@ -6360,7 +5750,7 @@ function applyPlayerEffects(root) {
6360
5750
  // Resolved engine: `frames` ONLY when explicitly set; auto/waapi/unset →
6361
5751
  // waapi (we're not 100% sure it's frames, and CSS/WAAPI need the inline form).
6362
5752
  engine: resolveTimelineEngine((_a2 = getAnimatorConfig(root)) == null ? void 0 : _a2.engine),
6363
- glyphs: (_b = getDefs(root)) == null ? void 0 : _b.fonts
5753
+ glyphs: (_b = getDefinitions(root)) == null ? void 0 : _b.fonts
6364
5754
  };
6365
5755
  const working = clone(root);
6366
5756
  indexById(working, ctx.idMap);
@@ -6444,11 +5834,11 @@ function buildOffsetPath(propAnim) {
6444
5834
  if (propAnim.alongPathMode !== "offsetPath") return void 0;
6445
5835
  const kfs = propAnim.keyframes;
6446
5836
  if (!kfs || kfs.length < 2) return void 0;
6447
- const first = kfValue(kfs[0]);
5837
+ const first = keyframeValue(kfs[0]);
6448
5838
  const anchor = (first == null ? void 0 : first.origin) && first.origin.length >= 2 ? [first.origin[0], first.origin[1]] : [0, 0];
6449
5839
  const points = [];
6450
5840
  for (const kf of kfs) {
6451
- const v = kfValue(kf);
5841
+ const v = keyframeValue(kf);
6452
5842
  const tr = v == null ? void 0 : v.translate;
6453
5843
  if (!tr || tr.length < 2) return void 0;
6454
5844
  const parts = Object.keys(v);
@@ -6457,13 +5847,13 @@ function buildOffsetPath(propAnim) {
6457
5847
  if (o[0] !== anchor[0] || o[1] !== anchor[1]) return void 0;
6458
5848
  points.push([tr[0] + anchor[0], tr[1] + anchor[1]]);
6459
5849
  }
6460
- if (!kfs.some((kf) => kfTangentIn(kf) || kfTangentOut(kf))) return void 0;
5850
+ if (!kfs.some((kf) => keyframeTangentIn(kf) || keyframeTangentOut(kf))) return void 0;
6461
5851
  let d = "M" + fmt2(points[0][0]) + "," + fmt2(points[0][1]);
6462
5852
  const segLens = [];
6463
5853
  for (let i = 0; i < points.length - 1; i++) {
6464
5854
  const p0 = points[i], p1 = points[i + 1];
6465
- const to = (_b = kfTangentOut(kfs[i])) != null ? _b : [0, 0];
6466
- const ti = (_c = kfTangentIn(kfs[i + 1])) != null ? _c : [0, 0];
5855
+ const to = (_b = keyframeTangentOut(kfs[i])) != null ? _b : [0, 0];
5856
+ const ti = (_c = keyframeTangentIn(kfs[i + 1])) != null ? _c : [0, 0];
6467
5857
  const c1 = [p0[0] + to[0], p0[1] + to[1]];
6468
5858
  const c2 = [p1[0] + ti[0], p1[1] + ti[1]];
6469
5859
  d += "C" + fmt2(c1[0]) + "," + fmt2(c1[1]) + "," + fmt2(c2[0]) + "," + fmt2(c2[1]) + "," + fmt2(p1[0]) + "," + fmt2(p1[1]);
@@ -6475,8 +5865,8 @@ function buildOffsetPath(propAnim) {
6475
5865
  let cum = 0;
6476
5866
  for (let i = 0; i < kfs.length; i++) {
6477
5867
  if (i > 0) cum += segLens[i - 1];
6478
- const out = { t: kfTime(kfs[i]), v: cum / total };
6479
- const e = kfEasing(kfs[i]);
5868
+ const out = { t: keyframeTime(kfs[i]), v: cum / total };
5869
+ const e = keyframeEasing(kfs[i]);
6480
5870
  if (e !== void 0) out.e = e;
6481
5871
  distanceKfs.push(out);
6482
5872
  }
@@ -6526,15 +5916,163 @@ function materializeOffsetPathsInTree(root) {
6526
5916
  return walk(root);
6527
5917
  }
6528
5918
 
5919
+ // src/materialize/PxAnimatorUseMaterializer.ts
5920
+ function materializeAnimatedUseInstances(root) {
5921
+ var _a2;
5922
+ const idMap = buildIdMap(root);
5923
+ const animatedIds = computeAnimatedSubtreeIds(root, idMap);
5924
+ if (animatedIds.size === 0) return root;
5925
+ let idCounter = 0;
5926
+ const genId3 = () => "_lw_use_mat_" + ++idCounter;
5927
+ const rootViewport = readRootViewport(root);
5928
+ const defsCollector = [];
5929
+ const walked = walkAndMaterialize2(root, idMap, animatedIds, genId3, defsCollector, rootViewport);
5930
+ if (defsCollector.length === 0) return walked;
5931
+ const defsNode = { type: "defs", children: defsCollector };
5932
+ const newChildren = [...(_a2 = walked.children) != null ? _a2 : [], defsNode];
5933
+ return __spreadProps(__spreadValues({}, walked), { children: newChildren });
5934
+ }
5935
+ function readRootViewport(root) {
5936
+ const vb = parseViewBox(root.viewBox);
5937
+ if (vb) return [vb[2], vb[3]];
5938
+ const w = numericAttr(root.width);
5939
+ const h = numericAttr(root.height);
5940
+ if (w !== void 0 && h !== void 0) return [w, h];
5941
+ return [1, 1];
5942
+ }
5943
+ function numericAttr(v) {
5944
+ if (typeof v === "number") return v;
5945
+ if (typeof v === "string") {
5946
+ const n = parseFloat(v);
5947
+ return Number.isFinite(n) ? n : void 0;
5948
+ }
5949
+ return void 0;
5950
+ }
5951
+ function buildIdMap(root) {
5952
+ const map = /* @__PURE__ */ new Map();
5953
+ const visit = (n) => {
5954
+ var _a2;
5955
+ if (typeof n.id === "string") map.set(n.id, n);
5956
+ (_a2 = n.children) == null ? void 0 : _a2.forEach(visit);
5957
+ };
5958
+ visit(root);
5959
+ return map;
5960
+ }
5961
+ function computeAnimatedSubtreeIds(root, idMap) {
5962
+ const cache = /* @__PURE__ */ new WeakMap();
5963
+ const result = /* @__PURE__ */ new Set();
5964
+ const hasAnim = (n, visiting) => {
5965
+ const cached = cache.get(n);
5966
+ if (cached !== void 0) return cached;
5967
+ if (visiting.has(n)) return false;
5968
+ visiting.add(n);
5969
+ let r = false;
5970
+ if (n.animate && typeof n.animate === "object" && !Array.isArray(n.animate)) {
5971
+ for (const _ in n.animate) {
5972
+ r = true;
5973
+ break;
5974
+ }
5975
+ }
5976
+ if (!r && n.children) {
5977
+ for (const ch of n.children) {
5978
+ if (hasAnim(ch, visiting)) {
5979
+ r = true;
5980
+ break;
5981
+ }
5982
+ }
5983
+ }
5984
+ if (!r && n.type === "use" && typeof n.href === "string") {
5985
+ const targetId = stripHash2(n.href);
5986
+ const target = targetId ? idMap.get(targetId) : void 0;
5987
+ if (target) r = hasAnim(target, visiting);
5988
+ }
5989
+ visiting.delete(n);
5990
+ cache.set(n, r);
5991
+ return r;
5992
+ };
5993
+ for (const [id, node] of idMap) {
5994
+ if (hasAnim(node, /* @__PURE__ */ new Set())) result.add(id);
5995
+ }
5996
+ return result;
5997
+ }
5998
+ function stripHash2(href) {
5999
+ if (typeof href !== "string") return void 0;
6000
+ return href.startsWith("#") ? href.slice(1) : href;
6001
+ }
6002
+ function materializeOneUse(useNode, target, idMap, animatedIds, genId3, defsCollector, rootViewport) {
6003
+ var _a2, _b, _c, _d;
6004
+ const clone2 = deepClonePxNode(target);
6005
+ regenerateIdsAndRewriteRefs(clone2, genId3);
6006
+ const symbolViewBox = clone2.type === "symbol" ? parseViewBox(clone2.viewBox) : void 0;
6007
+ const useW = (_b = (_a2 = numericAttr(useNode.width)) != null ? _a2 : symbolViewBox == null ? void 0 : symbolViewBox[2]) != null ? _b : rootViewport[0];
6008
+ const useH = (_d = (_c = numericAttr(useNode.height)) != null ? _c : symbolViewBox == null ? void 0 : symbolViewBox[3]) != null ? _d : rootViewport[1];
6009
+ const rewrittenClone = clone2.type === "symbol" ? rewriteSymbolRootToGroup(clone2, genId3, defsCollector, useW, useH) : clone2;
6010
+ const materializedClone = walkAndMaterialize2(rewrittenClone, idMap, animatedIds, genId3, defsCollector, rootViewport);
6011
+ const newNode = __spreadProps(__spreadValues({}, useNode), { type: "g", children: [materializedClone] });
6012
+ delete newNode.href;
6013
+ delete newNode.width;
6014
+ delete newNode.height;
6015
+ return applyUseOffsetToG(newNode);
6016
+ }
6017
+ function rewriteSymbolRootToGroup(symbolNode, genId3, defsCollector, useW, useH) {
6018
+ const viewBox = parseViewBox(symbolNode.viewBox);
6019
+ const g = __spreadProps(__spreadValues({}, symbolNode), { type: "g" });
6020
+ delete g.viewBox;
6021
+ delete g.preserveAspectRatio;
6022
+ delete g.width;
6023
+ delete g.height;
6024
+ if (!viewBox) return g;
6025
+ const [vbX, vbY, vbW, vbH] = viewBox;
6026
+ const scale = vbW > 0 && vbH > 0 ? Math.min(useW / vbW, useH / vbH) : 1;
6027
+ const xOff = (useW - vbW * scale) / 2;
6028
+ const yOff = (useH - vbH * scale) / 2;
6029
+ const parts = [];
6030
+ if (xOff !== 0 || yOff !== 0) parts.push("translate(" + xOff + "," + yOff + ")");
6031
+ if (scale !== 1) parts.push("scale(" + scale + ")");
6032
+ if (vbX !== 0 || vbY !== 0) parts.push("translate(" + -vbX + "," + -vbY + ")");
6033
+ if (parts.length) g.transform = parts.join("");
6034
+ const clipId = genId3();
6035
+ defsCollector.push({
6036
+ type: "clipPath",
6037
+ id: clipId,
6038
+ children: [{ type: "rect", x: vbX, y: vbY, width: vbW, height: vbH }]
6039
+ });
6040
+ g.clipPath = "url(#" + clipId + ")";
6041
+ return g;
6042
+ }
6043
+ function parseViewBox(v) {
6044
+ if (typeof v !== "string") return void 0;
6045
+ const parts = v.trim().split(/[\s,]+/).map(Number);
6046
+ if (parts.length < 4 || parts.some((n) => !Number.isFinite(n))) return void 0;
6047
+ return [parts[0], parts[1], parts[2], parts[3]];
6048
+ }
6049
+ function walkAndMaterialize2(node, idMap, animatedIds, genId3, defsCollector, rootViewport) {
6050
+ if (node.type === "use" && typeof node.href === "string") {
6051
+ const targetId = stripHash2(node.href);
6052
+ if (targetId && animatedIds.has(targetId)) {
6053
+ const target = idMap.get(targetId);
6054
+ if (target) return materializeOneUse(node, target, idMap, animatedIds, genId3, defsCollector, rootViewport);
6055
+ }
6056
+ }
6057
+ if (!node.children) return node;
6058
+ let changed = false;
6059
+ const newChildren = node.children.map((ch) => {
6060
+ const m = walkAndMaterialize2(ch, idMap, animatedIds, genId3, defsCollector, rootViewport);
6061
+ if (m !== ch) changed = true;
6062
+ return m;
6063
+ });
6064
+ return changed ? __spreadProps(__spreadValues({}, node), { children: newChildren }) : node;
6065
+ }
6066
+
6529
6067
  // src/materialize/PxAnimatorMaterializeAll.ts
6530
- function materializeAllInTree(doc, engine, opts) {
6068
+ function materializeAllInTree(doc, engine, options) {
6531
6069
  var _a2, _b;
6532
- let root = applyPlayerEffects(doc).root;
6070
+ let root = materializeNodeEffects(doc).root;
6533
6071
  root = materializeOffsetPathsInTree(root);
6534
- const duration = (_b = (_a2 = getAnimatorConfig(root)) == null ? void 0 : _a2.duration) != null ? _b : DEFAULT_DURATION_MS;
6072
+ const duration = (_b = (_a2 = getAnimatorConfig(root)) == null ? void 0 : _a2.duration) != null ? _b : PX_DEFAULT_DURATION_MS;
6535
6073
  root = materializeInternalLoopsInTree(root, duration);
6536
6074
  if (engine === PxTimelineEngine.native) {
6537
- root = materializeMotionPathsInTree(root, opts == null ? void 0 : opts.motionPath);
6075
+ root = materializeMotionPathsInTree(root, options == null ? void 0 : options.motionPath);
6538
6076
  root = materializeAnimatedUseInstances(root);
6539
6077
  root = pruneUnreferencedDefs(root);
6540
6078
  }
@@ -6644,16 +6182,16 @@ function cancelFrame(handle) {
6644
6182
  }
6645
6183
  g.clearTimeout(handle);
6646
6184
  }
6647
- function createBasicFrameLoopAnimator(doc, adapter, callbacks) {
6185
+ function createAdapterAnimator(doc, adapter, callbacks) {
6648
6186
  var _a2;
6649
6187
  const config = getAnimatorConfig(doc) || {};
6650
- const bindings = getNormalizedBindings(doc, PxTimelineEngine.js);
6188
+ const bindings = normalizeBindings(doc, PxTimelineEngine.js);
6651
6189
  const _iterations = config.iterations;
6652
6190
  let iterations = 1;
6653
6191
  if (typeof _iterations === "number") iterations = _iterations || 1;
6654
6192
  if (_iterations === "infinite") iterations = Infinity;
6655
6193
  if (iterations < 1) iterations = 1;
6656
- const duration = +(config.duration || DEFAULT_DURATION_MS);
6194
+ const duration = +(config.duration || PX_DEFAULT_DURATION_MS);
6657
6195
  const totalDuration = duration && iterations ? duration * (iterations === Infinity ? Infinity : iterations) : duration ? (iterations != null ? iterations : 1) * duration : 0;
6658
6196
  const direction = config.direction || "normal";
6659
6197
  const fill = (_a2 = config.fill) != null ? _a2 : "forwards";
@@ -6924,246 +6462,6 @@ var PxDiagnosticKind = {
6924
6462
  /** The player failed where it did not expect to — report it to us. */
6925
6463
  internal: "internal"
6926
6464
  };
6927
- function asError(error) {
6928
- return typeof error === "string" ? new Error(error) : error;
6929
- }
6930
- function isSilenced(silent, kind) {
6931
- if (!silent) return false;
6932
- return silent === true || silent.includes(kind);
6933
- }
6934
- function createDiagnostics(config, prefix) {
6935
- const tag = prefix ? prefix + " " : "";
6936
- return {
6937
- warn: (kind, message, detail) => {
6938
- if (config == null ? void 0 : config.onWarn) {
6939
- config.onWarn({ kind, message, detail });
6940
- return;
6941
- }
6942
- if (isSilenced(config == null ? void 0 : config.silent, kind)) return;
6943
- const line = tag + kind + ": " + message;
6944
- if (detail === void 0) console.warn(line);
6945
- else console.warn(line, detail);
6946
- },
6947
- error: (kind, error) => {
6948
- const err = asError(error);
6949
- if (config == null ? void 0 : config.onError) {
6950
- config.onError({ kind, message: err.message, error: err });
6951
- return;
6952
- }
6953
- if (isSilenced(config == null ? void 0 : config.silent, kind)) return;
6954
- console.error(tag + kind + ": " + err.message);
6955
- }
6956
- };
6957
- }
6958
-
6959
- // src/effects/PlayerEffectsUtil.visualModel.ts
6960
- var IDENTITY = [1, 0, 0, 1, 0, 0];
6961
- function mul(m, n) {
6962
- return [
6963
- m[0] * n[0] + m[2] * n[1],
6964
- m[1] * n[0] + m[3] * n[1],
6965
- m[0] * n[2] + m[2] * n[3],
6966
- m[1] * n[2] + m[3] * n[3],
6967
- m[0] * n[4] + m[2] * n[5] + m[4],
6968
- m[1] * n[4] + m[3] * n[5] + m[5]
6969
- ];
6970
- }
6971
- var translateM = (x, y) => [1, 0, 0, 1, x, y];
6972
- var scaleM = (sx, sy) => [sx, 0, 0, sy, 0, 0];
6973
- function rotateM(deg) {
6974
- const r = deg * Math.PI / 180;
6975
- return [Math.cos(r), Math.sin(r), -Math.sin(r), Math.cos(r), 0, 0];
6976
- }
6977
- var skewXM = (deg) => [1, 0, Math.tan(deg * Math.PI / 180), 1, 0, 0];
6978
- var skewYM = (deg) => [1, Math.tan(deg * Math.PI / 180), 0, 1, 0, 0];
6979
- function parseTransformString(s) {
6980
- let m = IDENTITY;
6981
- const re = /(translate|rotate|scale|matrix|skewX|skewY)\(([^)]*)\)/g;
6982
- let hit;
6983
- while (hit = re.exec(s)) {
6984
- const fn = hit[1];
6985
- const a = hit[2].split(/[\s,]+/).filter(Boolean).map(Number);
6986
- if (fn === "translate") m = mul(m, translateM(a[0] || 0, a[1] || 0));
6987
- else if (fn === "scale") m = mul(m, scaleM(a[0], a.length > 1 ? a[1] : a[0]));
6988
- else if (fn === "rotate") m = mul(m, rotateM(a[0]));
6989
- else if (fn === "skewX") m = mul(m, skewXM(a[0]));
6990
- else if (fn === "skewY") m = mul(m, skewYM(a[0]));
6991
- else if (fn === "matrix") m = mul(m, [a[0], a[1], a[2], a[3], a[4], a[5]]);
6992
- }
6993
- return m;
6994
- }
6995
- function partsToMatrix(p) {
6996
- let m = IDENTITY;
6997
- if (p.translate) m = mul(m, translateM(p.translate[0], p.translate[1]));
6998
- const pivot = p.origin && (p.rotate !== void 0 || p.scale);
6999
- if (pivot) m = mul(m, translateM(p.origin[0], p.origin[1]));
7000
- if (p.rotate !== void 0) m = mul(m, rotateM(p.rotate));
7001
- if (p.scale) m = mul(m, scaleM(p.scale[0], p.scale[1]));
7002
- if (pivot) m = mul(m, translateM(-p.origin[0], -p.origin[1]));
7003
- return m;
7004
- }
7005
- function lerp(a, b, f) {
7006
- return a + (b - a) * f;
7007
- }
7008
- function interpParts(kfs, t) {
7009
- var _a2, _b, _c, _d, _e, _f, _g;
7010
- if (!kfs.length) return {};
7011
- if (t <= ((_a2 = kfs[0].time) != null ? _a2 : 0)) return kfs[0].value || {};
7012
- if (t >= ((_b = kfs[kfs.length - 1].time) != null ? _b : 0)) return kfs[kfs.length - 1].value || {};
7013
- let i = 0;
7014
- while (i < kfs.length - 1 && ((_c = kfs[i + 1].time) != null ? _c : 0) < t) i++;
7015
- const a = kfs[i], b = kfs[i + 1];
7016
- const f = (t - ((_d = a.time) != null ? _d : 0)) / (((_e = b.time) != null ? _e : 0) - ((_f = a.time) != null ? _f : 0) || 1);
7017
- const va = a.value || {}, vb = b.value || {};
7018
- const out = {};
7019
- if (va.translate && vb.translate) out.translate = [lerp(va.translate[0], vb.translate[0], f), lerp(va.translate[1], vb.translate[1], f)];
7020
- else out.translate = va.translate || vb.translate;
7021
- if (va.rotate !== void 0 && vb.rotate !== void 0) out.rotate = lerp(va.rotate, vb.rotate, f);
7022
- else out.rotate = (_g = va.rotate) != null ? _g : vb.rotate;
7023
- if (va.scale && vb.scale) out.scale = [lerp(va.scale[0], vb.scale[0], f), lerp(va.scale[1], vb.scale[1], f)];
7024
- else out.scale = va.scale || vb.scale;
7025
- out.origin = va.origin || vb.origin;
7026
- return out;
7027
- }
7028
- function evalTransformValue(v, t) {
7029
- if (v === void 0 || v === null) return IDENTITY;
7030
- if (typeof v === "string") return parseTransformString(v);
7031
- if (v.keyframes) return partsToMatrix(interpParts(v.keyframes, t));
7032
- if (v.value) return partsToMatrix(v.value);
7033
- if (typeof v === "object" && !Array.isArray(v)) return partsToMatrix(v);
7034
- return IDENTITY;
7035
- }
7036
- function nodeMatrix(node, t) {
7037
- if (node.animate && node.animate.transform) return evalTransformValue(node.animate.transform, t);
7038
- if (node.transform !== void 0) return evalTransformValue(node.transform, t);
7039
- return IDENTITY;
7040
- }
7041
- function evalScalar(animated, staticVal, fallback, t) {
7042
- var _a2, _b, _c, _d, _e, _f;
7043
- if (animated && animated.keyframes && animated.keyframes.length) {
7044
- const kfs = animated.keyframes;
7045
- if (t <= ((_a2 = kfs[0].time) != null ? _a2 : 0)) return kfs[0].value;
7046
- if (t >= ((_b = kfs[kfs.length - 1].time) != null ? _b : 0)) return kfs[kfs.length - 1].value;
7047
- let i = 0;
7048
- while (i < kfs.length - 1 && ((_c = kfs[i + 1].time) != null ? _c : 0) < t) i++;
7049
- const a = kfs[i], b = kfs[i + 1];
7050
- const f = (t - ((_d = a.time) != null ? _d : 0)) / (((_e = b.time) != null ? _e : 0) - ((_f = a.time) != null ? _f : 0) || 1);
7051
- return lerp(a.value, b.value, f);
7052
- }
7053
- return staticVal !== void 0 ? Number(staticVal) : fallback;
7054
- }
7055
- var CONTAINER_TYPES = /* @__PURE__ */ new Set(["svg", "g", "symbol"]);
7056
- var SKIP_TYPES = /* @__PURE__ */ new Set(["defs", "mask", "clipPath", "title"]);
7057
- function buildIdMap2(node, map) {
7058
- var _a2;
7059
- if (typeof node.id === "string") map.set(node.id, node);
7060
- (_a2 = node.children) == null ? void 0 : _a2.forEach((c) => buildIdMap2(c, map));
7061
- }
7062
- function num(v) {
7063
- return v === void 0 || v === null ? 0 : Number(v);
7064
- }
7065
- function round(n) {
7066
- return Math.round(n * 100) / 100 + 0;
7067
- }
7068
- function geomKey(node) {
7069
- var _a2;
7070
- switch (node.type) {
7071
- case "rect":
7072
- return num(node.width) + "," + num(node.height) + "," + num(node.x) + "," + num(node.y);
7073
- case "ellipse":
7074
- return num(node.rx) + "," + num(node.ry) + "," + num(node.cx) + "," + num(node.cy);
7075
- case "circle":
7076
- return num(node.r) + "," + num(node.cx) + "," + num(node.cy);
7077
- case "path":
7078
- return String((_a2 = node.d) != null ? _a2 : "");
7079
- default:
7080
- return "";
7081
- }
7082
- }
7083
- function describePrimitive(node, m, t) {
7084
- var _a2, _b, _c, _d, _e;
7085
- const fill = (_a2 = node.fill) != null ? _a2 : "";
7086
- const stroke = (_b = node.stroke) != null ? _b : "";
7087
- const sw = (_d = (_c = node["stroke-width"]) != null ? _c : node.strokeWidth) != null ? _d : "";
7088
- const opacity = round(evalScalar((_e = node.animate) == null ? void 0 : _e.opacity, node.opacity, 1, t));
7089
- const masked = node.mask ? 1 : 0;
7090
- const mat = m.map(round).join(",");
7091
- return node.type + "|" + geomKey(node) + "|[" + mat + "]|f:" + fill + "|s:" + stroke + "|sw:" + (num(sw) || "") + "|o:" + opacity + "|m:" + masked;
7092
- }
7093
- function flatten(node, parent, t, idMap, out) {
7094
- var _a2;
7095
- const type = node.type || "";
7096
- if (SKIP_TYPES.has(type)) return;
7097
- const m = mul(parent, nodeMatrix(node, t));
7098
- if (type === "use") {
7099
- const targetId = typeof node.href === "string" ? node.href.replace(/^#/, "") : "";
7100
- const target = idMap.get(targetId);
7101
- const useM = mul(m, translateM(num(node.x), num(node.y)));
7102
- if (target) flatten(target, useM, t, idMap, out);
7103
- else out.push("UNRESOLVED_USE:#" + targetId);
7104
- return;
7105
- }
7106
- if (CONTAINER_TYPES.has(type)) {
7107
- (_a2 = node.children) == null ? void 0 : _a2.forEach((c) => flatten(c, m, t, idMap, out));
7108
- return;
7109
- }
7110
- out.push(describePrimitive(node, m, t));
7111
- }
7112
- function collectSampleTimes(node, into) {
7113
- var _a2;
7114
- into.add(0);
7115
- const scanAnim = (anim) => {
7116
- var _a3;
7117
- if (!anim || typeof anim !== "object") return;
7118
- for (const key of Object.keys(anim)) {
7119
- const kfs = (_a3 = anim[key]) == null ? void 0 : _a3.keyframes;
7120
- if (Array.isArray(kfs)) kfs.forEach((kf) => {
7121
- var _a4;
7122
- return into.add((_a4 = kf.time) != null ? _a4 : 0);
7123
- });
7124
- }
7125
- };
7126
- scanAnim(node.animate);
7127
- if (node.transform && typeof node.transform === "object" && node.transform.keyframes) {
7128
- node.transform.keyframes.forEach((kf) => {
7129
- var _a3;
7130
- return into.add((_a3 = kf.time) != null ? _a3 : 0);
7131
- });
7132
- }
7133
- (_a2 = node.children) == null ? void 0 : _a2.forEach((c) => collectSampleTimes(c, into));
7134
- }
7135
- function visualModelAt(root, t) {
7136
- const idMap = /* @__PURE__ */ new Map();
7137
- buildIdMap2(root, idMap);
7138
- const out = [];
7139
- flatten(root, IDENTITY, t, idMap, out);
7140
- return out.sort();
7141
- }
7142
- function diffInEffect(a, b) {
7143
- const times = /* @__PURE__ */ new Set();
7144
- collectSampleTimes(a, times);
7145
- collectSampleTimes(b, times);
7146
- const diffs = [];
7147
- for (const t of Array.from(times).sort((x, y) => x - y)) {
7148
- const ma = visualModelAt(a, t);
7149
- const mb = visualModelAt(b, t);
7150
- const onlyInA = subtractMultiset(ma, mb);
7151
- const onlyInB = subtractMultiset(mb, ma);
7152
- if (onlyInA.length || onlyInB.length) diffs.push({ time: t, onlyInA, onlyInB });
7153
- }
7154
- return diffs;
7155
- }
7156
- function subtractMultiset(a, b) {
7157
- const counts = /* @__PURE__ */ new Map();
7158
- for (const x of b) counts.set(x, (counts.get(x) || 0) + 1);
7159
- const extra = [];
7160
- for (const x of a) {
7161
- const c = counts.get(x) || 0;
7162
- if (c > 0) counts.set(x, c - 1);
7163
- else extra.push(x);
7164
- }
7165
- return extra;
7166
- }
7167
6465
 
7168
6466
  // src/playback/PxAnimatorConfigPatch.ts
7169
6467
  var FLAT_ONLY_KEYS = [
@@ -7179,7 +6477,7 @@ var FLAT_ONLY_KEYS = [
7179
6477
  "mode",
7180
6478
  "frameRate"
7181
6479
  ];
7182
- var CONTENT_KEYS = ["definitions", "animateById"];
6480
+ var CONTENT_KEYS = ["definitions", "bindings"];
7183
6481
  var isPlainObject = (v) => !!v && typeof v === "object" && !Array.isArray(v);
7184
6482
  var timelineTypeOf = (t) => isPlainObject(t) && typeof t.type === "string" ? t.type : "time";
7185
6483
  var isScrollish = (type) => type === "scroll" || type === "view";
@@ -7283,9 +6581,9 @@ function mergeAnimatorConfig(base, patch) {
7283
6581
  }
7284
6582
  return { config: out, warnings };
7285
6583
  }
7286
- function applyAnimatorConfig(doc, patch, opts) {
6584
+ function applyAnimatorConfig(doc, patch, options) {
7287
6585
  var _a2, _b;
7288
- const reset = !!(opts == null ? void 0 : opts.resetDefaults);
6586
+ const reset = !!(options == null ? void 0 : options.resetTimeline);
7289
6587
  if (!doc || (patch === void 0 || !reset && (patch === null || !isPlainObject(patch) || !Object.keys(patch).length))) {
7290
6588
  return { doc, warnings: [] };
7291
6589
  }
@@ -7318,7 +6616,6 @@ function applyAnimatorConfig(doc, patch, opts) {
7318
6616
  }
7319
6617
 
7320
6618
  // src/format/PxDocumentDiagnostic.ts
7321
- var MAX_REPORTED = 6;
7322
6619
  function diagnoseDocument(doc) {
7323
6620
  try {
7324
6621
  return { problems: validateDocument(doc) };
@@ -7326,49 +6623,27 @@ function diagnoseDocument(doc) {
7326
6623
  return { problems: [] };
7327
6624
  }
7328
6625
  }
7329
- function reportDocumentDiagnostics(doc, where) {
7330
- const { problems } = diagnoseDocument(doc);
7331
- if (!problems.length) return;
7332
- const shown = problems.slice(0, MAX_REPORTED);
7333
- const more = problems.length - shown.length;
7334
- console.warn(
7335
- where + ": this document does not match the animation schema in " + problems.length + " place" + (problems.length === 1 ? "" : "s") + ".\n" + shown.map((p) => " - " + p).join("\n") + (more > 0 ? "\n \u2026 and " + more + " more" : "") + "\n\nIf you did not author these keys, the usual cause is a build that MANGLES PROPERTY NAMES. An animation document is data loaded at runtime, so renaming the property reads inside the player stops them matching the keys in the JSON, and the animation silently does nothing. Feed the published reserved-name list to your minifier \u2014 @pixodesk/svg-animator-web/mangle-reserved.json \u2014 see docs/library/minification.md."
7336
- );
7337
- }
7338
6626
  // Annotate the CommonJS export names for ESM import in node:
7339
6627
  0 && (module.exports = {
7340
- BASELINE_PLAYER_VERSION,
7341
- COLOR_ATTR_NAMES,
7342
- CSS_ONLY_STYLE_PROPS,
7343
- DEFAULT_DURATION_MS,
7344
- DISALLOWED_SVG_TAGS_LOWER,
7345
- INTERNAL_ATTRS,
7346
- LOOP_JUMP_SHIFT_MS,
7347
- MISSING_GLYPH_CLASS_NAME,
7348
- PCT_BASED_ATTR_NAMES,
7349
- PLAYER_WIRE_STEPS,
7350
- PLAYER_WIRE_VERSION,
7351
- PX_ANIM_ATTR_NAME,
7352
- PX_ANIM_SRC_ATTR_NAME,
7353
- PX_PLAYER_SCHEMA_VERSION,
7354
6628
  PX_RATE_REJECTED,
7355
6629
  PX_TRANSFORM_PART_KEYS,
7356
6630
  PX_TRIGGER_DEFAULTS,
7357
- PX_UNKNOWN_KEY_ERROR,
6631
+ PX_WIRE_BASELINE_VERSION,
6632
+ PX_WIRE_SCHEMA_VERSION,
6633
+ PX_WIRE_STEPS,
6634
+ PX_WIRE_VERSION,
6635
+ PX_WIRE_VERSION_KEY,
7358
6636
  PxAlongPathMode,
7359
6637
  PxAnimatedSvgDocumentSchema,
7360
- PxAnimationDefinitionSchema,
7361
6638
  PxAnimatorConfigSchema,
7362
6639
  PxAttrValueSchema,
7363
6640
  PxBezierPathSchema,
7364
- PxBindingSchema,
7365
6641
  PxClipPathEffectSchema,
7366
6642
  PxCloneEffectSchema,
7367
6643
  PxCloneWithout,
7368
6644
  PxControlMode,
7369
- PxDefsSchema,
6645
+ PxDefinitionsSchema,
7370
6646
  PxDiagnosticKind,
7371
- PxEasingOrRefSchema,
7372
6647
  PxEffectsSchema,
7373
6648
  PxElementAnimationSchema,
7374
6649
  PxFillGradientEffectSchema,
@@ -7385,7 +6660,7 @@ function reportDocumentDiagnostics(doc, where) {
7385
6660
  PxLoopSchema,
7386
6661
  PxMaskType,
7387
6662
  PxMaskedByEffectSchema,
7388
- PxNodeBase,
6663
+ PxNodeBaseSchema,
7389
6664
  PxNodeSchema,
7390
6665
  PxOutAction,
7391
6666
  PxPathOverflow,
@@ -7402,127 +6677,67 @@ function reportDocumentDiagnostics(doc, where) {
7402
6677
  PxScrollSchema,
7403
6678
  PxScrollSource,
7404
6679
  PxStartOn,
7405
- PxStrokeGradientEffectSchema,
7406
6680
  PxStrokeTrimEffectSchema,
7407
6681
  PxStrokeTrimSubPaths,
7408
- PxSvgNodeExtra,
6682
+ PxSvgNodeRootSchema,
7409
6683
  PxTextEffectSchema,
7410
6684
  PxTextPathEffectSchema,
7411
6685
  PxTextPathMethod,
7412
6686
  PxTextPathSpacing,
7413
6687
  PxTimelineEngine,
7414
- PxTimelineEngineExtra,
7415
- PxTimelinePinSchema,
6688
+ PxTimelineEngineSetting,
7416
6689
  PxTimelineSchema,
7417
6690
  PxTransformByEffectSchema,
7418
6691
  PxTransformPartsSchema,
7419
6692
  PxTransformValueSchema,
7420
6693
  PxTriggerSchema,
7421
6694
  PxUnits,
7422
- STYLE_ATTR_NAMES,
7423
- TEXT_CONTENT_ATTR,
7424
- TRANSFORM_FN_NAMES,
7425
- WIRE_VERSION_KEY,
7426
- WireStepKind,
7427
- WireVersionRelation,
6695
+ PxWireStepKind,
6696
+ PxWireVersionRelation,
7428
6697
  applyAnimatorConfig,
7429
- applyPlayerEffects,
7430
6698
  applyWireSteps,
7431
- applyWireStepsDown,
7432
- bezierToSvgPath,
7433
6699
  calcAnimationValues,
7434
- camelCaseToKebabWordIfNeeded,
7435
- clamp,
7436
6700
  clampSeekMs,
7437
- collectSampleTimes,
7438
6701
  compareWireVersion,
7439
- composeTransformParts,
7440
6702
  controlModeTakesOverTrigger,
7441
- convertPlayerDocument,
7442
- createBasicFrameLoopAnimator,
7443
- createDiagnostics,
7444
- createPathSampler,
6703
+ convertWireDocument,
6704
+ createAdapterAnimator,
7445
6705
  createRunClock,
7446
- cubicBezier,
7447
- deepClone,
7448
6706
  describeSchema,
7449
6707
  diagnoseDocument,
7450
- diffFieldUniverse,
7451
- diffInEffect,
7452
- downgradePlayerDocument,
7453
- evaluateMotionPathSegment,
7454
- extendedPathForBrowser,
6708
+ downgradeWireDocument,
7455
6709
  flattenAnimatorTimeline,
7456
6710
  foldTimelineOverride,
7457
6711
  formatWireVersion,
7458
6712
  generateNewIds,
7459
- generateUniqueId,
7460
6713
  getAnimatorConfig,
7461
6714
  getBindings,
7462
6715
  getChildren,
7463
- getDefs,
7464
- getNormalizedBindings,
7465
- getNormalizedProps,
7466
- interpolateBeziers,
7467
- interpolateValue,
6716
+ getDefinitions,
7468
6717
  isNativeForced,
7469
- isPxElementFileFormat,
7470
- isPxElementFileFormatDeep,
7471
- isScrollTimeline,
6718
+ isPxDocument,
7472
6719
  isValidPlaybackRate,
7473
- jsonElementFactory,
7474
- kebabToCamelCaseWord,
7475
- kfEasing,
7476
- kfTangentIn,
7477
- kfTangentOut,
7478
- kfTime,
7479
- kfValue,
7480
- layoutGlyphTextChars,
6720
+ isValidPxDocument,
7481
6721
  materializeAllInTree,
7482
- materializeAnimatedUseInstances,
7483
- materializeGlyphText,
7484
- materializeGlyphTextAlongPath,
7485
- materializeGlyphTextHorizontal,
7486
- materializeInternalLoopsInPropAnim,
7487
- materializeInternalLoopsInTree,
7488
- materializeMotionPathInPropAnim,
7489
- materializeMotionPathsInTree,
6722
+ materializeNodeEffects,
7490
6723
  mayUseNativeScrollTimeline,
7491
6724
  mergeAnimatorConfig,
7492
- mergeStaticTransformIntoAnimDef,
7493
6725
  nestAnimatorTimeline,
7494
- parseTransformParts,
6726
+ normalizeBindings,
7495
6727
  parseWireVersion,
7496
- planSchemaRelease,
7497
6728
  progressSpanMs,
7498
6729
  progressToTimeMs,
7499
- propAnimIsMotionPath,
7500
6730
  px,
7501
6731
  readWireVersion,
7502
- releaseLogProblems,
7503
- reportDocumentDiagnostics,
7504
6732
  resolveControlMode,
7505
- resolveStyle,
7506
6733
  resolveTimelineEngine,
7507
6734
  resolveTrigger,
7508
- reverseEasing,
7509
- sanitizeAttributeValue,
7510
- schemaFieldUniverse,
7511
6735
  schemaKeys,
7512
- scrollOffsetProgress,
7513
- scrollPhaseInterval,
7514
- scrollResolveAxis,
7515
- scrollTotalDurationMs,
7516
- scrollViewProgress,
7517
6736
  seekCeilingMs,
7518
- shiftAnimatable,
7519
- splitEasing,
7520
- subdivideCubicBezier,
7521
6737
  timeToProgress,
7522
- toRGBA,
6738
+ toDomProps,
7523
6739
  validateDocument,
7524
6740
  validateNodeEffects,
7525
- versionAdvice,
7526
- visualModelAt
6741
+ wireVersionAdvice
7527
6742
  });
7528
6743
  //# sourceMappingURL=index.cjs.map