@pixodesk/svg-animator-web 1.0.34 → 1.0.35

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.
@@ -55,7 +55,7 @@ var PixodeskAnimator = (() => {
55
55
  setupAnimationTriggers: () => setupAnimationTriggers
56
56
  });
57
57
 
58
- // ../svg-animator-core/src/PxAnimatorUtil.ts
58
+ // ../svg-animator-core/src/util/PxAnimatorUtil.ts
59
59
  function bezierToSvgPath(path, forceCurves = false) {
60
60
  var _a, _b, _c, _d;
61
61
  const v = path.v;
@@ -485,7 +485,7 @@ var PixodeskAnimator = (() => {
485
485
  return cubicBezier(flipped);
486
486
  }
487
487
 
488
- // ../svg-animator-core/src/PxScrollMath.ts
488
+ // ../svg-animator-core/src/playback/PxScrollMath.ts
489
489
  function isScrollTimeline(config) {
490
490
  return (config == null ? void 0 : config.timelineSource) === "scroll";
491
491
  }
@@ -541,23 +541,569 @@ var PixodeskAnimator = (() => {
541
541
  return vertical ? "x" : "y";
542
542
  }
543
543
 
544
- // ../svg-animator-core/src/PxAnimatorConstants.ts
545
- var PxAnimatorMode = {
544
+ // ../svg-animator-core/src/schema/PxSchema.ts
545
+ var PX_UNKNOWN_KEY_ERROR = "unexpected extra key";
546
+ function pathStr(path) {
547
+ if (!path.length) return ".";
548
+ let result = "";
549
+ for (const seg of path) {
550
+ if (seg.startsWith("[")) result += seg;
551
+ else result += (result ? "." : "") + seg;
552
+ }
553
+ return result;
554
+ }
555
+ var Base = class {
556
+ _canSanitize(raw) {
557
+ return this.isValid(raw);
558
+ }
559
+ optional() {
560
+ return new Optional(this);
561
+ }
562
+ };
563
+ var Optional = class extends Base {
564
+ constructor(inner) {
565
+ super();
566
+ this.inner = inner;
567
+ this._default = void 0;
568
+ }
569
+ sanitize(raw) {
570
+ if (raw === void 0 || raw === null) return void 0;
571
+ return this.inner._canSanitize(raw) ? this.inner.sanitize(raw) : void 0;
572
+ }
573
+ isValid(raw, ctx, path) {
574
+ if (raw === void 0 || raw === null) return true;
575
+ return this.inner.isValid(raw, ctx, path);
576
+ }
577
+ _canSanitize(raw) {
578
+ return raw === void 0 || raw === null || this.inner._canSanitize(raw);
579
+ }
580
+ };
581
+ var Str = class extends Base {
582
+ constructor(_default = "") {
583
+ super();
584
+ this._default = _default;
585
+ }
586
+ sanitize(raw) {
587
+ return typeof raw === "string" ? raw : this._default;
588
+ }
589
+ isValid(raw, ctx, path) {
590
+ if (typeof raw === "string") return true;
591
+ ctx == null ? void 0 : ctx.errors.push(pathStr(path != null ? path : []) + ": expected string, got " + typeof raw);
592
+ return false;
593
+ }
594
+ };
595
+ var Num = class extends Base {
596
+ constructor(_default = 0) {
597
+ super();
598
+ this._default = _default;
599
+ }
600
+ sanitize(raw) {
601
+ return typeof raw === "number" && isFinite(raw) ? raw : this._default;
602
+ }
603
+ isValid(raw, ctx, path) {
604
+ if (typeof raw === "number" && isFinite(raw)) return true;
605
+ ctx == null ? void 0 : ctx.errors.push(pathStr(path != null ? path : []) + ": expected finite number, got " + JSON.stringify(raw));
606
+ return false;
607
+ }
608
+ };
609
+ var Bool = class extends Base {
610
+ constructor(_default = false) {
611
+ super();
612
+ this._default = _default;
613
+ }
614
+ sanitize(raw) {
615
+ return typeof raw === "boolean" ? raw : this._default;
616
+ }
617
+ isValid(raw, ctx, path) {
618
+ if (typeof raw === "boolean") return true;
619
+ ctx == null ? void 0 : ctx.errors.push(pathStr(path != null ? path : []) + ": expected boolean, got " + typeof raw);
620
+ return false;
621
+ }
622
+ };
623
+ var Literal = class extends Base {
624
+ constructor(value) {
625
+ super();
626
+ this.value = value;
627
+ this._default = value;
628
+ }
629
+ sanitize(raw) {
630
+ return raw === this.value ? this.value : this._default;
631
+ }
632
+ isValid(raw, ctx, path) {
633
+ if (raw === this.value) return true;
634
+ ctx == null ? void 0 : ctx.errors.push(pathStr(path != null ? path : []) + ": expected " + JSON.stringify(this.value) + ", got " + JSON.stringify(raw));
635
+ return false;
636
+ }
637
+ };
638
+ var Enum = class extends Base {
639
+ constructor(values, defaultVal) {
640
+ super();
641
+ this.values = values;
642
+ this._default = defaultVal != null ? defaultVal : values[0];
643
+ }
644
+ sanitize(raw) {
645
+ return this.values.includes(raw) ? raw : this._default;
646
+ }
647
+ isValid(raw, ctx, path) {
648
+ if (this.values.includes(raw)) return true;
649
+ 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));
650
+ return false;
651
+ }
652
+ };
653
+ var Union = class extends Base {
654
+ constructor(schemas, defaultVal) {
655
+ super();
656
+ this.schemas = schemas;
657
+ /** Structural tag read by {@link describeSchema} — `schemas` alone cannot tell Union from Tuple. */
658
+ this._kind = "union";
659
+ this._default = defaultVal != null ? defaultVal : schemas[0]._default;
660
+ }
661
+ sanitize(raw) {
662
+ for (const s of this.schemas) {
663
+ if (s.isValid(raw)) return s.sanitize(raw);
664
+ }
665
+ return this._default;
666
+ }
667
+ isValid(raw, ctx, path) {
668
+ var _a;
669
+ const probe = ctx && { errors: [], warnings: [], strict: ctx.strict };
670
+ if (this.schemas.some((s) => s.isValid(raw, probe, path ? [...path] : void 0))) return true;
671
+ ctx == null ? void 0 : ctx.errors.push(pathStr(path != null ? path : []) + ": no union member matched for value " + ((_a = JSON.stringify(raw)) != null ? _a : "").slice(0, 240));
672
+ return false;
673
+ }
674
+ _canSanitize(raw) {
675
+ return this.schemas.some((s) => s._canSanitize(raw));
676
+ }
677
+ };
678
+ var DiscriminatedUnion = class extends Base {
679
+ constructor(_key, _schemas, defaultVal) {
680
+ var _a;
681
+ super();
682
+ this._key = _key;
683
+ this._schemas = _schemas;
684
+ /** Structural tag read by {@link describeSchema}. */
685
+ this._kind = "discriminatedUnion";
686
+ this._default = defaultVal != null ? defaultVal : _schemas[0]._default;
687
+ this._map = /* @__PURE__ */ new Map();
688
+ for (const s of _schemas) {
689
+ const keySchema = s._shape[_key];
690
+ if (!keySchema) continue;
691
+ const literal = (_a = keySchema.inner) != null ? _a : keySchema;
692
+ this._map.set(literal._default, s);
693
+ if (keySchema.inner) this._absentMember = s;
694
+ }
695
+ }
696
+ _findSchema(raw) {
697
+ if (raw === null || typeof raw !== "object" || Array.isArray(raw)) return void 0;
698
+ const val = raw[this._key];
699
+ if (val === void 0 || val === null) return this._absentMember;
700
+ return this._map.get(val);
701
+ }
702
+ sanitize(raw) {
703
+ var _a;
704
+ return ((_a = this._findSchema(raw)) != null ? _a : this._schemas[0]).sanitize(raw);
705
+ }
706
+ isValid(raw, ctx, path) {
707
+ const schema = this._findSchema(raw);
708
+ if (!schema) {
709
+ const val = raw !== null && typeof raw === "object" && !Array.isArray(raw) ? raw[this._key] : void 0;
710
+ ctx == null ? void 0 : ctx.errors.push(pathStr(path != null ? path : []) + ": no discriminated union member matched " + this._key + "=" + JSON.stringify(val));
711
+ return false;
712
+ }
713
+ return schema.isValid(raw, ctx, path);
714
+ }
715
+ _canSanitize(raw) {
716
+ if (raw === null || typeof raw !== "object" || Array.isArray(raw)) return false;
717
+ const schema = this._findSchema(raw);
718
+ return schema ? schema._canSanitize(raw) : this._schemas[0]._canSanitize(raw);
719
+ }
720
+ };
721
+ var Obj = class extends Base {
722
+ constructor(_shape) {
723
+ super();
724
+ this._shape = _shape;
725
+ const d = {};
726
+ for (const key of Object.keys(_shape)) d[key] = _shape[key]._default;
727
+ this._default = d;
728
+ }
729
+ sanitize(raw) {
730
+ const src = raw && typeof raw === "object" && !Array.isArray(raw) ? raw : {};
731
+ const out = {};
732
+ for (const key of Object.keys(this._shape)) {
733
+ const v = this._shape[key].sanitize(src[key]);
734
+ if (v !== void 0) out[key] = v;
735
+ }
736
+ return out;
737
+ }
738
+ isValid(raw, ctx, path) {
739
+ if (!raw || typeof raw !== "object" || Array.isArray(raw)) {
740
+ ctx == null ? void 0 : ctx.errors.push(pathStr(path != null ? path : []) + ": expected object, got " + (Array.isArray(raw) ? "array" : typeof raw));
741
+ return false;
742
+ }
743
+ const obj = raw;
744
+ const p = path != null ? path : [];
745
+ let ok = true;
746
+ for (const key of Object.keys(this._shape)) {
747
+ p.push(key);
748
+ if (!this._shape[key].isValid(obj[key], ctx, p)) ok = false;
749
+ p.pop();
750
+ }
751
+ if (ctx == null ? void 0 : ctx.strict) {
752
+ for (const key of Object.keys(obj)) {
753
+ if (key in this._shape) continue;
754
+ if (obj[key] === void 0) continue;
755
+ p.push(key);
756
+ ctx.errors.push(pathStr(p) + ": " + PX_UNKNOWN_KEY_ERROR);
757
+ p.pop();
758
+ ok = false;
759
+ }
760
+ }
761
+ return ok;
762
+ }
763
+ _canSanitize(raw) {
764
+ return !!raw && typeof raw === "object" && !Array.isArray(raw);
765
+ }
766
+ };
767
+ var OpenObj = class extends Base {
768
+ constructor(_shape, _openSchema) {
769
+ super();
770
+ this._shape = _shape;
771
+ this._openSchema = _openSchema;
772
+ const d = {};
773
+ for (const key of Object.keys(_shape)) d[key] = _shape[key]._default;
774
+ this._default = d;
775
+ }
776
+ sanitize(raw) {
777
+ const src = raw && typeof raw === "object" && !Array.isArray(raw) ? raw : {};
778
+ const out = __spreadValues({}, src);
779
+ for (const key of Object.keys(this._shape)) {
780
+ const v = this._shape[key].sanitize(src[key]);
781
+ if (v !== void 0) out[key] = v;
782
+ }
783
+ if (this._openSchema) {
784
+ for (const key of Object.keys(src)) {
785
+ if (!(key in this._shape)) out[key] = this._openSchema.sanitize(src[key]);
786
+ }
787
+ }
788
+ return out;
789
+ }
790
+ isValid(raw, ctx, path) {
791
+ if (!raw || typeof raw !== "object" || Array.isArray(raw)) {
792
+ ctx == null ? void 0 : ctx.errors.push(pathStr(path != null ? path : []) + ": expected object, got " + (Array.isArray(raw) ? "array" : typeof raw));
793
+ return false;
794
+ }
795
+ const obj = raw;
796
+ const p = path != null ? path : [];
797
+ let ok = true;
798
+ for (const key of Object.keys(this._shape)) {
799
+ p.push(key);
800
+ if (!this._shape[key].isValid(obj[key], ctx, p)) ok = false;
801
+ p.pop();
802
+ }
803
+ if (this._openSchema) {
804
+ for (const key of Object.keys(obj)) {
805
+ if (key in this._shape) continue;
806
+ p.push(key);
807
+ if (!this._openSchema.isValid(obj[key], ctx, p)) ok = false;
808
+ p.pop();
809
+ }
810
+ }
811
+ return ok;
812
+ }
813
+ _canSanitize(raw) {
814
+ return !!raw && typeof raw === "object" && !Array.isArray(raw);
815
+ }
816
+ };
817
+ var Arr = class extends Base {
818
+ constructor(item) {
819
+ super();
820
+ this.item = item;
821
+ this._default = [];
822
+ }
823
+ sanitize(raw) {
824
+ if (!Array.isArray(raw)) return [];
825
+ const out = [];
826
+ for (const el of raw) {
827
+ if (this.item._canSanitize(el)) out.push(this.item.sanitize(el));
828
+ }
829
+ return out;
830
+ }
831
+ isValid(raw, ctx, path) {
832
+ if (!Array.isArray(raw)) {
833
+ ctx == null ? void 0 : ctx.errors.push(pathStr(path != null ? path : []) + ": expected array, got " + typeof raw);
834
+ return false;
835
+ }
836
+ const p = path != null ? path : [];
837
+ let ok = true;
838
+ for (let i = 0; i < raw.length; i++) {
839
+ p.push("[" + i + "]");
840
+ if (!this.item.isValid(raw[i], ctx, p)) ok = false;
841
+ p.pop();
842
+ }
843
+ return ok;
844
+ }
845
+ _canSanitize(raw) {
846
+ return Array.isArray(raw);
847
+ }
848
+ };
849
+ var Rec = class extends Base {
850
+ constructor(value) {
851
+ super();
852
+ this.value = value;
853
+ /** Structural tag read by {@link describeSchema}. */
854
+ this._kind = "record";
855
+ this._default = {};
856
+ }
857
+ sanitize(raw) {
858
+ if (!raw || typeof raw !== "object" || Array.isArray(raw)) return {};
859
+ const out = {};
860
+ for (const [k, v] of Object.entries(raw)) {
861
+ if (this.value._canSanitize(v)) out[k] = this.value.sanitize(v);
862
+ }
863
+ return out;
864
+ }
865
+ isValid(raw, ctx, path) {
866
+ if (!raw || typeof raw !== "object" || Array.isArray(raw)) {
867
+ ctx == null ? void 0 : ctx.errors.push(pathStr(path != null ? path : []) + ": expected object/record, got " + (Array.isArray(raw) ? "array" : typeof raw));
868
+ return false;
869
+ }
870
+ const p = path != null ? path : [];
871
+ let ok = true;
872
+ for (const [k, v] of Object.entries(raw)) {
873
+ p.push(k);
874
+ if (!this.value.isValid(v, ctx, p)) ok = false;
875
+ p.pop();
876
+ }
877
+ return ok;
878
+ }
879
+ _canSanitize(raw) {
880
+ return !!raw && typeof raw === "object" && !Array.isArray(raw);
881
+ }
882
+ };
883
+ var Any = class extends Base {
884
+ constructor() {
885
+ super(...arguments);
886
+ this._default = void 0;
887
+ }
888
+ sanitize(raw) {
889
+ return raw;
890
+ }
891
+ isValid(_raw, _ctx, _path) {
892
+ return true;
893
+ }
894
+ _canSanitize(_raw) {
895
+ return true;
896
+ }
897
+ };
898
+ var Defined = class extends Base {
899
+ constructor() {
900
+ super(...arguments);
901
+ this._default = void 0;
902
+ }
903
+ sanitize(raw) {
904
+ return raw;
905
+ }
906
+ isValid(raw, ctx, path) {
907
+ if (raw !== void 0) return true;
908
+ ctx == null ? void 0 : ctx.errors.push(pathStr(path != null ? path : []) + ": required value is missing");
909
+ return false;
910
+ }
911
+ _canSanitize(raw) {
912
+ return raw !== void 0;
913
+ }
914
+ };
915
+ var Lazy = class extends Base {
916
+ constructor(fn, _default) {
917
+ super();
918
+ this.fn = fn;
919
+ this._default = _default;
920
+ this.resolved = null;
921
+ }
922
+ get schema() {
923
+ var _a;
924
+ return (_a = this.resolved) != null ? _a : this.resolved = this.fn();
925
+ }
926
+ sanitize(raw) {
927
+ return this.schema.sanitize(raw);
928
+ }
929
+ isValid(raw, ctx, path) {
930
+ return this.schema.isValid(raw, ctx, path);
931
+ }
932
+ _canSanitize(raw) {
933
+ return this.schema._canSanitize(raw);
934
+ }
935
+ };
936
+ var Tuple = class extends Base {
937
+ constructor(schemas) {
938
+ super();
939
+ this.schemas = schemas;
940
+ /** Structural tag read by {@link describeSchema} — `schemas` alone cannot tell Tuple from Union. */
941
+ this._kind = "tuple";
942
+ this._default = schemas.map((s) => s._default);
943
+ }
944
+ sanitize(raw) {
945
+ if (!Array.isArray(raw) || raw.length !== this.schemas.length) return this._default;
946
+ return this.schemas.map((s, i) => s.sanitize(raw[i]));
947
+ }
948
+ isValid(raw, ctx, path) {
949
+ if (!Array.isArray(raw) || raw.length !== this.schemas.length) {
950
+ 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));
951
+ return false;
952
+ }
953
+ const p = path != null ? path : [];
954
+ let ok = true;
955
+ for (let i = 0; i < this.schemas.length; i++) {
956
+ p.push("[" + i + "]");
957
+ if (!this.schemas[i].isValid(raw[i], ctx, p)) ok = false;
958
+ p.pop();
959
+ }
960
+ return ok;
961
+ }
962
+ // Require exact length so wrong-length arrays are dropped rather than repaired to default.
963
+ _canSanitize(raw) {
964
+ return Array.isArray(raw) && raw.length === this.schemas.length;
965
+ }
966
+ };
967
+ function implementsInterface() {
968
+ return (schema) => schema;
969
+ }
970
+ var px = {
971
+ /** Matches a string. Default: '' or provided value. */
972
+ string: (defaultVal = "") => new Str(defaultVal),
973
+ /** Matches a finite number. Default: 0 or provided value. */
974
+ number: (defaultVal = 0) => new Num(defaultVal),
975
+ /** Matches a boolean. Default: false or provided value. */
976
+ boolean: (defaultVal = false) => new Bool(defaultVal),
977
+ /** Matches one exact primitive value; its default is the value itself. */
978
+ literal: (value) => new Literal(value),
979
+ /** Matches one of a fixed set of string/number values. Default: first value. */
980
+ enum: (values, defaultVal) => new Enum(values, defaultVal),
981
+ /**
982
+ * Returns the first schema whose isValid passes.
983
+ * TypeScript infers the union of all member types automatically.
984
+ */
985
+ union: (schemas, defaultVal) => new Union(schemas, defaultVal),
986
+ /**
987
+ * Discriminated union — reads `raw[key]`, finds the member schema whose
988
+ * literal at `key` matches, then delegates sanitize/isValid to that member.
989
+ * Each member must be an object schema with a `px.literal(...)` at `key`.
990
+ * TypeScript infers the union of all member types automatically.
991
+ */
992
+ discriminatedUnion: (key, schemas) => new DiscriminatedUnion(key, schemas),
993
+ /** Typed object — unknown keys are stripped. Required fields fall back to their default. */
994
+ object: (shape) => new Obj(shape),
995
+ /**
996
+ * Open object — validates known keys; passes unknown keys through as-is,
997
+ * or validates/sanitizes them against `openSchema` when provided.
998
+ */
999
+ openObject: (shape, openSchema) => new OpenObj(shape, openSchema),
1000
+ /**
1001
+ * Creates a new closed object schema by merging a base schema's shape with additional fields.
1002
+ * The base can be the result of px.object() or px.openObject() — anything with a _shape property.
1003
+ *
1004
+ * @example
1005
+ * const PxSvgNodeSchema = px.extendedObject(PxNodeBase, { width: px.number().optional() });
1006
+ */
1007
+ extendedObject: (base, extra) => new Obj(__spreadValues(__spreadValues({}, base._shape), extra)),
1008
+ /** Array whose unrecoverable items are filtered out. Default: []. */
1009
+ array: (item) => new Arr(item),
1010
+ /** String-keyed record whose unrecoverable values are dropped. Default: {}. */
1011
+ record: (value) => new Rec(value),
1012
+ /** Passes anything through unchanged — always valid. */
1013
+ any: () => new Any(),
1014
+ /** Anything EXCEPT `undefined` — an open type whose presence is required (V6). */
1015
+ defined: () => new Defined(),
1016
+ /** Fixed-length tuple — validates element count and each position individually. */
1017
+ tuple: (schemas) => new Tuple(schemas),
1018
+ /** Defers schema creation — required for recursive types. Must supply a default value. */
1019
+ lazy: (fn, defaultVal) => new Lazy(fn, defaultVal)
1020
+ };
1021
+
1022
+ // ../svg-animator-core/src/format/PxAnimatorConstants.ts
1023
+ var PxTimelineEngine = {
1024
+ native: "native",
1025
+ js: "js"
1026
+ };
1027
+ var PxTimelineEngineExtra = __spreadProps(__spreadValues({}, PxTimelineEngine), {
1028
+ auto: "auto"
1029
+ });
1030
+ function isNativeForced(engine) {
1031
+ return engine === PxTimelineEngineExtra.native;
1032
+ }
1033
+ function mayUseNativeScrollTimeline(engine) {
1034
+ return engine !== PxTimelineEngineExtra.js;
1035
+ }
1036
+ var PxLoopRepeatAt = {
1037
+ /** Segment from the START; the repetition runs BEFORE the first keyframe
1038
+ * (intro loops that play until the main timeline begins). */
1039
+ start: "start",
1040
+ /** DEFAULT — segment from the END; the repetition runs AFTER the last keyframe
1041
+ * (idle/outro loops that continue once the main timeline has finished). */
1042
+ end: "end"
1043
+ };
1044
+ var PxLoopDirection = {
1045
+ /** DEFAULT — cycle: every repetition replays the segment the same way round. */
1046
+ normal: "normal",
1047
+ /** Ping-pong: repetitions alternate forward / backward. */
1048
+ alternate: "alternate"
1049
+ };
1050
+ var PxMaskType = {
1051
+ luminance: "luminance",
1052
+ alpha: "alpha"
1053
+ };
1054
+ var PxUnits = {
1055
+ userSpaceOnUse: "userSpaceOnUse",
1056
+ objectBoundingBox: "objectBoundingBox"
1057
+ };
1058
+ var PxCloneWithout = {
1059
+ translate: "translate"
1060
+ // transform: 'transform', // future: drop rotate/scale too (content only)
1061
+ };
1062
+ var PxPathOverflow = {
1063
+ clip: "clip",
1064
+ extend: "extend"
1065
+ };
1066
+ var PxLengthAdjust = {
1067
+ spacing: "spacing",
1068
+ spacingAndGlyphs: "spacingAndGlyphs"
1069
+ };
1070
+ var PxTextPathMethod = {
1071
+ align: "align",
1072
+ stretch: "stretch"
1073
+ };
1074
+ var PxTextPathSpacing = {
546
1075
  auto: "auto",
547
- waapi: "waapi",
548
- frames: "frames"
1076
+ exact: "exact"
1077
+ };
1078
+ var PxStrokeTrimSubPaths = {
1079
+ separate: "separate",
1080
+ combined: "combined"
1081
+ };
1082
+ var TRANSFORM_ATTR = "transform";
1083
+ var TRANSFORM_PART = {
1084
+ translate: "translate",
1085
+ rotate: "rotate",
1086
+ scale: "scale",
1087
+ origin: "origin"
549
1088
  };
