@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/README.md +59 -14
- package/dist/PxDocumentDiagnostic-COGEjBbg.d.cts +10987 -0
- package/dist/PxDocumentDiagnostic-COGEjBbg.d.ts +10987 -0
- package/dist/chunk-7ZO7PQKZ.min.js +1 -0
- package/dist/chunk-L6GJ6Y2M.js +4595 -0
- package/dist/chunk-L6GJ6Y2M.js.map +1 -0
- package/dist/index.cjs +1193 -1978
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +40 -12317
- package/dist/index.d.ts +40 -12317
- package/dist/index.js +469 -5230
- package/dist/index.js.map +1 -1
- package/dist/index.min.cjs +1 -1
- package/dist/index.min.js +1 -1
- package/dist/internal.cjs +3513 -0
- package/dist/internal.cjs.map +1 -0
- package/dist/internal.d.cts +378 -0
- package/dist/internal.d.ts +378 -0
- package/dist/internal.js +480 -0
- package/dist/internal.js.map +1 -0
- package/dist/internal.min.cjs +1 -0
- package/dist/internal.min.js +1 -0
- package/package.json +6 -1
|
@@ -0,0 +1,3513 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __defProps = Object.defineProperties;
|
|
4
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
5
|
+
var __getOwnPropDescs = Object.getOwnPropertyDescriptors;
|
|
6
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
7
|
+
var __getOwnPropSymbols = Object.getOwnPropertySymbols;
|
|
8
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
9
|
+
var __propIsEnum = Object.prototype.propertyIsEnumerable;
|
|
10
|
+
var __pow = Math.pow;
|
|
11
|
+
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
|
|
12
|
+
var __spreadValues = (a, b) => {
|
|
13
|
+
for (var prop in b || (b = {}))
|
|
14
|
+
if (__hasOwnProp.call(b, prop))
|
|
15
|
+
__defNormalProp(a, prop, b[prop]);
|
|
16
|
+
if (__getOwnPropSymbols)
|
|
17
|
+
for (var prop of __getOwnPropSymbols(b)) {
|
|
18
|
+
if (__propIsEnum.call(b, prop))
|
|
19
|
+
__defNormalProp(a, prop, b[prop]);
|
|
20
|
+
}
|
|
21
|
+
return a;
|
|
22
|
+
};
|
|
23
|
+
var __spreadProps = (a, b) => __defProps(a, __getOwnPropDescs(b));
|
|
24
|
+
var __objRest = (source, exclude) => {
|
|
25
|
+
var target = {};
|
|
26
|
+
for (var prop in source)
|
|
27
|
+
if (__hasOwnProp.call(source, prop) && exclude.indexOf(prop) < 0)
|
|
28
|
+
target[prop] = source[prop];
|
|
29
|
+
if (source != null && __getOwnPropSymbols)
|
|
30
|
+
for (var prop of __getOwnPropSymbols(source)) {
|
|
31
|
+
if (exclude.indexOf(prop) < 0 && __propIsEnum.call(source, prop))
|
|
32
|
+
target[prop] = source[prop];
|
|
33
|
+
}
|
|
34
|
+
return target;
|
|
35
|
+
};
|
|
36
|
+
var __export = (target, all) => {
|
|
37
|
+
for (var name in all)
|
|
38
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
39
|
+
};
|
|
40
|
+
var __copyProps = (to, from, except, desc) => {
|
|
41
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
42
|
+
for (let key of __getOwnPropNames(from))
|
|
43
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
44
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
45
|
+
}
|
|
46
|
+
return to;
|
|
47
|
+
};
|
|
48
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
49
|
+
|
|
50
|
+
// src/internal.ts
|
|
51
|
+
var internal_exports = {};
|
|
52
|
+
__export(internal_exports, {
|
|
53
|
+
PX_ANIM_ATTR_NAME: () => PX_ANIM_ATTR_NAME,
|
|
54
|
+
PX_ANIM_SRC_ATTR_NAME: () => PX_ANIM_SRC_ATTR_NAME,
|
|
55
|
+
PX_COLOR_ATTR_NAMES: () => PX_COLOR_ATTR_NAMES,
|
|
56
|
+
PX_CSS_ONLY_STYLE_PROPS: () => PX_CSS_ONLY_STYLE_PROPS,
|
|
57
|
+
PX_DEFAULT_DURATION_MS: () => PX_DEFAULT_DURATION_MS,
|
|
58
|
+
PX_DISALLOWED_SVG_TAGS_LOWER: () => PX_DISALLOWED_SVG_TAGS_LOWER,
|
|
59
|
+
PX_LOOP_JUMP_SHIFT_MS: () => PX_LOOP_JUMP_SHIFT_MS,
|
|
60
|
+
PX_PCT_BASED_ATTR_NAMES: () => PX_PCT_BASED_ATTR_NAMES,
|
|
61
|
+
PX_STYLE_ATTR_NAMES: () => PX_STYLE_ATTR_NAMES,
|
|
62
|
+
PX_TEXT_CONTENT_ATTR: () => PX_TEXT_CONTENT_ATTR,
|
|
63
|
+
PX_TRANSFORM_FN_NAMES: () => PX_TRANSFORM_FN_NAMES,
|
|
64
|
+
PX_UNKNOWN_KEY_ERROR: () => PX_UNKNOWN_KEY_ERROR,
|
|
65
|
+
bezierToSvgPath: () => bezierToSvgPath,
|
|
66
|
+
camelCaseToKebabWordIfNeeded: () => camelCaseToKebabWordIfNeeded,
|
|
67
|
+
clamp: () => clamp,
|
|
68
|
+
composeTransformParts: () => composeTransformParts,
|
|
69
|
+
createDiagnostics: () => createDiagnostics,
|
|
70
|
+
createPathSampler: () => createPathSampler,
|
|
71
|
+
cubicBezier: () => cubicBezier,
|
|
72
|
+
deepClone: () => deepClone,
|
|
73
|
+
diffFieldUniverse: () => diffFieldUniverse,
|
|
74
|
+
diffInEffect: () => diffInEffect,
|
|
75
|
+
extendedPathForBrowser: () => extendedPathForBrowser,
|
|
76
|
+
generateUniqueId: () => generateUniqueId,
|
|
77
|
+
interpolateValue: () => interpolateValue,
|
|
78
|
+
isScrollTimeline: () => isScrollTimeline,
|
|
79
|
+
kebabToCamelCaseWord: () => kebabToCamelCaseWord,
|
|
80
|
+
keyframeEasing: () => keyframeEasing,
|
|
81
|
+
keyframeValue: () => keyframeValue,
|
|
82
|
+
layoutGlyphTextChars: () => layoutGlyphTextChars,
|
|
83
|
+
materializeGlyphText: () => materializeGlyphText,
|
|
84
|
+
materializeGlyphTextAlongPath: () => materializeGlyphTextAlongPath,
|
|
85
|
+
materializeMotionPathInPropAnim: () => materializeMotionPathInPropAnim,
|
|
86
|
+
mergeStaticTransformIntoAnimDef: () => mergeStaticTransformIntoAnimDef,
|
|
87
|
+
planSchemaRelease: () => planSchemaRelease,
|
|
88
|
+
releaseLogProblems: () => releaseLogProblems,
|
|
89
|
+
reportDocumentDiagnostics: () => reportDocumentDiagnostics,
|
|
90
|
+
reverseEasing: () => reverseEasing,
|
|
91
|
+
sanitizeAttributeValue: () => sanitizeAttributeValue,
|
|
92
|
+
schemaFieldUniverse: () => schemaFieldUniverse,
|
|
93
|
+
scrollOffsetProgress: () => scrollOffsetProgress,
|
|
94
|
+
scrollPhaseInterval: () => scrollPhaseInterval,
|
|
95
|
+
scrollResolveAxis: () => scrollResolveAxis,
|
|
96
|
+
scrollTotalDurationMs: () => scrollTotalDurationMs,
|
|
97
|
+
scrollViewProgress: () => scrollViewProgress,
|
|
98
|
+
splitEasing: () => splitEasing,
|
|
99
|
+
subdivideCubicBezier: () => subdivideCubicBezier,
|
|
100
|
+
toRGBA: () => toRGBA
|
|
101
|
+
});
|
|
102
|
+
module.exports = __toCommonJS(internal_exports);
|
|
103
|
+
|
|
104
|
+
// src/schema/PxSchema.ts
|
|
105
|
+
var PX_UNKNOWN_KEY_ERROR = "unexpected extra key";
|
|
106
|
+
function pathStr(path) {
|
|
107
|
+
if (!path.length) return ".";
|
|
108
|
+
let result = "";
|
|
109
|
+
for (const seg of path) {
|
|
110
|
+
if (seg.startsWith("[")) result += seg;
|
|
111
|
+
else result += (result ? "." : "") + seg;
|
|
112
|
+
}
|
|
113
|
+
return result;
|
|
114
|
+
}
|
|
115
|
+
var Base = class {
|
|
116
|
+
_canSanitize(raw) {
|
|
117
|
+
return this.isValid(raw);
|
|
118
|
+
}
|
|
119
|
+
optional() {
|
|
120
|
+
return new Optional(this);
|
|
121
|
+
}
|
|
122
|
+
};
|
|
123
|
+
var Optional = class extends Base {
|
|
124
|
+
constructor(inner) {
|
|
125
|
+
super();
|
|
126
|
+
this.inner = inner;
|
|
127
|
+
this._default = void 0;
|
|
128
|
+
}
|
|
129
|
+
sanitize(raw) {
|
|
130
|
+
if (raw === void 0 || raw === null) return void 0;
|
|
131
|
+
return this.inner._canSanitize(raw) ? this.inner.sanitize(raw) : void 0;
|
|
132
|
+
}
|
|
133
|
+
isValid(raw, ctx, path) {
|
|
134
|
+
if (raw === void 0 || raw === null) return true;
|
|
135
|
+
return this.inner.isValid(raw, ctx, path);
|
|
136
|
+
}
|
|
137
|
+
_canSanitize(raw) {
|
|
138
|
+
return raw === void 0 || raw === null || this.inner._canSanitize(raw);
|
|
139
|
+
}
|
|
140
|
+
};
|
|
141
|
+
var Str = class extends Base {
|
|
142
|
+
constructor(_default = "") {
|
|
143
|
+
super();
|
|
144
|
+
this._default = _default;
|
|
145
|
+
}
|
|
146
|
+
sanitize(raw) {
|
|
147
|
+
return typeof raw === "string" ? raw : this._default;
|
|
148
|
+
}
|
|
149
|
+
isValid(raw, ctx, path) {
|
|
150
|
+
if (typeof raw === "string") return true;
|
|
151
|
+
ctx == null ? void 0 : ctx.errors.push(pathStr(path != null ? path : []) + ": expected string, got " + typeof raw);
|
|
152
|
+
return false;
|
|
153
|
+
}
|
|
154
|
+
};
|
|
155
|
+
var Num = class extends Base {
|
|
156
|
+
constructor(_default = 0) {
|
|
157
|
+
super();
|
|
158
|
+
this._default = _default;
|
|
159
|
+
}
|
|
160
|
+
sanitize(raw) {
|
|
161
|
+
return typeof raw === "number" && isFinite(raw) ? raw : this._default;
|
|
162
|
+
}
|
|
163
|
+
isValid(raw, ctx, path) {
|
|
164
|
+
if (typeof raw === "number" && isFinite(raw)) return true;
|
|
165
|
+
ctx == null ? void 0 : ctx.errors.push(pathStr(path != null ? path : []) + ": expected finite number, got " + JSON.stringify(raw));
|
|
166
|
+
return false;
|
|
167
|
+
}
|
|
168
|
+
};
|
|
169
|
+
var Bool = class extends Base {
|
|
170
|
+
constructor(_default = false) {
|
|
171
|
+
super();
|
|
172
|
+
this._default = _default;
|
|
173
|
+
}
|
|
174
|
+
sanitize(raw) {
|
|
175
|
+
return typeof raw === "boolean" ? raw : this._default;
|
|
176
|
+
}
|
|
177
|
+
isValid(raw, ctx, path) {
|
|
178
|
+
if (typeof raw === "boolean") return true;
|
|
179
|
+
ctx == null ? void 0 : ctx.errors.push(pathStr(path != null ? path : []) + ": expected boolean, got " + typeof raw);
|
|
180
|
+
return false;
|
|
181
|
+
}
|
|
182
|
+
};
|
|
183
|
+
var Literal = class extends Base {
|
|
184
|
+
constructor(value) {
|
|
185
|
+
super();
|
|
186
|
+
this.value = value;
|
|
187
|
+
this._default = value;
|
|
188
|
+
}
|
|
189
|
+
sanitize(raw) {
|
|
190
|
+
return raw === this.value ? this.value : this._default;
|
|
191
|
+
}
|
|
192
|
+
isValid(raw, ctx, path) {
|
|
193
|
+
if (raw === this.value) return true;
|
|
194
|
+
ctx == null ? void 0 : ctx.errors.push(pathStr(path != null ? path : []) + ": expected " + JSON.stringify(this.value) + ", got " + JSON.stringify(raw));
|
|
195
|
+
return false;
|
|
196
|
+
}
|
|
197
|
+
};
|
|
198
|
+
var Enum = class extends Base {
|
|
199
|
+
constructor(values, defaultVal) {
|
|
200
|
+
super();
|
|
201
|
+
this.values = values;
|
|
202
|
+
this._default = defaultVal != null ? defaultVal : values[0];
|
|
203
|
+
}
|
|
204
|
+
sanitize(raw) {
|
|
205
|
+
return this.values.includes(raw) ? raw : this._default;
|
|
206
|
+
}
|
|
207
|
+
isValid(raw, ctx, path) {
|
|
208
|
+
if (this.values.includes(raw)) return true;
|
|
209
|
+
ctx == null ? void 0 : ctx.errors.push(pathStr(path != null ? path : []) + ": expected one of " + this.values.map((v) => JSON.stringify(v)).join(" | ") + ", got " + JSON.stringify(raw));
|
|
210
|
+
return false;
|
|
211
|
+
}
|
|
212
|
+
};
|
|
213
|
+
var UNION_MEMBER_ERROR_LIMIT = 4;
|
|
214
|
+
var Union = class extends Base {
|
|
215
|
+
constructor(schemas, defaultVal) {
|
|
216
|
+
super();
|
|
217
|
+
this.schemas = schemas;
|
|
218
|
+
/** Structural tag read by {@link describeSchema} — `schemas` alone cannot tell Union from Tuple. */
|
|
219
|
+
this._kind = "union";
|
|
220
|
+
this._default = defaultVal != null ? defaultVal : schemas[0]._default;
|
|
221
|
+
}
|
|
222
|
+
sanitize(raw) {
|
|
223
|
+
for (const s of this.schemas) {
|
|
224
|
+
if (s.isValid(raw)) return s.sanitize(raw);
|
|
225
|
+
}
|
|
226
|
+
return this._default;
|
|
227
|
+
}
|
|
228
|
+
isValid(raw, ctx, path) {
|
|
229
|
+
var _a2;
|
|
230
|
+
const probe = ctx && { errors: [], warnings: [], strict: ctx.strict };
|
|
231
|
+
if (this.schemas.some((s) => s.isValid(raw, probe, path ? [...path] : void 0))) return true;
|
|
232
|
+
if (!ctx) return false;
|
|
233
|
+
const base = pathStr(path != null ? path : []);
|
|
234
|
+
ctx.errors.push(base + ": no union member matched for value " + ((_a2 = JSON.stringify(raw)) != null ? _a2 : "").slice(0, 240));
|
|
235
|
+
let best;
|
|
236
|
+
let bestDepth = -1;
|
|
237
|
+
const leafExpectations = [];
|
|
238
|
+
for (const member of this.schemas) {
|
|
239
|
+
const sink = { errors: [], warnings: [], strict: ctx.strict };
|
|
240
|
+
member.isValid(raw, sink, path ? [...path] : void 0);
|
|
241
|
+
if (!sink.errors.length) continue;
|
|
242
|
+
const depth = Math.max(...sink.errors.map((e) => e.slice(0, e.indexOf(":")).length));
|
|
243
|
+
if (depth > bestDepth || depth === bestDepth && best && sink.errors.length < best.length) {
|
|
244
|
+
bestDepth = depth;
|
|
245
|
+
best = sink.errors;
|
|
246
|
+
}
|
|
247
|
+
if (depth <= base.length) {
|
|
248
|
+
for (const e of sink.errors) {
|
|
249
|
+
const m = /: expected (.+?), got /.exec(e);
|
|
250
|
+
if (m && !leafExpectations.includes(m[1])) leafExpectations.push(m[1]);
|
|
251
|
+
}
|
|
252
|
+
}
|
|
253
|
+
}
|
|
254
|
+
if (best && bestDepth > base.length) {
|
|
255
|
+
for (const e of best.slice(0, UNION_MEMBER_ERROR_LIMIT)) {
|
|
256
|
+
if (!ctx.errors.includes(e)) ctx.errors.push(e);
|
|
257
|
+
}
|
|
258
|
+
} else if (leafExpectations.length) {
|
|
259
|
+
ctx.errors.push(base + ": expected " + leafExpectations.join(" | "));
|
|
260
|
+
}
|
|
261
|
+
return false;
|
|
262
|
+
}
|
|
263
|
+
_canSanitize(raw) {
|
|
264
|
+
return this.schemas.some((s) => s._canSanitize(raw));
|
|
265
|
+
}
|
|
266
|
+
};
|
|
267
|
+
var DiscriminatedUnion = class extends Base {
|
|
268
|
+
constructor(_key, _schemas, defaultVal) {
|
|
269
|
+
var _a2;
|
|
270
|
+
super();
|
|
271
|
+
this._key = _key;
|
|
272
|
+
this._schemas = _schemas;
|
|
273
|
+
/** Structural tag read by {@link describeSchema}. */
|
|
274
|
+
this._kind = "discriminatedUnion";
|
|
275
|
+
this._default = defaultVal != null ? defaultVal : _schemas[0]._default;
|
|
276
|
+
this._map = /* @__PURE__ */ new Map();
|
|
277
|
+
for (const s of _schemas) {
|
|
278
|
+
const keySchema = s._shape[_key];
|
|
279
|
+
if (!keySchema) continue;
|
|
280
|
+
const literal = (_a2 = keySchema.inner) != null ? _a2 : keySchema;
|
|
281
|
+
this._map.set(literal._default, s);
|
|
282
|
+
if (keySchema.inner) this._absentMember = s;
|
|
283
|
+
}
|
|
284
|
+
}
|
|
285
|
+
_findSchema(raw) {
|
|
286
|
+
if (raw === null || typeof raw !== "object" || Array.isArray(raw)) return void 0;
|
|
287
|
+
const val = raw[this._key];
|
|
288
|
+
if (val === void 0 || val === null) return this._absentMember;
|
|
289
|
+
return this._map.get(val);
|
|
290
|
+
}
|
|
291
|
+
sanitize(raw) {
|
|
292
|
+
var _a2;
|
|
293
|
+
return ((_a2 = this._findSchema(raw)) != null ? _a2 : this._schemas[0]).sanitize(raw);
|
|
294
|
+
}
|
|
295
|
+
isValid(raw, ctx, path) {
|
|
296
|
+
const schema = this._findSchema(raw);
|
|
297
|
+
if (!schema) {
|
|
298
|
+
const val = raw !== null && typeof raw === "object" && !Array.isArray(raw) ? raw[this._key] : void 0;
|
|
299
|
+
ctx == null ? void 0 : ctx.errors.push(pathStr(path != null ? path : []) + ": no discriminated union member matched " + this._key + "=" + JSON.stringify(val));
|
|
300
|
+
return false;
|
|
301
|
+
}
|
|
302
|
+
return schema.isValid(raw, ctx, path);
|
|
303
|
+
}
|
|
304
|
+
_canSanitize(raw) {
|
|
305
|
+
if (raw === null || typeof raw !== "object" || Array.isArray(raw)) return false;
|
|
306
|
+
const schema = this._findSchema(raw);
|
|
307
|
+
return schema ? schema._canSanitize(raw) : this._schemas[0]._canSanitize(raw);
|
|
308
|
+
}
|
|
309
|
+
};
|
|
310
|
+
var Obj = class extends Base {
|
|
311
|
+
constructor(_shape) {
|
|
312
|
+
super();
|
|
313
|
+
this._shape = _shape;
|
|
314
|
+
const d = {};
|
|
315
|
+
for (const key of Object.keys(_shape)) d[key] = _shape[key]._default;
|
|
316
|
+
this._default = d;
|
|
317
|
+
}
|
|
318
|
+
sanitize(raw) {
|
|
319
|
+
const src = raw && typeof raw === "object" && !Array.isArray(raw) ? raw : {};
|
|
320
|
+
const out = {};
|
|
321
|
+
for (const key of Object.keys(this._shape)) {
|
|
322
|
+
const v = this._shape[key].sanitize(src[key]);
|
|
323
|
+
if (v !== void 0) out[key] = v;
|
|
324
|
+
}
|
|
325
|
+
return out;
|
|
326
|
+
}
|
|
327
|
+
isValid(raw, ctx, path) {
|
|
328
|
+
if (!raw || typeof raw !== "object" || Array.isArray(raw)) {
|
|
329
|
+
ctx == null ? void 0 : ctx.errors.push(pathStr(path != null ? path : []) + ": expected object, got " + (Array.isArray(raw) ? "array" : typeof raw));
|
|
330
|
+
return false;
|
|
331
|
+
}
|
|
332
|
+
const obj = raw;
|
|
333
|
+
const p = path != null ? path : [];
|
|
334
|
+
let ok = true;
|
|
335
|
+
for (const key of Object.keys(this._shape)) {
|
|
336
|
+
p.push(key);
|
|
337
|
+
if (!this._shape[key].isValid(obj[key], ctx, p)) ok = false;
|
|
338
|
+
p.pop();
|
|
339
|
+
}
|
|
340
|
+
if (ctx == null ? void 0 : ctx.strict) {
|
|
341
|
+
for (const key of Object.keys(obj)) {
|
|
342
|
+
if (key in this._shape) continue;
|
|
343
|
+
if (obj[key] === void 0) continue;
|
|
344
|
+
p.push(key);
|
|
345
|
+
ctx.errors.push(pathStr(p) + ": " + PX_UNKNOWN_KEY_ERROR);
|
|
346
|
+
p.pop();
|
|
347
|
+
ok = false;
|
|
348
|
+
}
|
|
349
|
+
}
|
|
350
|
+
return ok;
|
|
351
|
+
}
|
|
352
|
+
_canSanitize(raw) {
|
|
353
|
+
return !!raw && typeof raw === "object" && !Array.isArray(raw);
|
|
354
|
+
}
|
|
355
|
+
};
|
|
356
|
+
var OpenObj = class extends Base {
|
|
357
|
+
constructor(_shape, _openSchema) {
|
|
358
|
+
super();
|
|
359
|
+
this._shape = _shape;
|
|
360
|
+
this._openSchema = _openSchema;
|
|
361
|
+
const d = {};
|
|
362
|
+
for (const key of Object.keys(_shape)) d[key] = _shape[key]._default;
|
|
363
|
+
this._default = d;
|
|
364
|
+
}
|
|
365
|
+
sanitize(raw) {
|
|
366
|
+
const src = raw && typeof raw === "object" && !Array.isArray(raw) ? raw : {};
|
|
367
|
+
const out = __spreadValues({}, src);
|
|
368
|
+
for (const key of Object.keys(this._shape)) {
|
|
369
|
+
const v = this._shape[key].sanitize(src[key]);
|
|
370
|
+
if (v !== void 0) out[key] = v;
|
|
371
|
+
}
|
|
372
|
+
if (this._openSchema) {
|
|
373
|
+
for (const key of Object.keys(src)) {
|
|
374
|
+
if (!(key in this._shape)) out[key] = this._openSchema.sanitize(src[key]);
|
|
375
|
+
}
|
|
376
|
+
}
|
|
377
|
+
return out;
|
|
378
|
+
}
|
|
379
|
+
isValid(raw, ctx, path) {
|
|
380
|
+
if (!raw || typeof raw !== "object" || Array.isArray(raw)) {
|
|
381
|
+
ctx == null ? void 0 : ctx.errors.push(pathStr(path != null ? path : []) + ": expected object, got " + (Array.isArray(raw) ? "array" : typeof raw));
|
|
382
|
+
return false;
|
|
383
|
+
}
|
|
384
|
+
const obj = raw;
|
|
385
|
+
const p = path != null ? path : [];
|
|
386
|
+
let ok = true;
|
|
387
|
+
for (const key of Object.keys(this._shape)) {
|
|
388
|
+
p.push(key);
|
|
389
|
+
if (!this._shape[key].isValid(obj[key], ctx, p)) ok = false;
|
|
390
|
+
p.pop();
|
|
391
|
+
}
|
|
392
|
+
if (this._openSchema) {
|
|
393
|
+
for (const key of Object.keys(obj)) {
|
|
394
|
+
if (key in this._shape) continue;
|
|
395
|
+
p.push(key);
|
|
396
|
+
if (!this._openSchema.isValid(obj[key], ctx, p)) ok = false;
|
|
397
|
+
p.pop();
|
|
398
|
+
}
|
|
399
|
+
}
|
|
400
|
+
return ok;
|
|
401
|
+
}
|
|
402
|
+
_canSanitize(raw) {
|
|
403
|
+
return !!raw && typeof raw === "object" && !Array.isArray(raw);
|
|
404
|
+
}
|
|
405
|
+
};
|
|
406
|
+
var Arr = class extends Base {
|
|
407
|
+
constructor(item) {
|
|
408
|
+
super();
|
|
409
|
+
this.item = item;
|
|
410
|
+
this._default = [];
|
|
411
|
+
}
|
|
412
|
+
sanitize(raw) {
|
|
413
|
+
if (!Array.isArray(raw)) return [];
|
|
414
|
+
const out = [];
|
|
415
|
+
for (const el of raw) {
|
|
416
|
+
if (this.item._canSanitize(el)) out.push(this.item.sanitize(el));
|
|
417
|
+
}
|
|
418
|
+
return out;
|
|
419
|
+
}
|
|
420
|
+
isValid(raw, ctx, path) {
|
|
421
|
+
if (!Array.isArray(raw)) {
|
|
422
|
+
ctx == null ? void 0 : ctx.errors.push(pathStr(path != null ? path : []) + ": expected array, got " + typeof raw);
|
|
423
|
+
return false;
|
|
424
|
+
}
|
|
425
|
+
const p = path != null ? path : [];
|
|
426
|
+
let ok = true;
|
|
427
|
+
for (let i = 0; i < raw.length; i++) {
|
|
428
|
+
p.push("[" + i + "]");
|
|
429
|
+
if (!this.item.isValid(raw[i], ctx, p)) ok = false;
|
|
430
|
+
p.pop();
|
|
431
|
+
}
|
|
432
|
+
return ok;
|
|
433
|
+
}
|
|
434
|
+
_canSanitize(raw) {
|
|
435
|
+
return Array.isArray(raw);
|
|
436
|
+
}
|
|
437
|
+
};
|
|
438
|
+
var Rec = class extends Base {
|
|
439
|
+
constructor(value) {
|
|
440
|
+
super();
|
|
441
|
+
this.value = value;
|
|
442
|
+
/** Structural tag read by {@link describeSchema}. */
|
|
443
|
+
this._kind = "record";
|
|
444
|
+
this._default = {};
|
|
445
|
+
}
|
|
446
|
+
sanitize(raw) {
|
|
447
|
+
if (!raw || typeof raw !== "object" || Array.isArray(raw)) return {};
|
|
448
|
+
const out = {};
|
|
449
|
+
for (const [k, v] of Object.entries(raw)) {
|
|
450
|
+
if (this.value._canSanitize(v)) out[k] = this.value.sanitize(v);
|
|
451
|
+
}
|
|
452
|
+
return out;
|
|
453
|
+
}
|
|
454
|
+
isValid(raw, ctx, path) {
|
|
455
|
+
if (!raw || typeof raw !== "object" || Array.isArray(raw)) {
|
|
456
|
+
ctx == null ? void 0 : ctx.errors.push(pathStr(path != null ? path : []) + ": expected object/record, got " + (Array.isArray(raw) ? "array" : typeof raw));
|
|
457
|
+
return false;
|
|
458
|
+
}
|
|
459
|
+
const p = path != null ? path : [];
|
|
460
|
+
let ok = true;
|
|
461
|
+
for (const [k, v] of Object.entries(raw)) {
|
|
462
|
+
p.push(k);
|
|
463
|
+
if (!this.value.isValid(v, ctx, p)) ok = false;
|
|
464
|
+
p.pop();
|
|
465
|
+
}
|
|
466
|
+
return ok;
|
|
467
|
+
}
|
|
468
|
+
_canSanitize(raw) {
|
|
469
|
+
return !!raw && typeof raw === "object" && !Array.isArray(raw);
|
|
470
|
+
}
|
|
471
|
+
};
|
|
472
|
+
var Any = class extends Base {
|
|
473
|
+
constructor() {
|
|
474
|
+
super(...arguments);
|
|
475
|
+
this._default = void 0;
|
|
476
|
+
}
|
|
477
|
+
sanitize(raw) {
|
|
478
|
+
return raw;
|
|
479
|
+
}
|
|
480
|
+
isValid(_raw, _ctx, _path) {
|
|
481
|
+
return true;
|
|
482
|
+
}
|
|
483
|
+
_canSanitize(_raw) {
|
|
484
|
+
return true;
|
|
485
|
+
}
|
|
486
|
+
};
|
|
487
|
+
var Defined = class extends Base {
|
|
488
|
+
constructor() {
|
|
489
|
+
super(...arguments);
|
|
490
|
+
this._default = void 0;
|
|
491
|
+
}
|
|
492
|
+
sanitize(raw) {
|
|
493
|
+
return raw;
|
|
494
|
+
}
|
|
495
|
+
isValid(raw, ctx, path) {
|
|
496
|
+
if (raw !== void 0) return true;
|
|
497
|
+
ctx == null ? void 0 : ctx.errors.push(pathStr(path != null ? path : []) + ": required value is missing");
|
|
498
|
+
return false;
|
|
499
|
+
}
|
|
500
|
+
_canSanitize(raw) {
|
|
501
|
+
return raw !== void 0;
|
|
502
|
+
}
|
|
503
|
+
};
|
|
504
|
+
var Lazy = class extends Base {
|
|
505
|
+
constructor(fn, _default) {
|
|
506
|
+
super();
|
|
507
|
+
this.fn = fn;
|
|
508
|
+
this._default = _default;
|
|
509
|
+
this.resolved = null;
|
|
510
|
+
}
|
|
511
|
+
get schema() {
|
|
512
|
+
var _a2;
|
|
513
|
+
return (_a2 = this.resolved) != null ? _a2 : this.resolved = this.fn();
|
|
514
|
+
}
|
|
515
|
+
sanitize(raw) {
|
|
516
|
+
return this.schema.sanitize(raw);
|
|
517
|
+
}
|
|
518
|
+
isValid(raw, ctx, path) {
|
|
519
|
+
return this.schema.isValid(raw, ctx, path);
|
|
520
|
+
}
|
|
521
|
+
_canSanitize(raw) {
|
|
522
|
+
return this.schema._canSanitize(raw);
|
|
523
|
+
}
|
|
524
|
+
};
|
|
525
|
+
var Tuple = class extends Base {
|
|
526
|
+
constructor(schemas) {
|
|
527
|
+
super();
|
|
528
|
+
this.schemas = schemas;
|
|
529
|
+
/** Structural tag read by {@link describeSchema} — `schemas` alone cannot tell Tuple from Union. */
|
|
530
|
+
this._kind = "tuple";
|
|
531
|
+
this._default = schemas.map((s) => s._default);
|
|
532
|
+
}
|
|
533
|
+
sanitize(raw) {
|
|
534
|
+
if (!Array.isArray(raw) || raw.length !== this.schemas.length) return this._default;
|
|
535
|
+
return this.schemas.map((s, i) => s.sanitize(raw[i]));
|
|
536
|
+
}
|
|
537
|
+
isValid(raw, ctx, path) {
|
|
538
|
+
if (!Array.isArray(raw) || raw.length !== this.schemas.length) {
|
|
539
|
+
ctx == null ? void 0 : ctx.errors.push(pathStr(path != null ? path : []) + ": expected tuple of length " + this.schemas.length + ", got " + (Array.isArray(raw) ? "array[" + raw.length + "]" : typeof raw));
|
|
540
|
+
return false;
|
|
541
|
+
}
|
|
542
|
+
const p = path != null ? path : [];
|
|
543
|
+
let ok = true;
|
|
544
|
+
for (let i = 0; i < this.schemas.length; i++) {
|
|
545
|
+
p.push("[" + i + "]");
|
|
546
|
+
if (!this.schemas[i].isValid(raw[i], ctx, p)) ok = false;
|
|
547
|
+
p.pop();
|
|
548
|
+
}
|
|
549
|
+
return ok;
|
|
550
|
+
}
|
|
551
|
+
// Require exact length so wrong-length arrays are dropped rather than repaired to default.
|
|
552
|
+
_canSanitize(raw) {
|
|
553
|
+
return Array.isArray(raw) && raw.length === this.schemas.length;
|
|
554
|
+
}
|
|
555
|
+
};
|
|
556
|
+
function implementsInterface() {
|
|
557
|
+
return (schema) => schema;
|
|
558
|
+
}
|
|
559
|
+
function describeSchema(schema) {
|
|
560
|
+
var _a2;
|
|
561
|
+
const s = schema;
|
|
562
|
+
switch (s._kind) {
|
|
563
|
+
case "union":
|
|
564
|
+
return { kind: "union", members: s.schemas };
|
|
565
|
+
case "discriminatedUnion":
|
|
566
|
+
return { kind: "discriminatedUnion", key: s._key, members: s._schemas };
|
|
567
|
+
case "record":
|
|
568
|
+
return { kind: "record", value: s.value };
|
|
569
|
+
case "tuple":
|
|
570
|
+
return { kind: "tuple", items: s.schemas };
|
|
571
|
+
}
|
|
572
|
+
if ("_shape" in s) return { kind: "shape", shape: s._shape, openValue: s._openSchema };
|
|
573
|
+
if ("item" in s) return { kind: "array", item: s.item };
|
|
574
|
+
if ("inner" in s) return { kind: "optional", inner: s.inner };
|
|
575
|
+
if ("fn" in s) return { kind: "lazy", resolved: (_a2 = s.resolved) != null ? _a2 : s.resolved = s.fn() };
|
|
576
|
+
return { kind: "leaf" };
|
|
577
|
+
}
|
|
578
|
+
var px = {
|
|
579
|
+
/** Matches a string. Default: '' or provided value. */
|
|
580
|
+
string: (defaultVal = "") => new Str(defaultVal),
|
|
581
|
+
/** Matches a finite number. Default: 0 or provided value. */
|
|
582
|
+
number: (defaultVal = 0) => new Num(defaultVal),
|
|
583
|
+
/** Matches a boolean. Default: false or provided value. */
|
|
584
|
+
boolean: (defaultVal = false) => new Bool(defaultVal),
|
|
585
|
+
/** Matches one exact primitive value; its default is the value itself. */
|
|
586
|
+
literal: (value) => new Literal(value),
|
|
587
|
+
/** Matches one of a fixed set of string/number values. Default: first value. */
|
|
588
|
+
enum: (values, defaultVal) => new Enum(values, defaultVal),
|
|
589
|
+
/**
|
|
590
|
+
* Returns the first schema whose isValid passes.
|
|
591
|
+
* TypeScript infers the union of all member types automatically.
|
|
592
|
+
*/
|
|
593
|
+
union: (schemas, defaultVal) => new Union(schemas, defaultVal),
|
|
594
|
+
/**
|
|
595
|
+
* Discriminated union — reads `raw[key]`, finds the member schema whose
|
|
596
|
+
* literal at `key` matches, then delegates sanitize/isValid to that member.
|
|
597
|
+
* Each member must be an object schema with a `px.literal(...)` at `key`.
|
|
598
|
+
* TypeScript infers the union of all member types automatically.
|
|
599
|
+
*/
|
|
600
|
+
discriminatedUnion: (key, schemas) => new DiscriminatedUnion(key, schemas),
|
|
601
|
+
/** Typed object — unknown keys are stripped. Required fields fall back to their default. */
|
|
602
|
+
object: (shape) => new Obj(shape),
|
|
603
|
+
/**
|
|
604
|
+
* Open object — validates known keys; passes unknown keys through as-is,
|
|
605
|
+
* or validates/sanitizes them against `openSchema` when provided.
|
|
606
|
+
*/
|
|
607
|
+
openObject: (shape, openSchema) => new OpenObj(shape, openSchema),
|
|
608
|
+
/**
|
|
609
|
+
* Creates a new closed object schema by merging a base schema's shape with additional fields.
|
|
610
|
+
* The base can be the result of px.object() or px.openObject() — anything with a _shape property.
|
|
611
|
+
*
|
|
612
|
+
* @example
|
|
613
|
+
* const PxSvgNodeSchema = px.extendedObject(PxNodeBaseSchema, { width: px.number().optional() });
|
|
614
|
+
*/
|
|
615
|
+
extendedObject: (base, extra) => new Obj(__spreadValues(__spreadValues({}, base._shape), extra)),
|
|
616
|
+
/** Array whose unrecoverable items are filtered out. Default: []. */
|
|
617
|
+
array: (item) => new Arr(item),
|
|
618
|
+
/** String-keyed record whose unrecoverable values are dropped. Default: {}. */
|
|
619
|
+
record: (value) => new Rec(value),
|
|
620
|
+
/** Passes anything through unchanged — always valid. */
|
|
621
|
+
any: () => new Any(),
|
|
622
|
+
/** Anything EXCEPT `undefined` — an open type whose presence is required (V6). */
|
|
623
|
+
defined: () => new Defined(),
|
|
624
|
+
/** Fixed-length tuple — validates element count and each position individually. */
|
|
625
|
+
tuple: (schemas) => new Tuple(schemas),
|
|
626
|
+
/** Defers schema creation — required for recursive types. Must supply a default value. */
|
|
627
|
+
lazy: (fn, defaultVal) => new Lazy(fn, defaultVal)
|
|
628
|
+
};
|
|
629
|
+
|
|
630
|
+
// src/format/PxAnimatorConstants.ts
|
|
631
|
+
var PxFillMode = {
|
|
632
|
+
forwards: "forwards",
|
|
633
|
+
backwards: "backwards",
|
|
634
|
+
both: "both",
|
|
635
|
+
none: "none"
|
|
636
|
+
};
|
|
637
|
+
var PxPlaybackDirection = {
|
|
638
|
+
normal: "normal",
|
|
639
|
+
reverse: "reverse",
|
|
640
|
+
alternate: "alternate",
|
|
641
|
+
alternateReverse: "alternate-reverse"
|
|
642
|
+
};
|
|
643
|
+
var PX_ANIM_SRC_ATTR_NAME = "data-px-animation-src";
|
|
644
|
+
var PX_ANIM_ATTR_NAME = "_px_animator";
|
|
645
|
+
var PxStartOn = {
|
|
646
|
+
load: "load",
|
|
647
|
+
mouseOver: "mouseOver",
|
|
648
|
+
click: "click",
|
|
649
|
+
scrollIntoView: "scrollIntoView",
|
|
650
|
+
programmatic: "programmatic"
|
|
651
|
+
};
|
|
652
|
+
var PxOutAction = {
|
|
653
|
+
continue: "continue",
|
|
654
|
+
pause: "pause",
|
|
655
|
+
reset: "reset",
|
|
656
|
+
reverse: "reverse"
|
|
657
|
+
};
|
|
658
|
+
var PxFinishAction = {
|
|
659
|
+
hold: "hold",
|
|
660
|
+
reset: "reset"
|
|
661
|
+
};
|
|
662
|
+
var PxScrollKind = {
|
|
663
|
+
view: "view",
|
|
664
|
+
scroll: "scroll"
|
|
665
|
+
};
|
|
666
|
+
var PxScrollAxis = {
|
|
667
|
+
block: "block",
|
|
668
|
+
inline: "inline",
|
|
669
|
+
x: "x",
|
|
670
|
+
y: "y"
|
|
671
|
+
};
|
|
672
|
+
var PxScrollSource = {
|
|
673
|
+
nearest: "nearest",
|
|
674
|
+
root: "root"
|
|
675
|
+
};
|
|
676
|
+
var PxPinAlign = {
|
|
677
|
+
top: "top",
|
|
678
|
+
center: "center",
|
|
679
|
+
bottom: "bottom"
|
|
680
|
+
};
|
|
681
|
+
var PxScrollPhase = {
|
|
682
|
+
cover: "cover",
|
|
683
|
+
contain: "contain",
|
|
684
|
+
entry: "entry",
|
|
685
|
+
exit: "exit",
|
|
686
|
+
entryCrossing: "entry-crossing",
|
|
687
|
+
exitCrossing: "exit-crossing"
|
|
688
|
+
};
|
|
689
|
+
var PxAlongPathMode = {
|
|
690
|
+
sampled: "sampled",
|
|
691
|
+
offsetPath: "offsetPath"
|
|
692
|
+
};
|
|
693
|
+
var PX_TIMELINE_SHARED_KEYS = ["duration", "iterations", "engine", "frameRate"];
|
|
694
|
+
var PX_TIME_ONLY_TIMELINE_KEYS = ["trigger", "delay", "fillMode", "direction"];
|
|
695
|
+
var PX_FLAT_RUNTIME_VIEW_KEYS = [
|
|
696
|
+
...PX_TIMELINE_SHARED_KEYS,
|
|
697
|
+
...PX_TIME_ONLY_TIMELINE_KEYS,
|
|
698
|
+
"fill",
|
|
699
|
+
"resetOnFinish",
|
|
700
|
+
"timelineSource",
|
|
701
|
+
"scroll"
|
|
702
|
+
];
|
|
703
|
+
var PxTimelineEngine = {
|
|
704
|
+
native: "native",
|
|
705
|
+
js: "js"
|
|
706
|
+
};
|
|
707
|
+
var PxTimelineEngineSetting = __spreadProps(__spreadValues({}, PxTimelineEngine), {
|
|
708
|
+
auto: "auto"
|
|
709
|
+
});
|
|
710
|
+
var PX_TRIGGER_DEFAULTS = {
|
|
711
|
+
startOn: "load",
|
|
712
|
+
outAction: "continue",
|
|
713
|
+
scrollIntoViewThreshold: 0
|
|
714
|
+
};
|
|
715
|
+
var PxLoopRepeatAt = {
|
|
716
|
+
/** Segment from the START; the repetition runs BEFORE the first keyframe
|
|
717
|
+
* (intro loops that play until the main timeline begins). */
|
|
718
|
+
start: "start",
|
|
719
|
+
/** DEFAULT — segment from the END; the repetition runs AFTER the last keyframe
|
|
720
|
+
* (idle/outro loops that continue once the main timeline has finished). */
|
|
721
|
+
end: "end"
|
|
722
|
+
};
|
|
723
|
+
var PxLoopDirection = {
|
|
724
|
+
/** DEFAULT — cycle: every repetition replays the segment the same way round. */
|
|
725
|
+
normal: "normal",
|
|
726
|
+
/** Ping-pong: repetitions alternate forward / backward. */
|
|
727
|
+
alternate: "alternate"
|
|
728
|
+
};
|
|
729
|
+
var PxMaskType = {
|
|
730
|
+
luminance: "luminance",
|
|
731
|
+
alpha: "alpha"
|
|
732
|
+
};
|
|
733
|
+
var PxUnits = {
|
|
734
|
+
userSpaceOnUse: "userSpaceOnUse",
|
|
735
|
+
objectBoundingBox: "objectBoundingBox"
|
|
736
|
+
};
|
|
737
|
+
var PxCloneWithout = {
|
|
738
|
+
translate: "translate"
|
|
739
|
+
// transform: 'transform', // future: drop rotate/scale too (content only)
|
|
740
|
+
};
|
|
741
|
+
var PxPathOverflow = {
|
|
742
|
+
clip: "clip",
|
|
743
|
+
extend: "extend"
|
|
744
|
+
};
|
|
745
|
+
var PxLengthAdjust = {
|
|
746
|
+
spacing: "spacing",
|
|
747
|
+
spacingAndGlyphs: "spacingAndGlyphs"
|
|
748
|
+
};
|
|
749
|
+
var PxTextPathMethod = {
|
|
750
|
+
align: "align",
|
|
751
|
+
stretch: "stretch"
|
|
752
|
+
};
|
|
753
|
+
var PxTextPathSpacing = {
|
|
754
|
+
auto: "auto",
|
|
755
|
+
exact: "exact"
|
|
756
|
+
};
|
|
757
|
+
var PxStrokeTrimSubPaths = {
|
|
758
|
+
separate: "separate",
|
|
759
|
+
combined: "combined"
|
|
760
|
+
};
|
|
761
|
+
var PX_TEXT_CONTENT_ATTR = "textContent";
|
|
762
|
+
var CLASS_ATTR = "class";
|
|
763
|
+
var TRANSFORM_ATTR = "transform";
|
|
764
|
+
var TRANSFORM_PART = {
|
|
765
|
+
translate: "translate",
|
|
766
|
+
rotate: "rotate",
|
|
767
|
+
scale: "scale",
|
|
768
|
+
origin: "origin"
|
|
769
|
+
};
|
|
770
|
+
var PX_TRANSFORM_PART_KEYS = [
|
|
771
|
+
TRANSFORM_PART.translate,
|
|
772
|
+
TRANSFORM_PART.rotate,
|
|
773
|
+
TRANSFORM_PART.scale,
|
|
774
|
+
TRANSFORM_PART.origin
|
|
775
|
+
];
|
|
776
|
+
var PxGradientSpreadMethod = {
|
|
777
|
+
pad: "pad",
|
|
778
|
+
reflect: "reflect",
|
|
779
|
+
repeat: "repeat"
|
|
780
|
+
};
|
|
781
|
+
var PxGradientType = {
|
|
782
|
+
linear: "linear",
|
|
783
|
+
radial: "radial"
|
|
784
|
+
};
|
|
785
|
+
function getAnimatorConfig(doc) {
|
|
786
|
+
var _a2;
|
|
787
|
+
const cfg = (doc == null ? void 0 : doc.animator) || ((_a2 = doc == null ? void 0 : doc.meta) == null ? void 0 : _a2.animator);
|
|
788
|
+
if (!cfg) return void 0;
|
|
789
|
+
const memoised = wireViewMemo.get(cfg);
|
|
790
|
+
if (memoised) return memoised;
|
|
791
|
+
const wire = cfg;
|
|
792
|
+
const stray = PX_FLAT_RUNTIME_VIEW_KEYS.filter((k) => wire[k] !== void 0);
|
|
793
|
+
const source = stray.length ? __spreadValues({}, wire) : cfg;
|
|
794
|
+
for (const k of stray) delete source[k];
|
|
795
|
+
const view = flattenAnimatorTimeline(source);
|
|
796
|
+
wireViewMemo.set(cfg, view);
|
|
797
|
+
return view;
|
|
798
|
+
}
|
|
799
|
+
var wireViewMemo = /* @__PURE__ */ new WeakMap();
|
|
800
|
+
var flattenMemo = /* @__PURE__ */ new WeakMap();
|
|
801
|
+
function flattenAnimatorTimeline(cfg) {
|
|
802
|
+
const timeline = cfg.timeline;
|
|
803
|
+
if (timeline === void 0 || timeline === null || typeof timeline !== "object") return cfg;
|
|
804
|
+
const memoised = flattenMemo.get(cfg);
|
|
805
|
+
if (memoised) return memoised;
|
|
806
|
+
const _a2 = cfg, { timeline: _dropped } = _a2, flat = __objRest(_a2, ["timeline"]);
|
|
807
|
+
if (timeline.engine !== void 0) flat.engine = timeline.engine;
|
|
808
|
+
if (timeline.frameRate !== void 0) flat.frameRate = timeline.frameRate;
|
|
809
|
+
if (timeline.type === "scroll" || timeline.type === "view") {
|
|
810
|
+
flat.timelineSource = "scroll";
|
|
811
|
+
if (timeline.duration !== void 0) flat.duration = timeline.duration;
|
|
812
|
+
if (timeline.iterations !== void 0) flat.iterations = timeline.iterations;
|
|
813
|
+
const scroll = __spreadValues({}, flat.scroll || {});
|
|
814
|
+
scroll.kind = timeline.type;
|
|
815
|
+
if (timeline.axis !== void 0) scroll.axis = timeline.axis;
|
|
816
|
+
if (timeline.source !== void 0) scroll.source = timeline.source;
|
|
817
|
+
if (timeline.subject !== void 0) scroll.subject = timeline.subject;
|
|
818
|
+
if (timeline.smoothing !== void 0) scroll.smoothing = timeline.smoothing;
|
|
819
|
+
if (timeline.range !== void 0) scroll.range = timeline.range;
|
|
820
|
+
const pin = timeline.pin;
|
|
821
|
+
if (typeof pin === "boolean") scroll.pin = pin;
|
|
822
|
+
else if (pin && typeof pin === "object") {
|
|
823
|
+
scroll.pin = true;
|
|
824
|
+
if (pin.align !== void 0) scroll.pinAlign = pin.align;
|
|
825
|
+
if (pin.offset !== void 0) scroll.pinOffset = pin.offset;
|
|
826
|
+
if (pin.distance !== void 0) scroll.pinDistance = pin.distance;
|
|
827
|
+
}
|
|
828
|
+
flat.scroll = scroll;
|
|
829
|
+
} else {
|
|
830
|
+
if (timeline.duration !== void 0) flat.duration = timeline.duration;
|
|
831
|
+
if (timeline.trigger !== void 0) {
|
|
832
|
+
const _b = timeline.trigger, { finishAction } = _b, restTrigger = __objRest(_b, ["finishAction"]);
|
|
833
|
+
if (Object.keys(restTrigger).length) flat.trigger = restTrigger;
|
|
834
|
+
if (finishAction !== void 0) flat.resetOnFinish = finishAction === "reset";
|
|
835
|
+
}
|
|
836
|
+
if (timeline.delay !== void 0) flat.delay = timeline.delay;
|
|
837
|
+
if (timeline.iterations !== void 0) flat.iterations = timeline.iterations;
|
|
838
|
+
if (timeline.direction !== void 0) flat.direction = timeline.direction;
|
|
839
|
+
if (timeline.fillMode !== void 0) flat.fill = timeline.fillMode;
|
|
840
|
+
}
|
|
841
|
+
flattenMemo.set(cfg, flat);
|
|
842
|
+
return flat;
|
|
843
|
+
}
|
|
844
|
+
|
|
845
|
+
// src/version/PxSchemaVersion.ts
|
|
846
|
+
var PX_WIRE_SCHEMA_VERSION = "1.1";
|
|
847
|
+
|
|
848
|
+
// src/version/PxWireVersion.ts
|
|
849
|
+
var VERSION_RE = /^(\d+)\.(\d+)(?:\.(\d+))?$/;
|
|
850
|
+
function parseWireVersion(raw) {
|
|
851
|
+
if (typeof raw !== "string") return void 0;
|
|
852
|
+
const m = VERSION_RE.exec(raw.trim());
|
|
853
|
+
if (!m) return void 0;
|
|
854
|
+
return { a: Number(m[1]), b: Number(m[2]), c: m[3] === void 0 ? 0 : Number(m[3]) };
|
|
855
|
+
}
|
|
856
|
+
var _a;
|
|
857
|
+
var PX_WIRE_VERSION = (_a = parseWireVersion(PX_WIRE_SCHEMA_VERSION)) != null ? _a : { a: 1, b: 1, c: 0 };
|
|
858
|
+
|
|
859
|
+
// src/format/PxAnimatorTypes.ts
|
|
860
|
+
var PxEasingOrRefSchema = px.union([
|
|
861
|
+
px.string(),
|
|
862
|
+
px.tuple([px.number(), px.number(), px.number(), px.number()])
|
|
863
|
+
]);
|
|
864
|
+
var PxKeyframeValueSchema = implementsInterface()(px.union([
|
|
865
|
+
px.string(),
|
|
866
|
+
// e.g. for colors
|
|
867
|
+
px.number(),
|
|
868
|
+
px.array(px.number()),
|
|
869
|
+
// ORDER LAW: the key-discriminated object shape (`{pathData}`) comes BEFORE the
|
|
870
|
+
// all-optional transform-parts record. In default (non-strict) mode that record accepts
|
|
871
|
+
// ANY object (every key optional, unknown keys ignored), so listing it earlier made
|
|
872
|
+
// Union.sanitize route `{pathData}` values into it and strip them to `{}` —
|
|
873
|
+
// silent morph-data loss (repro: the editor's keyframeValueSanitize spec). Validity is
|
|
874
|
+
// order-independent (`some()`); only sanitize routing depends on this order.
|
|
875
|
+
px.object({ pathData: px.string() }),
|
|
876
|
+
// Gradient `stops` timeline — each kf value is the full stops-array snapshot.
|
|
877
|
+
px.lazy(() => px.array(PxGradientStopSchema), []),
|
|
878
|
+
px.lazy(() => PxTransformPartsSchema, {})
|
|
879
|
+
]));
|
|
880
|
+
var PxKeyframeSchema = implementsInterface()(px.object({
|
|
881
|
+
time: px.number().optional(),
|
|
882
|
+
value: PxKeyframeValueSchema.optional(),
|
|
883
|
+
easing: PxEasingOrRefSchema.optional(),
|
|
884
|
+
tangentOut: px.tuple([px.number(), px.number()]).optional(),
|
|
885
|
+
tangentIn: px.tuple([px.number(), px.number()]).optional()
|
|
886
|
+
// (`selected` — editor timeline-selection UI state — was REMOVED from the wire
|
|
887
|
+
// (review §1.3): editor data lives under `meta`. The editor still carries it on
|
|
888
|
+
// its internal COPY-PASTE payload, which never validates against this schema.)
|
|
889
|
+
}));
|
|
890
|
+
var anyKf = (kf) => kf;
|
|
891
|
+
var keyframeTime = (kf) => {
|
|
892
|
+
var _a2, _b;
|
|
893
|
+
return (_b = (_a2 = anyKf(kf).time) != null ? _a2 : anyKf(kf).t) != null ? _b : 0;
|
|
894
|
+
};
|
|
895
|
+
var keyframeValue = (kf) => {
|
|
896
|
+
var _a2;
|
|
897
|
+
return (_a2 = anyKf(kf).value) != null ? _a2 : anyKf(kf).v;
|
|
898
|
+
};
|
|
899
|
+
var keyframeEasing = (kf) => {
|
|
900
|
+
var _a2;
|
|
901
|
+
return (_a2 = anyKf(kf).easing) != null ? _a2 : anyKf(kf).e;
|
|
902
|
+
};
|
|
903
|
+
var keyframeTangentIn = (kf) => anyKf(kf).tangentIn;
|
|
904
|
+
var keyframeTangentOut = (kf) => anyKf(kf).tangentOut;
|
|
905
|
+
var PxLoopSchema = implementsInterface()(px.object({
|
|
906
|
+
segmentCount: px.number().optional(),
|
|
907
|
+
repeatAt: px.enum([PxLoopRepeatAt.start, PxLoopRepeatAt.end]).optional(),
|
|
908
|
+
direction: px.enum([PxLoopDirection.normal, PxLoopDirection.alternate]).optional()
|
|
909
|
+
}));
|
|
910
|
+
var PxPropertyAnimationSchema = implementsInterface()(px.object({
|
|
911
|
+
value: PxKeyframeValueSchema.optional(),
|
|
912
|
+
keyframes: px.array(PxKeyframeSchema).optional(),
|
|
913
|
+
loop: px.union([PxLoopSchema, px.boolean()]).optional(),
|
|
914
|
+
autoOrient: px.boolean().optional(),
|
|
915
|
+
alongPathMode: px.enum([PxAlongPathMode.sampled, PxAlongPathMode.offsetPath]).optional()
|
|
916
|
+
}));
|
|
917
|
+
var PxTransformPartsSchema = implementsInterface()(px.object({
|
|
918
|
+
translate: px.tuple([px.number(), px.number()]).optional(),
|
|
919
|
+
rotate: px.number().optional(),
|
|
920
|
+
skew: px.number().optional(),
|
|
921
|
+
scale: px.tuple([px.number(), px.number()]).optional(),
|
|
922
|
+
origin: px.tuple([px.number(), px.number()]).optional()
|
|
923
|
+
}));
|
|
924
|
+
var PxTransformValueSchema = px.union([
|
|
925
|
+
px.string(),
|
|
926
|
+
PxTransformPartsSchema,
|
|
927
|
+
px.object({ value: PxTransformPartsSchema }),
|
|
928
|
+
PxPropertyAnimationSchema
|
|
929
|
+
]);
|
|
930
|
+
var PxAnimationDefinitionSchema = implementsInterface()(
|
|
931
|
+
px.record(PxPropertyAnimationSchema)
|
|
932
|
+
);
|
|
933
|
+
var PxElementAnimationSchema = implementsInterface()(px.union([
|
|
934
|
+
px.string(),
|
|
935
|
+
px.array(px.union([px.string(), PxAnimationDefinitionSchema])),
|
|
936
|
+
PxAnimationDefinitionSchema
|
|
937
|
+
]));
|
|
938
|
+
var PxTriggerSchema = implementsInterface()(px.object({
|
|
939
|
+
startOn: px.enum([PxStartOn.load, PxStartOn.mouseOver, PxStartOn.click, PxStartOn.scrollIntoView, PxStartOn.programmatic], PX_TRIGGER_DEFAULTS.startOn).optional(),
|
|
940
|
+
outAction: px.enum([PxOutAction.continue, PxOutAction.pause, PxOutAction.reset, PxOutAction.reverse], PX_TRIGGER_DEFAULTS.outAction).optional(),
|
|
941
|
+
// What happens after a NATURAL finish — `'hold'` (default: keep the end state per
|
|
942
|
+
// `fill`) or `'reset'` (snap back to the start state). Pairs with `outAction` ("what
|
|
943
|
+
// happens when the trigger condition ends"); both end-of-life knobs now read alike.
|
|
944
|
+
finishAction: px.enum([PxFinishAction.hold, PxFinishAction.reset]).optional(),
|
|
945
|
+
scrollIntoViewThreshold: px.number().optional()
|
|
946
|
+
}));
|
|
947
|
+
var PxGlyphSchema = implementsInterface()(px.object({
|
|
948
|
+
width: px.number(),
|
|
949
|
+
pathData: px.string()
|
|
950
|
+
}));
|
|
951
|
+
var PxGlyphFontSchema = implementsInterface()(px.object({
|
|
952
|
+
fontFamily: px.string(),
|
|
953
|
+
fontStyle: px.string(),
|
|
954
|
+
ascent: px.number(),
|
|
955
|
+
unitsPerEm: px.number(),
|
|
956
|
+
glyphs: px.record(PxGlyphSchema)
|
|
957
|
+
}));
|
|
958
|
+
var PxDefinitionsSchema = implementsInterface()(px.object({
|
|
959
|
+
easings: px.record(px.tuple([px.number(), px.number(), px.number(), px.number()])).optional(),
|
|
960
|
+
animations: px.record(PxAnimationDefinitionSchema).optional(),
|
|
961
|
+
fonts: px.record(PxGlyphFontSchema).optional()
|
|
962
|
+
}));
|
|
963
|
+
var PxScrollRangePointSchema = implementsInterface()(px.object({
|
|
964
|
+
phase: px.enum([
|
|
965
|
+
PxScrollPhase.cover,
|
|
966
|
+
PxScrollPhase.contain,
|
|
967
|
+
PxScrollPhase.entry,
|
|
968
|
+
PxScrollPhase.exit,
|
|
969
|
+
PxScrollPhase.entryCrossing,
|
|
970
|
+
PxScrollPhase.exitCrossing
|
|
971
|
+
]).optional(),
|
|
972
|
+
fraction: px.number().optional()
|
|
973
|
+
}));
|
|
974
|
+
var PxScrollRangeSchema = px.object({
|
|
975
|
+
start: PxScrollRangePointSchema.optional(),
|
|
976
|
+
end: PxScrollRangePointSchema.optional()
|
|
977
|
+
});
|
|
978
|
+
var PxScrollSchema = implementsInterface()(px.object({
|
|
979
|
+
kind: px.enum([PxScrollKind.view, PxScrollKind.scroll]).optional(),
|
|
980
|
+
axis: px.enum([PxScrollAxis.block, PxScrollAxis.inline, PxScrollAxis.x, PxScrollAxis.y]).optional(),
|
|
981
|
+
source: px.enum([PxScrollSource.nearest, PxScrollSource.root]).optional(),
|
|
982
|
+
// Free-form: the two keywords `parent`/`scroller` plus any CSS selector.
|
|
983
|
+
subject: px.string().optional(),
|
|
984
|
+
smoothing: px.number().optional(),
|
|
985
|
+
pin: px.boolean().optional(),
|
|
986
|
+
pinAlign: px.enum([PxPinAlign.top, PxPinAlign.center, PxPinAlign.bottom]).optional(),
|
|
987
|
+
pinOffset: px.number().optional(),
|
|
988
|
+
pinDistance: px.number().optional(),
|
|
989
|
+
range: PxScrollRangeSchema.optional()
|
|
990
|
+
}));
|
|
991
|
+
var PxTimelinePinSchema = implementsInterface()(px.object({
|
|
992
|
+
align: px.enum([PxPinAlign.top, PxPinAlign.center, PxPinAlign.bottom]).optional(),
|
|
993
|
+
offset: px.number().optional(),
|
|
994
|
+
distance: px.number().optional()
|
|
995
|
+
}));
|
|
996
|
+
var PxTimelineEngineSchema = px.enum([PxTimelineEngineSetting.auto, PxTimelineEngineSetting.native, PxTimelineEngineSetting.js]).optional();
|
|
997
|
+
var PxTimeTimelineSchema = implementsInterface()(px.object({
|
|
998
|
+
type: px.literal("time").optional(),
|
|
999
|
+
engine: PxTimelineEngineSchema,
|
|
1000
|
+
frameRate: px.number().optional(),
|
|
1001
|
+
// §2.8: duration is a property of the TIMELINE — how long one pass takes.
|
|
1002
|
+
duration: px.number().optional(),
|
|
1003
|
+
trigger: PxTriggerSchema.optional(),
|
|
1004
|
+
delay: px.number().optional(),
|
|
1005
|
+
iterations: px.union([px.number(), px.literal("infinite")]).optional(),
|
|
1006
|
+
// `fillMode` on the wire (CSS `animation-fill-mode`; the runtime view calls it `fill`)
|
|
1007
|
+
// — never `fill`, which is paint everywhere else in the format.
|
|
1008
|
+
fillMode: px.enum([PxFillMode.forwards, PxFillMode.backwards, PxFillMode.both, PxFillMode.none]).optional(),
|
|
1009
|
+
direction: px.enum([PxPlaybackDirection.normal, PxPlaybackDirection.reverse, PxPlaybackDirection.alternate, PxPlaybackDirection.alternateReverse]).optional()
|
|
1010
|
+
}));
|
|
1011
|
+
var scrollishTimelineShape = {
|
|
1012
|
+
// §2.8: duration is a property of the TIMELINE — under scrubbing it is the keyframe
|
|
1013
|
+
// span the scroll range maps onto.
|
|
1014
|
+
duration: px.number().optional(),
|
|
1015
|
+
// Finite repeat count IS meaningful when scrubbing — the scroll range maps onto
|
|
1016
|
+
// duration × iterations (rule D4; `'infinite'` cannot map to a range, so no literal here).
|
|
1017
|
+
iterations: px.number().optional(),
|
|
1018
|
+
engine: PxTimelineEngineSchema,
|
|
1019
|
+
frameRate: px.number().optional(),
|
|
1020
|
+
axis: px.enum([PxScrollAxis.block, PxScrollAxis.inline, PxScrollAxis.x, PxScrollAxis.y]).optional(),
|
|
1021
|
+
source: px.enum([PxScrollSource.nearest, PxScrollSource.root]).optional(),
|
|
1022
|
+
subject: px.string().optional(),
|
|
1023
|
+
// 'parent' | 'scroller' | any CSS selector
|
|
1024
|
+
smoothing: px.number().optional(),
|
|
1025
|
+
// ms
|
|
1026
|
+
pin: px.union([px.boolean(), PxTimelinePinSchema]).optional(),
|
|
1027
|
+
range: PxScrollRangeSchema.optional()
|
|
1028
|
+
};
|
|
1029
|
+
var PxScrollTimelineSchema = implementsInterface()(
|
|
1030
|
+
px.object(__spreadValues({ type: px.literal("scroll") }, scrollishTimelineShape))
|
|
1031
|
+
);
|
|
1032
|
+
var PxViewTimelineSchema = implementsInterface()(
|
|
1033
|
+
px.object(__spreadValues({ type: px.literal("view") }, scrollishTimelineShape))
|
|
1034
|
+
);
|
|
1035
|
+
var PxTimelineSchema = px.discriminatedUnion("type", [
|
|
1036
|
+
PxTimeTimelineSchema,
|
|
1037
|
+
// first = the member an absent `type` selects
|
|
1038
|
+
PxScrollTimelineSchema,
|
|
1039
|
+
PxViewTimelineSchema
|
|
1040
|
+
]);
|
|
1041
|
+
var PxBindingSchema = implementsInterface()(px.object({
|
|
1042
|
+
target: px.string(),
|
|
1043
|
+
animateWith: px.array(px.string())
|
|
1044
|
+
}));
|
|
1045
|
+
var PxAnimatorConfigSchema = implementsInterface()(px.object({
|
|
1046
|
+
// (`mode`, `duration` and `frameRate` live INSIDE `timeline` on the wire — §2.8; they exist
|
|
1047
|
+
// at this level only on the runtime view, like the rest of the playback dynamics.)
|
|
1048
|
+
// THE spelling of "what advances progress" — clock / scroll / view (review §2.1).
|
|
1049
|
+
timeline: PxTimelineSchema.optional(),
|
|
1050
|
+
definitions: PxDefinitionsSchema.optional(),
|
|
1051
|
+
bindings: px.array(PxBindingSchema).optional(),
|
|
1052
|
+
debugGlobalName: px.string().optional(),
|
|
1053
|
+
// Declared HERE because this is a closed object: an undeclared key would be stripped by
|
|
1054
|
+
// `sanitize` and flagged by strict validation on our own files.
|
|
1055
|
+
version: px.string().optional()
|
|
1056
|
+
}));
|
|
1057
|
+
var PxAttrValueSchema = px.union([
|
|
1058
|
+
px.string(),
|
|
1059
|
+
px.number(),
|
|
1060
|
+
px.array(px.number()),
|
|
1061
|
+
// Structured static — `{value: …}` (read-accepted transitional spelling, S1).
|
|
1062
|
+
// `defined`, not `any`: the KEY's presence is what identifies this branch (V6).
|
|
1063
|
+
px.object({ value: px.defined() }),
|
|
1064
|
+
// Bare transform parts record — the canonical static `transform` on the wire (T2).
|
|
1065
|
+
PxTransformPartsSchema
|
|
1066
|
+
]);
|
|
1067
|
+
var PxAnimatableNumberSchema = px.union([
|
|
1068
|
+
px.number(),
|
|
1069
|
+
PxPropertyAnimationSchema,
|
|
1070
|
+
px.object({ value: px.number() })
|
|
1071
|
+
]);
|
|
1072
|
+
var PxAnimatableVec2Schema = px.union([
|
|
1073
|
+
px.tuple([px.number(), px.number()]),
|
|
1074
|
+
PxPropertyAnimationSchema,
|
|
1075
|
+
px.object({ value: px.tuple([px.number(), px.number()]) })
|
|
1076
|
+
]);
|
|
1077
|
+
var PxAnimatableStringSchema = px.union([
|
|
1078
|
+
px.string(),
|
|
1079
|
+
PxPropertyAnimationSchema,
|
|
1080
|
+
px.object({ value: px.string() })
|
|
1081
|
+
]);
|
|
1082
|
+
var PxTransformByEffectSchema = implementsInterface()(px.object({
|
|
1083
|
+
translate: PxAnimatableVec2Schema.optional(),
|
|
1084
|
+
rotate: PxAnimatableNumberSchema.optional(),
|
|
1085
|
+
scale: PxAnimatableVec2Schema.optional(),
|
|
1086
|
+
skew: PxAnimatableNumberSchema.optional(),
|
|
1087
|
+
origin: PxAnimatableVec2Schema.optional()
|
|
1088
|
+
}));
|
|
1089
|
+
var PxRepeaterEffectSchema = implementsInterface()(px.object({
|
|
1090
|
+
// STATIC config, not a channel (V2/SCHEMA-DESIGN R5): the copy COUNT is read
|
|
1091
|
+
// once at expansion time and never sampled — plain number, no `keyframes`.
|
|
1092
|
+
copies: px.number().optional(),
|
|
1093
|
+
translate: PxAnimatableVec2Schema.optional(),
|
|
1094
|
+
rotate: PxAnimatableNumberSchema.optional(),
|
|
1095
|
+
skew: PxAnimatableNumberSchema.optional(),
|
|
1096
|
+
scale: PxAnimatableVec2Schema.optional(),
|
|
1097
|
+
origin: PxAnimatableVec2Schema.optional()
|
|
1098
|
+
}));
|
|
1099
|
+
var PxMaskedByEffectSchema = implementsInterface()(px.object({
|
|
1100
|
+
source: px.string().optional(),
|
|
1101
|
+
maskType: px.enum([PxMaskType.luminance, PxMaskType.alpha]).optional(),
|
|
1102
|
+
maskUnits: px.enum([PxUnits.userSpaceOnUse, PxUnits.objectBoundingBox]).optional(),
|
|
1103
|
+
maskContentUnits: px.enum([PxUnits.userSpaceOnUse, PxUnits.objectBoundingBox]).optional(),
|
|
1104
|
+
x: px.number().optional(),
|
|
1105
|
+
y: px.number().optional(),
|
|
1106
|
+
width: px.number().optional(),
|
|
1107
|
+
height: px.number().optional()
|
|
1108
|
+
}));
|
|
1109
|
+
var PxClipPathEffectSchema = implementsInterface()(px.object({
|
|
1110
|
+
pathData: PxAnimatableStringSchema.optional()
|
|
1111
|
+
}));
|
|
1112
|
+
var PxStrokeTrimEffectSchema = implementsInterface()(px.object({
|
|
1113
|
+
offset: PxAnimatableNumberSchema.optional(),
|
|
1114
|
+
range: PxAnimatableVec2Schema.optional(),
|
|
1115
|
+
subPaths: px.enum([PxStrokeTrimSubPaths.separate, PxStrokeTrimSubPaths.combined]).optional()
|
|
1116
|
+
}));
|
|
1117
|
+
var PxRetimeEffectSchema = implementsInterface()(px.object({
|
|
1118
|
+
start: px.number().optional(),
|
|
1119
|
+
stretch: px.number().optional(),
|
|
1120
|
+
timeCrop: px.tuple([px.number(), px.number()]).optional()
|
|
1121
|
+
}));
|
|
1122
|
+
var PxCloneEffectSchema = implementsInterface()(px.object({
|
|
1123
|
+
// Subtractive on purpose: the `<use>` can only point at one wrapper layer of the
|
|
1124
|
+
// source, so the choices form a ladder — 'translate' now, maybe 'transform' later.
|
|
1125
|
+
without: px.enum([PxCloneWithout.translate]).optional(),
|
|
1126
|
+
source: px.string().optional(),
|
|
1127
|
+
retime: PxRetimeEffectSchema.optional()
|
|
1128
|
+
}));
|
|
1129
|
+
var PxGradientStopSchema = implementsInterface()(px.object({
|
|
1130
|
+
offset: px.number(),
|
|
1131
|
+
color: px.string()
|
|
1132
|
+
}));
|
|
1133
|
+
var PxAnimatableGradientStopsSchema = px.union([
|
|
1134
|
+
px.array(PxGradientStopSchema),
|
|
1135
|
+
px.object({ value: px.array(PxGradientStopSchema) }),
|
|
1136
|
+
PxPropertyAnimationSchema
|
|
1137
|
+
]);
|
|
1138
|
+
var PxFillGradientEffectSchema = implementsInterface()(px.object({
|
|
1139
|
+
// Contextual kind — the `type` convention, see `PxNodeBaseSchema.type`.
|
|
1140
|
+
type: px.enum([PxGradientType.linear, PxGradientType.radial]),
|
|
1141
|
+
start: PxAnimatableVec2Schema.optional(),
|
|
1142
|
+
end: PxAnimatableVec2Schema.optional(),
|
|
1143
|
+
center: PxAnimatableVec2Schema.optional(),
|
|
1144
|
+
radius: PxAnimatableNumberSchema.optional(),
|
|
1145
|
+
focal: PxAnimatableVec2Schema.optional(),
|
|
1146
|
+
stops: PxAnimatableGradientStopsSchema.optional(),
|
|
1147
|
+
gradientUnits: px.enum([PxUnits.userSpaceOnUse, PxUnits.objectBoundingBox]).optional(),
|
|
1148
|
+
spreadMethod: px.enum([PxGradientSpreadMethod.pad, PxGradientSpreadMethod.reflect, PxGradientSpreadMethod.repeat]).optional(),
|
|
1149
|
+
gradientTransform: px.string().optional()
|
|
1150
|
+
}));
|
|
1151
|
+
var PxStrokeGradientEffectSchema = PxFillGradientEffectSchema;
|
|
1152
|
+
var PxTextPathEffectSchema = implementsInterface()(px.object({
|
|
1153
|
+
pathData: px.string(),
|
|
1154
|
+
pathOverflow: px.enum([PxPathOverflow.clip, PxPathOverflow.extend]).optional(),
|
|
1155
|
+
lengthAdjust: px.enum([PxLengthAdjust.spacing, PxLengthAdjust.spacingAndGlyphs]).optional(),
|
|
1156
|
+
method: px.enum([PxTextPathMethod.align, PxTextPathMethod.stretch]).optional(),
|
|
1157
|
+
spacing: px.enum([PxTextPathSpacing.auto, PxTextPathSpacing.exact]).optional(),
|
|
1158
|
+
startOffset: PxAnimatableNumberSchema.optional(),
|
|
1159
|
+
textLength: PxAnimatableNumberSchema.optional()
|
|
1160
|
+
}));
|
|
1161
|
+
var PxTextEffectSchema = implementsInterface()(px.object({
|
|
1162
|
+
useGlyphs: px.boolean().optional()
|
|
1163
|
+
}));
|
|
1164
|
+
var PxEffectsSchema = implementsInterface()(px.object({
|
|
1165
|
+
transformBy: PxTransformByEffectSchema.optional(),
|
|
1166
|
+
repeater: PxRepeaterEffectSchema.optional(),
|
|
1167
|
+
maskedBy: PxMaskedByEffectSchema.optional(),
|
|
1168
|
+
clipPath: PxClipPathEffectSchema.optional(),
|
|
1169
|
+
strokeTrim: PxStrokeTrimEffectSchema.optional(),
|
|
1170
|
+
clone: PxCloneEffectSchema.optional(),
|
|
1171
|
+
fillGradient: PxFillGradientEffectSchema.optional(),
|
|
1172
|
+
strokeGradient: PxStrokeGradientEffectSchema.optional(),
|
|
1173
|
+
textPath: PxTextPathEffectSchema.optional(),
|
|
1174
|
+
text: PxTextEffectSchema.optional()
|
|
1175
|
+
}));
|
|
1176
|
+
function validateNodeEffects(root, options) {
|
|
1177
|
+
const warnings = [];
|
|
1178
|
+
const walk = (node, path) => {
|
|
1179
|
+
if (node && node.effects) {
|
|
1180
|
+
const ctx = { errors: [], warnings: [], strict: !!(options == null ? void 0 : options.strict) };
|
|
1181
|
+
const ok = PxEffectsSchema.isValid(node.effects, ctx, [path + ".effects"]);
|
|
1182
|
+
if (!ok) {
|
|
1183
|
+
for (const err of ctx.errors) warnings.push(err);
|
|
1184
|
+
}
|
|
1185
|
+
}
|
|
1186
|
+
if (node && Array.isArray(node.children)) {
|
|
1187
|
+
node.children.forEach((c, i) => walk(c, path + ".children[" + i + "]"));
|
|
1188
|
+
}
|
|
1189
|
+
};
|
|
1190
|
+
walk(root, "root");
|
|
1191
|
+
return warnings;
|
|
1192
|
+
}
|
|
1193
|
+
function validateGlyphFontRefs(root, fonts) {
|
|
1194
|
+
if (!fonts || !Object.keys(fonts).length) return [];
|
|
1195
|
+
const problems = [];
|
|
1196
|
+
const walk = (node, path, inherited, inGlyphText) => {
|
|
1197
|
+
var _a2, _b;
|
|
1198
|
+
if (!node) return;
|
|
1199
|
+
const own = typeof node.fontFamily === "string" ? node.fontFamily : void 0;
|
|
1200
|
+
const family = own != null ? own : inherited;
|
|
1201
|
+
const isGlyphText = inGlyphText || node.type === "text" && !!((_b = (_a2 = node.effects) == null ? void 0 : _a2.text) == null ? void 0 : _b.useGlyphs);
|
|
1202
|
+
if (isGlyphText && own && !Object.prototype.hasOwnProperty.call(fonts, own)) {
|
|
1203
|
+
const problem = path + ': glyph-mode text uses font-family "' + own + '", which has no entry in animator.definitions.fonts';
|
|
1204
|
+
if (!problems.includes(problem)) problems.push(problem);
|
|
1205
|
+
}
|
|
1206
|
+
if (Array.isArray(node.children)) {
|
|
1207
|
+
node.children.forEach((c, i) => walk(c, path + ".children[" + i + "]", family, isGlyphText));
|
|
1208
|
+
}
|
|
1209
|
+
};
|
|
1210
|
+
walk(root, "root", void 0, false);
|
|
1211
|
+
return problems;
|
|
1212
|
+
}
|
|
1213
|
+
function validateEasingRefs(root, easings) {
|
|
1214
|
+
const problems = [];
|
|
1215
|
+
const walk = (node, path) => {
|
|
1216
|
+
if (Array.isArray(node)) {
|
|
1217
|
+
node.forEach((item, i) => walk(item, path + "[" + i + "]"));
|
|
1218
|
+
return;
|
|
1219
|
+
}
|
|
1220
|
+
if (!node || typeof node !== "object") return;
|
|
1221
|
+
const easing = node.easing;
|
|
1222
|
+
if (typeof easing === "string" && !(easings && Object.prototype.hasOwnProperty.call(easings, easing))) {
|
|
1223
|
+
const problem = path + '.easing: "' + easing + '" names no entry in animator.definitions.easings \u2014 it will play linear';
|
|
1224
|
+
if (!problems.includes(problem)) problems.push(problem);
|
|
1225
|
+
}
|
|
1226
|
+
for (const [key, value] of Object.entries(node)) {
|
|
1227
|
+
if (key === "easing") continue;
|
|
1228
|
+
if (value && typeof value === "object") walk(value, path + "." + key);
|
|
1229
|
+
}
|
|
1230
|
+
};
|
|
1231
|
+
walk(root, "root");
|
|
1232
|
+
return problems;
|
|
1233
|
+
}
|
|
1234
|
+
function validateVersionStamp(doc) {
|
|
1235
|
+
var _a2;
|
|
1236
|
+
const version = (_a2 = getAnimatorConfig(doc)) == null ? void 0 : _a2.version;
|
|
1237
|
+
if (version === void 0) return [];
|
|
1238
|
+
if (parseWireVersion(version) !== void 0) return [];
|
|
1239
|
+
return ["root.animator.version: " + JSON.stringify(version) + ' is not a version stamp ("a.b" or "a.b.c") \u2014 it reads as unstamped'];
|
|
1240
|
+
}
|
|
1241
|
+
function validateDocument(doc, options) {
|
|
1242
|
+
var _a2;
|
|
1243
|
+
const strict = (options == null ? void 0 : options.strict) !== false;
|
|
1244
|
+
const ctx = { errors: [], warnings: [], strict };
|
|
1245
|
+
const problems = PxAnimatedSvgDocumentSchema.isValid(doc, ctx, ["root"]) ? [] : [...ctx.errors];
|
|
1246
|
+
if (doc && typeof doc === "object") {
|
|
1247
|
+
for (const w of validateNodeEffects(doc, { strict })) {
|
|
1248
|
+
if (!problems.includes(w)) problems.push(w);
|
|
1249
|
+
}
|
|
1250
|
+
const defs = (_a2 = getAnimatorConfig(doc)) == null ? void 0 : _a2.definitions;
|
|
1251
|
+
for (const w of validateGlyphFontRefs(doc, defs == null ? void 0 : defs.fonts)) {
|
|
1252
|
+
if (!problems.includes(w)) problems.push(w);
|
|
1253
|
+
}
|
|
1254
|
+
for (const w of validateEasingRefs(doc, defs == null ? void 0 : defs.easings)) {
|
|
1255
|
+
if (!problems.includes(w)) problems.push(w);
|
|
1256
|
+
}
|
|
1257
|
+
for (const w of validateVersionStamp(doc)) {
|
|
1258
|
+
if (!problems.includes(w)) problems.push(w);
|
|
1259
|
+
}
|
|
1260
|
+
}
|
|
1261
|
+
return problems;
|
|
1262
|
+
}
|
|
1263
|
+
var PxNodeBaseSchema = px.openObject({
|
|
1264
|
+
// CONVENTION (SCHEMA-DESIGN R1 / issues N4): `type` is the ONE word for "what
|
|
1265
|
+
// kind of thing is this", discriminated by its CARRIER — here the node TAG
|
|
1266
|
+
// (`rect`, `text`), and inside a sub-object that object's kind (`fillGradient.type`,
|
|
1267
|
+
// `fillGradient.type`, editor `preset.type`). Each sits in its own object, so
|
|
1268
|
+
// the carrier disambiguates completely; synonyms (`cloneKind`, `presetShape`)
|
|
1269
|
+
// would add words that all mean "type" and still need the carrier to read.
|
|
1270
|
+
// Guarding a `type` SLOT against a wrong VALUE is the job of strict enums
|
|
1271
|
+
// (issues V3), never of distinct key names.
|
|
1272
|
+
type: px.string(),
|
|
1273
|
+
// The escape hatch for elements that carry a REAL `type` attribute — `<feTurbulence
|
|
1274
|
+
// type="fractalNoise">`, `<feFuncR type="table">`, `<feColorMatrix type="saturate">`.
|
|
1275
|
+
// `type` is taken by the tag name, so the attribute travels here and the renderer puts
|
|
1276
|
+
// it back (`PxAnimatorDOM.renderNode`, `PxRnRender`). Declared here — not merely
|
|
1277
|
+
// documented — because a wire key that is not in a schema is invisible to the
|
|
1278
|
+
// minifier's reserve list and gets renamed (dev-docs/plans/minification-boundary.md §1.1).
|
|
1279
|
+
domType: px.string().optional(),
|
|
1280
|
+
// Text content of a `<text>` / `<tspan>`. Declared, so a non-string value is a schema error
|
|
1281
|
+
// and the minifier reserves the key; `text` is NOT an alias for it and is not read anywhere.
|
|
1282
|
+
textContent: px.string().optional(),
|
|
1283
|
+
id: px.string().optional(),
|
|
1284
|
+
meta: px.any().optional(),
|
|
1285
|
+
// Player-effects bucket emitted by the Editor's lightweight design format.
|
|
1286
|
+
// Consumed and removed by `materializeNodeEffects` before any other normalization
|
|
1287
|
+
// (see `createAnimatorImpl`), so downstream code never sees it.
|
|
1288
|
+
effects: PxEffectsSchema.optional(),
|
|
1289
|
+
// `PxElementAnimation` (not just `PxAnimationDefinition`) — accepts
|
|
1290
|
+
// string ref / array of refs / inline definition / mixed array; mirrors
|
|
1291
|
+
// `node.animate` values and what `processNode` resolves at runtime.
|
|
1292
|
+
animate: PxElementAnimationSchema.optional(),
|
|
1293
|
+
style: px.record(px.union([px.string(), px.number()])).optional()
|
|
1294
|
+
}, PxAttrValueSchema);
|
|
1295
|
+
var PxNodeSchema = px.openObject(__spreadProps(__spreadValues({}, PxNodeBaseSchema._shape), {
|
|
1296
|
+
children: px.lazy(() => px.array(PxNodeSchema), []).optional()
|
|
1297
|
+
}), PxAttrValueSchema);
|
|
1298
|
+
var PxSvgNodeRootSchema = px.object({
|
|
1299
|
+
// `"100%"` and other SVG length strings are legal here — a number-only slot rejected
|
|
1300
|
+
// real documents (e.g. apple-store-look-14-main.json) at the root <svg>.
|
|
1301
|
+
width: px.union([px.number(), px.string()]).optional(),
|
|
1302
|
+
height: px.union([px.number(), px.string()]).optional(),
|
|
1303
|
+
viewBox: px.string().optional(),
|
|
1304
|
+
animator: PxAnimatorConfigSchema.optional()
|
|
1305
|
+
});
|
|
1306
|
+
var PxAnimatedSvgDocumentSchema = px.openObject(__spreadProps(__spreadValues(__spreadValues({}, PxNodeBaseSchema._shape), PxSvgNodeRootSchema._shape), {
|
|
1307
|
+
type: px.literal("svg"),
|
|
1308
|
+
// override string → literal to require 'svg'
|
|
1309
|
+
children: px.array(PxNodeSchema).optional()
|
|
1310
|
+
}), PxAttrValueSchema);
|
|
1311
|
+
var PxBezierPathSchema = implementsInterface()(px.object({
|
|
1312
|
+
v: px.array(px.array(px.number())),
|
|
1313
|
+
i: px.array(px.array(px.number())).optional(),
|
|
1314
|
+
o: px.array(px.array(px.number())).optional(),
|
|
1315
|
+
c: px.boolean().optional()
|
|
1316
|
+
}));
|
|
1317
|
+
|
|
1318
|
+
// src/util/PxAnimatorUtil.ts
|
|
1319
|
+
function bezierToSvgPath(path, forceCurves = false) {
|
|
1320
|
+
var _a2, _b, _c, _d;
|
|
1321
|
+
const v = path.v;
|
|
1322
|
+
const i = path.i;
|
|
1323
|
+
const o = path.o;
|
|
1324
|
+
const c = path.c;
|
|
1325
|
+
if (!v.length) return "";
|
|
1326
|
+
const d = [];
|
|
1327
|
+
const len = v.length;
|
|
1328
|
+
d.push("M" + v[0][0] + "," + v[0][1]);
|
|
1329
|
+
for (let idx = 1; idx < len; idx++) {
|
|
1330
|
+
const prevV = v[idx - 1];
|
|
1331
|
+
const prevO = (_a2 = o == null ? void 0 : o[idx - 1]) != null ? _a2 : prevV;
|
|
1332
|
+
const currI = (_b = i == null ? void 0 : i[idx]) != null ? _b : v[idx];
|
|
1333
|
+
const currV = v[idx];
|
|
1334
|
+
const isLine = !forceCurves && (prevO[0] === prevV[0] && prevO[1] === prevV[1]) && (currI[0] === currV[0] && currI[1] === currV[1]);
|
|
1335
|
+
if (isLine) {
|
|
1336
|
+
d.push("L" + currV[0] + "," + currV[1]);
|
|
1337
|
+
} else {
|
|
1338
|
+
d.push("C" + prevO[0] + "," + prevO[1] + "," + currI[0] + "," + currI[1] + "," + currV[0] + "," + currV[1]);
|
|
1339
|
+
}
|
|
1340
|
+
}
|
|
1341
|
+
if (c && len > 0) {
|
|
1342
|
+
const lastV = v[len - 1];
|
|
1343
|
+
const lastO = (_c = o == null ? void 0 : o[len - 1]) != null ? _c : lastV;
|
|
1344
|
+
const firstI = (_d = i == null ? void 0 : i[0]) != null ? _d : v[0];
|
|
1345
|
+
const firstV = v[0];
|
|
1346
|
+
const isLine = !forceCurves && (lastO[0] === lastV[0] && lastO[1] === lastV[1]) && (firstI[0] === firstV[0] && firstI[1] === firstV[1]);
|
|
1347
|
+
if (!isLine) {
|
|
1348
|
+
d.push("C" + lastO[0] + "," + lastO[1] + "," + firstI[0] + "," + firstI[1] + "," + firstV[0] + "," + firstV[1]);
|
|
1349
|
+
}
|
|
1350
|
+
d.push("z");
|
|
1351
|
+
}
|
|
1352
|
+
return d.join("");
|
|
1353
|
+
}
|
|
1354
|
+
function interpolateNum(a, b, t) {
|
|
1355
|
+
return a + (b - a) * t;
|
|
1356
|
+
}
|
|
1357
|
+
function interpolateVec(a, b, t) {
|
|
1358
|
+
const res = [];
|
|
1359
|
+
const count = Math.max(a.length, b.length);
|
|
1360
|
+
for (let i = 0; i < count; i++) {
|
|
1361
|
+
res[i] = interpolateNum(a[i] || 0, b[i] || 0, t);
|
|
1362
|
+
}
|
|
1363
|
+
return res;
|
|
1364
|
+
}
|
|
1365
|
+
function interpolateColor(a, b, t) {
|
|
1366
|
+
return [
|
|
1367
|
+
interpolateNum(a[0] || 0, b[0] || 0, t),
|
|
1368
|
+
interpolateNum(a[1] || 0, b[1] || 0, t),
|
|
1369
|
+
interpolateNum(a[2] || 0, b[2] || 0, t),
|
|
1370
|
+
interpolateNum(a[3] === void 0 ? 1 : a[3], b[3] === void 0 ? 1 : b[3], t)
|
|
1371
|
+
];
|
|
1372
|
+
}
|
|
1373
|
+
function interpolateBeziers(paths1, paths2, progress) {
|
|
1374
|
+
const count = Math.max(paths1.length, paths2.length);
|
|
1375
|
+
const res = [];
|
|
1376
|
+
for (let i = 0; i < count; i++) {
|
|
1377
|
+
res.push(interpolateBezier(paths1[i], paths2[i], progress));
|
|
1378
|
+
}
|
|
1379
|
+
return res;
|
|
1380
|
+
}
|
|
1381
|
+
function interpolateBezier(path1, path2, progress) {
|
|
1382
|
+
var _a2, _b, _c, _d, _e, _f, _g, _h, _i;
|
|
1383
|
+
if (!path1 || !path2) return path1 || path2 || { v: [] };
|
|
1384
|
+
const t = Math.min(Math.max(progress, 0), 1);
|
|
1385
|
+
const len = Math.min(path1.v.length, path2.v.length);
|
|
1386
|
+
const v = [];
|
|
1387
|
+
const i = [];
|
|
1388
|
+
const o = [];
|
|
1389
|
+
for (let idx = 0; idx < len; idx++) {
|
|
1390
|
+
const v1 = path1.v[idx];
|
|
1391
|
+
const v2 = path2.v[idx];
|
|
1392
|
+
v.push(interpolateVec(v1, v2, t));
|
|
1393
|
+
const i1 = (_b = (_a2 = path1.i) == null ? void 0 : _a2[idx]) != null ? _b : v1;
|
|
1394
|
+
const i2 = (_d = (_c = path2.i) == null ? void 0 : _c[idx]) != null ? _d : v2;
|
|
1395
|
+
i.push(interpolateVec(i1, i2, t));
|
|
1396
|
+
const o1 = (_f = (_e = path1.o) == null ? void 0 : _e[idx]) != null ? _f : v1;
|
|
1397
|
+
const o2 = (_h = (_g = path2.o) == null ? void 0 : _g[idx]) != null ? _h : v2;
|
|
1398
|
+
o.push(interpolateVec(o1, o2, t));
|
|
1399
|
+
}
|
|
1400
|
+
return { v, i: i.length ? i : void 0, o: o.length ? o : void 0, c: (_i = path1.c) != null ? _i : path2.c };
|
|
1401
|
+
}
|
|
1402
|
+
function solveCubicBezierX(p1x, p2x, x) {
|
|
1403
|
+
if (x <= 0) return 0;
|
|
1404
|
+
if (x >= 1) return 1;
|
|
1405
|
+
const cx = 3 * p1x;
|
|
1406
|
+
const bx = 3 * (p2x - p1x) - cx;
|
|
1407
|
+
const ax = 1 - cx - bx;
|
|
1408
|
+
function sampleX(t) {
|
|
1409
|
+
return ((ax * t + bx) * t + cx) * t;
|
|
1410
|
+
}
|
|
1411
|
+
function sampleDX(t) {
|
|
1412
|
+
return (3 * ax * t + 2 * bx) * t + cx;
|
|
1413
|
+
}
|
|
1414
|
+
let t2 = x;
|
|
1415
|
+
let t0 = 0;
|
|
1416
|
+
let t1 = 1;
|
|
1417
|
+
for (let i = 0; i < 8; i++) {
|
|
1418
|
+
const x2 = sampleX(t2) - x;
|
|
1419
|
+
if (Math.abs(x2) < 1e-6) return t2;
|
|
1420
|
+
const d2 = sampleDX(t2);
|
|
1421
|
+
if (Math.abs(d2) < 1e-6) break;
|
|
1422
|
+
t2 -= x2 / d2;
|
|
1423
|
+
}
|
|
1424
|
+
t2 = x;
|
|
1425
|
+
while (t0 < t1) {
|
|
1426
|
+
const x2 = sampleX(t2);
|
|
1427
|
+
if (Math.abs(x2 - x) < 1e-6) return t2;
|
|
1428
|
+
if (x > x2) t0 = t2;
|
|
1429
|
+
else t1 = t2;
|
|
1430
|
+
t2 = (t1 + t0) / 2;
|
|
1431
|
+
}
|
|
1432
|
+
return t2;
|
|
1433
|
+
}
|
|
1434
|
+
function cubicBezier(easing) {
|
|
1435
|
+
const [p1x, p1y, p2x, p2y] = easing;
|
|
1436
|
+
const cy = 3 * p1y;
|
|
1437
|
+
const by = 3 * (p2y - p1y) - cy;
|
|
1438
|
+
const ay = 1 - cy - by;
|
|
1439
|
+
function sampleCurveY(t) {
|
|
1440
|
+
return ((ay * t + by) * t + cy) * t;
|
|
1441
|
+
}
|
|
1442
|
+
return function(x) {
|
|
1443
|
+
return sampleCurveY(solveCubicBezierX(p1x, p2x, x));
|
|
1444
|
+
};
|
|
1445
|
+
}
|
|
1446
|
+
function lerp2(a, b, t) {
|
|
1447
|
+
return [a[0] + (b[0] - a[0]) * t, a[1] + (b[1] - a[1]) * t];
|
|
1448
|
+
}
|
|
1449
|
+
function subdivideCubicBezier(p0, p1, p2, p3, t) {
|
|
1450
|
+
const q0 = lerp2(p0, p1, t);
|
|
1451
|
+
const q1 = lerp2(p1, p2, t);
|
|
1452
|
+
const q2 = lerp2(p2, p3, t);
|
|
1453
|
+
const r0 = lerp2(q0, q1, t);
|
|
1454
|
+
const r1 = lerp2(q1, q2, t);
|
|
1455
|
+
const s = lerp2(r0, r1, t);
|
|
1456
|
+
return {
|
|
1457
|
+
left: [p0, q0, r0, s],
|
|
1458
|
+
right: [s, r1, q2, p3]
|
|
1459
|
+
};
|
|
1460
|
+
}
|
|
1461
|
+
function splitEasing(easing, xFraction) {
|
|
1462
|
+
if (!easing) return { left: void 0, right: void 0 };
|
|
1463
|
+
if (xFraction <= 0) return { left: void 0, right: easing };
|
|
1464
|
+
if (xFraction >= 1) return { left: easing, right: void 0 };
|
|
1465
|
+
const [x1, y1, x2, y2] = easing;
|
|
1466
|
+
const t = solveCubicBezierX(x1, x2, xFraction);
|
|
1467
|
+
const p0 = [0, 0];
|
|
1468
|
+
const p1 = [x1, y1];
|
|
1469
|
+
const p2 = [x2, y2];
|
|
1470
|
+
const p3 = [1, 1];
|
|
1471
|
+
const { left, right } = subdivideCubicBezier(p0, p1, p2, p3, t);
|
|
1472
|
+
const sx = left[3][0];
|
|
1473
|
+
const sy = left[3][1];
|
|
1474
|
+
let leftEasing;
|
|
1475
|
+
if (sx > 1e-9 && Math.abs(sy) > 1e-9) {
|
|
1476
|
+
leftEasing = [
|
|
1477
|
+
left[1][0] / sx,
|
|
1478
|
+
left[1][1] / sy,
|
|
1479
|
+
left[2][0] / sx,
|
|
1480
|
+
left[2][1] / sy
|
|
1481
|
+
];
|
|
1482
|
+
}
|
|
1483
|
+
let rightEasing;
|
|
1484
|
+
const rx = 1 - sx;
|
|
1485
|
+
const ry = 1 - sy;
|
|
1486
|
+
if (rx > 1e-9 && Math.abs(ry) > 1e-9) {
|
|
1487
|
+
rightEasing = [
|
|
1488
|
+
(right[1][0] - sx) / rx,
|
|
1489
|
+
(right[1][1] - sy) / ry,
|
|
1490
|
+
(right[2][0] - sx) / rx,
|
|
1491
|
+
(right[2][1] - sy) / ry
|
|
1492
|
+
];
|
|
1493
|
+
}
|
|
1494
|
+
return { left: leftEasing, right: rightEasing };
|
|
1495
|
+
}
|
|
1496
|
+
function reverseEasing(easing) {
|
|
1497
|
+
if (!easing) return void 0;
|
|
1498
|
+
return [1 - easing[2], 1 - easing[3], 1 - easing[0], 1 - easing[1]];
|
|
1499
|
+
}
|
|
1500
|
+
function toRGBA(color) {
|
|
1501
|
+
const r = Math.round(color[0] * 255);
|
|
1502
|
+
const g = Math.round(color[1] * 255);
|
|
1503
|
+
const b = Math.round(color[2] * 255);
|
|
1504
|
+
return color.length === 4 ? "rgba(" + r + "," + g + "," + b + "," + color[3] + ")" : "rgb(" + r + "," + g + "," + b + ")";
|
|
1505
|
+
}
|
|
1506
|
+
var PX_COLOR_ATTR_NAMES = /* @__PURE__ */ new Set(["color", "fill", "flood-color", "lighting-color", "stop-color", "stroke"]);
|
|
1507
|
+
var PX_TRANSFORM_FN_NAMES = /* @__PURE__ */ new Set(["translate", "rotate", "scale", "skew"]);
|
|
1508
|
+
var PX_PCT_BASED_ATTR_NAMES = /* @__PURE__ */ new Set(["offset-distance", "offsetDistance"]);
|
|
1509
|
+
function composeTransformParts(parts, opts) {
|
|
1510
|
+
var _a2;
|
|
1511
|
+
if (!parts) return "";
|
|
1512
|
+
const withUnits = (_a2 = opts == null ? void 0 : opts.withUnits) != null ? _a2 : true;
|
|
1513
|
+
const segs = [];
|
|
1514
|
+
const t = parts.translate;
|
|
1515
|
+
const o = parts.origin;
|
|
1516
|
+
const r = parts.rotate;
|
|
1517
|
+
const k = parts.skew;
|
|
1518
|
+
const s = parts.scale;
|
|
1519
|
+
const tu = withUnits ? "px" : "";
|
|
1520
|
+
const ru = withUnits ? "deg" : "";
|
|
1521
|
+
if (t) segs.push("translate(" + t[0] + tu + "," + t[1] + tu + ")");
|
|
1522
|
+
if (o) segs.push("translate(" + o[0] + tu + "," + o[1] + tu + ")");
|
|
1523
|
+
if (r !== void 0 && r !== null) segs.push("rotate(" + r + ru + ")");
|
|
1524
|
+
if (k !== void 0 && k !== null) segs.push("skewX(" + k + ru + ")");
|
|
1525
|
+
if (s) segs.push("scale(" + s[0] + "," + s[1] + ")");
|
|
1526
|
+
if (o) segs.push("translate(" + -o[0] + tu + "," + -o[1] + tu + ")");
|
|
1527
|
+
return segs.join("");
|
|
1528
|
+
}
|
|
1529
|
+
function parseTransformParts(str2) {
|
|
1530
|
+
var _a2, _b;
|
|
1531
|
+
if (!str2 || typeof str2 !== "string") return void 0;
|
|
1532
|
+
const out = {};
|
|
1533
|
+
const re = /([a-zA-Z]+)\s*\(([^)]*)\)/g;
|
|
1534
|
+
const order = ["translate", "rotate", "skewX", "scale"];
|
|
1535
|
+
let lastIdx = -1;
|
|
1536
|
+
let m;
|
|
1537
|
+
while ((m = re.exec(str2)) !== null) {
|
|
1538
|
+
const fn = m[1];
|
|
1539
|
+
const idx = order.indexOf(fn);
|
|
1540
|
+
if (idx < 0 || idx <= lastIdx) return void 0;
|
|
1541
|
+
lastIdx = idx;
|
|
1542
|
+
const nums = m[2].split(/[\s,]+/).filter(Boolean).map(Number);
|
|
1543
|
+
if (nums.some((n) => Number.isNaN(n))) return void 0;
|
|
1544
|
+
if (fn === "translate") {
|
|
1545
|
+
if (nums.length < 1 || nums.length > 2) return void 0;
|
|
1546
|
+
out.translate = [nums[0], (_a2 = nums[1]) != null ? _a2 : 0];
|
|
1547
|
+
} else if (fn === "rotate") {
|
|
1548
|
+
if (nums.length !== 1) return void 0;
|
|
1549
|
+
out.rotate = nums[0];
|
|
1550
|
+
} else if (fn === "skewX") {
|
|
1551
|
+
if (nums.length !== 1) return void 0;
|
|
1552
|
+
out.skew = nums[0];
|
|
1553
|
+
} else {
|
|
1554
|
+
if (nums.length < 1 || nums.length > 2) return void 0;
|
|
1555
|
+
out.scale = [nums[0], (_b = nums[1]) != null ? _b : nums[0]];
|
|
1556
|
+
}
|
|
1557
|
+
}
|
|
1558
|
+
if (str2.replace(/([a-zA-Z]+)\s*\(([^)]*)\)/g, "").replace(/[\s,]/g, "").length) return void 0;
|
|
1559
|
+
return Object.keys(out).length ? out : void 0;
|
|
1560
|
+
}
|
|
1561
|
+
var PX_STYLE_ATTR_NAMES = /* @__PURE__ */ new Set(["offset-distance", "offsetDistance"]);
|
|
1562
|
+
var PX_DEFAULT_DURATION_MS = 1e3;
|
|
1563
|
+
function kebabToCamelCaseWord(kebab) {
|
|
1564
|
+
return kebab.includes("-") ? kebab.replace(/-([a-z])/g, (_, letter) => letter.toUpperCase()) : kebab;
|
|
1565
|
+
}
|
|
1566
|
+
var SVG_CAMEL_CASE_ATTRS = /* @__PURE__ */ new Set([
|
|
1567
|
+
// Transform/positioning
|
|
1568
|
+
"viewBox",
|
|
1569
|
+
"preserveAspectRatio",
|
|
1570
|
+
// Gradient
|
|
1571
|
+
"gradientUnits",
|
|
1572
|
+
"gradientTransform",
|
|
1573
|
+
"spreadMethod",
|
|
1574
|
+
// Pattern
|
|
1575
|
+
"patternUnits",
|
|
1576
|
+
"patternContentUnits",
|
|
1577
|
+
"patternTransform",
|
|
1578
|
+
// Clipping/masking
|
|
1579
|
+
"clipPathUnits",
|
|
1580
|
+
"maskUnits",
|
|
1581
|
+
"maskContentUnits",
|
|
1582
|
+
// Marker (SVG spec keeps these camelCase, like viewBox)
|
|
1583
|
+
"markerUnits",
|
|
1584
|
+
"markerWidth",
|
|
1585
|
+
"markerHeight",
|
|
1586
|
+
"refX",
|
|
1587
|
+
"refY",
|
|
1588
|
+
// Text
|
|
1589
|
+
"textLength",
|
|
1590
|
+
"lengthAdjust",
|
|
1591
|
+
"startOffset",
|
|
1592
|
+
// Filter
|
|
1593
|
+
"filterUnits",
|
|
1594
|
+
"primitiveUnits",
|
|
1595
|
+
"tableValues",
|
|
1596
|
+
// feFuncR/G/B/A transfer table (type="table")
|
|
1597
|
+
"stdDeviation",
|
|
1598
|
+
"baseFrequency",
|
|
1599
|
+
"numOctaves",
|
|
1600
|
+
"surfaceScale",
|
|
1601
|
+
"diffuseConstant",
|
|
1602
|
+
"specularConstant",
|
|
1603
|
+
"specularExponent",
|
|
1604
|
+
"kernelMatrix",
|
|
1605
|
+
"kernelUnitLength",
|
|
1606
|
+
"edgeMode",
|
|
1607
|
+
"preserveAlpha",
|
|
1608
|
+
"targetX",
|
|
1609
|
+
"targetY"
|
|
1610
|
+
// // Animation
|
|
1611
|
+
// 'attributeName',
|
|
1612
|
+
// 'attributeType',
|
|
1613
|
+
// 'calcMode',
|
|
1614
|
+
// 'keyTimes',
|
|
1615
|
+
// 'keySplines',
|
|
1616
|
+
// 'repeatCount',
|
|
1617
|
+
// 'repeatDur'
|
|
1618
|
+
]);
|
|
1619
|
+
function camelCaseToKebabWordIfNeeded(camel) {
|
|
1620
|
+
return SVG_CAMEL_CASE_ATTRS.has(camel) ? camel : camel.replace(/([a-z0-9])([A-Z])/g, "$1-$2").toLowerCase();
|
|
1621
|
+
}
|
|
1622
|
+
function clamp(value, min, max) {
|
|
1623
|
+
return Math.max(min, Math.min(value, max));
|
|
1624
|
+
}
|
|
1625
|
+
function bezier2D_pointAt(P0, P1, P2, P3, t) {
|
|
1626
|
+
if (t <= 0) return [P0[0], P0[1]];
|
|
1627
|
+
if (t >= 1) return [P3[0], P3[1]];
|
|
1628
|
+
const u = 1 - t;
|
|
1629
|
+
const u2 = u * u;
|
|
1630
|
+
const u3 = u2 * u;
|
|
1631
|
+
const t2 = t * t;
|
|
1632
|
+
const t3 = t2 * t;
|
|
1633
|
+
const w0 = u3;
|
|
1634
|
+
const w1 = 3 * t * u2;
|
|
1635
|
+
const w2 = 3 * t2 * u;
|
|
1636
|
+
const w3 = t3;
|
|
1637
|
+
return [
|
|
1638
|
+
w0 * P0[0] + w1 * P1[0] + w2 * P2[0] + w3 * P3[0],
|
|
1639
|
+
w0 * P0[1] + w1 * P1[1] + w2 * P2[1] + w3 * P3[1]
|
|
1640
|
+
];
|
|
1641
|
+
}
|
|
1642
|
+
var BEZIER_T_NUDGE = 1e-4;
|
|
1643
|
+
function bezier2D_derivativeAt(P0, P1, P2, P3, t) {
|
|
1644
|
+
const result = _bezier2D_derivativeAtRaw(P0, P1, P2, P3, t);
|
|
1645
|
+
if (result[0] === 0 && result[1] === 0) {
|
|
1646
|
+
const nudgedT = t < 0.5 ? t + BEZIER_T_NUDGE : t - BEZIER_T_NUDGE;
|
|
1647
|
+
return _bezier2D_derivativeAtRaw(P0, P1, P2, P3, nudgedT);
|
|
1648
|
+
}
|
|
1649
|
+
return result;
|
|
1650
|
+
}
|
|
1651
|
+
function _bezier2D_derivativeAtRaw(P0, P1, P2, P3, t) {
|
|
1652
|
+
const u = 1 - t;
|
|
1653
|
+
const a = 3 * u * u;
|
|
1654
|
+
const b = 6 * t * u;
|
|
1655
|
+
const c = 3 * t * t;
|
|
1656
|
+
return [
|
|
1657
|
+
a * (P1[0] - P0[0]) + b * (P2[0] - P1[0]) + c * (P3[0] - P2[0]),
|
|
1658
|
+
a * (P1[1] - P0[1]) + b * (P2[1] - P1[1]) + c * (P3[1] - P2[1])
|
|
1659
|
+
];
|
|
1660
|
+
}
|
|
1661
|
+
function bezier2D_arcLengthLUT(P0, P1, P2, P3, steps = 100) {
|
|
1662
|
+
const n = steps + 1;
|
|
1663
|
+
const ts = new Float64Array(n);
|
|
1664
|
+
const ds = new Float64Array(n);
|
|
1665
|
+
let prev = bezier2D_pointAt(P0, P1, P2, P3, 0);
|
|
1666
|
+
ts[0] = 0;
|
|
1667
|
+
ds[0] = 0;
|
|
1668
|
+
let cum = 0;
|
|
1669
|
+
for (let i = 1; i < n; i++) {
|
|
1670
|
+
const t = i / steps;
|
|
1671
|
+
const cur = bezier2D_pointAt(P0, P1, P2, P3, t);
|
|
1672
|
+
const dx = cur[0] - prev[0];
|
|
1673
|
+
const dy = cur[1] - prev[1];
|
|
1674
|
+
cum += Math.sqrt(dx * dx + dy * dy);
|
|
1675
|
+
ts[i] = t;
|
|
1676
|
+
ds[i] = cum;
|
|
1677
|
+
prev = cur;
|
|
1678
|
+
}
|
|
1679
|
+
return { ts, ds };
|
|
1680
|
+
}
|
|
1681
|
+
function bezier2D_tForDistance(lut, distance) {
|
|
1682
|
+
const { ts, ds } = lut;
|
|
1683
|
+
const last = ds.length - 1;
|
|
1684
|
+
if (distance <= 0) return ts[0];
|
|
1685
|
+
if (distance >= ds[last]) return ts[last];
|
|
1686
|
+
let lo = 1;
|
|
1687
|
+
let hi = last;
|
|
1688
|
+
while (lo < hi) {
|
|
1689
|
+
const mid = lo + hi >>> 1;
|
|
1690
|
+
if (ds[mid] < distance) lo = mid + 1;
|
|
1691
|
+
else hi = mid;
|
|
1692
|
+
}
|
|
1693
|
+
const dPrev = ds[hi - 1];
|
|
1694
|
+
const dCur = ds[hi];
|
|
1695
|
+
const span = dCur - dPrev;
|
|
1696
|
+
const frac = span > 0 ? (distance - dPrev) / span : 0;
|
|
1697
|
+
return ts[hi - 1] + frac * (ts[hi] - ts[hi - 1]);
|
|
1698
|
+
}
|
|
1699
|
+
function bezier2D_arcAtT(lut, t) {
|
|
1700
|
+
const { ts, ds } = lut;
|
|
1701
|
+
const last = ts.length - 1;
|
|
1702
|
+
if (t <= ts[0]) return ds[0];
|
|
1703
|
+
if (t >= ts[last]) return ds[last];
|
|
1704
|
+
let lo = 1, hi = last;
|
|
1705
|
+
while (lo < hi) {
|
|
1706
|
+
const mid = lo + hi >>> 1;
|
|
1707
|
+
if (ts[mid] < t) lo = mid + 1;
|
|
1708
|
+
else hi = mid;
|
|
1709
|
+
}
|
|
1710
|
+
const tPrev = ts[hi - 1];
|
|
1711
|
+
const span = ts[hi] - tPrev;
|
|
1712
|
+
const frac = span > 0 ? (t - tPrev) / span : 0;
|
|
1713
|
+
return ds[hi - 1] + frac * (ds[hi] - ds[hi - 1]);
|
|
1714
|
+
}
|
|
1715
|
+
function invertEasing(easing) {
|
|
1716
|
+
if (!easing) return (y) => y;
|
|
1717
|
+
const flipped = [easing[1], easing[0], easing[3], easing[2]];
|
|
1718
|
+
return cubicBezier(flipped);
|
|
1719
|
+
}
|
|
1720
|
+
|
|
1721
|
+
// src/materialize/PxMotionPath.ts
|
|
1722
|
+
function getKfTranslate(kf) {
|
|
1723
|
+
const v = keyframeValue(kf);
|
|
1724
|
+
if (!v) return void 0;
|
|
1725
|
+
if (Array.isArray(v) && v.length >= 2 && typeof v[0] === "number" && typeof v[1] === "number") {
|
|
1726
|
+
return [v[0], v[1]];
|
|
1727
|
+
}
|
|
1728
|
+
const tr = v.translate;
|
|
1729
|
+
if (Array.isArray(tr) && tr.length >= 2) return [tr[0], tr[1]];
|
|
1730
|
+
return void 0;
|
|
1731
|
+
}
|
|
1732
|
+
function getKfTime(kf) {
|
|
1733
|
+
return keyframeTime(kf);
|
|
1734
|
+
}
|
|
1735
|
+
function getKfEasing(kf) {
|
|
1736
|
+
return keyframeEasing(kf);
|
|
1737
|
+
}
|
|
1738
|
+
function propAnimIsMotionPath(anim) {
|
|
1739
|
+
const kfs = anim.keyframes;
|
|
1740
|
+
if (!Array.isArray(kfs)) return false;
|
|
1741
|
+
if (anim.autoOrient) return true;
|
|
1742
|
+
for (const kf of kfs) {
|
|
1743
|
+
if (keyframeTangentIn(kf) || keyframeTangentOut(kf)) return true;
|
|
1744
|
+
}
|
|
1745
|
+
return false;
|
|
1746
|
+
}
|
|
1747
|
+
var _segmentCache = /* @__PURE__ */ new WeakMap();
|
|
1748
|
+
function getSegmentCache(prevKf, nextKf, prevPos, nextPos) {
|
|
1749
|
+
let byNext = _segmentCache.get(prevKf);
|
|
1750
|
+
const existing = byNext == null ? void 0 : byNext.get(nextKf);
|
|
1751
|
+
if (existing) return existing;
|
|
1752
|
+
const to = keyframeTangentOut(prevKf);
|
|
1753
|
+
const ti = keyframeTangentIn(nextKf);
|
|
1754
|
+
const P1 = [prevPos[0] + (to ? to[0] : 0), prevPos[1] + (to ? to[1] : 0)];
|
|
1755
|
+
const P2 = [nextPos[0] + (ti ? ti[0] : 0), nextPos[1] + (ti ? ti[1] : 0)];
|
|
1756
|
+
const lut = bezier2D_arcLengthLUT(prevPos, P1, P2, nextPos);
|
|
1757
|
+
const entry = {
|
|
1758
|
+
P0: prevPos,
|
|
1759
|
+
P1,
|
|
1760
|
+
P2,
|
|
1761
|
+
P3: nextPos,
|
|
1762
|
+
lut,
|
|
1763
|
+
totalArc: lut.ds[lut.ds.length - 1]
|
|
1764
|
+
};
|
|
1765
|
+
if (!byNext) {
|
|
1766
|
+
byNext = /* @__PURE__ */ new WeakMap();
|
|
1767
|
+
_segmentCache.set(prevKf, byNext);
|
|
1768
|
+
}
|
|
1769
|
+
byNext.set(nextKf, entry);
|
|
1770
|
+
return entry;
|
|
1771
|
+
}
|
|
1772
|
+
var DEFAULT_FLATNESS_TOL = 0.5;
|
|
1773
|
+
var DEFAULT_ROTATION_TOL = 5;
|
|
1774
|
+
var DEFAULT_MAX_SAMPLES = 32;
|
|
1775
|
+
function materializeMotionPathInPropAnim(anim, opts) {
|
|
1776
|
+
var _a2, _b, _c;
|
|
1777
|
+
if (!propAnimIsMotionPath(anim)) return anim;
|
|
1778
|
+
const kfs = anim.keyframes;
|
|
1779
|
+
if (!Array.isArray(kfs) || kfs.length < 2) return anim;
|
|
1780
|
+
const autoOrient = !!anim.autoOrient;
|
|
1781
|
+
const flatnessTol = (_a2 = opts == null ? void 0 : opts.flatnessTolerance) != null ? _a2 : DEFAULT_FLATNESS_TOL;
|
|
1782
|
+
const rotationTol = (_b = opts == null ? void 0 : opts.rotationTolerance) != null ? _b : DEFAULT_ROTATION_TOL;
|
|
1783
|
+
const maxSamples = (_c = opts == null ? void 0 : opts.maxSamplesPerSegment) != null ? _c : DEFAULT_MAX_SAMPLES;
|
|
1784
|
+
const out = [];
|
|
1785
|
+
const firstPos = getKfTranslate(kfs[0]);
|
|
1786
|
+
if (!firstPos) return anim;
|
|
1787
|
+
const firstRotate = autoOrient ? derivAngleForFirstKf(kfs[0], kfs[1]) : void 0;
|
|
1788
|
+
out.push(makeOutKf(
|
|
1789
|
+
getKfTime(kfs[0]),
|
|
1790
|
+
buildOutKfValue(getKfValueParts(kfs[0]), getKfValueParts(kfs[0]), 0, firstPos, firstRotate, autoOrient)
|
|
1791
|
+
));
|
|
1792
|
+
for (let i = 0; i < kfs.length - 1; i++) {
|
|
1793
|
+
const prevKf = kfs[i];
|
|
1794
|
+
const nextKf = kfs[i + 1];
|
|
1795
|
+
const prevPos = getKfTranslate(prevKf);
|
|
1796
|
+
const nextPos = getKfTranslate(nextKf);
|
|
1797
|
+
if (!prevPos || !nextPos) {
|
|
1798
|
+
out.push(makeOutKf(
|
|
1799
|
+
getKfTime(nextKf),
|
|
1800
|
+
buildOutKfValue(getKfValueParts(nextKf), getKfValueParts(nextKf), 1, nextPos != null ? nextPos : [0, 0], void 0, autoOrient)
|
|
1801
|
+
));
|
|
1802
|
+
continue;
|
|
1803
|
+
}
|
|
1804
|
+
if (autoOrient && i > 0) {
|
|
1805
|
+
insertSharpCornerStepKfIfNeeded(out, prevKf, nextKf, prevPos, nextPos, rotationTol);
|
|
1806
|
+
}
|
|
1807
|
+
materializeSegment(out, prevKf, nextKf, prevPos, nextPos, autoOrient, flatnessTol, rotationTol, maxSamples);
|
|
1808
|
+
}
|
|
1809
|
+
const lastInE = getKfEasing(kfs[kfs.length - 1]);
|
|
1810
|
+
if (lastInE) out[out.length - 1].e = lastInE;
|
|
1811
|
+
if (autoOrient) unwrapAutoOrientRotations(out);
|
|
1812
|
+
const result = { keyframes: out };
|
|
1813
|
+
if (anim.loop !== void 0) result.loop = anim.loop;
|
|
1814
|
+
return result;
|
|
1815
|
+
}
|
|
1816
|
+
function unwrapAutoOrientRotations(kfs) {
|
|
1817
|
+
let prev;
|
|
1818
|
+
for (const kf of kfs) {
|
|
1819
|
+
const v = keyframeValue(kf);
|
|
1820
|
+
if (!v || typeof v.rotate !== "number") continue;
|
|
1821
|
+
if (prev === void 0) {
|
|
1822
|
+
prev = v.rotate;
|
|
1823
|
+
continue;
|
|
1824
|
+
}
|
|
1825
|
+
let r = v.rotate;
|
|
1826
|
+
while (r - prev > 180) r -= 360;
|
|
1827
|
+
while (r - prev < -180) r += 360;
|
|
1828
|
+
v.rotate = r;
|
|
1829
|
+
prev = r;
|
|
1830
|
+
}
|
|
1831
|
+
}
|
|
1832
|
+
function makeOutKf(time, value) {
|
|
1833
|
+
return { t: time, v: value };
|
|
1834
|
+
}
|
|
1835
|
+
function getKfValueParts(kf) {
|
|
1836
|
+
const v = keyframeValue(kf);
|
|
1837
|
+
if (!v || typeof v !== "object" || Array.isArray(v)) return void 0;
|
|
1838
|
+
return v;
|
|
1839
|
+
}
|
|
1840
|
+
function interpolatePart(prev, next, p) {
|
|
1841
|
+
if (prev === void 0) return next;
|
|
1842
|
+
if (next === void 0) return prev;
|
|
1843
|
+
if (typeof prev === "number" && typeof next === "number") {
|
|
1844
|
+
return prev + (next - prev) * p;
|
|
1845
|
+
}
|
|
1846
|
+
if (Array.isArray(prev) && Array.isArray(next) && prev.length === next.length) {
|
|
1847
|
+
const out = new Array(prev.length);
|
|
1848
|
+
for (let i = 0; i < prev.length; i++) {
|
|
1849
|
+
const a = typeof prev[i] === "number" ? prev[i] : 0;
|
|
1850
|
+
const b = typeof next[i] === "number" ? next[i] : 0;
|
|
1851
|
+
out[i] = a + (b - a) * p;
|
|
1852
|
+
}
|
|
1853
|
+
return out;
|
|
1854
|
+
}
|
|
1855
|
+
return p < 0.5 ? prev : next;
|
|
1856
|
+
}
|
|
1857
|
+
function buildOutKfValue(prevV, nextV, p, translate, rotateDegFromAutoOrient, autoOrient) {
|
|
1858
|
+
const value = { translate };
|
|
1859
|
+
const keys = /* @__PURE__ */ new Set();
|
|
1860
|
+
if (prevV) for (const k of Object.keys(prevV)) keys.add(k);
|
|
1861
|
+
if (nextV) for (const k of Object.keys(nextV)) keys.add(k);
|
|
1862
|
+
for (const k of keys) {
|
|
1863
|
+
if (k === "translate") continue;
|
|
1864
|
+
if (k === "rotate" && autoOrient) continue;
|
|
1865
|
+
const pv = prevV == null ? void 0 : prevV[k];
|
|
1866
|
+
const nv = nextV == null ? void 0 : nextV[k];
|
|
1867
|
+
if (pv === void 0 && nv === void 0) continue;
|
|
1868
|
+
value[k] = interpolatePart(pv, nv, p);
|
|
1869
|
+
}
|
|
1870
|
+
if (rotateDegFromAutoOrient !== void 0) {
|
|
1871
|
+
value.rotate = rotateDegFromAutoOrient + explicitRotateAt(prevV, nextV, p);
|
|
1872
|
+
}
|
|
1873
|
+
return value;
|
|
1874
|
+
}
|
|
1875
|
+
function explicitRotateAt(prevV, nextV, p) {
|
|
1876
|
+
const pv = typeof (prevV == null ? void 0 : prevV.rotate) === "number" ? prevV.rotate : void 0;
|
|
1877
|
+
const nv = typeof (nextV == null ? void 0 : nextV.rotate) === "number" ? nextV.rotate : void 0;
|
|
1878
|
+
if (pv === void 0 && nv === void 0) return 0;
|
|
1879
|
+
const r = interpolatePart(pv, nv, p);
|
|
1880
|
+
return typeof r === "number" ? r : 0;
|
|
1881
|
+
}
|
|
1882
|
+
function derivAngleForFirstKf(kf0, kf1) {
|
|
1883
|
+
const p0 = getKfTranslate(kf0);
|
|
1884
|
+
const p1 = getKfTranslate(kf1);
|
|
1885
|
+
if (!p0 || !p1) return 0;
|
|
1886
|
+
const seg = getSegmentCache(kf0, kf1, p0, p1);
|
|
1887
|
+
const tan = bezier2D_derivativeAt(seg.P0, seg.P1, seg.P2, seg.P3, 0);
|
|
1888
|
+
return Math.atan2(tan[1], tan[0]) * 180 / Math.PI;
|
|
1889
|
+
}
|
|
1890
|
+
function wrappedAngleDelta(a, b) {
|
|
1891
|
+
let d = a - b;
|
|
1892
|
+
while (d > 180) d -= 360;
|
|
1893
|
+
while (d < -180) d += 360;
|
|
1894
|
+
return d;
|
|
1895
|
+
}
|
|
1896
|
+
function insertSharpCornerStepKfIfNeeded(out, prevKf, nextKf, prevPos, nextPos, rotationTol) {
|
|
1897
|
+
const lastKf = out[out.length - 1];
|
|
1898
|
+
const lastV = keyframeValue(lastKf);
|
|
1899
|
+
const prevExit = lastV == null ? void 0 : lastV.rotate;
|
|
1900
|
+
if (typeof prevExit !== "number") return;
|
|
1901
|
+
const boundaryV = getKfValueParts(prevKf);
|
|
1902
|
+
const prevExitTangent = prevExit - explicitRotateAt(boundaryV, boundaryV, 0);
|
|
1903
|
+
const seg = getSegmentCache(prevKf, nextKf, prevPos, nextPos);
|
|
1904
|
+
const tanAtStart = bezier2D_derivativeAt(seg.P0, seg.P1, seg.P2, seg.P3, 0);
|
|
1905
|
+
const nextEntry = Math.atan2(tanAtStart[1], tanAtStart[0]) * 180 / Math.PI;
|
|
1906
|
+
const delta = wrappedAngleDelta(nextEntry, prevExitTangent);
|
|
1907
|
+
if (Math.abs(delta) <= rotationTol) return;
|
|
1908
|
+
const prevTime = getKfTime(prevKf);
|
|
1909
|
+
const stepTime = Math.min(prevTime + CORNER_STEP_AFTER_BOUNDARY_MS, (prevTime + getKfTime(nextKf)) / 2);
|
|
1910
|
+
const dupValue = buildOutKfValue(
|
|
1911
|
+
getKfValueParts(prevKf),
|
|
1912
|
+
getKfValueParts(prevKf),
|
|
1913
|
+
0,
|
|
1914
|
+
prevPos,
|
|
1915
|
+
nextEntry,
|
|
1916
|
+
true
|
|
1917
|
+
);
|
|
1918
|
+
out.push(makeOutKf(stepTime, dupValue));
|
|
1919
|
+
}
|
|
1920
|
+
var CORNER_STEP_AFTER_BOUNDARY_MS = 0.05;
|
|
1921
|
+
function materializeSegment(out, prevKf, nextKf, prevPos, nextPos, autoOrient, flatnessTol, rotationTol, maxSamples) {
|
|
1922
|
+
const seg = getSegmentCache(prevKf, nextKf, prevPos, nextPos);
|
|
1923
|
+
const prevTime = getKfTime(prevKf);
|
|
1924
|
+
const nextTime = getKfTime(nextKf);
|
|
1925
|
+
const prevEasing = getKfEasing(prevKf);
|
|
1926
|
+
const invertFn = invertEasing(prevEasing);
|
|
1927
|
+
const prevV = getKfValueParts(prevKf);
|
|
1928
|
+
const nextV = getKfValueParts(nextKf);
|
|
1929
|
+
const interiorTs = computeSampleTs(seg, autoOrient, flatnessTol, rotationTol, maxSamples);
|
|
1930
|
+
const samples = [];
|
|
1931
|
+
for (const t of interiorTs) {
|
|
1932
|
+
const arc = bezier2D_arcAtT(seg.lut, t);
|
|
1933
|
+
const p = clamp(seg.totalArc > 0 ? arc / seg.totalArc : t, 0, 1);
|
|
1934
|
+
const u = clamp(invertFn(p), 0, 1);
|
|
1935
|
+
const pos = bezier2D_pointAt(seg.P0, seg.P1, seg.P2, seg.P3, t);
|
|
1936
|
+
const sample = { u, p, pos };
|
|
1937
|
+
if (autoOrient) {
|
|
1938
|
+
const tan = bezier2D_derivativeAt(seg.P0, seg.P1, seg.P2, seg.P3, t);
|
|
1939
|
+
sample.rotateDeg = Math.atan2(tan[1], tan[0]) * 180 / Math.PI;
|
|
1940
|
+
}
|
|
1941
|
+
samples.push(sample);
|
|
1942
|
+
}
|
|
1943
|
+
let remaining = prevEasing;
|
|
1944
|
+
let prevU = 0;
|
|
1945
|
+
const startIdx = out.length - 1;
|
|
1946
|
+
for (let i = 0; i < samples.length; i++) {
|
|
1947
|
+
const s = samples[i];
|
|
1948
|
+
const xFrac = prevU < 1 ? clamp((s.u - prevU) / (1 - prevU), 0, 1) : 1;
|
|
1949
|
+
const { left, right } = splitEasing(remaining, xFrac);
|
|
1950
|
+
const ownerIdx = i === 0 ? startIdx : out.length - 1;
|
|
1951
|
+
if (left) out[ownerIdx].e = left;
|
|
1952
|
+
else delete out[ownerIdx].e;
|
|
1953
|
+
const tGlobal = prevTime + s.u * (nextTime - prevTime);
|
|
1954
|
+
const value = buildOutKfValue(prevV, nextV, s.p, s.pos, s.rotateDeg, autoOrient);
|
|
1955
|
+
out.push(makeOutKf(tGlobal, value));
|
|
1956
|
+
remaining = right;
|
|
1957
|
+
prevU = s.u;
|
|
1958
|
+
}
|
|
1959
|
+
}
|
|
1960
|
+
function computeSampleTs(seg, autoOrient, flatnessTol, rotationTol, maxSamples) {
|
|
1961
|
+
const extremes = [];
|
|
1962
|
+
addAxisExtremes(seg.P0[0], seg.P1[0], seg.P2[0], seg.P3[0], extremes);
|
|
1963
|
+
addAxisExtremes(seg.P0[1], seg.P1[1], seg.P2[1], seg.P3[1], extremes);
|
|
1964
|
+
extremes.sort((a, b) => a - b);
|
|
1965
|
+
const critical = [0];
|
|
1966
|
+
for (const t of extremes) {
|
|
1967
|
+
if (t > critical[critical.length - 1] + 1e-6 && t < 1 - 1e-6) {
|
|
1968
|
+
critical.push(t);
|
|
1969
|
+
}
|
|
1970
|
+
}
|
|
1971
|
+
critical.push(1);
|
|
1972
|
+
const out = [];
|
|
1973
|
+
const budget = { remaining: maxSamples - critical.length };
|
|
1974
|
+
for (let i = 0; i < critical.length - 1; i++) {
|
|
1975
|
+
bisect(critical[i], critical[i + 1], out, seg, autoOrient, flatnessTol, rotationTol, budget);
|
|
1976
|
+
}
|
|
1977
|
+
return out;
|
|
1978
|
+
}
|
|
1979
|
+
function addAxisExtremes(p0, p1, p2, p3, out) {
|
|
1980
|
+
const a = p1 - p0;
|
|
1981
|
+
const b = p2 - p1;
|
|
1982
|
+
const c = p3 - p2;
|
|
1983
|
+
const A = a - 2 * b + c;
|
|
1984
|
+
const B = 2 * (b - a);
|
|
1985
|
+
const C = a;
|
|
1986
|
+
if (Math.abs(A) < 1e-10) {
|
|
1987
|
+
if (Math.abs(B) > 1e-10) {
|
|
1988
|
+
const t = -C / B;
|
|
1989
|
+
if (t > 1e-6 && t < 1 - 1e-6) out.push(t);
|
|
1990
|
+
}
|
|
1991
|
+
return;
|
|
1992
|
+
}
|
|
1993
|
+
const disc = B * B - 4 * A * C;
|
|
1994
|
+
if (disc < 0) return;
|
|
1995
|
+
const sq = Math.sqrt(disc);
|
|
1996
|
+
const t1 = (-B - sq) / (2 * A);
|
|
1997
|
+
const t2 = (-B + sq) / (2 * A);
|
|
1998
|
+
if (t1 > 1e-6 && t1 < 1 - 1e-6) out.push(t1);
|
|
1999
|
+
if (t2 > 1e-6 && t2 < 1 - 1e-6) out.push(t2);
|
|
2000
|
+
}
|
|
2001
|
+
function bisect(tA, tB, out, seg, autoOrient, flatnessTol, rotationTol, budget) {
|
|
2002
|
+
const tMid = (tA + tB) / 2;
|
|
2003
|
+
const pA = bezier2D_pointAt(seg.P0, seg.P1, seg.P2, seg.P3, tA);
|
|
2004
|
+
const pB = bezier2D_pointAt(seg.P0, seg.P1, seg.P2, seg.P3, tB);
|
|
2005
|
+
const span = tB - tA;
|
|
2006
|
+
const p25 = bezier2D_pointAt(seg.P0, seg.P1, seg.P2, seg.P3, tA + span * 0.25);
|
|
2007
|
+
const p50 = bezier2D_pointAt(seg.P0, seg.P1, seg.P2, seg.P3, tMid);
|
|
2008
|
+
const p75 = bezier2D_pointAt(seg.P0, seg.P1, seg.P2, seg.P3, tA + span * 0.75);
|
|
2009
|
+
const dev = Math.max(
|
|
2010
|
+
perpDist(p25, pA, pB),
|
|
2011
|
+
perpDist(p50, pA, pB),
|
|
2012
|
+
perpDist(p75, pA, pB)
|
|
2013
|
+
);
|
|
2014
|
+
let rotOk = true;
|
|
2015
|
+
if (autoOrient) {
|
|
2016
|
+
const tanA = bezier2D_derivativeAt(seg.P0, seg.P1, seg.P2, seg.P3, tA);
|
|
2017
|
+
const tanB = bezier2D_derivativeAt(seg.P0, seg.P1, seg.P2, seg.P3, tB);
|
|
2018
|
+
const angA = Math.atan2(tanA[1], tanA[0]) * 180 / Math.PI;
|
|
2019
|
+
const angB = Math.atan2(tanB[1], tanB[0]) * 180 / Math.PI;
|
|
2020
|
+
let delta = Math.abs(angA - angB);
|
|
2021
|
+
if (delta > 180) delta = 360 - delta;
|
|
2022
|
+
if (delta > rotationTol) rotOk = false;
|
|
2023
|
+
}
|
|
2024
|
+
if (dev <= flatnessTol && rotOk || budget.remaining <= 0 || span < 1e-6) {
|
|
2025
|
+
out.push(tB);
|
|
2026
|
+
return;
|
|
2027
|
+
}
|
|
2028
|
+
budget.remaining -= 1;
|
|
2029
|
+
bisect(tA, tMid, out, seg, autoOrient, flatnessTol, rotationTol, budget);
|
|
2030
|
+
bisect(tMid, tB, out, seg, autoOrient, flatnessTol, rotationTol, budget);
|
|
2031
|
+
}
|
|
2032
|
+
function perpDist(q, pA, pB) {
|
|
2033
|
+
const dx = pB[0] - pA[0];
|
|
2034
|
+
const dy = pB[1] - pA[1];
|
|
2035
|
+
const len2 = dx * dx + dy * dy;
|
|
2036
|
+
if (len2 < 1e-20) {
|
|
2037
|
+
const qdx = q[0] - pA[0];
|
|
2038
|
+
const qdy = q[1] - pA[1];
|
|
2039
|
+
return Math.sqrt(qdx * qdx + qdy * qdy);
|
|
2040
|
+
}
|
|
2041
|
+
const cross = (q[0] - pA[0]) * dy - (q[1] - pA[1]) * dx;
|
|
2042
|
+
return Math.abs(cross) / Math.sqrt(len2);
|
|
2043
|
+
}
|
|
2044
|
+
|
|
2045
|
+
// src/animation/PxDefinitions.ts
|
|
2046
|
+
var PX_LOOP_JUMP_SHIFT_MS = 1;
|
|
2047
|
+
function interpolateValue(propName, a, b, t) {
|
|
2048
|
+
var _a2, _b;
|
|
2049
|
+
if (propName === "d") {
|
|
2050
|
+
const aPaths = (_a2 = a == null ? void 0 : a.paths) != null ? _a2 : Array.isArray(a) ? a : [];
|
|
2051
|
+
const bPaths = (_b = b == null ? void 0 : b.paths) != null ? _b : Array.isArray(b) ? b : [];
|
|
2052
|
+
return { paths: interpolateBeziers(aPaths, bPaths, t) };
|
|
2053
|
+
}
|
|
2054
|
+
if (PX_COLOR_ATTR_NAMES.has(propName)) {
|
|
2055
|
+
return interpolateColor(a || [0, 0, 0, 1], b || [0, 0, 0, 1], t);
|
|
2056
|
+
}
|
|
2057
|
+
if (propName === "transform" && typeof a === "object" && a !== null && !Array.isArray(a) && typeof b === "object" && b !== null && !Array.isArray(b)) {
|
|
2058
|
+
return interpolateTransformParts(a, b, t);
|
|
2059
|
+
}
|
|
2060
|
+
if (propName === "rotate" && typeof a === "number" && typeof b === "number") {
|
|
2061
|
+
return interpolateNum(a, b, t);
|
|
2062
|
+
}
|
|
2063
|
+
if (PX_TRANSFORM_FN_NAMES.has(propName) || propName === "stroke-dasharray" || propName === "strokeDasharray") {
|
|
2064
|
+
return interpolateVec(a || [], b || [], t);
|
|
2065
|
+
}
|
|
2066
|
+
return interpolateNum(+(a || 0), +(b || 0), t);
|
|
2067
|
+
}
|
|
2068
|
+
function interpolateTransformParts(a, b, t) {
|
|
2069
|
+
const keys = /* @__PURE__ */ new Set([...Object.keys(a != null ? a : {}), ...Object.keys(b != null ? b : {})]);
|
|
2070
|
+
const out = {};
|
|
2071
|
+
for (const k of keys) {
|
|
2072
|
+
const av = a == null ? void 0 : a[k];
|
|
2073
|
+
const bv = b == null ? void 0 : b[k];
|
|
2074
|
+
if (k === "rotate" || k === "skew") {
|
|
2075
|
+
out[k] = interpolateNum(+(av != null ? av : 0), +(bv != null ? bv : 0), t);
|
|
2076
|
+
} else if (k === "translate" || k === "scale" || k === "origin") {
|
|
2077
|
+
const fallback = k === "scale" ? [1, 1] : [0, 0];
|
|
2078
|
+
out[k] = interpolateVec(av || fallback, bv || fallback, t);
|
|
2079
|
+
} else {
|
|
2080
|
+
out[k] = bv != null ? bv : av;
|
|
2081
|
+
}
|
|
2082
|
+
}
|
|
2083
|
+
return out;
|
|
2084
|
+
}
|
|
2085
|
+
function mergeStaticTransformIntoAnimDef(animDef, staticTransform) {
|
|
2086
|
+
if (!animDef) return animDef;
|
|
2087
|
+
const staticParts = staticTransform && typeof staticTransform === "object" && !Array.isArray(staticTransform) ? staticTransform : parseTransformParts(staticTransform);
|
|
2088
|
+
if (!staticParts || !Object.keys(staticParts).length) return animDef;
|
|
2089
|
+
const mergeKfValue = (v) => v && typeof v === "object" && !Array.isArray(v) ? __spreadValues(__spreadValues({}, staticParts), v) : v;
|
|
2090
|
+
const transformAnim = animDef[TRANSFORM_ATTR];
|
|
2091
|
+
if (transformAnim && typeof transformAnim === "object") {
|
|
2092
|
+
const anim = transformAnim;
|
|
2093
|
+
if (Array.isArray(anim.keyframes)) {
|
|
2094
|
+
const out = __spreadProps(__spreadValues({}, anim), {
|
|
2095
|
+
keyframes: anim.keyframes.map((kf) => __spreadProps(__spreadValues({}, kf), { value: mergeKfValue(kf.value) }))
|
|
2096
|
+
});
|
|
2097
|
+
if (out.value !== void 0) out.value = mergeKfValue(out.value);
|
|
2098
|
+
return __spreadProps(__spreadValues({}, animDef), { transform: out });
|
|
2099
|
+
}
|
|
2100
|
+
return animDef;
|
|
2101
|
+
}
|
|
2102
|
+
const channels = Object.keys(animDef).filter((k) => PX_TRANSFORM_FN_NAMES.has(k));
|
|
2103
|
+
if (channels.length !== 1) return animDef;
|
|
2104
|
+
const ch = channels[0];
|
|
2105
|
+
const chAnim = animDef[ch];
|
|
2106
|
+
if (!chAnim || typeof chAnim !== "object" || !Array.isArray(chAnim.keyframes)) return animDef;
|
|
2107
|
+
const lifted = __spreadProps(__spreadValues({}, chAnim), {
|
|
2108
|
+
keyframes: chAnim.keyframes.map((kf) => __spreadProps(__spreadValues({}, kf), { value: __spreadProps(__spreadValues({}, staticParts), { [ch]: kf.value }) }))
|
|
2109
|
+
});
|
|
2110
|
+
if (lifted.value !== void 0) lifted.value = __spreadProps(__spreadValues({}, staticParts), { [ch]: lifted.value });
|
|
2111
|
+
const rest = __spreadValues({}, animDef);
|
|
2112
|
+
delete rest[ch];
|
|
2113
|
+
return __spreadProps(__spreadValues({}, rest), { transform: lifted });
|
|
2114
|
+
}
|
|
2115
|
+
|
|
2116
|
+
// src/effects/PlayerEffectsUtil.visualModel.ts
|
|
2117
|
+
var IDENTITY = [1, 0, 0, 1, 0, 0];
|
|
2118
|
+
function mul(m, n) {
|
|
2119
|
+
return [
|
|
2120
|
+
m[0] * n[0] + m[2] * n[1],
|
|
2121
|
+
m[1] * n[0] + m[3] * n[1],
|
|
2122
|
+
m[0] * n[2] + m[2] * n[3],
|
|
2123
|
+
m[1] * n[2] + m[3] * n[3],
|
|
2124
|
+
m[0] * n[4] + m[2] * n[5] + m[4],
|
|
2125
|
+
m[1] * n[4] + m[3] * n[5] + m[5]
|
|
2126
|
+
];
|
|
2127
|
+
}
|
|
2128
|
+
var translateM = (x, y) => [1, 0, 0, 1, x, y];
|
|
2129
|
+
var scaleM = (sx, sy) => [sx, 0, 0, sy, 0, 0];
|
|
2130
|
+
function rotateM(deg) {
|
|
2131
|
+
const r = deg * Math.PI / 180;
|
|
2132
|
+
return [Math.cos(r), Math.sin(r), -Math.sin(r), Math.cos(r), 0, 0];
|
|
2133
|
+
}
|
|
2134
|
+
var skewXM = (deg) => [1, 0, Math.tan(deg * Math.PI / 180), 1, 0, 0];
|
|
2135
|
+
var skewYM = (deg) => [1, Math.tan(deg * Math.PI / 180), 0, 1, 0, 0];
|
|
2136
|
+
function parseTransformString(s) {
|
|
2137
|
+
let m = IDENTITY;
|
|
2138
|
+
const re = /(translate|rotate|scale|matrix|skewX|skewY)\(([^)]*)\)/g;
|
|
2139
|
+
let hit;
|
|
2140
|
+
while (hit = re.exec(s)) {
|
|
2141
|
+
const fn = hit[1];
|
|
2142
|
+
const a = hit[2].split(/[\s,]+/).filter(Boolean).map(Number);
|
|
2143
|
+
if (fn === "translate") m = mul(m, translateM(a[0] || 0, a[1] || 0));
|
|
2144
|
+
else if (fn === "scale") m = mul(m, scaleM(a[0], a.length > 1 ? a[1] : a[0]));
|
|
2145
|
+
else if (fn === "rotate") m = mul(m, rotateM(a[0]));
|
|
2146
|
+
else if (fn === "skewX") m = mul(m, skewXM(a[0]));
|
|
2147
|
+
else if (fn === "skewY") m = mul(m, skewYM(a[0]));
|
|
2148
|
+
else if (fn === "matrix") m = mul(m, [a[0], a[1], a[2], a[3], a[4], a[5]]);
|
|
2149
|
+
}
|
|
2150
|
+
return m;
|
|
2151
|
+
}
|
|
2152
|
+
function partsToMatrix(p) {
|
|
2153
|
+
let m = IDENTITY;
|
|
2154
|
+
if (p.translate) m = mul(m, translateM(p.translate[0], p.translate[1]));
|
|
2155
|
+
const pivot = p.origin && (p.rotate !== void 0 || p.scale);
|
|
2156
|
+
if (pivot) m = mul(m, translateM(p.origin[0], p.origin[1]));
|
|
2157
|
+
if (p.rotate !== void 0) m = mul(m, rotateM(p.rotate));
|
|
2158
|
+
if (p.scale) m = mul(m, scaleM(p.scale[0], p.scale[1]));
|
|
2159
|
+
if (pivot) m = mul(m, translateM(-p.origin[0], -p.origin[1]));
|
|
2160
|
+
return m;
|
|
2161
|
+
}
|
|
2162
|
+
function lerp(a, b, f) {
|
|
2163
|
+
return a + (b - a) * f;
|
|
2164
|
+
}
|
|
2165
|
+
function interpParts(kfs, t) {
|
|
2166
|
+
var _a2, _b, _c, _d, _e, _f, _g;
|
|
2167
|
+
if (!kfs.length) return {};
|
|
2168
|
+
if (t <= ((_a2 = kfs[0].time) != null ? _a2 : 0)) return kfs[0].value || {};
|
|
2169
|
+
if (t >= ((_b = kfs[kfs.length - 1].time) != null ? _b : 0)) return kfs[kfs.length - 1].value || {};
|
|
2170
|
+
let i = 0;
|
|
2171
|
+
while (i < kfs.length - 1 && ((_c = kfs[i + 1].time) != null ? _c : 0) < t) i++;
|
|
2172
|
+
const a = kfs[i], b = kfs[i + 1];
|
|
2173
|
+
const f = (t - ((_d = a.time) != null ? _d : 0)) / (((_e = b.time) != null ? _e : 0) - ((_f = a.time) != null ? _f : 0) || 1);
|
|
2174
|
+
const va = a.value || {}, vb = b.value || {};
|
|
2175
|
+
const out = {};
|
|
2176
|
+
if (va.translate && vb.translate) out.translate = [lerp(va.translate[0], vb.translate[0], f), lerp(va.translate[1], vb.translate[1], f)];
|
|
2177
|
+
else out.translate = va.translate || vb.translate;
|
|
2178
|
+
if (va.rotate !== void 0 && vb.rotate !== void 0) out.rotate = lerp(va.rotate, vb.rotate, f);
|
|
2179
|
+
else out.rotate = (_g = va.rotate) != null ? _g : vb.rotate;
|
|
2180
|
+
if (va.scale && vb.scale) out.scale = [lerp(va.scale[0], vb.scale[0], f), lerp(va.scale[1], vb.scale[1], f)];
|
|
2181
|
+
else out.scale = va.scale || vb.scale;
|
|
2182
|
+
out.origin = va.origin || vb.origin;
|
|
2183
|
+
return out;
|
|
2184
|
+
}
|
|
2185
|
+
function evalTransformValue(v, t) {
|
|
2186
|
+
if (v === void 0 || v === null) return IDENTITY;
|
|
2187
|
+
if (typeof v === "string") return parseTransformString(v);
|
|
2188
|
+
if (v.keyframes) return partsToMatrix(interpParts(v.keyframes, t));
|
|
2189
|
+
if (v.value) return partsToMatrix(v.value);
|
|
2190
|
+
if (typeof v === "object" && !Array.isArray(v)) return partsToMatrix(v);
|
|
2191
|
+
return IDENTITY;
|
|
2192
|
+
}
|
|
2193
|
+
function nodeMatrix(node, t) {
|
|
2194
|
+
if (node.animate && node.animate.transform) return evalTransformValue(node.animate.transform, t);
|
|
2195
|
+
if (node.transform !== void 0) return evalTransformValue(node.transform, t);
|
|
2196
|
+
return IDENTITY;
|
|
2197
|
+
}
|
|
2198
|
+
function evalScalar(animated, staticVal, fallback, t) {
|
|
2199
|
+
var _a2, _b, _c, _d, _e, _f;
|
|
2200
|
+
if (animated && animated.keyframes && animated.keyframes.length) {
|
|
2201
|
+
const kfs = animated.keyframes;
|
|
2202
|
+
if (t <= ((_a2 = kfs[0].time) != null ? _a2 : 0)) return kfs[0].value;
|
|
2203
|
+
if (t >= ((_b = kfs[kfs.length - 1].time) != null ? _b : 0)) return kfs[kfs.length - 1].value;
|
|
2204
|
+
let i = 0;
|
|
2205
|
+
while (i < kfs.length - 1 && ((_c = kfs[i + 1].time) != null ? _c : 0) < t) i++;
|
|
2206
|
+
const a = kfs[i], b = kfs[i + 1];
|
|
2207
|
+
const f = (t - ((_d = a.time) != null ? _d : 0)) / (((_e = b.time) != null ? _e : 0) - ((_f = a.time) != null ? _f : 0) || 1);
|
|
2208
|
+
return lerp(a.value, b.value, f);
|
|
2209
|
+
}
|
|
2210
|
+
return staticVal !== void 0 ? Number(staticVal) : fallback;
|
|
2211
|
+
}
|
|
2212
|
+
var CONTAINER_TYPES = /* @__PURE__ */ new Set(["svg", "g", "symbol"]);
|
|
2213
|
+
var SKIP_TYPES = /* @__PURE__ */ new Set(["defs", "mask", "clipPath", "title"]);
|
|
2214
|
+
function buildIdMap(node, map) {
|
|
2215
|
+
var _a2;
|
|
2216
|
+
if (typeof node.id === "string") map.set(node.id, node);
|
|
2217
|
+
(_a2 = node.children) == null ? void 0 : _a2.forEach((c) => buildIdMap(c, map));
|
|
2218
|
+
}
|
|
2219
|
+
function num(v) {
|
|
2220
|
+
return v === void 0 || v === null ? 0 : Number(v);
|
|
2221
|
+
}
|
|
2222
|
+
function round(n) {
|
|
2223
|
+
return Math.round(n * 100) / 100 + 0;
|
|
2224
|
+
}
|
|
2225
|
+
function geomKey(node) {
|
|
2226
|
+
var _a2;
|
|
2227
|
+
switch (node.type) {
|
|
2228
|
+
case "rect":
|
|
2229
|
+
return num(node.width) + "," + num(node.height) + "," + num(node.x) + "," + num(node.y);
|
|
2230
|
+
case "ellipse":
|
|
2231
|
+
return num(node.rx) + "," + num(node.ry) + "," + num(node.cx) + "," + num(node.cy);
|
|
2232
|
+
case "circle":
|
|
2233
|
+
return num(node.r) + "," + num(node.cx) + "," + num(node.cy);
|
|
2234
|
+
case "path":
|
|
2235
|
+
return String((_a2 = node.d) != null ? _a2 : "");
|
|
2236
|
+
default:
|
|
2237
|
+
return "";
|
|
2238
|
+
}
|
|
2239
|
+
}
|
|
2240
|
+
function describePrimitive(node, m, t) {
|
|
2241
|
+
var _a2, _b, _c, _d, _e;
|
|
2242
|
+
const fill = (_a2 = node.fill) != null ? _a2 : "";
|
|
2243
|
+
const stroke = (_b = node.stroke) != null ? _b : "";
|
|
2244
|
+
const sw = (_d = (_c = node["stroke-width"]) != null ? _c : node.strokeWidth) != null ? _d : "";
|
|
2245
|
+
const opacity = round(evalScalar((_e = node.animate) == null ? void 0 : _e.opacity, node.opacity, 1, t));
|
|
2246
|
+
const masked = node.mask ? 1 : 0;
|
|
2247
|
+
const mat = m.map(round).join(",");
|
|
2248
|
+
return node.type + "|" + geomKey(node) + "|[" + mat + "]|f:" + fill + "|s:" + stroke + "|sw:" + (num(sw) || "") + "|o:" + opacity + "|m:" + masked;
|
|
2249
|
+
}
|
|
2250
|
+
function flatten(node, parent, t, idMap, out) {
|
|
2251
|
+
var _a2;
|
|
2252
|
+
const type = node.type || "";
|
|
2253
|
+
if (SKIP_TYPES.has(type)) return;
|
|
2254
|
+
const m = mul(parent, nodeMatrix(node, t));
|
|
2255
|
+
if (type === "use") {
|
|
2256
|
+
const targetId = typeof node.href === "string" ? node.href.replace(/^#/, "") : "";
|
|
2257
|
+
const target = idMap.get(targetId);
|
|
2258
|
+
const useM = mul(m, translateM(num(node.x), num(node.y)));
|
|
2259
|
+
if (target) flatten(target, useM, t, idMap, out);
|
|
2260
|
+
else out.push("UNRESOLVED_USE:#" + targetId);
|
|
2261
|
+
return;
|
|
2262
|
+
}
|
|
2263
|
+
if (CONTAINER_TYPES.has(type)) {
|
|
2264
|
+
(_a2 = node.children) == null ? void 0 : _a2.forEach((c) => flatten(c, m, t, idMap, out));
|
|
2265
|
+
return;
|
|
2266
|
+
}
|
|
2267
|
+
out.push(describePrimitive(node, m, t));
|
|
2268
|
+
}
|
|
2269
|
+
function collectSampleTimes(node, into) {
|
|
2270
|
+
var _a2;
|
|
2271
|
+
into.add(0);
|
|
2272
|
+
const scanAnim = (anim) => {
|
|
2273
|
+
var _a3;
|
|
2274
|
+
if (!anim || typeof anim !== "object") return;
|
|
2275
|
+
for (const key of Object.keys(anim)) {
|
|
2276
|
+
const kfs = (_a3 = anim[key]) == null ? void 0 : _a3.keyframes;
|
|
2277
|
+
if (Array.isArray(kfs)) kfs.forEach((kf) => {
|
|
2278
|
+
var _a4;
|
|
2279
|
+
return into.add((_a4 = kf.time) != null ? _a4 : 0);
|
|
2280
|
+
});
|
|
2281
|
+
}
|
|
2282
|
+
};
|
|
2283
|
+
scanAnim(node.animate);
|
|
2284
|
+
if (node.transform && typeof node.transform === "object" && node.transform.keyframes) {
|
|
2285
|
+
node.transform.keyframes.forEach((kf) => {
|
|
2286
|
+
var _a3;
|
|
2287
|
+
return into.add((_a3 = kf.time) != null ? _a3 : 0);
|
|
2288
|
+
});
|
|
2289
|
+
}
|
|
2290
|
+
(_a2 = node.children) == null ? void 0 : _a2.forEach((c) => collectSampleTimes(c, into));
|
|
2291
|
+
}
|
|
2292
|
+
function visualModelAt(root, t) {
|
|
2293
|
+
const idMap = /* @__PURE__ */ new Map();
|
|
2294
|
+
buildIdMap(root, idMap);
|
|
2295
|
+
const out = [];
|
|
2296
|
+
flatten(root, IDENTITY, t, idMap, out);
|
|
2297
|
+
return out.sort();
|
|
2298
|
+
}
|
|
2299
|
+
function diffInEffect(a, b) {
|
|
2300
|
+
const times = /* @__PURE__ */ new Set();
|
|
2301
|
+
collectSampleTimes(a, times);
|
|
2302
|
+
collectSampleTimes(b, times);
|
|
2303
|
+
const diffs = [];
|
|
2304
|
+
for (const t of Array.from(times).sort((x, y) => x - y)) {
|
|
2305
|
+
const ma = visualModelAt(a, t);
|
|
2306
|
+
const mb = visualModelAt(b, t);
|
|
2307
|
+
const onlyInA = subtractMultiset(ma, mb);
|
|
2308
|
+
const onlyInB = subtractMultiset(mb, ma);
|
|
2309
|
+
if (onlyInA.length || onlyInB.length) diffs.push({ time: t, onlyInA, onlyInB });
|
|
2310
|
+
}
|
|
2311
|
+
return diffs;
|
|
2312
|
+
}
|
|
2313
|
+
function subtractMultiset(a, b) {
|
|
2314
|
+
const counts = /* @__PURE__ */ new Map();
|
|
2315
|
+
for (const x of b) counts.set(x, (counts.get(x) || 0) + 1);
|
|
2316
|
+
const extra = [];
|
|
2317
|
+
for (const x of a) {
|
|
2318
|
+
const c = counts.get(x) || 0;
|
|
2319
|
+
if (c > 0) counts.set(x, c - 1);
|
|
2320
|
+
else extra.push(x);
|
|
2321
|
+
}
|
|
2322
|
+
return extra;
|
|
2323
|
+
}
|
|
2324
|
+
|
|
2325
|
+
// src/effects/text/pathSampler.ts
|
|
2326
|
+
var LUT_STEPS = 48;
|
|
2327
|
+
var CMD_RE = /[MmLlHhVvCcSsQqTtAaZz]/;
|
|
2328
|
+
function tokenize(d) {
|
|
2329
|
+
const tokens = [];
|
|
2330
|
+
const re = /([MmLlHhVvCcSsQqTtAaZz])|(-?\d*\.?\d+(?:[eE][-+]?\d+)?)/g;
|
|
2331
|
+
let m;
|
|
2332
|
+
while ((m = re.exec(d)) !== null) tokens.push(m[0]);
|
|
2333
|
+
return tokens;
|
|
2334
|
+
}
|
|
2335
|
+
function quadToCubic(P0, Qc, P3) {
|
|
2336
|
+
return {
|
|
2337
|
+
P1: [P0[0] + 2 / 3 * (Qc[0] - P0[0]), P0[1] + 2 / 3 * (Qc[1] - P0[1])],
|
|
2338
|
+
P2: [P3[0] + 2 / 3 * (Qc[0] - P3[0]), P3[1] + 2 / 3 * (Qc[1] - P3[1])]
|
|
2339
|
+
};
|
|
2340
|
+
}
|
|
2341
|
+
function parseCubics(d) {
|
|
2342
|
+
const tokens = tokenize(d);
|
|
2343
|
+
const segs = [];
|
|
2344
|
+
let i = 0;
|
|
2345
|
+
let cx = 0, cy = 0;
|
|
2346
|
+
let sx = 0, sy = 0;
|
|
2347
|
+
let pcx = 0, pcy = 0;
|
|
2348
|
+
let pqx = 0, pqy = 0;
|
|
2349
|
+
let prevCmd = "";
|
|
2350
|
+
const num2 = () => parseFloat(tokens[i++]);
|
|
2351
|
+
const push = (P1, P2, P3) => {
|
|
2352
|
+
const P0 = [cx, cy];
|
|
2353
|
+
const lut = bezier2D_arcLengthLUT(P0, P1, P2, P3, LUT_STEPS);
|
|
2354
|
+
segs.push({ P0, P1, P2, P3, lut, len: lut.ds[lut.ds.length - 1] });
|
|
2355
|
+
cx = P3[0];
|
|
2356
|
+
cy = P3[1];
|
|
2357
|
+
};
|
|
2358
|
+
const pushLine = (x, y) => {
|
|
2359
|
+
push(
|
|
2360
|
+
[cx + (x - cx) / 3, cy + (y - cy) / 3],
|
|
2361
|
+
[cx + 2 * (x - cx) / 3, cy + 2 * (y - cy) / 3],
|
|
2362
|
+
[x, y]
|
|
2363
|
+
);
|
|
2364
|
+
};
|
|
2365
|
+
while (i < tokens.length) {
|
|
2366
|
+
let cmd = tokens[i];
|
|
2367
|
+
if (CMD_RE.test(cmd)) i++;
|
|
2368
|
+
else cmd = prevCmd === "M" ? "L" : prevCmd === "m" ? "l" : prevCmd;
|
|
2369
|
+
const rel = cmd >= "a";
|
|
2370
|
+
const U = cmd.toUpperCase();
|
|
2371
|
+
if (U === "Z") {
|
|
2372
|
+
pushLine(sx, sy);
|
|
2373
|
+
cx = sx;
|
|
2374
|
+
cy = sy;
|
|
2375
|
+
prevCmd = cmd;
|
|
2376
|
+
continue;
|
|
2377
|
+
}
|
|
2378
|
+
if (U === "M") {
|
|
2379
|
+
const x = num2() + (rel ? cx : 0), y = num2() + (rel ? cy : 0);
|
|
2380
|
+
cx = x;
|
|
2381
|
+
cy = y;
|
|
2382
|
+
sx = x;
|
|
2383
|
+
sy = y;
|
|
2384
|
+
prevCmd = cmd;
|
|
2385
|
+
continue;
|
|
2386
|
+
}
|
|
2387
|
+
if (U === "L") {
|
|
2388
|
+
pushLine(num2() + (rel ? cx : 0), num2() + (rel ? cy : 0));
|
|
2389
|
+
} else if (U === "H") {
|
|
2390
|
+
pushLine(num2() + (rel ? cx : 0), cy);
|
|
2391
|
+
} else if (U === "V") {
|
|
2392
|
+
pushLine(cx, num2() + (rel ? cy : 0));
|
|
2393
|
+
} else if (U === "C") {
|
|
2394
|
+
const p1 = [num2() + (rel ? cx : 0), num2() + (rel ? cy : 0)];
|
|
2395
|
+
const p2 = [num2() + (rel ? cx : 0), num2() + (rel ? cy : 0)];
|
|
2396
|
+
const p3 = [num2() + (rel ? cx : 0), num2() + (rel ? cy : 0)];
|
|
2397
|
+
pcx = p2[0];
|
|
2398
|
+
pcy = p2[1];
|
|
2399
|
+
push(p1, p2, p3);
|
|
2400
|
+
} else if (U === "S") {
|
|
2401
|
+
const smooth = prevCmd.toUpperCase() === "C" || prevCmd.toUpperCase() === "S";
|
|
2402
|
+
const p1 = smooth ? [2 * cx - pcx, 2 * cy - pcy] : [cx, cy];
|
|
2403
|
+
const p2 = [num2() + (rel ? cx : 0), num2() + (rel ? cy : 0)];
|
|
2404
|
+
const p3 = [num2() + (rel ? cx : 0), num2() + (rel ? cy : 0)];
|
|
2405
|
+
pcx = p2[0];
|
|
2406
|
+
pcy = p2[1];
|
|
2407
|
+
push(p1, p2, p3);
|
|
2408
|
+
} else if (U === "Q") {
|
|
2409
|
+
const qc = [num2() + (rel ? cx : 0), num2() + (rel ? cy : 0)];
|
|
2410
|
+
const p3 = [num2() + (rel ? cx : 0), num2() + (rel ? cy : 0)];
|
|
2411
|
+
pqx = qc[0];
|
|
2412
|
+
pqy = qc[1];
|
|
2413
|
+
const { P1, P2 } = quadToCubic([cx, cy], qc, p3);
|
|
2414
|
+
push(P1, P2, p3);
|
|
2415
|
+
} else if (U === "T") {
|
|
2416
|
+
const smooth = prevCmd.toUpperCase() === "Q" || prevCmd.toUpperCase() === "T";
|
|
2417
|
+
const qc = smooth ? [2 * cx - pqx, 2 * cy - pqy] : [cx, cy];
|
|
2418
|
+
const p3 = [num2() + (rel ? cx : 0), num2() + (rel ? cy : 0)];
|
|
2419
|
+
pqx = qc[0];
|
|
2420
|
+
pqy = qc[1];
|
|
2421
|
+
const { P1, P2 } = quadToCubic([cx, cy], qc, p3);
|
|
2422
|
+
push(P1, P2, p3);
|
|
2423
|
+
} else if (U === "A") {
|
|
2424
|
+
i += 5;
|
|
2425
|
+
pushLine(num2() + (rel ? cx : 0), num2() + (rel ? cy : 0));
|
|
2426
|
+
} else {
|
|
2427
|
+
i++;
|
|
2428
|
+
continue;
|
|
2429
|
+
}
|
|
2430
|
+
prevCmd = cmd;
|
|
2431
|
+
}
|
|
2432
|
+
return segs.length ? segs : null;
|
|
2433
|
+
}
|
|
2434
|
+
function clamp2(v, lo, hi) {
|
|
2435
|
+
return v < lo ? lo : v > hi ? hi : v;
|
|
2436
|
+
}
|
|
2437
|
+
function createPathSampler(d) {
|
|
2438
|
+
const segs = parseCubics(d);
|
|
2439
|
+
if (!segs) return null;
|
|
2440
|
+
const cum = new Float64Array(segs.length + 1);
|
|
2441
|
+
for (let k = 0; k < segs.length; k++) cum[k + 1] = cum[k] + segs[k].len;
|
|
2442
|
+
const totalLength = cum[segs.length];
|
|
2443
|
+
const start = segs[0].P0, end = segs[segs.length - 1].P3;
|
|
2444
|
+
const closed = Math.hypot(end[0] - start[0], end[1] - start[1]) < 1e-3;
|
|
2445
|
+
const sampleOn = (dist) => {
|
|
2446
|
+
let k = 0;
|
|
2447
|
+
while (k < segs.length - 1 && dist > cum[k + 1]) k++;
|
|
2448
|
+
const seg = segs[k];
|
|
2449
|
+
const local = dist - cum[k];
|
|
2450
|
+
const t = seg.len > 0 ? bezier2D_tForDistance(seg.lut, local) : 0;
|
|
2451
|
+
const [x, y] = bezier2D_pointAt(seg.P0, seg.P1, seg.P2, seg.P3, t);
|
|
2452
|
+
const [dx, dy] = bezier2D_derivativeAt(seg.P0, seg.P1, seg.P2, seg.P3, t);
|
|
2453
|
+
return { x, y, angle: Math.atan2(dy, dx) };
|
|
2454
|
+
};
|
|
2455
|
+
return {
|
|
2456
|
+
totalLength,
|
|
2457
|
+
closed,
|
|
2458
|
+
sampleAtDistance(dist) {
|
|
2459
|
+
if (closed && totalLength > 0 && (dist < 0 || dist > totalLength)) {
|
|
2460
|
+
return sampleOn((dist % totalLength + totalLength) % totalLength);
|
|
2461
|
+
}
|
|
2462
|
+
if (!closed && (dist < 0 || dist > totalLength)) {
|
|
2463
|
+
const edge = dist < 0 ? 0 : totalLength;
|
|
2464
|
+
const p = sampleOn(edge);
|
|
2465
|
+
const over = dist - edge;
|
|
2466
|
+
return { x: p.x + Math.cos(p.angle) * over, y: p.y + Math.sin(p.angle) * over, angle: p.angle };
|
|
2467
|
+
}
|
|
2468
|
+
return sampleOn(clamp2(dist, 0, totalLength));
|
|
2469
|
+
}
|
|
2470
|
+
};
|
|
2471
|
+
}
|
|
2472
|
+
|
|
2473
|
+
// src/effects/text/elementFactory.ts
|
|
2474
|
+
var jsonElementFactory = (type, props, children) => {
|
|
2475
|
+
const node = { type };
|
|
2476
|
+
for (const k in props) if (props[k] !== void 0) node[k] = props[k];
|
|
2477
|
+
const arr = Array.isArray(children) ? children.filter((c) => c != null) : children != null ? [children] : [];
|
|
2478
|
+
if (arr.length) node.children = arr;
|
|
2479
|
+
return node;
|
|
2480
|
+
};
|
|
2481
|
+
|
|
2482
|
+
// src/effects/text/glyphPathBake.ts
|
|
2483
|
+
function fmt(v, decimals) {
|
|
2484
|
+
return Math.round(v) === v ? "" + Math.round(v) : v.toFixed(decimals);
|
|
2485
|
+
}
|
|
2486
|
+
function pack(nums, decimals) {
|
|
2487
|
+
let s = "";
|
|
2488
|
+
for (let i = 0; i < nums.length; i++) {
|
|
2489
|
+
const str2 = fmt(nums[i], decimals);
|
|
2490
|
+
if (i > 0 && str2.charCodeAt(0) !== 45) s += " ";
|
|
2491
|
+
s += str2;
|
|
2492
|
+
}
|
|
2493
|
+
return s;
|
|
2494
|
+
}
|
|
2495
|
+
function apply(m, x, y) {
|
|
2496
|
+
return [m[0] * x + m[2] * y + m[4], m[1] * x + m[3] * y + m[5]];
|
|
2497
|
+
}
|
|
2498
|
+
var TOKEN_RE = /([MLCQZ])|(-?\d*\.?\d+(?:e[-+]?\d+)?)/gi;
|
|
2499
|
+
function transformPathData(d, m, decimals = 2) {
|
|
2500
|
+
const tokens = [];
|
|
2501
|
+
let match;
|
|
2502
|
+
TOKEN_RE.lastIndex = 0;
|
|
2503
|
+
while ((match = TOKEN_RE.exec(d)) !== null) tokens.push(match[0]);
|
|
2504
|
+
let out = "";
|
|
2505
|
+
let i = 0;
|
|
2506
|
+
const num2 = () => parseFloat(tokens[i++]);
|
|
2507
|
+
while (i < tokens.length) {
|
|
2508
|
+
const cmd = tokens[i++];
|
|
2509
|
+
if (cmd === "M" || cmd === "L") {
|
|
2510
|
+
const [x, y] = apply(m, num2(), num2());
|
|
2511
|
+
out += cmd + pack([x, y], decimals);
|
|
2512
|
+
} else if (cmd === "C") {
|
|
2513
|
+
const [x1, y1] = apply(m, num2(), num2());
|
|
2514
|
+
const [x2, y2] = apply(m, num2(), num2());
|
|
2515
|
+
const [x, y] = apply(m, num2(), num2());
|
|
2516
|
+
out += "C" + pack([x1, y1, x2, y2, x, y], decimals);
|
|
2517
|
+
} else if (cmd === "Q") {
|
|
2518
|
+
const [x1, y1] = apply(m, num2(), num2());
|
|
2519
|
+
const [x, y] = apply(m, num2(), num2());
|
|
2520
|
+
out += "Q" + pack([x1, y1, x, y], decimals);
|
|
2521
|
+
} else if (cmd === "Z" || cmd === "z") {
|
|
2522
|
+
out += "Z";
|
|
2523
|
+
}
|
|
2524
|
+
}
|
|
2525
|
+
return out;
|
|
2526
|
+
}
|
|
2527
|
+
|
|
2528
|
+
// src/effects/shared/transformParts.ts
|
|
2529
|
+
function readAnimatable(raw) {
|
|
2530
|
+
var _a2, _b;
|
|
2531
|
+
if (raw === void 0) return { kind: "absent" /* Absent */ };
|
|
2532
|
+
if (Array.isArray(raw)) return { kind: "static" /* Static */, value: raw };
|
|
2533
|
+
if (typeof raw === "object") {
|
|
2534
|
+
const obj = raw;
|
|
2535
|
+
const kfs = obj.keyframes;
|
|
2536
|
+
if (kfs) {
|
|
2537
|
+
const out = { kind: "animated" /* Animated */, keyframes: kfs.map(normalizeKeyframe), autoOrient: obj.autoOrient, loop: obj.loop };
|
|
2538
|
+
const base = (_a2 = obj.value) != null ? _a2 : obj.v;
|
|
2539
|
+
if (base !== void 0 && out.kind === "animated" /* Animated */) out.base = base;
|
|
2540
|
+
return out;
|
|
2541
|
+
}
|
|
2542
|
+
const staticValue = (_b = obj.value) != null ? _b : obj.v;
|
|
2543
|
+
if (staticValue !== void 0) return { kind: "static" /* Static */, value: staticValue };
|
|
2544
|
+
}
|
|
2545
|
+
return { kind: "static" /* Static */, value: raw };
|
|
2546
|
+
}
|
|
2547
|
+
function normalizeKeyframe(kf) {
|
|
2548
|
+
if (!kf || typeof kf !== "object") return kf;
|
|
2549
|
+
const k = kf;
|
|
2550
|
+
if (k.t === void 0 && k.v === void 0 && k.e === void 0 && k.to === void 0 && k.ti === void 0) {
|
|
2551
|
+
return kf;
|
|
2552
|
+
}
|
|
2553
|
+
const out = __spreadValues({}, k);
|
|
2554
|
+
if (out.time === void 0 && k.t !== void 0) out.time = k.t;
|
|
2555
|
+
if (out.value === void 0 && k.v !== void 0) out.value = k.v;
|
|
2556
|
+
if (out.easing === void 0 && k.e !== void 0) out.easing = k.e;
|
|
2557
|
+
if (out.tangentOut === void 0 && k.to !== void 0) out.tangentOut = k.to;
|
|
2558
|
+
if (out.tangentIn === void 0 && k.ti !== void 0) out.tangentIn = k.ti;
|
|
2559
|
+
return out;
|
|
2560
|
+
}
|
|
2561
|
+
|
|
2562
|
+
// src/effects/text/textGlyphsEffect.ts
|
|
2563
|
+
var DEFAULT_FONT_SIZE = 16;
|
|
2564
|
+
var TEXT_ATTR_KEYS = [
|
|
2565
|
+
"fontFamily",
|
|
2566
|
+
"fontSize",
|
|
2567
|
+
"fontWeight",
|
|
2568
|
+
"fontStyle",
|
|
2569
|
+
"textAnchor",
|
|
2570
|
+
"letterSpacing",
|
|
2571
|
+
"wordSpacing",
|
|
2572
|
+
"textDecoration",
|
|
2573
|
+
"textTransform",
|
|
2574
|
+
"whiteSpace",
|
|
2575
|
+
"x",
|
|
2576
|
+
"y",
|
|
2577
|
+
"dx",
|
|
2578
|
+
"dy",
|
|
2579
|
+
"lengthAdjust",
|
|
2580
|
+
"fill",
|
|
2581
|
+
"stroke",
|
|
2582
|
+
"strokeWidth",
|
|
2583
|
+
"effects",
|
|
2584
|
+
PX_TEXT_CONTENT_ATTR,
|
|
2585
|
+
"xml:space"
|
|
2586
|
+
];
|
|
2587
|
+
var PAINT_STATIC_KEYS = [
|
|
2588
|
+
"fillOpacity",
|
|
2589
|
+
"fillRule",
|
|
2590
|
+
"strokeOpacity",
|
|
2591
|
+
"strokeDasharray",
|
|
2592
|
+
"strokeDashoffset",
|
|
2593
|
+
"strokeLinecap",
|
|
2594
|
+
"strokeLinejoin",
|
|
2595
|
+
"strokeMiterlimit",
|
|
2596
|
+
"mixBlendMode",
|
|
2597
|
+
"filter"
|
|
2598
|
+
];
|
|
2599
|
+
var PAINT_ANIMATE_KEYS = ["fill", "stroke", "strokeWidth", "opacity", "fillOpacity", "strokeOpacity", "strokeDasharray", "strokeDashoffset"];
|
|
2600
|
+
function parseLen(v) {
|
|
2601
|
+
if (typeof v === "number") return v;
|
|
2602
|
+
if (typeof v === "string") {
|
|
2603
|
+
const n = parseFloat(v);
|
|
2604
|
+
return isNaN(n) ? void 0 : n;
|
|
2605
|
+
}
|
|
2606
|
+
return void 0;
|
|
2607
|
+
}
|
|
2608
|
+
function str(v) {
|
|
2609
|
+
return typeof v === "string" ? v : void 0;
|
|
2610
|
+
}
|
|
2611
|
+
function paintAnimateOf(node) {
|
|
2612
|
+
const bag = node.animate;
|
|
2613
|
+
if (!bag || typeof bag !== "object") return void 0;
|
|
2614
|
+
let out;
|
|
2615
|
+
for (const k of PAINT_ANIMATE_KEYS) {
|
|
2616
|
+
if (bag[k] !== void 0) (out != null ? out : out = {})[k] = bag[k];
|
|
2617
|
+
}
|
|
2618
|
+
return out;
|
|
2619
|
+
}
|
|
2620
|
+
function resolveStyle(node, parent) {
|
|
2621
|
+
var _a2, _b, _c, _d, _e, _f, _g, _h, _i, _j;
|
|
2622
|
+
const isTextRoot = node.type === "text";
|
|
2623
|
+
const nodeStyle = node.style;
|
|
2624
|
+
const own = (key) => {
|
|
2625
|
+
var _a3;
|
|
2626
|
+
return isTextRoot ? void 0 : (_a3 = node[key]) != null ? _a3 : nodeStyle == null ? void 0 : nodeStyle[key];
|
|
2627
|
+
};
|
|
2628
|
+
const res = {
|
|
2629
|
+
fontFamily: (_a2 = str(node.fontFamily)) != null ? _a2 : parent.fontFamily,
|
|
2630
|
+
fontSize: (_b = parseLen(node.fontSize)) != null ? _b : parent.fontSize,
|
|
2631
|
+
fill: (_c = node.fill) != null ? _c : parent.fill,
|
|
2632
|
+
stroke: (_d = node.stroke) != null ? _d : parent.stroke,
|
|
2633
|
+
strokeWidth: (_e = node.strokeWidth) != null ? _e : parent.strokeWidth,
|
|
2634
|
+
letterSpacing: (_f = parseLen(node.letterSpacing)) != null ? _f : parent.letterSpacing,
|
|
2635
|
+
wordSpacing: (_g = parseLen(node.wordSpacing)) != null ? _g : parent.wordSpacing,
|
|
2636
|
+
opacity: (_h = parseLen(own("opacity"))) != null ? _h : parent.opacity,
|
|
2637
|
+
animate: (_i = isTextRoot ? void 0 : paintAnimateOf(node)) != null ? _i : parent.animate
|
|
2638
|
+
};
|
|
2639
|
+
for (const key of PAINT_STATIC_KEYS) {
|
|
2640
|
+
const v = (_j = own(key)) != null ? _j : parent[key];
|
|
2641
|
+
if (v !== void 0) res[key] = v;
|
|
2642
|
+
}
|
|
2643
|
+
return res;
|
|
2644
|
+
}
|
|
2645
|
+
function rootStyleOf(node) {
|
|
2646
|
+
var _a2, _b, _c;
|
|
2647
|
+
return {
|
|
2648
|
+
fontFamily: str(node.fontFamily),
|
|
2649
|
+
fontSize: (_a2 = parseLen(node.fontSize)) != null ? _a2 : DEFAULT_FONT_SIZE,
|
|
2650
|
+
fill: node.fill,
|
|
2651
|
+
stroke: node.stroke,
|
|
2652
|
+
strokeWidth: node.strokeWidth,
|
|
2653
|
+
letterSpacing: (_b = parseLen(node.letterSpacing)) != null ? _b : 0,
|
|
2654
|
+
wordSpacing: (_c = parseLen(node.wordSpacing)) != null ? _c : 0
|
|
2655
|
+
};
|
|
2656
|
+
}
|
|
2657
|
+
function paintOf(s) {
|
|
2658
|
+
const p = {};
|
|
2659
|
+
if (s.fill !== void 0) p.fill = s.fill;
|
|
2660
|
+
if (s.stroke !== void 0) p.stroke = s.stroke;
|
|
2661
|
+
if (s.strokeWidth !== void 0) p.strokeWidth = s.strokeWidth;
|
|
2662
|
+
if (s.opacity !== void 0 && s.opacity !== 1) p.opacity = s.opacity;
|
|
2663
|
+
for (const key of PAINT_STATIC_KEYS) {
|
|
2664
|
+
if (s[key] !== void 0) p[key] = s[key];
|
|
2665
|
+
}
|
|
2666
|
+
if (s.animate !== void 0) p.animate = s.animate;
|
|
2667
|
+
return p;
|
|
2668
|
+
}
|
|
2669
|
+
function glyphFontFor(s, glyphs, soleFont, warnings) {
|
|
2670
|
+
var _a2;
|
|
2671
|
+
const gf = s.fontFamily ? glyphs[s.fontFamily] : soleFont;
|
|
2672
|
+
if (!gf) warnings == null ? void 0 : warnings.push('textGlyphs: no glyphs for font "' + ((_a2 = s.fontFamily) != null ? _a2 : "") + '"');
|
|
2673
|
+
return gf;
|
|
2674
|
+
}
|
|
2675
|
+
function soleFontOf(glyphs) {
|
|
2676
|
+
const names = Object.keys(glyphs);
|
|
2677
|
+
return names.length === 1 ? glyphs[names[0]] : void 0;
|
|
2678
|
+
}
|
|
2679
|
+
var MISSING_GLYPH_ADVANCE_EM = 0.6;
|
|
2680
|
+
var MISSING_GLYPH_CLASS_NAME = "px-missing-glyph";
|
|
2681
|
+
function missingGlyphBoxEm(advanceEm, ascentEm) {
|
|
2682
|
+
if (advanceEm <= 0 || ascentEm <= 0) return "";
|
|
2683
|
+
const inset = 0.08;
|
|
2684
|
+
const x0 = advanceEm * inset, x1 = advanceEm * (1 - inset);
|
|
2685
|
+
const y1 = -ascentEm * (1 - inset);
|
|
2686
|
+
const bw = x1 - x0, bh = -y1;
|
|
2687
|
+
const t = Math.max(1, Math.min(bw, bh) * 0.12);
|
|
2688
|
+
const outer = "M" + x0 + " 0L" + x1 + " 0L" + x1 + " " + y1 + "L" + x0 + " " + y1 + "Z";
|
|
2689
|
+
if (bw <= 2 * t || bh <= 2 * t) return outer;
|
|
2690
|
+
const ix0 = x0 + t, ix1 = x1 - t, iyb = -t, iyt = y1 + t;
|
|
2691
|
+
return outer + "M" + ix0 + " " + iyb + "L" + ix0 + " " + iyt + "L" + ix1 + " " + iyt + "L" + ix1 + " " + iyb + "Z";
|
|
2692
|
+
}
|
|
2693
|
+
function materializeGlyphTextHorizontal(node, opts) {
|
|
2694
|
+
var _a2, _b, _c;
|
|
2695
|
+
const { glyphs, create = jsonElementFactory, warnings } = opts;
|
|
2696
|
+
const soleFont = soleFontOf(glyphs);
|
|
2697
|
+
const pen = { x: (_a2 = parseLen(node.x)) != null ? _a2 : 0, y: (_b = parseLen(node.y)) != null ? _b : 0 };
|
|
2698
|
+
const placements = [];
|
|
2699
|
+
const lines = [{ start: pen.x, end: pen.x }];
|
|
2700
|
+
let line = 0;
|
|
2701
|
+
const renderChars = (content, s) => {
|
|
2702
|
+
var _a3;
|
|
2703
|
+
const gf = glyphFontFor(s, glyphs, soleFont, warnings);
|
|
2704
|
+
const upm = (gf == null ? void 0 : gf.unitsPerEm) || 1e3;
|
|
2705
|
+
const scale = s.fontSize / upm;
|
|
2706
|
+
const ascentEm = (_a3 = gf == null ? void 0 : gf.ascent) != null ? _a3 : 0.9 * upm;
|
|
2707
|
+
const paint = paintOf(s);
|
|
2708
|
+
for (let i = 0; i < content.length; i++) {
|
|
2709
|
+
const ch = content.charAt(i);
|
|
2710
|
+
const g = gf == null ? void 0 : gf.glyphs[ch];
|
|
2711
|
+
if (g && g.pathData) {
|
|
2712
|
+
placements.push({ glyphD: g.pathData, m: [scale, 0, 0, scale, pen.x, pen.y], paint, line, x: pen.x, y: pen.y, scale });
|
|
2713
|
+
pen.x += g.width * scale;
|
|
2714
|
+
} else if (/\S/.test(ch)) {
|
|
2715
|
+
const advEm = g && g.width > 0 ? g.width : MISSING_GLYPH_ADVANCE_EM * upm;
|
|
2716
|
+
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 });
|
|
2717
|
+
pen.x += advEm * scale;
|
|
2718
|
+
} else {
|
|
2719
|
+
pen.x += (g ? g.width : 0) * scale;
|
|
2720
|
+
}
|
|
2721
|
+
pen.x += s.letterSpacing + (ch === " " ? s.wordSpacing : 0);
|
|
2722
|
+
lines[line].end = pen.x;
|
|
2723
|
+
}
|
|
2724
|
+
};
|
|
2725
|
+
const walk = (el, parentStyle) => {
|
|
2726
|
+
var _a3, _b2, _c2;
|
|
2727
|
+
const s = resolveStyle(el, parentStyle);
|
|
2728
|
+
const x = parseLen(el.x);
|
|
2729
|
+
const y = parseLen(el.y);
|
|
2730
|
+
if (x !== void 0) {
|
|
2731
|
+
pen.x = x;
|
|
2732
|
+
line = lines.length;
|
|
2733
|
+
lines.push({ start: pen.x, end: pen.x });
|
|
2734
|
+
}
|
|
2735
|
+
if (y !== void 0) pen.y = y;
|
|
2736
|
+
pen.x += (_a3 = parseLen(el.dx)) != null ? _a3 : 0;
|
|
2737
|
+
pen.y += (_b2 = parseLen(el.dy)) != null ? _b2 : 0;
|
|
2738
|
+
const content = str(el[PX_TEXT_CONTENT_ATTR]);
|
|
2739
|
+
if (content && !((_c2 = el.children) == null ? void 0 : _c2.length)) renderChars(content, s);
|
|
2740
|
+
if (el.children) for (const ch of el.children) walk(ch, s);
|
|
2741
|
+
};
|
|
2742
|
+
const rootStyle = rootStyleOf(node);
|
|
2743
|
+
if (node.children) for (const ch of node.children) walk(ch, rootStyle);
|
|
2744
|
+
const rootContent = str(node[PX_TEXT_CONTENT_ATTR]);
|
|
2745
|
+
if (rootContent && !((_c = node.children) == null ? void 0 : _c.length)) renderChars(rootContent, rootStyle);
|
|
2746
|
+
const anchor = str(node.textAnchor);
|
|
2747
|
+
if (anchor === "middle" || anchor === "end") {
|
|
2748
|
+
for (const p of placements) {
|
|
2749
|
+
const w = lines[p.line].end - lines[p.line].start;
|
|
2750
|
+
const shift = anchor === "middle" ? -w / 2 : -w;
|
|
2751
|
+
p.m = [p.scale, 0, 0, p.scale, p.x + shift, p.y];
|
|
2752
|
+
}
|
|
2753
|
+
}
|
|
2754
|
+
return toGroup(node, buildPaths(placements, create, warnings), create);
|
|
2755
|
+
}
|
|
2756
|
+
function layoutGlyphTextChars(node, opts) {
|
|
2757
|
+
var _a2, _b, _c, _d, _e;
|
|
2758
|
+
if ((_a2 = opts.alongPath) == null ? void 0 : _a2.pathD) return layoutGlyphTextCharsAlongPath(node, opts.alongPath.pathD, opts);
|
|
2759
|
+
const { glyphs, warnings } = opts;
|
|
2760
|
+
const soleFont = soleFontOf(glyphs);
|
|
2761
|
+
const pen = { x: (_b = parseLen(node.x)) != null ? _b : 0, y: (_c = parseLen(node.y)) != null ? _c : 0 };
|
|
2762
|
+
const boxes = [];
|
|
2763
|
+
const lines = [{ start: pen.x, end: pen.x }];
|
|
2764
|
+
let line = 0;
|
|
2765
|
+
const renderChars = (content, s) => {
|
|
2766
|
+
var _a3;
|
|
2767
|
+
const gf = glyphFontFor(s, glyphs, soleFont, warnings);
|
|
2768
|
+
const upm = (gf == null ? void 0 : gf.unitsPerEm) || 1e3;
|
|
2769
|
+
const scale = s.fontSize / upm;
|
|
2770
|
+
const ascent = ((_a3 = gf == null ? void 0 : gf.ascent) != null ? _a3 : 0.9 * upm) * scale;
|
|
2771
|
+
for (let i = 0; i < content.length; i++) {
|
|
2772
|
+
const ch = content.charAt(i);
|
|
2773
|
+
const g = gf == null ? void 0 : gf.glyphs[ch];
|
|
2774
|
+
const advance = (g ? g.width : 0) * scale + s.letterSpacing + (ch === " " ? s.wordSpacing : 0);
|
|
2775
|
+
boxes.push({ x: pen.x, y: pen.y, width: advance, ascent, fontSize: s.fontSize, line });
|
|
2776
|
+
pen.x += advance;
|
|
2777
|
+
lines[line].end = pen.x;
|
|
2778
|
+
}
|
|
2779
|
+
};
|
|
2780
|
+
const walk = (el, parentStyle) => {
|
|
2781
|
+
var _a3, _b2, _c2;
|
|
2782
|
+
const s = resolveStyle(el, parentStyle);
|
|
2783
|
+
const x = parseLen(el.x);
|
|
2784
|
+
const y = parseLen(el.y);
|
|
2785
|
+
if (x !== void 0) {
|
|
2786
|
+
pen.x = x;
|
|
2787
|
+
line = lines.length;
|
|
2788
|
+
lines.push({ start: pen.x, end: pen.x });
|
|
2789
|
+
}
|
|
2790
|
+
if (y !== void 0) pen.y = y;
|
|
2791
|
+
pen.x += (_a3 = parseLen(el.dx)) != null ? _a3 : 0;
|
|
2792
|
+
pen.y += (_b2 = parseLen(el.dy)) != null ? _b2 : 0;
|
|
2793
|
+
const content = str(el[PX_TEXT_CONTENT_ATTR]);
|
|
2794
|
+
if (content && !((_c2 = el.children) == null ? void 0 : _c2.length)) renderChars(content, s);
|
|
2795
|
+
if (el.children) for (const ch of el.children) walk(ch, s);
|
|
2796
|
+
};
|
|
2797
|
+
const rootStyle = rootStyleOf(node);
|
|
2798
|
+
if (node.children) for (const ch of node.children) {
|
|
2799
|
+
const before = boxes.length;
|
|
2800
|
+
walk(ch, rootStyle);
|
|
2801
|
+
if (boxes.length === before) {
|
|
2802
|
+
const s = resolveStyle(ch, rootStyle);
|
|
2803
|
+
const gf = glyphFontFor(s, glyphs, soleFont);
|
|
2804
|
+
const upm = (gf == null ? void 0 : gf.unitsPerEm) || 1e3;
|
|
2805
|
+
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 });
|
|
2806
|
+
}
|
|
2807
|
+
}
|
|
2808
|
+
const rootContent = str(node[PX_TEXT_CONTENT_ATTR]);
|
|
2809
|
+
if (rootContent && !((_e = node.children) == null ? void 0 : _e.length)) renderChars(rootContent, rootStyle);
|
|
2810
|
+
const anchor = str(node.textAnchor);
|
|
2811
|
+
if (anchor === "middle" || anchor === "end") {
|
|
2812
|
+
for (const b of boxes) {
|
|
2813
|
+
const w = lines[b.line].end - lines[b.line].start;
|
|
2814
|
+
b.x += anchor === "middle" ? -w / 2 : -w;
|
|
2815
|
+
}
|
|
2816
|
+
}
|
|
2817
|
+
return boxes.map((_f) => {
|
|
2818
|
+
var _g = _f, { line: _l } = _g, b = __objRest(_g, ["line"]);
|
|
2819
|
+
return b;
|
|
2820
|
+
});
|
|
2821
|
+
}
|
|
2822
|
+
function layoutGlyphTextCharsAlongPath(node, pathD, opts) {
|
|
2823
|
+
var _a2, _b;
|
|
2824
|
+
const { glyphs, warnings, alongPath } = opts;
|
|
2825
|
+
const sampler = createPathSampler(pathD);
|
|
2826
|
+
if (!sampler) {
|
|
2827
|
+
warnings == null ? void 0 : warnings.push("textGlyphs: unparsable along-path geometry (caret)");
|
|
2828
|
+
return [];
|
|
2829
|
+
}
|
|
2830
|
+
const soleFont = soleFontOf(glyphs);
|
|
2831
|
+
const chars = [];
|
|
2832
|
+
let adv = 0;
|
|
2833
|
+
const walk = (el, parentStyle) => {
|
|
2834
|
+
var _a3, _b2;
|
|
2835
|
+
const s = resolveStyle(el, parentStyle);
|
|
2836
|
+
const content = str(el[PX_TEXT_CONTENT_ATTR]);
|
|
2837
|
+
if (content && !((_a3 = el.children) == null ? void 0 : _a3.length)) {
|
|
2838
|
+
const gf = glyphFontFor(s, glyphs, soleFont, warnings);
|
|
2839
|
+
const upm = (gf == null ? void 0 : gf.unitsPerEm) || 1e3;
|
|
2840
|
+
const scale = s.fontSize / upm;
|
|
2841
|
+
const ascent = ((_b2 = gf == null ? void 0 : gf.ascent) != null ? _b2 : 0.9 * upm) * scale;
|
|
2842
|
+
for (let i = 0; i < content.length; i++) {
|
|
2843
|
+
const ch = content.charAt(i);
|
|
2844
|
+
const g = gf == null ? void 0 : gf.glyphs[ch];
|
|
2845
|
+
const glyphW = (g ? g.width : 0) * scale;
|
|
2846
|
+
const advance = glyphW + s.letterSpacing + (ch === " " ? s.wordSpacing : 0);
|
|
2847
|
+
chars.push({ advStart: adv, advEnd: adv + advance, glyphW, ascent, fontSize: s.fontSize });
|
|
2848
|
+
adv += advance;
|
|
2849
|
+
}
|
|
2850
|
+
}
|
|
2851
|
+
if (el.children) for (const ch of el.children) walk(ch, s);
|
|
2852
|
+
};
|
|
2853
|
+
walk(node, rootStyleOf(node));
|
|
2854
|
+
const width = adv;
|
|
2855
|
+
const tlr = readAnimatable(alongPath == null ? void 0 : alongPath.textLength);
|
|
2856
|
+
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;
|
|
2857
|
+
const k = tlv > 0 && width > 0 ? tlv / width : 1;
|
|
2858
|
+
const so = readAnimatable(alongPath == null ? void 0 : alongPath.startOffset);
|
|
2859
|
+
const { along: alongOffset, perp } = alongPathNodeOffsets(node);
|
|
2860
|
+
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);
|
|
2861
|
+
const withPerp = (p) => ({
|
|
2862
|
+
x: p.x - perp * Math.sin(p.angle),
|
|
2863
|
+
y: p.y + perp * Math.cos(p.angle),
|
|
2864
|
+
angle: p.angle
|
|
2865
|
+
});
|
|
2866
|
+
return chars.map((c) => {
|
|
2867
|
+
const dStart = base + c.advStart * k;
|
|
2868
|
+
const dEnd = base + c.advEnd * k;
|
|
2869
|
+
const p0 = withPerp(sampler.sampleAtDistance(dStart));
|
|
2870
|
+
const p1 = withPerp(sampler.sampleAtDistance(dEnd));
|
|
2871
|
+
const glyphMid = sampler.sampleAtDistance(base + (c.advStart + c.glyphW / 2) * k);
|
|
2872
|
+
return {
|
|
2873
|
+
x: p0.x,
|
|
2874
|
+
y: p0.y,
|
|
2875
|
+
width: c.advEnd - c.advStart,
|
|
2876
|
+
ascent: c.ascent,
|
|
2877
|
+
fontSize: c.fontSize,
|
|
2878
|
+
endX: p1.x,
|
|
2879
|
+
endY: p1.y,
|
|
2880
|
+
rotation: glyphMid.angle * 180 / Math.PI
|
|
2881
|
+
};
|
|
2882
|
+
});
|
|
2883
|
+
}
|
|
2884
|
+
function collectAlongPathCells(node, glyphs, soleFont, warnings) {
|
|
2885
|
+
const cells = [];
|
|
2886
|
+
let adv = 0;
|
|
2887
|
+
const walk = (el, parentStyle) => {
|
|
2888
|
+
var _a2, _b;
|
|
2889
|
+
const s = resolveStyle(el, parentStyle);
|
|
2890
|
+
const content = str(el[PX_TEXT_CONTENT_ATTR]);
|
|
2891
|
+
if (content && !((_a2 = el.children) == null ? void 0 : _a2.length)) {
|
|
2892
|
+
const gf = glyphFontFor(s, glyphs, soleFont, warnings);
|
|
2893
|
+
if (gf) {
|
|
2894
|
+
const scale = s.fontSize / gf.unitsPerEm;
|
|
2895
|
+
const ascentEm = (_b = gf.ascent) != null ? _b : 0.9 * gf.unitsPerEm;
|
|
2896
|
+
const paint = paintOf(s);
|
|
2897
|
+
for (let i = 0; i < content.length; i++) {
|
|
2898
|
+
const ch = content.charAt(i);
|
|
2899
|
+
const g = gf.glyphs[ch];
|
|
2900
|
+
if (g && g.pathData) {
|
|
2901
|
+
const glyphAdv = g.width * scale;
|
|
2902
|
+
cells.push({ glyphD: g.pathData, widthEm: g.width, scale, paint, midBase: adv + glyphAdv / 2 });
|
|
2903
|
+
adv += glyphAdv;
|
|
2904
|
+
} else if (/\S/.test(ch)) {
|
|
2905
|
+
const wEm = g && g.width > 0 ? g.width : MISSING_GLYPH_ADVANCE_EM * gf.unitsPerEm;
|
|
2906
|
+
const boxAdv = wEm * scale;
|
|
2907
|
+
cells.push({ glyphD: missingGlyphBoxEm(wEm, ascentEm), widthEm: wEm, scale, paint, isMissing: true, midBase: adv + boxAdv / 2 });
|
|
2908
|
+
adv += boxAdv;
|
|
2909
|
+
} else {
|
|
2910
|
+
adv += (g ? g.width : 0) * scale;
|
|
2911
|
+
}
|
|
2912
|
+
adv += s.letterSpacing + (ch === " " ? s.wordSpacing : 0);
|
|
2913
|
+
}
|
|
2914
|
+
}
|
|
2915
|
+
}
|
|
2916
|
+
if (el.children) for (const ch of el.children) walk(ch, s);
|
|
2917
|
+
};
|
|
2918
|
+
walk(node, rootStyleOf(node));
|
|
2919
|
+
return { cells, width: adv };
|
|
2920
|
+
}
|
|
2921
|
+
function alongAffine(sampler, dist, scale, widthEm, perp = 0) {
|
|
2922
|
+
const { x, y, angle } = sampler.sampleAtDistance(dist);
|
|
2923
|
+
const cos = Math.cos(angle), sin = Math.sin(angle), hw = widthEm / 2;
|
|
2924
|
+
return [scale * cos, scale * sin, -scale * sin, scale * cos, x - scale * cos * hw - perp * sin, y - scale * sin * hw + perp * cos];
|
|
2925
|
+
}
|
|
2926
|
+
function alongPathNodeOffsets(node) {
|
|
2927
|
+
var _a2, _b, _c;
|
|
2928
|
+
return {
|
|
2929
|
+
along: ((_a2 = parseLen(node.x)) != null ? _a2 : 0) + ((_b = parseLen(node.dx)) != null ? _b : 0),
|
|
2930
|
+
perp: (_c = parseLen(node.dy)) != null ? _c : 0
|
|
2931
|
+
};
|
|
2932
|
+
}
|
|
2933
|
+
function materializeGlyphTextAlongPath(node, pathD, startOffset, opts, textLength, pathOverflow) {
|
|
2934
|
+
const { glyphs, create = jsonElementFactory, warnings } = opts;
|
|
2935
|
+
const sampler = pathD ? createPathSampler(pathD) : null;
|
|
2936
|
+
if (!sampler) {
|
|
2937
|
+
warnings == null ? void 0 : warnings.push("textGlyphs: unparsable along-path geometry");
|
|
2938
|
+
return null;
|
|
2939
|
+
}
|
|
2940
|
+
const soleFont = soleFontOf(glyphs);
|
|
2941
|
+
const { cells, width } = collectAlongPathCells(node, glyphs, soleFont, warnings);
|
|
2942
|
+
if (!cells.length) return toGroup(node, [], create);
|
|
2943
|
+
const { along: alongOffset, perp } = alongPathNodeOffsets(node);
|
|
2944
|
+
const soTrack = numTrackOf(startOffset);
|
|
2945
|
+
const tlTrack = numTrackOf(textLength);
|
|
2946
|
+
const kOf = (tl) => tl > 0 && width > 0 ? tl / width : 1;
|
|
2947
|
+
const isClip = pathOverflow === "clip" && !sampler.closed;
|
|
2948
|
+
if (soTrack.animated || tlTrack.animated) {
|
|
2949
|
+
const times = mergeTrackTimes(soTrack.times, tlTrack.times);
|
|
2950
|
+
const distOf = (c, t) => alongOffset + soTrack.at(t) + kOf(tlTrack.at(t)) * c.midBase;
|
|
2951
|
+
const loop = soTrack.animated ? soTrack.loop : tlTrack.loop;
|
|
2952
|
+
return toGroup(node, buildAnimatedAlongPath(cells, sampler, distOf, times, loop, create, isClip, perp), create);
|
|
2953
|
+
}
|
|
2954
|
+
const k = kOf(tlTrack.at(0));
|
|
2955
|
+
const base = alongOffset + soTrack.at(0);
|
|
2956
|
+
const placeCells = isClip ? cells.filter((c) => {
|
|
2957
|
+
const d = base + c.midBase * k;
|
|
2958
|
+
return d >= 0 && d <= sampler.totalLength;
|
|
2959
|
+
}) : cells;
|
|
2960
|
+
const placements = placeCells.map((c) => ({
|
|
2961
|
+
glyphD: c.glyphD,
|
|
2962
|
+
paint: c.paint,
|
|
2963
|
+
isMissing: c.isMissing,
|
|
2964
|
+
m: alongAffine(sampler, base + c.midBase * k, c.scale, c.widthEm, perp)
|
|
2965
|
+
}));
|
|
2966
|
+
return toGroup(node, buildPaths(placements, create, warnings), create);
|
|
2967
|
+
}
|
|
2968
|
+
function numTrackOf(raw) {
|
|
2969
|
+
var _a2;
|
|
2970
|
+
const r = readAnimatable(raw);
|
|
2971
|
+
if (r.kind === "animated" /* Animated */ && r.keyframes.length >= 2) {
|
|
2972
|
+
const kfs = [...r.keyframes].sort((k1, k2) => (Number(k1.time) || 0) - (Number(k2.time) || 0));
|
|
2973
|
+
const times = kfs.map((kf) => Number(kf.time) || 0);
|
|
2974
|
+
const vals = kfs.map((kf) => Number(kf.value) || 0);
|
|
2975
|
+
return {
|
|
2976
|
+
animated: true,
|
|
2977
|
+
times,
|
|
2978
|
+
loop: r.loop,
|
|
2979
|
+
at(t) {
|
|
2980
|
+
if (t <= times[0]) return vals[0];
|
|
2981
|
+
for (let i = 1; i < times.length; i++) {
|
|
2982
|
+
if (t <= times[i]) {
|
|
2983
|
+
const span = times[i] - times[i - 1];
|
|
2984
|
+
const f = span > 0 ? (t - times[i - 1]) / span : 1;
|
|
2985
|
+
return vals[i - 1] + f * (vals[i] - vals[i - 1]);
|
|
2986
|
+
}
|
|
2987
|
+
}
|
|
2988
|
+
return vals[vals.length - 1];
|
|
2989
|
+
}
|
|
2990
|
+
};
|
|
2991
|
+
}
|
|
2992
|
+
const v = r.kind === "animated" /* Animated */ ? Number((_a2 = r.keyframes[0]) == null ? void 0 : _a2.value) || 0 : r.kind === "static" /* Static */ ? Number(r.value) || 0 : 0;
|
|
2993
|
+
return { animated: false, times: [], at: () => v };
|
|
2994
|
+
}
|
|
2995
|
+
function mergeTrackTimes(a, b) {
|
|
2996
|
+
const all = [...a, ...b].sort((t1, t2) => t1 - t2);
|
|
2997
|
+
const out = [];
|
|
2998
|
+
for (const t of all) if (!out.length || t !== out[out.length - 1]) out.push(t);
|
|
2999
|
+
return out;
|
|
3000
|
+
}
|
|
3001
|
+
var ALONG_PATH_MAX_STEPS = 48;
|
|
3002
|
+
var ALONG_PATH_MAX_STEPS_PER_SEGMENT = 64;
|
|
3003
|
+
function roundN(v, n) {
|
|
3004
|
+
const f = __pow(10, n);
|
|
3005
|
+
return Math.round(v * f) / f;
|
|
3006
|
+
}
|
|
3007
|
+
function buildAnimatedAlongPath(cells, sampler, distOf, times, loop, create, isClip, perp = 0) {
|
|
3008
|
+
const step = Math.max(sampler.totalLength / ALONG_PATH_MAX_STEPS, 0.5);
|
|
3009
|
+
const onPath = (dist) => dist >= 0 && dist <= sampler.totalLength;
|
|
3010
|
+
const out = [];
|
|
3011
|
+
for (const c of cells) {
|
|
3012
|
+
const centered = [c.scale, 0, 0, c.scale, -c.scale * (c.widthEm / 2), 0];
|
|
3013
|
+
const d = transformPathData(c.glyphD, centered);
|
|
3014
|
+
const sampleKf = (dist, time) => {
|
|
3015
|
+
const { x, y, angle } = sampler.sampleAtDistance(dist);
|
|
3016
|
+
const cos = Math.cos(angle), sin = Math.sin(angle);
|
|
3017
|
+
return {
|
|
3018
|
+
time,
|
|
3019
|
+
value: {
|
|
3020
|
+
["translate" /* Translate */]: [roundN(x - perp * sin, 3), roundN(y + perp * cos, 3)],
|
|
3021
|
+
["rotate" /* Rotate */]: roundN(angle * 180 / Math.PI, 3)
|
|
3022
|
+
}
|
|
3023
|
+
};
|
|
3024
|
+
};
|
|
3025
|
+
const kfs = [];
|
|
3026
|
+
const opKfs = [];
|
|
3027
|
+
const pushKf = (dist, time) => {
|
|
3028
|
+
kfs.push(sampleKf(dist, time));
|
|
3029
|
+
if (isClip) opKfs.push({ time, value: onPath(dist) ? 1 : 0 });
|
|
3030
|
+
};
|
|
3031
|
+
pushKf(distOf(c, times[0]), times[0]);
|
|
3032
|
+
for (let k = 1; k < times.length; k++) {
|
|
3033
|
+
const t0 = times[k - 1], t1 = times[k];
|
|
3034
|
+
const d0 = distOf(c, t0), d1 = distOf(c, t1);
|
|
3035
|
+
const n = Math.min(ALONG_PATH_MAX_STEPS_PER_SEGMENT, Math.max(1, Math.ceil(Math.abs(d1 - d0) / step)));
|
|
3036
|
+
for (let s = 1; s <= n; s++) {
|
|
3037
|
+
const f = s / n;
|
|
3038
|
+
const t = t0 + f * (t1 - t0);
|
|
3039
|
+
pushKf(distOf(c, t), t);
|
|
3040
|
+
}
|
|
3041
|
+
}
|
|
3042
|
+
unwrapAutoOrientRotations(kfs);
|
|
3043
|
+
const transform = { keyframes: kfs };
|
|
3044
|
+
if (loop !== void 0) transform.loop = loop;
|
|
3045
|
+
const animate = { transform };
|
|
3046
|
+
if (c.paint.animate) Object.assign(animate, c.paint.animate);
|
|
3047
|
+
if (isClip && opKfs.some((k) => k.value === 0)) {
|
|
3048
|
+
const op = { keyframes: opKfs };
|
|
3049
|
+
if (loop !== void 0) op.loop = loop;
|
|
3050
|
+
animate.opacity = op;
|
|
3051
|
+
}
|
|
3052
|
+
out.push(create("path", __spreadProps(__spreadValues(__spreadValues({ d }, paintProps(c.paint)), missingGlyphProps(c.isMissing)), { animate }), []));
|
|
3053
|
+
}
|
|
3054
|
+
return out;
|
|
3055
|
+
}
|
|
3056
|
+
function paintProps(paint) {
|
|
3057
|
+
const p = {};
|
|
3058
|
+
if (paint.fill !== void 0) p.fill = paint.fill;
|
|
3059
|
+
if (paint.stroke !== void 0) p.stroke = paint.stroke;
|
|
3060
|
+
if (paint.strokeWidth !== void 0) p.strokeWidth = paint.strokeWidth;
|
|
3061
|
+
if (paint.opacity !== void 0) p.opacity = paint.opacity;
|
|
3062
|
+
for (const key of PAINT_STATIC_KEYS) {
|
|
3063
|
+
if (paint[key] !== void 0) p[key] = paint[key];
|
|
3064
|
+
}
|
|
3065
|
+
return p;
|
|
3066
|
+
}
|
|
3067
|
+
function missingGlyphProps(isMissing) {
|
|
3068
|
+
return isMissing ? { [CLASS_ATTR]: MISSING_GLYPH_CLASS_NAME } : {};
|
|
3069
|
+
}
|
|
3070
|
+
function buildPaths(placements, create, warnings) {
|
|
3071
|
+
if (!placements.length) {
|
|
3072
|
+
warnings == null ? void 0 : warnings.push("textGlyphs: nothing to render");
|
|
3073
|
+
return [];
|
|
3074
|
+
}
|
|
3075
|
+
const byPaint = /* @__PURE__ */ new Map();
|
|
3076
|
+
for (const p of placements) {
|
|
3077
|
+
const key = JSON.stringify([p.paint, !!p.isMissing]);
|
|
3078
|
+
const baked = transformPathData(p.glyphD, p.m);
|
|
3079
|
+
const entry = byPaint.get(key);
|
|
3080
|
+
if (entry) entry.d += baked;
|
|
3081
|
+
else byPaint.set(key, { paint: p.paint, d: baked, isMissing: p.isMissing });
|
|
3082
|
+
}
|
|
3083
|
+
const out = [];
|
|
3084
|
+
for (const { paint, d, isMissing } of byPaint.values()) {
|
|
3085
|
+
out.push(create("path", __spreadValues(__spreadValues(__spreadValues({
|
|
3086
|
+
d
|
|
3087
|
+
}, paintProps(paint)), missingGlyphProps(isMissing)), paint.animate !== void 0 ? { animate: __spreadValues({}, paint.animate) } : {}), []));
|
|
3088
|
+
}
|
|
3089
|
+
return out;
|
|
3090
|
+
}
|
|
3091
|
+
function toGroup(node, children, create) {
|
|
3092
|
+
const gProps = {};
|
|
3093
|
+
for (const k of Object.keys(node)) {
|
|
3094
|
+
if (k === "type" || k === "children" || TEXT_ATTR_KEYS.indexOf(k) !== -1) continue;
|
|
3095
|
+
gProps[k] = node[k];
|
|
3096
|
+
}
|
|
3097
|
+
if (gProps.style && typeof gProps.style === "object") {
|
|
3098
|
+
const style = __spreadValues({}, gProps.style);
|
|
3099
|
+
delete style["white-space"];
|
|
3100
|
+
if (Object.keys(style).length) gProps.style = style;
|
|
3101
|
+
else delete gProps.style;
|
|
3102
|
+
}
|
|
3103
|
+
return create("g", gProps, children);
|
|
3104
|
+
}
|
|
3105
|
+
function materializeGlyphText(node, opts) {
|
|
3106
|
+
if (opts.alongPath) return materializeGlyphTextAlongPath(node, opts.alongPath.pathD, opts.alongPath.startOffset, opts, opts.alongPath.textLength, opts.alongPath.pathOverflow);
|
|
3107
|
+
return materializeGlyphTextHorizontal(node, opts);
|
|
3108
|
+
}
|
|
3109
|
+
|
|
3110
|
+
// src/effects/text/textPathEffect.ts
|
|
3111
|
+
var EXTEND_MARGIN_FRAC = 0.15;
|
|
3112
|
+
function numRange(v) {
|
|
3113
|
+
const read = readAnimatable(v);
|
|
3114
|
+
if (read.kind === "static" /* Static */ && typeof read.value === "number") return { min: read.value, max: read.value };
|
|
3115
|
+
if (read.kind === "animated" /* Animated */ && read.keyframes.length) {
|
|
3116
|
+
const vals = read.keyframes.map((k) => Number(k.value) || 0);
|
|
3117
|
+
return { min: Math.min(...vals), max: Math.max(...vals) };
|
|
3118
|
+
}
|
|
3119
|
+
return { min: 0, max: 0 };
|
|
3120
|
+
}
|
|
3121
|
+
var r3 = (n) => Math.round(n * 1e3) / 1e3;
|
|
3122
|
+
function extendedPathForBrowser(pathD, opts) {
|
|
3123
|
+
var _a2;
|
|
3124
|
+
if (opts.pathOverflow === "clip") return { d: pathD, startShift: 0 };
|
|
3125
|
+
const sampler = createPathSampler(pathD);
|
|
3126
|
+
if (!sampler || sampler.closed || sampler.totalLength <= 0) return { d: pathD, startShift: 0 };
|
|
3127
|
+
const L = sampler.totalLength;
|
|
3128
|
+
const margin = EXTEND_MARGIN_FRAC * L;
|
|
3129
|
+
const so = numRange(opts.startOffset);
|
|
3130
|
+
const runWidth = numRange(opts.textLength).max || ((_a2 = opts.advance) != null ? _a2 : 0);
|
|
3131
|
+
const startOverflow = Math.max(0, -so.min);
|
|
3132
|
+
const endOverflow = Math.max(0, so.max + runWidth - L);
|
|
3133
|
+
const startExt = startOverflow > 0 ? startOverflow + margin : 0;
|
|
3134
|
+
const endExt = endOverflow > 0 ? endOverflow + margin : 0;
|
|
3135
|
+
if (endExt <= 0 && startExt <= 0) return { d: pathD, startShift: 0 };
|
|
3136
|
+
const s = sampler.sampleAtDistance(0);
|
|
3137
|
+
const e = sampler.sampleAtDistance(L);
|
|
3138
|
+
let d = pathD;
|
|
3139
|
+
if (startExt > 0) {
|
|
3140
|
+
const sx = s.x - Math.cos(s.angle) * startExt, sy = s.y - Math.sin(s.angle) * startExt;
|
|
3141
|
+
const rest = pathD.replace(/^\s*[Mm]\s*-?[\d.]+[\s,]+-?[\d.]+/, "");
|
|
3142
|
+
d = "M" + r3(sx) + "," + r3(sy) + "L" + r3(s.x) + "," + r3(s.y) + rest;
|
|
3143
|
+
}
|
|
3144
|
+
if (endExt > 0) {
|
|
3145
|
+
const ex = e.x + Math.cos(e.angle) * endExt, ey = e.y + Math.sin(e.angle) * endExt;
|
|
3146
|
+
d += "L" + r3(ex) + "," + r3(ey);
|
|
3147
|
+
}
|
|
3148
|
+
return { d, startShift: startExt };
|
|
3149
|
+
}
|
|
3150
|
+
|
|
3151
|
+
// src/format/PxDocumentDiagnostic.ts
|
|
3152
|
+
var MAX_REPORTED = 6;
|
|
3153
|
+
function diagnoseDocument(doc) {
|
|
3154
|
+
try {
|
|
3155
|
+
return { problems: validateDocument(doc) };
|
|
3156
|
+
} catch (e) {
|
|
3157
|
+
return { problems: [] };
|
|
3158
|
+
}
|
|
3159
|
+
}
|
|
3160
|
+
function reportDocumentDiagnostics(doc, where) {
|
|
3161
|
+
const { problems } = diagnoseDocument(doc);
|
|
3162
|
+
if (!problems.length) return;
|
|
3163
|
+
const shown = problems.slice(0, MAX_REPORTED);
|
|
3164
|
+
const more = problems.length - shown.length;
|
|
3165
|
+
console.warn(
|
|
3166
|
+
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."
|
|
3167
|
+
);
|
|
3168
|
+
}
|
|
3169
|
+
|
|
3170
|
+
// src/playback/PxDiagnostics.ts
|
|
3171
|
+
function asError(error) {
|
|
3172
|
+
return typeof error === "string" ? new Error(error) : error;
|
|
3173
|
+
}
|
|
3174
|
+
function createDiagnostics(config, prefix) {
|
|
3175
|
+
const tag = prefix ? prefix + " " : "";
|
|
3176
|
+
return {
|
|
3177
|
+
warn: (kind, message, detail) => {
|
|
3178
|
+
if (config == null ? void 0 : config.onWarn) {
|
|
3179
|
+
config.onWarn({ kind, message, detail });
|
|
3180
|
+
return;
|
|
3181
|
+
}
|
|
3182
|
+
if (config == null ? void 0 : config.muteWarn) return;
|
|
3183
|
+
const line = tag + kind + ": " + message;
|
|
3184
|
+
if (detail === void 0) console.warn(line);
|
|
3185
|
+
else console.warn(line, detail);
|
|
3186
|
+
},
|
|
3187
|
+
error: (kind, error, detail) => {
|
|
3188
|
+
const err = asError(error);
|
|
3189
|
+
if (config == null ? void 0 : config.onError) {
|
|
3190
|
+
config.onError({ kind, message: err.message, error: err, detail });
|
|
3191
|
+
return;
|
|
3192
|
+
}
|
|
3193
|
+
if (config == null ? void 0 : config.muteError) return;
|
|
3194
|
+
const line = tag + kind + ": " + err.message;
|
|
3195
|
+
if (detail === void 0) console.error(line);
|
|
3196
|
+
else console.error(line, detail);
|
|
3197
|
+
}
|
|
3198
|
+
};
|
|
3199
|
+
}
|
|
3200
|
+
|
|
3201
|
+
// src/playback/PxScrollMath.ts
|
|
3202
|
+
function isScrollTimeline(config) {
|
|
3203
|
+
return (config == null ? void 0 : config.timelineSource) === "scroll";
|
|
3204
|
+
}
|
|
3205
|
+
function scrollTotalDurationMs(config) {
|
|
3206
|
+
const duration = typeof (config == null ? void 0 : config.duration) === "number" && config.duration > 0 ? config.duration : PX_DEFAULT_DURATION_MS;
|
|
3207
|
+
const iterations = typeof (config == null ? void 0 : config.iterations) === "number" && config.iterations > 0 ? config.iterations : 1;
|
|
3208
|
+
return duration * iterations;
|
|
3209
|
+
}
|
|
3210
|
+
function scrollPhaseInterval(phase, subjectSize, scrollportSize) {
|
|
3211
|
+
const s = subjectSize, vp = scrollportSize;
|
|
3212
|
+
switch (phase) {
|
|
3213
|
+
case "cover":
|
|
3214
|
+
return [0, s + vp];
|
|
3215
|
+
case "entry":
|
|
3216
|
+
return [0, Math.min(s, vp)];
|
|
3217
|
+
case "contain":
|
|
3218
|
+
return [Math.min(s, vp), Math.max(s, vp)];
|
|
3219
|
+
case "exit":
|
|
3220
|
+
return [Math.max(s, vp), s + vp];
|
|
3221
|
+
case "entry-crossing":
|
|
3222
|
+
return [0, s];
|
|
3223
|
+
case "exit-crossing":
|
|
3224
|
+
return [vp, s + vp];
|
|
3225
|
+
}
|
|
3226
|
+
}
|
|
3227
|
+
var DEFAULT_PHASE = "cover";
|
|
3228
|
+
function resolveRangePointU(point, defaultFraction, subjectSize, scrollportSize) {
|
|
3229
|
+
var _a2;
|
|
3230
|
+
const [u0, u1] = scrollPhaseInterval((_a2 = point == null ? void 0 : point.phase) != null ? _a2 : DEFAULT_PHASE, subjectSize, scrollportSize);
|
|
3231
|
+
const fraction = typeof (point == null ? void 0 : point.fraction) === "number" ? point.fraction : defaultFraction;
|
|
3232
|
+
return u0 + fraction * (u1 - u0);
|
|
3233
|
+
}
|
|
3234
|
+
function scrollViewProgress(subjectStart, subjectSize, scrollportSize, range) {
|
|
3235
|
+
const u = scrollportSize - subjectStart;
|
|
3236
|
+
const uStart = resolveRangePointU(range == null ? void 0 : range.start, 0, subjectSize, scrollportSize);
|
|
3237
|
+
const uEnd = resolveRangePointU(range == null ? void 0 : range.end, 1, subjectSize, scrollportSize);
|
|
3238
|
+
if (uEnd <= uStart) return u >= uEnd ? 1 : 0;
|
|
3239
|
+
return clamp((u - uStart) / (uEnd - uStart), 0, 1);
|
|
3240
|
+
}
|
|
3241
|
+
function scrollOffsetProgress(offset, maxOffset, range) {
|
|
3242
|
+
var _a2, _b;
|
|
3243
|
+
const raw = maxOffset > 0 ? clamp(offset / maxOffset, 0, 1) : 1;
|
|
3244
|
+
const start = typeof ((_a2 = range == null ? void 0 : range.start) == null ? void 0 : _a2.fraction) === "number" ? range.start.fraction : 0;
|
|
3245
|
+
const end = typeof ((_b = range == null ? void 0 : range.end) == null ? void 0 : _b.fraction) === "number" ? range.end.fraction : 1;
|
|
3246
|
+
if (end <= start) return raw >= end ? 1 : 0;
|
|
3247
|
+
return clamp((raw - start) / (end - start), 0, 1);
|
|
3248
|
+
}
|
|
3249
|
+
function scrollResolveAxis(axis, writingMode) {
|
|
3250
|
+
const a = axis != null ? axis : "block";
|
|
3251
|
+
if (a === "x" || a === "y") return a;
|
|
3252
|
+
const vertical = !!writingMode && writingMode.startsWith("vertical");
|
|
3253
|
+
if (a === "inline") return vertical ? "y" : "x";
|
|
3254
|
+
return vertical ? "x" : "y";
|
|
3255
|
+
}
|
|
3256
|
+
|
|
3257
|
+
// src/util/PxIdUtil.ts
|
|
3258
|
+
var _idCounter = 0;
|
|
3259
|
+
function generateUniqueId() {
|
|
3260
|
+
const timestamp = Date.now().toString(36);
|
|
3261
|
+
const counter = (++_idCounter).toString(36);
|
|
3262
|
+
const random = Math.random().toString(36).substring(2, 6);
|
|
3263
|
+
return "_px_" + timestamp + counter + random;
|
|
3264
|
+
}
|
|
3265
|
+
function deepClone(value) {
|
|
3266
|
+
if (value === null || typeof value !== "object") return value;
|
|
3267
|
+
if (Array.isArray(value)) return value.map((item) => deepClone(item));
|
|
3268
|
+
const obj = value;
|
|
3269
|
+
const cloned = {};
|
|
3270
|
+
for (const key of Object.keys(obj)) {
|
|
3271
|
+
cloned[key] = deepClone(obj[key]);
|
|
3272
|
+
}
|
|
3273
|
+
return cloned;
|
|
3274
|
+
}
|
|
3275
|
+
|
|
3276
|
+
// src/util/PxNodeProps.ts
|
|
3277
|
+
var PX_DISALLOWED_SVG_TAGS_LOWER = /* @__PURE__ */ new Set([
|
|
3278
|
+
"script",
|
|
3279
|
+
"foreignobject"
|
|
3280
|
+
]);
|
|
3281
|
+
var URL_VALUE_ATTRS_LOWER = /* @__PURE__ */ new Set([
|
|
3282
|
+
"href",
|
|
3283
|
+
// <use>, <image>
|
|
3284
|
+
"xlink:href",
|
|
3285
|
+
// legacy <use>
|
|
3286
|
+
"src",
|
|
3287
|
+
// <image>
|
|
3288
|
+
"filter",
|
|
3289
|
+
// url(#filterId)
|
|
3290
|
+
"clippath",
|
|
3291
|
+
// clip-path="url(#…)"
|
|
3292
|
+
"mask",
|
|
3293
|
+
// url(#maskId)
|
|
3294
|
+
"markerstart",
|
|
3295
|
+
// marker-start="url(#…)"
|
|
3296
|
+
"markermid",
|
|
3297
|
+
// marker-mid="url(#…)"
|
|
3298
|
+
"markerend"
|
|
3299
|
+
// marker-end="url(#…)"
|
|
3300
|
+
]);
|
|
3301
|
+
var IMAGE_REF_ATTRS_LOWER = /* @__PURE__ */ new Set(["href", "xlink:href", "src"]);
|
|
3302
|
+
var PX_CSS_ONLY_STYLE_PROPS = /* @__PURE__ */ new Set(["mixBlendMode", "isolation"]);
|
|
3303
|
+
var DATA_RASTER_IMAGE_RE = /^data:image\/(?:png|jpe?g|gif|webp|bmp);base64,/i;
|
|
3304
|
+
var DATA_SVG_IMAGE_RE = /^data:image\/svg\+xml(?:;[^,]*)?,/i;
|
|
3305
|
+
var DATA_IMAGE_BASE64_PAYLOAD_RE = /^data:image\/[^;,]*;base64,([A-Za-z0-9+/]{8})/i;
|
|
3306
|
+
var BASE64_RASTER_MAGICS = ["iVBORw0K", "/9j/", "R0lGOD", "UklGR", "Qk"];
|
|
3307
|
+
function isContentSniffedRasterImage(str2) {
|
|
3308
|
+
const m = DATA_IMAGE_BASE64_PAYLOAD_RE.exec(str2);
|
|
3309
|
+
return !!m && BASE64_RASTER_MAGICS.some((magic) => m[1].startsWith(magic));
|
|
3310
|
+
}
|
|
3311
|
+
function isDangerousAttrName(nameLower) {
|
|
3312
|
+
if (nameLower.startsWith("on")) return true;
|
|
3313
|
+
return false;
|
|
3314
|
+
}
|
|
3315
|
+
function sanitizeAttributeValue(name, value) {
|
|
3316
|
+
const nameLower = name.toLowerCase();
|
|
3317
|
+
if (isDangerousAttrName(nameLower)) {
|
|
3318
|
+
console.warn("Attribute blocked (event handler / dangerous): ", nameLower);
|
|
3319
|
+
return void 0;
|
|
3320
|
+
}
|
|
3321
|
+
if (nameLower === "fill" || nameLower === "stroke" || nameLower === "stopcolor") {
|
|
3322
|
+
const str2 = String(value);
|
|
3323
|
+
if (str2.includes("url(") && !/^url\(#[^)]+\)$/.test(str2)) {
|
|
3324
|
+
console.warn('Attribute "' + nameLower + '" blocked: url() must be internal url(#id), got:', value);
|
|
3325
|
+
return void 0;
|
|
3326
|
+
}
|
|
3327
|
+
return value;
|
|
3328
|
+
}
|
|
3329
|
+
if (URL_VALUE_ATTRS_LOWER.has(nameLower)) {
|
|
3330
|
+
const str2 = String(value);
|
|
3331
|
+
if (str2.startsWith("#")) return value;
|
|
3332
|
+
if (/^url\(#[^)]+\)$/.test(str2)) return value;
|
|
3333
|
+
if (IMAGE_REF_ATTRS_LOWER.has(nameLower) && (DATA_RASTER_IMAGE_RE.test(str2) || DATA_SVG_IMAGE_RE.test(str2) || isContentSniffedRasterImage(str2))) return value;
|
|
3334
|
+
console.warn('Attribute "' + nameLower + '" blocked: must be #id, url(#id), or data:image/\u2026 URI, got:', value);
|
|
3335
|
+
return void 0;
|
|
3336
|
+
}
|
|
3337
|
+
return value;
|
|
3338
|
+
}
|
|
3339
|
+
|
|
3340
|
+
// src/version/PxSchemaFieldUniverse.ts
|
|
3341
|
+
function schemaFieldUniverse(root) {
|
|
3342
|
+
const fields = /* @__PURE__ */ new Set();
|
|
3343
|
+
const enumerated = /* @__PURE__ */ new Set();
|
|
3344
|
+
const queue = [{ schema: root, path: "" }];
|
|
3345
|
+
while (queue.length) {
|
|
3346
|
+
const { schema, path } = queue.shift();
|
|
3347
|
+
const d = describeSchema(schema);
|
|
3348
|
+
switch (d.kind) {
|
|
3349
|
+
case "shape": {
|
|
3350
|
+
if (enumerated.has(schema)) break;
|
|
3351
|
+
enumerated.add(schema);
|
|
3352
|
+
for (const key of Object.keys(d.shape)) {
|
|
3353
|
+
const id = path ? path + "." + key : key;
|
|
3354
|
+
fields.add(id);
|
|
3355
|
+
queue.push({ schema: d.shape[key], path: id });
|
|
3356
|
+
}
|
|
3357
|
+
if (d.openValue) queue.push({ schema: d.openValue, path: path + "{*}" });
|
|
3358
|
+
break;
|
|
3359
|
+
}
|
|
3360
|
+
case "optional":
|
|
3361
|
+
queue.push({ schema: d.inner, path });
|
|
3362
|
+
break;
|
|
3363
|
+
case "array":
|
|
3364
|
+
queue.push({ schema: d.item, path: path + "[]" });
|
|
3365
|
+
break;
|
|
3366
|
+
case "lazy":
|
|
3367
|
+
queue.push({ schema: d.resolved, path });
|
|
3368
|
+
break;
|
|
3369
|
+
case "record":
|
|
3370
|
+
queue.push({ schema: d.value, path: path + "{*}" });
|
|
3371
|
+
break;
|
|
3372
|
+
case "union":
|
|
3373
|
+
d.members.forEach((member, i) => queue.push({ schema: member, path: path + "|" + i }));
|
|
3374
|
+
break;
|
|
3375
|
+
case "discriminatedUnion":
|
|
3376
|
+
for (const member of d.members) queue.push({ schema: member, path: path + "|" + discriminantOf(member, d.key) });
|
|
3377
|
+
break;
|
|
3378
|
+
default:
|
|
3379
|
+
break;
|
|
3380
|
+
}
|
|
3381
|
+
}
|
|
3382
|
+
return [...fields].sort();
|
|
3383
|
+
}
|
|
3384
|
+
function discriminantOf(member, key) {
|
|
3385
|
+
const d = describeSchema(member);
|
|
3386
|
+
if (d.kind !== "shape") return "?";
|
|
3387
|
+
const keySchema = d.shape[key];
|
|
3388
|
+
if (keySchema === void 0) return "?";
|
|
3389
|
+
const kd = describeSchema(keySchema);
|
|
3390
|
+
return String((kd.kind === "optional" ? kd.inner : keySchema)._default);
|
|
3391
|
+
}
|
|
3392
|
+
|
|
3393
|
+
// src/version/PxSchemaRelease.ts
|
|
3394
|
+
function diffFieldUniverse(previous, current) {
|
|
3395
|
+
const prev = new Set(previous);
|
|
3396
|
+
const cur = new Set(current);
|
|
3397
|
+
return {
|
|
3398
|
+
added: current.filter((k) => !prev.has(k)).sort(),
|
|
3399
|
+
removed: previous.filter((k) => !cur.has(k)).sort()
|
|
3400
|
+
};
|
|
3401
|
+
}
|
|
3402
|
+
function planSchemaRelease(p) {
|
|
3403
|
+
const changed = p.added.length > 0 || p.removed.length > 0;
|
|
3404
|
+
const last = parseWireVersion(p.lastReleased);
|
|
3405
|
+
const declared = parseWireVersion(p.declared);
|
|
3406
|
+
if (!last || !declared) return { changed, refuse: "Unparseable version: " + p.lastReleased + " / " + p.declared + "." };
|
|
3407
|
+
const requiredVersion = last.a + "." + (last.b + 1);
|
|
3408
|
+
if (!changed) {
|
|
3409
|
+
if (declared.b === last.b && declared.a === last.a) return { changed };
|
|
3410
|
+
const step2 = p.steps.find((s) => s.to === p.declared);
|
|
3411
|
+
return step2 ? { changed, requiredVersion: p.declared } : { changed, refuse: "The version moved to " + p.declared + " with no key change and no step explaining it." };
|
|
3412
|
+
}
|
|
3413
|
+
const requiredKind = p.removed.length ? "converted" /* converted */ : "additive" /* additive */;
|
|
3414
|
+
const summary = p.added.length + " key(s) added, " + p.removed.length + " removed";
|
|
3415
|
+
if (declared.a !== last.a || declared.b !== last.b + 1) {
|
|
3416
|
+
return {
|
|
3417
|
+
changed,
|
|
3418
|
+
requiredKind,
|
|
3419
|
+
requiredVersion,
|
|
3420
|
+
refuse: "The player schema changed (" + summary + ") but PX_WIRE_SCHEMA_VERSION is " + p.declared + ". Set it to " + requiredVersion + " and add the PX_WIRE_STEPS entry."
|
|
3421
|
+
};
|
|
3422
|
+
}
|
|
3423
|
+
const step = p.steps.find((s) => s.to === p.declared);
|
|
3424
|
+
if (!step) {
|
|
3425
|
+
return { changed, requiredKind, requiredVersion, refuse: "No PX_WIRE_STEPS entry reaches " + p.declared + "." };
|
|
3426
|
+
}
|
|
3427
|
+
if (requiredKind === "converted" /* converted */ && step.kind !== "converted" /* converted */) {
|
|
3428
|
+
return {
|
|
3429
|
+
changed,
|
|
3430
|
+
requiredKind,
|
|
3431
|
+
requiredVersion,
|
|
3432
|
+
refuse: "Keys were REMOVED (" + p.removed.join(", ") + "), which is never additive \u2014 the " + p.declared + " step must be `converted`, with an up()."
|
|
3433
|
+
};
|
|
3434
|
+
}
|
|
3435
|
+
return { changed, requiredKind, requiredVersion };
|
|
3436
|
+
}
|
|
3437
|
+
function releaseLogProblems(releases, steps, declared, baseline) {
|
|
3438
|
+
const problems = [];
|
|
3439
|
+
if (!releases.length) return ["The release log is empty."];
|
|
3440
|
+
if (!releases[0].baseline || releases[0].version !== baseline) {
|
|
3441
|
+
problems.push("The first release must be the baseline " + baseline + ".");
|
|
3442
|
+
}
|
|
3443
|
+
for (let i = 1; i < releases.length; i++) {
|
|
3444
|
+
const prev = parseWireVersion(releases[i - 1].version);
|
|
3445
|
+
const cur = parseWireVersion(releases[i].version);
|
|
3446
|
+
if (!prev || !cur || cur.a !== prev.a || cur.b !== prev.b + 1) {
|
|
3447
|
+
problems.push("Release " + releases[i].version + " does not follow " + releases[i - 1].version + " by one `b` step.");
|
|
3448
|
+
}
|
|
3449
|
+
if (releases[i].date < releases[i - 1].date) problems.push("Release " + releases[i].version + " is dated before its predecessor.");
|
|
3450
|
+
const step = steps.find((s) => s.to === releases[i].version);
|
|
3451
|
+
if (!step) problems.push("Release " + releases[i].version + " has no PX_WIRE_STEPS entry.");
|
|
3452
|
+
else if (releases[i].removed.length && step.kind !== "converted" /* converted */) {
|
|
3453
|
+
problems.push("Release " + releases[i].version + " removed keys, but its step is not `converted`.");
|
|
3454
|
+
}
|
|
3455
|
+
}
|
|
3456
|
+
const latest = releases[releases.length - 1].version;
|
|
3457
|
+
if (latest !== declared) {
|
|
3458
|
+
problems.push("PX_WIRE_SCHEMA_VERSION is " + declared + " but the last release record is " + latest + " \u2014 a bump needs its changelog entry (run scripts/schema-release.mjs --apply).");
|
|
3459
|
+
}
|
|
3460
|
+
return problems;
|
|
3461
|
+
}
|
|
3462
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
3463
|
+
0 && (module.exports = {
|
|
3464
|
+
PX_ANIM_ATTR_NAME,
|
|
3465
|
+
PX_ANIM_SRC_ATTR_NAME,
|
|
3466
|
+
PX_COLOR_ATTR_NAMES,
|
|
3467
|
+
PX_CSS_ONLY_STYLE_PROPS,
|
|
3468
|
+
PX_DEFAULT_DURATION_MS,
|
|
3469
|
+
PX_DISALLOWED_SVG_TAGS_LOWER,
|
|
3470
|
+
PX_LOOP_JUMP_SHIFT_MS,
|
|
3471
|
+
PX_PCT_BASED_ATTR_NAMES,
|
|
3472
|
+
PX_STYLE_ATTR_NAMES,
|
|
3473
|
+
PX_TEXT_CONTENT_ATTR,
|
|
3474
|
+
PX_TRANSFORM_FN_NAMES,
|
|
3475
|
+
PX_UNKNOWN_KEY_ERROR,
|
|
3476
|
+
bezierToSvgPath,
|
|
3477
|
+
camelCaseToKebabWordIfNeeded,
|
|
3478
|
+
clamp,
|
|
3479
|
+
composeTransformParts,
|
|
3480
|
+
createDiagnostics,
|
|
3481
|
+
createPathSampler,
|
|
3482
|
+
cubicBezier,
|
|
3483
|
+
deepClone,
|
|
3484
|
+
diffFieldUniverse,
|
|
3485
|
+
diffInEffect,
|
|
3486
|
+
extendedPathForBrowser,
|
|
3487
|
+
generateUniqueId,
|
|
3488
|
+
interpolateValue,
|
|
3489
|
+
isScrollTimeline,
|
|
3490
|
+
kebabToCamelCaseWord,
|
|
3491
|
+
keyframeEasing,
|
|
3492
|
+
keyframeValue,
|
|
3493
|
+
layoutGlyphTextChars,
|
|
3494
|
+
materializeGlyphText,
|
|
3495
|
+
materializeGlyphTextAlongPath,
|
|
3496
|
+
materializeMotionPathInPropAnim,
|
|
3497
|
+
mergeStaticTransformIntoAnimDef,
|
|
3498
|
+
planSchemaRelease,
|
|
3499
|
+
releaseLogProblems,
|
|
3500
|
+
reportDocumentDiagnostics,
|
|
3501
|
+
reverseEasing,
|
|
3502
|
+
sanitizeAttributeValue,
|
|
3503
|
+
schemaFieldUniverse,
|
|
3504
|
+
scrollOffsetProgress,
|
|
3505
|
+
scrollPhaseInterval,
|
|
3506
|
+
scrollResolveAxis,
|
|
3507
|
+
scrollTotalDurationMs,
|
|
3508
|
+
scrollViewProgress,
|
|
3509
|
+
splitEasing,
|
|
3510
|
+
subdivideCubicBezier,
|
|
3511
|
+
toRGBA
|
|
3512
|
+
});
|
|
3513
|
+
//# sourceMappingURL=internal.cjs.map
|