@octane-xplat/motion 0.0.0 → 0.7.1

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.
@@ -0,0 +1,1747 @@
1
+ import { createContext, defineUniversalComponent, hookSlots, universalChildren, universalComponent, universalContext, universalIf, universalPlan, universalProps, universalValue, useContext, useEffect, useLayoutEffect, useRef, useState, withSlot } from "@nativescript-community/octane";
2
+ import { Pressable, Row, View } from "@octane-xplat/ui";
3
+ import { Application, Utils } from "@nativescript/core";
4
+ import { cancelAnimationFrame, requestAnimationFrame } from "@nativescript/core/animation-frame";
5
+ //#region src/reduced-motion.ts
6
+ function readReducedMotion() {
7
+ const platform = globalThis;
8
+ if (Application.ios) return Boolean(platform.UIAccessibilityIsReduceMotionEnabled?.());
9
+ const context = Utils.android.getApplicationContext();
10
+ return platform.android.provider.Settings.Global.getFloat(context.getContentResolver(), "animator_duration_scale", 1) === 0;
11
+ }
12
+ function observeReducedMotion(notify) {
13
+ let previous = readReducedMotion();
14
+ const check = () => {
15
+ const next = readReducedMotion();
16
+ if (next !== previous) {
17
+ previous = next;
18
+ notify();
19
+ }
20
+ };
21
+ const timer = setInterval(check, 500);
22
+ Application.on(Application.resumeEvent, check);
23
+ return () => {
24
+ clearInterval(timer);
25
+ Application.off(Application.resumeEvent, check);
26
+ };
27
+ }
28
+ //#endregion
29
+ //#region src/config.tsrx
30
+ var _hs$$3 = /* @__PURE__ */ hookSlots(2);
31
+ var _h$0$3 = /* @__PURE__ */ Symbol(_hs$$3);
32
+ var _h$1$3 = /* @__PURE__ */ Symbol(_hs$$3 + 1);
33
+ var __octaneUniversalPlan0$2 = universalPlan("nativescript", {
34
+ "kind": "slot",
35
+ "slot": 0
36
+ });
37
+ var ConfigContext = createContext({ reducedMotion: "never" });
38
+ function useReducedMotion() {
39
+ const [reduced, setReduced] = useState(readReducedMotion, _h$0$3);
40
+ useEffect(() => {
41
+ const update = () => setReduced(readReducedMotion());
42
+ const off = observeReducedMotion(update);
43
+ update();
44
+ return off;
45
+ }, [], _h$1$3);
46
+ return reduced;
47
+ }
48
+ var MotionConfig = defineUniversalComponent("nativescript", function MotionConfig(props) {
49
+ const parent = useContext(ConfigContext);
50
+ const value = {
51
+ transition: props.transition ?? parent.transition,
52
+ reducedMotion: props.reducedMotion ?? parent.reducedMotion
53
+ };
54
+ return universalValue(__octaneUniversalPlan0$2, [((__octaneContextProps) => universalContext(ConfigContext, __octaneContextProps.value, props.children))({ "value": value })]);
55
+ }, { "module": "@nativescript-community/octane" });
56
+ //#endregion
57
+ //#region src/presence-state.ts
58
+ var PresenceState = class {
59
+ present;
60
+ complete;
61
+ members = /* @__PURE__ */ new Set();
62
+ pending = /* @__PURE__ */ new Map();
63
+ sequence = 0;
64
+ generation = 0;
65
+ disposed = false;
66
+ removed = false;
67
+ constructor(present, complete) {
68
+ this.present = present;
69
+ this.complete = complete;
70
+ }
71
+ register(member) {
72
+ this.members.add(member);
73
+ if (!this.present) this.restart(member);
74
+ return () => {
75
+ this.members.delete(member);
76
+ this.pending.delete(member);
77
+ this.check();
78
+ };
79
+ }
80
+ setPresent(present) {
81
+ if (this.disposed || present === this.present) return;
82
+ this.present = present;
83
+ ++this.generation;
84
+ this.removed = false;
85
+ this.pending.clear();
86
+ if (present) for (const member of this.members) member.enter();
87
+ else {
88
+ for (const member of this.members) this.restart(member);
89
+ this.check();
90
+ }
91
+ }
92
+ restart(member) {
93
+ if (this.disposed || this.present || !this.members.has(member)) return;
94
+ const token = ++this.sequence;
95
+ this.pending.set(member, token);
96
+ member.exit().then((result) => {
97
+ if (this.disposed || this.present || this.pending.get(member) !== token) return;
98
+ if (result !== "finished") return;
99
+ this.pending.delete(member);
100
+ this.check();
101
+ });
102
+ }
103
+ check() {
104
+ const generation = this.generation;
105
+ queueMicrotask(() => {
106
+ if (!this.disposed && !this.present && !this.removed && !this.pending.size && generation === this.generation) {
107
+ this.removed = true;
108
+ this.complete();
109
+ }
110
+ });
111
+ }
112
+ destroy() {
113
+ this.disposed = true;
114
+ ++this.generation;
115
+ this.members.clear();
116
+ this.pending.clear();
117
+ }
118
+ };
119
+ //#endregion
120
+ //#region src/presence-input.ts
121
+ function blockInput(node) {
122
+ const enabled = node.isUserInteractionEnabled;
123
+ const iosHidden = node.ios?.accessibilityElementsHidden;
124
+ const androidImportance = node.android?.getImportantForAccessibility?.();
125
+ node.ios?.endEditing?.(true);
126
+ const focused = node.android?.findFocus?.();
127
+ if (focused) {
128
+ const platform = globalThis;
129
+ focused.getContext().getSystemService(platform.android.content.Context.INPUT_METHOD_SERVICE)?.hideSoftInputFromWindow(focused.getWindowToken(), 0);
130
+ focused.clearFocus();
131
+ }
132
+ node.isUserInteractionEnabled = false;
133
+ if (node.ios) node.ios.accessibilityElementsHidden = true;
134
+ node.android?.setImportantForAccessibility?.(4);
135
+ return () => {
136
+ node.isUserInteractionEnabled = enabled;
137
+ if (node.ios) node.ios.accessibilityElementsHidden = iosHidden;
138
+ if (androidImportance !== void 0) node.android?.setImportantForAccessibility?.(androidImportance);
139
+ };
140
+ }
141
+ //#endregion
142
+ //#region src/presence.tsrx
143
+ var _hs$$2 = /* @__PURE__ */ hookSlots(7);
144
+ var _h$0$2 = /* @__PURE__ */ Symbol(_hs$$2);
145
+ var _h$1$2 = /* @__PURE__ */ Symbol(_hs$$2 + 1);
146
+ var _h$2$2 = /* @__PURE__ */ Symbol(_hs$$2 + 2);
147
+ var _h$3$2 = /* @__PURE__ */ Symbol(_hs$$2 + 3);
148
+ var _h$4$2 = /* @__PURE__ */ Symbol(_hs$$2 + 4);
149
+ var _h$5$2 = /* @__PURE__ */ Symbol(_hs$$2 + 5);
150
+ var _h$6$2 = /* @__PURE__ */ Symbol(_hs$$2 + 6);
151
+ var __octaneUniversalPlan0$1 = universalPlan("nativescript", {
152
+ "kind": "slot",
153
+ "slot": 0
154
+ });
155
+ var __octaneUniversalPlan1$1 = universalPlan("nativescript", {
156
+ "kind": "slot",
157
+ "slot": 0
158
+ });
159
+ var __octaneUniversalPlan2$1 = universalPlan("nativescript", {
160
+ "kind": "slot",
161
+ "slot": 0
162
+ });
163
+ var PresenceContext = createContext(null);
164
+ var Presence = defineUniversalComponent("nativescript", function Presence(props) {
165
+ const [retained, setRetained] = useState(props.present, _h$0$2);
166
+ const latest = useRef(props, _h$1$2);
167
+ latest.current = props;
168
+ const ref = useRef(null, _h$2$2);
169
+ if (!ref.current) ref.current = new PresenceState(props.present, () => {
170
+ setRetained(false);
171
+ latest.current.onExitComplete?.();
172
+ });
173
+ const state = ref.current;
174
+ const host = useRef(null, _h$3$2);
175
+ const restoreInput = useRef(null, _h$4$2);
176
+ const syncInput = () => {
177
+ if (!props.present && host.current && !restoreInput.current) restoreInput.current = blockInput(host.current);
178
+ if (props.present && restoreInput.current) {
179
+ restoreInput.current();
180
+ restoreInput.current = null;
181
+ }
182
+ };
183
+ useLayoutEffect(() => {
184
+ if (props.present) setRetained(true);
185
+ syncInput();
186
+ state.setPresent(props.present);
187
+ }, [props.present], _h$5$2);
188
+ useLayoutEffect(() => () => {
189
+ state.destroy();
190
+ restoreInput.current?.();
191
+ restoreInput.current = null;
192
+ host.current = null;
193
+ }, [], _h$6$2);
194
+ const { present, onExitComplete, children, bind, ...viewProps } = props;
195
+ return universalValue(__octaneUniversalPlan2$1, [universalIf(props.present || retained, () => {
196
+ return universalValue(__octaneUniversalPlan1$1, [universalComponent("nativescript", View, universalProps([["spread", viewProps], [
197
+ "set",
198
+ "bind",
199
+ (node) => {
200
+ if (host.current !== node) {
201
+ restoreInput.current?.();
202
+ restoreInput.current = null;
203
+ host.current = node;
204
+ }
205
+ syncInput();
206
+ bind?.(node);
207
+ }
208
+ ]], universalChildren("nativescript", () => {
209
+ return universalValue(__octaneUniversalPlan0$1, [((__octaneContextProps) => universalContext(PresenceContext, __octaneContextProps.value, children))({ "value": state })]);
210
+ })))]);
211
+ })]);
212
+ }, { "module": "@nativescript-community/octane" });
213
+ //#endregion
214
+ //#region src/clock.ts
215
+ var clock = {
216
+ now: () => Date.now(),
217
+ request: requestAnimationFrame,
218
+ cancel: cancelAnimationFrame
219
+ };
220
+ //#endregion
221
+ //#region src/host.ts
222
+ function attachHost(node) {
223
+ const original = {
224
+ opacity: node.opacity ?? 1,
225
+ x: node.translateX ?? 0,
226
+ y: node.translateY ?? 0,
227
+ scaleX: node.scaleX ?? 1,
228
+ scaleY: node.scaleY ?? 1,
229
+ rotate: node.rotate ?? 0
230
+ };
231
+ if (original.x || original.y || original.rotate || original.scaleX !== 1 || original.scaleY !== 1) throw new Error("motion: put existing transforms on an outer container");
232
+ const write = (values) => {
233
+ if (values.opacity !== void 0) node.opacity = Math.min(1, Math.max(0, values.opacity));
234
+ if (values.x !== void 0) node.translateX = values.x;
235
+ if (values.y !== void 0) node.translateY = values.y;
236
+ if (values.rotate !== void 0) node.rotate = values.rotate;
237
+ if (values.scale !== void 0 || values.scaleX !== void 0) node.scaleX = (values.scale ?? 1) * (values.scaleX ?? 1);
238
+ if (values.scale !== void 0 || values.scaleY !== void 0) node.scaleY = (values.scale ?? 1) * (values.scaleY ?? 1);
239
+ };
240
+ return {
241
+ read: () => ({
242
+ ...original,
243
+ scale: 1
244
+ }),
245
+ write,
246
+ restore: () => write(original)
247
+ };
248
+ }
249
+ //#endregion
250
+ //#region ../../node_modules/.pnpm/motion-utils@12.39.0/node_modules/motion-utils/dist/es/clamp.mjs
251
+ var clamp = (min, max, v) => {
252
+ if (v > max) return max;
253
+ if (v < min) return min;
254
+ return v;
255
+ };
256
+ //#endregion
257
+ //#region ../../node_modules/.pnpm/motion-utils@12.39.0/node_modules/motion-utils/dist/es/format-error-message.mjs
258
+ function formatErrorMessage(message, errorCode) {
259
+ return errorCode ? `${message}. For more information and steps for solving, visit https://motion.dev/troubleshooting/${errorCode}` : message;
260
+ }
261
+ //#endregion
262
+ //#region ../../node_modules/.pnpm/motion-utils@12.39.0/node_modules/motion-utils/dist/es/errors.mjs
263
+ var warning = () => {};
264
+ var invariant = () => {};
265
+ if (typeof process !== "undefined" && process.env.NODE_ENV !== "production") {
266
+ warning = (check, message, errorCode) => {
267
+ if (!check && typeof console !== "undefined") console.warn(formatErrorMessage(message, errorCode));
268
+ };
269
+ invariant = (check, message, errorCode) => {
270
+ if (!check) throw new Error(formatErrorMessage(message, errorCode));
271
+ };
272
+ }
273
+ //#endregion
274
+ //#region ../../node_modules/.pnpm/motion-utils@12.39.0/node_modules/motion-utils/dist/es/global-config.mjs
275
+ var MotionGlobalConfig = {};
276
+ //#endregion
277
+ //#region ../../node_modules/.pnpm/motion-utils@12.39.0/node_modules/motion-utils/dist/es/noop.mjs
278
+ var noop = /* @__NO_SIDE_EFFECTS__ */ (any) => any;
279
+ //#endregion
280
+ //#region ../../node_modules/.pnpm/motion-utils@12.39.0/node_modules/motion-utils/dist/es/pipe.mjs
281
+ /**
282
+ * Pipe
283
+ * Compose other transformers to run linearily
284
+ * pipe(min(20), max(40))
285
+ * @param {...functions} transformers
286
+ * @return {function}
287
+ */
288
+ var pipe = (...transformers) => transformers.reduce((a, b) => (v) => b(a(v)));
289
+ //#endregion
290
+ //#region ../../node_modules/.pnpm/motion-utils@12.39.0/node_modules/motion-utils/dist/es/progress.mjs
291
+ var progress = /* @__NO_SIDE_EFFECTS__ */ (from, to, value) => {
292
+ const range = to - from;
293
+ return range ? (value - from) / range : 1;
294
+ };
295
+ //#endregion
296
+ //#region ../../node_modules/.pnpm/motion-utils@12.39.0/node_modules/motion-utils/dist/es/time-conversion.mjs
297
+ /**
298
+ * Converts seconds to milliseconds
299
+ *
300
+ * @param seconds - Time in seconds.
301
+ * @return milliseconds - Converted time in milliseconds.
302
+ */
303
+ var secondsToMilliseconds = /* @__NO_SIDE_EFFECTS__ */ (seconds) => seconds * 1e3;
304
+ var millisecondsToSeconds = /* @__NO_SIDE_EFFECTS__ */ (milliseconds) => milliseconds / 1e3;
305
+ //#endregion
306
+ //#region ../../node_modules/.pnpm/motion-utils@12.39.0/node_modules/motion-utils/dist/es/easing/cubic-bezier.mjs
307
+ var calcBezier = (t, a1, a2) => (((1 - 3 * a2 + 3 * a1) * t + (3 * a2 - 6 * a1)) * t + 3 * a1) * t;
308
+ var subdivisionPrecision = 1e-7;
309
+ var subdivisionMaxIterations = 12;
310
+ function binarySubdivide(x, lowerBound, upperBound, mX1, mX2) {
311
+ let currentX;
312
+ let currentT;
313
+ let i = 0;
314
+ do {
315
+ currentT = lowerBound + (upperBound - lowerBound) / 2;
316
+ currentX = calcBezier(currentT, mX1, mX2) - x;
317
+ if (currentX > 0) upperBound = currentT;
318
+ else lowerBound = currentT;
319
+ } while (Math.abs(currentX) > subdivisionPrecision && ++i < subdivisionMaxIterations);
320
+ return currentT;
321
+ }
322
+ /*#__NO_SIDE_EFFECTS__*/
323
+ function cubicBezier(mX1, mY1, mX2, mY2) {
324
+ if (mX1 === mY1 && mX2 === mY2) return noop;
325
+ const getTForX = (aX) => binarySubdivide(aX, 0, 1, mX1, mX2);
326
+ return (t) => t === 0 || t === 1 ? t : calcBezier(getTForX(t), mY1, mY2);
327
+ }
328
+ //#endregion
329
+ //#region ../../node_modules/.pnpm/motion-utils@12.39.0/node_modules/motion-utils/dist/es/easing/modifiers/mirror.mjs
330
+ var mirrorEasing = /* @__NO_SIDE_EFFECTS__ */ (easing) => (p) => p <= .5 ? easing(2 * p) / 2 : (2 - easing(2 * (1 - p))) / 2;
331
+ //#endregion
332
+ //#region ../../node_modules/.pnpm/motion-utils@12.39.0/node_modules/motion-utils/dist/es/easing/modifiers/reverse.mjs
333
+ var reverseEasing = /* @__NO_SIDE_EFFECTS__ */ (easing) => (p) => 1 - easing(1 - p);
334
+ //#endregion
335
+ //#region ../../node_modules/.pnpm/motion-utils@12.39.0/node_modules/motion-utils/dist/es/easing/back.mjs
336
+ var backOut = /*@__PURE__*/ cubicBezier(.33, 1.53, .69, .99);
337
+ var backIn = /*@__PURE__*/ reverseEasing(backOut);
338
+ var backInOut = /*@__PURE__*/ mirrorEasing(backIn);
339
+ //#endregion
340
+ //#region ../../node_modules/.pnpm/motion-utils@12.39.0/node_modules/motion-utils/dist/es/easing/anticipate.mjs
341
+ var anticipate = (p) => p >= 1 ? 1 : (p *= 2) < 1 ? .5 * backIn(p) : .5 * (2 - Math.pow(2, -10 * (p - 1)));
342
+ //#endregion
343
+ //#region ../../node_modules/.pnpm/motion-utils@12.39.0/node_modules/motion-utils/dist/es/easing/circ.mjs
344
+ var circIn = (p) => 1 - Math.sin(Math.acos(p));
345
+ var circOut = /* @__PURE__ */ reverseEasing(circIn);
346
+ var circInOut = /* @__PURE__ */ mirrorEasing(circIn);
347
+ //#endregion
348
+ //#region ../../node_modules/.pnpm/motion-utils@12.39.0/node_modules/motion-utils/dist/es/easing/ease.mjs
349
+ var easeIn = /*@__PURE__*/ cubicBezier(.42, 0, 1, 1);
350
+ var easeOut = /*@__PURE__*/ cubicBezier(0, 0, .58, 1);
351
+ var easeInOut = /*@__PURE__*/ cubicBezier(.42, 0, .58, 1);
352
+ //#endregion
353
+ //#region ../../node_modules/.pnpm/motion-utils@12.39.0/node_modules/motion-utils/dist/es/easing/utils/is-easing-array.mjs
354
+ var isEasingArray = /* @__NO_SIDE_EFFECTS__ */ (ease) => {
355
+ return Array.isArray(ease) && typeof ease[0] !== "number";
356
+ };
357
+ //#endregion
358
+ //#region ../../node_modules/.pnpm/motion-utils@12.39.0/node_modules/motion-utils/dist/es/easing/utils/is-bezier-definition.mjs
359
+ var isBezierDefinition = /* @__NO_SIDE_EFFECTS__ */ (easing) => Array.isArray(easing) && typeof easing[0] === "number";
360
+ //#endregion
361
+ //#region ../../node_modules/.pnpm/motion-utils@12.39.0/node_modules/motion-utils/dist/es/easing/utils/map.mjs
362
+ var easingLookup = {
363
+ linear: noop,
364
+ easeIn,
365
+ easeInOut,
366
+ easeOut,
367
+ circIn,
368
+ circInOut,
369
+ circOut,
370
+ backIn,
371
+ backInOut,
372
+ backOut,
373
+ anticipate
374
+ };
375
+ var isValidEasing = (easing) => {
376
+ return typeof easing === "string";
377
+ };
378
+ var easingDefinitionToFunction = (definition) => {
379
+ if (/* @__PURE__ */ isBezierDefinition(definition)) {
380
+ invariant(definition.length === 4, `Cubic bezier arrays must contain four numerical values.`, "cubic-bezier-length");
381
+ const [x1, y1, x2, y2] = definition;
382
+ return /* @__PURE__ */ cubicBezier(x1, y1, x2, y2);
383
+ } else if (isValidEasing(definition)) {
384
+ invariant(easingLookup[definition] !== void 0, `Invalid easing type '${definition}'`, "invalid-easing-type");
385
+ return easingLookup[definition];
386
+ }
387
+ return definition;
388
+ };
389
+ //#endregion
390
+ //#region ../../node_modules/.pnpm/motion-dom@12.42.2/node_modules/motion-dom/dist/es/animation/utils/is-css-variable.mjs
391
+ var checkStringStartsWith = (token) => (key) => typeof key === "string" && key.startsWith(token);
392
+ var startsAsVariableToken = /*@__PURE__*/ checkStringStartsWith("var(--");
393
+ var isCSSVariableToken = (value) => {
394
+ if (!startsAsVariableToken(value)) return false;
395
+ return singleCssVariableRegex.test(value.split("/*")[0].trim());
396
+ };
397
+ var singleCssVariableRegex = /var\(--(?:[\w-]+\s*|[\w-]+\s*,(?:\s*[^)(\s]|\s*\((?:[^)(]|\([^)(]*\))*\))+\s*)\)$/iu;
398
+ //#endregion
399
+ //#region ../../node_modules/.pnpm/motion-dom@12.42.2/node_modules/motion-dom/dist/es/value/types/numbers/index.mjs
400
+ var number = {
401
+ test: (v) => typeof v === "number",
402
+ parse: parseFloat,
403
+ transform: (v) => v
404
+ };
405
+ var alpha = {
406
+ ...number,
407
+ transform: (v) => clamp(0, 1, v)
408
+ };
409
+ ({ ...number });
410
+ //#endregion
411
+ //#region ../../node_modules/.pnpm/motion-dom@12.42.2/node_modules/motion-dom/dist/es/value/types/utils/sanitize.mjs
412
+ var sanitize = (v) => Math.round(v * 1e5) / 1e5;
413
+ //#endregion
414
+ //#region ../../node_modules/.pnpm/motion-dom@12.42.2/node_modules/motion-dom/dist/es/value/types/utils/float-regex.mjs
415
+ var floatRegex = /-?(?:\d+(?:\.\d+)?|\.\d+)/gu;
416
+ //#endregion
417
+ //#region ../../node_modules/.pnpm/motion-dom@12.42.2/node_modules/motion-dom/dist/es/value/types/utils/is-nullish.mjs
418
+ function isNullish(v) {
419
+ return v == null;
420
+ }
421
+ //#endregion
422
+ //#region ../../node_modules/.pnpm/motion-dom@12.42.2/node_modules/motion-dom/dist/es/value/types/utils/single-color-regex.mjs
423
+ var singleColorRegex = /^(?:#[\da-f]{3,8}|(?:rgb|hsl)a?\((?:-?[\d.]+%?[,\s]+){2}-?[\d.]+%?\s*(?:[,/]\s*)?(?:\b\d+(?:\.\d+)?|\.\d+)?%?\))$/iu;
424
+ //#endregion
425
+ //#region ../../node_modules/.pnpm/motion-dom@12.42.2/node_modules/motion-dom/dist/es/value/types/color/utils.mjs
426
+ /**
427
+ * Returns true if the provided string is a color, ie rgba(0,0,0,0) or #000,
428
+ * but false if a number or multiple colors
429
+ */
430
+ var isColorString = (type, testProp) => (v) => {
431
+ return Boolean(typeof v === "string" && singleColorRegex.test(v) && v.startsWith(type) || testProp && !isNullish(v) && Object.prototype.hasOwnProperty.call(v, testProp));
432
+ };
433
+ var splitColor = (aName, bName, cName) => (v) => {
434
+ if (typeof v !== "string") return v;
435
+ const [a, b, c, alpha] = v.match(floatRegex);
436
+ return {
437
+ [aName]: parseFloat(a),
438
+ [bName]: parseFloat(b),
439
+ [cName]: parseFloat(c),
440
+ alpha: alpha !== void 0 ? parseFloat(alpha) : 1
441
+ };
442
+ };
443
+ //#endregion
444
+ //#region ../../node_modules/.pnpm/motion-dom@12.42.2/node_modules/motion-dom/dist/es/value/types/color/rgba.mjs
445
+ var clampRgbUnit = (v) => clamp(0, 255, v);
446
+ var rgbUnit = {
447
+ ...number,
448
+ transform: (v) => Math.round(clampRgbUnit(v))
449
+ };
450
+ var rgba = {
451
+ test: /*@__PURE__*/ isColorString("rgb", "red"),
452
+ parse: /*@__PURE__*/ splitColor("red", "green", "blue"),
453
+ transform: ({ red, green, blue, alpha: alpha$1 = 1 }) => "rgba(" + rgbUnit.transform(red) + ", " + rgbUnit.transform(green) + ", " + rgbUnit.transform(blue) + ", " + sanitize(alpha.transform(alpha$1)) + ")"
454
+ };
455
+ //#endregion
456
+ //#region ../../node_modules/.pnpm/motion-dom@12.42.2/node_modules/motion-dom/dist/es/value/types/color/hex.mjs
457
+ function parseHex(v) {
458
+ let r = "";
459
+ let g = "";
460
+ let b = "";
461
+ let a = "";
462
+ if (v.length > 5) {
463
+ r = v.substring(1, 3);
464
+ g = v.substring(3, 5);
465
+ b = v.substring(5, 7);
466
+ a = v.substring(7, 9);
467
+ } else {
468
+ r = v.substring(1, 2);
469
+ g = v.substring(2, 3);
470
+ b = v.substring(3, 4);
471
+ a = v.substring(4, 5);
472
+ r += r;
473
+ g += g;
474
+ b += b;
475
+ a += a;
476
+ }
477
+ return {
478
+ red: parseInt(r, 16),
479
+ green: parseInt(g, 16),
480
+ blue: parseInt(b, 16),
481
+ alpha: a ? parseInt(a, 16) / 255 : 1
482
+ };
483
+ }
484
+ var hex = {
485
+ test: /*@__PURE__*/ isColorString("#"),
486
+ parse: parseHex,
487
+ transform: rgba.transform
488
+ };
489
+ //#endregion
490
+ //#region ../../node_modules/.pnpm/motion-dom@12.42.2/node_modules/motion-dom/dist/es/value/types/numbers/units.mjs
491
+ var createUnitType = /* @__NO_SIDE_EFFECTS__ */ (unit) => ({
492
+ test: (v) => typeof v === "string" && v.endsWith(unit) && v.split(" ").length === 1,
493
+ parse: parseFloat,
494
+ transform: (v) => `${v}${unit}`
495
+ });
496
+ var percent = /*@__PURE__*/ createUnitType("%");
497
+ //#endregion
498
+ //#region ../../node_modules/.pnpm/motion-dom@12.42.2/node_modules/motion-dom/dist/es/value/types/color/hsla.mjs
499
+ var hsla = {
500
+ test: /*@__PURE__*/ isColorString("hsl", "hue"),
501
+ parse: /*@__PURE__*/ splitColor("hue", "saturation", "lightness"),
502
+ transform: ({ hue, saturation, lightness, alpha: alpha$1 = 1 }) => {
503
+ return "hsla(" + Math.round(hue) + ", " + percent.transform(sanitize(saturation)) + ", " + percent.transform(sanitize(lightness)) + ", " + sanitize(alpha.transform(alpha$1)) + ")";
504
+ }
505
+ };
506
+ //#endregion
507
+ //#region ../../node_modules/.pnpm/motion-dom@12.42.2/node_modules/motion-dom/dist/es/value/types/color/index.mjs
508
+ var color = {
509
+ test: (v) => rgba.test(v) || hex.test(v) || hsla.test(v),
510
+ parse: (v) => {
511
+ if (rgba.test(v)) return rgba.parse(v);
512
+ else if (hsla.test(v)) return hsla.parse(v);
513
+ else return hex.parse(v);
514
+ },
515
+ transform: (v) => {
516
+ return typeof v === "string" ? v : v.hasOwnProperty("red") ? rgba.transform(v) : hsla.transform(v);
517
+ },
518
+ getAnimatableNone: (v) => {
519
+ const parsed = color.parse(v);
520
+ parsed.alpha = 0;
521
+ return color.transform(parsed);
522
+ }
523
+ };
524
+ //#endregion
525
+ //#region ../../node_modules/.pnpm/motion-dom@12.42.2/node_modules/motion-dom/dist/es/value/types/utils/color-regex.mjs
526
+ var colorRegex = /(?:#[\da-f]{3,8}|(?:rgb|hsl)a?\((?:-?[\d.]+%?[,\s]+){2}-?[\d.]+%?\s*(?:[,/]\s*)?(?:\b\d+(?:\.\d+)?|\.\d+)?%?\))/giu;
527
+ //#endregion
528
+ //#region ../../node_modules/.pnpm/motion-dom@12.42.2/node_modules/motion-dom/dist/es/value/types/complex/index.mjs
529
+ function test(v) {
530
+ return isNaN(v) && typeof v === "string" && (v.match(floatRegex)?.length || 0) + (v.match(colorRegex)?.length || 0) > 0;
531
+ }
532
+ var NUMBER_TOKEN = "number";
533
+ var COLOR_TOKEN = "color";
534
+ var VAR_TOKEN = "var";
535
+ var VAR_FUNCTION_TOKEN = "var(";
536
+ var SPLIT_TOKEN = "${}";
537
+ var complexRegex = /var\s*\(\s*--(?:[\w-]+\s*|[\w-]+\s*,(?:\s*[^)(\s]|\s*\((?:[^)(]|\([^)(]*\))*\))+\s*)\)|#[\da-f]{3,8}|(?:rgb|hsl)a?\((?:-?[\d.]+%?[,\s]+){2}-?[\d.]+%?\s*(?:[,/]\s*)?(?:\b\d+(?:\.\d+)?|\.\d+)?%?\)|-?(?:\d+(?:\.\d+)?|\.\d+)/giu;
538
+ function analyseComplexValue(value) {
539
+ const originalValue = value.toString();
540
+ const values = [];
541
+ const indexes = {
542
+ color: [],
543
+ number: [],
544
+ var: []
545
+ };
546
+ const types = [];
547
+ let i = 0;
548
+ return {
549
+ values,
550
+ split: originalValue.replace(complexRegex, (parsedValue) => {
551
+ if (color.test(parsedValue)) {
552
+ indexes.color.push(i);
553
+ types.push(COLOR_TOKEN);
554
+ values.push(color.parse(parsedValue));
555
+ } else if (parsedValue.startsWith(VAR_FUNCTION_TOKEN)) {
556
+ indexes.var.push(i);
557
+ types.push(VAR_TOKEN);
558
+ values.push(parsedValue);
559
+ } else {
560
+ indexes.number.push(i);
561
+ types.push(NUMBER_TOKEN);
562
+ values.push(parseFloat(parsedValue));
563
+ }
564
+ ++i;
565
+ return SPLIT_TOKEN;
566
+ }).split(SPLIT_TOKEN),
567
+ indexes,
568
+ types
569
+ };
570
+ }
571
+ function parseComplexValue(v) {
572
+ return analyseComplexValue(v).values;
573
+ }
574
+ function buildTransformer({ split, types }) {
575
+ const numSections = split.length;
576
+ return (v) => {
577
+ let output = "";
578
+ for (let i = 0; i < numSections; i++) {
579
+ output += split[i];
580
+ if (v[i] !== void 0) {
581
+ const type = types[i];
582
+ if (type === NUMBER_TOKEN) output += sanitize(v[i]);
583
+ else if (type === COLOR_TOKEN) output += color.transform(v[i]);
584
+ else output += v[i];
585
+ }
586
+ }
587
+ return output;
588
+ };
589
+ }
590
+ function createTransformer(source) {
591
+ return buildTransformer(analyseComplexValue(source));
592
+ }
593
+ var convertNumbersToZero = (v) => typeof v === "number" ? 0 : color.test(v) ? color.getAnimatableNone(v) : v;
594
+ /**
595
+ * Convert a parsed value to its zero equivalent, but preserve numbers
596
+ * that act as divisors in CSS calc() expressions.
597
+ *
598
+ * analyseComplexValue extracts numbers from CSS strings and puts the
599
+ * surrounding text into a `split` template array. For example:
600
+ * "calc(var(--gap) / 5)" → values: [var(--gap), 5]
601
+ * split: ["calc(", " / ", ")"]
602
+ *
603
+ * When building a zero-equivalent for animation, naively zeroing all
604
+ * numbers turns the divisor into 0 → "calc(var(--gap) / 0)" → NaN.
605
+ * We detect this by checking whether the text preceding a number
606
+ * (split[i]) ends with "/" — the CSS calc division operator.
607
+ */
608
+ var convertToZero = (value, splitBefore) => {
609
+ if (typeof value === "number") return splitBefore?.trim().endsWith("/") ? value : 0;
610
+ return convertNumbersToZero(value);
611
+ };
612
+ function getAnimatableNone(v) {
613
+ const info = analyseComplexValue(v);
614
+ return buildTransformer(info)(info.values.map((value, i) => convertToZero(value, info.split[i])));
615
+ }
616
+ var complex = {
617
+ test,
618
+ parse: parseComplexValue,
619
+ createTransformer,
620
+ getAnimatableNone
621
+ };
622
+ //#endregion
623
+ //#region ../../node_modules/.pnpm/motion-dom@12.42.2/node_modules/motion-dom/dist/es/value/types/color/hsla-to-rgba.mjs
624
+ function hueToRgb(p, q, t) {
625
+ if (t < 0) t += 1;
626
+ if (t > 1) t -= 1;
627
+ if (t < 1 / 6) return p + (q - p) * 6 * t;
628
+ if (t < 1 / 2) return q;
629
+ if (t < 2 / 3) return p + (q - p) * (2 / 3 - t) * 6;
630
+ return p;
631
+ }
632
+ function hslaToRgba({ hue, saturation, lightness, alpha }) {
633
+ hue /= 360;
634
+ saturation /= 100;
635
+ lightness /= 100;
636
+ let red = 0;
637
+ let green = 0;
638
+ let blue = 0;
639
+ if (!saturation) red = green = blue = lightness;
640
+ else {
641
+ const q = lightness < .5 ? lightness * (1 + saturation) : lightness + saturation - lightness * saturation;
642
+ const p = 2 * lightness - q;
643
+ red = hueToRgb(p, q, hue + 1 / 3);
644
+ green = hueToRgb(p, q, hue);
645
+ blue = hueToRgb(p, q, hue - 1 / 3);
646
+ }
647
+ return {
648
+ red: Math.round(red * 255),
649
+ green: Math.round(green * 255),
650
+ blue: Math.round(blue * 255),
651
+ alpha
652
+ };
653
+ }
654
+ //#endregion
655
+ //#region ../../node_modules/.pnpm/motion-dom@12.42.2/node_modules/motion-dom/dist/es/utils/mix/immediate.mjs
656
+ function mixImmediate(a, b) {
657
+ return (p) => p > 0 ? b : a;
658
+ }
659
+ //#endregion
660
+ //#region ../../node_modules/.pnpm/motion-dom@12.42.2/node_modules/motion-dom/dist/es/utils/mix/number.mjs
661
+ var mixNumber$1 = (from, to, progress) => {
662
+ return from + (to - from) * progress;
663
+ };
664
+ //#endregion
665
+ //#region ../../node_modules/.pnpm/motion-dom@12.42.2/node_modules/motion-dom/dist/es/utils/mix/color.mjs
666
+ var mixLinearColor = (from, to, v) => {
667
+ const fromExpo = from * from;
668
+ const expo = v * (to * to - fromExpo) + fromExpo;
669
+ return expo < 0 ? 0 : Math.sqrt(expo);
670
+ };
671
+ var colorTypes = [
672
+ hex,
673
+ rgba,
674
+ hsla
675
+ ];
676
+ var getColorType = (v) => colorTypes.find((type) => type.test(v));
677
+ function asRGBA(color) {
678
+ const type = getColorType(color);
679
+ warning(Boolean(type), `'${color}' is not an animatable color. Use the equivalent color code instead.`, "color-not-animatable");
680
+ if (!Boolean(type)) return false;
681
+ let model = type.parse(color);
682
+ if (type === hsla) model = hslaToRgba(model);
683
+ return model;
684
+ }
685
+ var mixColor = (from, to) => {
686
+ const fromRGBA = asRGBA(from);
687
+ const toRGBA = asRGBA(to);
688
+ if (!fromRGBA || !toRGBA) return mixImmediate(from, to);
689
+ const blended = { ...fromRGBA };
690
+ return (v) => {
691
+ blended.red = mixLinearColor(fromRGBA.red, toRGBA.red, v);
692
+ blended.green = mixLinearColor(fromRGBA.green, toRGBA.green, v);
693
+ blended.blue = mixLinearColor(fromRGBA.blue, toRGBA.blue, v);
694
+ blended.alpha = mixNumber$1(fromRGBA.alpha, toRGBA.alpha, v);
695
+ return rgba.transform(blended);
696
+ };
697
+ };
698
+ //#endregion
699
+ //#region ../../node_modules/.pnpm/motion-dom@12.42.2/node_modules/motion-dom/dist/es/utils/mix/visibility.mjs
700
+ var invisibleValues = /* @__PURE__ */ new Set(["none", "hidden"]);
701
+ /**
702
+ * Returns a function that, when provided a progress value between 0 and 1,
703
+ * will return the "none" or "hidden" string only when the progress is that of
704
+ * the origin or target.
705
+ */
706
+ function mixVisibility(origin, target) {
707
+ if (invisibleValues.has(origin)) return (p) => p <= 0 ? origin : target;
708
+ else return (p) => p >= 1 ? target : origin;
709
+ }
710
+ //#endregion
711
+ //#region ../../node_modules/.pnpm/motion-dom@12.42.2/node_modules/motion-dom/dist/es/utils/mix/complex.mjs
712
+ function mixNumber(a, b) {
713
+ return (p) => mixNumber$1(a, b, p);
714
+ }
715
+ function getMixer(a) {
716
+ if (typeof a === "number") return mixNumber;
717
+ else if (typeof a === "string") return isCSSVariableToken(a) ? mixImmediate : color.test(a) ? mixColor : mixComplex;
718
+ else if (Array.isArray(a)) return mixArray;
719
+ else if (typeof a === "object") return color.test(a) ? mixColor : mixObject;
720
+ return mixImmediate;
721
+ }
722
+ function mixArray(a, b) {
723
+ const output = [...a];
724
+ const numValues = output.length;
725
+ const blendValue = a.map((v, i) => getMixer(v)(v, b[i]));
726
+ return (p) => {
727
+ for (let i = 0; i < numValues; i++) output[i] = blendValue[i](p);
728
+ return output;
729
+ };
730
+ }
731
+ function mixObject(a, b) {
732
+ const output = {
733
+ ...a,
734
+ ...b
735
+ };
736
+ const blendValue = {};
737
+ for (const key in output) if (a[key] !== void 0 && b[key] !== void 0) blendValue[key] = getMixer(a[key])(a[key], b[key]);
738
+ return (v) => {
739
+ for (const key in blendValue) output[key] = blendValue[key](v);
740
+ return output;
741
+ };
742
+ }
743
+ function matchOrder(origin, target) {
744
+ const orderedOrigin = [];
745
+ const pointers = {
746
+ color: 0,
747
+ var: 0,
748
+ number: 0
749
+ };
750
+ for (let i = 0; i < target.values.length; i++) {
751
+ const type = target.types[i];
752
+ const originIndex = origin.indexes[type][pointers[type]];
753
+ const originValue = origin.values[originIndex] ?? 0;
754
+ orderedOrigin[i] = originValue;
755
+ pointers[type]++;
756
+ }
757
+ return orderedOrigin;
758
+ }
759
+ var mixComplex = (origin, target) => {
760
+ const template = complex.createTransformer(target);
761
+ const originStats = analyseComplexValue(origin);
762
+ const targetStats = analyseComplexValue(target);
763
+ if (originStats.indexes.var.length === targetStats.indexes.var.length && originStats.indexes.color.length === targetStats.indexes.color.length && originStats.indexes.number.length >= targetStats.indexes.number.length) {
764
+ if (invisibleValues.has(origin) && !targetStats.values.length || invisibleValues.has(target) && !originStats.values.length) return mixVisibility(origin, target);
765
+ return pipe(mixArray(matchOrder(originStats, targetStats), targetStats.values), template);
766
+ } else {
767
+ warning(true, `Complex values '${origin}' and '${target}' too different to mix. Ensure all colors are of the same type, and that each contains the same quantity of number and color values. Falling back to instant transition.`, "complex-values-different");
768
+ return mixImmediate(origin, target);
769
+ }
770
+ };
771
+ //#endregion
772
+ //#region ../../node_modules/.pnpm/motion-dom@12.42.2/node_modules/motion-dom/dist/es/utils/mix/index.mjs
773
+ function mix(from, to, p) {
774
+ if (typeof from === "number" && typeof to === "number" && typeof p === "number") return mixNumber$1(from, to, p);
775
+ return getMixer(from)(from, to);
776
+ }
777
+ //#endregion
778
+ //#region ../../node_modules/.pnpm/motion-dom@12.42.2/node_modules/motion-dom/dist/es/animation/waapi/utils/linear.mjs
779
+ var generateLinearEasing = (easing, duration, resolution = 10) => {
780
+ let points = "";
781
+ const numPoints = Math.max(Math.round(duration / resolution), 2);
782
+ for (let i = 0; i < numPoints; i++) points += Math.round(easing(i / (numPoints - 1)) * 1e4) / 1e4 + ", ";
783
+ return `linear(${points.substring(0, points.length - 2)})`;
784
+ };
785
+ //#endregion
786
+ //#region ../../node_modules/.pnpm/motion-dom@12.42.2/node_modules/motion-dom/dist/es/animation/generators/utils/calc-duration.mjs
787
+ /**
788
+ * Implement a practical max duration for keyframe generation
789
+ * to prevent infinite loops
790
+ */
791
+ var maxGeneratorDuration = 2e4;
792
+ function calcGeneratorDuration(generator) {
793
+ let duration = 0;
794
+ const timeStep = 50;
795
+ let state = generator.next(duration);
796
+ while (!state.done && duration < 2e4) {
797
+ duration += timeStep;
798
+ state = generator.next(duration);
799
+ }
800
+ return duration >= 2e4 ? Infinity : duration;
801
+ }
802
+ //#endregion
803
+ //#region ../../node_modules/.pnpm/motion-dom@12.42.2/node_modules/motion-dom/dist/es/animation/generators/utils/create-generator-easing.mjs
804
+ /**
805
+ * Create a progress => progress easing function from a generator.
806
+ */
807
+ function createGeneratorEasing(options, scale = 100, createGenerator) {
808
+ const generator = createGenerator({
809
+ ...options,
810
+ keyframes: [0, scale]
811
+ });
812
+ const duration = Math.min(calcGeneratorDuration(generator), maxGeneratorDuration);
813
+ return {
814
+ type: "keyframes",
815
+ ease: (progress) => {
816
+ return generator.next(duration * progress).value / scale;
817
+ },
818
+ duration: /* @__PURE__ */ millisecondsToSeconds(duration)
819
+ };
820
+ }
821
+ //#endregion
822
+ //#region ../../node_modules/.pnpm/motion-dom@12.42.2/node_modules/motion-dom/dist/es/animation/generators/spring.mjs
823
+ var springDefaults = {
824
+ stiffness: 100,
825
+ damping: 10,
826
+ mass: 1,
827
+ velocity: 0,
828
+ duration: 800,
829
+ bounce: .3,
830
+ visualDuration: .3,
831
+ restSpeed: {
832
+ granular: .01,
833
+ default: 2
834
+ },
835
+ restDelta: {
836
+ granular: .005,
837
+ default: .5
838
+ },
839
+ minDuration: .01,
840
+ maxDuration: 10,
841
+ minDamping: .05,
842
+ maxDamping: 1
843
+ };
844
+ function calcAngularFreq(undampedFreq, dampingRatio) {
845
+ return undampedFreq * Math.sqrt(1 - dampingRatio * dampingRatio);
846
+ }
847
+ var rootIterations = 12;
848
+ function approximateRoot(envelope, derivative, initialGuess) {
849
+ let result = initialGuess;
850
+ for (let i = 1; i < rootIterations; i++) result = result - envelope(result) / derivative(result);
851
+ return result;
852
+ }
853
+ /**
854
+ * This is ported from the Framer implementation of duration-based spring resolution.
855
+ */
856
+ var safeMin = .001;
857
+ function findSpring({ duration = springDefaults.duration, bounce = springDefaults.bounce, velocity = springDefaults.velocity, mass = springDefaults.mass }) {
858
+ let envelope;
859
+ let derivative;
860
+ warning(duration <= /* @__PURE__ */ secondsToMilliseconds(springDefaults.maxDuration), "Spring duration must be 10 seconds or less", "spring-duration-limit");
861
+ let dampingRatio = 1 - bounce;
862
+ /**
863
+ * Restrict dampingRatio and duration to within acceptable ranges.
864
+ */
865
+ dampingRatio = clamp(springDefaults.minDamping, springDefaults.maxDamping, dampingRatio);
866
+ duration = clamp(springDefaults.minDuration, springDefaults.maxDuration, /* @__PURE__ */ millisecondsToSeconds(duration));
867
+ if (dampingRatio < 1) {
868
+ /**
869
+ * Underdamped spring
870
+ */
871
+ envelope = (undampedFreq) => {
872
+ const exponentialDecay = undampedFreq * dampingRatio;
873
+ const delta = exponentialDecay * duration;
874
+ const a = exponentialDecay - velocity;
875
+ const b = calcAngularFreq(undampedFreq, dampingRatio);
876
+ const c = Math.exp(-delta);
877
+ return safeMin - a / b * c;
878
+ };
879
+ derivative = (undampedFreq) => {
880
+ const delta = undampedFreq * dampingRatio * duration;
881
+ const d = delta * velocity + velocity;
882
+ const e = Math.pow(dampingRatio, 2) * Math.pow(undampedFreq, 2) * duration;
883
+ const f = Math.exp(-delta);
884
+ const g = calcAngularFreq(Math.pow(undampedFreq, 2), dampingRatio);
885
+ return (-envelope(undampedFreq) + safeMin > 0 ? -1 : 1) * ((d - e) * f) / g;
886
+ };
887
+ } else {
888
+ /**
889
+ * Critically-damped spring
890
+ */
891
+ envelope = (undampedFreq) => {
892
+ return -.001 + Math.exp(-undampedFreq * duration) * ((undampedFreq - velocity) * duration + 1);
893
+ };
894
+ derivative = (undampedFreq) => {
895
+ return Math.exp(-undampedFreq * duration) * ((velocity - undampedFreq) * (duration * duration));
896
+ };
897
+ }
898
+ const initialGuess = 5 / duration;
899
+ const undampedFreq = approximateRoot(envelope, derivative, initialGuess);
900
+ duration = /* @__PURE__ */ secondsToMilliseconds(duration);
901
+ if (isNaN(undampedFreq)) return {
902
+ stiffness: springDefaults.stiffness,
903
+ damping: springDefaults.damping,
904
+ duration
905
+ };
906
+ else {
907
+ const stiffness = Math.pow(undampedFreq, 2) * mass;
908
+ return {
909
+ stiffness,
910
+ damping: dampingRatio * 2 * Math.sqrt(mass * stiffness),
911
+ duration
912
+ };
913
+ }
914
+ }
915
+ var durationKeys = ["duration", "bounce"];
916
+ var physicsKeys = [
917
+ "stiffness",
918
+ "damping",
919
+ "mass"
920
+ ];
921
+ function isSpringType(options, keys) {
922
+ return keys.some((key) => options[key] !== void 0);
923
+ }
924
+ function getSpringOptions(options) {
925
+ let springOptions = {
926
+ velocity: springDefaults.velocity,
927
+ stiffness: springDefaults.stiffness,
928
+ damping: springDefaults.damping,
929
+ mass: springDefaults.mass,
930
+ isResolvedFromDuration: false,
931
+ ...options
932
+ };
933
+ if (!isSpringType(options, physicsKeys) && isSpringType(options, durationKeys)) {
934
+ springOptions.velocity = 0;
935
+ if (options.visualDuration) {
936
+ const visualDuration = options.visualDuration;
937
+ const root = 2 * Math.PI / (visualDuration * 1.2);
938
+ const stiffness = root * root;
939
+ const damping = 2 * clamp(.05, 1, 1 - (options.bounce || 0)) * Math.sqrt(stiffness);
940
+ springOptions = {
941
+ ...springOptions,
942
+ mass: springDefaults.mass,
943
+ stiffness,
944
+ damping
945
+ };
946
+ } else {
947
+ const derived = findSpring({
948
+ ...options,
949
+ velocity: 0
950
+ });
951
+ springOptions = {
952
+ ...springOptions,
953
+ ...derived,
954
+ mass: springDefaults.mass
955
+ };
956
+ springOptions.isResolvedFromDuration = true;
957
+ }
958
+ }
959
+ return springOptions;
960
+ }
961
+ function spring(optionsOrVisualDuration = springDefaults.visualDuration, bounce = springDefaults.bounce) {
962
+ const options = typeof optionsOrVisualDuration !== "object" ? {
963
+ visualDuration: optionsOrVisualDuration,
964
+ keyframes: [0, 1],
965
+ bounce
966
+ } : optionsOrVisualDuration;
967
+ let { restSpeed, restDelta } = options;
968
+ const origin = options.keyframes[0];
969
+ const target = options.keyframes[options.keyframes.length - 1];
970
+ /**
971
+ * This is the Iterator-spec return value. We ensure it's mutable rather than using a generator
972
+ * to reduce GC during animation.
973
+ */
974
+ const state = {
975
+ done: false,
976
+ value: origin
977
+ };
978
+ const { stiffness, damping, mass, duration, velocity, isResolvedFromDuration } = getSpringOptions({
979
+ ...options,
980
+ velocity: -/* @__PURE__ */ millisecondsToSeconds(options.velocity || 0)
981
+ });
982
+ const initialVelocity = velocity || 0;
983
+ const dampingRatio = damping / (2 * Math.sqrt(stiffness * mass));
984
+ const initialDelta = target - origin;
985
+ const undampedAngularFreq = /* @__PURE__ */ millisecondsToSeconds(Math.sqrt(stiffness / mass));
986
+ /**
987
+ * If we're working on a granular scale, use smaller defaults for determining
988
+ * when the spring is finished.
989
+ *
990
+ * These defaults have been selected emprically based on what strikes a good
991
+ * ratio between feeling good and finishing as soon as changes are imperceptible.
992
+ */
993
+ const isGranularScale = Math.abs(initialDelta) < 5;
994
+ restSpeed || (restSpeed = isGranularScale ? springDefaults.restSpeed.granular : springDefaults.restSpeed.default);
995
+ restDelta || (restDelta = isGranularScale ? springDefaults.restDelta.granular : springDefaults.restDelta.default);
996
+ let resolveSpring;
997
+ let resolveVelocity;
998
+ let angularFreq;
999
+ let A;
1000
+ let sinCoeff;
1001
+ let cosCoeff;
1002
+ if (dampingRatio < 1) {
1003
+ angularFreq = calcAngularFreq(undampedAngularFreq, dampingRatio);
1004
+ A = (initialVelocity + dampingRatio * undampedAngularFreq * initialDelta) / angularFreq;
1005
+ resolveSpring = (t) => {
1006
+ const envelope = Math.exp(-dampingRatio * undampedAngularFreq * t);
1007
+ return target - envelope * (A * Math.sin(angularFreq * t) + initialDelta * Math.cos(angularFreq * t));
1008
+ };
1009
+ sinCoeff = dampingRatio * undampedAngularFreq * A + initialDelta * angularFreq;
1010
+ cosCoeff = dampingRatio * undampedAngularFreq * initialDelta - A * angularFreq;
1011
+ resolveVelocity = (t) => {
1012
+ return Math.exp(-dampingRatio * undampedAngularFreq * t) * (sinCoeff * Math.sin(angularFreq * t) + cosCoeff * Math.cos(angularFreq * t));
1013
+ };
1014
+ } else if (dampingRatio === 1) {
1015
+ resolveSpring = (t) => target - Math.exp(-undampedAngularFreq * t) * (initialDelta + (initialVelocity + undampedAngularFreq * initialDelta) * t);
1016
+ const C = initialVelocity + undampedAngularFreq * initialDelta;
1017
+ resolveVelocity = (t) => Math.exp(-undampedAngularFreq * t) * (undampedAngularFreq * C * t - initialVelocity);
1018
+ } else {
1019
+ const dampedAngularFreq = undampedAngularFreq * Math.sqrt(dampingRatio * dampingRatio - 1);
1020
+ resolveSpring = (t) => {
1021
+ const envelope = Math.exp(-dampingRatio * undampedAngularFreq * t);
1022
+ const freqForT = Math.min(dampedAngularFreq * t, 300);
1023
+ return target - envelope * ((initialVelocity + dampingRatio * undampedAngularFreq * initialDelta) * Math.sinh(freqForT) + dampedAngularFreq * initialDelta * Math.cosh(freqForT)) / dampedAngularFreq;
1024
+ };
1025
+ const P = (initialVelocity + dampingRatio * undampedAngularFreq * initialDelta) / dampedAngularFreq;
1026
+ const sinhCoeff = dampingRatio * undampedAngularFreq * P - initialDelta * dampedAngularFreq;
1027
+ const coshCoeff = dampingRatio * undampedAngularFreq * initialDelta - P * dampedAngularFreq;
1028
+ resolveVelocity = (t) => {
1029
+ const envelope = Math.exp(-dampingRatio * undampedAngularFreq * t);
1030
+ const freqForT = Math.min(dampedAngularFreq * t, 300);
1031
+ return envelope * (sinhCoeff * Math.sinh(freqForT) + coshCoeff * Math.cosh(freqForT));
1032
+ };
1033
+ }
1034
+ const generator = {
1035
+ calculatedDuration: isResolvedFromDuration ? duration || null : null,
1036
+ velocity: (t) => /* @__PURE__ */ secondsToMilliseconds(resolveVelocity(t)),
1037
+ next: (t) => {
1038
+ /**
1039
+ * For underdamped physics springs we need both position and
1040
+ * velocity each tick. Compute shared trig values once to avoid
1041
+ * duplicate Math.exp/sin/cos calls on the hot path.
1042
+ */
1043
+ if (!isResolvedFromDuration && dampingRatio < 1) {
1044
+ const envelope = Math.exp(-dampingRatio * undampedAngularFreq * t);
1045
+ const sin = Math.sin(angularFreq * t);
1046
+ const cos = Math.cos(angularFreq * t);
1047
+ const current = target - envelope * (A * sin + initialDelta * cos);
1048
+ const currentVelocity = /* @__PURE__ */ secondsToMilliseconds(envelope * (sinCoeff * sin + cosCoeff * cos));
1049
+ state.done = Math.abs(currentVelocity) <= restSpeed && Math.abs(target - current) <= restDelta;
1050
+ state.value = state.done ? target : current;
1051
+ return state;
1052
+ }
1053
+ const current = resolveSpring(t);
1054
+ if (!isResolvedFromDuration) {
1055
+ const currentVelocity = /* @__PURE__ */ secondsToMilliseconds(resolveVelocity(t));
1056
+ state.done = Math.abs(currentVelocity) <= restSpeed && Math.abs(target - current) <= restDelta;
1057
+ } else state.done = t >= duration;
1058
+ state.value = state.done ? target : current;
1059
+ return state;
1060
+ },
1061
+ toString: () => {
1062
+ const calculatedDuration = Math.min(calcGeneratorDuration(generator), maxGeneratorDuration);
1063
+ const easing = generateLinearEasing((progress) => generator.next(calculatedDuration * progress).value, calculatedDuration, 30);
1064
+ return calculatedDuration + "ms " + easing;
1065
+ },
1066
+ toTransition: () => {}
1067
+ };
1068
+ return generator;
1069
+ }
1070
+ spring.applyToOptions = (options) => {
1071
+ const generatorOptions = createGeneratorEasing(options, 100, spring);
1072
+ options.ease = generatorOptions.ease;
1073
+ options.duration = /* @__PURE__ */ secondsToMilliseconds(generatorOptions.duration);
1074
+ options.type = "keyframes";
1075
+ return options;
1076
+ };
1077
+ //#endregion
1078
+ //#region ../../node_modules/.pnpm/motion-dom@12.42.2/node_modules/motion-dom/dist/es/utils/interpolate.mjs
1079
+ function createMixers(output, ease, customMixer) {
1080
+ const mixers = [];
1081
+ const mixerFactory = customMixer || MotionGlobalConfig.mix || mix;
1082
+ const numMixers = output.length - 1;
1083
+ for (let i = 0; i < numMixers; i++) {
1084
+ let mixer = mixerFactory(output[i], output[i + 1]);
1085
+ if (ease) mixer = pipe(Array.isArray(ease) ? ease[i] || noop : ease, mixer);
1086
+ mixers.push(mixer);
1087
+ }
1088
+ return mixers;
1089
+ }
1090
+ /**
1091
+ * Create a function that maps from a numerical input array to a generic output array.
1092
+ *
1093
+ * Accepts:
1094
+ * - Numbers
1095
+ * - Colors (hex, hsl, hsla, rgb, rgba)
1096
+ * - Complex (combinations of one or more numbers or strings)
1097
+ *
1098
+ * ```jsx
1099
+ * const mixColor = interpolate([0, 1], ['#fff', '#000'])
1100
+ *
1101
+ * mixColor(0.5) // 'rgba(128, 128, 128, 1)'
1102
+ * ```
1103
+ *
1104
+ * TODO Revisit this approach once we've moved to data models for values,
1105
+ * probably not needed to pregenerate mixer functions.
1106
+ *
1107
+ * @public
1108
+ */
1109
+ function interpolate(input, output, { clamp: isClamp = true, ease, mixer } = {}) {
1110
+ const inputLength = input.length;
1111
+ invariant(inputLength === output.length, "Both input and output ranges must be the same length", "range-length");
1112
+ /**
1113
+ * If we're only provided a single input, we can just make a function
1114
+ * that returns the output.
1115
+ */
1116
+ if (inputLength === 1) return () => output[0];
1117
+ if (inputLength === 2 && output[0] === output[1]) return () => output[1];
1118
+ const isZeroDeltaRange = input[0] === input[1];
1119
+ if (input[0] > input[inputLength - 1]) {
1120
+ input = [...input].reverse();
1121
+ output = [...output].reverse();
1122
+ }
1123
+ const mixers = createMixers(output, ease, mixer);
1124
+ const numMixers = mixers.length;
1125
+ const interpolator = (v) => {
1126
+ if (isZeroDeltaRange && v < input[0]) return output[0];
1127
+ let i = 0;
1128
+ if (numMixers > 1) {
1129
+ for (; i < input.length - 2; i++) if (v < input[i + 1]) break;
1130
+ }
1131
+ const progressInRange = /* @__PURE__ */ progress(input[i], input[i + 1], v);
1132
+ return mixers[i](progressInRange);
1133
+ };
1134
+ return isClamp ? (v) => interpolator(clamp(input[0], input[inputLength - 1], v)) : interpolator;
1135
+ }
1136
+ //#endregion
1137
+ //#region ../../node_modules/.pnpm/motion-dom@12.42.2/node_modules/motion-dom/dist/es/animation/keyframes/offsets/fill.mjs
1138
+ function fillOffset(offset, remaining) {
1139
+ const min = offset[offset.length - 1];
1140
+ for (let i = 1; i <= remaining; i++) {
1141
+ const offsetProgress = /* @__PURE__ */ progress(0, remaining, i);
1142
+ offset.push(mixNumber$1(min, 1, offsetProgress));
1143
+ }
1144
+ }
1145
+ //#endregion
1146
+ //#region ../../node_modules/.pnpm/motion-dom@12.42.2/node_modules/motion-dom/dist/es/animation/keyframes/offsets/default.mjs
1147
+ function defaultOffset(arr) {
1148
+ const offset = [0];
1149
+ fillOffset(offset, arr.length - 1);
1150
+ return offset;
1151
+ }
1152
+ //#endregion
1153
+ //#region ../../node_modules/.pnpm/motion-dom@12.42.2/node_modules/motion-dom/dist/es/animation/keyframes/offsets/time.mjs
1154
+ function convertOffsetToTimes(offset, duration) {
1155
+ return offset.map((o) => o * duration);
1156
+ }
1157
+ //#endregion
1158
+ //#region ../../node_modules/.pnpm/motion-dom@12.42.2/node_modules/motion-dom/dist/es/animation/generators/keyframes.mjs
1159
+ function defaultEasing(values, easing) {
1160
+ return values.map(() => easing || easeInOut).splice(0, values.length - 1);
1161
+ }
1162
+ function keyframes({ duration = 300, keyframes: keyframeValues, times, ease = "easeInOut" }) {
1163
+ /**
1164
+ * Easing functions can be externally defined as strings. Here we convert them
1165
+ * into actual functions.
1166
+ */
1167
+ const easingFunctions = /* @__PURE__ */ isEasingArray(ease) ? ease.map(easingDefinitionToFunction) : easingDefinitionToFunction(ease);
1168
+ /**
1169
+ * This is the Iterator-spec return value. We ensure it's mutable rather than using a generator
1170
+ * to reduce GC during animation.
1171
+ */
1172
+ const state = {
1173
+ done: false,
1174
+ value: keyframeValues[0]
1175
+ };
1176
+ const mapTimeToKeyframe = interpolate(convertOffsetToTimes(times && times.length === keyframeValues.length ? times : defaultOffset(keyframeValues), duration), keyframeValues, { ease: Array.isArray(easingFunctions) ? easingFunctions : defaultEasing(keyframeValues, easingFunctions) });
1177
+ return {
1178
+ calculatedDuration: duration,
1179
+ next: (t) => {
1180
+ state.value = mapTimeToKeyframe(t);
1181
+ state.done = t >= duration;
1182
+ return state;
1183
+ }
1184
+ };
1185
+ }
1186
+ //#endregion
1187
+ //#region src/engine.ts
1188
+ function validateTransition(t) {
1189
+ if (t.type === "spring" && (t.duration !== void 0 || t.ease !== void 0)) throw new Error("motion: physical springs do not accept duration or ease");
1190
+ const allowed = [
1191
+ "type",
1192
+ "duration",
1193
+ "delay",
1194
+ "ease",
1195
+ "stiffness",
1196
+ "damping",
1197
+ "mass",
1198
+ "velocity",
1199
+ "restSpeed",
1200
+ "restDelta"
1201
+ ];
1202
+ for (const key of Object.keys(t)) if (!allowed.includes(key)) throw new Error(`motion: unsupported transition ${key}`);
1203
+ if (t.type !== void 0 && t.type !== "tween" && t.type !== "spring") throw new Error("motion: unsupported transition type");
1204
+ for (const key of [
1205
+ "duration",
1206
+ "delay",
1207
+ "stiffness",
1208
+ "damping",
1209
+ "mass",
1210
+ "velocity",
1211
+ "restSpeed",
1212
+ "restDelta"
1213
+ ]) {
1214
+ const value = t[key];
1215
+ if (value !== void 0 && (!Number.isFinite(value) || key !== "velocity" && value < 0)) throw new Error(`motion: invalid ${key}`);
1216
+ }
1217
+ for (const key of [
1218
+ "mass",
1219
+ "stiffness",
1220
+ "damping",
1221
+ "restSpeed",
1222
+ "restDelta"
1223
+ ]) if (t[key] === 0) throw new Error(`motion: ${key} must be positive`);
1224
+ if (t.ease !== void 0) {
1225
+ if (Array.isArray(t.ease)) {
1226
+ if (t.ease.length !== 4 || !t.ease.every(Number.isFinite) || t.ease[0] < 0 || t.ease[0] > 1 || t.ease[2] < 0 || t.ease[2] > 1) throw new Error("motion: invalid cubic Bezier");
1227
+ } else if (![
1228
+ "linear",
1229
+ "easeIn",
1230
+ "easeOut",
1231
+ "easeInOut"
1232
+ ].includes(t.ease)) throw new Error("motion: unsupported easing");
1233
+ }
1234
+ }
1235
+ function runAnimation(clock, from, to, transition, update, complete) {
1236
+ validateTransition(transition);
1237
+ let frame = 0;
1238
+ let settled = false;
1239
+ let resolve;
1240
+ const finished = new Promise((done) => {
1241
+ resolve = done;
1242
+ });
1243
+ const settle = (result) => {
1244
+ if (settled) return;
1245
+ settled = true;
1246
+ clock.cancel(frame);
1247
+ resolve(result);
1248
+ if (result === "finished") complete?.();
1249
+ };
1250
+ const duration = transition.duration ?? .3;
1251
+ const generator = transition.type === "spring" ? spring({
1252
+ keyframes: [from, to],
1253
+ stiffness: transition.stiffness ?? 100,
1254
+ damping: transition.damping ?? 10,
1255
+ mass: transition.mass ?? 1,
1256
+ velocity: transition.velocity ?? 0,
1257
+ restSpeed: transition.restSpeed,
1258
+ restDelta: transition.restDelta
1259
+ }) : keyframes({
1260
+ keyframes: [from, to],
1261
+ duration: duration * 1e3,
1262
+ ease: transition.ease ?? "easeInOut"
1263
+ });
1264
+ const start = clock.now() + (transition.delay ?? 0) * 1e3;
1265
+ const tick = () => {
1266
+ if (settled) return;
1267
+ const elapsed = Math.max(0, clock.now() - start);
1268
+ if (clock.now() >= start) {
1269
+ const state = generator.next(elapsed);
1270
+ update(state.done ? to : state.value);
1271
+ if (state.done) {
1272
+ settle("finished");
1273
+ return;
1274
+ }
1275
+ }
1276
+ if (!settled) frame = clock.request(tick);
1277
+ };
1278
+ if (transition.type !== "spring" && duration === 0 && !transition.delay) {
1279
+ update(to);
1280
+ settle("finished");
1281
+ } else frame = clock.request(tick);
1282
+ return {
1283
+ finished,
1284
+ stop: (reason = "cancelled") => settle(reason)
1285
+ };
1286
+ }
1287
+ //#endregion
1288
+ //#region src/value.ts
1289
+ /** Numeric value with direct subscriptions; it does not subscribe Octane renders. */
1290
+ var MotionValue = class {
1291
+ clock;
1292
+ current;
1293
+ previous;
1294
+ velocity = 0;
1295
+ updated;
1296
+ controls;
1297
+ generation = 0;
1298
+ listeners = /* @__PURE__ */ new Map();
1299
+ passive;
1300
+ disposed = false;
1301
+ constructor(initial, clock) {
1302
+ this.clock = clock;
1303
+ this.assert(initial);
1304
+ this.current = this.previous = initial;
1305
+ this.updated = clock.now();
1306
+ }
1307
+ assert(value) {
1308
+ if (!Number.isFinite(value)) throw new Error("motion: values must be finite numbers");
1309
+ }
1310
+ /** Read the current sample. */
1311
+ get() {
1312
+ return this.current;
1313
+ }
1314
+ /** Read the previous sample. */
1315
+ getPrevious() {
1316
+ return this.previous;
1317
+ }
1318
+ /** Velocity in units per second; stale samples have zero velocity. */
1319
+ getVelocity() {
1320
+ return this.clock.now() - this.updated > 30 ? 0 : this.velocity;
1321
+ }
1322
+ /** Set immediately, or animate when this is a useSpring value. */
1323
+ set(value) {
1324
+ this.assert(value);
1325
+ if (this.disposed) return;
1326
+ if (this.passive) this.passive(value);
1327
+ else {
1328
+ this.stop();
1329
+ this.write(value);
1330
+ }
1331
+ }
1332
+ /** Snap and stop current playback, resetting velocity. */
1333
+ jump(value) {
1334
+ this.assert(value);
1335
+ this.stop();
1336
+ this.write(value);
1337
+ this.velocity = 0;
1338
+ }
1339
+ /** Subscribe without causing a component render. Returns an unsubscribe function. */
1340
+ on(event, callback) {
1341
+ let listeners = this.listeners.get(event);
1342
+ if (!listeners) this.listeners.set(event, listeners = /* @__PURE__ */ new Set());
1343
+ listeners.add(callback);
1344
+ return () => {
1345
+ listeners.delete(callback);
1346
+ };
1347
+ }
1348
+ emit(event, value) {
1349
+ for (const callback of [...this.listeners.get(event) ?? []]) callback(value);
1350
+ }
1351
+ write(value) {
1352
+ if (this.disposed) return;
1353
+ const now = this.clock.now();
1354
+ const elapsed = now - this.updated;
1355
+ if (elapsed > 0) this.velocity = elapsed > 30 ? 0 : (value - this.current) * 1e3 / elapsed;
1356
+ this.previous = this.current;
1357
+ this.current = value;
1358
+ this.updated = now;
1359
+ if (value !== this.previous) this.emit("change", value);
1360
+ }
1361
+ /** Animate to a destination. New playback replaces old playback. */
1362
+ animate(target, transition = {}) {
1363
+ this.assert(target);
1364
+ validateTransition(transition);
1365
+ if (this.disposed) return {
1366
+ finished: Promise.resolve("cancelled"),
1367
+ stop() {}
1368
+ };
1369
+ const velocity = transition.velocity ?? this.getVelocity();
1370
+ this.stop("replaced");
1371
+ const generation = ++this.generation;
1372
+ this.emit("animationStart");
1373
+ const controls = runAnimation(this.clock, this.current, target, {
1374
+ ...transition,
1375
+ velocity
1376
+ }, (value) => this.write(value));
1377
+ this.controls = controls;
1378
+ controls.finished.then((result) => {
1379
+ if (generation !== this.generation || this.disposed) return;
1380
+ this.controls = void 0;
1381
+ if (result === "finished") this.emit("animationComplete");
1382
+ });
1383
+ return controls;
1384
+ }
1385
+ /** Stop playback at its current value. */
1386
+ stop(reason = "cancelled") {
1387
+ ++this.generation;
1388
+ if (this.controls) {
1389
+ this.controls.stop(reason);
1390
+ this.controls = void 0;
1391
+ this.emit("animationCancel");
1392
+ }
1393
+ }
1394
+ /** Release playback and listeners when the owning component unmounts. */
1395
+ destroy() {
1396
+ this.stop();
1397
+ this.emit("destroy");
1398
+ this.listeners.clear();
1399
+ this.passive = void 0;
1400
+ this.disposed = true;
1401
+ }
1402
+ /** @internal Install the useSpring setter interception. */
1403
+ attach(setter) {
1404
+ this.passive = setter;
1405
+ return () => {
1406
+ this.passive = void 0;
1407
+ this.stop();
1408
+ };
1409
+ }
1410
+ };
1411
+ //#endregion
1412
+ //#region src/controller.ts
1413
+ var keys = [
1414
+ "opacity",
1415
+ "x",
1416
+ "y",
1417
+ "scale",
1418
+ "scaleX",
1419
+ "scaleY",
1420
+ "rotate"
1421
+ ];
1422
+ var defaults = {
1423
+ opacity: 1,
1424
+ x: 0,
1425
+ y: 0,
1426
+ scale: 1,
1427
+ scaleX: 1,
1428
+ scaleY: 1,
1429
+ rotate: 0
1430
+ };
1431
+ function validateTarget(target) {
1432
+ for (const [key, value] of Object.entries(target ?? {})) if (!keys.includes(key) || !Number.isFinite(value)) throw new Error(`motion: unsupported target ${key}; expected a finite numeric motion channel`);
1433
+ }
1434
+ var Controller = class {
1435
+ clock;
1436
+ values = /* @__PURE__ */ new Map();
1437
+ write;
1438
+ generation = 0;
1439
+ constructor(clock) {
1440
+ this.clock = clock;
1441
+ }
1442
+ value(key) {
1443
+ let value = this.values.get(key);
1444
+ if (!value) {
1445
+ value = new MotionValue(defaults[key], this.clock);
1446
+ this.values.set(key, value);
1447
+ value.on("change", () => this.flush());
1448
+ }
1449
+ return value;
1450
+ }
1451
+ attach(write) {
1452
+ this.write = write;
1453
+ this.flush();
1454
+ }
1455
+ snapshot() {
1456
+ return Object.fromEntries([...this.values].map(([key, value]) => [key, value.get()]));
1457
+ }
1458
+ flush() {
1459
+ this.write?.(Object.fromEntries([...this.values].map(([key, value]) => [key, value.get()])));
1460
+ }
1461
+ set(key, next) {
1462
+ this.value(key).jump(next);
1463
+ }
1464
+ seed(target) {
1465
+ validateTarget(target);
1466
+ for (const [key, value] of Object.entries(target)) this.set(key, value);
1467
+ }
1468
+ async animate(target, transition, reduced) {
1469
+ validateTarget(target);
1470
+ const generation = ++this.generation;
1471
+ for (const value of this.values.values()) value.stop("replaced");
1472
+ const jobs = Object.entries(target).map(([key, to]) => {
1473
+ return this.value(key).animate(to, reduced && key !== "opacity" ? { duration: 0 } : transition).finished;
1474
+ });
1475
+ const results = await Promise.all(jobs);
1476
+ if (generation !== this.generation) return "replaced";
1477
+ return results.every((result) => result === "finished") ? "finished" : "cancelled";
1478
+ }
1479
+ stop() {
1480
+ ++this.generation;
1481
+ for (const value of this.values.values()) value.stop();
1482
+ }
1483
+ destroy() {
1484
+ this.stop();
1485
+ for (const value of this.values.values()) value.destroy();
1486
+ this.values.clear();
1487
+ this.write = void 0;
1488
+ }
1489
+ };
1490
+ //#endregion
1491
+ //#region src/components.tsrx
1492
+ var _hs$$1 = /* @__PURE__ */ hookSlots(19);
1493
+ var _h$0$1 = /* @__PURE__ */ Symbol(_hs$$1);
1494
+ var _h$1$1 = /* @__PURE__ */ Symbol(_hs$$1 + 1);
1495
+ var _h$2$1 = /* @__PURE__ */ Symbol(_hs$$1 + 2);
1496
+ var _h$3$1 = /* @__PURE__ */ Symbol(_hs$$1 + 3);
1497
+ var _h$4$1 = /* @__PURE__ */ Symbol(_hs$$1 + 4);
1498
+ var _h$5$1 = /* @__PURE__ */ Symbol(_hs$$1 + 5);
1499
+ var _h$6$1 = /* @__PURE__ */ Symbol(_hs$$1 + 6);
1500
+ var _h$7$1 = /* @__PURE__ */ Symbol(_hs$$1 + 7);
1501
+ var _h$8 = /* @__PURE__ */ Symbol(_hs$$1 + 8);
1502
+ var _h$9 = /* @__PURE__ */ Symbol(_hs$$1 + 9);
1503
+ var _h$10 = /* @__PURE__ */ Symbol(_hs$$1 + 10);
1504
+ var _h$11 = /* @__PURE__ */ Symbol(_hs$$1 + 11);
1505
+ var _h$12 = /* @__PURE__ */ Symbol(_hs$$1 + 12);
1506
+ var _h$13 = /* @__PURE__ */ Symbol(_hs$$1 + 13);
1507
+ var _h$14 = /* @__PURE__ */ Symbol(_hs$$1 + 14);
1508
+ var _h$15 = /* @__PURE__ */ Symbol(_hs$$1 + 15);
1509
+ var _h$16 = /* @__PURE__ */ Symbol(_hs$$1 + 16);
1510
+ var _h$17 = /* @__PURE__ */ Symbol(_hs$$1 + 17);
1511
+ var _h$18 = /* @__PURE__ */ Symbol(_hs$$1 + 18);
1512
+ var __octaneUniversalPlan0 = universalPlan("nativescript", {
1513
+ "kind": "slot",
1514
+ "slot": 0
1515
+ });
1516
+ var __octaneUniversalPlan1 = universalPlan("nativescript", {
1517
+ "kind": "slot",
1518
+ "slot": 0
1519
+ });
1520
+ var __octaneUniversalPlan2 = universalPlan("nativescript", {
1521
+ "kind": "slot",
1522
+ "slot": 0
1523
+ });
1524
+ function useMotion(props) {
1525
+ for (const name of [
1526
+ "drag",
1527
+ "layout",
1528
+ "layoutId",
1529
+ "variants",
1530
+ "whileTap",
1531
+ "whileHover",
1532
+ "whileFocus",
1533
+ "whileInView"
1534
+ ]) if (name in props) throw new Error(`motion: ${name} is outside the supported subset`);
1535
+ const presence = useContext(PresenceContext);
1536
+ if (props.exit && !presence) throw new Error("motion: exit requires a mounted Presence boundary");
1537
+ const config = useContext(ConfigContext);
1538
+ const systemReduced = withSlot(_h$0$1, useReducedMotion);
1539
+ const reduced = config.reducedMotion === "always" || config.reducedMotion === "user" && systemReduced;
1540
+ const transition = props.transition ?? config.transition ?? {};
1541
+ validateTransition(transition);
1542
+ validateTarget(props.animate);
1543
+ validateTarget(props.exit);
1544
+ if (props.initial !== false) validateTarget(props.initial);
1545
+ const latest = useRef(props, _h$1$1);
1546
+ latest.current = props;
1547
+ const state = useRef(null, _h$2$1);
1548
+ if (!state.current) state.current = {
1549
+ controller: new Controller(clock),
1550
+ initialized: false
1551
+ };
1552
+ const current = state.current;
1553
+ const style = {};
1554
+ const bindings = [];
1555
+ for (const [key, value] of Object.entries(props.style ?? {})) if (keys.includes(key)) {
1556
+ if (!(value instanceof MotionValue) && (typeof value !== "number" || !Number.isFinite(value))) throw new Error(`motion: invalid style ${key}`);
1557
+ if (value instanceof MotionValue && (props.animate?.[key] !== void 0 || props.exit?.[key] !== void 0 || props.initial && props.initial[key] !== void 0)) throw new Error(`motion: ${key} has both an animate target and a MotionValue writer`);
1558
+ bindings.push([key, value]);
1559
+ } else {
1560
+ if (value instanceof MotionValue || [
1561
+ "transform",
1562
+ "translateX",
1563
+ "translateY",
1564
+ "animation",
1565
+ "transition"
1566
+ ].includes(key)) throw new Error(`motion: unsupported or conflicting style ${key}`);
1567
+ style[key] = value;
1568
+ }
1569
+ const previous = useRef(bindings, _h$3$1);
1570
+ const boundKeys = useRef([], _h$4$1);
1571
+ const firstBinding = useRef(true, _h$5$1);
1572
+ const firstAnimation = useRef(true, _h$6$1);
1573
+ if (previous.current.length !== bindings.length || previous.current.some(([key, value], i) => key !== bindings[i][0] || value !== bindings[i][1])) previous.current = bindings;
1574
+ const bind = useRef(() => {}, _h$7$1);
1575
+ bind.current = (host) => {
1576
+ if (!host) return;
1577
+ if (current.host !== host) {
1578
+ current.adapter?.restore();
1579
+ current.host = host;
1580
+ current.adapter = attachHost(host);
1581
+ if (!current.initialized) {
1582
+ const baseline = current.adapter.read();
1583
+ for (const [key, value] of previous.current) baseline[key] = value instanceof MotionValue ? value.get() : value;
1584
+ current.controller.seed(baseline);
1585
+ current.controller.seed(props.initial === false ? props.animate ?? {} : props.initial ?? {});
1586
+ current.initialized = true;
1587
+ }
1588
+ current.controller.attach(current.adapter.write);
1589
+ }
1590
+ current.controller.flush();
1591
+ latest.current.bind?.(host);
1592
+ };
1593
+ const playback = useRef({
1594
+ transition,
1595
+ reduced
1596
+ }, _h$8);
1597
+ playback.current = {
1598
+ transition,
1599
+ reduced
1600
+ };
1601
+ const returning = useRef(null, _h$9);
1602
+ const member = useRef(null, _h$10);
1603
+ if (!member.current) member.current = {
1604
+ exit() {
1605
+ const snapshot = current.controller.snapshot();
1606
+ returning.current ??= {};
1607
+ for (const key of Object.keys(latest.current.exit ?? {})) if (!(key in returning.current)) returning.current[key] = snapshot[key];
1608
+ return current.controller.animate(latest.current.exit ?? {}, playback.current.transition, playback.current.reduced);
1609
+ },
1610
+ enter() {
1611
+ const target = {
1612
+ ...returning.current,
1613
+ ...latest.current.animate
1614
+ };
1615
+ returning.current = null;
1616
+ current.controller.animate(target, playback.current.transition, playback.current.reduced).then((result) => {
1617
+ if (result === "finished" && current.host && presence?.present) latest.current.onAnimationComplete?.();
1618
+ });
1619
+ }
1620
+ };
1621
+ useLayoutEffect(() => presence?.register(member.current), [presence], _h$11);
1622
+ const stableBind = useRef((host) => bind.current(host), _h$12).current;
1623
+ useLayoutEffect(() => () => {
1624
+ current.controller.destroy();
1625
+ current.host = void 0;
1626
+ current.adapter = void 0;
1627
+ }, [], _h$13);
1628
+ useLayoutEffect(() => {
1629
+ const off = [];
1630
+ for (const key of boundKeys.current) if (!previous.current.some(([next]) => key === next)) current.controller.set(key, defaults[key]);
1631
+ boundKeys.current = previous.current.map(([key]) => key);
1632
+ for (const [key, value] of previous.current) {
1633
+ if (!firstBinding.current) current.controller.set(key, value instanceof MotionValue ? value.get() : value);
1634
+ if (value instanceof MotionValue) off.push(value.on("change", (next) => current.controller.set(key, next)));
1635
+ }
1636
+ firstBinding.current = false;
1637
+ return () => off.forEach((unsubscribe) => unsubscribe());
1638
+ }, [previous.current], _h$14);
1639
+ useLayoutEffect(() => {
1640
+ let active = true;
1641
+ const skip = firstAnimation.current && props.initial === false;
1642
+ firstAnimation.current = false;
1643
+ if (presence && !presence.present) presence.restart(member.current);
1644
+ else if (props.animate && !skip) current.controller.animate(props.animate, transition, reduced).then((result) => {
1645
+ if (active && result === "finished") latest.current.onAnimationComplete?.();
1646
+ });
1647
+ return () => {
1648
+ active = false;
1649
+ current.controller.stop();
1650
+ };
1651
+ }, [
1652
+ JSON.stringify(props.animate),
1653
+ JSON.stringify(props.exit),
1654
+ JSON.stringify(transition),
1655
+ reduced
1656
+ ], _h$15);
1657
+ const { initial, exit, animate, transition: ignoredTransition, onAnimationComplete, style: ignoredStyle, bind: ignoredBind, ...rest } = props;
1658
+ return {
1659
+ ...rest,
1660
+ style,
1661
+ bind: stableBind
1662
+ };
1663
+ }
1664
+ var MotionView = defineUniversalComponent("nativescript", function MotionView(props) {
1665
+ return universalValue(__octaneUniversalPlan0, [universalComponent("nativescript", View, universalProps([["spread", withSlot(_h$16, useMotion, props)]], props.children))]);
1666
+ }, { "module": "@nativescript-community/octane" });
1667
+ var MotionRow = defineUniversalComponent("nativescript", function MotionRow(props) {
1668
+ return universalValue(__octaneUniversalPlan1, [universalComponent("nativescript", Row, universalProps([["spread", withSlot(_h$17, useMotion, props)]], props.children))]);
1669
+ }, { "module": "@nativescript-community/octane" });
1670
+ var MotionPressable = defineUniversalComponent("nativescript", function MotionPressable(props) {
1671
+ return universalValue(__octaneUniversalPlan2, [universalComponent("nativescript", Pressable, universalProps([["spread", withSlot(_h$18, useMotion, props)]], props.children))]);
1672
+ }, { "module": "@nativescript-community/octane" });
1673
+ //#endregion
1674
+ //#region src/hooks.tsrx
1675
+ var _hs$ = /* @__PURE__ */ hookSlots(8);
1676
+ var _h$0 = /* @__PURE__ */ Symbol(_hs$);
1677
+ var _h$1 = /* @__PURE__ */ Symbol(_hs$ + 1);
1678
+ var _h$2 = /* @__PURE__ */ Symbol(_hs$ + 2);
1679
+ var _h$3 = /* @__PURE__ */ Symbol(_hs$ + 3);
1680
+ var _h$4 = /* @__PURE__ */ Symbol(_hs$ + 4);
1681
+ var _h$5 = /* @__PURE__ */ Symbol(_hs$ + 5);
1682
+ var _h$6 = /* @__PURE__ */ Symbol(_hs$ + 6);
1683
+ var _h$7 = /* @__PURE__ */ Symbol(_hs$ + 7);
1684
+ function useMotionValue(initial) {
1685
+ const ref = useRef(null, _h$0);
1686
+ if (!ref.current) ref.current = new MotionValue(initial, clock);
1687
+ const value = ref.current;
1688
+ useLayoutEffect(() => () => value.destroy(), [], _h$1);
1689
+ return value;
1690
+ }
1691
+ function useMotionValueEvent(value, event, callback) {
1692
+ useLayoutEffect(() => value.on(event, callback), [
1693
+ value,
1694
+ event,
1695
+ callback
1696
+ ], _h$2);
1697
+ }
1698
+ function useTransform(source, input, output, options) {
1699
+ const sources = Array.isArray(source) ? source : [source];
1700
+ if (Array.isArray(input) && (!output || input.length !== output.length || input.length < 2)) throw new Error("motion: transform ranges must have matching lengths >= 2");
1701
+ const transform = typeof input === "function" ? input : interpolate(input, output, options);
1702
+ const read = () => transform(Array.isArray(source) ? sources.map((value) => value.get()) : source.get());
1703
+ const value = withSlot(_h$3, useMotionValue, read());
1704
+ const previous = useRef(sources, _h$4);
1705
+ if (previous.current.length !== sources.length || previous.current.some((value, i) => value !== sources[i])) previous.current = sources;
1706
+ useLayoutEffect(() => {
1707
+ const update = () => value.set(read());
1708
+ const off = sources.map((source) => source.on("change", update));
1709
+ update();
1710
+ return () => off.forEach((unsubscribe) => unsubscribe());
1711
+ }, [
1712
+ previous.current,
1713
+ input,
1714
+ output,
1715
+ options?.clamp
1716
+ ], _h$5);
1717
+ return value;
1718
+ }
1719
+ function useSpring(source, options = {}) {
1720
+ const value = withSlot(_h$6, useMotionValue, source instanceof MotionValue ? source.get() : source);
1721
+ useLayoutEffect(() => {
1722
+ const follow = (target) => {
1723
+ value.animate(target, {
1724
+ ...options,
1725
+ type: "spring"
1726
+ });
1727
+ };
1728
+ const detach = value.attach(follow);
1729
+ const unsubscribe = source instanceof MotionValue ? source.on("change", follow) : void 0;
1730
+ if (source instanceof MotionValue && source.get() !== value.get()) follow(source.get());
1731
+ return () => {
1732
+ unsubscribe?.();
1733
+ detach();
1734
+ };
1735
+ }, [source instanceof MotionValue ? source : null, JSON.stringify(options)], _h$7);
1736
+ return value;
1737
+ }
1738
+ //#endregion
1739
+ //#region src/index.ts
1740
+ /** Bounded motion hosts for shared xplat UI primitives. */
1741
+ var motion = {
1742
+ View: MotionView,
1743
+ Row: MotionRow,
1744
+ Pressable: MotionPressable
1745
+ };
1746
+ //#endregion
1747
+ export { MotionConfig, Presence, motion, useMotionValue, useMotionValueEvent, useReducedMotion, useSpring, useTransform };