550
- var PxAnimatorEngine = {
551
- waapi: PxAnimatorMode.waapi,
552
- frames: PxAnimatorMode.frames
1089
+ var PX_TRANSFORM_PART_KEYS = [
1090
+ TRANSFORM_PART.translate,
1091
+ TRANSFORM_PART.rotate,
1092
+ TRANSFORM_PART.scale,
1093
+ TRANSFORM_PART.origin
1094
+ ];
1095
+ var PxGradientUnits = {
1096
+ userSpaceOnUse: "userSpaceOnUse",
1097
+ objectBoundingBox: "objectBoundingBox"
553
1098
  };
554
- var PxLoopExtend = {
555
- /** Segment from the START; the animation is extended BEFORE the first keyframe
556
- * (intro loops that run before the main timeline begins). */
557
- before: "before",
558
- /** DEFAULT — segment from the END; extended AFTER the last keyframe (idle/outro
559
- * loops that continue once the main timeline has finished). */
560
- after: "after"
1099
+ var PxGradientSpreadMethod = {
1100
+ pad: "pad",
1101
+ reflect: "reflect",
1102
+ repeat: "repeat"
1103
+ };
1104
+ var PxGradientType = {
1105
+ linear: "linear",
1106
+ radial: "radial"
561
1107
  };
562
1108
  function getAnimatorConfig(doc) {
563
1109
  var _a;
@@ -571,13 +1117,14 @@ var PixodeskAnimator = (() => {
571
1117
  const memoised = flattenMemo.get(cfg);
572
1118
  if (memoised) return memoised;
573
1119
  const _a = cfg, { timeline: _dropped } = _a, flat = __objRest(_a, ["timeline"]);
1120
+ if (timeline.engine !== void 0) flat.engine = timeline.engine;
1121
+ if (timeline.frameRate !== void 0) flat.frameRate = timeline.frameRate;
574
1122
  if (timeline.type === "scroll" || timeline.type === "view") {
575
1123
  flat.timelineSource = "scroll";
576
1124
  if (timeline.duration !== void 0) flat.duration = timeline.duration;
577
1125
  if (timeline.iterations !== void 0) flat.iterations = timeline.iterations;
578
1126
  const scroll = __spreadValues({}, flat.scroll || {});
579
1127
  scroll.kind = timeline.type;
580
- if (timeline.engine !== void 0) scroll.driver = timeline.engine;
581
1128
  if (timeline.axis !== void 0) scroll.axis = timeline.axis;
582
1129
  if (timeline.source !== void 0) scroll.source = timeline.source;
583
1130
  if (timeline.subject !== void 0) scroll.subject = timeline.subject;
@@ -595,14 +1142,14 @@ var PixodeskAnimator = (() => {
595
1142
  } else {
596
1143
  if (timeline.duration !== void 0) flat.duration = timeline.duration;
597
1144
  if (timeline.trigger !== void 0) {
598
- const _b = timeline.trigger, { onFinish } = _b, restTrigger = __objRest(_b, ["onFinish"]);
1145
+ const _b = timeline.trigger, { finishAction } = _b, restTrigger = __objRest(_b, ["finishAction"]);
599
1146
  if (Object.keys(restTrigger).length) flat.trigger = restTrigger;
600
- if (onFinish !== void 0) flat.resetOnFinish = onFinish === "reset";
1147
+ if (finishAction !== void 0) flat.resetOnFinish = finishAction === "reset";
601
1148
  }
602
1149
  if (timeline.delay !== void 0) flat.delay = timeline.delay;
603
1150
  if (timeline.iterations !== void 0) flat.iterations = timeline.iterations;
604
1151
  if (timeline.direction !== void 0) flat.direction = timeline.direction;
605
- if (timeline.fill !== void 0) flat.fill = timeline.fill;
1152
+ if (timeline.fillMode !== void 0) flat.fill = timeline.fillMode;
606
1153
  }
607
1154
  flattenMemo.set(cfg, flat);
608
1155
  return flat;
@@ -620,10 +1167,376 @@ var PixodeskAnimator = (() => {
620
1167
  return Object.entries(animateById).map(([id, anim]) => ({ id: id.startsWith("#") ? id.slice(1) : id, animate: anim }));
621
1168
  }
622
1169
 
623
- // ../svg-animator-core/src/PxMotionPath.ts
624
- function getKfTranslate(kf) {
1170
+ // ../svg-animator-core/src/format/PxAnimatorTypes.ts
1171
+ var PxEasingOrRefSchema = px.union([
1172
+ px.string(),
1173
+ px.tuple([px.number(), px.number(), px.number(), px.number()])
1174
+ ]);
1175
+ var PxKeyframeValueSchema = implementsInterface()(px.union([
1176
+ px.string(),
1177
+ // e.g. for colors
1178
+ px.number(),
1179
+ px.array(px.number()),
1180
+ // ORDER LAW: the key-discriminated object shapes (`{path}`, `{paths}`) come BEFORE the
1181
+ // all-optional transform-parts record. In default (non-strict) mode that record accepts
1182
+ // ANY object (every key optional, unknown keys ignored), so listing it earlier made
1183
+ // Union.sanitize route `{path}`/`{paths}` values into it and strip them to `{}` —
1184
+ // silent morph-data loss (repro: the editor's keyframeValueSanitize spec). Validity is
1185
+ // order-independent (`some()`); only sanitize routing depends on this order.
1186
+ px.object({ path: px.string() }),
1187
+ px.lazy(() => px.object({ paths: px.array(PxBezierPathSchema) }), { paths: [] }),
1188
+ // Gradient `stops` timeline — each kf value is the full stops-array snapshot.
1189
+ px.lazy(() => px.array(PxGradientStopSchema), []),
1190
+ px.lazy(() => PxTransformPartsSchema, {})
1191
+ ]));
1192
+ var PxKeyframeSchema = implementsInterface()(px.object({
1193
+ time: px.number().optional(),
1194
+ value: PxKeyframeValueSchema.optional(),
1195
+ easing: PxEasingOrRefSchema.optional(),
1196
+ tangentOut: px.tuple([px.number(), px.number()]).optional(),
1197
+ tangentIn: px.tuple([px.number(), px.number()]).optional()
1198
+ // (`selected` — editor timeline-selection UI state — was REMOVED from the wire
1199
+ // (review §1.3): editor data lives under `meta`. The editor still carries it on
1200
+ // its internal COPY-PASTE payload, which never validates against this schema.)
1201
+ }));
1202
+ var anyKf = (kf) => kf;
1203
+ var kfTime = (kf) => {
1204
+ var _a, _b;
1205
+ return (_b = (_a = anyKf(kf).time) != null ? _a : anyKf(kf).t) != null ? _b : 0;
1206
+ };
1207
+ var kfValue = (kf) => {
625
1208
  var _a;
626
- const v = (_a = kf.value) != null ? _a : kf.v;
1209
+ return (_a = anyKf(kf).value) != null ? _a : anyKf(kf).v;
1210
+ };
1211
+ var kfEasing = (kf) => {
1212
+ var _a;
1213
+ return (_a = anyKf(kf).easing) != null ? _a : anyKf(kf).e;
1214
+ };
1215
+ var kfTangentIn = (kf) => anyKf(kf).tangentIn;
1216
+ var kfTangentOut = (kf) => anyKf(kf).tangentOut;
1217
+ var PxLoopSchema = implementsInterface()(px.object({
1218
+ segmentCount: px.number().optional(),
1219
+ repeatAt: px.enum([PxLoopRepeatAt.start, PxLoopRepeatAt.end]).optional(),
1220
+ direction: px.enum([PxLoopDirection.normal, PxLoopDirection.alternate]).optional()
1221
+ }));
1222
+ var PxPropertyAnimationSchema = implementsInterface()(px.object({
1223
+ value: PxKeyframeValueSchema.optional(),
1224
+ keyframes: px.array(PxKeyframeSchema).optional(),
1225
+ loop: px.union([PxLoopSchema, px.boolean()]).optional(),
1226
+ autoOrient: px.boolean().optional(),
1227
+ alongPathMode: px.enum(["sampled", "offsetPath"]).optional()
1228
+ }));
1229
+ var PxTransformPartsSchema = implementsInterface()(px.object({
1230
+ translate: px.tuple([px.number(), px.number()]).optional(),
1231
+ rotate: px.number().optional(),
1232
+ skew: px.number().optional(),
1233
+ scale: px.tuple([px.number(), px.number()]).optional(),
1234
+ origin: px.tuple([px.number(), px.number()]).optional()
1235
+ }));
1236
+ var PxTransformValueSchema = px.union([
1237
+ px.string(),
1238
+ PxTransformPartsSchema,
1239
+ px.object({ value: PxTransformPartsSchema }),
1240
+ PxPropertyAnimationSchema
1241
+ ]);
1242
+ var PxAnimationDefinitionSchema = implementsInterface()(
1243
+ px.record(PxPropertyAnimationSchema)
1244
+ );
1245
+ var PxElementAnimationSchema = implementsInterface()(px.union([
1246
+ px.string(),
1247
+ px.array(px.union([px.string(), PxAnimationDefinitionSchema])),
1248
+ PxAnimationDefinitionSchema
1249
+ ]));
1250
+ var PxTriggerSchema = implementsInterface()(px.object({
1251
+ startOn: px.enum(["load", "mouseOver", "click", "scrollIntoView", "programmatic"]).optional(),
1252
+ outAction: px.enum(["continue", "pause", "reset", "reverse"]).optional(),
1253
+ // What happens after a NATURAL finish — `'hold'` (default: keep the end state per
1254
+ // `fill`) or `'reset'` (snap back to the start state). Pairs with `outAction` ("what
1255
+ // happens when the trigger condition ends"); both end-of-life knobs now read alike.
1256
+ finishAction: px.enum(["hold", "reset"]).optional(),
1257
+ scrollIntoViewThreshold: px.number().optional()
1258
+ }));
1259
+ var PxGlyphSchema = implementsInterface()(px.object({
1260
+ width: px.number(),
1261
+ d: px.string()
1262
+ }));
1263
+ var PxGlyphFontSchema = implementsInterface()(px.object({
1264
+ fontFamily: px.string(),
1265
+ fontStyle: px.string(),
1266
+ ascent: px.number(),
1267
+ unitsPerEm: px.number(),
1268
+ glyphs: px.record(PxGlyphSchema)
1269
+ }));
1270
+ var PxDefsSchema = implementsInterface()(px.object({
1271
+ easings: px.record(px.tuple([px.number(), px.number(), px.number(), px.number()])).optional(),
1272
+ animations: px.record(PxAnimationDefinitionSchema).optional(),
1273
+ // Review §2.6: the schema now matches the declared type — a style preset is a flat
1274
+ // record of string|number attribute values, nothing nested.
1275
+ styles: px.record(px.record(px.union([px.string(), px.number()]))).optional(),
1276
+ fonts: px.record(PxGlyphFontSchema).optional()
1277
+ }));
1278
+ var PX_SCROLL_PHASES = ["cover", "contain", "entry", "exit", "entry-crossing", "exit-crossing"];
1279
+ var PxScrollRangePointSchema = implementsInterface()(px.object({
1280
+ phase: px.enum(PX_SCROLL_PHASES).optional(),
1281
+ fraction: px.number().optional()
1282
+ }));
1283
+ var PxScrollRangeSchema = px.object({
1284
+ start: PxScrollRangePointSchema.optional(),
1285
+ end: PxScrollRangePointSchema.optional()
1286
+ });
1287
+ var PxScrollSchema = implementsInterface()(px.object({
1288
+ kind: px.enum(["view", "scroll"]).optional(),
1289
+ axis: px.enum(["block", "inline", "x", "y"]).optional(),
1290
+ source: px.enum(["nearest", "root"]).optional(),
1291
+ // Free-form: the two keywords `parent`/`scroller` plus any CSS selector.
1292
+ subject: px.string().optional(),
1293
+ smoothing: px.number().optional(),
1294
+ pin: px.boolean().optional(),
1295
+ pinAlign: px.enum(["top", "center", "bottom"]).optional(),
1296
+ pinTop: px.number().optional(),
1297
+ pinDistance: px.number().optional(),
1298
+ range: PxScrollRangeSchema.optional()
1299
+ }));
1300
+ var PxTimelinePinSchema = implementsInterface()(px.object({
1301
+ align: px.enum(["top", "center", "bottom"]).optional(),
1302
+ top: px.number().optional(),
1303
+ distance: px.number().optional()
1304
+ }));
1305
+ var PxTimelineEngineSchema = px.enum([PxTimelineEngineExtra.auto, PxTimelineEngineExtra.native, PxTimelineEngineExtra.js]).optional();
1306
+ var PxTimeTimelineSchema = implementsInterface()(px.object({
1307
+ type: px.literal("time").optional(),
1308
+ engine: PxTimelineEngineSchema,
1309
+ frameRate: px.number().optional(),
1310
+ // §2.8: duration is a property of the TIMELINE — how long one pass takes.
1311
+ duration: px.number().optional(),
1312
+ trigger: PxTriggerSchema.optional(),
1313
+ delay: px.number().optional(),
1314
+ iterations: px.union([px.number(), px.literal("infinite")]).optional(),
1315
+ // `fillMode` on the wire (CSS `animation-fill-mode`; the runtime view calls it `fill`)
1316
+ // — never `fill`, which is paint everywhere else in the format.
1317
+ fillMode: px.enum(["forwards", "backwards", "both", "none"]).optional(),
1318
+ direction: px.enum(["normal", "reverse", "alternate", "alternate-reverse"]).optional()
1319
+ }));
1320
+ var scrollishTimelineShape = {
1321
+ // §2.8: duration is a property of the TIMELINE — under scrubbing it is the keyframe
1322
+ // span the scroll range maps onto.
1323
+ duration: px.number().optional(),
1324
+ // Finite repeat count IS meaningful when scrubbing — the scroll range maps onto
1325
+ // duration × iterations (rule D4; `'infinite'` cannot map to a range, so no literal here).
1326
+ iterations: px.number().optional(),
1327
+ engine: PxTimelineEngineSchema,
1328
+ frameRate: px.number().optional(),
1329
+ axis: px.enum(["block", "inline", "x", "y"]).optional(),
1330
+ source: px.enum(["nearest", "root"]).optional(),
1331
+ subject: px.string().optional(),
1332
+ // 'parent' | 'scroller' | any CSS selector
1333
+ smoothing: px.number().optional(),
1334
+ // ms
1335
+ pin: px.union([px.boolean(), PxTimelinePinSchema]).optional(),
1336
+ range: PxScrollRangeSchema.optional()
1337
+ };
1338
+ var PxScrollTimelineSchema = implementsInterface()(
1339
+ px.object(__spreadValues({ type: px.literal("scroll") }, scrollishTimelineShape))
1340
+ );
1341
+ var PxViewTimelineSchema = implementsInterface()(
1342
+ px.object(__spreadValues({ type: px.literal("view") }, scrollishTimelineShape))
1343
+ );
1344
+ var PxTimelineSchema = px.discriminatedUnion("type", [
1345
+ PxTimeTimelineSchema,
1346
+ // first = the member an absent `type` selects
1347
+ PxScrollTimelineSchema,
1348
+ PxViewTimelineSchema
1349
+ ]);
1350
+ var PxAnimatorConfigSchema = implementsInterface()(px.object({
1351
+ // (`mode`, `duration` and `frameRate` live INSIDE `timeline` on the wire — §2.8; they exist
1352
+ // at this level only on the runtime view, like the rest of the playback dynamics.)
1353
+ // THE spelling of "what advances progress" — clock / scroll / view (review §2.1).
1354
+ timeline: PxTimelineSchema.optional(),
1355
+ definitions: PxDefsSchema.optional(),
1356
+ animateById: px.record(PxElementAnimationSchema).optional(),
1357
+ debugGlobalName: px.string().optional(),
1358
+ // Declared HERE because this is a closed object: an undeclared key would be stripped by
1359
+ // `sanitize` and flagged by strict validation on our own files.
1360
+ version: px.string().optional()
1361
+ }));
1362
+ var PxBindingSchema = implementsInterface()(px.object({
1363
+ id: px.string(),
1364
+ animate: PxElementAnimationSchema
1365
+ }));
1366
+ var PxAttrValueSchema = px.union([
1367
+ px.string(),
1368
+ px.number(),
1369
+ px.array(px.number()),
1370
+ // Structured static — `{value: …}` (read-accepted transitional spelling, S1).
1371
+ // `defined`, not `any`: the KEY's presence is what identifies this branch (V6).
1372
+ px.object({ value: px.defined() }),
1373
+ // Bare transform parts record — the canonical static `transform` on the wire (T2).
1374
+ PxTransformPartsSchema
1375
+ ]);
1376
+ var PxAnimatableNumberSchema = px.union([
1377
+ px.number(),
1378
+ PxPropertyAnimationSchema,
1379
+ px.object({ value: px.number() })
1380
+ ]);
1381
+ var PxAnimatableVec2Schema = px.union([
1382
+ px.tuple([px.number(), px.number()]),
1383
+ PxPropertyAnimationSchema,
1384
+ px.object({ value: px.tuple([px.number(), px.number()]) })
1385
+ ]);
1386
+ var PxAnimatableStringSchema = px.union([
1387
+ px.string(),
1388
+ PxPropertyAnimationSchema,
1389
+ px.object({ value: px.string() })
1390
+ ]);
1391
+ var PxTransformByEffectSchema = implementsInterface()(px.object({
1392
+ translate: PxAnimatableVec2Schema.optional(),
1393
+ rotate: PxAnimatableNumberSchema.optional(),
1394
+ scale: PxAnimatableVec2Schema.optional(),
1395
+ skew: PxAnimatableNumberSchema.optional(),
1396
+ origin: PxAnimatableVec2Schema.optional()
1397
+ }));
1398
+ var PxRepeaterEffectSchema = implementsInterface()(px.object({
1399
+ // STATIC config, not a channel (V2/SCHEMA-DESIGN R5): the copy COUNT is read
1400
+ // once at expansion time and never sampled — plain number, no `keyframes`.
1401
+ copies: px.number().optional(),
1402
+ translate: PxAnimatableVec2Schema.optional(),
1403
+ rotate: PxAnimatableNumberSchema.optional(),
1404
+ skew: PxAnimatableNumberSchema.optional(),
1405
+ scale: PxAnimatableVec2Schema.optional(),
1406
+ origin: PxAnimatableVec2Schema.optional()
1407
+ }));
1408
+ var PxMaskedByEffectSchema = implementsInterface()(px.object({
1409
+ source: px.string().optional(),
1410
+ maskType: px.enum([PxMaskType.luminance, PxMaskType.alpha]).optional(),
1411
+ maskUnits: px.enum([PxUnits.userSpaceOnUse, PxUnits.objectBoundingBox]).optional(),
1412
+ maskContentUnits: px.enum([PxUnits.userSpaceOnUse, PxUnits.objectBoundingBox]).optional(),
1413
+ x: px.number().optional(),
1414
+ y: px.number().optional(),
1415
+ width: px.number().optional(),
1416
+ height: px.number().optional()
1417
+ }));
1418
+ var PxClipPathEffectSchema = implementsInterface()(px.object({
1419
+ d: PxAnimatableStringSchema.optional()
1420
+ }));
1421
+ var PxStrokeTrimEffectSchema = implementsInterface()(px.object({
1422
+ offset: PxAnimatableNumberSchema.optional(),
1423
+ range: PxAnimatableVec2Schema.optional(),
1424
+ subPaths: px.enum([PxStrokeTrimSubPaths.separate, PxStrokeTrimSubPaths.combined]).optional()
1425
+ }));
1426
+ var PxRetimeEffectSchema = implementsInterface()(px.object({
1427
+ start: px.number().optional(),
1428
+ stretch: px.number().optional(),
1429
+ timeCrop: px.tuple([px.number(), px.number()]).optional()
1430
+ }));
1431
+ var PxCloneEffectSchema = implementsInterface()(px.object({
1432
+ // Subtractive on purpose: the `<use>` can only point at one wrapper layer of the
1433
+ // source, so the choices form a ladder — 'translate' now, maybe 'transform' later.
1434
+ without: px.enum([PxCloneWithout.translate]).optional(),
1435
+ source: px.string().optional(),
1436
+ retime: PxRetimeEffectSchema.optional()
1437
+ }));
1438
+ var PxGradientStopSchema = implementsInterface()(px.object({
1439
+ offset: px.number(),
1440
+ color: px.string()
1441
+ }));
1442
+ var PxAnimatableGradientStopsSchema = px.union([
1443
+ px.array(PxGradientStopSchema),
1444
+ px.object({ value: px.array(PxGradientStopSchema) }),
1445
+ PxPropertyAnimationSchema
1446
+ ]);
1447
+ var PxFillGradientEffectSchema = implementsInterface()(px.object({
1448
+ // Contextual kind — the `type` convention, see `PxNodeBase.type`.
1449
+ type: px.enum([PxGradientType.linear, PxGradientType.radial]),
1450
+ start: PxAnimatableVec2Schema.optional(),
1451
+ end: PxAnimatableVec2Schema.optional(),
1452
+ center: PxAnimatableVec2Schema.optional(),
1453
+ radius: PxAnimatableNumberSchema.optional(),
1454
+ focal: PxAnimatableVec2Schema.optional(),
1455
+ stops: PxAnimatableGradientStopsSchema.optional(),
1456
+ gradientUnits: px.enum([PxGradientUnits.userSpaceOnUse, PxGradientUnits.objectBoundingBox]).optional(),
1457
+ spreadMethod: px.enum([PxGradientSpreadMethod.pad, PxGradientSpreadMethod.reflect, PxGradientSpreadMethod.repeat]).optional(),
1458
+ gradientTransform: px.string().optional()
1459
+ }));
1460
+ var PxStrokeGradientEffectSchema = PxFillGradientEffectSchema;
1461
+ var PxTextPathEffectSchema = implementsInterface()(px.object({
1462
+ pathData: px.string(),
1463
+ pathOverflow: px.enum([PxPathOverflow.clip, PxPathOverflow.extend]).optional(),
1464
+ lengthAdjust: px.enum([PxLengthAdjust.spacing, PxLengthAdjust.spacingAndGlyphs]).optional(),
1465
+ method: px.enum([PxTextPathMethod.align, PxTextPathMethod.stretch]).optional(),
1466
+ spacing: px.enum([PxTextPathSpacing.auto, PxTextPathSpacing.exact]).optional(),
1467
+ startOffset: PxAnimatableNumberSchema.optional(),
1468
+ textLength: PxAnimatableNumberSchema.optional()
1469
+ }));
1470
+ var PxTextEffectSchema = implementsInterface()(px.object({
1471
+ useGlyphs: px.boolean().optional()
1472
+ }));
1473
+ var PxEffectsSchema = implementsInterface()(px.object({
1474
+ transformBy: PxTransformByEffectSchema.optional(),
1475
+ repeater: PxRepeaterEffectSchema.optional(),
1476
+ maskedBy: PxMaskedByEffectSchema.optional(),
1477
+ clipPath: PxClipPathEffectSchema.optional(),
1478
+ strokeTrim: PxStrokeTrimEffectSchema.optional(),
1479
+ clone: PxCloneEffectSchema.optional(),
1480
+ fillGradient: PxFillGradientEffectSchema.optional(),
1481
+ strokeGradient: PxStrokeGradientEffectSchema.optional(),
1482
+ textPath: PxTextPathEffectSchema.optional(),
1483
+ text: PxTextEffectSchema.optional()
1484
+ }));
1485
+ var PxNodeBase = px.openObject({
1486
+ // CONVENTION (SCHEMA-DESIGN R1 / issues N4): `type` is the ONE word for "what
1487
+ // kind of thing is this", discriminated by its CARRIER — here the node TAG
1488
+ // (`rect`, `text`), and inside a sub-object that object's kind (`fillGradient.type`,
1489
+ // `fillGradient.type`, editor `preset.type`). Each sits in its own object, so
1490
+ // the carrier disambiguates completely; synonyms (`cloneKind`, `presetShape`)
1491
+ // would add words that all mean "type" and still need the carrier to read.
1492
+ // Guarding a `type` SLOT against a wrong VALUE is the job of strict enums
1493
+ // (issues V3), never of distinct key names.
1494
+ type: px.string(),
1495
+ // The escape hatch for elements that carry a REAL `type` attribute — `<feTurbulence
1496
+ // type="fractalNoise">`, `<feFuncR type="table">`, `<feColorMatrix type="saturate">`.
1497
+ // `type` is taken by the tag name, so the attribute travels here and the renderer puts
1498
+ // it back (`PxAnimatorDOM.renderNode`, `PxRnRender`). Declared here — not merely
1499
+ // documented — because a wire key that is not in a schema is invisible to the
1500
+ // minifier's reserve list and gets renamed (MINIFICATION-BOUNDARY-PLAN.md §1.1).
1501
+ domType: px.string().optional(),
1502
+ id: px.string().optional(),
1503
+ meta: px.any().optional(),
1504
+ // Player-effects bucket emitted by the Editor's lightweight design format.
1505
+ // Consumed and removed by `applyPlayerEffects` before any other normalisation
1506
+ // (see `createAnimatorImpl`), so downstream code never sees it.
1507
+ effects: PxEffectsSchema.optional(),
1508
+ // `PxElementAnimation` (not just `PxAnimationDefinition`) — accepts
1509
+ // string ref / array of refs / inline definition / mixed array; mirrors
1510
+ // `animator.animateById` map values and what `processNode` resolves at runtime.
1511
+ animate: PxElementAnimationSchema.optional(),
1512
+ style: px.union([px.string(), px.record(px.union([px.string(), px.number()]))]).optional()
1513
+ }, PxAttrValueSchema);
1514
+ var PxNodeSchema = px.openObject(__spreadProps(__spreadValues({}, PxNodeBase._shape), {
1515
+ children: px.lazy(() => px.array(PxNodeSchema), []).optional()
1516
+ }), PxAttrValueSchema);
1517
+ var PxSvgNodeExtra = px.object({
1518
+ // `"100%"` and other SVG length strings are legal here — a number-only slot rejected
1519
+ // real documents (e.g. apple-store-look-14-main.json) at the root <svg>.
1520
+ width: px.union([px.number(), px.string()]).optional(),
1521
+ height: px.union([px.number(), px.string()]).optional(),
1522
+ viewBox: px.string().optional(),
1523
+ animator: PxAnimatorConfigSchema.optional()
1524
+ });
1525
+ var PxAnimatedSvgDocumentSchema = px.openObject(__spreadProps(__spreadValues(__spreadValues({}, PxNodeBase._shape), PxSvgNodeExtra._shape), {
1526
+ type: px.literal("svg"),
1527
+ // override string → literal to require 'svg'
1528
+ children: px.array(PxNodeSchema).optional()
1529
+ }), PxAttrValueSchema);
1530
+ var PxBezierPathSchema = implementsInterface()(px.object({
1531
+ v: px.array(px.array(px.number())),
1532
+ i: px.array(px.array(px.number())).optional(),
1533
+ o: px.array(px.array(px.number())).optional(),
1534
+ c: px.boolean().optional()
1535
+ }));
1536
+
1537
+ // ../svg-animator-core/src/materialise/PxMotionPath.ts
1538
+ function getKfTranslate(kf) {
1539
+ const v = kfValue(kf);
627
1540
  if (!v) return void 0;
628
1541
  if (Array.isArray(v) && v.length >= 2 && typeof v[0] === "number" && typeof v[1] === "number") {
629
1542
  return [v[0], v[1]];
@@ -633,31 +1546,27 @@ var PixodeskAnimator = (() => {
633
1546
  return void 0;
634
1547
  }
635
1548
  function getKfTime(kf) {
636
- var _a, _b;
637
- return (_b = (_a = kf.time) != null ? _a : kf.t) != null ? _b : 0;
1549
+ return kfTime(kf);
638
1550
  }
639
1551
  function getKfEasing(kf) {
640
- var _a;
641
- return (_a = kf.easing) != null ? _a : kf.e;
1552
+ return kfEasing(kf);
642
1553
  }
643
1554
  function propAnimIsMotionPath(anim) {
644
- var _a, _b;
645
1555
  const kfs = anim.keyframes;
646
1556
  if (!Array.isArray(kfs)) return false;
647
1557
  if (anim.autoOrient) return true;
648
1558
  for (const kf of kfs) {
649
- if (((_a = kf.tangentIn) != null ? _a : kf.ti) || ((_b = kf.tangentOut) != null ? _b : kf.to)) return true;
1559
+ if (kfTangentIn(kf) || kfTangentOut(kf)) return true;
650
1560
  }
651
1561
  return false;
652
1562
  }
653
1563
  var _segmentCache = /* @__PURE__ */ new WeakMap();
654
1564
  function getSegmentCache(prevKf, nextKf, prevPos, nextPos) {
655
- var _a, _b;
656
1565
  let byNext = _segmentCache.get(prevKf);
657
1566
  const existing = byNext == null ? void 0 : byNext.get(nextKf);
658
1567
  if (existing) return existing;
659
- const to = (_a = prevKf.tangentOut) != null ? _a : prevKf.to;
660
- const ti = (_b = nextKf.tangentIn) != null ? _b : nextKf.ti;
1568
+ const to = kfTangentOut(prevKf);
1569
+ const ti = kfTangentIn(nextKf);
661
1570
  const P1 = [prevPos[0] + (to ? to[0] : 0), prevPos[1] + (to ? to[1] : 0)];
662
1571
  const P2 = [nextPos[0] + (ti ? ti[0] : 0), nextPos[1] + (ti ? ti[1] : 0)];
663
1572
  const lut = bezier2D_arcLengthLUT(prevPos, P1, P2, nextPos);
@@ -748,10 +1657,9 @@ var PixodeskAnimator = (() => {
748
1657
  return result;
749
1658
  }
750
1659
  function unwrapAutoOrientRotations(kfs) {
751
- var _a;
752
1660
  let prev;
753
1661
  for (const kf of kfs) {
754
- const v = (_a = kf.v) != null ? _a : kf.value;
1662
+ const v = kfValue(kf);
755
1663
  if (!v || typeof v.rotate !== "number") continue;
756
1664
  if (prev === void 0) {
757
1665
  prev = v.rotate;
@@ -768,8 +1676,7 @@ var PixodeskAnimator = (() => {
768
1676
  return { t: time, v: value };
769
1677
  }
770
1678
  function getKfValueParts(kf) {
771
- var _a;
772
- const v = (_a = kf.value) != null ? _a : kf.v;
1679
+ const v = kfValue(kf);
773
1680
  if (!v || typeof v !== "object" || Array.isArray(v)) return void 0;
774
1681
  return v;
775
1682
  }
@@ -830,9 +1737,8 @@ var PixodeskAnimator = (() => {
830
1737
  return d;
831
1738
  }
832
1739
  function insertSharpCornerStepKfIfNeeded(out, prevKf, nextKf, prevPos, nextPos, rotationTol) {
833
- var _a;
834
1740
  const lastKf = out[out.length - 1];
835
- const lastV = (_a = lastKf.v) != null ? _a : lastKf.value;
1741
+ const lastV = kfValue(lastKf);
836
1742
  const prevExit = lastV == null ? void 0 : lastV.rotate;
837
1743
  if (typeof prevExit !== "number") return;
838
1744
  const boundaryV = getKfValueParts(prevKf);
@@ -979,7 +1885,7 @@ var PixodeskAnimator = (() => {
979
1885
  return Math.abs(cross) / Math.sqrt(len2);
980
1886
  }
981
1887
 
982
- // ../svg-animator-core/src/PxDefinitions.ts
1888
+ // ../svg-animator-core/src/animation/PxDefinitions.ts
983
1889
  var LOOP_JUMP_SHIFT_MS = 1;
984
1890
  function deepEqualValue(a, b) {
985
1891
  if (a === b) return true;
@@ -1080,8 +1986,8 @@ var PixodeskAnimator = (() => {
1080
1986
  if (Array.isArray(pathsArray) && pathsArray.length > 0) {
1081
1987
  if (isPathString(pathsArray[0])) {
1082
1988
  const paths = [];
1083
- for (const pathStr of pathsArray) {
1084
- const d = extractPathData(pathStr);
1989
+ for (const pathStr2 of pathsArray) {
1990
+ const d = extractPathData(pathStr2);
1085
1991
  if (d) {
1086
1992
  paths.push(...parseSvgPathToBezier(d));
1087
1993
  }
@@ -1094,8 +2000,8 @@ var PixodeskAnimator = (() => {
1094
2000
  if (Array.isArray(value)) {
1095
2001
  if (value.length > 0 && isPathString(value[0])) {
1096
2002
  const paths = [];
1097
- for (const pathStr of value) {
1098
- const d = extractPathData(pathStr);
2003
+ for (const pathStr2 of value) {
2004
+ const d = extractPathData(pathStr2);
1099
2005
  if (d) {
1100
2006
  paths.push(...parseSvgPathToBezier(d));
1101
2007
  }
@@ -1192,7 +2098,7 @@ var PixodeskAnimator = (() => {
1192
2098
  const totalIntervals = keyframes.length - 1;
1193
2099
  const segCount = clamp((_a = loop.segmentCount) != null ? _a : totalIntervals, 1, totalIntervals);
1194
2100
  let segKfs;
1195
- if (loop.extend === PxLoopExtend.before) {
2101
+ if (loop.repeatAt === PxLoopRepeatAt.start) {
1196
2102
  segKfs = keyframes.slice(0, segCount + 1);
1197
2103
  } else {
1198
2104
  segKfs = keyframes.slice(totalIntervals - segCount);
@@ -1200,7 +2106,7 @@ var PixodeskAnimator = (() => {
1200
2106
  const firstT = (_b = keyframes[0].t) != null ? _b : 0;
1201
2107
  const lastT = (_c = keyframes[keyframes.length - 1].t) != null ? _c : 0;
1202
2108
  let fillStart, fillEnd;
1203
- if (loop.extend === PxLoopExtend.before) {
2109
+ if (loop.repeatAt === PxLoopRepeatAt.start) {
1204
2110
  fillStart = 0;
1205
2111
  fillEnd = firstT;
1206
2112
  } else {
@@ -1213,21 +2119,18 @@ var PixodeskAnimator = (() => {
1213
2119
  const segEndT = (_e = segKfs[segKfs.length - 1].t) != null ? _e : 0;
1214
2120
  const segDuration = segEndT - segStartT;
1215
2121
  if (segDuration <= 0) return keyframes;
1216
- const template = segKfs.map((kf) => {
1217
- var _a2, _b2;
1218
- return {
1219
- relT: (kf.t - segStartT) / segDuration,
1220
- v: kf.v,
1221
- e: kf.e,
1222
- tangentIn: (_a2 = kf.tangentIn) != null ? _a2 : kf.ti,
1223
- tangentOut: (_b2 = kf.tangentOut) != null ? _b2 : kf.to
1224
- };
1225
- });
2122
+ const template = segKfs.map((kf) => ({
2123
+ relT: (kf.t - segStartT) / segDuration,
2124
+ v: kf.v,
2125
+ e: kf.e,
2126
+ tangentIn: kfTangentIn(kf),
2127
+ tangentOut: kfTangentOut(kf)
2128
+ }));
1226
2129
  const fullReps = Math.floor(fillDuration / segDuration);
1227
2130
  const remainder = fillDuration - fullReps * segDuration;
1228
2131
  const partialFraction = remainder / segDuration;
1229
2132
  const looped = [];
1230
- const separateBoundary = loop.extend !== PxLoopExtend.before;
2133
+ const separateBoundary = loop.repeatAt !== PxLoopRepeatAt.start;
1231
2134
  const originalTerminalKf = keyframes[keyframes.length - 1];
1232
2135
  let terminalEasingOverride;
1233
2136
  let hasTerminalEasingOverride = false;
@@ -1335,30 +2238,30 @@ var PixodeskAnimator = (() => {
1335
2238
  looped.push(pushed);
1336
2239
  }
1337
2240
  }
1338
- if (loop.extend === PxLoopExtend.before) {
2241
+ if (loop.repeatAt === PxLoopRepeatAt.start) {
1339
2242
  if (partialFraction > 1e-9) {
1340
- const isReversed = !!loop.alternate && fullReps % 2 === 0;
2243
+ const isReversed = loop.direction === PxLoopDirection.alternate && fullReps % 2 === 0;
1341
2244
  appendRepTail(fillStart, isReversed, partialFraction);
1342
2245
  }
1343
2246
  for (let rep = 0; rep < fullReps; rep++) {
1344
2247
  const distFromBoundary = fullReps - 1 - rep;
1345
- const isReversed = !!loop.alternate && distFromBoundary % 2 === 0;
2248
+ const isReversed = loop.direction === PxLoopDirection.alternate && distFromBoundary % 2 === 0;
1346
2249
  const repStart = fillStart + remainder + rep * segDuration;
1347
2250
  appendRep(repStart, isReversed);
1348
2251
  }
1349
2252
  } else {
1350
2253
  for (let rep = 0; rep < fullReps; rep++) {
1351
- const isReversed = !!loop.alternate && rep % 2 === 0;
2254
+ const isReversed = loop.direction === PxLoopDirection.alternate && rep % 2 === 0;
1352
2255
  const repStart = fillStart + rep * segDuration;
1353
2256
  appendRep(repStart, isReversed);
1354
2257
  }
1355
2258
  if (partialFraction > 1e-9) {
1356
- const isReversed = !!loop.alternate && fullReps % 2 === 0;
2259
+ const isReversed = loop.direction === PxLoopDirection.alternate && fullReps % 2 === 0;
1357
2260
  const repStart = fillStart + fullReps * segDuration;
1358
2261
  appendRep(repStart, isReversed, partialFraction);
1359
2262
  }
1360
2263
  }
1361
- if (loop.extend === PxLoopExtend.before) {
2264
+ if (loop.repeatAt === PxLoopRepeatAt.start) {
1362
2265
  return [...looped, ...keyframes];
1363
2266
  } else {
1364
2267
  if (hasTerminalEasingOverride && keyframes.length > 0) {
@@ -1370,34 +2273,34 @@ var PixodeskAnimator = (() => {
1370
2273
  }
1371
2274
  }
1372
2275
  function normalizeKeyframes(propName, propAnim, duration, defs) {
1373
- var _a, _b, _c, _d, _e, _f, _g;
2276
+ var _a;
1374
2277
  const keyframes = propAnim.keyframes || [];
1375
2278
  const normalized = [];
1376
2279
  for (const kf of keyframes) {
1377
- const timePct = (_b = (_a = kf.time) != null ? _a : kf.t) != null ? _b : 0;
1378
- let value = (_c = kf.value) != null ? _c : kf.v;
1379
- const easing = (_d = kf.easing) != null ? _d : kf.e;
2280
+ const timePct = kfTime(kf);
2281
+ let value = kfValue(kf);
2282
+ const easing = kfEasing(kf);
1380
2283
  if (propName === "d") {
1381
2284
  value = normalizePathValue(value);
1382
2285
  }
1383
2286
  const propNameKebab = isCamelCaseWord(propName) ? camelCaseToKebabWordIfNeeded(propName) : propName;
1384
2287
  if (COLOUR_ATTR_NAMES.has(propNameKebab)) {
1385
- value = (_e = parseColor(value)) != null ? _e : value;
2288
+ value = (_a = parseColor(value)) != null ? _a : value;
1386
2289
  }
1387
2290
  const normKf = {
1388
2291
  t: timePct,
1389
2292
  v: value,
1390
2293
  e: resolveEasing(easing, defs)
1391
2294
  };
1392
- const tIn = (_f = kf.tangentIn) != null ? _f : kf.ti;
1393
- const tOut = (_g = kf.tangentOut) != null ? _g : kf.to;
2295
+ const tIn = kfTangentIn(kf);
2296
+ const tOut = kfTangentOut(kf);
1394
2297
  if (tIn) normKf.tangentIn = tIn;
1395
2298
  if (tOut) normKf.tangentOut = tOut;
1396
2299
  normalized.push(normKf);
1397
2300
  }
1398
2301
  normalized.sort((a, b) => {
1399
- var _a2, _b2;
1400
- return ((_a2 = a.t) != null ? _a2 : 0) - ((_b2 = b.t) != null ? _b2 : 0);
2302
+ var _a2, _b;
2303
+ return ((_a2 = a.t) != null ? _a2 : 0) - ((_b = b.t) != null ? _b : 0);
1401
2304
  });
1402
2305
  const loopRaw = propAnim.loop;
1403
2306
  const loop = loopRaw === true ? {} : loopRaw || void 0;
@@ -1424,7 +2327,7 @@ var PixodeskAnimator = (() => {
1424
2327
  const staticParts = staticTransform && typeof staticTransform === "object" && !Array.isArray(staticTransform) ? staticTransform : parseTransformParts(staticTransform);
1425
2328
  if (!staticParts || !Object.keys(staticParts).length) return animDef;
1426
2329
  const mergeKfValue = (v) => v && typeof v === "object" && !Array.isArray(v) ? __spreadValues(__spreadValues({}, staticParts), v) : v;
1427
- const transformAnim = animDef["transform"];
2330
+ const transformAnim = animDef[TRANSFORM_ATTR];
1428
2331
  if (transformAnim && typeof transformAnim === "object") {
1429
2332
  const anim = transformAnim;
1430
2333
  if (Array.isArray(anim.keyframes)) {
@@ -1449,7 +2352,7 @@ var PixodeskAnimator = (() => {
1449
2352
  delete rest[ch];
1450
2353
  return __spreadProps(__spreadValues({}, rest), { transform: lifted });
1451
2354
  }
1452
- function normalizeAnimationDefinition(animDef, duration, defs, engine = PxAnimatorEngine.waapi) {
2355
+ function normalizeAnimationDefinition(animDef, duration, defs, engine = PxTimelineEngine.native) {
1453
2356
  const normalized = {};
1454
2357
  for (const [propName, propAnim] of Object.entries(animDef)) {
1455
2358
  if (propName === "transform" && propAnim.alongPathMode === "offsetPath" && animDef["offsetDistance"] !== void 0) {
@@ -1460,12 +2363,12 @@ var PixodeskAnimator = (() => {
1460
2363
  const out = { keyframes: normalizedKfs };
1461
2364
  if (propAnim.autoOrient !== void 0) out.autoOrient = propAnim.autoOrient;
1462
2365
  if (propAnim.loop !== void 0) out.loop = propAnim.loop;
1463
- normalized[propName] = engine === PxAnimatorEngine.waapi && propName === "transform" ? materialiseMotionPathInPropAnim(out) : out;
2366
+ normalized[propName] = engine === PxTimelineEngine.native && propName === "transform" ? materialiseMotionPathInPropAnim(out) : out;
1464
2367
  }
1465
2368
  }
1466
2369
  return normalized;
1467
2370
  }
1468
- function getNormalisedBindings(doc, engine = PxAnimatorEngine.waapi) {
2371
+ function getNormalisedBindings(doc, engine = PxTimelineEngine.native) {
1469
2372
  const animatorConfig = getAnimatorConfig(doc) || {};
1470
2373
  const defs = getDefs(doc);
1471
2374
  const duration = animatorConfig.duration || 1e3;
@@ -1531,13 +2434,13 @@ var PixodeskAnimator = (() => {
1531
2434
  return { prevKf, nextKf };
1532
2435
  }
1533
2436
  function calcPropertyValue(propName, propAnim, progress) {
1534
- var _a, _b, _c, _d, _e, _f, _g;
2437
+ var _a, _b, _c, _d;
1535
2438
  const keyframes = propAnim.keyframes || [];
1536
2439
  if (keyframes.length === 0) return null;
1537
2440
  const { prevKf, nextKf } = getKeyframesPair(keyframes, progress);
1538
2441
  let localProgress = prevKf === nextKf ? 0 : remap(progress, (_a = prevKf.t) != null ? _a : 0, (_b = nextKf.t) != null ? _b : 0, 0, 1);
1539
2442
  localProgress = clamp(localProgress, 0, 1);
1540
- const easing = (_c = prevKf.e) != null ? _c : prevKf.easing;
2443
+ const easing = kfEasing(prevKf);
1541
2444
  if (easing && Array.isArray(easing)) {
1542
2445
  try {
1543
2446
  localProgress = cubicBezier(easing)(localProgress);
@@ -1546,11 +2449,11 @@ var PixodeskAnimator = (() => {
1546
2449
  }
1547
2450
  let cssAttrName = isCamelCaseWord(propName) ? camelCaseToKebabWordIfNeeded(propName) : propName;
1548
2451
  let cssValue = null;
1549
- const prevV = (_d = prevKf == null ? void 0 : prevKf.v) != null ? _d : prevKf == null ? void 0 : prevKf.value;
1550
- const nextV = (_e = nextKf == null ? void 0 : nextKf.v) != null ? _e : nextKf == null ? void 0 : nextKf.value;
2452
+ const prevV = prevKf == null ? void 0 : prevKf.v;
2453
+ const nextV = nextKf == null ? void 0 : nextKf.v;
1551
2454
  if (cssAttrName === "d") {
1552
- const prevPaths = (_f = prevV == null ? void 0 : prevV.paths) != null ? _f : Array.isArray(prevV) ? prevV : [];
1553
- const nextPaths = (_g = nextV == null ? void 0 : nextV.paths) != null ? _g : Array.isArray(nextV) ? nextV : [];
2455
+ const prevPaths = (_c = prevV == null ? void 0 : prevV.paths) != null ? _c : Array.isArray(prevV) ? prevV : [];
2456
+ const nextPaths = (_d = nextV == null ? void 0 : nextV.paths) != null ? _d : Array.isArray(nextV) ? nextV : [];
1554
2457
  cssValue = interpolateBeziers(
1555
2458
  prevPaths,
1556
2459
  nextPaths,
@@ -1653,7 +2556,7 @@ var PixodeskAnimator = (() => {
1653
2556
  return result;
1654
2557
  }
1655
2558
 
1656
- // ../svg-animator-core/src/PxFrameLoop.ts
2559
+ // ../svg-animator-core/src/playback/PxFrameLoop.ts
1657
2560
  function requestFrame(cb) {
1658
2561
  const g = globalThis;
1659
2562
  if (typeof g.requestAnimationFrame === "function") return g.requestAnimationFrame(cb);
@@ -1670,7 +2573,7 @@ var PixodeskAnimator = (() => {
1670
2573
  function createBasicFrameLoopAnimator(doc, adapter, callbacks) {
1671
2574
  var _a;
1672
2575
  const config = getAnimatorConfig(doc) || {};
1673
- const bindings = getNormalisedBindings(doc, PxAnimatorEngine.frames);
2576
+ const bindings = getNormalisedBindings(doc, PxTimelineEngine.js);
1674
2577
  const _iterations = config.iterations;
1675
2578
  let iterations = 1;
1676
2579
  if (typeof _iterations === "number") iterations = _iterations || 1;
@@ -1931,7 +2834,7 @@ var PixodeskAnimator = (() => {
1931
2834
  return api;
1932
2835
  }
1933
2836
 
1934
- // src/PxAnimatorTriggers.ts
2837
+ // src/triggers/PxAnimatorTriggers.ts
1935
2838
  function setupAnimationTriggers(api, config) {
1936
2839
  const { startOn, outAction = "continue", scrollIntoViewThreshold = 0 } = config;
1937
2840
  const root = api.getRootElement();
@@ -2036,7 +2939,7 @@ var PixodeskAnimator = (() => {
2036
2939
  return api;
2037
2940
  }
2038
2941
 
2039
- // src/PxAnimatorFrameLoop.ts
2942
+ // src/engines/PxAnimatorFrameLoop.ts
2040
2943
  function getSelector(id) {
2041
2944
  return "#" + id;
2042
2945
  }
@@ -2096,11 +2999,10 @@ var PixodeskAnimator = (() => {
2096
2999
  return adapter;
2097
3000
  }
2098
3001
 
2099
- // src/PxAnimatorWebApi.ts
3002
+ // src/engines/PxAnimatorWebApi.ts
2100
3003
  function createCssKf(kf, t, propName, unsupportedSet) {
2101
- var _a, _b;
2102
- let value = (_a = kf.v) != null ? _a : kf.value;
2103
- const e = (_b = kf.e) != null ? _b : kf.easing;
3004
+ let value = kfValue(kf);
3005
+ const e = kfEasing(kf);
2104
3006
  const cssKf = {
2105
3007
  offset: t,
2106
3008
  easing: e && Array.isArray(e) ? "cubic-bezier(" + e.join(",") + ")" : void 0
@@ -2205,7 +3107,7 @@ var PixodeskAnimator = (() => {
2205
3107
  console.warn("createFrameLoopAnimator: No root element provided");
2206
3108
  }
2207
3109
  }
2208
- const bindings = getNormalisedBindings(doc, PxAnimatorEngine.waapi);
3110
+ const bindings = getNormalisedBindings(doc, PxTimelineEngine.native);
2209
3111
  const animations = [];
2210
3112
  const _iterations = config.iterations;
2211
3113
  let iterations;
@@ -2363,7 +3265,7 @@ var PixodeskAnimator = (() => {
2363
3265
  return api;
2364
3266
  }
2365
3267
 
2366
- // src/PxScrollDriver.ts
3268
+ // src/scroll/PxScrollDriver.ts
2367
3269
  function nativeRangeOffset(point, defaultFraction, view) {
2368
3270
  var _a, _b, _c;
2369
3271
  const fraction = typeof (point == null ? void 0 : point.fraction) === "number" ? point.fraction : defaultFraction;
@@ -2377,7 +3279,7 @@ var PixodeskAnimator = (() => {
2377
3279
  const scroll = config.scroll || {};
2378
3280
  const kind = (_a = scroll.kind) != null ? _a : "view";
2379
3281
  if (scroll.smoothing) {
2380
- console.warn('scroll timeline: `smoothing` needs the built-in driver \u2014 ignoring `driver: "native"`');
3282
+ console.warn("scroll timeline: `smoothing` needs the built-in driver \u2014 using the built-in driver instead of the browser timeline");
2381
3283
  return null;
2382
3284
  }
2383
3285
  const g = globalThis;
@@ -2394,7 +3296,7 @@ var PixodeskAnimator = (() => {
2394
3296
  timeline = new Ctor({ source, axis });
2395
3297
  }
2396
3298
  } catch (e) {
2397
- console.warn("scroll timeline: native timeline construction failed \u2014 falling back to the custom driver", e);
3299
+ console.warn("scroll timeline: native timeline construction failed \u2014 falling back to the player measuring progress itself", e);
2398
3300
  return null;
2399
3301
  }
2400
3302
  return {
@@ -2613,7 +3515,7 @@ var PixodeskAnimator = (() => {
2613
3515
  };
2614
3516
  }
2615
3517
 
2616
- // src/PxAnimatorBind.ts
3518
+ // src/engines/PxAnimatorBind.ts
2617
3519
  function finaliseAnimator(animatorConfig, callbacks, make) {
2618
3520
  let apiRef;
2619
3521
  let effectiveCallbacks = callbacks;
@@ -2628,8 +3530,8 @@ var PixodeskAnimator = (() => {
2628
3530
  }
2629
3531
  const res = make(effectiveCallbacks);
2630
3532
  apiRef = res;
2631
- if (animatorConfig.debugInstName) {
2632
- window[animatorConfig.debugInstName] = res;
3533
+ if (animatorConfig.debugGlobalName) {
3534
+ window[animatorConfig.debugGlobalName] = res;
2633
3535
  }
2634
3536
  return res;
2635
3537
  }
@@ -2637,10 +3539,10 @@ var PixodeskAnimator = (() => {
2637
3539
  const animatorConfig = getAnimatorConfig(doc) || {};
2638
3540
  if (isScrollTimeline(animatorConfig)) {
2639
3541
  return finaliseAnimator(animatorConfig, callbacks, (cb) => {
2640
- var _a, _b;
3542
+ var _a;
2641
3543
  let unpin = () => {
2642
3544
  };
2643
- if (animatorConfig.mode !== PxAnimatorMode.frames && ((_a = animatorConfig.scroll) == null ? void 0 : _a.driver) === "native" && rootElement) {
3545
+ if (mayUseNativeScrollTimeline(animatorConfig.engine) && rootElement) {
2644
3546
  unpin = applyScrollPin(rootElement, animatorConfig.scroll);
2645
3547
  const native = createNativeScrollTimeline(rootElement, animatorConfig);
2646
3548
  if (native) {
@@ -2648,7 +3550,7 @@ var PixodeskAnimator = (() => {
2648
3550
  doc,
2649
3551
  cb,
2650
3552
  rootElement,
2651
- animatorConfig.mode === PxAnimatorMode.waapi,
3553
+ isNativeForced(animatorConfig.engine),
2652
3554
  native
2653
3555
  );
2654
3556
  if (api2) {
@@ -2664,8 +3566,8 @@ var PixodeskAnimator = (() => {
2664
3566
  unpin = () => {
2665
3567
  };
2666
3568
  }
2667
- const api = (animatorConfig.mode !== PxAnimatorMode.frames ? createWebApiAnimator(doc, cb, rootElement, animatorConfig.mode === PxAnimatorMode.waapi) : null) || createFrameLoopAnimator(doc, adapter, cb, rootElement);
2668
- const subject = ((_b = api.getRootElement) == null ? void 0 : _b.call(api)) || rootElement;
3569
+ const api = (animatorConfig.engine !== PxTimelineEngineExtra.js ? createWebApiAnimator(doc, cb, rootElement, isNativeForced(animatorConfig.engine)) : null) || createFrameLoopAnimator(doc, adapter, cb, rootElement);
3570
+ const subject = ((_a = api.getRootElement) == null ? void 0 : _a.call(api)) || rootElement;
2669
3571
  if (subject) {
2670
3572
  unpin = applyScrollPin(subject, animatorConfig.scroll);
2671
3573
  const totalMs = scrollTotalDurationMs(animatorConfig);
@@ -2689,15 +3591,14 @@ var PixodeskAnimator = (() => {
2689
3591
  });
2690
3592
  }
2691
3593
  return finaliseAnimator(animatorConfig, callbacks, (cb) => {
2692
- if (animatorConfig.mode === PxAnimatorMode.frames) {
3594
+ if (animatorConfig.engine === PxTimelineEngineExtra.js) {
2693
3595
  return createFrameLoopAnimator(doc, adapter, cb, rootElement);
2694
3596
  }
2695
3597
  return createWebApiAnimator(
2696
3598
  doc,
2697
3599
  cb,
2698
3600
  rootElement,
2699
- animatorConfig.mode === PxAnimatorMode.waapi
2700
- // forcing waapi
3601
+ isNativeForced(animatorConfig.engine)
2701
3602
  ) || createFrameLoopAnimator(doc, adapter, cb, rootElement);
2702
3603
  });
2703
3604
  }
@@ -2709,7 +3610,7 @@ var PixodeskAnimator = (() => {
2709
3610
  return bindWithEngineChoice(requireData(options), options.adapter, options.callbacks, null);
2710
3611
  }
2711
3612
 
2712
- // src/PxAnimatorKeys.ts
3613
+ // src/shared/PxAnimatorKeys.ts
2713
3614
  var PX_ANIMATOR_DATA_KEY = "data";
2714
3615
  return __toCommonJS(index_prerendered_exports);
2715
3616
  })();