PageSourceSearch

https://wolli.ai/wp-content/plugins/elementor/assets/lib/motion/motion.js?ver=11.13.5

js wolli.ai collected 2026-10-05 15:59:53 UTC 290,987 bytes, 7,621 lines download raw bytes

vendor: 14,473 bytes, lines 1-403
1(function (global, factory) {
2    typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) :
3    typeof define === 'function' && define.amd ? define(['exports'], factory) :
4    (global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global.Motion = {}));
5})(this, (function (exports) { 'use strict';
6
7    function addUniqueItem(arr, item) {
8        if (arr.indexOf(item) === -1)
9            arr.push(item);
10    }
11    function removeItem(arr, item) {
12        const index = arr.indexOf(item);
13        if (index > -1)
14            arr.splice(index, 1);
15    }
16    // Adapted from array-move
17    function moveItem([...arr], fromIndex, toIndex) {
18        const startIndex = fromIndex < 0 ? arr.length + fromIndex : fromIndex;
19        if (startIndex >= 0 && startIndex < arr.length) {
20            const endIndex = toIndex < 0 ? arr.length + toIndex : toIndex;
21            const [item] = arr.splice(fromIndex, 1);
22            arr.splice(endIndex, 0, item);
23        }
24        return arr;
25    }
26
27    const clamp = (min, max, v) => {
28        if (v > max)
29            return max;
30        if (v < min)
31            return min;
32        return v;
33    };
34
35    function formatErrorMessage(message, errorCode) {
36        return errorCode
37            ? `${message}. For more information and steps for solving, visit https://motion.dev/troubleshooting/${errorCode}`
38            : message;
39    }
40
41    exports.warning = () => { };
42    exports.invariant = () => { };
43    {
44        exports.warning = (check, message, errorCode) => {
45            if (!check && typeof console !== "undefined") {
46                console.warn(formatErrorMessage(message, errorCode));
47            }
48        };
49        exports.invariant = (check, message, errorCode) => {
50            if (!check) {
51                throw new Error(formatErrorMessage(message, errorCode));
52            }
53        };
54    }
55
56    const MotionGlobalConfig = {};
57
58    /**
59     * Check if value is a numerical string, ie a string that is purely a number eg "100" or "-100.1"
60     */
61    const isNumericalString = (v) => /^-?(?:\d+(?:\.\d+)?|\.\d+)$/u.test(v);
62
63    function isObject(value) {
64        return typeof value === "object" && value !== null;
65    }
66
67    /**
68     * Check if the value is a zero value string like "0px" or "0%"
69     */
70    const isZeroValueString = (v) => /^0[^.\s]+$/u.test(v);
71
72    /*#__NO_SIDE_EFFECTS__*/
73    function memo(callback) {
74        let result;
75        return () => {
76            if (result === undefined)
77                result = callback();
78            return result;
79        };
80    }
81
82    /*#__NO_SIDE_EFFECTS__*/
83    const noop = (any) => any;
84
85    /**
86     * Pipe
87     * Compose other transformers to run linearily
88     * pipe(min(20), max(40))
89     * @param  {...functions} transformers
90     * @return {function}
91     */
92    const combineFunctions = (a, b) => (v) => b(a(v));
93    const pipe = (...transformers) => transformers.reduce(combineFunctions);
94
95    /*
96      Progress within given range
97
98      Given a lower limit and an upper limit, we return the progress
99      (expressed as a number 0-1) represented by the given value, and
100      limit that progress to within 0-1.
101
102      @param [number]: Lower limit
103      @param [number]: Upper limit
104      @param [number]: Value to find progress within given range
105      @return [number]: Progress of value within range as expressed 0-1
106    */
107    /*#__NO_SIDE_EFFECTS__*/
108    const progress = (from, to, value) => {
109        const toFromDifference = to - from;
110        return toFromDifference === 0 ? 1 : (value - from) / toFromDifference;
111    };
112
113    class SubscriptionManager {
114        constructor() {
115            this.subscriptions = [];
116        }
117        add(handler) {
118            addUniqueItem(this.subscriptions, handler);
119            return () => removeItem(this.subscriptions, handler);
120        }
121        notify(a, b, c) {
122            const numSubscriptions = this.subscriptions.length;
123            if (!numSubscriptions)
124                return;
125            if (numSubscriptions === 1) {
126                /**
127                 * If there's only a single handler we can just call it without invoking a loop.
128                 */
129                this.subscriptions[0](a, b, c);
130            }
131            else {
132                for (let i = 0; i < numSubscriptions; i++) {
133                    /**
134                     * Check whether the handler exists before firing as it's possible
135                     * the subscriptions were modified during this loop running.
136                     */
137                    const handler = this.subscriptions[i];
138                    handler && handler(a, b, c);
139                }
140            }
141        }
142        getSize() {
143            return this.subscriptions.length;
144        }
145        clear() {
146            this.subscriptions.length = 0;
147        }
148    }
149
150    /**
151     * Converts seconds to milliseconds
152     *
153     * @param seconds - Time in seconds.
154     * @return milliseconds - Converted time in milliseconds.
155     */
156    /*#__NO_SIDE_EFFECTS__*/
157    const secondsToMilliseconds = (seconds) => seconds * 1000;
158    /*#__NO_SIDE_EFFECTS__*/
159    const millisecondsToSeconds = (milliseconds) => milliseconds / 1000;
160
161    /*
162      Convert velocity into velocity per second
163
164      @param [number]: Unit per frame
165      @param [number]: Frame duration in ms
166    */
167    function velocityPerSecond(velocity, frameDuration) {
168        return frameDuration ? velocity * (1000 / frameDuration) : 0;
169    }
170
171    const warned = new Set();
172    function hasWarned(message) {
173        return warned.has(message);
174    }
175    function warnOnce(condition, message, errorCode) {
176        if (condition || warned.has(message))
177            return;
178        console.warn(formatErrorMessage(message, errorCode));
179        warned.add(message);
180    }
181
182    const wrap = (min, max, v) => {
183        const rangeSize = max - min;
184        return ((((v - min) % rangeSize) + rangeSize) % rangeSize) + min;
185    };
186
187    /*
188      Bezier function generator
189      This has been modified from Gaëtan Renaudeau's BezierEasing
190      https://github.com/gre/bezier-easing/blob/master/src/index.js
191      https://github.com/gre/bezier-easing/blob/master/LICENSE
192      
193      I've removed the newtonRaphsonIterate algo because in benchmarking it
194      wasn't noticeably faster than binarySubdivision, indeed removing it
195      usually improved times, depending on the curve.
196      I also removed the lookup table, as for the added bundle size and loop we're
197      only cutting ~4 or so subdivision iterations. I bumped the max iterations up
198      to 12 to compensate and this still tended to be faster for no perceivable
199      loss in accuracy.
200      Usage
201        const easeOut = cubicBezier(.17,.67,.83,.67);
202        const x = easeOut(0.5); // returns 0.627...
203    */
204    // Returns x(t) given t, x1, and x2, or y(t) given t, y1, and y2.
205    const calcBezier = (t, a1, a2) => (((1.0 - 3.0 * a2 + 3.0 * a1) * t + (3.0 * a2 - 6.0 * a1)) * t + 3.0 * a1) *
206        t;
207    const subdivisionPrecision = 0.0000001;
208    const subdivisionMaxIterations = 12;
209    function binarySubdivide(x, lowerBound, upperBound, mX1, mX2) {
210        let currentX;
211        let currentT;
212        let i = 0;
213        do {
214            currentT = lowerBound + (upperBound - lowerBound) / 2.0;
215            currentX = calcBezier(currentT, mX1, mX2) - x;
216            if (currentX > 0.0) {
217                upperBound = currentT;
218            }
219            else {
220                lowerBound = currentT;
221            }
222        } while (Math.abs(currentX) > subdivisionPrecision &&
223            ++i < subdivisionMaxIterations);
224        return currentT;
225    }
226    function cubicBezier(mX1, mY1, mX2, mY2) {
227        // If this is a linear gradient, return linear easing
228        if (mX1 === mY1 && mX2 === mY2)
229            return noop;
230        const getTForX = (aX) => binarySubdivide(aX, 0, 1, mX1, mX2);
231        // If animation is at start/end, return t without easing
232        return (t) => t === 0 || t === 1 ? t : calcBezier(getTForX(t), mY1, mY2);
233    }
234
235    // Accepts an easing function and returns a new one that outputs mirrored values for
236    // the second half of the animation. Turns easeIn into easeInOut.
237    const mirrorEasing = (easing) => (p) => p <= 0.5 ? easing(2 * p) / 2 : (2 - easing(2 * (1 - p))) / 2;
238
239    // Accepts an easing function and returns a new one that outputs reversed values.
240    // Turns easeIn into easeOut.
241    const reverseEasing = (easing) => (p) => 1 - easing(1 - p);
242
243    const backOut = /*@__PURE__*/ cubicBezier(0.33, 1.53, 0.69, 0.99);
244    const backIn = /*@__PURE__*/ reverseEasing(backOut);
245    const backInOut = /*@__PURE__*/ mirrorEasing(backIn);
246
247    const anticipate = (p) => (p *= 2) < 1 ? 0.5 * backIn(p) : 0.5 * (2 - Math.pow(2, -10 * (p - 1)));
248
249    const circIn = (p) => 1 - Math.sin(Math.acos(p));
250    const circOut = reverseEasing(circIn);
251    const circInOut = mirrorEasing(circIn);
252
253    const easeIn = /*@__PURE__*/ cubicBezier(0.42, 0, 1, 1);
254    const easeOut = /*@__PURE__*/ cubicBezier(0, 0, 0.58, 1);
255    const easeInOut = /*@__PURE__*/ cubicBezier(0.42, 0, 0.58, 1);
256
257    function steps(numSteps, direction = "end") {
258        return (progress) => {
259            progress =
260                direction === "end"
261                    ? Math.min(progress, 0.999)
262                    : Math.max(progress, 0.001);
263            const expanded = progress * numSteps;
264            const rounded = direction === "end" ? Math.floor(expanded) : Math.ceil(expanded);
265            return clamp(0, 1, rounded / numSteps);
266        };
267    }
268
269    const isEasingArray = (ease) => {
270        return Array.isArray(ease) && typeof ease[0] !== "number";
271    };
272
273    function getEasingForSegment(easing, i) {
274        return isEasingArray(easing) ? easing[wrap(0, easing.length, i)] : easing;
275    }
276
277    const isBezierDefinition = (easing) => Array.isArray(easing) && typeof easing[0] === "number";
278
279    const easingLookup = {
280        linear: noop,
281        easeIn,
282        easeInOut,
283        easeOut,
284        circIn,
285        circInOut,
286        circOut,
287        backIn,
288        backInOut,
289        backOut,
290        anticipate,
291    };
292    const isValidEasing = (easing) => {
293        return typeof easing === "string";
294    };
295    const easingDefinitionToFunction = (definition) => {
296        if (isBezierDefinition(definition)) {
297            // If cubic bezier definition, create bezier curve
298            exports.invariant(definition.length === 4, `Cubic bezier arrays must contain four numerical values.`, "cubic-bezier-length");
299            const [x1, y1, x2, y2] = definition;
300            return cubicBezier(x1, y1, x2, y2);
301        }
302        else if (isValidEasing(definition)) {
303            // Else lookup from table
304            exports.invariant(easingLookup[definition] !== undefined, `Invalid easing type '${definition}'`, "invalid-easing-type");
305            return easingLookup[definition];
306        }
307        return definition;
308    };
309
310    const stepsOrder = [
311        "setup", // Compute
312        "read", // Read
313        "resolveKeyframes", // Write/Read/Write/Read
314        "preUpdate", // Compute
315        "update", // Compute
316        "preRender", // Compute
317        "render", // Write
318        "postRender", // Compute
319    ];
320
321    const statsBuffer = {
322        value: null,
323        addProjectionMetrics: null,
324    };
325
326    function createRenderStep(runNextFrame, stepName) {
327        /**
328         * We create and reuse two queues, one to queue jobs for the current frame
329         * and one for the next. We reuse to avoid triggering GC after x frames.
330         */
331        let thisFrame = new Set();
332        let nextFrame = new Set();
333        /**
334         * Track whether we're currently processing jobs in this step. This way
335         * we can decide whether to schedule new jobs for this frame or next.
336         */
337        let isProcessing = false;
338        let flushNextFrame = false;
339        /**
340         * A set of processes which were marked keepAlive when scheduled.
341         */
342        const toKeepAlive = new WeakSet();
343        let latestFrameData = {
344            delta: 0.0,
345            timestamp: 0.0,
346            isProcessing: false,
347        };
348        let numCalls = 0;
349        function triggerCallback(callback) {
350            if (toKeepAlive.has(callback)) {
351                step.schedule(callback);
352                runNextFrame();
353            }
354            numCalls++;
355            callback(latestFrameData);
356        }
357        const step = {
358            /**
359             * Schedule a process to run on the next frame.
360             */
361            schedule: (callback, keepAlive = false, immediate = false) => {
362                const addToCurrentFrame = immediate && isProcessing;
363                const queue = addToCurrentFrame ? thisFrame : nextFrame;
364                if (keepAlive)
365                    toKeepAlive.add(callback);
366                if (!queue.has(callback))
367                    queue.add(callback);
368                return callback;
369            },
370            /**
371             * Cancel the provided callback from running on the next frame.
372             */
373            cancel: (callback) => {
374                nextFrame.delete(callback);
375                toKeepAlive.delete(callback);
376            },
377            /**
378             * Execute all schedule callbacks.
379             */
380            process: (frameData) => {
381                latestFrameData = frameData;
382                /**
383                 * If we're already processing we've probably been triggered by a flushSync
384                 * inside an existing process. Instead of executing, mark flushNextFrame
385                 * as true and ensure we flush the following frame at the end of this one.
386                 */
387                if (isProcessing) {
388                    flushNextFrame = true;
389                    return;
390                }
391                isProcessing = true;
392                [thisFrame, nextFrame] = [nextFrame, thisFrame];
393                // Execute this frame
394                thisFrame.forEach(triggerCallback);
395                /**
396                 * If we're recording stats then
397                 */
398                if (stepName && statsBuffer.value) {
399                    statsBuffer.value.frameloop[stepName].push(numCalls);
400                }
401                numCalls = 0;
402                // Clear the frame so no callbacks remain. This is to avoid
403                // memory leaks should this render step not run for a 
vendor: 44,926 bytes, lines 403-1598
403while.
404                thisFrame.clear();
405                isProcessing = false;
406                if (flushNextFrame) {
407                    flushNextFrame = false;
408                    step.process(frameData);
409                }
410            },
411        };
412        return step;
413    }
414
415    const maxElapsed$1 = 40;
416    function createRenderBatcher(scheduleNextBatch, allowKeepAlive) {
417        let runNextFrame = false;
418        let useDefaultElapsed = true;
419        const state = {
420            delta: 0.0,
421            timestamp: 0.0,
422            isProcessing: false,
423        };
424        const flagRunNextFrame = () => (runNextFrame = true);
425        const steps = stepsOrder.reduce((acc, key) => {
426            acc[key] = createRenderStep(flagRunNextFrame, allowKeepAlive ? key : undefined);
427            return acc;
428        }, {});
429        const { setup, read, resolveKeyframes, preUpdate, update, preRender, render, postRender, } = steps;
430        const processBatch = () => {
431            const timestamp = MotionGlobalConfig.useManualTiming
432                ? state.timestamp
433                : performance.now();
434            runNextFrame = false;
435            if (!MotionGlobalConfig.useManualTiming) {
436                state.delta = useDefaultElapsed
437                    ? 1000 / 60
438                    : Math.max(Math.min(timestamp - state.timestamp, maxElapsed$1), 1);
439            }
440            state.timestamp = timestamp;
441            state.isProcessing = true;
442            // Unrolled render loop for better per-frame performance
443            setup.process(state);
444            read.process(state);
445            resolveKeyframes.process(state);
446            preUpdate.process(state);
447            update.process(state);
448            preRender.process(state);
449            render.process(state);
450            postRender.process(state);
451            state.isProcessing = false;
452            if (runNextFrame && allowKeepAlive) {
453                useDefaultElapsed = false;
454                scheduleNextBatch(processBatch);
455            }
456        };
457        const wake = () => {
458            runNextFrame = true;
459            useDefaultElapsed = true;
460            if (!state.isProcessing) {
461                scheduleNextBatch(processBatch);
462            }
463        };
464        const schedule = stepsOrder.reduce((acc, key) => {
465            const step = steps[key];
466            acc[key] = (process, keepAlive = false, immediate = false) => {
467                if (!runNextFrame)
468                    wake();
469                return step.schedule(process, keepAlive, immediate);
470            };
471            return acc;
472        }, {});
473        const cancel = (process) => {
474            for (let i = 0; i < stepsOrder.length; i++) {
475                steps[stepsOrder[i]].cancel(process);
476            }
477        };
478        return { schedule, cancel, state, steps };
479    }
480
481    const { schedule: frame, cancel: cancelFrame, state: frameData, steps: frameSteps, } = /* @__PURE__ */ createRenderBatcher(typeof requestAnimationFrame !== "undefined" ? requestAnimationFrame : noop, true);
482
483    let now;
484    function clearTime() {
485        now = undefined;
486    }
487    /**
488     * An eventloop-synchronous alternative to performance.now().
489     *
490     * Ensures that time measurements remain consistent within a synchronous context.
491     * Usually calling performance.now() twice within the same synchronous context
492     * will return different values which isn't useful for animations when we're usually
493     * trying to sync animations to the same frame.
494     */
495    const time = {
496        now: () => {
497            if (now === undefined) {
498                time.set(frameData.isProcessing || MotionGlobalConfig.useManualTiming
499                    ? frameData.timestamp
500                    : performance.now());
501            }
502            return now;
503        },
504        set: (newTime) => {
505            now = newTime;
506            queueMicrotask(clearTime);
507        },
508    };
509
510    const activeAnimations = {
511        layout: 0,
512        mainThread: 0,
513        waapi: 0,
514    };
515
516    const checkStringStartsWith = (token) => (key) => typeof key === "string" && key.startsWith(token);
517    const isCSSVariableName = 
518    /*@__PURE__*/ checkStringStartsWith("--");
519    const startsAsVariableToken = 
520    /*@__PURE__*/ checkStringStartsWith("var(--");
521    const isCSSVariableToken = (value) => {
522        const startsWithToken = startsAsVariableToken(value);
523        if (!startsWithToken)
524            return false;
525        // Ensure any comments are stripped from the value as this can harm performance of the regex.
526        return singleCssVariableRegex.test(value.split("/*")[0].trim());
527    };
528    const singleCssVariableRegex = /var\(--(?:[\w-]+\s*|[\w-]+\s*,(?:\s*[^)(\s]|\s*\((?:[^)(]|\([^)(]*\))*\))+\s*)\)$/iu;
529
530    const number = {
531        test: (v) => typeof v === "number",
532        parse: parseFloat,
533        transform: (v) => v,
534    };
535    const alpha = {
536        ...number,
537        transform: (v) => clamp(0, 1, v),
538    };
539    const scale = {
540        ...number,
541        default: 1,
542    };
543
544    // If this number is a decimal, make it just five decimal places
545    // to avoid exponents
546    const sanitize = (v) => Math.round(v * 100000) / 100000;
547
548    const floatRegex = /-?(?:\d+(?:\.\d+)?|\.\d+)/gu;
549
550    function isNullish(v) {
551        return v == null;
552    }
553
554    const singleColorRegex = /^(?:#[\da-f]{3,8}|(?:rgb|hsl)a?\((?:-?[\d.]+%?[,\s]+){2}-?[\d.]+%?\s*(?:[,/]\s*)?(?:\b\d+(?:\.\d+)?|\.\d+)?%?\))$/iu;
555
556    /**
557     * Returns true if the provided string is a color, ie rgba(0,0,0,0) or #000,
558     * but false if a number or multiple colors
559     */
560    const isColorString = (type, testProp) => (v) => {
561        return Boolean((typeof v === "string" &&
562            singleColorRegex.test(v) &&
563            v.startsWith(type)) ||
564            (testProp &&
565                !isNullish(v) &&
566                Object.prototype.hasOwnProperty.call(v, testProp)));
567    };
568    const splitColor = (aName, bName, cName) => (v) => {
569        if (typeof v !== "string")
570            return v;
571        const [a, b, c, alpha] = v.match(floatRegex);
572        return {
573            [aName]: parseFloat(a),
574            [bName]: parseFloat(b),
575            [cName]: parseFloat(c),
576            alpha: alpha !== undefined ? parseFloat(alpha) : 1,
577        };
578    };
579
580    const clampRgbUnit = (v) => clamp(0, 255, v);
581    const rgbUnit = {
582        ...number,
583        transform: (v) => Math.round(clampRgbUnit(v)),
584    };
585    const rgba = {
586        test: /*@__PURE__*/ isColorString("rgb", "red"),
587        parse: /*@__PURE__*/ splitColor("red", "green", "blue"),
588        transform: ({ red, green, blue, alpha: alpha$1 = 1 }) => "rgba(" +
589            rgbUnit.transform(red) +
590            ", " +
591            rgbUnit.transform(green) +
592            ", " +
593            rgbUnit.transform(blue) +
594            ", " +
595            sanitize(alpha.transform(alpha$1)) +
596            ")",
597    };
598
599    function parseHex(v) {
600        let r = "";
601        let g = "";
602        let b = "";
603        let a = "";
604        // If we have 6 characters, ie #FF0000
605        if (v.length > 5) {
606            r = v.substring(1, 3);
607            g = v.substring(3, 5);
608            b = v.substring(5, 7);
609            a = v.substring(7, 9);
610            // Or we have 3 characters, ie #F00
611        }
612        else {
613            r = v.substring(1, 2);
614            g = v.substring(2, 3);
615            b = v.substring(3, 4);
616            a = v.substring(4, 5);
617            r += r;
618            g += g;
619            b += b;
620            a += a;
621        }
622        return {
623            red: parseInt(r, 16),
624            green: parseInt(g, 16),
625            blue: parseInt(b, 16),
626            alpha: a ? parseInt(a, 16) / 255 : 1,
627        };
628    }
629    const hex = {
630        test: /*@__PURE__*/ isColorString("#"),
631        parse: parseHex,
632        transform: rgba.transform,
633    };
634
635    /*#__NO_SIDE_EFFECTS__*/
636    const createUnitType = (unit) => ({
637        test: (v) => typeof v === "string" && v.endsWith(unit) && v.split(" ").length === 1,
638        parse: parseFloat,
639        transform: (v) => `${v}${unit}`,
640    });
641    const degrees = /*@__PURE__*/ createUnitType("deg");
642    const percent = /*@__PURE__*/ createUnitType("%");
643    const px = /*@__PURE__*/ createUnitType("px");
644    const vh = /*@__PURE__*/ createUnitType("vh");
645    const vw = /*@__PURE__*/ createUnitType("vw");
646    const progressPercentage = /*@__PURE__*/ (() => ({
647        ...percent,
648        parse: (v) => percent.parse(v) / 100,
649        transform: (v) => percent.transform(v * 100),
650    }))();
651
652    const hsla = {
653        test: /*@__PURE__*/ isColorString("hsl", "hue"),
654        parse: /*@__PURE__*/ splitColor("hue", "saturation", "lightness"),
655        transform: ({ hue, saturation, lightness, alpha: alpha$1 = 1 }) => {
656            return ("hsla(" +
657                Math.round(hue) +
658                ", " +
659                percent.transform(sanitize(saturation)) +
660                ", " +
661                percent.transform(sanitize(lightness)) +
662                ", " +
663                sanitize(alpha.transform(alpha$1)) +
664                ")");
665        },
666    };
667
668    const color = {
669        test: (v) => rgba.test(v) || hex.test(v) || hsla.test(v),
670        parse: (v) => {
671            if (rgba.test(v)) {
672                return rgba.parse(v);
673            }
674            else if (hsla.test(v)) {
675                return hsla.parse(v);
676            }
677            else {
678                return hex.parse(v);
679            }
680        },
681        transform: (v) => {
682            return typeof v === "string"
683                ? v
684                : v.hasOwnProperty("red")
685                    ? rgba.transform(v)
686                    : hsla.transform(v);
687        },
688        getAnimatableNone: (v) => {
689            const parsed = color.parse(v);
690            parsed.alpha = 0;
691            return color.transform(parsed);
692        },
693    };
694
695    const colorRegex = /(?:#[\da-f]{3,8}|(?:rgb|hsl)a?\((?:-?[\d.]+%?[,\s]+){2}-?[\d.]+%?\s*(?:[,/]\s*)?(?:\b\d+(?:\.\d+)?|\.\d+)?%?\))/giu;
696
697    function test(v) {
698        return (isNaN(v) &&
699            typeof v === "string" &&
700            (v.match(floatRegex)?.length || 0) +
701                (v.match(colorRegex)?.length || 0) >
702                0);
703    }
704    const NUMBER_TOKEN = "number";
705    const COLOR_TOKEN = "color";
706    const VAR_TOKEN = "var";
707    const VAR_FUNCTION_TOKEN = "var(";
708    const SPLIT_TOKEN = "${}";
709    // this regex consists of the `singleCssVariableRegex|rgbHSLValueRegex|digitRegex`
710    const 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;
711    function analyseComplexValue(value) {
712        const originalValue = value.toString();
713        const values = [];
714        const indexes = {
715            color: [],
716            number: [],
717            var: [],
718        };
719        const types = [];
720        let i = 0;
721        const tokenised = originalValue.replace(complexRegex, (parsedValue) => {
722            if (color.test(parsedValue)) {
723                indexes.color.push(i);
724                types.push(COLOR_TOKEN);
725                values.push(color.parse(parsedValue));
726            }
727            else if (parsedValue.startsWith(VAR_FUNCTION_TOKEN)) {
728                indexes.var.push(i);
729                types.push(VAR_TOKEN);
730                values.push(parsedValue);
731            }
732            else {
733                indexes.number.push(i);
734                types.push(NUMBER_TOKEN);
735                values.push(parseFloat(parsedValue));
736            }
737            ++i;
738            return SPLIT_TOKEN;
739        });
740        const split = tokenised.split(SPLIT_TOKEN);
741        return { values, split, indexes, types };
742    }
743    function parseComplexValue(v) {
744        return analyseComplexValue(v).values;
745    }
746    function createTransformer(source) {
747        const { split, types } = analyseComplexValue(source);
748        const numSections = split.length;
749        return (v) => {
750            let output = "";
751            for (let i = 0; i < numSections; i++) {
752                output += split[i];
753                if (v[i] !== undefined) {
754                    const type = types[i];
755                    if (type === NUMBER_TOKEN) {
756                        output += sanitize(v[i]);
757                    }
758                    else if (type === COLOR_TOKEN) {
759                        output += color.transform(v[i]);
760                    }
761                    else {
762                        output += v[i];
763                    }
764                }
765            }
766            return output;
767        };
768    }
769    const convertNumbersToZero = (v) => typeof v === "number" ? 0 : color.test(v) ? color.getAnimatableNone(v) : v;
770    function getAnimatableNone$1(v) {
771        const parsed = parseComplexValue(v);
772        const transformer = createTransformer(v);
773        return transformer(parsed.map(convertNumbersToZero));
774    }
775    const complex = {
776        test,
777        parse: parseComplexValue,
778        createTransformer,
779        getAnimatableNone: getAnimatableNone$1,
780    };
781
782    // Adapted from https://gist.github.com/mjackson/5311256
783    function hueToRgb(p, q, t) {
784        if (t < 0)
785            t += 1;
786        if (t > 1)
787            t -= 1;
788        if (t < 1 / 6)
789            return p + (q - p) * 6 * t;
790        if (t < 1 / 2)
791            return q;
792        if (t < 2 / 3)
793            return p + (q - p) * (2 / 3 - t) * 6;
794        return p;
795    }
796    function hslaToRgba({ hue, saturation, lightness, alpha }) {
797        hue /= 360;
798        saturation /= 100;
799        lightness /= 100;
800        let red = 0;
801        let green = 0;
802        let blue = 0;
803        if (!saturation) {
804            red = green = blue = lightness;
805        }
806        else {
807            const q = lightness < 0.5
808                ? lightness * (1 + saturation)
809                : lightness + saturation - lightness * saturation;
810            const p = 2 * lightness - q;
811            red = hueToRgb(p, q, hue + 1 / 3);
812            green = hueToRgb(p, q, hue);
813            blue = hueToRgb(p, q, hue - 1 / 3);
814        }
815        return {
816            red: Math.round(red * 255),
817            green: Math.round(green * 255),
818            blue: Math.round(blue * 255),
819            alpha,
820        };
821    }
822
823    function mixImmediate(a, b) {
824        return (p) => (p > 0 ? b : a);
825    }
826
827    /*
828      Value in range from progress
829
830      Given a lower limit and an upper limit, we return the value within
831      that range as expressed by progress (usually a number from 0 to 1)
832
833      So progress = 0.5 would change
834
835      from -------- to
836
837      to
838
839      from ---- to
840
841      E.g. from = 10, to = 20, progress = 0.5 => 15
842
843      @param [number]: Lower limit of range
844      @param [number]: Upper limit of range
845      @param [number]: The progress between lower and upper limits expressed 0-1
846      @return [number]: Value as calculated from progress within range (not limited within range)
847    */
848    const mixNumber$1 = (from, to, progress) => {
849        return from + (to - from) * progress;
850    };
851
852    // Linear color space blending
853    // Explained https://www.youtube.com/watch?v=LKnqECcg6Gw
854    // Demonstrated http://codepen.io/osublake/pen/xGVVaN
855    const mixLinearColor = (from, to, v) => {
856        const fromExpo = from * from;
857        const expo = v * (to * to - fromExpo) + fromExpo;
858        return expo < 0 ? 0 : Math.sqrt(expo);
859    };
860    const colorTypes = [hex, rgba, hsla];
861    const getColorType = (v) => colorTypes.find((type) => type.test(v));
862    function asRGBA(color) {
863        const type = getColorType(color);
864        exports.warning(Boolean(type), `'${color}' is not an animatable color. Use the equivalent color code instead.`, "color-not-animatable");
865        if (!Boolean(type))
866            return false;
867        let model = type.parse(color);
868        if (type === hsla) {
869            // TODO Remove this cast - needed since Motion's stricter typing
870            model = hslaToRgba(model);
871        }
872        return model;
873    }
874    const mixColor = (from, to) => {
875        const fromRGBA = asRGBA(from);
876        const toRGBA = asRGBA(to);
877        if (!fromRGBA || !toRGBA) {
878            return mixImmediate(from, to);
879        }
880        const blended = { ...fromRGBA };
881        return (v) => {
882            blended.red = mixLinearColor(fromRGBA.red, toRGBA.red, v);
883            blended.green = mixLinearColor(fromRGBA.green, toRGBA.green, v);
884            blended.blue = mixLinearColor(fromRGBA.blue, toRGBA.blue, v);
885            blended.alpha = mixNumber$1(fromRGBA.alpha, toRGBA.alpha, v);
886            return rgba.transform(blended);
887        };
888    };
889
890    const invisibleValues = new Set(["none", "hidden"]);
891    /**
892     * Returns a function that, when provided a progress value between 0 and 1,
893     * will return the "none" or "hidden" string only when the progress is that of
894     * the origin or target.
895     */
896    function mixVisibility(origin, target) {
897        if (invisibleValues.has(origin)) {
898            return (p) => (p <= 0 ? origin : target);
899        }
900        else {
901            return (p) => (p >= 1 ? target : origin);
902        }
903    }
904
905    function mixNumber(a, b) {
906        return (p) => mixNumber$1(a, b, p);
907    }
908    function getMixer(a) {
909        if (typeof a === "number") {
910            return mixNumber;
911        }
912        else if (typeof a === "string") {
913            return isCSSVariableToken(a)
914                ? mixImmediate
915                : color.test(a)
916                    ? mixColor
917                    : mixComplex;
918        }
919        else if (Array.isArray(a)) {
920            return mixArray;
921        }
922        else if (typeof a === "object") {
923            return color.test(a) ? mixColor : mixObject;
924        }
925        return mixImmediate;
926    }
927    function mixArray(a, b) {
928        const output = [...a];
929        const numValues = output.length;
930        const blendValue = a.map((v, i) => getMixer(v)(v, b[i]));
931        return (p) => {
932            for (let i = 0; i < numValues; i++) {
933                output[i] = blendValue[i](p);
934            }
935            return output;
936        };
937    }
938    function mixObject(a, b) {
939        const output = { ...a, ...b };
940        const blendValue = {};
941        for (const key in output) {
942            if (a[key] !== undefined && b[key] !== undefined) {
943                blendValue[key] = getMixer(a[key])(a[key], b[key]);
944            }
945        }
946        return (v) => {
947            for (const key in blendValue) {
948                output[key] = blendValue[key](v);
949            }
950            return output;
951        };
952    }
953    function matchOrder(origin, target) {
954        const orderedOrigin = [];
955        const pointers = { color: 0, var: 0, number: 0 };
956        for (let i = 0; i < target.values.length; i++) {
957            const type = target.types[i];
958            const originIndex = origin.indexes[type][pointers[type]];
959            const originValue = origin.values[originIndex] ?? 0;
960            orderedOrigin[i] = originValue;
961            pointers[type]++;
962        }
963        return orderedOrigin;
964    }
965    const mixComplex = (origin, target) => {
966        const template = complex.createTransformer(target);
967        const originStats = analyseComplexValue(origin);
968        const targetStats = analyseComplexValue(target);
969        const canInterpolate = originStats.indexes.var.length === targetStats.indexes.var.length &&
970            originStats.indexes.color.length === targetStats.indexes.color.length &&
971            originStats.indexes.number.length >= targetStats.indexes.number.length;
972        if (canInterpolate) {
973            if ((invisibleValues.has(origin) &&
974                !targetStats.values.length) ||
975                (invisibleValues.has(target) &&
976                    !originStats.values.length)) {
977                return mixVisibility(origin, target);
978            }
979            return pipe(mixArray(matchOrder(originStats, targetStats), targetStats.values), template);
980        }
981        else {
982            exports.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");
983            return mixImmediate(origin, target);
984        }
985    };
986
987    function mix(from, to, p) {
988        if (typeof from === "number" &&
989            typeof to === "number" &&
990            typeof p === "number") {
991            return mixNumber$1(from, to, p);
992        }
993        const mixer = getMixer(from);
994        return mixer(from, to);
995    }
996
997    const frameloopDriver = (update) => {
998        const passTimestamp = ({ timestamp }) => update(timestamp);
999        return {
1000            start: (keepAlive = true) => frame.update(passTimestamp, keepAlive),
1001            stop: () => cancelFrame(passTimestamp),
1002            /**
1003             * If we're processing this frame we can use the
1004             * framelocked timestamp to keep things in sync.
1005             */
1006            now: () => (frameData.isProcessing ? frameData.timestamp : time.now()),
1007        };
1008    };
1009
1010    const generateLinearEasing = (easing, duration, // as milliseconds
1011    resolution = 10 // as milliseconds
1012    ) => {
1013        let points = "";
1014        const numPoints = Math.max(Math.round(duration / resolution), 2);
1015        for (let i = 0; i < numPoints; i++) {
1016            points += Math.round(easing(i / (numPoints - 1)) * 10000) / 10000 + ", ";
1017        }
1018        return `linear(${points.substring(0, points.length - 2)})`;
1019    };
1020
1021    /**
1022     * Implement a practical max duration for keyframe generation
1023     * to prevent infinite loops
1024     */
1025    const maxGeneratorDuration = 20000;
1026    function calcGeneratorDuration(generator) {
1027        let duration = 0;
1028        const timeStep = 50;
1029        let state = generator.next(duration);
1030        while (!state.done && duration < maxGeneratorDuration) {
1031            duration += timeStep;
1032            state = generator.next(duration);
1033        }
1034        return duration >= maxGeneratorDuration ? Infinity : duration;
1035    }
1036
1037    /**
1038     * Create a progress => progress easing function from a generator.
1039     */
1040    function createGeneratorEasing(options, scale = 100, createGenerator) {
1041        const generator = createGenerator({ ...options, keyframes: [0, scale] });
1042        const duration = Math.min(calcGeneratorDuration(generator), maxGeneratorDuration);
1043        return {
1044            type: "keyframes",
1045            ease: (progress) => {
1046                return generator.next(duration * progress).value / scale;
1047            },
1048            duration: millisecondsToSeconds(duration),
1049        };
1050    }
1051
1052    const velocitySampleDuration = 5; // ms
1053    function calcGeneratorVelocity(resolveValue, t, current) {
1054        const prevT = Math.max(t - velocitySampleDuration, 0);
1055        return velocityPerSecond(current - resolveValue(prevT), t - prevT);
1056    }
1057
1058    const springDefaults = {
1059        // Default spring physics
1060        stiffness: 100,
1061        damping: 10,
1062        mass: 1.0,
1063        velocity: 0.0,
1064        // Default duration/bounce-based options
1065        duration: 800, // in ms
1066        bounce: 0.3,
1067        visualDuration: 0.3, // in seconds
1068        // Rest thresholds
1069        restSpeed: {
1070            granular: 0.01,
1071            default: 2,
1072        },
1073        restDelta: {
1074            granular: 0.005,
1075            default: 0.5,
1076        },
1077        // Limits
1078        minDuration: 0.01, // in seconds
1079        maxDuration: 10.0, // in seconds
1080        minDamping: 0.05,
1081        maxDamping: 1,
1082    };
1083
1084    const safeMin = 0.001;
1085    function findSpring({ duration = springDefaults.duration, bounce = springDefaults.bounce, velocity = springDefaults.velocity, mass = springDefaults.mass, }) {
1086        let envelope;
1087        let derivative;
1088        exports.warning(duration <= secondsToMilliseconds(springDefaults.maxDuration), "Spring duration must be 10 seconds or less", "spring-duration-limit");
1089        let dampingRatio = 1 - bounce;
1090        /**
1091         * Restrict dampingRatio and duration to within acceptable ranges.
1092         */
1093        dampingRatio = clamp(springDefaults.minDamping, springDefaults.maxDamping, dampingRatio);
1094        duration = clamp(springDefaults.minDuration, springDefaults.maxDuration, millisecondsToSeconds(duration));
1095        if (dampingRatio < 1) {
1096            /**
1097             * Underdamped spring
1098             */
1099            envelope = (undampedFreq) => {
1100                const exponentialDecay = undampedFreq * dampingRatio;
1101                const delta = exponentialDecay * duration;
1102                const a = exponentialDecay - velocity;
1103                const b = calcAngularFreq(undampedFreq, dampingRatio);
1104                const c = Math.exp(-delta);
1105                return safeMin - (a / b) * c;
1106            };
1107            derivative = (undampedFreq) => {
1108                const exponentialDecay = undampedFreq * dampingRatio;
1109                const delta = exponentialDecay * duration;
1110                const d = delta * velocity + velocity;
1111                const e = Math.pow(dampingRatio, 2) * Math.pow(undampedFreq, 2) * duration;
1112                const f = Math.exp(-delta);
1113                const g = calcAngularFreq(Math.pow(undampedFreq, 2), dampingRatio);
1114                const factor = -envelope(undampedFreq) + safeMin > 0 ? -1 : 1;
1115                return (factor * ((d - e) * f)) / g;
1116            };
1117        }
1118        else {
1119            /**
1120             * Critically-damped spring
1121             */
1122            envelope = (undampedFreq) => {
1123                const a = Math.exp(-undampedFreq * duration);
1124                const b = (undampedFreq - velocity) * duration + 1;
1125                return -safeMin + a * b;
1126            };
1127            derivative = (undampedFreq) => {
1128                const a = Math.exp(-undampedFreq * duration);
1129                const b = (velocity - undampedFreq) * (duration * duration);
1130                return a * b;
1131            };
1132        }
1133        const initialGuess = 5 / duration;
1134        const undampedFreq = approximateRoot(envelope, derivative, initialGuess);
1135        duration = secondsToMilliseconds(duration);
1136        if (isNaN(undampedFreq)) {
1137            return {
1138                stiffness: springDefaults.stiffness,
1139                damping: springDefaults.damping,
1140                duration,
1141            };
1142        }
1143        else {
1144            const stiffness = Math.pow(undampedFreq, 2) * mass;
1145            return {
1146                stiffness,
1147                damping: dampingRatio * 2 * Math.sqrt(mass * stiffness),
1148                duration,
1149            };
1150        }
1151    }
1152    const rootIterations = 12;
1153    function approximateRoot(envelope, derivative, initialGuess) {
1154        let result = initialGuess;
1155        for (let i = 1; i < rootIterations; i++) {
1156            result = result - envelope(result) / derivative(result);
1157        }
1158        return result;
1159    }
1160    function calcAngularFreq(undampedFreq, dampingRatio) {
1161        return undampedFreq * Math.sqrt(1 - dampingRatio * dampingRatio);
1162    }
1163
1164    const durationKeys = ["duration", "bounce"];
1165    const physicsKeys = ["stiffness", "damping", "mass"];
1166    function isSpringType(options, keys) {
1167        return keys.some((key) => options[key] !== undefined);
1168    }
1169    function getSpringOptions(options) {
1170        let springOptions = {
1171            velocity: springDefaults.velocity,
1172            stiffness: springDefaults.stiffness,
1173            damping: springDefaults.damping,
1174            mass: springDefaults.mass,
1175            isResolvedFromDuration: false,
1176            ...options,
1177        };
1178        // stiffness/damping/mass overrides duration/bounce
1179        if (!isSpringType(options, physicsKeys) &&
1180            isSpringType(options, durationKeys)) {
1181            if (options.visualDuration) {
1182                const visualDuration = options.visualDuration;
1183                const root = (2 * Math.PI) / (visualDuration * 1.2);
1184                const stiffness = root * root;
1185                const damping = 2 *
1186                    clamp(0.05, 1, 1 - (options.bounce || 0)) *
1187                    Math.sqrt(stiffness);
1188                springOptions = {
1189                    ...springOptions,
1190                    mass: springDefaults.mass,
1191                    stiffness,
1192                    damping,
1193                };
1194            }
1195            else {
1196                const derived = findSpring(options);
1197                springOptions = {
1198                    ...springOptions,
1199                    ...derived,
1200                    mass: springDefaults.mass,
1201                };
1202                springOptions.isResolvedFromDuration = true;
1203            }
1204        }
1205        return springOptions;
1206    }
1207    function spring(optionsOrVisualDuration = springDefaults.visualDuration, bounce = springDefaults.bounce) {
1208        const options = typeof optionsOrVisualDuration !== "object"
1209            ? {
1210                visualDuration: optionsOrVisualDuration,
1211                keyframes: [0, 1],
1212                bounce,
1213            }
1214            : optionsOrVisualDuration;
1215        let { restSpeed, restDelta } = options;
1216        const origin = options.keyframes[0];
1217        const target = options.keyframes[options.keyframes.length - 1];
1218        /**
1219         * This is the Iterator-spec return value. We ensure it's mutable rather than using a generator
1220         * to reduce GC during animation.
1221         */
1222        const state = { done: false, value: origin };
1223        const { stiffness, damping, mass, duration, velocity, isResolvedFromDuration, } = getSpringOptions({
1224            ...options,
1225            velocity: -millisecondsToSeconds(options.velocity || 0),
1226        });
1227        const initialVelocity = velocity || 0.0;
1228        const dampingRatio = damping / (2 * Math.sqrt(stiffness * mass));
1229        const initialDelta = target - origin;
1230        const undampedAngularFreq = millisecondsToSeconds(Math.sqrt(stiffness / mass));
1231        /**
1232         * If we're working on a granular scale, use smaller defaults for determining
1233         * when the spring is finished.
1234         *
1235         * These defaults have been selected emprically based on what strikes a good
1236         * ratio between feeling good and finishing as soon as changes are imperceptible.
1237         */
1238        const isGranularScale = Math.abs(initialDelta) < 5;
1239        restSpeed || (restSpeed = isGranularScale
1240            ? springDefaults.restSpeed.granular
1241            : springDefaults.restSpeed.default);
1242        restDelta || (restDelta = isGranularScale
1243            ? springDefaults.restDelta.granular
1244            : springDefaults.restDelta.default);
1245        let resolveSpring;
1246        if (dampingRatio < 1) {
1247            const angularFreq = calcAngularFreq(undampedAngularFreq, dampingRatio);
1248            // Underdamped spring
1249            resolveSpring = (t) => {
1250                const envelope = Math.exp(-dampingRatio * undampedAngularFreq * t);
1251                return (target -
1252                    envelope *
1253                        (((initialVelocity +
1254                            dampingRatio * undampedAngularFreq * initialDelta) /
1255                            angularFreq) *
1256                            Math.sin(angularFreq * t) +
1257                            initialDelta * Math.cos(angularFreq * t)));
1258            };
1259        }
1260        else if (dampingRatio === 1) {
1261            // Critically damped spring
1262            resolveSpring = (t) => target -
1263                Math.exp(-undampedAngularFreq * t) *
1264                    (initialDelta +
1265                        (initialVelocity + undampedAngularFreq * initialDelta) * t);
1266        }
1267        else {
1268            // Overdamped spring
1269            const dampedAngularFreq = undampedAngularFreq * Math.sqrt(dampingRatio * dampingRatio - 1);
1270            resolveSpring = (t) => {
1271                const envelope = Math.exp(-dampingRatio * undampedAngularFreq * t);
1272                // When performing sinh or cosh values can hit Infinity so we cap them here
1273                const freqForT = Math.min(dampedAngularFreq * t, 300);
1274                return (target -
1275                    (envelope *
1276                        ((initialVelocity +
1277                            dampingRatio * undampedAngularFreq * initialDelta) *
1278                            Math.sinh(freqForT) +
1279                            dampedAngularFreq *
1280                                initialDelta *
1281                                Math.cosh(freqForT))) /
1282                        dampedAngularFreq);
1283            };
1284        }
1285        const generator = {
1286            calculatedDuration: isResolvedFromDuration ? duration || null : null,
1287            next: (t) => {
1288                const current = resolveSpring(t);
1289                if (!isResolvedFromDuration) {
1290                    let currentVelocity = t === 0 ? initialVelocity : 0.0;
1291                    /**
1292                     * We only need to calculate velocity for under-damped springs
1293                     * as over- and critically-damped springs can't overshoot, so
1294                     * checking only for displacement is enough.
1295                     */
1296                    if (dampingRatio < 1) {
1297                        currentVelocity =
1298                            t === 0
1299                                ? secondsToMilliseconds(initialVelocity)
1300                                : calcGeneratorVelocity(resolveSpring, t, current);
1301                    }
1302                    const isBelowVelocityThreshold = Math.abs(currentVelocity) <= restSpeed;
1303                    const isBelowDisplacementThreshold = Math.abs(target - current) <= restDelta;
1304                    state.done =
1305                        isBelowVelocityThreshold && isBelowDisplacementThreshold;
1306                }
1307                else {
1308                    state.done = t >= duration;
1309                }
1310                state.value = state.done ? target : current;
1311                return state;
1312            },
1313            toString: () => {
1314                const calculatedDuration = Math.min(calcGeneratorDuration(generator), maxGeneratorDuration);
1315                const easing = generateLinearEasing((progress) => generator.next(calculatedDuration * progress).value, calculatedDuration, 30);
1316                return calculatedDuration + "ms " + easing;
1317            },
1318            toTransition: () => { },
1319        };
1320        return generator;
1321    }
1322    spring.applyToOptions = (options) => {
1323        const generatorOptions = createGeneratorEasing(options, 100, spring);
1324        options.ease = generatorOptions.ease;
1325        options.duration = secondsToMilliseconds(generatorOptions.duration);
1326        options.type = "keyframes";
1327        return options;
1328    };
1329
1330    function inertia({ keyframes, velocity = 0.0, power = 0.8, timeConstant = 325, bounceDamping = 10, bounceStiffness = 500, modifyTarget, min, max, restDelta = 0.5, restSpeed, }) {
1331        const origin = keyframes[0];
1332        const state = {
1333            done: false,
1334            value: origin,
1335        };
1336        const isOutOfBounds = (v) => (min !== undefined && v < min) || (max !== undefined && v > max);
1337        const nearestBoundary = (v) => {
1338            if (min === undefined)
1339                return max;
1340            if (max === undefined)
1341                return min;
1342            return Math.abs(min - v) < Math.abs(max - v) ? min : max;
1343        };
1344        let amplitude = power * velocity;
1345        const ideal = origin + amplitude;
1346        const target = modifyTarget === undefined ? ideal : modifyTarget(ideal);
1347        /**
1348         * If the target has changed we need to re-calculate the amplitude, otherwise
1349         * the animation will start from the wrong position.
1350         */
1351        if (target !== ideal)
1352            amplitude = target - origin;
1353        const calcDelta = (t) => -amplitude * Math.exp(-t / timeConstant);
1354        const calcLatest = (t) => target + calcDelta(t);
1355        const applyFriction = (t) => {
1356            const delta = calcDelta(t);
1357            const latest = calcLatest(t);
1358            state.done = Math.abs(delta) <= restDelta;
1359            state.value = state.done ? target : latest;
1360        };
1361        /**
1362         * Ideally this would resolve for t in a stateless way, we could
1363         * do that by always precalculating the animation but as we know
1364         * this will be done anyway we can assume that spring will
1365         * be discovered during that.
1366         */
1367        let timeReachedBoundary;
1368        let spring$1;
1369        const checkCatchBoundary = (t) => {
1370            if (!isOutOfBounds(state.value))
1371                return;
1372            timeReachedBoundary = t;
1373            spring$1 = spring({
1374                keyframes: [state.value, nearestBoundary(state.value)],
1375                velocity: calcGeneratorVelocity(calcLatest, t, state.value), // TODO: This should be passing * 1000
1376                damping: bounceDamping,
1377                stiffness: bounceStiffness,
1378                restDelta,
1379                restSpeed,
1380            });
1381        };
1382        checkCatchBoundary(0);
1383        return {
1384            calculatedDuration: null,
1385            next: (t) => {
1386                /**
1387                 * We need to resolve the friction to figure out if we need a
1388                 * spring but we don't want to do this twice per frame. So here
1389                 * we flag if we updated for this frame and later if we did
1390                 * we can skip doing it again.
1391                 */
1392                let hasUpdatedFrame = false;
1393                if (!spring$1 && timeReachedBoundary === undefined) {
1394                    hasUpdatedFrame = true;
1395                    applyFriction(t);
1396                    checkCatchBoundary(t);
1397                }
1398                /**
1399                 * If we have a spring and the provided t is beyond the moment the friction
1400                 * animation crossed the min/max boundary, use the spring.
1401                 */
1402                if (timeReachedBoundary !== undefined && t >= timeReachedBoundary) {
1403                    return spring$1.next(t - timeReachedBoundary);
1404                }
1405                else {
1406                    !hasUpdatedFrame && applyFriction(t);
1407                    return state;
1408                }
1409            },
1410        };
1411    }
1412
1413    function createMixers(output, ease, customMixer) {
1414        const mixers = [];
1415        const mixerFactory = customMixer || MotionGlobalConfig.mix || mix;
1416        const numMixers = output.length - 1;
1417        for (let i = 0; i < numMixers; i++) {
1418            let mixer = mixerFactory(output[i], output[i + 1]);
1419            if (ease) {
1420                const easingFunction = Array.isArray(ease) ? ease[i] || noop : ease;
1421                mixer = pipe(easingFunction, mixer);
1422            }
1423            mixers.push(mixer);
1424        }
1425        return mixers;
1426    }
1427    /**
1428     * Create a function that maps from a numerical input array to a generic output array.
1429     *
1430     * Accepts:
1431     *   - Numbers
1432     *   - Colors (hex, hsl, hsla, rgb, rgba)
1433     *   - Complex (combinations of one or more numbers or strings)
1434     *
1435     * ```jsx
1436     * const mixColor = interpolate([0, 1], ['#fff', '#000'])
1437     *
1438     * mixColor(0.5) // 'rgba(128, 128, 128, 1)'
1439     * ```
1440     *
1441     * TODO Revisit this approach once we've moved to data models for values,
1442     * probably not needed to pregenerate mixer functions.
1443     *
1444     * @public
1445     */
1446    function interpolate(input, output, { clamp: isClamp = true, ease, mixer } = {}) {
1447        const inputLength = input.length;
1448        exports.invariant(inputLength === output.length, "Both input and output ranges must be the same length", "range-length");
1449        /**
1450         * If we're only provided a single input, we can just make a function
1451         * that returns the output.
1452         */
1453        if (inputLength === 1)
1454            return () => output[0];
1455        if (inputLength === 2 && output[0] === output[1])
1456            return () => output[1];
1457        const isZeroDeltaRange = input[0] === input[1];
1458        // If input runs highest -> lowest, reverse both arrays
1459        if (input[0] > input[inputLength - 1]) {
1460            input = [...input].reverse();
1461            output = [...output].reverse();
1462        }
1463        const mixers = createMixers(output, ease, mixer);
1464        const numMixers = mixers.length;
1465        const interpolator = (v) => {
1466            if (isZeroDeltaRange && v < input[0])
1467                return output[0];
1468            let i = 0;
1469            if (numMixers > 1) {
1470                for (; i < input.length - 2; i++) {
1471                    if (v < input[i + 1])
1472                        break;
1473                }
1474            }
1475            const progressInRange = progress(input[i], input[i + 1], v);
1476            return mixers[i](progressInRange);
1477        };
1478        return isClamp
1479            ? (v) => interpolator(clamp(input[0], input[inputLength - 1], v))
1480            : interpolator;
1481    }
1482
1483    function fillOffset(offset, remaining) {
1484        const min = offset[offset.length - 1];
1485        for (let i = 1; i <= remaining; i++) {
1486            const offsetProgress = progress(0, remaining, i);
1487            offset.push(mixNumber$1(min, 1, offsetProgress));
1488        }
1489    }
1490
1491    function defaultOffset$1(arr) {
1492        const offset = [0];
1493        fillOffset(offset, arr.length - 1);
1494        return offset;
1495    }
1496
1497    function convertOffsetToTimes(offset, duration) {
1498        return offset.map((o) => o * duration);
1499    }
1500
1501    function defaultEasing(values, easing) {
1502        return values.map(() => easing || easeInOut).splice(0, values.length - 1);
1503    }
1504    function keyframes({ duration = 300, keyframes: keyframeValues, times, ease = "easeInOut", }) {
1505        /**
1506         * Easing functions can be externally defined as strings. Here we convert them
1507         * into actual functions.
1508         */
1509        const easingFunctions = isEasingArray(ease)
1510            ? ease.map(easingDefinitionToFunction)
1511            : easingDefinitionToFunction(ease);
1512        /**
1513         * This is the Iterator-spec return value. We ensure it's mutable rather than using a generator
1514         * to reduce GC during animation.
1515         */
1516        const state = {
1517            done: false,
1518            value: keyframeValues[0],
1519        };
1520        /**
1521         * Create a times array based on the provided 0-1 offsets
1522         */
1523        const absoluteTimes = convertOffsetToTimes(
1524        // Only use the provided offsets if they're the correct length
1525        // TODO Maybe we should warn here if there's a length mismatch
1526        times && times.length === keyframeValues.length
1527            ? times
1528            : defaultOffset$1(keyframeValues), duration);
1529        const mapTimeToKeyframe = interpolate(absoluteTimes, keyframeValues, {
1530            ease: Array.isArray(easingFunctions)
1531                ? easingFunctions
1532                : defaultEasing(keyframeValues, easingFunctions),
1533        });
1534        return {
1535            calculatedDuration: duration,
1536            next: (t) => {
1537                state.value = mapTimeToKeyframe(t);
1538                state.done = t >= duration;
1539                return state;
1540            },
1541        };
1542    }
1543
1544    const isNotNull$1 = (value) => value !== null;
1545    function getFinalKeyframe$1(keyframes, { repeat, repeatType = "loop" }, finalKeyframe, speed = 1) {
1546        const resolvedKeyframes = keyframes.filter(isNotNull$1);
1547        const useFirstKeyframe = speed < 0 || (repeat && repeatType !== "loop" && repeat % 2 === 1);
1548        const index = useFirstKeyframe ? 0 : resolvedKeyframes.length - 1;
1549        return !index || finalKeyframe === undefined
1550            ? resolvedKeyframes[index]
1551            : finalKeyframe;
1552    }
1553
1554    const transitionTypeMap = {
1555        decay: inertia,
1556        inertia,
1557        tween: keyframes,
1558        keyframes: keyframes,
1559        spring,
1560    };
1561    function replaceTransitionType(transition) {
1562        if (typeof transition.type === "string") {
1563            transition.type = transitionTypeMap[transition.type];
1564        }
1565    }
1566
1567    class WithPromise {
1568        constructor() {
1569            this.updateFinished();
1570        }
1571        get finished() {
1572            return this._finished;
1573        }
1574        updateFinished() {
1575            this._finished = new Promise((resolve) => {
1576                this.resolve = resolve;
1577            });
1578        }
1579        notifyFinished() {
1580            this.resolve();
1581        }
1582        /**
1583         * Allows the animation to be awaited.
1584         *
1585         * @deprecated Use `finished` instead.
1586         */
1587        then(onResolve, onReject) {
1588            return this.finished.then(onResolve, onReject);
1589        }
1590    }
1591
1592    const percentToProgress = (percent) => percent / 100;
1593    class JSAnimation extends WithPromise {
1594        constructor(options) {
1595            super();
1596            this.state = "idle";
1597            this.startTime = null;
1598            this.isStopped = false;
vendor: 4,373 bytes, lines 1599-1692
1599            /**
1600             * The current time of the animation.
1601             */
1602            this.currentTime = 0;
1603            /**
1604             * The time at which the animation was paused.
1605             */
1606            this.holdTime = null;
1607            /**
1608             * Playback speed as a factor. 0 would be stopped, -1 reverse and 2 double speed.
1609             */
1610            this.playbackSpeed = 1;
1611            /**
1612             * This method is bound to the instance to fix a pattern where
1613             * animation.stop is returned as a reference from a useEffect.
1614             */
1615            this.stop = () => {
1616                const { motionValue } = this.options;
1617                if (motionValue && motionValue.updatedAt !== time.now()) {
1618                    this.tick(time.now());
1619                }
1620                this.isStopped = true;
1621                if (this.state === "idle")
1622                    return;
1623                this.teardown();
1624                this.options.onStop?.();
1625            };
1626            activeAnimations.mainThread++;
1627            this.options = options;
1628            this.initAnimation();
1629            this.play();
1630            if (options.autoplay === false)
1631                this.pause();
1632        }
1633        initAnimation() {
1634            const { options } = this;
1635            replaceTransitionType(options);
1636            const { type = keyframes, repeat = 0, repeatDelay = 0, repeatType, velocity = 0, } = options;
1637            let { keyframes: keyframes$1 } = options;
1638            const generatorFactory = type || keyframes;
1639            if (generatorFactory !== keyframes) {
1640                exports.invariant(keyframes$1.length <= 2, `Only two keyframes currently supported with spring and inertia animations. Trying to animate ${keyframes$1}`, "spring-two-frames");
1641            }
1642            if (generatorFactory !== keyframes &&
1643                typeof keyframes$1[0] !== "number") {
1644                this.mixKeyframes = pipe(percentToProgress, mix(keyframes$1[0], keyframes$1[1]));
1645                keyframes$1 = [0, 100];
1646            }
1647            const generator = generatorFactory({ ...options, keyframes: keyframes$1 });
1648            /**
1649             * If we have a mirror repeat type we need to create a second generator that outputs the
1650             * mirrored (not reversed) animation and later ping pong between the two generators.
1651             */
1652            if (repeatType === "mirror") {
1653                this.mirroredGenerator = generatorFactory({
1654                    ...options,
1655                    keyframes: [...keyframes$1].reverse(),
1656                    velocity: -velocity,
1657                });
1658            }
1659            /**
1660             * If duration is undefined and we have repeat options,
1661             * we need to calculate a duration from the generator.
1662             *
1663             * We set it to the generator itself to cache the duration.
1664             * Any timeline resolver will need to have already precalculated
1665             * the duration by this step.
1666             */
1667            if (generator.calculatedDuration === null) {
1668                generator.calculatedDuration = calcGeneratorDuration(generator);
1669            }
1670            const { calculatedDuration } = generator;
1671            this.calculatedDuration = calculatedDuration;
1672            this.resolvedDuration = calculatedDuration + repeatDelay;
1673            this.totalDuration = this.resolvedDuration * (repeat + 1) - repeatDelay;
1674            this.generator = generator;
1675        }
1676        updateTime(timestamp) {
1677            const animationTime = Math.round(timestamp - this.startTime) * this.playbackSpeed;
1678            // Update currentTime
1679            if (this.holdTime !== null) {
1680                this.currentTime = this.holdTime;
1681            }
1682            else {
1683                // Rounding the time because floating point arithmetic is not always accurate, e.g. 3000.367 - 1000.367 =
1684                // 2000.0000000000002. This is a problem when we are comparing the currentTime with the duration, for
1685                // example.
1686                this.currentTime = animationTime;
1687            }
1688        }
1689        tick(timestamp, sample = false) {
1690            const { generator, totalDuration, mixKeyframes, mirroredGenerator, resolvedDuration, calculatedDuration, } = this;
1691            if (this.startTime === null)
1692                return generator.next(0);
vendor: 20,678 bytes, lines 1693-2242
1693            const { delay = 0, keyframes, repeat, repeatType, repeatDelay, type, onUpdate, finalKeyframe, } = this.options;
1694            /**
1695             * requestAnimationFrame timestamps can come through as lower than
1696             * the startTime as set by performance.now(). Here we prevent this,
1697             * though in the future it could be possible to make setting startTime
1698             * a pending operation that gets resolved here.
1699             */
1700            if (this.speed > 0) {
1701                this.startTime = Math.min(this.startTime, timestamp);
1702            }
1703            else if (this.speed < 0) {
1704                this.startTime = Math.min(timestamp - totalDuration / this.speed, this.startTime);
1705            }
1706            if (sample) {
1707                this.currentTime = timestamp;
1708            }
1709            else {
1710                this.updateTime(timestamp);
1711            }
1712            // Rebase on delay
1713            const timeWithoutDelay = this.currentTime - delay * (this.playbackSpeed >= 0 ? 1 : -1);
1714            const isInDelayPhase = this.playbackSpeed >= 0
1715                ? timeWithoutDelay < 0
1716                : timeWithoutDelay > totalDuration;
1717            this.currentTime = Math.max(timeWithoutDelay, 0);
1718            // If this animation has finished, set the current time  to the total duration.
1719            if (this.state === "finished" && this.holdTime === null) {
1720                this.currentTime = totalDuration;
1721            }
1722            let elapsed = this.currentTime;
1723            let frameGenerator = generator;
1724            if (repeat) {
1725                /**
1726                 * Get the current progress (0-1) of the animation. If t is >
1727                 * than duration we'll get values like 2.5 (midway through the
1728                 * third iteration)
1729                 */
1730                const progress = Math.min(this.currentTime, totalDuration) / resolvedDuration;
1731                /**
1732                 * Get the current iteration (0 indexed). For instance the floor of
1733                 * 2.5 is 2.
1734                 */
1735                let currentIteration = Math.floor(progress);
1736                /**
1737                 * Get the current progress of the iteration by taking the remainder
1738                 * so 2.5 is 0.5 through iteration 2
1739                 */
1740                let iterationProgress = progress % 1.0;
1741                /**
1742                 * If iteration progress is 1 we count that as the end
1743                 * of the previous iteration.
1744                 */
1745                if (!iterationProgress && progress >= 1) {
1746                    iterationProgress = 1;
1747                }
1748                iterationProgress === 1 && currentIteration--;
1749                currentIteration = Math.min(currentIteration, repeat + 1);
1750                /**
1751                 * Reverse progress if we're not running in "normal" direction
1752                 */
1753                const isOddIteration = Boolean(currentIteration % 2);
1754                if (isOddIteration) {
1755                    if (repeatType === "reverse") {
1756                        iterationProgress = 1 - iterationProgress;
1757                        if (repeatDelay) {
1758                            iterationProgress -= repeatDelay / resolvedDuration;
1759                        }
1760                    }
1761                    else if (repeatType === "mirror") {
1762                        frameGenerator = mirroredGenerator;
1763                    }
1764                }
1765                elapsed = clamp(0, 1, iterationProgress) * resolvedDuration;
1766            }
1767            /**
1768             * If we're in negative time, set state as the initial keyframe.
1769             * This prevents delay: x, duration: 0 animations from finishing
1770             * instantly.
1771             */
1772            const state = isInDelayPhase
1773                ? { done: false, value: keyframes[0] }
1774                : frameGenerator.next(elapsed);
1775            if (mixKeyframes) {
1776                state.value = mixKeyframes(state.value);
1777            }
1778            let { done } = state;
1779            if (!isInDelayPhase && calculatedDuration !== null) {
1780                done =
1781                    this.playbackSpeed >= 0
1782                        ? this.currentTime >= totalDuration
1783                        : this.currentTime <= 0;
1784            }
1785            const isAnimationFinished = this.holdTime === null &&
1786                (this.state === "finished" || (this.state === "running" && done));
1787            // TODO: The exception for inertia could be cleaner here
1788            if (isAnimationFinished && type !== inertia) {
1789                state.value = getFinalKeyframe$1(keyframes, this.options, finalKeyframe, this.speed);
1790            }
1791            if (onUpdate) {
1792                onUpdate(state.value);
1793            }
1794            if (isAnimationFinished) {
1795                this.finish();
1796            }
1797            return state;
1798        }
1799        /**
1800         * Allows the returned animation to be awaited or promise-chained. Currently
1801         * resolves when the animation finishes at all but in a future update could/should
1802         * reject if its cancels.
1803         */
1804        then(resolve, reject) {
1805            return this.finished.then(resolve, reject);
1806        }
1807        get duration() {
1808            return millisecondsToSeconds(this.calculatedDuration);
1809        }
1810        get iterationDuration() {
1811            const { delay = 0 } = this.options || {};
1812            return this.duration + millisecondsToSeconds(delay);
1813        }
1814        get time() {
1815            return millisecondsToSeconds(this.currentTime);
1816        }
1817        set time(newTime) {
1818            newTime = secondsToMilliseconds(newTime);
1819            this.currentTime = newTime;
1820            if (this.startTime === null ||
1821                this.holdTime !== null ||
1822                this.playbackSpeed === 0) {
1823                this.holdTime = newTime;
1824            }
1825            else if (this.driver) {
1826                this.startTime = this.driver.now() - newTime / this.playbackSpeed;
1827            }
1828            this.driver?.start(false);
1829        }
1830        get speed() {
1831            return this.playbackSpeed;
1832        }
1833        set speed(newSpeed) {
1834            this.updateTime(time.now());
1835            const hasChanged = this.playbackSpeed !== newSpeed;
1836            this.playbackSpeed = newSpeed;
1837            if (hasChanged) {
1838                this.time = millisecondsToSeconds(this.currentTime);
1839            }
1840        }
1841        play() {
1842            if (this.isStopped)
1843                return;
1844            const { driver = frameloopDriver, startTime } = this.options;
1845            if (!this.driver) {
1846                this.driver = driver((timestamp) => this.tick(timestamp));
1847            }
1848            this.options.onPlay?.();
1849            const now = this.driver.now();
1850            if (this.state === "finished") {
1851                this.updateFinished();
1852                this.startTime = now;
1853            }
1854            else if (this.holdTime !== null) {
1855                this.startTime = now - this.holdTime;
1856            }
1857            else if (!this.startTime) {
1858                this.startTime = startTime ?? now;
1859            }
1860            if (this.state === "finished" && this.speed < 0) {
1861                this.startTime += this.calculatedDuration;
1862            }
1863            this.holdTime = null;
1864            /**
1865             * Set playState to running only after we've used it in
1866             * the previous logic.
1867             */
1868            this.state = "running";
1869            this.driver.start();
1870        }
1871        pause() {
1872            this.state = "paused";
1873            this.updateTime(time.now());
1874            this.holdTime = this.currentTime;
1875        }
1876        complete() {
1877            if (this.state !== "running") {
1878                this.play();
1879            }
1880            this.state = "finished";
1881            this.holdTime = null;
1882        }
1883        finish() {
1884            this.notifyFinished();
1885            this.teardown();
1886            this.state = "finished";
1887            this.options.onComplete?.();
1888        }
1889        cancel() {
1890            this.holdTime = null;
1891            this.startTime = 0;
1892            this.tick(0);
1893            this.teardown();
1894            this.options.onCancel?.();
1895        }
1896        teardown() {
1897            this.state = "idle";
1898            this.stopDriver();
1899            this.startTime = this.holdTime = null;
1900            activeAnimations.mainThread--;
1901        }
1902        stopDriver() {
1903            if (!this.driver)
1904                return;
1905            this.driver.stop();
1906            this.driver = undefined;
1907        }
1908        sample(sampleTime) {
1909            this.startTime = 0;
1910            return this.tick(sampleTime, true);
1911        }
1912        attachTimeline(timeline) {
1913            if (this.options.allowFlatten) {
1914                this.options.type = "keyframes";
1915                this.options.ease = "linear";
1916                this.initAnimation();
1917            }
1918            this.driver?.stop();
1919            return timeline.observe(this);
1920        }
1921    }
1922    // Legacy function support
1923    function animateValue(options) {
1924        return new JSAnimation(options);
1925    }
1926
1927    function fillWildcards(keyframes) {
1928        for (let i = 1; i < keyframes.length; i++) {
1929            keyframes[i] ?? (keyframes[i] = keyframes[i - 1]);
1930        }
1931    }
1932
1933    const radToDeg = (rad) => (rad * 180) / Math.PI;
1934    const rotate = (v) => {
1935        const angle = radToDeg(Math.atan2(v[1], v[0]));
1936        return rebaseAngle(angle);
1937    };
1938    const matrix2dParsers = {
1939        x: 4,
1940        y: 5,
1941        translateX: 4,
1942        translateY: 5,
1943        scaleX: 0,
1944        scaleY: 3,
1945        scale: (v) => (Math.abs(v[0]) + Math.abs(v[3])) / 2,
1946        rotate,
1947        rotateZ: rotate,
1948        skewX: (v) => radToDeg(Math.atan(v[1])),
1949        skewY: (v) => radToDeg(Math.atan(v[2])),
1950        skew: (v) => (Math.abs(v[1]) + Math.abs(v[2])) / 2,
1951    };
1952    const rebaseAngle = (angle) => {
1953        angle = angle % 360;
1954        if (angle < 0)
1955            angle += 360;
1956        return angle;
1957    };
1958    const rotateZ = rotate;
1959    const scaleX = (v) => Math.sqrt(v[0] * v[0] + v[1] * v[1]);
1960    const scaleY = (v) => Math.sqrt(v[4] * v[4] + v[5] * v[5]);
1961    const matrix3dParsers = {
1962        x: 12,
1963        y: 13,
1964        z: 14,
1965        translateX: 12,
1966        translateY: 13,
1967        translateZ: 14,
1968        scaleX,
1969        scaleY,
1970        scale: (v) => (scaleX(v) + scaleY(v)) / 2,
1971        rotateX: (v) => rebaseAngle(radToDeg(Math.atan2(v[6], v[5]))),
1972        rotateY: (v) => rebaseAngle(radToDeg(Math.atan2(-v[2], v[0]))),
1973        rotateZ,
1974        rotate: rotateZ,
1975        skewX: (v) => radToDeg(Math.atan(v[4])),
1976        skewY: (v) => radToDeg(Math.atan(v[1])),
1977        skew: (v) => (Math.abs(v[1]) + Math.abs(v[4])) / 2,
1978    };
1979    function defaultTransformValue(name) {
1980        return name.includes("scale") ? 1 : 0;
1981    }
1982    function parseValueFromTransform(transform, name) {
1983        if (!transform || transform === "none") {
1984            return defaultTransformValue(name);
1985        }
1986        const matrix3dMatch = transform.match(/^matrix3d\(([-\d.e\s,]+)\)$/u);
1987        let parsers;
1988        let match;
1989        if (matrix3dMatch) {
1990            parsers = matrix3dParsers;
1991            match = matrix3dMatch;
1992        }
1993        else {
1994            const matrix2dMatch = transform.match(/^matrix\(([-\d.e\s,]+)\)$/u);
1995            parsers = matrix2dParsers;
1996            match = matrix2dMatch;
1997        }
1998        if (!match) {
1999            return defaultTransformValue(name);
2000        }
2001        const valueParser = parsers[name];
2002        const values = match[1].split(",").map(convertTransformToNumber);
2003        return typeof valueParser === "function"
2004            ? valueParser(values)
2005            : values[valueParser];
2006    }
2007    const readTransformValue = (instance, name) => {
2008        const { transform = "none" } = getComputedStyle(instance);
2009        return parseValueFromTransform(transform, name);
2010    };
2011    function convertTransformToNumber(value) {
2012        return parseFloat(value.trim());
2013    }
2014
2015    /**
2016     * Generate a list of every possible transform key.
2017     */
2018    const transformPropOrder = [
2019        "transformPerspective",
2020        "x",
2021        "y",
2022        "z",
2023        "translateX",
2024        "translateY",
2025        "translateZ",
2026        "scale",
2027        "scaleX",
2028        "scaleY",
2029        "rotate",
2030        "rotateX",
2031        "rotateY",
2032        "rotateZ",
2033        "skew",
2034        "skewX",
2035        "skewY",
2036    ];
2037    /**
2038     * A quick lookup for transform props.
2039     */
2040    const transformProps = /*@__PURE__*/ (() => new Set(transformPropOrder))();
2041
2042    const isNumOrPxType = (v) => v === number || v === px;
2043    const transformKeys = new Set(["x", "y", "z"]);
2044    const nonTranslationalTransformKeys = transformPropOrder.filter((key) => !transformKeys.has(key));
2045    function removeNonTranslationalTransform(visualElement) {
2046        const removedTransforms = [];
2047        nonTranslationalTransformKeys.forEach((key) => {
2048            const value = visualElement.getValue(key);
2049            if (value !== undefined) {
2050                removedTransforms.push([key, value.get()]);
2051                value.set(key.startsWith("scale") ? 1 : 0);
2052            }
2053        });
2054        return removedTransforms;
2055    }
2056    const positionalValues = {
2057        // Dimensions
2058        width: ({ x }, { paddingLeft = "0", paddingRight = "0" }) => x.max - x.min - parseFloat(paddingLeft) - parseFloat(paddingRight),
2059        height: ({ y }, { paddingTop = "0", paddingBottom = "0" }) => y.max - y.min - parseFloat(paddingTop) - parseFloat(paddingBottom),
2060        top: (_bbox, { top }) => parseFloat(top),
2061        left: (_bbox, { left }) => parseFloat(left),
2062        bottom: ({ y }, { top }) => parseFloat(top) + (y.max - y.min),
2063        right: ({ x }, { left }) => parseFloat(left) + (x.max - x.min),
2064        // Transform
2065        x: (_bbox, { transform }) => parseValueFromTransform(transform, "x"),
2066        y: (_bbox, { transform }) => parseValueFromTransform(transform, "y"),
2067    };
2068    // Alias translate longform names
2069    positionalValues.translateX = positionalValues.x;
2070    positionalValues.translateY = positionalValues.y;
2071
2072    const toResolve = new Set();
2073    let isScheduled = false;
2074    let anyNeedsMeasurement = false;
2075    let isForced = false;
2076    function measureAllKeyframes() {
2077        if (anyNeedsMeasurement) {
2078            const resolversToMeasure = Array.from(toResolve).filter((resolver) => resolver.needsMeasurement);
2079            const elementsToMeasure = new Set(resolversToMeasure.map((resolver) => resolver.element));
2080            const transformsToRestore = new Map();
2081            /**
2082             * Write pass
2083             * If we're measuring elements we want to remove bounding box-changing transforms.
2084             */
2085            elementsToMeasure.forEach((element) => {
2086                const removedTransforms = removeNonTranslationalTransform(element);
2087                if (!removedTransforms.length)
2088                    return;
2089                transformsToRestore.set(element, removedTransforms);
2090                element.render();
2091            });
2092            // Read
2093            resolversToMeasure.forEach((resolver) => resolver.measureInitialState());
2094            // Write
2095            elementsToMeasure.forEach((element) => {
2096                element.render();
2097                const restore = transformsToRestore.get(element);
2098                if (restore) {
2099                    restore.forEach(([key, value]) => {
2100                        element.getValue(key)?.set(value);
2101                    });
2102                }
2103            });
2104            // Read
2105            resolversToMeasure.forEach((resolver) => resolver.measureEndState());
2106            // Write
2107            resolversToMeasure.forEach((resolver) => {
2108                if (resolver.suspendedScrollY !== undefined) {
2109                    window.scrollTo(0, resolver.suspendedScrollY);
2110                }
2111            });
2112        }
2113        anyNeedsMeasurement = false;
2114        isScheduled = false;
2115        toResolve.forEach((resolver) => resolver.complete(isForced));
2116        toResolve.clear();
2117    }
2118    function readAllKeyframes() {
2119        toResolve.forEach((resolver) => {
2120            resolver.readKeyframes();
2121            if (resolver.needsMeasurement) {
2122                anyNeedsMeasurement = true;
2123            }
2124        });
2125    }
2126    function flushKeyframeResolvers() {
2127        isForced = true;
2128        readAllKeyframes();
2129        measureAllKeyframes();
2130        isForced = false;
2131    }
2132    class KeyframeResolver {
2133        constructor(unresolvedKeyframes, onComplete, name, motionValue, element, isAsync = false) {
2134            this.state = "pending";
2135            /**
2136             * Track whether this resolver is async. If it is, it'll be added to the
2137             * resolver queue and flushed in the next frame. Resolvers that aren't going
2138             * to trigger read/write thrashing don't need to be async.
2139             */
2140            this.isAsync = false;
2141            /**
2142             * Track whether this resolver needs to perform a measurement
2143             * to resolve its keyframes.
2144             */
2145            this.needsMeasurement = false;
2146            this.unresolvedKeyframes = [...unresolvedKeyframes];
2147            this.onComplete = onComplete;
2148            this.name = name;
2149            this.motionValue = motionValue;
2150            this.element = element;
2151            this.isAsync = isAsync;
2152        }
2153        scheduleResolve() {
2154            this.state = "scheduled";
2155            if (this.isAsync) {
2156                toResolve.add(this);
2157                if (!isScheduled) {
2158                    isScheduled = true;
2159                    frame.read(readAllKeyframes);
2160                    frame.resolveKeyframes(measureAllKeyframes);
2161                }
2162            }
2163            else {
2164                this.readKeyframes();
2165                this.complete();
2166            }
2167        }
2168        readKeyframes() {
2169            const { unresolvedKeyframes, name, element, motionValue } = this;
2170            // If initial keyframe is null we need to read it from the DOM
2171            if (unresolvedKeyframes[0] === null) {
2172                const currentValue = motionValue?.get();
2173                // TODO: This doesn't work if the final keyframe is a wildcard
2174                const finalKeyframe = unresolvedKeyframes[unresolvedKeyframes.length - 1];
2175                if (currentValue !== undefined) {
2176                    unresolvedKeyframes[0] = currentValue;
2177                }
2178                else if (element && name) {
2179                    const valueAsRead = element.readValue(name, finalKeyframe);
2180                    if (valueAsRead !== undefined && valueAsRead !== null) {
2181                        unresolvedKeyframes[0] = valueAsRead;
2182                    }
2183                }
2184                if (unresolvedKeyframes[0] === undefined) {
2185                    unresolvedKeyframes[0] = finalKeyframe;
2186                }
2187                if (motionValue && currentValue === undefined) {
2188                    motionValue.set(unresolvedKeyframes[0]);
2189                }
2190            }
2191            fillWildcards(unresolvedKeyframes);
2192        }
2193        setFinalKeyframe() { }
2194        measureInitialState() { }
2195        renderEndStyles() { }
2196        measureEndState() { }
2197        complete(isForcedComplete = false) {
2198            this.state = "complete";
2199            this.onComplete(this.unresolvedKeyframes, this.finalKeyframe, isForcedComplete);
2200            toResolve.delete(this);
2201        }
2202        cancel() {
2203            if (this.state === "scheduled") {
2204                toResolve.delete(this);
2205                this.state = "pending";
2206            }
2207        }
2208        resume() {
2209            if (this.state === "pending")
2210                this.scheduleResolve();
2211        }
2212    }
2213
2214    const isCSSVar = (name) => name.startsWith("--");
2215
2216    function setStyle(element, name, value) {
2217        isCSSVar(name)
2218            ? element.style.setProperty(name, value)
2219            : (element.style[name] = value);
2220    }
2221
2222    const supportsScrollTimeline = /* @__PURE__ */ memo(() => window.ScrollTimeline !== undefined);
2223
2224    /**
2225     * Add the ability for test suites to manually set support flags
2226     * to better test more environments.
2227     */
2228    const supportsFlags = {};
2229
2230    function memoSupports(callback, supportsFlag) {
2231        const memoized = memo(callback);
2232        return () => supportsFlags[supportsFlag] ?? memoized();
2233    }
2234
2235    const supportsLinearEasing = /*@__PURE__*/ memoSupports(() => {
2236        try {
2237            document
2238                .createElement("div")
2239                .animate({ opacity: 0 }, { easing: "linear(0, 1)" });
2240        }
2241        catch (e) {
2242            return false;
vendor: 4,186 bytes, lines 2243-2353
2243        }
2244        return true;
2245    }, "linearEasing");
2246
2247    const cubicBezierAsString = ([a, b, c, d]) => `cubic-bezier(${a}, ${b}, ${c}, ${d})`;
2248
2249    const supportedWaapiEasing = {
2250        linear: "linear",
2251        ease: "ease",
2252        easeIn: "ease-in",
2253        easeOut: "ease-out",
2254        easeInOut: "ease-in-out",
2255        circIn: /*@__PURE__*/ cubicBezierAsString([0, 0.65, 0.55, 1]),
2256        circOut: /*@__PURE__*/ cubicBezierAsString([0.55, 0, 1, 0.45]),
2257        backIn: /*@__PURE__*/ cubicBezierAsString([0.31, 0.01, 0.66, -0.59]),
2258        backOut: /*@__PURE__*/ cubicBezierAsString([0.33, 1.53, 0.69, 0.99]),
2259    };
2260
2261    function mapEasingToNativeEasing(easing, duration) {
2262        if (!easing) {
2263            return undefined;
2264        }
2265        else if (typeof easing === "function") {
2266            return supportsLinearEasing()
2267                ? generateLinearEasing(easing, duration)
2268                : "ease-out";
2269        }
2270        else if (isBezierDefinition(easing)) {
2271            return cubicBezierAsString(easing);
2272        }
2273        else if (Array.isArray(easing)) {
2274            return easing.map((segmentEasing) => mapEasingToNativeEasing(segmentEasing, duration) ||
2275                supportedWaapiEasing.easeOut);
2276        }
2277        else {
2278            return supportedWaapiEasing[easing];
2279        }
2280    }
2281
2282    function startWaapiAnimation(element, valueName, keyframes, { delay = 0, duration = 300, repeat = 0, repeatType = "loop", ease = "easeOut", times, } = {}, pseudoElement = undefined) {
2283        const keyframeOptions = {
2284            [valueName]: keyframes,
2285        };
2286        if (times)
2287            keyframeOptions.offset = times;
2288        const easing = mapEasingToNativeEasing(ease, duration);
2289        /**
2290         * If this is an easing array, apply to keyframes, not animation as a whole
2291         */
2292        if (Array.isArray(easing))
2293            keyframeOptions.easing = easing;
2294        if (statsBuffer.value) {
2295            activeAnimations.waapi++;
2296        }
2297        const options = {
2298            delay,
2299            duration,
2300            easing: !Array.isArray(easing) ? easing : "linear",
2301            fill: "both",
2302            iterations: repeat + 1,
2303            direction: repeatType === "reverse" ? "alternate" : "normal",
2304        };
2305        if (pseudoElement)
2306            options.pseudoElement = pseudoElement;
2307        const animation = element.animate(keyframeOptions, options);
2308        if (statsBuffer.value) {
2309            animation.finished.finally(() => {
2310                activeAnimations.waapi--;
2311            });
2312        }
2313        return animation;
2314    }
2315
2316    function isGenerator(type) {
2317        return typeof type === "function" && "applyToOptions" in type;
2318    }
2319
2320    function applyGeneratorOptions({ type, ...options }) {
2321        if (isGenerator(type) && supportsLinearEasing()) {
2322            return type.applyToOptions(options);
2323        }
2324        else {
2325            options.duration ?? (options.duration = 300);
2326            options.ease ?? (options.ease = "easeOut");
2327        }
2328        return options;
2329    }
2330
2331    /**
2332     * NativeAnimation implements AnimationPlaybackControls for the browser's Web Animations API.
2333     */
2334    class NativeAnimation extends WithPromise {
2335        constructor(options) {
2336            super();
2337            this.finishedTime = null;
2338            this.isStopped = false;
2339            if (!options)
2340                return;
2341            const { element, name, keyframes, pseudoElement, allowFlatten = false, finalKeyframe, onComplete, } = options;
2342            this.isPseudoElement = Boolean(pseudoElement);
2343            this.allowFlatten = allowFlatten;
2344            this.options = options;
2345            exports.invariant(typeof options.type !== "string", `Mini animate() doesn't support "type" as a string.`, "mini-spring");
2346            const transition = applyGeneratorOptions(options);
2347            this.animation = startWaapiAnimation(element, name, keyframes, transition, pseudoElement);
2348            if (transition.autoplay === false) {
2349                this.animation.pause();
2350            }
2351            this.animation.onfinish = () => {
2352                this.finishedTime = this.time;
2353                if (!pseudoElement) {
vendor: 18,281 bytes, lines 2354-2833
2354                    const keyframe = getFinalKeyframe$1(keyframes, this.options, finalKeyframe, this.speed);
2355                    if (this.updateMotionValue) {
2356                        this.updateMotionValue(keyframe);
2357                    }
2358                    else {
2359                        /**
2360                         * If we can, we want to commit the final style as set by the user,
2361                         * rather than the computed keyframe value supplied by the animation.
2362                         */
2363                        setStyle(element, name, keyframe);
2364                    }
2365                    this.animation.cancel();
2366                }
2367                onComplete?.();
2368                this.notifyFinished();
2369            };
2370        }
2371        play() {
2372            if (this.isStopped)
2373                return;
2374            this.animation.play();
2375            if (this.state === "finished") {
2376                this.updateFinished();
2377            }
2378        }
2379        pause() {
2380            this.animation.pause();
2381        }
2382        complete() {
2383            this.animation.finish?.();
2384        }
2385        cancel() {
2386            try {
2387                this.animation.cancel();
2388            }
2389            catch (e) { }
2390        }
2391        stop() {
2392            if (this.isStopped)
2393                return;
2394            this.isStopped = true;
2395            const { state } = this;
2396            if (state === "idle" || state === "finished") {
2397                return;
2398            }
2399            if (this.updateMotionValue) {
2400                this.updateMotionValue();
2401            }
2402            else {
2403                this.commitStyles();
2404            }
2405            if (!this.isPseudoElement)
2406                this.cancel();
2407        }
2408        /**
2409         * WAAPI doesn't natively have any interruption capabilities.
2410         *
2411         * In this method, we commit styles back to the DOM before cancelling
2412         * the animation.
2413         *
2414         * This is designed to be overridden by NativeAnimationExtended, which
2415         * will create a renderless JS animation and sample it twice to calculate
2416         * its current value, "previous" value, and therefore allow
2417         * Motion to also correctly calculate velocity for any subsequent animation
2418         * while deferring the commit until the next animation frame.
2419         */
2420        commitStyles() {
2421            if (!this.isPseudoElement) {
2422                this.animation.commitStyles?.();
2423            }
2424        }
2425        get duration() {
2426            const duration = this.animation.effect?.getComputedTiming?.().duration || 0;
2427            return millisecondsToSeconds(Number(duration));
2428        }
2429        get iterationDuration() {
2430            const { delay = 0 } = this.options || {};
2431            return this.duration + millisecondsToSeconds(delay);
2432        }
2433        get time() {
2434            return millisecondsToSeconds(Number(this.animation.currentTime) || 0);
2435        }
2436        set time(newTime) {
2437            this.finishedTime = null;
2438            this.animation.currentTime = secondsToMilliseconds(newTime);
2439        }
2440        /**
2441         * The playback speed of the animation.
2442         * 1 = normal speed, 2 = double speed, 0.5 = half speed.
2443         */
2444        get speed() {
2445            return this.animation.playbackRate;
2446        }
2447        set speed(newSpeed) {
2448            // Allow backwards playback after finishing
2449            if (newSpeed < 0)
2450                this.finishedTime = null;
2451            this.animation.playbackRate = newSpeed;
2452        }
2453        get state() {
2454            return this.finishedTime !== null
2455                ? "finished"
2456                : this.animation.playState;
2457        }
2458        get startTime() {
2459            return Number(this.animation.startTime);
2460        }
2461        set startTime(newStartTime) {
2462            this.animation.startTime = newStartTime;
2463        }
2464        /**
2465         * Attaches a timeline to the animation, for instance the `ScrollTimeline`.
2466         */
2467        attachTimeline({ timeline, observe }) {
2468            if (this.allowFlatten) {
2469                this.animation.effect?.updateTiming({ easing: "linear" });
2470            }
2471            this.animation.onfinish = null;
2472            if (timeline && supportsScrollTimeline()) {
2473                this.animation.timeline = timeline;
2474                return noop;
2475            }
2476            else {
2477                return observe(this);
2478            }
2479        }
2480    }
2481
2482    const unsupportedEasingFunctions = {
2483        anticipate,
2484        backInOut,
2485        circInOut,
2486    };
2487    function isUnsupportedEase(key) {
2488        return key in unsupportedEasingFunctions;
2489    }
2490    function replaceStringEasing(transition) {
2491        if (typeof transition.ease === "string" &&
2492            isUnsupportedEase(transition.ease)) {
2493            transition.ease = unsupportedEasingFunctions[transition.ease];
2494        }
2495    }
2496
2497    /**
2498     * 10ms is chosen here as it strikes a balance between smooth
2499     * results (more than one keyframe per frame at 60fps) and
2500     * keyframe quantity.
2501     */
2502    const sampleDelta = 10; //ms
2503    class NativeAnimationExtended extends NativeAnimation {
2504        constructor(options) {
2505            /**
2506             * The base NativeAnimation function only supports a subset
2507             * of Motion easings, and WAAPI also only supports some
2508             * easing functions via string/cubic-bezier definitions.
2509             *
2510             * This function replaces those unsupported easing functions
2511             * with a JS easing function. This will later get compiled
2512             * to a linear() easing function.
2513             */
2514            replaceStringEasing(options);
2515            /**
2516             * Ensure we replace the transition type with a generator function
2517             * before passing to WAAPI.
2518             *
2519             * TODO: Does this have a better home? It could be shared with
2520             * JSAnimation.
2521             */
2522            replaceTransitionType(options);
2523            super(options);
2524            if (options.startTime) {
2525                this.startTime = options.startTime;
2526            }
2527            this.options = options;
2528        }
2529        /**
2530         * WAAPI doesn't natively have any interruption capabilities.
2531         *
2532         * Rather than read commited styles back out of the DOM, we can
2533         * create a renderless JS animation and sample it twice to calculate
2534         * its current value, "previous" value, and therefore allow
2535         * Motion to calculate velocity for any subsequent animation.
2536         */
2537        updateMotionValue(value) {
2538            const { motionValue, onUpdate, onComplete, element, ...options } = this.options;
2539            if (!motionValue)
2540                return;
2541            if (value !== undefined) {
2542                motionValue.set(value);
2543                return;
2544            }
2545            const sampleAnimation = new JSAnimation({
2546                ...options,
2547                autoplay: false,
2548            });
2549            const sampleTime = secondsToMilliseconds(this.finishedTime ?? this.time);
2550            motionValue.setWithVelocity(sampleAnimation.sample(sampleTime - sampleDelta).value, sampleAnimation.sample(sampleTime).value, sampleDelta);
2551            sampleAnimation.stop();
2552        }
2553    }
2554
2555    /**
2556     * Check if a value is animatable. Examples:
2557     *
2558     * ✅: 100, "100px", "#fff"
2559     * ❌: "block", "url(2.jpg)"
2560     * @param value
2561     *
2562     * @internal
2563     */
2564    const isAnimatable = (value, name) => {
2565        // If the list of keys that might be non-animatable grows, replace with Set
2566        if (name === "zIndex")
2567            return false;
2568        // If it's a number or a keyframes array, we can animate it. We might at some point
2569        // need to do a deep isAnimatable check of keyframes, or let Popmotion handle this,
2570        // but for now lets leave it like this for performance reasons
2571        if (typeof value === "number" || Array.isArray(value))
2572            return true;
2573        if (typeof value === "string" && // It's animatable if we have a string
2574            (complex.test(value) || value === "0") && // And it contains numbers and/or colors
2575            !value.startsWith("url(") // Unless it starts with "url("
2576        ) {
2577            return true;
2578        }
2579        return false;
2580    };
2581
2582    function hasKeyframesChanged(keyframes) {
2583        const current = keyframes[0];
2584        if (keyframes.length === 1)
2585            return true;
2586        for (let i = 0; i < keyframes.length; i++) {
2587            if (keyframes[i] !== current)
2588                return true;
2589        }
2590    }
2591    function canAnimate(keyframes, name, type, velocity) {
2592        /**
2593         * Check if we're able to animate between the start and end keyframes,
2594         * and throw a warning if we're attempting to animate between one that's
2595         * animatable and another that isn't.
2596         */
2597        const originKeyframe = keyframes[0];
2598        if (originKeyframe === null)
2599            return false;
2600        /**
2601         * These aren't traditionally animatable but we do support them.
2602         * In future we could look into making this more generic or replacing
2603         * this function with mix() === mixImmediate
2604         */
2605        if (name === "display" || name === "visibility")
2606            return true;
2607        const targetKeyframe = keyframes[keyframes.length - 1];
2608        const isOriginAnimatable = isAnimatable(originKeyframe, name);
2609        const isTargetAnimatable = isAnimatable(targetKeyframe, name);
2610        exports.warning(isOriginAnimatable === isTargetAnimatable, `You are trying to animate ${name} from "${originKeyframe}" to "${targetKeyframe}". "${isOriginAnimatable ? targetKeyframe : originKeyframe}" is not an animatable value.`, "value-not-animatable");
2611        // Always skip if any of these are true
2612        if (!isOriginAnimatable || !isTargetAnimatable) {
2613            return false;
2614        }
2615        return (hasKeyframesChanged(keyframes) ||
2616            ((type === "spring" || isGenerator(type)) && velocity));
2617    }
2618
2619    function makeAnimationInstant(options) {
2620        options.duration = 0;
2621        options.type = "keyframes";
2622    }
2623
2624    /**
2625     * A list of values that can be hardware-accelerated.
2626     */
2627    const acceleratedValues$1 = new Set([
2628        "opacity",
2629        "clipPath",
2630        "filter",
2631        "transform",
2632        // TODO: Could be re-enabled now we have support for linear() easing
2633        // "background-color"
2634    ]);
2635    const supportsWaapi = /*@__PURE__*/ memo(() => Object.hasOwnProperty.call(Element.prototype, "animate"));
2636    function supportsBrowserAnimation(options) {
2637        const { motionValue, name, repeatDelay, repeatType, damping, type } = options;
2638        const subject = motionValue?.owner?.current;
2639        /**
2640         * We use this check instead of isHTMLElement() because we explicitly
2641         * **don't** want elements in different timing contexts (i.e. popups)
2642         * to be accelerated, as it's not possible to sync these animations
2643         * properly with those driven from the main window frameloop.
2644         */
2645        if (!(subject instanceof HTMLElement)) {
2646            return false;
2647        }
2648        const { onUpdate, transformTemplate } = motionValue.owner.getProps();
2649        return (supportsWaapi() &&
2650            name &&
2651            acceleratedValues$1.has(name) &&
2652            (name !== "transform" || !transformTemplate) &&
2653            /**
2654             * If we're outputting values to onUpdate then we can't use WAAPI as there's
2655             * no way to read the value from WAAPI every frame.
2656             */
2657            !onUpdate &&
2658            !repeatDelay &&
2659            repeatType !== "mirror" &&
2660            damping !== 0 &&
2661            type !== "inertia");
2662    }
2663
2664    /**
2665     * Maximum time allowed between an animation being created and it being
2666     * resolved for us to use the latter as the start time.
2667     *
2668     * This is to ensure that while we prefer to "start" an animation as soon
2669     * as it's triggered, we also want to avoid a visual jump if there's a big delay
2670     * between these two moments.
2671     */
2672    const MAX_RESOLVE_DELAY = 40;
2673    class AsyncMotionValueAnimation extends WithPromise {
2674        constructor({ autoplay = true, delay = 0, type = "keyframes", repeat = 0, repeatDelay = 0, repeatType = "loop", keyframes, name, motionValue, element, ...options }) {
2675            super();
2676            /**
2677             * Bound to support return animation.stop pattern
2678             */
2679            this.stop = () => {
2680                if (this._animation) {
2681                    this._animation.stop();
2682                    this.stopTimeline?.();
2683                }
2684                this.keyframeResolver?.cancel();
2685            };
2686            this.createdAt = time.now();
2687            const optionsWithDefaults = {
2688                autoplay,
2689                delay,
2690                type,
2691                repeat,
2692                repeatDelay,
2693                repeatType,
2694                name,
2695                motionValue,
2696                element,
2697                ...options,
2698            };
2699            const KeyframeResolver$1 = element?.KeyframeResolver || KeyframeResolver;
2700            this.keyframeResolver = new KeyframeResolver$1(keyframes, (resolvedKeyframes, finalKeyframe, forced) => this.onKeyframesResolved(resolvedKeyframes, finalKeyframe, optionsWithDefaults, !forced), name, motionValue, element);
2701            this.keyframeResolver?.scheduleResolve();
2702        }
2703        onKeyframesResolved(keyframes, finalKeyframe, options, sync) {
2704            this.keyframeResolver = undefined;
2705            const { name, type, velocity, delay, isHandoff, onUpdate } = options;
2706            this.resolvedAt = time.now();
2707            /**
2708             * If we can't animate this value with the resolved keyframes
2709             * then we should complete it immediately.
2710             */
2711            if (!canAnimate(keyframes, name, type, velocity)) {
2712                if (MotionGlobalConfig.instantAnimations || !delay) {
2713                    onUpdate?.(getFinalKeyframe$1(keyframes, options, finalKeyframe));
2714                }
2715                keyframes[0] = keyframes[keyframes.length - 1];
2716                makeAnimationInstant(options);
2717                options.repeat = 0;
2718            }
2719            /**
2720             * Resolve startTime for the animation.
2721             *
2722             * This method uses the createdAt and resolvedAt to calculate the
2723             * animation startTime. *Ideally*, we would use the createdAt time as t=0
2724             * as the following frame would then be the first frame of the animation in
2725             * progress, which would feel snappier.
2726             *
2727             * However, if there's a delay (main thread work) between the creation of
2728             * the animation and the first commited frame, we prefer to use resolvedAt
2729             * to avoid a sudden jump into the animation.
2730             */
2731            const startTime = sync
2732                ? !this.resolvedAt
2733                    ? this.createdAt
2734                    : this.resolvedAt - this.createdAt > MAX_RESOLVE_DELAY
2735                        ? this.resolvedAt
2736                        : this.createdAt
2737                : undefined;
2738            const resolvedOptions = {
2739                startTime,
2740                finalKeyframe,
2741                ...options,
2742                keyframes,
2743            };
2744            /**
2745             * Animate via WAAPI if possible. If this is a handoff animation, the optimised animation will be running via
2746             * WAAPI. Therefore, this animation must be JS to ensure it runs "under" the
2747             * optimised animation.
2748             */
2749            const animation = !isHandoff && supportsBrowserAnimation(resolvedOptions)
2750                ? new NativeAnimationExtended({
2751                    ...resolvedOptions,
2752                    element: resolvedOptions.motionValue.owner.current,
2753                })
2754                : new JSAnimation(resolvedOptions);
2755            animation.finished.then(() => this.notifyFinished()).catch(noop);
2756            if (this.pendingTimeline) {
2757                this.stopTimeline = animation.attachTimeline(this.pendingTimeline);
2758                this.pendingTimeline = undefined;
2759            }
2760            this._animation = animation;
2761        }
2762        get finished() {
2763            if (!this._animation) {
2764                return this._finished;
2765            }
2766            else {
2767                return this.animation.finished;
2768            }
2769        }
2770        then(onResolve, _onReject) {
2771            return this.finished.finally(onResolve).then(() => { });
2772        }
2773        get animation() {
2774            if (!this._animation) {
2775                this.keyframeResolver?.resume();
2776                flushKeyframeResolvers();
2777            }
2778            return this._animation;
2779        }
2780        get duration() {
2781            return this.animation.duration;
2782        }
2783        get iterationDuration() {
2784            return this.animation.iterationDuration;
2785        }
2786        get time() {
2787            return this.animation.time;
2788        }
2789        set time(newTime) {
2790            this.animation.time = newTime;
2791        }
2792        get speed() {
2793            return this.animation.speed;
2794        }
2795        get state() {
2796            return this.animation.state;
2797        }
2798        set speed(newSpeed) {
2799            this.animation.speed = newSpeed;
2800        }
2801        get startTime() {
2802            return this.animation.startTime;
2803        }
2804        attachTimeline(timeline) {
2805            if (this._animation) {
2806                this.stopTimeline = this.animation.attachTimeline(timeline);
2807            }
2808            else {
2809                this.pendingTimeline = timeline;
2810            }
2811            return () => this.stop();
2812        }
2813        play() {
2814            this.animation.play();
2815        }
2816        pause() {
2817            this.animation.pause();
2818        }
2819        complete() {
2820            this.animation.complete();
2821        }
2822        cancel() {
2823            if (this._animation) {
2824                this.animation.cancel();
2825            }
2826            this.keyframeResolver?.cancel();
2827        }
2828    }
2829
2830    class GroupAnimation {
2831        constructor(animations) {
2832            // Bound to accomadate common `return animation.stop` pattern
2833            this.stop = () => this.runAll("stop");
vendor: 10,157 bytes, lines 2834-3169
2834            this.animations = animations.filter(Boolean);
2835        }
2836        get finished() {
2837            return Promise.all(this.animations.map((animation) => animation.finished));
2838        }
2839        /**
2840         * TODO: Filter out cancelled or stopped animations before returning
2841         */
2842        getAll(propName) {
2843            return this.animations[0][propName];
2844        }
2845        setAll(propName, newValue) {
2846            for (let i = 0; i < this.animations.length; i++) {
2847                this.animations[i][propName] = newValue;
2848            }
2849        }
2850        attachTimeline(timeline) {
2851            const subscriptions = this.animations.map((animation) => animation.attachTimeline(timeline));
2852            return () => {
2853                subscriptions.forEach((cancel, i) => {
2854                    cancel && cancel();
2855                    this.animations[i].stop();
2856                });
2857            };
2858        }
2859        get time() {
2860            return this.getAll("time");
2861        }
2862        set time(time) {
2863            this.setAll("time", time);
2864        }
2865        get speed() {
2866            return this.getAll("speed");
2867        }
2868        set speed(speed) {
2869            this.setAll("speed", speed);
2870        }
2871        get state() {
2872            return this.getAll("state");
2873        }
2874        get startTime() {
2875            return this.getAll("startTime");
2876        }
2877        get duration() {
2878            return getMax(this.animations, "duration");
2879        }
2880        get iterationDuration() {
2881            return getMax(this.animations, "iterationDuration");
2882        }
2883        runAll(methodName) {
2884            this.animations.forEach((controls) => controls[methodName]());
2885        }
2886        play() {
2887            this.runAll("play");
2888        }
2889        pause() {
2890            this.runAll("pause");
2891        }
2892        cancel() {
2893            this.runAll("cancel");
2894        }
2895        complete() {
2896            this.runAll("complete");
2897        }
2898    }
2899    function getMax(animations, propName) {
2900        let max = 0;
2901        for (let i = 0; i < animations.length; i++) {
2902            const value = animations[i][propName];
2903            if (value !== null && value > max) {
2904                max = value;
2905            }
2906        }
2907        return max;
2908    }
2909
2910    class GroupAnimationWithThen extends GroupAnimation {
2911        then(onResolve, _onReject) {
2912            return this.finished.finally(onResolve).then(() => { });
2913        }
2914    }
2915
2916    class NativeAnimationWrapper extends NativeAnimation {
2917        constructor(animation) {
2918            super();
2919            this.animation = animation;
2920            animation.onfinish = () => {
2921                this.finishedTime = this.time;
2922                this.notifyFinished();
2923            };
2924        }
2925    }
2926
2927    const animationMaps = new WeakMap();
2928    const animationMapKey = (name, pseudoElement = "") => `${name}:${pseudoElement}`;
2929    function getAnimationMap(element) {
2930        const map = animationMaps.get(element) || new Map();
2931        animationMaps.set(element, map);
2932        return map;
2933    }
2934
2935    /**
2936     * Parse Framer's special CSS variable format into a CSS token and a fallback.
2937     *
2938     * ```
2939     * `var(--foo, #fff)` => [`--foo`, '#fff']
2940     * ```
2941     *
2942     * @param current
2943     */
2944    const splitCSSVariableRegex = 
2945    // eslint-disable-next-line redos-detector/no-unsafe-regex -- false positive, as it can match a lot of words
2946    /^var\(--(?:([\w-]+)|([\w-]+), ?([a-zA-Z\d ()%#.,-]+))\)/u;
2947    function parseCSSVariable(current) {
2948        const match = splitCSSVariableRegex.exec(current);
2949        if (!match)
2950            return [,];
2951        const [, token1, token2, fallback] = match;
2952        return [`--${token1 ?? token2}`, fallback];
2953    }
2954    const maxDepth = 4;
2955    function getVariableValue(current, element, depth = 1) {
2956        exports.invariant(depth <= maxDepth, `Max CSS variable fallback depth detected in property "${current}". This may indicate a circular fallback dependency.`, "max-css-var-depth");
2957        const [token, fallback] = parseCSSVariable(current);
2958        // No CSS variable detected
2959        if (!token)
2960            return;
2961        // Attempt to read this CSS variable off the element
2962        const resolved = window.getComputedStyle(element).getPropertyValue(token);
2963        if (resolved) {
2964            const trimmed = resolved.trim();
2965            return isNumericalString(trimmed) ? parseFloat(trimmed) : trimmed;
2966        }
2967        return isCSSVariableToken(fallback)
2968            ? getVariableValue(fallback, element, depth + 1)
2969            : fallback;
2970    }
2971
2972    function getValueTransition$1(transition, key) {
2973        return (transition?.[key] ??
2974            transition?.["default"] ??
2975            transition);
2976    }
2977
2978    const positionalKeys = new Set([
2979        "width",
2980        "height",
2981        "top",
2982        "left",
2983        "right",
2984        "bottom",
2985        ...transformPropOrder,
2986    ]);
2987
2988    /**
2989     * ValueType for "auto"
2990     */
2991    const auto = {
2992        test: (v) => v === "auto",
2993        parse: (v) => v,
2994    };
2995
2996    /**
2997     * Tests a provided value against a ValueType
2998     */
2999    const testValueType = (v) => (type) => type.test(v);
3000
3001    /**
3002     * A list of value types commonly used for dimensions
3003     */
3004    const dimensionValueTypes = [number, px, percent, degrees, vw, vh, auto];
3005    /**
3006     * Tests a dimensional value against the list of dimension ValueTypes
3007     */
3008    const findDimensionValueType = (v) => dimensionValueTypes.find(testValueType(v));
3009
3010    function isNone(value) {
3011        if (typeof value === "number") {
3012            return value === 0;
3013        }
3014        else if (value !== null) {
3015            return value === "none" || value === "0" || isZeroValueString(value);
3016        }
3017        else {
3018            return true;
3019        }
3020    }
3021
3022    /**
3023     * Properties that should default to 1 or 100%
3024     */
3025    const maxDefaults = new Set(["brightness", "contrast", "saturate", "opacity"]);
3026    function applyDefaultFilter(v) {
3027        const [name, value] = v.slice(0, -1).split("(");
3028        if (name === "drop-shadow")
3029            return v;
3030        const [number] = value.match(floatRegex) || [];
3031        if (!number)
3032            return v;
3033        const unit = value.replace(number, "");
3034        let defaultValue = maxDefaults.has(name) ? 1 : 0;
3035        if (number !== value)
3036            defaultValue *= 100;
3037        return name + "(" + defaultValue + unit + ")";
3038    }
3039    const functionRegex = /\b([a-z-]*)\(.*?\)/gu;
3040    const filter = {
3041        ...complex,
3042        getAnimatableNone: (v) => {
3043            const functions = v.match(functionRegex);
3044            return functions ? functions.map(applyDefaultFilter).join(" ") : v;
3045        },
3046    };
3047
3048    const int = {
3049        ...number,
3050        transform: Math.round,
3051    };
3052
3053    const transformValueTypes = {
3054        rotate: degrees,
3055        rotateX: degrees,
3056        rotateY: degrees,
3057        rotateZ: degrees,
3058        scale,
3059        scaleX: scale,
3060        scaleY: scale,
3061        scaleZ: scale,
3062        skew: degrees,
3063        skewX: degrees,
3064        skewY: degrees,
3065        distance: px,
3066        translateX: px,
3067        translateY: px,
3068        translateZ: px,
3069        x: px,
3070        y: px,
3071        z: px,
3072        perspective: px,
3073        transformPerspective: px,
3074        opacity: alpha,
3075        originX: progressPercentage,
3076        originY: progressPercentage,
3077        originZ: px,
3078    };
3079
3080    const numberValueTypes = {
3081        // Border props
3082        borderWidth: px,
3083        borderTopWidth: px,
3084        borderRightWidth: px,
3085        borderBottomWidth: px,
3086        borderLeftWidth: px,
3087        borderRadius: px,
3088        radius: px,
3089        borderTopLeftRadius: px,
3090        borderTopRightRadius: px,
3091        borderBottomRightRadius: px,
3092        borderBottomLeftRadius: px,
3093        // Positioning props
3094        width: px,
3095        maxWidth: px,
3096        height: px,
3097        maxHeight: px,
3098        top: px,
3099        right: px,
3100        bottom: px,
3101        left: px,
3102        // Spacing props
3103        padding: px,
3104        paddingTop: px,
3105        paddingRight: px,
3106        paddingBottom: px,
3107        paddingLeft: px,
3108        margin: px,
3109        marginTop: px,
3110        marginRight: px,
3111        marginBottom: px,
3112        marginLeft: px,
3113        // Misc
3114        backgroundPositionX: px,
3115        backgroundPositionY: px,
3116        ...transformValueTypes,
3117        zIndex: int,
3118        // SVG
3119        fillOpacity: alpha,
3120        strokeOpacity: alpha,
3121        numOctaves: int,
3122    };
3123
3124    /**
3125     * A map of default value types for common values
3126     */
3127    const defaultValueTypes = {
3128        ...numberValueTypes,
3129        // Color props
3130        color,
3131        backgroundColor: color,
3132        outlineColor: color,
3133        fill: color,
3134        stroke: color,
3135        // Border props
3136        borderColor: color,
3137        borderTopColor: color,
3138        borderRightColor: color,
3139        borderBottomColor: color,
3140        borderLeftColor: color,
3141        filter,
3142        WebkitFilter: filter,
3143    };
3144    /**
3145     * Gets the default ValueType for the provided value key
3146     */
3147    const getDefaultValueType = (key) => defaultValueTypes[key];
3148
3149    function getAnimatableNone(key, value) {
3150        let defaultValueType = getDefaultValueType(key);
3151        if (defaultValueType !== filter)
3152            defaultValueType = complex;
3153        // If value is not recognised as animatable, ie "none", create an animatable version origin based on the target
3154        return defaultValueType.getAnimatableNone
3155            ? defaultValueType.getAnimatableNone(value)
3156            : undefined;
3157    }
3158
3159    /**
3160     * If we encounter keyframes like "none" or "0" and we also have keyframes like
3161     * "#fff" or "200px 200px" we want to find a keyframe to serve as a template for
3162     * the "none" keyframes. In this case "#fff" or "200px 200px" - then these get turned into
3163     * zero equivalents, i.e. "#fff0" or "0px 0px".
3164     */
3165    const invalidTemplates = new Set(["auto", "none", "0"]);
3166    function makeNoneKeyframesAnimatable(unresolvedKeyframes, noneKeyframeIndexes, name) {
3167        let i = 0;
3168        let animatableTemplate = undefined;
3169        while (i < unresolvedKeyframes.length && !animatableTemplate) {
vendor: 5,998 bytes, lines 3170-3295
3170            const keyframe = unresolvedKeyframes[i];
3171            if (typeof keyframe === "string" &&
3172                !invalidTemplates.has(keyframe) &&
3173                analyseComplexValue(keyframe).values.length) {
3174                animatableTemplate = unresolvedKeyframes[i];
3175            }
3176            i++;
3177        }
3178        if (animatableTemplate && name) {
3179            for (const noneIndex of noneKeyframeIndexes) {
3180                unresolvedKeyframes[noneIndex] = getAnimatableNone(name, animatableTemplate);
3181            }
3182        }
3183    }
3184
3185    class DOMKeyframesResolver extends KeyframeResolver {
3186        constructor(unresolvedKeyframes, onComplete, name, motionValue, element) {
3187            super(unresolvedKeyframes, onComplete, name, motionValue, element, true);
3188        }
3189        readKeyframes() {
3190            const { unresolvedKeyframes, element, name } = this;
3191            if (!element || !element.current)
3192                return;
3193            super.readKeyframes();
3194            /**
3195             * If any keyframe is a CSS variable, we need to find its value by sampling the element
3196             */
3197            for (let i = 0; i < unresolvedKeyframes.length; i++) {
3198                let keyframe = unresolvedKeyframes[i];
3199                if (typeof keyframe === "string") {
3200                    keyframe = keyframe.trim();
3201                    if (isCSSVariableToken(keyframe)) {
3202                        const resolved = getVariableValue(keyframe, element.current);
3203                        if (resolved !== undefined) {
3204                            unresolvedKeyframes[i] = resolved;
3205                        }
3206                        if (i === unresolvedKeyframes.length - 1) {
3207                            this.finalKeyframe = keyframe;
3208                        }
3209                    }
3210                }
3211            }
3212            /**
3213             * Resolve "none" values. We do this potentially twice - once before and once after measuring keyframes.
3214             * This could be seen as inefficient but it's a trade-off to avoid measurements in more situations, which
3215             * have a far bigger performance impact.
3216             */
3217            this.resolveNoneKeyframes();
3218            /**
3219             * Check to see if unit type has changed. If so schedule jobs that will
3220             * temporarily set styles to the destination keyframes.
3221             * Skip if we have more than two keyframes or this isn't a positional value.
3222             * TODO: We can throw if there are multiple keyframes and the value type changes.
3223             */
3224            if (!positionalKeys.has(name) || unresolvedKeyframes.length !== 2) {
3225                return;
3226            }
3227            const [origin, target] = unresolvedKeyframes;
3228            const originType = findDimensionValueType(origin);
3229            const targetType = findDimensionValueType(target);
3230            /**
3231             * Either we don't recognise these value types or we can animate between them.
3232             */
3233            if (originType === targetType)
3234                return;
3235            /**
3236             * If both values are numbers or pixels, we can animate between them by
3237             * converting them to numbers.
3238             */
3239            if (isNumOrPxType(originType) && isNumOrPxType(targetType)) {
3240                for (let i = 0; i < unresolvedKeyframes.length; i++) {
3241                    const value = unresolvedKeyframes[i];
3242                    if (typeof value === "string") {
3243                        unresolvedKeyframes[i] = parseFloat(value);
3244                    }
3245                }
3246            }
3247            else if (positionalValues[name]) {
3248                /**
3249                 * Else, the only way to resolve this is by measuring the element.
3250                 */
3251                this.needsMeasurement = true;
3252            }
3253        }
3254        resolveNoneKeyframes() {
3255            const { unresolvedKeyframes, name } = this;
3256            const noneKeyframeIndexes = [];
3257            for (let i = 0; i < unresolvedKeyframes.length; i++) {
3258                if (unresolvedKeyframes[i] === null ||
3259                    isNone(unresolvedKeyframes[i])) {
3260                    noneKeyframeIndexes.push(i);
3261                }
3262            }
3263            if (noneKeyframeIndexes.length) {
3264                makeNoneKeyframesAnimatable(unresolvedKeyframes, noneKeyframeIndexes, name);
3265            }
3266        }
3267        measureInitialState() {
3268            const { element, unresolvedKeyframes, name } = this;
3269            if (!element || !element.current)
3270                return;
3271            if (name === "height") {
3272                this.suspendedScrollY = window.pageYOffset;
3273            }
3274            this.measuredOrigin = positionalValues[name](element.measureViewportBox(), window.getComputedStyle(element.current));
3275            unresolvedKeyframes[0] = this.measuredOrigin;
3276            // Set final key frame to measure after next render
3277            const measureKeyframe = unresolvedKeyframes[unresolvedKeyframes.length - 1];
3278            if (measureKeyframe !== undefined) {
3279                element.getValue(name, measureKeyframe).jump(measureKeyframe, false);
3280            }
3281        }
3282        measureEndState() {
3283            const { element, name, unresolvedKeyframes } = this;
3284            if (!element || !element.current)
3285                return;
3286            const value = element.getValue(name);
3287            value && value.jump(this.measuredOrigin, false);
3288            const finalKeyframeIndex = unresolvedKeyframes.length - 1;
3289            const finalKeyframe = unresolvedKeyframes[finalKeyframeIndex];
3290            unresolvedKeyframes[finalKeyframeIndex] = positionalValues[name](element.measureViewportBox(), window.getComputedStyle(element.current));
3291            if (finalKeyframe !== null && this.finalKeyframe === undefined) {
3292                this.finalKeyframe = finalKeyframe;
3293            }
3294            // If we removed transform values, reapply them before the next render
3295            if (this.removedTransforms?.length) {
3296                this.removedTransforms.forEach(([unsetTransformName, unsetTransformValue]) => {
3297                    element
3298                        .getValue(unsetTransformName)
3299                        .set(unsetTransformValue);
3300                });
3301            }
3302            this.resolveNoneKeyframes();
3303        }
3304    }
3305
3306    const pxValues = new Set([
3307        // Border props
3308        "borderWidth",
3309        "borderTopWidth",
3310        "borderRightWidth",
3311        "borderBottomWidth",
3312        "borderLeftWidth",
3313        "borderRadius",
3314        "radius",
3315        "borderTopLeftRadius",
3316        "borderTopRightRadius",
3317        "borderBottomRightRadius",
3318        "borderBottomLeftRadius",
3319        // Positioning props
3320        "width",
3321        "maxWidth",
3322        "height",
3323        "maxHeight",
3324        "top",
3325        "right",
3326        "bottom",
3327        "left",
3328        // Spacing props
3329        "padding",
3330        "paddingTop",
3331        "paddingRight",
3332        "paddingBottom",
3333        "paddingLeft",
3334        "margin",
3335        "marginTop",
3336        "marginRight",
3337        "marginBottom",
3338        "marginLeft",
3339        // Misc
3340        "backgroundPositionX",
3341        "backgroundPositionY",
3342    ]);
3343
3344    function applyPxDefaults(keyframes, name) {
3345        for (let i = 0; i < keyframes.length; i++) {
3346            if (typeof keyframes[i] === "number" && pxValues.has(name)) {
3347                keyframes[i] = keyframes[i] + "px";
3348            }
3349        }
3350    }
3351
3352    function isWaapiSupportedEasing(easing) {
3353        return Boolean((typeof easing === "function" && supportsLinearEasing()) ||
3354            !easing ||
3355            (typeof easing === "string" &&
3356                (easing in supportedWaapiEasing || supportsLinearEasing())) ||
3357            isBezierDefinition(easing) ||
3358            (Array.isArray(easing) && easing.every(isWaapiSupportedEasing)));
3359    }
3360
3361    const supportsPartialKeyframes = /*@__PURE__*/ memo(() => {
3362        try {
3363            document.createElement("div").animate({ opacity: [1] });
3364        }
3365        catch (e) {
3366            return false;
3367        }
3368        return true;
3369    });
3370
3371    /**
3372     * A list of values that can be hardware-accelerated.
3373     */
3374    const acceleratedValues = new Set([
3375        "opacity",
3376        "clipPath",
3377        "filter",
3378        "transform",
3379        // TODO: Can be accelerated but currently disabled until https://issues.chromium.org/issues/41491098 is resolved
3380        // or until we implement support for linear() easing.
3381        // "background-color"
3382    ]);
3383
3384    function camelToDash$1(str) {
3385        return str.replace(/([A-Z])/g, (match) => `-${match.toLowerCase()}`);
3386    }
3387
3388    function resolveElements(elementOrSelector, scope, selectorCache) {
3389        if (elementOrSelector instanceof EventTarget) {
3390            return [elementOrSelector];
3391        }
3392        else if (typeof elementOrSelector === "string") {
3393            let root = document;
3394            if (scope) {
3395                root = scope.current;
3396            }
3397            const elements = selectorCache?.[elementOrSelector] ??
3398                root.querySelectorAll(elementOrSelector);
3399            return elements ? Array.from(elements) : [];
3400        }
3401        return Array.from(elementOrSelector);
3402    }
3403
3404    function createSelectorEffect(subjectEffect) {
3405        return (subject, values) => {
3406            const elements = resolveElements(subject);
3407            const subscriptions = [];
3408            for (const element of elements) {
3409                const remove = subjectEffect(element, values);
3410                subscriptions.push(remove);
3411            }
3412            return () => {
3413                for (const remove of subscriptions)
3414                    remove();
3415            };
3416        };
3417    }
3418
3419    /**
3420     * Provided a value and a ValueType, returns the value as that value type.
3421     */
3422    const getValueAsType = (value, type) => {
3423        return type && typeof value === "number"
3424            ? type.transform(value)
3425            : value;
3426    };
3427
3428    class MotionValueState {
3429        constructor() {
3430            this.latest = {};
3431            this.values = new Map();
3432        }
3433        set(name, value, render, computed, useDefaultValueType = true) {
3434            const existingValue = this.values.get(name);
3435            if (existingValue) {
3436                existingValue.onRemove();
3437            }
3438            const onChange = () => {
3439                const v = value.get();
3440                if (useDefaultValueType) {
3441                    this.latest[name] = getValueAsType(v, numberValueTypes[name]);
3442                }
3443                else {
3444                    this.latest[name] = v;
3445                }
3446                render && frame.render(render);
3447            };
3448            onChange();
3449            const cancelOnChange = value.on("change", onChange);
3450            computed && value.addDependent(computed);
3451            const remove = () => {
3452                cancelOnChange();
3453                render && cancelFrame(render);
3454                this.values.delete(name);
3455                computed && value.removeDependent(computed);
3456            };
3457            this.values.set(name, { value, onRemove: remove });
3458            return remove;
3459        }
3460        get(name) {
3461            return this.values.get(name)?.value;
3462        }
3463        destroy() {
3464            for (const value of this.values.values()) {
3465                value.onRemove();
3466            }
3467        }
3468    }
3469
3470    function createEffect(addValue) {
3471        const stateCache = new WeakMap();
3472        const subscriptions = [];
3473        return (subject, values) => {
3474            const state = stateCache.get(subject) ?? new MotionValueState();
3475            stateCache.set(subject, state);
3476            for (const key in values) {
3477                const value = values[key];
3478                const remove = addValue(subject, state, key, value);
3479                subscriptions.push(remove);
3480            }
3481            return () => {
3482                for (const cancel of subscriptions)
3483                    cancel();
3484            };
3485        };
3486    }
3487
3488    function canSetAsProperty(element, name) {
3489        if (!(name in element))
3490            return false;
3491        const descriptor = Object.getOwnPropertyDescriptor(Object.getPrototypeOf(element), name) ||
3492            Object.getOwnPropertyDescriptor(element, name);
3493        // Check if it has a setter
3494        return descriptor && typeof descriptor.set === "function";
3495    }
3496    const addAttrValue = (element, state, key, value) => {
3497        const isProp = canSetAsProperty(element, key);
3498        const name = isProp
3499            ? key
3500            : key.startsWith("data") || key.startsWith("aria")
3501                ? camelToDash$1(key)
3502                : key;
3503        /**
3504         * Set attribute directly via property if available
3505         */
3506        const render = isProp
3507            ? () => {
3508                element[name] = state.latest[key];
3509            }
3510            : () => {
3511                const v = state.latest[key];
3512                if (v === null || v === undefined) {
3513                    element.removeAttribute(name);
3514                }
3515                else {
3516                    element.setAttribute(name, String(v));
3517                }
3518            };
3519        return state.set(key, value, render);
3520    };
3521    const attrEffect = /*@__PURE__*/ createSelectorEffect(
3522    /*@__PURE__*/ createEffect(addAttrValue));
3523
3524    const propEffect = /*@__PURE__*/ createEffect((subject, state, key, value) => {
3525        return state.set(key, value, () => {
3526            subject[key] = state.latest[key];
3527        }, undefined, false);
3528    });
3529
3530    /**
3531     * Checks if an element is an HTML element in a way
3532     * that works across iframes
3533     */
3534    function isHTMLElement(element) {
3535        return isObject(element) && "offsetHeight" in element;
3536    }
3537
3538    /**
3539     * Maximum time between the value of two frames, beyond which we
3540     * assume the velocity has since been 0.
3541     */
3542    const MAX_VELOCITY_DELTA = 30;
3543    const isFloat = (value) => {
3544        return !isNaN(parseFloat(value));
3545    };
3546    const collectMotionValues = {
3547        current: undefined,
3548    };
3549    /**
3550     * `MotionValue` is used to track the state and velocity of motion values.
3551     *
3552     * @public
3553     */
3554    class MotionValue {
3555        /**
3556         * @param init - The initiating value
3557         * @param config - Optional configuration options
3558         *
3559         * -  `transformer`: A function to transform incoming values with.
3560         */
3561        constructor(init, options = {}) {
3562            /**
3563             * Tracks whether this value can output a velocity. Currently this is only true
3564             * if the value is numerical, but we might be able to widen the scope here and support
3565             * other value types.
3566             *
3567             * @internal
3568             */
3569            this.canTrackVelocity = null;
3570            /**
3571             * An object containing a SubscriptionManager for each active event.
3572             */
3573            this.events = {};
3574            this.updateAndNotify = (v) => {
3575                const currentTime = time.now();
3576                /**
3577                 * If we're updating the value during another frame or eventloop
3578                 * than the previous frame, then the we set the previous frame value
3579                 * to current.
3580                 */
3581                if (this.updatedAt !== currentTime) {
3582                    this.setPrevFrameValue();
3583                }
3584                this.prev = this.current;
3585                this.setCurrent(v);
3586                // Update update subscribers
3587                if (this.current !== this.prev) {
3588                    this.events.change?.notify(this.current);
3589                    if (this.dependents) {
3590                        for (const dependent of this.dependents) {
3591                            dependent.dirty();
3592                        }
3593                    }
3594                }
3595            };
3596            this.hasAnimated = false;
vendor: 9,660 bytes, lines 3597-3882
3597            this.setCurrent(init);
3598            this.owner = options.owner;
3599        }
3600        setCurrent(current) {
3601            this.current = current;
3602            this.updatedAt = time.now();
3603            if (this.canTrackVelocity === null && current !== undefined) {
3604                this.canTrackVelocity = isFloat(this.current);
3605            }
3606        }
3607        setPrevFrameValue(prevFrameValue = this.current) {
3608            this.prevFrameValue = prevFrameValue;
3609            this.prevUpdatedAt = this.updatedAt;
3610        }
3611        /**
3612         * Adds a function that will be notified when the `MotionValue` is updated.
3613         *
3614         * It returns a function that, when called, will cancel the subscription.
3615         *
3616         * When calling `onChange` inside a React component, it should be wrapped with the
3617         * `useEffect` hook. As it returns an unsubscribe function, this should be returned
3618         * from the `useEffect` function to ensure you don't add duplicate subscribers..
3619         *
3620         * ```jsx
3621         * export const MyComponent = () => {
3622         *   const x = useMotionValue(0)
3623         *   const y = useMotionValue(0)
3624         *   const opacity = useMotionValue(1)
3625         *
3626         *   useEffect(() => {
3627         *     function updateOpacity() {
3628         *       const maxXY = Math.max(x.get(), y.get())
3629         *       const newOpacity = transform(maxXY, [0, 100], [1, 0])
3630         *       opacity.set(newOpacity)
3631         *     }
3632         *
3633         *     const unsubscribeX = x.on("change", updateOpacity)
3634         *     const unsubscribeY = y.on("change", updateOpacity)
3635         *
3636         *     return () => {
3637         *       unsubscribeX()
3638         *       unsubscribeY()
3639         *     }
3640         *   }, [])
3641         *
3642         *   return <motion.div style={{ x }} />
3643         * }
3644         * ```
3645         *
3646         * @param subscriber - A function that receives the latest value.
3647         * @returns A function that, when called, will cancel this subscription.
3648         *
3649         * @deprecated
3650         */
3651        onChange(subscription) {
3652            {
3653                warnOnce(false, `value.onChange(callback) is deprecated. Switch to value.on("change", callback).`);
3654            }
3655            return this.on("change", subscription);
3656        }
3657        on(eventName, callback) {
3658            if (!this.events[eventName]) {
3659                this.events[eventName] = new SubscriptionManager();
3660            }
3661            const unsubscribe = this.events[eventName].add(callback);
3662            if (eventName === "change") {
3663                return () => {
3664                    unsubscribe();
3665                    /**
3666                     * If we have no more change listeners by the start
3667                     * of the next frame, stop active animations.
3668                     */
3669                    frame.read(() => {
3670                        if (!this.events.change.getSize()) {
3671                            this.stop();
3672                        }
3673                    });
3674                };
3675            }
3676            return unsubscribe;
3677        }
3678        clearListeners() {
3679            for (const eventManagers in this.events) {
3680                this.events[eventManagers].clear();
3681            }
3682        }
3683        /**
3684         * Attaches a passive effect to the `MotionValue`.
3685         */
3686        attach(passiveEffect, stopPassiveEffect) {
3687            this.passiveEffect = passiveEffect;
3688            this.stopPassiveEffect = stopPassiveEffect;
3689        }
3690        /**
3691         * Sets the state of the `MotionValue`.
3692         *
3693         * @remarks
3694         *
3695         * ```jsx
3696         * const x = useMotionValue(0)
3697         * x.set(10)
3698         * ```
3699         *
3700         * @param latest - Latest value to set.
3701         * @param render - Whether to notify render subscribers. Defaults to `true`
3702         *
3703         * @public
3704         */
3705        set(v) {
3706            if (!this.passiveEffect) {
3707                this.updateAndNotify(v);
3708            }
3709            else {
3710                this.passiveEffect(v, this.updateAndNotify);
3711            }
3712        }
3713        setWithVelocity(prev, current, delta) {
3714            this.set(current);
3715            this.prev = undefined;
3716            this.prevFrameValue = prev;
3717            this.prevUpdatedAt = this.updatedAt - delta;
3718        }
3719        /**
3720         * Set the state of the `MotionValue`, stopping any active animations,
3721         * effects, and resets velocity to `0`.
3722         */
3723        jump(v, endAnimation = true) {
3724            this.updateAndNotify(v);
3725            this.prev = v;
3726            this.prevUpdatedAt = this.prevFrameValue = undefined;
3727            endAnimation && this.stop();
3728            if (this.stopPassiveEffect)
3729                this.stopPassiveEffect();
3730        }
3731        dirty() {
3732            this.events.change?.notify(this.current);
3733        }
3734        addDependent(dependent) {
3735            if (!this.dependents) {
3736                this.dependents = new Set();
3737            }
3738            this.dependents.add(dependent);
3739        }
3740        removeDependent(dependent) {
3741            if (this.dependents) {
3742                this.dependents.delete(dependent);
3743            }
3744        }
3745        /**
3746         * Returns the latest state of `MotionValue`
3747         *
3748         * @returns - The latest state of `MotionValue`
3749         *
3750         * @public
3751         */
3752        get() {
3753            if (collectMotionValues.current) {
3754                collectMotionValues.current.push(this);
3755            }
3756            return this.current;
3757        }
3758        /**
3759         * @public
3760         */
3761        getPrevious() {
3762            return this.prev;
3763        }
3764        /**
3765         * Returns the latest velocity of `MotionValue`
3766         *
3767         * @returns - The latest velocity of `MotionValue`. Returns `0` if the state is non-numerical.
3768         *
3769         * @public
3770         */
3771        getVelocity() {
3772            const currentTime = time.now();
3773            if (!this.canTrackVelocity ||
3774                this.prevFrameValue === undefined ||
3775                currentTime - this.updatedAt > MAX_VELOCITY_DELTA) {
3776                return 0;
3777            }
3778            const delta = Math.min(this.updatedAt - this.prevUpdatedAt, MAX_VELOCITY_DELTA);
3779            // Casts because of parseFloat's poor typing
3780            return velocityPerSecond(parseFloat(this.current) -
3781                parseFloat(this.prevFrameValue), delta);
3782        }
3783        /**
3784         * Registers a new animation to control this `MotionValue`. Only one
3785         * animation can drive a `MotionValue` at one time.
3786         *
3787         * ```jsx
3788         * value.start()
3789         * ```
3790         *
3791         * @param animation - A function that starts the provided animation
3792         */
3793        start(startAnimation) {
3794            this.stop();
3795            return new Promise((resolve) => {
3796                this.hasAnimated = true;
3797                this.animation = startAnimation(resolve);
3798                if (this.events.animationStart) {
3799                    this.events.animationStart.notify();
3800                }
3801            }).then(() => {
3802                if (this.events.animationComplete) {
3803                    this.events.animationComplete.notify();
3804                }
3805                this.clearAnimation();
3806            });
3807        }
3808        /**
3809         * Stop the currently active animation.
3810         *
3811         * @public
3812         */
3813        stop() {
3814            if (this.animation) {
3815                this.animation.stop();
3816                if (this.events.animationCancel) {
3817                    this.events.animationCancel.notify();
3818                }
3819            }
3820            this.clearAnimation();
3821        }
3822        /**
3823         * Returns `true` if this value is currently animating.
3824         *
3825         * @public
3826         */
3827        isAnimating() {
3828            return !!this.animation;
3829        }
3830        clearAnimation() {
3831            delete this.animation;
3832        }
3833        /**
3834         * Destroy and clean up subscribers to this `MotionValue`.
3835         *
3836         * The `MotionValue` hooks like `useMotionValue` and `useTransform` automatically
3837         * handle the lifecycle of the returned `MotionValue`, so this method is only necessary if you've manually
3838         * created a `MotionValue` via the `motionValue` function.
3839         *
3840         * @public
3841         */
3842        destroy() {
3843            this.dependents?.clear();
3844            this.events.destroy?.notify();
3845            this.clearListeners();
3846            this.stop();
3847            if (this.stopPassiveEffect) {
3848                this.stopPassiveEffect();
3849            }
3850        }
3851    }
3852    function motionValue(init, options) {
3853        return new MotionValue(init, options);
3854    }
3855
3856    const translateAlias$1 = {
3857        x: "translateX",
3858        y: "translateY",
3859        z: "translateZ",
3860        transformPerspective: "perspective",
3861    };
3862    function buildTransform$1(state) {
3863        let transform = "";
3864        let transformIsDefault = true;
3865        /**
3866         * Loop over all possible transforms in order, adding the ones that
3867         * are present to the transform string.
3868         */
3869        for (let i = 0; i < transformPropOrder.length; i++) {
3870            const key = transformPropOrder[i];
3871            const value = state.latest[key];
3872            if (value === undefined)
3873                continue;
3874            let valueIsDefault = true;
3875            if (typeof value === "number") {
3876                valueIsDefault = value === (key.startsWith("scale") ? 1 : 0);
3877            }
3878            else {
3879                valueIsDefault = parseFloat(value) === 0;
3880            }
3881            if (!valueIsDefault) {
3882                transformIsDefault = false;
3883                const transformName = translateAlias$1[key] || key;
3884                const valueToRender = state.latest[key];
3885                transform += `${transformName}(${valueToRender}) `;
3886            }
3887        }
3888        return transformIsDefault ? "none" : transform.trim();
3889    }
3890
3891    const originProps = new Set(["originX", "originY", "originZ"]);
3892    const addStyleValue = (element, state, key, value) => {
3893        let render = undefined;
3894        let computed = undefined;
3895        if (transformProps.has(key)) {
3896            if (!state.get("transform")) {
3897                // If this is an HTML element, we need to set the transform-box to fill-box
3898                // to normalise the transform relative to the element's bounding box
3899                if (!isHTMLElement(element) && !state.get("transformBox")) {
3900                    addStyleValue(element, state, "transformBox", new MotionValue("fill-box"));
3901                }
3902                state.set("transform", new MotionValue("none"), () => {
3903                    element.style.transform = buildTransform$1(state);
3904                });
3905            }
3906            computed = state.get("transform");
3907        }
3908        else if (originProps.has(key)) {
3909            if (!state.get("transformOrigin")) {
3910                state.set("transformOrigin", new MotionValue(""), () => {
3911                    const originX = state.latest.originX ?? "50%";
3912                    const originY = state.latest.originY ?? "50%";
3913                    const originZ = state.latest.originZ ?? 0;
3914                    element.style.transformOrigin = `${originX} ${originY} ${originZ}`;
3915                });
3916            }
3917            computed = state.get("transformOrigin");
3918        }
3919        else if (isCSSVar(key)) {
3920            render = () => {
3921                element.style.setProperty(key, state.latest[key]);
3922            };
3923        }
3924        else {
3925            render = () => {
3926                element.style[key] = state.latest[key];
3927            };
3928        }
3929        return state.set(key, value, render, computed);
3930    };
3931    const styleEffect = /*@__PURE__*/ createSelectorEffect(
3932    /*@__PURE__*/ createEffect(addStyleValue));
3933
3934    const toPx = px.transform;
3935    function addSVGPathValue(element, state, key, value) {
3936        frame.render(() => element.setAttribute("pathLength", "1"));
3937        if (key === "pathOffset") {
3938            return state.set(key, value, () => element.setAttribute("stroke-dashoffset", toPx(-state.latest[key])));
3939        }
3940        else {
3941            if (!state.get("stroke-dasharray")) {
3942                state.set("stroke-dasharray", new MotionValue("1 1"), () => {
3943                    const { pathLength = 1, pathSpacing } = state.latest;
3944                    element.setAttribute("stroke-dasharray", `${toPx(pathLength)} ${toPx(pathSpacing ?? 1 - Number(pathLength))}`);
3945                });
3946            }
3947            return state.set(key, value, undefined, state.get("stroke-dasharray"));
3948        }
3949    }
3950    const addSVGValue = (element, state, key, value) => {
3951        if (key.startsWith("path")) {
3952            return addSVGPathValue(element, state, key, value);
3953        }
3954        else if (key.startsWith("attr")) {
3955            return addAttrValue(element, state, convertAttrKey(key), value);
3956        }
3957        const handler = key in element.style ? addStyleValue : addAttrValue;
3958        return handler(element, state, key, value);
3959    };
3960    const svgEffect = /*@__PURE__*/ createSelectorEffect(
3961    /*@__PURE__*/ createEffect(addSVGValue));
3962    function convertAttrKey(key) {
3963        return key.replace(/^attr([A-Z])/, (_, firstChar) => firstChar.toLowerCase());
3964    }
3965
3966    const { schedule: microtask, cancel: cancelMicrotask } = 
3967    /* @__PURE__ */ createRenderBatcher(queueMicrotask, false);
3968
3969    const isDragging = {
3970        x: false,
3971        y: false,
3972    };
3973    function isDragActive() {
3974        return isDragging.x || isDragging.y;
3975    }
3976
3977    function setDragLock(axis) {
3978        if (axis === "x" || axis === "y") {
3979            if (isDragging[axis]) {
3980                return null;
3981            }
3982            else {
3983                isDragging[axis] = true;
3984                return () => {
3985                    isDragging[axis] = false;
vendor: 7,642 bytes, lines 3986-4190
3986                };
3987            }
3988        }
3989        else {
3990            if (isDragging.x || isDragging.y) {
3991                return null;
3992            }
3993            else {
3994                isDragging.x = isDragging.y = true;
3995                return () => {
3996                    isDragging.x = isDragging.y = false;
3997                };
3998            }
3999        }
4000    }
4001
4002    function setupGesture(elementOrSelector, options) {
4003        const elements = resolveElements(elementOrSelector);
4004        const gestureAbortController = new AbortController();
4005        const eventOptions = {
4006            passive: true,
4007            ...options,
4008            signal: gestureAbortController.signal,
4009        };
4010        const cancel = () => gestureAbortController.abort();
4011        return [elements, eventOptions, cancel];
4012    }
4013
4014    function isValidHover(event) {
4015        return !(event.pointerType === "touch" || isDragActive());
4016    }
4017    /**
4018     * Create a hover gesture. hover() is different to .addEventListener("pointerenter")
4019     * in that it has an easier syntax, filters out polyfilled touch events, interoperates
4020     * with drag gestures, and automatically removes the "pointerennd" event listener when the hover ends.
4021     *
4022     * @public
4023     */
4024    function hover(elementOrSelector, onHoverStart, options = {}) {
4025        const [elements, eventOptions, cancel] = setupGesture(elementOrSelector, options);
4026        const onPointerEnter = (enterEvent) => {
4027            if (!isValidHover(enterEvent))
4028                return;
4029            const { target } = enterEvent;
4030            const onHoverEnd = onHoverStart(target, enterEvent);
4031            if (typeof onHoverEnd !== "function" || !target)
4032                return;
4033            const onPointerLeave = (leaveEvent) => {
4034                if (!isValidHover(leaveEvent))
4035                    return;
4036                onHoverEnd(leaveEvent);
4037                target.removeEventListener("pointerleave", onPointerLeave);
4038            };
4039            target.addEventListener("pointerleave", onPointerLeave, eventOptions);
4040        };
4041        elements.forEach((element) => {
4042            element.addEventListener("pointerenter", onPointerEnter, eventOptions);
4043        });
4044        return cancel;
4045    }
4046
4047    /**
4048     * Recursively traverse up the tree to check whether the provided child node
4049     * is the parent or a descendant of it.
4050     *
4051     * @param parent - Element to find
4052     * @param child - Element to test against parent
4053     */
4054    const isNodeOrChild = (parent, child) => {
4055        if (!child) {
4056            return false;
4057        }
4058        else if (parent === child) {
4059            return true;
4060        }
4061        else {
4062            return isNodeOrChild(parent, child.parentElement);
4063        }
4064    };
4065
4066    const isPrimaryPointer = (event) => {
4067        if (event.pointerType === "mouse") {
4068            return typeof event.button !== "number" || event.button <= 0;
4069        }
4070        else {
4071            /**
4072             * isPrimary is true for all mice buttons, whereas every touch point
4073             * is regarded as its own input. So subsequent concurrent touch points
4074             * will be false.
4075             *
4076             * Specifically match against false here as incomplete versions of
4077             * PointerEvents in very old browser might have it set as undefined.
4078             */
4079            return event.isPrimary !== false;
4080        }
4081    };
4082
4083    const focusableElements = new Set([
4084        "BUTTON",
4085        "INPUT",
4086        "SELECT",
4087        "TEXTAREA",
4088        "A",
4089    ]);
4090    function isElementKeyboardAccessible(element) {
4091        return (focusableElements.has(element.tagName) ||
4092            element.tabIndex !== -1);
4093    }
4094
4095    const isPressing = new WeakSet();
4096
4097    /**
4098     * Filter out events that are not "Enter" keys.
4099     */
4100    function filterEvents(callback) {
4101        return (event) => {
4102            if (event.key !== "Enter")
4103                return;
4104            callback(event);
4105        };
4106    }
4107    function firePointerEvent(target, type) {
4108        target.dispatchEvent(new PointerEvent("pointer" + type, { isPrimary: true, bubbles: true }));
4109    }
4110    const enableKeyboardPress = (focusEvent, eventOptions) => {
4111        const element = focusEvent.currentTarget;
4112        if (!element)
4113            return;
4114        const handleKeydown = filterEvents(() => {
4115            if (isPressing.has(element))
4116                return;
4117            firePointerEvent(element, "down");
4118            const handleKeyup = filterEvents(() => {
4119                firePointerEvent(element, "up");
4120            });
4121            const handleBlur = () => firePointerEvent(element, "cancel");
4122            element.addEventListener("keyup", handleKeyup, eventOptions);
4123            element.addEventListener("blur", handleBlur, eventOptions);
4124        });
4125        element.addEventListener("keydown", handleKeydown, eventOptions);
4126        /**
4127         * Add an event listener that fires on blur to remove the keydown events.
4128         */
4129        element.addEventListener("blur", () => element.removeEventListener("keydown", handleKeydown), eventOptions);
4130    };
4131
4132    /**
4133     * Filter out events that are not primary pointer events, or are triggering
4134     * while a Motion gesture is active.
4135     */
4136    function isValidPressEvent(event) {
4137        return isPrimaryPointer(event) && !isDragActive();
4138    }
4139    /**
4140     * Create a press gesture.
4141     *
4142     * Press is different to `"pointerdown"`, `"pointerup"` in that it
4143     * automatically filters out secondary pointer events like right
4144     * click and multitouch.
4145     *
4146     * It also adds accessibility support for keyboards, where
4147     * an element with a press gesture will receive focus and
4148     *  trigger on Enter `"keydown"` and `"keyup"` events.
4149     *
4150     * This is different to a browser's `"click"` event, which does
4151     * respond to keyboards but only for the `"click"` itself, rather
4152     * than the press start and end/cancel. The element also needs
4153     * to be focusable for this to work, whereas a press gesture will
4154     * make an element focusable by default.
4155     *
4156     * @public
4157     */
4158    function press(targetOrSelector, onPressStart, options = {}) {
4159        const [targets, eventOptions, cancelEvents] = setupGesture(targetOrSelector, options);
4160        const startPress = (startEvent) => {
4161            const target = startEvent.currentTarget;
4162            if (!isValidPressEvent(startEvent))
4163                return;
4164            isPressing.add(target);
4165            const onPressEnd = onPressStart(target, startEvent);
4166            const onPointerEnd = (endEvent, success) => {
4167                window.removeEventListener("pointerup", onPointerUp);
4168                window.removeEventListener("pointercancel", onPointerCancel);
4169                if (isPressing.has(target)) {
4170                    isPressing.delete(target);
4171                }
4172                if (!isValidPressEvent(endEvent)) {
4173                    return;
4174                }
4175                if (typeof onPressEnd === "function") {
4176                    onPressEnd(endEvent, { success });
4177                }
4178            };
4179            const onPointerUp = (upEvent) => {
4180                onPointerEnd(upEvent, target === window ||
4181                    target === document ||
4182                    options.useGlobalTarget ||
4183                    isNodeOrChild(target, upEvent.target));
4184            };
4185            const onPointerCancel = (cancelEvent) => {
4186                onPointerEnd(cancelEvent, false);
4187            };
4188            window.addEventListener("pointerup", onPointerUp, eventOptions);
4189            window.addEventListener("pointercancel", onPointerCancel, eventOptions);
4190        };
4191        targets.forEach((target) => {
4192            const pointerDownTarget = options.useGlobalTarget ? window : target;
4193            pointerDownTarget.addEventListener("pointerdown", startPress, eventOptions);
4194            if (isHTMLElement(target)) {
4195                target.addEventListener("focus", (event) => enableKeyboardPress(event, eventOptions));
4196                if (!isElementKeyboardAccessible(target) &&
4197                    !target.hasAttribute("tabindex")) {
4198                    target.tabIndex = 0;
4199                }
4200            }
4201        });
4202        return cancelEvents;
4203    }
4204
4205    function getComputedStyle$2(element, name) {
4206        const computedStyle = window.getComputedStyle(element);
4207        return isCSSVar(name)
4208            ? computedStyle.getPropertyValue(name)
4209            : computedStyle[name];
4210    }
4211
4212    /**
4213     * Checks if an element is an SVG element in a way
4214     * that works across iframes
4215     */
4216    function isSVGElement(element) {
4217        return isObject(element) && "ownerSVGElement" in element;
4218    }
4219
4220    const resizeHandlers = new WeakMap();
4221    let observer;
4222    const getSize = (borderBoxAxis, svgAxis, htmlAxis) => (target, borderBoxSize) => {
4223        if (borderBoxSize && borderBoxSize[0]) {
4224            return borderBoxSize[0][(borderBoxAxis + "Size")];
4225        }
4226        else if (isSVGElement(target) && "getBBox" in target) {
4227            return target.getBBox()[svgAxis];
4228        }
4229        else {
4230            return target[htmlAxis];
4231        }
4232    };
4233    const getWidth = /*@__PURE__*/ getSize("inline", "width", "offsetWidth");
4234    const getHeight = /*@__PURE__*/ getSize("block", "height", "offsetHeight");
4235    function notifyTarget({ target, borderBoxSize }) {
4236        resizeHandlers.get(target)?.forEach((handler) => {
4237            handler(target, {
4238                get width() {
4239                    return getWidth(target, borderBoxSize);
4240                },
4241                get height() {
4242                    return getHeight(target, borderBoxSize);
4243                },
4244            });
4245        });
4246    }
4247    function notifyAll(entries) {
4248        entries.forEach(notifyTarget);
4249    }
4250    function createResizeObserver() {
4251        if (typeof ResizeObserver === "undefined")
4252            return;
4253        observer = new ResizeObserver(notifyAll);
4254    }
4255    function resizeElement(target, handler) {
4256        if (!observer)
4257            createResizeObserver();
4258        const elements = resolveElements(target);
4259        elements.forEach((element) => {
4260            let elementHandlers = resizeHandlers.get(element);
4261            if (!elementHandlers) {
4262                elementHandlers = new Set();
4263                resizeHandlers.set(element, elementHandlers);
4264            }
4265            elementHandlers.add(handler);
4266            observer?.observe(element);
4267        });
4268        return () => {
4269            elements.forEach((element) => {
4270                const elementHandlers = resizeHandlers.get(element);
4271                elementHandlers?.delete(handler);
4272                if (!elementHandlers?.size) {
4273                    observer?.unobserve(element);
4274                }
4275            });
4276        };
4277    }
4278
4279    const windowCallbacks = new Set();
4280    let windowResizeHandler;
4281    function createWindowResizeHandler() {
4282        windowResizeHandler = () => {
4283            const info = {
4284                get width() {
4285                    return window.innerWidth;
4286                },
4287                get height() {
4288                    return window.innerHeight;
4289                },
4290            };
4291            windowCallbacks.forEach((callback) => callback(info));
4292        };
4293        window.addEventListener("resize", windowResizeHandler);
4294    }
4295    function resizeWindow(callback) {
4296        windowCallbacks.add(callback);
4297        if (!windowResizeHandler)
4298            createWindowResizeHandler();
4299        return () => {
4300            windowCallbacks.delete(callback);
4301            if (!windowCallbacks.size &&
4302                typeof windowResizeHandler === "function") {
4303                window.removeEventListener("resize", windowResizeHandler);
4304                windowResizeHandler = undefined;
4305            }
4306        };
4307    }
4308
4309    function resize(a, b) {
4310        return typeof a === "function" ? resizeWindow(a) : resizeElement(a, b);
4311    }
4312
4313    function observeTimeline(update, timeline) {
4314        let prevProgress;
4315        const onFrame = () => {
4316            const { currentTime } = timeline;
4317            const percentage = currentTime === null ? 0 : currentTime.value;
4318            const progress = percentage / 100;
4319            if (prevProgress !== progress) {
4320                update(progress);
4321            }
4322            prevProgress = progress;
4323        };
4324        frame.preUpdate(onFrame, true);
4325        return () => cancelFrame(onFrame);
4326    }
4327
4328    function record() {
4329        const { value } = statsBuffer;
4330        if (value === null) {
4331            cancelFrame(record);
4332            return;
4333        }
4334        value.frameloop.rate.push(frameData.delta);
4335        value.animations.mainThread.push(activeAnimations.mainThread);
4336        value.animations.waapi.push(activeAnimations.waapi);
4337        value.animations.layout.push(activeAnimations.layout);
4338    }
4339    function mean(values) {
4340        return values.reduce((acc, value) => acc + value, 0) / values.length;
4341    }
4342    function summarise(values, calcAverage = mean) {
4343        if (values.length === 0) {
4344            return {
4345                min: 0,
4346                max: 0,
4347                avg: 0,
4348            };
4349        }
4350        return {
4351            min: Math.min(...values),
4352            max: Math.max(...values),
4353            avg: calcAverage(values),
4354        };
4355    }
4356    const msToFps = (ms) => Math.round(1000 / ms);
4357    function clearStatsBuffer() {
4358        statsBuffer.value = null;
4359        statsBuffer.addProjectionMetrics = null;
4360    }
4361    function reportStats() {
4362        const { value } = statsBuffer;
4363        if (!value) {
4364            throw new Error("Stats are not being measured");
4365        }
4366        clearStatsBuffer();
4367        cancelFrame(record);
4368        const summary = {
4369            frameloop: {
4370                setup: summarise(value.frameloop.setup),
4371                rate: summarise(value.frameloop.rate),
4372                read: summarise(value.frameloop.read),
4373                resolveKeyframes: summarise(value.frameloop.resolveKeyframes),
4374                preUpdate: summarise(value.frameloop.preUpdate),
4375                update: summarise(value.frameloop.update),
4376                preRender: summarise(value.frameloop.preRender),
4377                render: summarise(value.frameloop.render),
4378                postRender: summarise(value.frameloop.postRender),
4379            },
4380            animations: {
4381                mainThread: summarise(value.animations.mainThread),
4382                waapi: summarise(value.animations.waapi),
4383                layout: summarise(value.animations.layout),
4384            },
4385            layoutProjection: {
4386                nodes: summarise(value.layoutProjection.nodes),
4387                calculatedTargetDeltas: summarise(value.layoutProjection.calculatedTargetDeltas),
4388                calculatedProjections: summarise(value.layoutProjection.calculatedProjections),
4389            },
4390        };
4391        /**
4392         * Convert the rate to FPS
4393         */
4394        const { rate } = summary.frameloop;
4395        rate.min = msToFps(rate.min);
4396        rate.max = msToFps(rate.max);
4397        rate.avg = msToFps(rate.avg);
4398        [rate.min, rate.max] = [rate.max, rate.min];
4399        return summary;
4400    }
4401    function recordStats() {
4402        if (statsBuffer.value) {
4403            clearStatsBuffer();
4404            throw new Error("Stats are already being measured");
4405        }
4406        const newStatsBuffer = statsBuffer;
4407        newStatsBuffer.value = {
4408            frameloop: {
4409                setup: [],
4410                rate: [],
4411                read: [],
4412                resolveKeyframes: [],
4413                preUpdate: [],
4414                update: [],
4415                preRender: [],
4416                render: [],
4417                postRender: [],
4418            },
4419            animations: {
4420                mainThread: [],
4421                waapi: [],
4422                layout: [],
4423            },
4424            layoutProjection: {
4425                nodes: [],
4426                calculatedTargetDeltas: [],
4427                calculatedProjections: [],
4428            },
4429        };
4430        newStatsBuffer.addProjectionMetrics = (metrics) => {
4431            const { layoutProjection } = newStatsBuffer.value;
4432            layoutProjection.nodes.push(metrics.nodes);
4433            layoutProjection.calculatedTargetDeltas.push(metrics.calculatedTargetDeltas);
4434            layoutProjection.calculatedProjections.push(metrics.calculatedProjections);
4435        };
4436        frame.postRender(record, true);
4437        return reportStats;
4438    }
4439
4440    /**
4441     * Checks if an element is specifically an SVGSVGElement (the root SVG element)
4442     * in a way that works across iframes
4443     */
4444    function isSVGSVGElement(element) {
4445        return isSVGElement(element) && element.tagName === "svg";
4446    }
4447
4448    function getOriginIndex(from, total) {
4449        if (from === "first") {
4450            return 0;
4451        }
4452        else {
4453            const lastIndex = total - 1;
4454            return from === "last" ? lastIndex : lastIndex / 2;
4455        }
4456    }
4457    function stagger(duration = 0.1, { startDelay = 0, from = 0, ease } = {}) {
4458        return (i, total) => {
4459            const fromIndex = typeof from === "number" ? from : getOriginIndex(from, total);
4460            const distance = Math.abs(fromIndex - i);
4461            let delay = duration * distance;
4462            if (ease) {
4463                const maxDelay = total * duration;
4464                const easingFunction = easingDefinitionToFunction(ease);
4465                delay = easingFunction(delay / maxDelay) * maxDelay;
4466            }
4467            return startDelay + delay;
4468        };
4469    }
4470
4471    function transform(...args) {
4472        const useImmediate = !Array.isArray(args[0]);
4473        const argOffset = useImmediate ? 0 : -1;
4474        const inputValue = args[0 + argOffset];
4475        const inputRange = args[1 + argOffset];
4476        const outputRange = args[2 + argOffset];
4477        const options = args[3 + argOffset];
4478        const interpolator = interpolate(inputRange, outputRange, options);
4479        return useImmediate ? interpolator(inputValue) : interpolator;
4480    }
4481
4482    function subscribeValue(inputValues, outputValue, getLatest) {
4483        const update = () => outputValue.set(getLatest());
4484        const scheduleUpdate = () => frame.preRender(update, false, true);
4485        const subscriptions = inputValues.map((v) => v.on("change", scheduleUpdate));
4486        outputValue.on("destroy", () => {
4487            subscriptions.forEach((unsubscribe) => unsubscribe());
4488            cancelFrame(update);
4489        });
4490    }
4491
4492    /**
4493     * Create a `MotionValue` that transforms the output of other `MotionValue`s by
4494     * passing their latest values through a transform function.
4495     *
4496     * Whenever a `MotionValue` referred to in the provided function is updated,
4497     * it will be re-evaluated.
4498     *
4499     * ```jsx
4500     * const x = motionValue(0)
4501     * const y = transformValue(() => x.get() * 2) // double x
4502     * ```
4503     *
4504     * @param transformer - A transform function. This function must be pure with no side-effects or conditional statements.
4505     * @returns `MotionValue`
4506     *
4507     * @public
4508     */
4509    function transformValue(transform) {
4510        const collectedValues = [];
4511        /**
4512         * Open session of collectMotionValues. Any MotionValue that calls get()
4513         * inside transform will be saved into this array.
4514         */
4515        collectMotionValues.current = collectedValues;
4516        const initialValue = transform();
4517        collectMotionValues.current = undefined;
4518        const value = motionValue(initialValue);
4519        subscribeValue(collectedValues, value, transform);
4520        return value;
4521    }
4522
4523    /**
4524     * Create a `MotionValue` that maps the output of another `MotionValue` by
4525     * mapping it from one range of values into another.
4526     *
4527     * @remarks
4528     *
4529     * Given an input range of `[-200, -100, 100, 200]` and an output range of
4530     * `[0, 1, 1, 0]`, the returned `MotionValue` will:
4531     *
4532     * - When provided a value between `-200` and `-100`, will return a value between `0` and  `1`.
4533     * - When provided a value between `-100` and `100`, will return `1`.
4534     * - When provided a value between `100` and `200`, will return a value between `1` and  `0`
4535     *
4536     * The input range must be a linear series of numbers. The output range
4537     * can be any value type supported by Motion: numbers, colors, shadows, etc.
4538     *
4539     * Every value in the output range must be of the same type and in the same format.
4540     *
4541     * ```jsx
4542     * const x = motionValue(0)
4543     * const xRange = [-200, -100, 100, 200]
4544     * const opacityRange = [0, 1, 1, 0]
4545     * const opacity = mapValue(x, xRange, opacityRange)
4546     * ```
4547     *
4548     * @param inputValue - `MotionValue`
4549     * @param inputRange - A linear series of numbers (either all increasing or decreasing)
4550     * @param outputRange - A series of numbers, colors or strings. Must be the same length as `inputRange`.
4551     * @param options -
4552     *
4553     *  - clamp: boolean. Clamp values to within the given range. Defaults to `true`
4554     *  - ease: EasingFunction[]. Easing functions to use on the interpolations between each value in the input and output ranges. If provided as an array, the array must be one item shorter than the input and output ranges, as the easings apply to the transition between each.
4555     *
4556     * @returns `MotionValue`
4557     *
4558     * @public
4559     */
4560    function mapValue(inputValue, inputRange, outputRange, options) {
4561        const map = transform(inputRange, outputRange, options);
4562        return transformValue(() => map(inputValue.get()));
4563    }
4564
4565    const isMotionValue = (value) => Boolean(value && value.getVelocity);
4566
4567    /**
4568     * Create a `MotionValue` that animates to its latest value using a spring.
4569     * Can either be a value or track another `MotionValue`.
4570     *
4571     * ```jsx
4572     * const x = motionValue(0)
4573     * const y = transformValue(() => x.get() * 2) // double x
4574     * ```
4575     *
4576     * @param transformer - A transform function. This function must be pure with no side-effects or conditional statements.
4577     * @returns `MotionValue`
4578     *
4579     * @public
4580     */
4581    function springValue(source, options) {
4582        const initialValue = isMotionValue(source) ? source.get() : source;
4583        const value = motionValue(initialValue);
4584        attachSpring(value, source, options);
4585        return value;
4586    }
4587    function attachSpring(value, source, options) {
4588        const initialValue = value.get();
4589        let activeAnimation = null;
4590        let latestValue = initialValue;
4591        let latestSetter;
4592        const unit = typeof initialValue === "string"
4593            ? initialValue.replace(/[\d.-]/g, "")
4594            : undefined;
4595        const stopAnimation = () => {
4596            if (activeAnimation) {
4597                activeAnimation.stop();
4598                activeAnimation = null;
4599            }
4600        };
4601        const startAnimation = () => {
4602            stopAnimation();
4603            activeAnimation = new JSAnimation({
4604                keyframes: [asNumber(value.get()), asNumber(latestValue)],
4605                velocity: value.getVelocity(),
4606                type: "spring",
4607                restDelta: 0.001,
4608                restSpeed: 0.01,
4609                ...options,
4610                onUpdate: latestSetter,
4611            });
4612        };
4613        value.attach((v, set) => {
4614            latestValue = v;
4615            latestSetter = (latest) => set(parseValue(latest, unit));
4616            frame.postRender(startAnimation);
4617        }, stopAnimation);
4618        if (isMotionValue(source)) {
4619            const removeSourceOnChange = source.on("change", (v) => value.set(parseValue(v, unit)));
4620            const removeValueOnDestroy = value.on("destroy", removeSourceOnChange);
4621            return () => {
4622                removeSourceOnChange();
4623                removeValueOnDestroy();
4624            };
4625        }
4626        return stopAnimation;
4627    }
4628    function parseValue(v, unit) {
4629        return unit ? v + unit : v;
4630    }
4631    function asNumber(v) {
4632        return typeof v === "number" ? v : parseFloat(v);
4633    }
4634
4635    /**
4636     * A list of all ValueTypes
4637     */
4638    const valueTypes = [...dimensionValueTypes, color, complex];
4639    /**
4640     * Tests a value against the list of ValueTypes
4641     */
4642    const findValueType = (v) => valueTypes.find(testValueType(v));
4643
4644    function chooseLayerType(valueName) {
4645        if (valueName === "layout")
4646            return "group";
4647        if (valueName === "enter" || valueName === "new")
4648            return "new";
4649        if (valueName === "exit" || valueName === "old")
4650            return "old";
4651        return "group";
4652    }
4653
4654    let pendingRules = {};
4655    let style = null;
4656    const css = {
4657        set: (selector, values) => {
4658            pendingRules[selector] = values;
4659        },
4660        commit: () => {
4661            if (!style) {
4662                style = document.createElement("style");
4663                style.id = "motion-view";
4664            }
4665            let cssText = "";
4666            for (const selector in pendingRules) {
4667                const rule = pendingRules[selector];
4668                cssText += `${selector} {\n`;
4669                for (const [property, value] of Object.entries(rule)) {
4670                    cssText += `  ${property}: ${value};\n`;
4671                }
4672                cssText += "}\n";
4673            }
4674            style.textContent = cssText;
4675            document.head.appendChild(style);
4676            pendingRules = {};
4677        },
4678        remove: () => {
4679            if (style && style.parentElement) {
4680                style.parentElement.removeChild(style);
4681            }
4682        },
4683    };
4684
4685    function getViewAnimationLayerInfo(pseudoElement) {
4686        const match = pseudoElement.match(/::view-transition-(old|new|group|image-pair)\((.*?)\)/);
4687        if (!match)
4688            return null;
4689        return { layer: match[2], type: match[1] };
4690    }
4691
4692    function filterViewAnimations(animation) {
4693        const { effect } = animation;
4694        if (!effect)
4695            return false;
4696        return (effect.target === document.documentElement &&
4697            effect.pseudoElement?.startsWith("::view-transition"));
4698    }
4699    function getViewAnimations() {
4700        return document.getAnimations().filter(filterViewAnimations);
4701    }
4702
4703    function hasTarget(target, targets) {
4704        return targets.has(target) && Object.keys(targets.get(target)).length > 0;
4705    }
4706
4707    const definitionNames = ["layout", "enter", "exit", "new", "old"];
4708    function startViewAnimation(builder) {
4709        const { update, targets, options: defaultOptions } = builder;
4710        if (!document.startViewTransition) {
4711            return new Promise(async (resolve) => {
4712                await update();
4713                resolve(new GroupAnimation([]));
4714            });
4715        }
4716        // TODO: Go over existing targets and ensure they all have ids
4717        /**
4718         * If we don't have any animations defined for the root target,
4719         * remove it from being captured.
4720         */
4721        if (!hasTarget("root", targets)) {
4722            css.set(":root", {
4723                "view-transition-name": "none",
4724            });
4725        }
4726        /**
4727         * Set the timing curve to linear for all view transition layers.
4728         * This gets baked into the keyframes, which can't be changed
4729         * without breaking the generated animation.
4730         *
4731         * This allows us to set easing via updateTiming - which can be changed.
4732         */
4733        css.set("::view-transition-group(*), ::view-transition-old(*), ::view-transition-new(*)", { "animation-timing-function": "linear !important" });
4734        css.commit(); // Write
4735        const transition = document.startViewTransition(async () => {
4736            await update();
4737            // TODO: Go over new targets and ensure they all have ids
4738        });
4739        transition.finished.finally(() => {
4740            css.remove(); // Write
4741        });
4742        return new Promise((resolve) => {
4743            transition.ready.then(() => {
4744                const generatedViewAnimations = getViewAnimations();
4745                const animations = [];
4746                /**
4747                 * Create animations for each of our explicitly-defined subjects.
4748                 */
4749                targets.forEach((definition, target) => {
4750                    // TODO: If target is not "root", resolve elements
4751                    // and iterate over each
4752                    for (const key of definitionNames) {
4753                        if (!definition[key])
4754                            continue;
4755                        const { keyframes, options } = definition[key];
4756                        for (let [valueName, valueKeyframes] of Object.entries(keyframes)) {
4757                            if (!valueKeyframes)
4758                                continue;
4759                            const valueOptions = {
4760                                ...getValueTransition$1(defaultOptions, valueName),
4761                                ...getValueTransition$1(options, valueName),
4762                            };
4763                            const type = chooseLayerType(key);
4764                            /**
4765                             * If this is an opacity animation, and keyframes are not an array,
4766                             * we need to convert them into an array and set an initial value.
4767                             */
4768                            if (valueName === "opacity" &&
4769                                !Array.isArray(valueKeyframes)) {
4770                                const initialValue = type === "new" ? 0 : 1;
4771                                valueKeyframes = [initialValue, valueKeyframes];
4772                            }
4773                            /**
4774                             * Resolve stagger function if provided.
4775                             */
4776                            if (typeof valueOptions.delay === "function") {
4777                                valueOptions.delay = valueOptions.delay(0, 1);
4778                            }
4779                            valueOptions.duration && (valueOptions.duration = secondsToMilliseconds(valueOptions.duration));
4780                            valueOptions.delay && (valueOptions.delay = secondsToMilliseconds(valueOptions.delay));
4781                            const animation = new NativeAnimation({
4782                                ...valueOptions,
4783                                element: document.documentElement,
4784                                name: valueName,
4785                                pseudoElement: `::view-transition-${type}(${target})`,
4786                                keyframes: valueKeyframes,
4787                            });
4788                            animations.push(animation);
4789                        }
4790                    }
4791                });
4792                /**
4793                 * Handle browser generated animations
4794                 */
4795                for (const animation of generatedViewAnimations) {
4796                    if (animation.playState === "finished")
4797                        continue;
4798                    const { effect } = animation;
4799                    if (!effect || !(effect instanceof KeyframeEffect))
4800                        continue;
4801                    const { pseudoElement } = effect;
4802                    if (!pseudoElement)
4803                        continue;
4804                    const name = getViewAnimationLayerInfo(pseudoElement);
4805                    if (!name)
4806                        continue;
4807                    const targetDefinition = targets.get(name.layer);
4808                    if (!targetDefinition) {
4809                        /**
4810                         * If transition name is group then update the timing of the animation
4811                         * whereas if it's old or new then we could possibly replace it using
4812                         * the above method.
4813                         */
4814                        const transitionName = name.type === "group" ? "layout" : "";
4815                        let animationTransition = {
4816                            ...getValueTransition$1(defaultOptions, transitionName),
4817                        };
4818                        animationTransition.duration && (animationTransition.duration = secondsToMilliseconds(animationTransition.duration));
4819                        animationTransition =
4820                            applyGeneratorOptions(animationTransition);
4821                        const easing = mapEasingToNativeEasing(animationTransition.ease, animationTransition.duration);
4822                        effect.updateTiming({
4823                            delay: secondsToMilliseconds(animationTransition.delay ?? 0),
4824                            duration: animationTransition.duration,
4825                            easing,
4826                        });
4827                        animations.push(new NativeAnimationWrapper(animation));
4828                    }
4829                    else if (hasOpacity(targetDefinition, "enter") &&
4830                        hasOpacity(targetDefinition, "exit") &&
4831                        effect
4832                            .getKeyframes()
4833                            .some((keyframe) => keyframe.mixBlendMode)) {
4834                        animations.push(new NativeAnimationWrapper(animation));
4835                    }
4836                    else {
4837                        animation.cancel();
4838                    }
4839                }
4840                resolve(new GroupAnimation(animations));
4841            });
4842        });
4843    }
4844    function hasOpacity(target, key) {
4845        return target?.[key]?.keyframes.opacity;
4846    }
4847
4848    let builders = [];
vendor: 1,253 bytes, lines 4849-4879
4849    let current = null;
4850    function next() {
4851        current = null;
4852        const [nextBuilder] = builders;
4853        if (nextBuilder)
4854            start(nextBuilder);
4855    }
4856    function start(builder) {
4857        removeItem(builders, builder);
4858        current = builder;
4859        startViewAnimation(builder).then((animation) => {
4860            builder.notifyReady(animation);
4861            animation.finished.finally(next);
4862        });
4863    }
4864    function processQueue() {
4865        /**
4866         * Iterate backwards over the builders array. We can ignore the
4867         * "wait" animations. If we have an interrupting animation in the
4868         * queue then we need to batch all preceeding animations into it.
4869         * Currently this only batches the update functions but will also
4870         * need to batch the targets.
4871         */
4872        for (let i = builders.length - 1; i >= 0; i--) {
4873            const builder = builders[i];
4874            const { interrupt } = builder.options;
4875            if (interrupt === "immediate") {
4876                const batchedUpdates = builders.slice(0, i + 1).map((b) => b.update);
4877                const remaining = builders.slice(i + 1);
4878                builder.update = () => {
4879                    batchedUpdates.forEach((update) =>
4879 update());
4880                };
4881                // Put the current builder at the front, followed by any "wait" builders
4882                builders = [builder, ...remaining];
4883                break;
4884            }
4885        }
4886        if (!current || builders[0]?.options.interrupt === "immediate") {
4887            next();
4888        }
4889    }
4890    function addToQueue(builder) {
4891        builders.push(builder);
4892        microtask.render(processQueue);
4893    }
4894
4895    class ViewTransitionBuilder {
4896        constructor(update, options = {}) {
4897            this.currentSubject = "root";
4898            this.targets = new Map();
4899            this.notifyReady = noop;
4900            this.readyPromise = new Promise((resolve) => {
4901                this.notifyReady = resolve;
4902            });
4903            this.update = update;
4904            this.options = {
4905                interrupt: "wait",
4906                ...options,
4907            };
4908            addToQueue(this);
4909        }
4910        get(subject) {
4911            this.currentSubject = subject;
4912            return this;
4913        }
4914        layout(keyframes, options) {
4915            this.updateTarget("layout", keyframes, options);
4916            return this;
4917        }
4918        new(keyframes, options) {
4919            this.updateTarget("new", keyframes, options);
4920            return this;
4921        }
4922        old(keyframes, options) {
4923            this.updateTarget("old", keyframes, options);
4924            return this;
4925        }
4926        enter(keyframes, options) {
4927            this.updateTarget("enter", keyframes, options);
4928            return this;
4929        }
4930        exit(keyframes, options) {
4931            this.updateTarget("exit", keyframes, options);
4932            return this;
4933        }
4934        crossfade(options) {
4935            this.updateTarget("enter", { opacity: 1 }, options);
4936            this.updateTarget("exit", { opacity: 0 }, options);
4937            return this;
4938        }
4939        updateTarget(target, keyframes, options = {}) {
4940            const { currentSubject, targets } = this;
4941            if (!targets.has(currentSubject)) {
4942                targets.set(currentSubject, {});
4943            }
4944            const targetData = targets.get(currentSubject);
4945            targetData[target] = { keyframes, options };
4946        }
4947        then(resolve, reject) {
4948            return this.readyPromise.then(resolve, reject);
4949        }
4950    }
4951    function animateView(update, defaultOptions = {}) {
4952        return new ViewTransitionBuilder(update, defaultOptions);
4953    }
4954
4955    /**
4956     * @deprecated
4957     *
4958     * Import as `frame` instead.
4959     */
4960    const sync = frame;
4961    /**
4962     * @deprecated
4963     *
4964     * Use cancelFrame(callback) instead.
4965     */
4966    const cancelSync = stepsOrder.reduce((acc, key) => {
4967        acc[key] = (process) => cancelFrame(process);
4968        return acc;
4969    }, {});
4970
4971    function isDOMKeyframes(keyframes) {
4972        return typeof keyframes === "object" && !Array.isArray(keyframes);
4973    }
4974
4975    function resolveSubjects(subject, keyframes, scope, selectorCache) {
4976        if (typeof subject === "string" && isDOMKeyframes(keyframes)) {
4977            return resolveElements(subject, scope, selectorCache);
4978        }
4979        else if (subject instanceof NodeList) {
4980            return Array.from(subject);
4981        }
4982        else if (Array.isArray(subject)) {
4983            return subject;
4984        }
4985        else {
4986            return [subject];
4987        }
4988    }
4989
4990    function calculateRepeatDuration(duration, repeat, _repeatDelay) {
4991        return duration * (repeat + 1);
4992    }
4993
4994    /**
4995     * Given a absolute or relative time definition and current/prev time state of the sequence,
4996     * calculate an absolute time for the next keyframes.
4997     */
4998    function calcNextTime(current, next, prev, labels) {
4999        if (typeof next === "number") {
5000            return next;
5001        }
5002        else if (next.startsWith("-") || next.startsWith("+")) {
5003            return Math.max(0, current + parseFloat(next));
5004        }
5005        else if (next === "<") {
5006            return prev;
5007        }
5008        else if (next.startsWith("<")) {
5009            return Math.max(0, prev + parseFloat(next.slice(1)));
5010        }
5011        else {
5012            return labels.get(next) ?? current;
5013        }
5014    }
5015
5016    function eraseKeyframes(sequence, startTime, endTime) {
5017        for (let i = 0; i < sequence.length; i++) {
vendor: 2,206 bytes, lines 5018-5079
5018            const keyframe = sequence[i];
5019            if (keyframe.at > startTime && keyframe.at < endTime) {
5020                removeItem(sequence, keyframe);
5021                // If we remove this item we have to push the pointer back one
5022                i--;
5023            }
5024        }
5025    }
5026    function addKeyframes(sequence, keyframes, easing, offset, startTime, endTime) {
5027        /**
5028         * Erase every existing value between currentTime and targetTime,
5029         * this will essentially splice this timeline into any currently
5030         * defined ones.
5031         */
5032        eraseKeyframes(sequence, startTime, endTime);
5033        for (let i = 0; i < keyframes.length; i++) {
5034            sequence.push({
5035                value: keyframes[i],
5036                at: mixNumber$1(startTime, endTime, offset[i]),
5037                easing: getEasingForSegment(easing, i),
5038            });
5039        }
5040    }
5041
5042    /**
5043     * Take an array of times that represent repeated keyframes. For instance
5044     * if we have original times of [0, 0.5, 1] then our repeated times will
5045     * be [0, 0.5, 1, 1, 1.5, 2]. Loop over the times and scale them back
5046     * down to a 0-1 scale.
5047     */
5048    function normalizeTimes(times, repeat) {
5049        for (let i = 0; i < times.length; i++) {
5050            times[i] = times[i] / (repeat + 1);
5051        }
5052    }
5053
5054    function compareByTime(a, b) {
5055        if (a.at === b.at) {
5056            if (a.value === null)
5057                return 1;
5058            if (b.value === null)
5059                return -1;
5060            return 0;
5061        }
5062        else {
5063            return a.at - b.at;
5064        }
5065    }
5066
5067    const defaultSegmentEasing = "easeInOut";
5068    const MAX_REPEAT = 20;
5069    function createAnimationsFromSequence(sequence, { defaultTransition = {}, ...sequenceTransition } = {}, scope, generators) {
5070        const defaultDuration = defaultTransition.duration || 0.3;
5071        const animationDefinitions = new Map();
5072        const sequences = new Map();
5073        const elementCache = {};
5074        const timeLabels = new Map();
5075        let prevTime = 0;
5076        let currentTime = 0;
5077        let totalDuration = 0;
5078        /**
5079         * Build the timeline by mapping over the sequence array and convert
vendor: 7,724 bytes, lines 5079-5224
5079ing
5080         * the definitions into keyframes and offsets with absolute time values.
5081         * These will later get converted into relative offsets in a second pass.
5082         */
5083        for (let i = 0; i < sequence.length; i++) {
5084            const segment = sequence[i];
5085            /**
5086             * If this is a timeline label, mark it and skip the rest of this iteration.
5087             */
5088            if (typeof segment === "string") {
5089                timeLabels.set(segment, currentTime);
5090                continue;
5091            }
5092            else if (!Array.isArray(segment)) {
5093                timeLabels.set(segment.name, calcNextTime(currentTime, segment.at, prevTime, timeLabels));
5094                continue;
5095            }
5096            let [subject, keyframes, transition = {}] = segment;
5097            /**
5098             * If a relative or absolute time value has been specified we need to resolve
5099             * it in relation to the currentTime.
5100             */
5101            if (transition.at !== undefined) {
5102                currentTime = calcNextTime(currentTime, transition.at, prevTime, timeLabels);
5103            }
5104            /**
5105             * Keep track of the maximum duration in this definition. This will be
5106             * applied to currentTime once the definition has been parsed.
5107             */
5108            let maxDuration = 0;
5109            const resolveValueSequence = (valueKeyframes, valueTransition, valueSequence, elementIndex = 0, numSubjects = 0) => {
5110                const valueKeyframesAsList = keyframesAsList(valueKeyframes);
5111                const { delay = 0, times = defaultOffset$1(valueKeyframesAsList), type = "keyframes", repeat, repeatType, repeatDelay = 0, ...remainingTransition } = valueTransition;
5112                let { ease = defaultTransition.ease || "easeOut", duration } = valueTransition;
5113                /**
5114                 * Resolve stagger() if defined.
5115                 */
5116                const calculatedDelay = typeof delay === "function"
5117                    ? delay(elementIndex, numSubjects)
5118                    : delay;
5119                /**
5120                 * If this animation should and can use a spring, generate a spring easing function.
5121                 */
5122                const numKeyframes = valueKeyframesAsList.length;
5123                const createGenerator = isGenerator(type)
5124                    ? type
5125                    : generators?.[type || "keyframes"];
5126                if (numKeyframes <= 2 && createGenerator) {
5127                    /**
5128                     * As we're creating an easing function from a spring,
5129                     * ideally we want to generate it using the real distance
5130                     * between the two keyframes. However this isn't always
5131                     * possible - in these situations we use 0-100.
5132                     */
5133                    let absoluteDelta = 100;
5134                    if (numKeyframes === 2 &&
5135                        isNumberKeyframesArray(valueKeyframesAsList)) {
5136                        const delta = valueKeyframesAsList[1] - valueKeyframesAsList[0];
5137                        absoluteDelta = Math.abs(delta);
5138                    }
5139                    const springTransition = { ...remainingTransition };
5140                    if (duration !== undefined) {
5141                        springTransition.duration = secondsToMilliseconds(duration);
5142                    }
5143                    const springEasing = createGeneratorEasing(springTransition, absoluteDelta, createGenerator);
5144                    ease = springEasing.ease;
5145                    duration = springEasing.duration;
5146                }
5147                duration ?? (duration = defaultDuration);
5148                const startTime = currentTime + calculatedDelay;
5149                /**
5150                 * If there's only one time offset of 0, fill in a second with length 1
5151                 */
5152                if (times.length === 1 && times[0] === 0) {
5153                    times[1] = 1;
5154                }
5155                /**
5156                 * Fill out if offset if fewer offsets than keyframes
5157                 */
5158                const remainder = times.length - valueKeyframesAsList.length;
5159                remainder > 0 && fillOffset(times, remainder);
5160                /**
5161                 * If only one value has been set, ie [1], push a null to the start of
5162                 * the keyframe array. This will let us mark a keyframe at this point
5163                 * that will later be hydrated with the previous value.
5164                 */
5165                valueKeyframesAsList.length === 1 &&
5166                    valueKeyframesAsList.unshift(null);
5167                /**
5168                 * Handle repeat options
5169                 */
5170                if (repeat) {
5171                    exports.invariant(repeat < MAX_REPEAT, "Repeat count too high, must be less than 20", "repeat-count-high");
5172                    duration = calculateRepeatDuration(duration, repeat);
5173                    const originalKeyframes = [...valueKeyframesAsList];
5174                    const originalTimes = [...times];
5175                    ease = Array.isArray(ease) ? [...ease] : [ease];
5176                    const originalEase = [...ease];
5177                    for (let repeatIndex = 0; repeatIndex < repeat; repeatIndex++) {
5178                        valueKeyframesAsList.push(...originalKeyframes);
5179                        for (let keyframeIndex = 0; keyframeIndex < originalKeyframes.length; keyframeIndex++) {
5180                            times.push(originalTimes[keyframeIndex] + (repeatIndex + 1));
5181                            ease.push(keyframeIndex === 0
5182                                ? "linear"
5183                                : getEasingForSegment(originalEase, keyframeIndex - 1));
5184                        }
5185                    }
5186                    normalizeTimes(times, repeat);
5187                }
5188                const targetTime = startTime + duration;
5189                /**
5190                 * Add keyframes, mapping offsets to absolute time.
5191                 */
5192                addKeyframes(valueSequence, valueKeyframesAsList, ease, times, startTime, targetTime);
5193                maxDuration = Math.max(calculatedDelay + duration, maxDuration);
5194                totalDuration = Math.max(targetTime, totalDuration);
5195            };
5196            if (isMotionValue(subject)) {
5197                const subjectSequence = getSubjectSequence(subject, sequences);
5198                resolveValueSequence(keyframes, transition, getValueSequence("default", subjectSequence));
5199            }
5200            else {
5201                const subjects = resolveSubjects(subject, keyframes, scope, elementCache);
5202                const numSubjects = subjects.length;
5203                /**
5204                 * For every element in this segment, process the defined values.
5205                 */
5206                for (let subjectIndex = 0; subjectIndex < numSubjects; subjectIndex++) {
5207                    /**
5208                     * Cast necessary, but we know these are of this type
5209                     */
5210                    keyframes = keyframes;
5211                    transition = transition;
5212                    const thisSubject = subjects[subjectIndex];
5213                    const subjectSequence = getSubjectSequence(thisSubject, sequences);
5214                    for (const key in keyframes) {
5215                        resolveValueSequence(keyframes[key], getValueTransition(transition, key), getValueSequence(key, subjectSequence), subjectIndex, numSubjects);
5216                    }
5217                }
5218            }
5219            prevTime = currentTime;
5220            currentTime += maxDuration;
5221        }
5222        /**
5223         * For every element and value combination create a new animation.
5224         */
vendor: 8,083 bytes, lines 5225-5432
5225        sequences.forEach((valueSequences, element) => {
5226            for (const key in valueSequences) {
5227                const valueSequence = valueSequences[key];
5228                /**
5229                 * Arrange all the keyframes in ascending time order.
5230                 */
5231                valueSequence.sort(compareByTime);
5232                const keyframes = [];
5233                const valueOffset = [];
5234                const valueEasing = [];
5235                /**
5236                 * For each keyframe, translate absolute times into
5237                 * relative offsets based on the total duration of the timeline.
5238                 */
5239                for (let i = 0; i < valueSequence.length; i++) {
5240                    const { at, value, easing } = valueSequence[i];
5241                    keyframes.push(value);
5242                    valueOffset.push(progress(0, totalDuration, at));
5243                    valueEasing.push(easing || "easeOut");
5244                }
5245                /**
5246                 * If the first keyframe doesn't land on offset: 0
5247                 * provide one by duplicating the initial keyframe. This ensures
5248                 * it snaps to the first keyframe when the animation starts.
5249                 */
5250                if (valueOffset[0] !== 0) {
5251                    valueOffset.unshift(0);
5252                    keyframes.unshift(keyframes[0]);
5253                    valueEasing.unshift(defaultSegmentEasing);
5254                }
5255                /**
5256                 * If the last keyframe doesn't land on offset: 1
5257                 * provide one with a null wildcard value. This will ensure it
5258                 * stays static until the end of the animation.
5259                 */
5260                if (valueOffset[valueOffset.length - 1] !== 1) {
5261                    valueOffset.push(1);
5262                    keyframes.push(null);
5263                }
5264                if (!animationDefinitions.has(element)) {
5265                    animationDefinitions.set(element, {
5266                        keyframes: {},
5267                        transition: {},
5268                    });
5269                }
5270                const definition = animationDefinitions.get(element);
5271                definition.keyframes[key] = keyframes;
5272                definition.transition[key] = {
5273                    ...defaultTransition,
5274                    duration: totalDuration,
5275                    ease: valueEasing,
5276                    times: valueOffset,
5277                    ...sequenceTransition,
5278                };
5279            }
5280        });
5281        return animationDefinitions;
5282    }
5283    function getSubjectSequence(subject, sequences) {
5284        !sequences.has(subject) && sequences.set(subject, {});
5285        return sequences.get(subject);
5286    }
5287    function getValueSequence(name, sequences) {
5288        if (!sequences[name])
5289            sequences[name] = [];
5290        return sequences[name];
5291    }
5292    function keyframesAsList(keyframes) {
5293        return Array.isArray(keyframes) ? keyframes : [keyframes];
5294    }
5295    function getValueTransition(transition, key) {
5296        return transition && transition[key]
5297            ? {
5298                ...transition,
5299                ...transition[key],
5300            }
5301            : { ...transition };
5302    }
5303    const isNumber = (keyframe) => typeof keyframe === "number";
5304    const isNumberKeyframesArray = (keyframes) => keyframes.every(isNumber);
5305
5306    const visualElementStore = new WeakMap();
5307
5308    const isKeyframesTarget = (v) => {
5309        return Array.isArray(v);
5310    };
5311
5312    function getValueState(visualElement) {
5313        const state = [{}, {}];
5314        visualElement?.values.forEach((value, key) => {
5315            state[0][key] = value.get();
5316            state[1][key] = value.getVelocity();
5317        });
5318        return state;
5319    }
5320    function resolveVariantFromProps(props, definition, custom, visualElement) {
5321        /**
5322         * If the variant definition is a function, resolve.
5323         */
5324        if (typeof definition === "function") {
5325            const [current, velocity] = getValueState(visualElement);
5326            definition = definition(custom !== undefined ? custom : props.custom, current, velocity);
5327        }
5328        /**
5329         * If the variant definition is a variant label, or
5330         * the function returned a variant label, resolve.
5331         */
5332        if (typeof definition === "string") {
5333            definition = props.variants && props.variants[definition];
5334        }
5335        /**
5336         * At this point we've resolved both functions and variant labels,
5337         * but the resolved variant label might itself have been a function.
5338         * If so, resolve. This can only have returned a valid target object.
5339         */
5340        if (typeof definition === "function") {
5341            const [current, velocity] = getValueState(visualElement);
5342            definition = definition(custom !== undefined ? custom : props.custom, current, velocity);
5343        }
5344        return definition;
5345    }
5346
5347    function resolveVariant(visualElement, definition, custom) {
5348        const props = visualElement.getProps();
5349        return resolveVariantFromProps(props, definition, props.custom, visualElement);
5350    }
5351
5352    /**
5353     * Set VisualElement's MotionValue, creating a new MotionValue for it if
5354     * it doesn't exist.
5355     */
5356    function setMotionValue(visualElement, key, value) {
5357        if (visualElement.hasValue(key)) {
5358            visualElement.getValue(key).set(value);
5359        }
5360        else {
5361            visualElement.addValue(key, motionValue(value));
5362        }
5363    }
5364    function resolveFinalValueInKeyframes(v) {
5365        // TODO maybe throw if v.length - 1 is placeholder token?
5366        return isKeyframesTarget(v) ? v[v.length - 1] || 0 : v;
5367    }
5368    function setTarget(visualElement, definition) {
5369        const resolved = resolveVariant(visualElement, definition);
5370        let { transitionEnd = {}, transition = {}, ...target } = resolved || {};
5371        target = { ...target, ...transitionEnd };
5372        for (const key in target) {
5373            const value = resolveFinalValueInKeyframes(target[key]);
5374            setMotionValue(visualElement, key, value);
5375        }
5376    }
5377
5378    function isWillChangeMotionValue(value) {
5379        return Boolean(isMotionValue(value) && value.add);
5380    }
5381
5382    function addValueToWillChange(visualElement, key) {
5383        const willChange = visualElement.getValue("willChange");
5384        /**
5385         * It could be that a user has set willChange to a regular MotionValue,
5386         * in which case we can't add the value to it.
5387         */
5388        if (isWillChangeMotionValue(willChange)) {
5389            return willChange.add(key);
5390        }
5391        else if (!willChange && MotionGlobalConfig.WillChange) {
5392            const newWillChange = new MotionGlobalConfig.WillChange("auto");
5393            visualElement.addValue("willChange", newWillChange);
5394            newWillChange.add(key);
5395        }
5396    }
5397
5398    /**
5399     * Convert camelCase to dash-case properties.
5400     */
5401    const camelToDash = (str) => str.replace(/([a-z])([A-Z])/gu, "$1-$2").toLowerCase();
5402
5403    const optimizedAppearDataId = "framerAppearId";
5404    const optimizedAppearDataAttribute = "data-" + camelToDash(optimizedAppearDataId);
5405
5406    function getOptimisedAppearId(visualElement) {
5407        return visualElement.props[optimizedAppearDataAttribute];
5408    }
5409
5410    const isNotNull = (value) => value !== null;
5411    function getFinalKeyframe(keyframes, { repeat, repeatType = "loop" }, finalKeyframe) {
5412        const resolvedKeyframes = keyframes.filter(isNotNull);
5413        const index = repeat && repeatType !== "loop" && repeat % 2 === 1
5414            ? 0
5415            : resolvedKeyframes.length - 1;
5416        return !index || finalKeyframe === undefined
5417            ? resolvedKeyframes[index]
5418            : finalKeyframe;
5419    }
5420
5421    const underDampedSpring = {
5422        type: "spring",
5423        stiffness: 500,
5424        damping: 25,
5425        restSpeed: 10,
5426    };
5427    const criticallyDampedSpring = (target) => ({
5428        type: "spring",
5429        stiffness: 550,
5430        damping: target === 0 ? 2 * Math.sqrt(550) : 30,
5431        restSpeed: 10,
5432    });
vendor: 35,986 bytes, lines 5433-6324
5433    const keyframesTransition = {
5434        type: "keyframes",
5435        duration: 0.8,
5436    };
5437    /**
5438     * Default easing curve is a slightly shallower version of
5439     * the default browser easing curve.
5440     */
5441    const ease = {
5442        type: "keyframes",
5443        ease: [0.25, 0.1, 0.35, 1],
5444        duration: 0.3,
5445    };
5446    const getDefaultTransition = (valueKey, { keyframes }) => {
5447        if (keyframes.length > 2) {
5448            return keyframesTransition;
5449        }
5450        else if (transformProps.has(valueKey)) {
5451            return valueKey.startsWith("scale")
5452                ? criticallyDampedSpring(keyframes[1])
5453                : underDampedSpring;
5454        }
5455        return ease;
5456    };
5457
5458    /**
5459     * Decide whether a transition is defined on a given Transition.
5460     * This filters out orchestration options and returns true
5461     * if any options are left.
5462     */
5463    function isTransitionDefined({ when, delay: _delay, delayChildren, staggerChildren, staggerDirection, repeat, repeatType, repeatDelay, from, elapsed, ...transition }) {
5464        return !!Object.keys(transition).length;
5465    }
5466
5467    const animateMotionValue = (name, value, target, transition = {}, element, isHandoff) => (onComplete) => {
5468        const valueTransition = getValueTransition$1(transition, name) || {};
5469        /**
5470         * Most transition values are currently completely overwritten by value-specific
5471         * transitions. In the future it'd be nicer to blend these transitions. But for now
5472         * delay actually does inherit from the root transition if not value-specific.
5473         */
5474        const delay = valueTransition.delay || transition.delay || 0;
5475        /**
5476         * Elapsed isn't a public transition option but can be passed through from
5477         * optimized appear effects in milliseconds.
5478         */
5479        let { elapsed = 0 } = transition;
5480        elapsed = elapsed - secondsToMilliseconds(delay);
5481        const options = {
5482            keyframes: Array.isArray(target) ? target : [null, target],
5483            ease: "easeOut",
5484            velocity: value.getVelocity(),
5485            ...valueTransition,
5486            delay: -elapsed,
5487            onUpdate: (v) => {
5488                value.set(v);
5489                valueTransition.onUpdate && valueTransition.onUpdate(v);
5490            },
5491            onComplete: () => {
5492                onComplete();
5493                valueTransition.onComplete && valueTransition.onComplete();
5494            },
5495            name,
5496            motionValue: value,
5497            element: isHandoff ? undefined : element,
5498        };
5499        /**
5500         * If there's no transition defined for this value, we can generate
5501         * unique transition settings for this value.
5502         */
5503        if (!isTransitionDefined(valueTransition)) {
5504            Object.assign(options, getDefaultTransition(name, options));
5505        }
5506        /**
5507         * Both WAAPI and our internal animation functions use durations
5508         * as defined by milliseconds, while our external API defines them
5509         * as seconds.
5510         */
5511        options.duration && (options.duration = secondsToMilliseconds(options.duration));
5512        options.repeatDelay && (options.repeatDelay = secondsToMilliseconds(options.repeatDelay));
5513        /**
5514         * Support deprecated way to set initial value. Prefer keyframe syntax.
5515         */
5516        if (options.from !== undefined) {
5517            options.keyframes[0] = options.from;
5518        }
5519        let shouldSkip = false;
5520        if (options.type === false ||
5521            (options.duration === 0 && !options.repeatDelay)) {
5522            makeAnimationInstant(options);
5523            if (options.delay === 0) {
5524                shouldSkip = true;
5525            }
5526        }
5527        if (MotionGlobalConfig.instantAnimations ||
5528            MotionGlobalConfig.skipAnimations) {
5529            shouldSkip = true;
5530            makeAnimationInstant(options);
5531            options.delay = 0;
5532        }
5533        /**
5534         * If the transition type or easing has been explicitly set by the user
5535         * then we don't want to allow flattening the animation.
5536         */
5537        options.allowFlatten = !valueTransition.type && !valueTransition.ease;
5538        /**
5539         * If we can or must skip creating the animation, and apply only
5540         * the final keyframe, do so. We also check once keyframes are resolved but
5541         * this early check prevents the need to create an animation at all.
5542         */
5543        if (shouldSkip && !isHandoff && value.get() !== undefined) {
5544            const finalKeyframe = getFinalKeyframe(options.keyframes, valueTransition);
5545            if (finalKeyframe !== undefined) {
5546                frame.update(() => {
5547                    options.onUpdate(finalKeyframe);
5548                    options.onComplete();
5549                });
5550                return;
5551            }
5552        }
5553        return valueTransition.isSync
5554            ? new JSAnimation(options)
5555            : new AsyncMotionValueAnimation(options);
5556    };
5557
5558    /**
5559     * Decide whether we should block this animation. Previously, we achieved this
5560     * just by checking whether the key was listed in protectedKeys, but this
5561     * posed problems if an animation was triggered by afterChildren and protectedKeys
5562     * had been set to true in the meantime.
5563     */
5564    function shouldBlockAnimation({ protectedKeys, needsAnimating }, key) {
5565        const shouldBlock = protectedKeys.hasOwnProperty(key) && needsAnimating[key] !== true;
5566        needsAnimating[key] = false;
5567        return shouldBlock;
5568    }
5569    function animateTarget(visualElement, targetAndTransition, { delay = 0, transitionOverride, type } = {}) {
5570        let { transition = visualElement.getDefaultTransition(), transitionEnd, ...target } = targetAndTransition;
5571        if (transitionOverride)
5572            transition = transitionOverride;
5573        const animations = [];
5574        const animationTypeState = type &&
5575            visualElement.animationState &&
5576            visualElement.animationState.getState()[type];
5577        for (const key in target) {
5578            const value = visualElement.getValue(key, visualElement.latestValues[key] ?? null);
5579            const valueTarget = target[key];
5580            if (valueTarget === undefined ||
5581                (animationTypeState &&
5582                    shouldBlockAnimation(animationTypeState, key))) {
5583                continue;
5584            }
5585            const valueTransition = {
5586                delay,
5587                ...getValueTransition$1(transition || {}, key),
5588            };
5589            /**
5590             * If the value is already at the defined target, skip the animation.
5591             */
5592            const currentValue = value.get();
5593            if (currentValue !== undefined &&
5594                !value.isAnimating &&
5595                !Array.isArray(valueTarget) &&
5596                valueTarget === currentValue &&
5597                !valueTransition.velocity) {
5598                continue;
5599            }
5600            /**
5601             * If this is the first time a value is being animated, check
5602             * to see if we're handling off from an existing animation.
5603             */
5604            let isHandoff = false;
5605            if (window.MotionHandoffAnimation) {
5606                const appearId = getOptimisedAppearId(visualElement);
5607                if (appearId) {
5608                    const startTime = window.MotionHandoffAnimation(appearId, key, frame);
5609                    if (startTime !== null) {
5610                        valueTransition.startTime = startTime;
5611                        isHandoff = true;
5612                    }
5613                }
5614            }
5615            addValueToWillChange(visualElement, key);
5616            value.start(animateMotionValue(key, value, valueTarget, visualElement.shouldReduceMotion && positionalKeys.has(key)
5617                ? { type: false }
5618                : valueTransition, visualElement, isHandoff));
5619            const animation = value.animation;
5620            if (animation) {
5621                animations.push(animation);
5622            }
5623        }
5624        if (transitionEnd) {
5625            Promise.all(animations).then(() => {
5626                frame.update(() => {
5627                    transitionEnd && setTarget(visualElement, transitionEnd);
5628                });
5629            });
5630        }
5631        return animations;
5632    }
5633
5634    /**
5635     * Bounding boxes tend to be defined as top, left, right, bottom. For various operations
5636     * it's easier to consider each axis individually. This function returns a bounding box
5637     * as a map of single-axis min/max values.
5638     */
5639    function convertBoundingBoxToBox({ top, left, right, bottom, }) {
5640        return {
5641            x: { min: left, max: right },
5642            y: { min: top, max: bottom },
5643        };
5644    }
5645    /**
5646     * Applies a TransformPoint function to a bounding box. TransformPoint is usually a function
5647     * provided by Framer to allow measured points to be corrected for device scaling. This is used
5648     * when measuring DOM elements and DOM event points.
5649     */
5650    function transformBoxPoints(point, transformPoint) {
5651        if (!transformPoint)
5652            return point;
5653        const topLeft = transformPoint({ x: point.left, y: point.top });
5654        const bottomRight = transformPoint({ x: point.right, y: point.bottom });
5655        return {
5656            top: topLeft.y,
5657            left: topLeft.x,
5658            bottom: bottomRight.y,
5659            right: bottomRight.x,
5660        };
5661    }
5662
5663    function measureViewportBox(instance, transformPoint) {
5664        return convertBoundingBoxToBox(transformBoxPoints(instance.getBoundingClientRect(), transformPoint));
5665    }
5666
5667    const featureProps = {
5668        animation: [
5669            "animate",
5670            "variants",
5671            "whileHover",
5672            "whileTap",
5673            "exit",
5674            "whileInView",
5675            "whileFocus",
5676            "whileDrag",
5677        ],
5678        exit: ["exit"],
5679        drag: ["drag", "dragControls"],
5680        focus: ["whileFocus"],
5681        hover: ["whileHover", "onHoverStart", "onHoverEnd"],
5682        tap: ["whileTap", "onTap", "onTapStart", "onTapCancel"],
5683        pan: ["onPan", "onPanStart", "onPanSessionStart", "onPanEnd"],
5684        inView: ["whileInView", "onViewportEnter", "onViewportLeave"],
5685        layout: ["layout", "layoutId"],
5686    };
5687    const featureDefinitions = {};
5688    for (const key in featureProps) {
5689        featureDefinitions[key] = {
5690            isEnabled: (props) => featureProps[key].some((name) => !!props[name]),
5691        };
5692    }
5693
5694    const createAxis = () => ({ min: 0, max: 0 });
5695    const createBox = () => ({
5696        x: createAxis(),
5697        y: createAxis(),
5698    });
5699
5700    const isBrowser = typeof window !== "undefined";
5701
5702    // Does this device prefer reduced motion? Returns `null` server-side.
5703    const prefersReducedMotion = { current: null };
5704    const hasReducedMotionListener = { current: false };
5705
5706    function initPrefersReducedMotion() {
5707        hasReducedMotionListener.current = true;
5708        if (!isBrowser)
5709            return;
5710        if (window.matchMedia) {
5711            const motionMediaQuery = window.matchMedia("(prefers-reduced-motion)");
5712            const setReducedMotionPreferences = () => (prefersReducedMotion.current = motionMediaQuery.matches);
5713            motionMediaQuery.addEventListener("change", setReducedMotionPreferences);
5714            setReducedMotionPreferences();
5715        }
5716        else {
5717            prefersReducedMotion.current = false;
5718        }
5719    }
5720
5721    function isAnimationControls(v) {
5722        return (v !== null &&
5723            typeof v === "object" &&
5724            typeof v.start === "function");
5725    }
5726
5727    /**
5728     * Decides if the supplied variable is variant label
5729     */
5730    function isVariantLabel(v) {
5731        return typeof v === "string" || Array.isArray(v);
5732    }
5733
5734    const variantPriorityOrder = [
5735        "animate",
5736        "whileInView",
5737        "whileFocus",
5738        "whileHover",
5739        "whileTap",
5740        "whileDrag",
5741        "exit",
5742    ];
5743    const variantProps = ["initial", ...variantPriorityOrder];
5744
5745    function isControllingVariants(props) {
5746        return (isAnimationControls(props.animate) ||
5747            variantProps.some((name) => isVariantLabel(props[name])));
5748    }
5749    function isVariantNode(props) {
5750        return Boolean(isControllingVariants(props) || props.variants);
5751    }
5752
5753    function updateMotionValuesFromProps(element, next, prev) {
5754        for (const key in next) {
5755            const nextValue = next[key];
5756            const prevValue = prev[key];
5757            if (isMotionValue(nextValue)) {
5758                /**
5759                 * If this is a motion value found in props or style, we want to add it
5760                 * to our visual element's motion value map.
5761                 */
5762                element.addValue(key, nextValue);
5763            }
5764            else if (isMotionValue(prevValue)) {
5765                /**
5766                 * If we're swapping from a motion value to a static value,
5767                 * create a new motion value from that
5768                 */
5769                element.addValue(key, motionValue(nextValue, { owner: element }));
5770            }
5771            else if (prevValue !== nextValue) {
5772                /**
5773                 * If this is a flat value that has changed, update the motion value
5774                 * or create one if it doesn't exist. We only want to do this if we're
5775                 * not handling the value with our animation state.
5776                 */
5777                if (element.hasValue(key)) {
5778                    const existingValue = element.getValue(key);
5779                    if (existingValue.liveStyle === true) {
5780                        existingValue.jump(nextValue);
5781                    }
5782                    else if (!existingValue.hasAnimated) {
5783                        existingValue.set(nextValue);
5784                    }
5785                }
5786                else {
5787                    const latestValue = element.getStaticValue(key);
5788                    element.addValue(key, motionValue(latestValue !== undefined ? latestValue : nextValue, { owner: element }));
5789                }
5790            }
5791        }
5792        // Handle removed values
5793        for (const key in prev) {
5794            if (next[key] === undefined)
5795                element.removeValue(key);
5796        }
5797        return next;
5798    }
5799
5800    const propEventHandlers = [
5801        "AnimationStart",
5802        "AnimationComplete",
5803        "Update",
5804        "BeforeLayoutMeasure",
5805        "LayoutMeasure",
5806        "LayoutAnimationStart",
5807        "LayoutAnimationComplete",
5808    ];
5809    /**
5810     * A VisualElement is an imperative abstraction around UI elements such as
5811     * HTMLElement, SVGElement, Three.Object3D etc.
5812     */
5813    class VisualElement {
5814        /**
5815         * This method takes React props and returns found MotionValues. For example, HTML
5816         * MotionValues will be found within the style prop, whereas for Three.js within attribute arrays.
5817         *
5818         * This isn't an abstract method as it needs calling in the constructor, but it is
5819         * intended to be one.
5820         */
5821        scrapeMotionValuesFromProps(_props, _prevProps, _visualElement) {
5822            return {};
5823        }
5824        constructor({ parent, props, presenceContext, reducedMotionConfig, blockInitialAnimation, visualState, }, options = {}) {
5825            /**
5826             * A reference to the current underlying Instance, e.g. a HTMLElement
5827             * or Three.Mesh etc.
5828             */
5829            this.current = null;
5830            /**
5831             * A set containing references to this VisualElement's children.
5832             */
5833            this.children = new Set();
5834            /**
5835             * Determine what role this visual element should take in the variant tree.
5836             */
5837            this.isVariantNode = false;
5838            this.isControllingVariants = false;
5839            /**
5840             * Decides whether this VisualElement should animate in reduced motion
5841             * mode.
5842             *
5843             * TODO: This is currently set on every individual VisualElement but feels
5844             * like it could be set globally.
5845             */
5846            this.shouldReduceMotion = null;
5847            /**
5848             * A map of all motion values attached to this visual element. Motion
5849             * values are source of truth for any given animated value. A motion
5850             * value might be provided externally by the component via props.
5851             */
5852            this.values = new Map();
5853            this.KeyframeResolver = KeyframeResolver;
5854            /**
5855             * Cleanup functions for active features (hover/tap/exit etc)
5856             */
5857            this.features = {};
5858            /**
5859             * A map of every subscription that binds the provided or generated
5860             * motion values onChange listeners to this visual element.
5861             */
5862            this.valueSubscriptions = new Map();
5863            /**
5864             * A reference to the previously-provided motion values as returned
5865             * from scrapeMotionValuesFromProps. We use the keys in here to determine
5866             * if any motion values need to be removed after props are updated.
5867             */
5868            this.prevMotionValues = {};
5869            /**
5870             * An object containing a SubscriptionManager for each active event.
5871             */
5872            this.events = {};
5873            /**
5874             * An object containing an unsubscribe function for each prop event subscription.
5875             * For example, every "Update" event can have multiple subscribers via
5876             * VisualElement.on(), but only one of those can be defined via the onUpdate prop.
5877             */
5878            this.propEventSubscriptions = {};
5879            this.notifyUpdate = () => this.notify("Update", this.latestValues);
5880            this.render = () => {
5881                if (!this.current)
5882                    return;
5883                this.triggerBuild();
5884                this.renderInstance(this.current, this.renderState, this.props.style, this.projection);
5885            };
5886            this.renderScheduledAt = 0.0;
5887            this.scheduleRender = () => {
5888                const now = time.now();
5889                if (this.renderScheduledAt < now) {
5890                    this.renderScheduledAt = now;
5891                    frame.render(this.render, false, true);
5892                }
5893            };
5894            const { latestValues, renderState } = visualState;
5895            this.latestValues = latestValues;
5896            this.baseTarget = { ...latestValues };
5897            this.initialValues = props.initial ? { ...latestValues } : {};
5898            this.renderState = renderState;
5899            this.parent = parent;
5900            this.props = props;
5901            this.presenceContext = presenceContext;
5902            this.depth = parent ? parent.depth + 1 : 0;
5903            this.reducedMotionConfig = reducedMotionConfig;
5904            this.options = options;
5905            this.blockInitialAnimation = Boolean(blockInitialAnimation);
5906            this.isControllingVariants = isControllingVariants(props);
5907            this.isVariantNode = isVariantNode(props);
5908            if (this.isVariantNode) {
5909                this.variantChildren = new Set();
5910            }
5911            this.manuallyAnimateOnMount = Boolean(parent && parent.current);
5912            /**
5913             * Any motion values that are provided to the element when created
5914             * aren't yet bound to the element, as this would technically be impure.
5915             * However, we iterate through the motion values and set them to the
5916             * initial values for this component.
5917             *
5918             * TODO: This is impure and we should look at changing this to run on mount.
5919             * Doing so will break some tests but this isn't necessarily a breaking change,
5920             * more a reflection of the test.
5921             */
5922            const { willChange, ...initialMotionValues } = this.scrapeMotionValuesFromProps(props, {}, this);
5923            for (const key in initialMotionValues) {
5924                const value = initialMotionValues[key];
5925                if (latestValues[key] !== undefined && isMotionValue(value)) {
5926                    value.set(latestValues[key]);
5927                }
5928            }
5929        }
5930        mount(instance) {
5931            this.current = instance;
5932            visualElementStore.set(instance, this);
5933            if (this.projection && !this.projection.instance) {
5934                this.projection.mount(instance);
5935            }
5936            if (this.parent && this.isVariantNode && !this.isControllingVariants) {
5937                this.removeFromVariantTree = this.parent.addVariantChild(this);
5938            }
5939            this.values.forEach((value, key) => this.bindToMotionValue(key, value));
5940            if (!hasReducedMotionListener.current) {
5941                initPrefersReducedMotion();
5942            }
5943            this.shouldReduceMotion =
5944                this.reducedMotionConfig === "never"
5945                    ? false
5946                    : this.reducedMotionConfig === "always"
5947                        ? true
5948                        : prefersReducedMotion.current;
5949            {
5950                warnOnce(this.shouldReduceMotion !== true, "You have Reduced Motion enabled on your device. Animations may not appear as expected.", "reduced-motion-disabled");
5951            }
5952            this.parent?.addChild(this);
5953            this.update(this.props, this.presenceContext);
5954        }
5955        unmount() {
5956            this.projection && this.projection.unmount();
5957            cancelFrame(this.notifyUpdate);
5958            cancelFrame(this.render);
5959            this.valueSubscriptions.forEach((remove) => remove());
5960            this.valueSubscriptions.clear();
5961            this.removeFromVariantTree && this.removeFromVariantTree();
5962            this.parent?.removeChild(this);
5963            for (const key in this.events) {
5964                this.events[key].clear();
5965            }
5966            for (const key in this.features) {
5967                const feature = this.features[key];
5968                if (feature) {
5969                    feature.unmount();
5970                    feature.isMounted = false;
5971                }
5972            }
5973            this.current = null;
5974        }
5975        addChild(child) {
5976            this.children.add(child);
5977            this.enteringChildren ?? (this.enteringChildren = new Set());
5978            this.enteringChildren.add(child);
5979        }
5980        removeChild(child) {
5981            this.children.delete(child);
5982            this.enteringChildren && this.enteringChildren.delete(child);
5983        }
5984        bindToMotionValue(key, value) {
5985            if (this.valueSubscriptions.has(key)) {
5986                this.valueSubscriptions.get(key)();
5987            }
5988            const valueIsTransform = transformProps.has(key);
5989            if (valueIsTransform && this.onBindTransform) {
5990                this.onBindTransform();
5991            }
5992            const removeOnChange = value.on("change", (latestValue) => {
5993                this.latestValues[key] = latestValue;
5994                this.props.onUpdate && frame.preRender(this.notifyUpdate);
5995                if (valueIsTransform && this.projection) {
5996                    this.projection.isTransformDirty = true;
5997                }
5998                this.scheduleRender();
5999            });
6000            let removeSyncCheck;
6001            if (window.MotionCheckAppearSync) {
6002                removeSyncCheck = window.MotionCheckAppearSync(this, key, value);
6003            }
6004            this.valueSubscriptions.set(key, () => {
6005                removeOnChange();
6006                if (removeSyncCheck)
6007                    removeSyncCheck();
6008                if (value.owner)
6009                    value.stop();
6010            });
6011        }
6012        sortNodePosition(other) {
6013            /**
6014             * If these nodes aren't even of the same type we can't compare their depth.
6015             */
6016            if (!this.current ||
6017                !this.sortInstanceNodePosition ||
6018                this.type !== other.type) {
6019                return 0;
6020            }
6021            return this.sortInstanceNodePosition(this.current, other.current);
6022        }
6023        updateFeatures() {
6024            let key = "animation";
6025            for (key in featureDefinitions) {
6026                const featureDefinition = featureDefinitions[key];
6027                if (!featureDefinition)
6028                    continue;
6029                const { isEnabled, Feature: FeatureConstructor } = featureDefinition;
6030                /**
6031                 * If this feature is enabled but not active, make a new instance.
6032                 */
6033                if (!this.features[key] &&
6034                    FeatureConstructor &&
6035                    isEnabled(this.props)) {
6036                    this.features[key] = new FeatureConstructor(this);
6037                }
6038                /**
6039                 * If we have a feature, mount or update it.
6040                 */
6041                if (this.features[key]) {
6042                    const feature = this.features[key];
6043                    if (feature.isMounted) {
6044                        feature.update();
6045                    }
6046                    else {
6047                        feature.mount();
6048                        feature.isMounted = true;
6049                    }
6050                }
6051            }
6052        }
6053        triggerBuild() {
6054            this.build(this.renderState, this.latestValues, this.props);
6055        }
6056        /**
6057         * Measure the current viewport box with or without transforms.
6058         * Only measures axis-aligned boxes, rotate and skew must be manually
6059         * removed with a re-render to work.
6060         */
6061        measureViewportBox() {
6062            return this.current
6063                ? this.measureInstanceViewportBox(this.current, this.props)
6064                : createBox();
6065        }
6066        getStaticValue(key) {
6067            return this.latestValues[key];
6068        }
6069        setStaticValue(key, value) {
6070            this.latestValues[key] = value;
6071        }
6072        /**
6073         * Update the provided props. Ensure any newly-added motion values are
6074         * added to our map, old ones removed, and listeners updated.
6075         */
6076        update(props, presenceContext) {
6077            if (props.transformTemplate || this.props.transformTemplate) {
6078                this.scheduleRender();
6079            }
6080            this.prevProps = this.props;
6081            this.props = props;
6082            this.prevPresenceContext = this.presenceContext;
6083            this.presenceContext = presenceContext;
6084            /**
6085             * Update prop event handlers ie onAnimationStart, onAnimationComplete
6086             */
6087            for (let i = 0; i < propEventHandlers.length; i++) {
6088                const key = propEventHandlers[i];
6089                if (this.propEventSubscriptions[key]) {
6090                    this.propEventSubscriptions[key]();
6091                    delete this.propEventSubscriptions[key];
6092                }
6093                const listenerName = ("on" + key);
6094                const listener = props[listenerName];
6095                if (listener) {
6096                    this.propEventSubscriptions[key] = this.on(key, listener);
6097                }
6098            }
6099            this.prevMotionValues = updateMotionValuesFromProps(this, this.scrapeMotionValuesFromProps(props, this.prevProps, this), this.prevMotionValues);
6100            if (this.handleChildMotionValue) {
6101                this.handleChildMotionValue();
6102            }
6103        }
6104        getProps() {
6105            return this.props;
6106        }
6107        /**
6108         * Returns the variant definition with a given name.
6109         */
6110        getVariant(name) {
6111            return this.props.variants ? this.props.variants[name] : undefined;
6112        }
6113        /**
6114         * Returns the defined default transition on this component.
6115         */
6116        getDefaultTransition() {
6117            return this.props.transition;
6118        }
6119        getTransformPagePoint() {
6120            return this.props.transformPagePoint;
6121        }
6122        getClosestVariantNode() {
6123            return this.isVariantNode
6124                ? this
6125                : this.parent
6126                    ? this.parent.getClosestVariantNode()
6127                    : undefined;
6128        }
6129        /**
6130         * Add a child visual element to our set of children.
6131         */
6132        addVariantChild(child) {
6133            const closestVariantNode = this.getClosestVariantNode();
6134            if (closestVariantNode) {
6135                closestVariantNode.variantChildren &&
6136                    closestVariantNode.variantChildren.add(child);
6137                return () => closestVariantNode.variantChildren.delete(child);
6138            }
6139        }
6140        /**
6141         * Add a motion value and bind it to this visual element.
6142         */
6143        addValue(key, value) {
6144            // Remove existing value if it exists
6145            const existingValue = this.values.get(key);
6146            if (value !== existingValue) {
6147                if (existingValue)
6148                    this.removeValue(key);
6149                this.bindToMotionValue(key, value);
6150                this.values.set(key, value);
6151                this.latestValues[key] = value.get();
6152            }
6153        }
6154        /**
6155         * Remove a motion value and unbind any active subscriptions.
6156         */
6157        removeValue(key) {
6158            this.values.delete(key);
6159            const unsubscribe = this.valueSubscriptions.get(key);
6160            if (unsubscribe) {
6161                unsubscribe();
6162                this.valueSubscriptions.delete(key);
6163            }
6164            delete this.latestValues[key];
6165            this.removeValueFromRenderState(key, this.renderState);
6166        }
6167        /**
6168         * Check whether we have a motion value for this key
6169         */
6170        hasValue(key) {
6171            return this.values.has(key);
6172        }
6173        getValue(key, defaultValue) {
6174            if (this.props.values && this.props.values[key]) {
6175                return this.props.values[key];
6176            }
6177            let value = this.values.get(key);
6178            if (value === undefined && defaultValue !== undefined) {
6179                value = motionValue(defaultValue === null ? undefined : defaultValue, { owner: this });
6180                this.addValue(key, value);
6181            }
6182            return value;
6183        }
6184        /**
6185         * If we're trying to animate to a previously unencountered value,
6186         * we need to check for it in our state and as a last resort read it
6187         * directly from the instance (which might have performance implications).
6188         */
6189        readValue(key, target) {
6190            let value = this.latestValues[key] !== undefined || !this.current
6191                ? this.latestValues[key]
6192                : this.getBaseTargetFromProps(this.props, key) ??
6193                    this.readValueFromInstance(this.current, key, this.options);
6194            if (value !== undefined && value !== null) {
6195                if (typeof value === "string" &&
6196                    (isNumericalString(value) || isZeroValueString(value))) {
6197                    // If this is a number read as a string, ie "0" or "200", convert it to a number
6198                    value = parseFloat(value);
6199                }
6200                else if (!findValueType(value) && complex.test(target)) {
6201                    value = getAnimatableNone(key, target);
6202                }
6203                this.setBaseTarget(key, isMotionValue(value) ? value.get() : value);
6204            }
6205            return isMotionValue(value) ? value.get() : value;
6206        }
6207        /**
6208         * Set the base target to later animate back to. This is currently
6209         * only hydrated on creation and when we first read a value.
6210         */
6211        setBaseTarget(key, value) {
6212            this.baseTarget[key] = value;
6213        }
6214        /**
6215         * Find the base target for a value thats been removed from all animation
6216         * props.
6217         */
6218        getBaseTarget(key) {
6219            const { initial } = this.props;
6220            let valueFromInitial;
6221            if (typeof initial === "string" || typeof initial === "object") {
6222                const variant = resolveVariantFromProps(this.props, initial, this.presenceContext?.custom);
6223                if (variant) {
6224                    valueFromInitial = variant[key];
6225                }
6226            }
6227            /**
6228             * If this value still exists in the current initial variant, read that.
6229             */
6230            if (initial && valueFromInitial !== undefined) {
6231                return valueFromInitial;
6232            }
6233            /**
6234             * Alternatively, if this VisualElement config has defined a getBaseTarget
6235             * so we can read the value from an alternative source, try that.
6236             */
6237            const target = this.getBaseTargetFromProps(this.props, key);
6238            if (target !== undefined && !isMotionValue(target))
6239                return target;
6240            /**
6241             * If the value was initially defined on initial, but it doesn't any more,
6242             * return undefined. Otherwise return the value as initially read from the DOM.
6243             */
6244            return this.initialValues[key] !== undefined &&
6245                valueFromInitial === undefined
6246                ? undefined
6247                : this.baseTarget[key];
6248        }
6249        on(eventName, callback) {
6250            if (!this.events[eventName]) {
6251                this.events[eventName] = new SubscriptionManager();
6252            }
6253            return this.events[eventName].add(callback);
6254        }
6255        notify(eventName, ...args) {
6256            if (this.events[eventName]) {
6257                this.events[eventName].notify(...args);
6258            }
6259        }
6260        scheduleRenderMicrotask() {
6261            microtask.render(this.render);
6262        }
6263    }
6264
6265    class DOMVisualElement extends VisualElement {
6266        constructor() {
6267            super(...arguments);
6268            this.KeyframeResolver = DOMKeyframesResolver;
6269        }
6270        sortInstanceNodePosition(a, b) {
6271            /**
6272             * compareDocumentPosition returns a bitmask, by using the bitwise &
6273             * we're returning true if 2 in that bitmask is set to true. 2 is set
6274             * to true if b preceeds a.
6275             */
6276            return a.compareDocumentPosition(b) & 2 ? 1 : -1;
6277        }
6278        getBaseTargetFromProps(props, key) {
6279            return props.style
6280                ? props.style[key]
6281                : undefined;
6282        }
6283        removeValueFromRenderState(key, { vars, style }) {
6284            delete vars[key];
6285            delete style[key];
6286        }
6287        handleChildMotionValue() {
6288            if (this.childSubscription) {
6289                this.childSubscription();
6290                delete this.childSubscription;
6291            }
6292            const { children } = this.props;
6293            if (isMotionValue(children)) {
6294                this.childSubscription = children.on("change", (latest) => {
6295                    if (this.current) {
6296                        this.current.textContent = `${latest}`;
6297                    }
6298                });
6299            }
6300        }
6301    }
6302
6303    const translateAlias = {
6304        x: "translateX",
6305        y: "translateY",
6306        z: "translateZ",
6307        transformPerspective: "perspective",
6308    };
6309    const numTransforms = transformPropOrder.length;
6310    /**
6311     * Build a CSS transform style from individual x/y/scale etc properties.
6312     *
6313     * This outputs with a default order of transforms/scales/rotations, this can be customised by
6314     * providing a transformTemplate function.
6315     */
6316    function buildTransform(latestValues, transform, transformTemplate) {
6317        // The transform string we're going to build into.
6318        let transformString = "";
6319        let transformIsDefault = true;
6320        /**
6321         * Loop over all possible transforms in order, adding the ones that
6322         * are present to the transform string.
6323         */
6324        for (let i = 0; i < numTransforms; i++) {
vendor: 8,600 bytes, lines 6325-6548
6325            const key = transformPropOrder[i];
6326            const value = latestValues[key];
6327            if (value === undefined)
6328                continue;
6329            let valueIsDefault = true;
6330            if (typeof value === "number") {
6331                valueIsDefault = value === (key.startsWith("scale") ? 1 : 0);
6332            }
6333            else {
6334                valueIsDefault = parseFloat(value) === 0;
6335            }
6336            if (!valueIsDefault || transformTemplate) {
6337                const valueAsType = getValueAsType(value, numberValueTypes[key]);
6338                if (!valueIsDefault) {
6339                    transformIsDefault = false;
6340                    const transformName = translateAlias[key] || key;
6341                    transformString += `${transformName}(${valueAsType}) `;
6342                }
6343                if (transformTemplate) {
6344                    transform[key] = valueAsType;
6345                }
6346            }
6347        }
6348        transformString = transformString.trim();
6349        // If we have a custom `transform` template, pass our transform values and
6350        // generated transformString to that before returning
6351        if (transformTemplate) {
6352            transformString = transformTemplate(transform, transformIsDefault ? "" : transformString);
6353        }
6354        else if (transformIsDefault) {
6355            transformString = "none";
6356        }
6357        return transformString;
6358    }
6359
6360    function buildHTMLStyles(state, latestValues, transformTemplate) {
6361        const { style, vars, transformOrigin } = state;
6362        // Track whether we encounter any transform or transformOrigin values.
6363        let hasTransform = false;
6364        let hasTransformOrigin = false;
6365        /**
6366         * Loop over all our latest animated values and decide whether to handle them
6367         * as a style or CSS variable.
6368         *
6369         * Transforms and transform origins are kept separately for further processing.
6370         */
6371        for (const key in latestValues) {
6372            const value = latestValues[key];
6373            if (transformProps.has(key)) {
6374                // If this is a transform, flag to enable further transform processing
6375                hasTransform = true;
6376                continue;
6377            }
6378            else if (isCSSVariableName(key)) {
6379                vars[key] = value;
6380                continue;
6381            }
6382            else {
6383                // Convert the value to its default value type, ie 0 -> "0px"
6384                const valueAsType = getValueAsType(value, numberValueTypes[key]);
6385                if (key.startsWith("origin")) {
6386                    // If this is a transform origin, flag and enable further transform-origin processing
6387                    hasTransformOrigin = true;
6388                    transformOrigin[key] =
6389                        valueAsType;
6390                }
6391                else {
6392                    style[key] = valueAsType;
6393                }
6394            }
6395        }
6396        if (!latestValues.transform) {
6397            if (hasTransform || transformTemplate) {
6398                style.transform = buildTransform(latestValues, state.transform, transformTemplate);
6399            }
6400            else if (style.transform) {
6401                /**
6402                 * If we have previously created a transform but currently don't have any,
6403                 * reset transform style to none.
6404                 */
6405                style.transform = "none";
6406            }
6407        }
6408        /**
6409         * Build a transformOrigin style. Uses the same defaults as the browser for
6410         * undefined origins.
6411         */
6412        if (hasTransformOrigin) {
6413            const { originX = "50%", originY = "50%", originZ = 0, } = transformOrigin;
6414            style.transformOrigin = `${originX} ${originY} ${originZ}`;
6415        }
6416    }
6417
6418    function renderHTML(element, { style, vars }, styleProp, projection) {
6419        const elementStyle = element.style;
6420        let key;
6421        for (key in style) {
6422            // CSSStyleDeclaration has [index: number]: string; in the types, so we use that as key type.
6423            elementStyle[key] = style[key];
6424        }
6425        // Write projection styles directly to element style
6426        projection?.applyProjectionStyles(elementStyle, styleProp);
6427        for (key in vars) {
6428            // Loop over any CSS variables and assign those.
6429            // They can only be assigned using `setProperty`.
6430            elementStyle.setProperty(key, vars[key]);
6431        }
6432    }
6433
6434    const scaleCorrectors = {};
6435
6436    function isForcedMotionValue(key, { layout, layoutId }) {
6437        return (transformProps.has(key) ||
6438            key.startsWith("origin") ||
6439            ((layout || layoutId !== undefined) &&
6440                (!!scaleCorrectors[key] || key === "opacity")));
6441    }
6442
6443    function scrapeMotionValuesFromProps$1(props, prevProps, visualElement) {
6444        const { style } = props;
6445        const newValues = {};
6446        for (const key in style) {
6447            if (isMotionValue(style[key]) ||
6448                (prevProps.style &&
6449                    isMotionValue(prevProps.style[key])) ||
6450                isForcedMotionValue(key, props) ||
6451                visualElement?.getValue(key)?.liveStyle !== undefined) {
6452                newValues[key] = style[key];
6453            }
6454        }
6455        return newValues;
6456    }
6457
6458    function getComputedStyle$1(element) {
6459        return window.getComputedStyle(element);
6460    }
6461    class HTMLVisualElement extends DOMVisualElement {
6462        constructor() {
6463            super(...arguments);
6464            this.type = "html";
6465            this.renderInstance = renderHTML;
6466        }
6467        readValueFromInstance(instance, key) {
6468            if (transformProps.has(key)) {
6469                return this.projection?.isProjecting
6470                    ? defaultTransformValue(key)
6471                    : readTransformValue(instance, key);
6472            }
6473            else {
6474                const computedStyle = getComputedStyle$1(instance);
6475                const value = (isCSSVariableName(key)
6476                    ? computedStyle.getPropertyValue(key)
6477                    : computedStyle[key]) || 0;
6478                return typeof value === "string" ? value.trim() : value;
6479            }
6480        }
6481        measureInstanceViewportBox(instance, { transformPagePoint }) {
6482            return measureViewportBox(instance, transformPagePoint);
6483        }
6484        build(renderState, latestValues, props) {
6485            buildHTMLStyles(renderState, latestValues, props.transformTemplate);
6486        }
6487        scrapeMotionValuesFromProps(props, prevProps, visualElement) {
6488            return scrapeMotionValuesFromProps$1(props, prevProps, visualElement);
6489        }
6490    }
6491
6492    function isObjectKey(key, object) {
6493        return key in object;
6494    }
6495    class ObjectVisualElement extends VisualElement {
6496        constructor() {
6497            super(...arguments);
6498            this.type = "object";
6499        }
6500        readValueFromInstance(instance, key) {
6501            if (isObjectKey(key, instance)) {
6502                const value = instance[key];
6503                if (typeof value === "string" || typeof value === "number") {
6504                    return value;
6505                }
6506            }
6507            return undefined;
6508        }
6509        getBaseTargetFromProps() {
6510            return undefined;
6511        }
6512        removeValueFromRenderState(key, renderState) {
6513            delete renderState.output[key];
6514        }
6515        measureInstanceViewportBox() {
6516            return createBox();
6517        }
6518        build(renderState, latestValues) {
6519            Object.assign(renderState.output, latestValues);
6520        }
6521        renderInstance(instance, { output }) {
6522            Object.assign(instance, output);
6523        }
6524        sortInstanceNodePosition() {
6525            return 0;
6526        }
6527    }
6528
6529    const dashKeys = {
6530        offset: "stroke-dashoffset",
6531        array: "stroke-dasharray",
6532    };
6533    const camelKeys = {
6534        offset: "strokeDashoffset",
6535        array: "strokeDasharray",
6536    };
6537    /**
6538     * Build SVG path properties. Uses the path's measured length to convert
6539     * our custom pathLength, pathSpacing and pathOffset into stroke-dashoffset
6540     * and stroke-dasharray attributes.
6541     *
6542     * This function is mutative to reduce per-frame GC.
6543     */
6544    function buildSVGPath(attrs, length, spacing = 1, offset = 0, useDashCase = true) {
6545        // Normalise path length by setting SVG attribute pathLength to 1
6546        attrs.pathLength = 1;
6547        // We use dash case when setting attributes directly to the DOM node and camel case
6548        // when defining props on a React component.
vendor: 3,158 bytes, lines 6549-6641
6549        const keys = useDashCase ? dashKeys : camelKeys;
6550        // Build the dash offset
6551        attrs[keys.offset] = px.transform(-offset);
6552        // Build the dash array
6553        const pathLength = px.transform(length);
6554        const pathSpacing = px.transform(spacing);
6555        attrs[keys.array] = `${pathLength} ${pathSpacing}`;
6556    }
6557
6558    /**
6559     * Build SVG visual attributes, like cx and style.transform
6560     */
6561    function buildSVGAttrs(state, { attrX, attrY, attrScale, pathLength, pathSpacing = 1, pathOffset = 0, 
6562    // This is object creation, which we try to avoid per-frame.
6563    ...latest }, isSVGTag, transformTemplate, styleProp) {
6564        buildHTMLStyles(state, latest, transformTemplate);
6565        /**
6566         * For svg tags we just want to make sure viewBox is animatable and treat all the styles
6567         * as normal HTML tags.
6568         */
6569        if (isSVGTag) {
6570            if (state.style.viewBox) {
6571                state.attrs.viewBox = state.style.viewBox;
6572            }
6573            return;
6574        }
6575        state.attrs = state.style;
6576        state.style = {};
6577        const { attrs, style } = state;
6578        /**
6579         * However, we apply transforms as CSS transforms.
6580         * So if we detect a transform, transformOrigin we take it from attrs and copy it into style.
6581         */
6582        if (attrs.transform) {
6583            style.transform = attrs.transform;
6584            delete attrs.transform;
6585        }
6586        if (style.transform || attrs.transformOrigin) {
6587            style.transformOrigin = attrs.transformOrigin ?? "50% 50%";
6588            delete attrs.transformOrigin;
6589        }
6590        if (style.transform) {
6591            /**
6592             * SVG's element transform-origin uses its own median as a reference.
6593             * Therefore, transformBox becomes a fill-box
6594             */
6595            style.transformBox = styleProp?.transformBox ?? "fill-box";
6596            delete attrs.transformBox;
6597        }
6598        // Render attrX/attrY/attrScale as attributes
6599        if (attrX !== undefined)
6600            attrs.x = attrX;
6601        if (attrY !== undefined)
6602            attrs.y = attrY;
6603        if (attrScale !== undefined)
6604            attrs.scale = attrScale;
6605        // Build SVG path if one has been defined
6606        if (pathLength !== undefined) {
6607            buildSVGPath(attrs, pathLength, pathSpacing, pathOffset, false);
6608        }
6609    }
6610
6611    /**
6612     * A set of attribute names that are always read/written as camel case.
6613     */
6614    const camelCaseAttributes = new Set([
6615        "baseFrequency",
6616        "diffuseConstant",
6617        "kernelMatrix",
6618        "kernelUnitLength",
6619        "keySplines",
6620        "keyTimes",
6621        "limitingConeAngle",
6622        "markerHeight",
6623        "markerWidth",
6624        "numOctaves",
6625        "targetX",
6626        "targetY",
6627        "surfaceScale",
6628        "specularConstant",
6629        "specularExponent",
6630        "stdDeviation",
6631        "tableValues",
6632        "viewBox",
6633        "gradientTransform",
6634        "pathLength",
6635        "startOffset",
6636        "textLength",
6637        "lengthAdjust",
6638    ]);
6639
6640    const isSVGTag = (tag) => typeof tag === "string" && tag.toLowerCase() === "svg";
6641
6642    function renderSVG(element, renderState, _styleProp, projection) {
6643        renderHTML(element, renderState, undefined, projection);
6644        for (const key in renderState.attrs) {
6645            element.setAttribute(!camelCaseAttributes.has(key) ? camelToDash(key) : key, renderState.attrs[key]);
6646        }
6647    }
6648
6649    function scrapeMotionValuesFromProps(props, prevProps, visualElement) {
6650        const newValues = scrapeMotionValuesFromProps$1(props, prevProps, visualElement);
6651        for (const key in props) {
6652            if (isMotionValue(props[key]) ||
6653                isMotionValue(prevProps[key])) {
6654                const targetKey = transformPropOrder.indexOf(key) !== -1
6655                    ? "attr" + key.charAt(0).toUpperCase() + key.substring(1)
6656                    : key;
6657                newValues[targetKey] = props[key];
6658            }
6659        }
6660        return newValues;
6661    }
6662
6663    class SVGVisualElement extends DOMVisualElement {
6664        constructor() {
6665            super(...arguments);
6666            this.type = "svg";
6667            this.isSVGTag = false;
6668            this.measureInstanceViewportBox = createBox;
6669        }
6670        getBaseTargetFromProps(props, key) {
6671            return props[key];
6672        }
6673        readValueFromInstance(instance, key) {
6674            if (transformProps.has(key)) {
6675                const defaultType = getDefaultValueType(key);
6676                return defaultType ? defaultType.default || 0 : 0;
6677            }
6678            key = !camelCaseAttributes.has(key) ? camelToDash(key) : key;
6679            return instance.getAttribute(key);
6680        }
6681        scrapeMotionValuesFromProps(props, prevProps, visualElement) {
6682            return scrapeMotionValuesFromProps(props, prevProps, visualElement);
6683        }
6684        build(renderState, latestValues, props) {
6685            buildSVGAttrs(renderState, latestValues, this.isSVGTag, props.transformTemplate, props.style);
6686        }
6687        renderInstance(instance, renderState, styleProp, projection) {
6688            renderSVG(instance, renderState, styleProp, projection);
6689        }
6690        mount(instance) {
6691            this.isSVGTag = isSVGTag(instance.tagName);
6692            super.mount(instance);
6693        }
6694    }
6695
6696    function createDOMVisualElement(element) {
6697        const options = {
6698            presenceContext: null,
6699            props: {},
6700            visualState: {
6701                renderState: {
6702                    transform: {},
6703                    transformOrigin: {},
6704                    style: {},
6705                    vars: {},
6706                    attrs: {},
6707                },
6708                latestValues: {},
6709            },
6710        };
6711        const node = isSVGElement(element) && !isSVGSVGElement(element)
6712            ? new SVGVisualElement(options)
6713            : new HTMLVisualElement(options);
6714        node.mount(element);
6715        visualElementStore.set(element, node);
6716    }
6717    function createObjectVisualElement(subject) {
6718        const options = {
6719            presenceContext: null,
6720            props: {},
6721            visualState: {
6722                renderState: {
6723                    output: {},
6724                },
6725                latestValues: {},
6726            },
6727        };
6728        const node = new ObjectVisualElement(options);
6729        node.mount(subject);
6730        visualElementStore.set(subject, node);
6731    }
6732
6733    function animateSingleValue(value, keyframes, options) {
6734        const motionValue$1 = isMotionValue(value) ? value : motionValue(value);
6735        motionValue$1.start(animateMotionValue("", motionValue$1, keyframes, options));
6736        return motionValue$1.animation;
6737    }
6738
6739    function isSingleValue(subject, keyframes) {
6740        return (isMotionValue(subject) ||
6741            typeof subject === "number" ||
6742            (typeof subject === "string" && !isDOMKeyframes(keyframes)));
6743    }
6744    /**
6745     * Implementation
6746     */
6747    function animateSubject(subject, keyframes, options, scope) {
6748        const animations = [];
6749        if (isSingleValue(subject, keyframes)) {
6750            animations.push(animateSingleValue(subject, isDOMKeyframes(keyframes)
6751                ? keyframes.default || keyframes
6752                : keyframes, options ? options.default || options : options));
6753        }
6754        else {
6755            const subjects = resolveSubjects(subject, keyframes, scope);
6756            const numSubjects = subjects.length;
6757            exports.invariant(Boolean(numSubjects), "No valid elements provided.", "no-valid-elements");
6758            for (let i = 0; i < numSubjects; i++) {
6759                const thisSubject = subjects[i];
6760                exports.invariant(thisSubject !== null, "You're trying to perform an animation on null. Ensure that selectors are correctly finding elements and refs are correctly hydrated.", "animate-null");
6761                const createVisualElement = thisSubject instanceof Element
6762                    ? createDOMVisualElement
6763                    : createObjectVisualElement;
6764                if (!visualElementStore.has(thisSubject)) {
6765                    createVisualElement(thisSubject);
6766                }
6767                const visualElement = visualElementStore.get(thisSubject);
6768                const transition = { ...options };
6769                /**
6770                 * Resolve stagger function if provided.
6771                 */
6772                if ("delay" in transition &&
6773                    typeof transition.delay === "function") {
6774                    transition.delay = transition.delay(i, numSubjects);
6775                }
6776                animations.push(...animateTarget(visualElement, { ...keyframes, transition }, {}));
6777            }
6778        }
6779        return animations;
6780    }
6781
6782    function animateSequence(sequence, options, scope) {
6783        const animations = [];
6784        const animationDefinitions = createAnimationsFromSequence(sequence, options, scope, { spring });
6785        animationDefinitions.forEach(({ keyframes, transition }, subject) => {
6786            animations.push(...animateSubject(subject, keyframes, transition));
6787        });
6788        return animations;
6789    }
6790
6791    function isSequence(value) {
6792        return Array.isArray(value) && value.some(Array.isArray);
6793    }
6794    /**
6795     * Creates an animation function that is optionally scoped
6796     * to a specific element.
6797     */
6798    function createScopedAnimate(scope) {
6799        /**
6800         * Implementation
6801         */
6802        function scopedAnimate(subjectOrSequence, optionsOrKeyframes, options) {
6803            let animations = [];
6804            let animationOnComplete;
6805            if (isSequence(subjectOrSequence)) {
6806                animations = animateSequence(subjectOrSequence, optionsOrKeyframes, scope);
6807            }
6808            else {
6809                // Extract top-level onComplete so it doesn't get applied per-value
6810                const { onComplete, ...rest } = options || {};
6811                if (typeof onComplete === "function") {
6812                    animationOnComplete = onComplete;
6813                }
6814                animations = animateSubject(subjectOrSequence, optionsOrKeyframes, rest, scope);
6815            }
6816            const animation = new GroupAnimationWithThen(animations);
6817            if (animationOnComplete) {
6818                animation.finished.then(animationOnComplete);
6819            }
6820            if (scope) {
6821                scope.animations.push(animation);
6822                animation.finished.then(() => {
6823                    removeItem(scope.animations, animation);
6824                });
6825            }
6826            return animation;
6827        }
6828        return scopedAnimate;
6829    }
6830    const animate = createScopedAnimate();
6831
6832    function animateElements(elementOrSelector, keyframes, options, scope) {
6833        const elements = resolveElements(elementOrSelector, scope);
6834        const numElements = elements.length;
6835        exports.invariant(Boolean(numElements), "No valid elements provided.", "no-valid-elements");
6836        /**
6837         * WAAPI doesn't support interrupting animations.
6838         *
6839         * Therefore, starting animations requires a three-step process:
6840         * 1. Stop existing animations (write styles to DOM)
6841         * 2. Resolve keyframes (read styles from DOM)
6842         * 3. Create new animations (write styles to DOM)
6843         *
6844         * The hybrid `animate()` function uses AsyncAnimation to resolve
6845         * keyframes before creating new animations, which removes style
6846         * thrashing. Here, we have much stricter filesize constraints.
6847         * Therefore we do this in a synchronous way that ensures that
6848         * at least within `animate()` calls there is no style thrashing.
6849         *
6850         * In the motion-native-animate-mini-interrupt benchmark this
6851         * was 80% faster than a single loop.
6852         */
6853        const animationDefinitions = [];
6854        /**
6855         * Step 1: Build options and stop existing animations (write)
6856         */
6857        for (let i = 0; i < numElements; i++) {
6858            const element = elements[i];
6859            const elementTransition = { ...options };
6860            /**
6861             * Resolve stagger function if provided.
6862             */
6863            if (typeof elementTransition.delay === "function") {
6864                elementTransition.delay = elementTransition.delay(i, numElements);
6865            }
6866            for (const valueName in keyframes) {
6867                let valueKeyframes = keyframes[valueName];
6868                if (!Array.isArray(valueKeyframes)) {
6869                    valueKeyframes = [valueKeyframes];
6870                }
6871                const valueOptions = {
6872                    ...getValueTransition$1(elementTransition, valueName),
6873                };
6874                valueOptions.duration && (valueOptions.duration = secondsToMilliseconds(valueOptions.duration));
6875                valueOptions.delay && (valueOptions.delay = secondsToMilliseconds(valueOptions.delay));
6876                /**
6877                 * If there's an existing animation playing on this element then stop it
6878                 * before creating a new one.
6879                 */
6880                const map = getAnimationMap(element);
vendor: 10,918 bytes, lines 6881-7168
6881                const key = animationMapKey(valueName, valueOptions.pseudoElement || "");
6882                const currentAnimation = map.get(key);
6883                currentAnimation && currentAnimation.stop();
6884                animationDefinitions.push({
6885                    map,
6886                    key,
6887                    unresolvedKeyframes: valueKeyframes,
6888                    options: {
6889                        ...valueOptions,
6890                        element,
6891                        name: valueName,
6892                        allowFlatten: !elementTransition.type && !elementTransition.ease,
6893                    },
6894                });
6895            }
6896        }
6897        /**
6898         * Step 2: Resolve keyframes (read)
6899         */
6900        for (let i = 0; i < animationDefinitions.length; i++) {
6901            const { unresolvedKeyframes, options: animationOptions } = animationDefinitions[i];
6902            const { element, name, pseudoElement } = animationOptions;
6903            if (!pseudoElement && unresolvedKeyframes[0] === null) {
6904                unresolvedKeyframes[0] = getComputedStyle$2(element, name);
6905            }
6906            fillWildcards(unresolvedKeyframes);
6907            applyPxDefaults(unresolvedKeyframes, name);
6908            /**
6909             * If we only have one keyframe, explicitly read the initial keyframe
6910             * from the computed style. This is to ensure consistency with WAAPI behaviour
6911             * for restarting animations, for instance .play() after finish, when it
6912             * has one vs two keyframes.
6913             */
6914            if (!pseudoElement && unresolvedKeyframes.length < 2) {
6915                unresolvedKeyframes.unshift(getComputedStyle$2(element, name));
6916            }
6917            animationOptions.keyframes = unresolvedKeyframes;
6918        }
6919        /**
6920         * Step 3: Create new animations (write)
6921         */
6922        const animations = [];
6923        for (let i = 0; i < animationDefinitions.length; i++) {
6924            const { map, key, options: animationOptions } = animationDefinitions[i];
6925            const animation = new NativeAnimation(animationOptions);
6926            map.set(key, animation);
6927            animation.finished.finally(() => map.delete(key));
6928            animations.push(animation);
6929        }
6930        return animations;
6931    }
6932
6933    const createScopedWaapiAnimate = (scope) => {
6934        function scopedAnimate(elementOrSelector, keyframes, options) {
6935            return new GroupAnimationWithThen(animateElements(elementOrSelector, keyframes, options, scope));
6936        }
6937        return scopedAnimate;
6938    };
6939    const animateMini = /*@__PURE__*/ createScopedWaapiAnimate();
6940
6941    /**
6942     * A time in milliseconds, beyond which we consider the scroll velocity to be 0.
6943     */
6944    const maxElapsed = 50;
6945    const createAxisInfo = () => ({
6946        current: 0,
6947        offset: [],
6948        progress: 0,
6949        scrollLength: 0,
6950        targetOffset: 0,
6951        targetLength: 0,
6952        containerLength: 0,
6953        velocity: 0,
6954    });
6955    const createScrollInfo = () => ({
6956        time: 0,
6957        x: createAxisInfo(),
6958        y: createAxisInfo(),
6959    });
6960    const keys = {
6961        x: {
6962            length: "Width",
6963            position: "Left",
6964        },
6965        y: {
6966            length: "Height",
6967            position: "Top",
6968        },
6969    };
6970    function updateAxisInfo(element, axisName, info, time) {
6971        const axis = info[axisName];
6972        const { length, position } = keys[axisName];
6973        const prev = axis.current;
6974        const prevTime = info.time;
6975        axis.current = element[`scroll${position}`];
6976        axis.scrollLength = element[`scroll${length}`] - element[`client${length}`];
6977        axis.offset.length = 0;
6978        axis.offset[0] = 0;
6979        axis.offset[1] = axis.scrollLength;
6980        axis.progress = progress(0, axis.scrollLength, axis.current);
6981        const elapsed = time - prevTime;
6982        axis.velocity =
6983            elapsed > maxElapsed
6984                ? 0
6985                : velocityPerSecond(axis.current - prev, elapsed);
6986    }
6987    function updateScrollInfo(element, info, time) {
6988        updateAxisInfo(element, "x", info, time);
6989        updateAxisInfo(element, "y", info, time);
6990        info.time = time;
6991    }
6992
6993    function calcInset(element, container) {
6994        const inset = { x: 0, y: 0 };
6995        let current = element;
6996        while (current && current !== container) {
6997            if (isHTMLElement(current)) {
6998                inset.x += current.offsetLeft;
6999                inset.y += current.offsetTop;
7000                current = current.offsetParent;
7001            }
7002            else if (current.tagName === "svg") {
7003                /**
7004                 * This isn't an ideal approach to measuring the offset of <svg /> tags.
7005                 * It would be preferable, given they behave like HTMLElements in most ways
7006                 * to use offsetLeft/Top. But these don't exist on <svg />. Likewise we
7007                 * can't use .getBBox() like most SVG elements as these provide the offset
7008                 * relative to the SVG itself, which for <svg /> is usually 0x0.
7009                 */
7010                const svgBoundingBox = current.getBoundingClientRect();
7011                current = current.parentElement;
7012                const parentBoundingBox = current.getBoundingClientRect();
7013                inset.x += svgBoundingBox.left - parentBoundingBox.left;
7014                inset.y += svgBoundingBox.top - parentBoundingBox.top;
7015            }
7016            else if (current instanceof SVGGraphicsElement) {
7017                const { x, y } = current.getBBox();
7018                inset.x += x;
7019                inset.y += y;
7020                let svg = null;
7021                let parent = current.parentNode;
7022                while (!svg) {
7023                    if (parent.tagName === "svg") {
7024                        svg = parent;
7025                    }
7026                    parent = current.parentNode;
7027                }
7028                current = svg;
7029            }
7030            else {
7031                break;
7032            }
7033        }
7034        return inset;
7035    }
7036
7037    const namedEdges = {
7038        start: 0,
7039        center: 0.5,
7040        end: 1,
7041    };
7042    function resolveEdge(edge, length, inset = 0) {
7043        let delta = 0;
7044        /**
7045         * If we have this edge defined as a preset, replace the definition
7046         * with the numerical value.
7047         */
7048        if (edge in namedEdges) {
7049            edge = namedEdges[edge];
7050        }
7051        /**
7052         * Handle unit values
7053         */
7054        if (typeof edge === "string") {
7055            const asNumber = parseFloat(edge);
7056            if (edge.endsWith("px")) {
7057                delta = asNumber;
7058            }
7059            else if (edge.endsWith("%")) {
7060                edge = asNumber / 100;
7061            }
7062            else if (edge.endsWith("vw")) {
7063                delta = (asNumber / 100) * document.documentElement.clientWidth;
7064            }
7065            else if (edge.endsWith("vh")) {
7066                delta = (asNumber / 100) * document.documentElement.clientHeight;
7067            }
7068            else {
7069                edge = asNumber;
7070            }
7071        }
7072        /**
7073         * If the edge is defined as a number, handle as a progress value.
7074         */
7075        if (typeof edge === "number") {
7076            delta = length * edge;
7077        }
7078        return inset + delta;
7079    }
7080
7081    const defaultOffset = [0, 0];
7082    function resolveOffset(offset, containerLength, targetLength, targetInset) {
7083        let offsetDefinition = Array.isArray(offset) ? offset : defaultOffset;
7084        let targetPoint = 0;
7085        let containerPoint = 0;
7086        if (typeof offset === "number") {
7087            /**
7088             * If we're provided offset: [0, 0.5, 1] then each number x should become
7089             * [x, x], so we default to the behaviour of mapping 0 => 0 of both target
7090             * and container etc.
7091             */
7092            offsetDefinition = [offset, offset];
7093        }
7094        else if (typeof offset === "string") {
7095            offset = offset.trim();
7096            if (offset.includes(" ")) {
7097                offsetDefinition = offset.split(" ");
7098            }
7099            else {
7100                /**
7101                 * If we're provided a definition like "100px" then we want to apply
7102                 * that only to the top of the target point, leaving the container at 0.
7103                 * Whereas a named offset like "end" should be applied to both.
7104                 */
7105                offsetDefinition = [offset, namedEdges[offset] ? offset : `0`];
7106            }
7107        }
7108        targetPoint = resolveEdge(offsetDefinition[0], targetLength, targetInset);
7109        containerPoint = resolveEdge(offsetDefinition[1], containerLength);
7110        return targetPoint - containerPoint;
7111    }
7112
7113    const ScrollOffset = {
7114        Enter: [
7115            [0, 1],
7116            [1, 1],
7117        ],
7118        Exit: [
7119            [0, 0],
7120            [1, 0],
7121        ],
7122        Any: [
7123            [1, 0],
7124            [0, 1],
7125        ],
7126        All: [
7127            [0, 0],
7128            [1, 1],
7129        ],
7130    };
7131
7132    const point = { x: 0, y: 0 };
7133    function getTargetSize(target) {
7134        return "getBBox" in target && target.tagName !== "svg"
7135            ? target.getBBox()
7136            : { width: target.clientWidth, height: target.clientHeight };
7137    }
7138    function resolveOffsets(container, info, options) {
7139        const { offset: offsetDefinition = ScrollOffset.All } = options;
7140        const { target = container, axis = "y" } = options;
7141        const lengthLabel = axis === "y" ? "height" : "width";
7142        const inset = target !== container ? calcInset(target, container) : point;
7143        /**
7144         * Measure the target and container. If they're the same thing then we
7145         * use the container's scrollWidth/Height as the target, from there
7146         * all other calculations can remain the same.
7147         */
7148        const targetSize = target === container
7149            ? { width: container.scrollWidth, height: container.scrollHeight }
7150            : getTargetSize(target);
7151        const containerSize = {
7152            width: container.clientWidth,
7153            height: container.clientHeight,
7154        };
7155        /**
7156         * Reset the length of the resolved offset array rather than creating a new one.
7157         * TODO: More reusable data structures for targetSize/containerSize would also be good.
7158         */
7159        info[axis].offset.length = 0;
7160        /**
7161         * Populate the offset array by resolving the user's offset definition into
7162         * a list of pixel scroll offets.
7163         */
7164        let hasChanged = !info[axis].interpolate;
7165        const numOffsets = offsetDefinition.length;
7166        for (let i = 0; i < numOffsets; i++) {
7167            const offset = resolveOffset(offsetDefinition[i], containerSize[lengthLabel], targetSize[lengthLabel], inset[axis]);
7168            if (!hasChanged && offset !== info[axis].interpolatorOff
vendor: 8,356 bytes, lines 7168-7375
7168sets[i]) {
7169                hasChanged = true;
7170            }
7171            info[axis].offset[i] = offset;
7172        }
7173        /**
7174         * If the pixel scroll offsets have changed, create a new interpolator function
7175         * to map scroll value into a progress.
7176         */
7177        if (hasChanged) {
7178            info[axis].interpolate = interpolate(info[axis].offset, defaultOffset$1(offsetDefinition), { clamp: false });
7179            info[axis].interpolatorOffsets = [...info[axis].offset];
7180        }
7181        info[axis].progress = clamp(0, 1, info[axis].interpolate(info[axis].current));
7182    }
7183
7184    function measure(container, target = container, info) {
7185        /**
7186         * Find inset of target within scrollable container
7187         */
7188        info.x.targetOffset = 0;
7189        info.y.targetOffset = 0;
7190        if (target !== container) {
7191            let node = target;
7192            while (node && node !== container) {
7193                info.x.targetOffset += node.offsetLeft;
7194                info.y.targetOffset += node.offsetTop;
7195                node = node.offsetParent;
7196            }
7197        }
7198        info.x.targetLength =
7199            target === container ? target.scrollWidth : target.clientWidth;
7200        info.y.targetLength =
7201            target === container ? target.scrollHeight : target.clientHeight;
7202        info.x.containerLength = container.clientWidth;
7203        info.y.containerLength = container.clientHeight;
7204        /**
7205         * In development mode ensure scroll containers aren't position: static as this makes
7206         * it difficult to measure their relative positions.
7207         */
7208        {
7209            if (container && target && target !== container) {
7210                warnOnce(getComputedStyle(container).position !== "static", "Please ensure that the container has a non-static position, like 'relative', 'fixed', or 'absolute' to ensure scroll offset is calculated correctly.");
7211            }
7212        }
7213    }
7214    function createOnScrollHandler(element, onScroll, info, options = {}) {
7215        return {
7216            measure: (time) => {
7217                measure(element, options.target, info);
7218                updateScrollInfo(element, info, time);
7219                if (options.offset || options.target) {
7220                    resolveOffsets(element, info, options);
7221                }
7222            },
7223            notify: () => onScroll(info),
7224        };
7225    }
7226
7227    const scrollListeners = new WeakMap();
7228    const resizeListeners = new WeakMap();
7229    const onScrollHandlers = new WeakMap();
7230    const getEventTarget = (element) => element === document.scrollingElement ? window : element;
7231    function scrollInfo(onScroll, { container = document.scrollingElement, ...options } = {}) {
7232        if (!container)
7233            return noop;
7234        let containerHandlers = onScrollHandlers.get(container);
7235        /**
7236         * Get the onScroll handlers for this container.
7237         * If one isn't found, create a new one.
7238         */
7239        if (!containerHandlers) {
7240            containerHandlers = new Set();
7241            onScrollHandlers.set(container, containerHandlers);
7242        }
7243        /**
7244         * Create a new onScroll handler for the provided callback.
7245         */
7246        const info = createScrollInfo();
7247        const containerHandler = createOnScrollHandler(container, onScroll, info, options);
7248        containerHandlers.add(containerHandler);
7249        /**
7250         * Check if there's a scroll event listener for this container.
7251         * If not, create one.
7252         */
7253        if (!scrollListeners.has(container)) {
7254            const measureAll = () => {
7255                for (const handler of containerHandlers) {
7256                    handler.measure(frameData.timestamp);
7257                }
7258                frame.preUpdate(notifyAll);
7259            };
7260            const notifyAll = () => {
7261                for (const handler of containerHandlers) {
7262                    handler.notify();
7263                }
7264            };
7265            const listener = () => frame.read(measureAll);
7266            scrollListeners.set(container, listener);
7267            const target = getEventTarget(container);
7268            window.addEventListener("resize", listener, { passive: true });
7269            if (container !== document.documentElement) {
7270                resizeListeners.set(container, resize(container, listener));
7271            }
7272            target.addEventListener("scroll", listener, { passive: true });
7273            listener();
7274        }
7275        const listener = scrollListeners.get(container);
7276        frame.read(listener, false, true);
7277        return () => {
7278            cancelFrame(listener);
7279            /**
7280             * Check if we even have any handlers for this container.
7281             */
7282            const currentHandlers = onScrollHandlers.get(container);
7283            if (!currentHandlers)
7284                return;
7285            currentHandlers.delete(containerHandler);
7286            if (currentHandlers.size)
7287                return;
7288            /**
7289             * If no more handlers, remove the scroll listener too.
7290             */
7291            const scrollListener = scrollListeners.get(container);
7292            scrollListeners.delete(container);
7293            if (scrollListener) {
7294                getEventTarget(container).removeEventListener("scroll", scrollListener);
7295                resizeListeners.get(container)?.();
7296                window.removeEventListener("resize", scrollListener);
7297            }
7298        };
7299    }
7300
7301    const timelineCache = new Map();
7302    function scrollTimelineFallback(options) {
7303        const currentTime = { value: 0 };
7304        const cancel = scrollInfo((info) => {
7305            currentTime.value = info[options.axis].progress * 100;
7306        }, options);
7307        return { currentTime, cancel };
7308    }
7309    function getTimeline({ source, container, ...options }) {
7310        const { axis } = options;
7311        if (source)
7312            container = source;
7313        const containerCache = timelineCache.get(container) ?? new Map();
7314        timelineCache.set(container, containerCache);
7315        const targetKey = options.target ?? "self";
7316        const targetCache = containerCache.get(targetKey) ?? {};
7317        const axisKey = axis + (options.offset ?? []).join(",");
7318        if (!targetCache[axisKey]) {
7319            targetCache[axisKey] =
7320                !options.target && supportsScrollTimeline()
7321                    ? new ScrollTimeline({ source: container, axis })
7322                    : scrollTimelineFallback({ container, ...options });
7323        }
7324        return targetCache[axisKey];
7325    }
7326
7327    function attachToAnimation(animation, options) {
7328        const timeline = getTimeline(options);
7329        return animation.attachTimeline({
7330            timeline: options.target ? undefined : timeline,
7331            observe: (valueAnimation) => {
7332                valueAnimation.pause();
7333                return observeTimeline((progress) => {
7334                    valueAnimation.time =
7335                        valueAnimation.iterationDuration * progress;
7336                }, timeline);
7337            },
7338        });
7339    }
7340
7341    /**
7342     * If the onScroll function has two arguments, it's expecting
7343     * more specific information about the scroll from scrollInfo.
7344     */
7345    function isOnScrollWithInfo(onScroll) {
7346        return onScroll.length === 2;
7347    }
7348    function attachToFunction(onScroll, options) {
7349        if (isOnScrollWithInfo(onScroll)) {
7350            return scrollInfo((info) => {
7351                onScroll(info[options.axis].progress, info);
7352            }, options);
7353        }
7354        else {
7355            return observeTimeline(onScroll, getTimeline(options));
7356        }
7357    }
7358
7359    function scroll(onScroll, { axis = "y", container = document.scrollingElement, ...options } = {}) {
7360        if (!container)
7361            return noop;
7362        const optionsWithDefaults = { axis, container, ...options };
7363        return typeof onScroll === "function"
7364            ? attachToFunction(onScroll, optionsWithDefaults)
7365            : attachToAnimation(onScroll, optionsWithDefaults);
7366    }
7367
7368    const thresholds = {
7369        some: 0,
7370        all: 1,
7371    };
7372    function inView(elementOrSelector, onStart, { root, margin: rootMargin, amount = "some" } = {}) {
7373        const elements = resolveElements(elementOrSelector);
7374        const activeIntersections = new WeakMap();
7375        const onIntersectionChange = (entries) => {
vendor: 4,586 bytes, lines 7376-7489
7376            entries.forEach((entry) => {
7377                const onEnd = activeIntersections.get(entry.target);
7378                /**
7379                 * If there's no change to the intersection, we don't need to
7380                 * do anything here.
7381                 */
7382                if (entry.isIntersecting === Boolean(onEnd))
7383                    return;
7384                if (entry.isIntersecting) {
7385                    const newOnEnd = onStart(entry.target, entry);
7386                    if (typeof newOnEnd === "function") {
7387                        activeIntersections.set(entry.target, newOnEnd);
7388                    }
7389                    else {
7390                        observer.unobserve(entry.target);
7391                    }
7392                }
7393                else if (typeof onEnd === "function") {
7394                    onEnd(entry);
7395                    activeIntersections.delete(entry.target);
7396                }
7397            });
7398        };
7399        const observer = new IntersectionObserver(onIntersectionChange, {
7400            root,
7401            rootMargin,
7402            threshold: typeof amount === "number" ? amount : thresholds[amount],
7403        });
7404        elements.forEach((element) => observer.observe(element));
7405        return () => observer.disconnect();
7406    }
7407
7408    /**
7409     * Timeout defined in ms
7410     */
7411    function delay(callback, timeout) {
7412        const start = time.now();
7413        const checkElapsed = ({ timestamp }) => {
7414            const elapsed = timestamp - start;
7415            if (elapsed >= timeout) {
7416                cancelFrame(checkElapsed);
7417                callback(elapsed - timeout);
7418            }
7419        };
7420        frame.setup(checkElapsed, true);
7421        return () => cancelFrame(checkElapsed);
7422    }
7423    function delayInSeconds(callback, timeout) {
7424        return delay(callback, secondsToMilliseconds(timeout));
7425    }
7426
7427    const distance = (a, b) => Math.abs(a - b);
7428    function distance2D(a, b) {
7429        // Multi-dimensional
7430        const xDelta = distance(a.x, b.x);
7431        const yDelta = distance(a.y, b.y);
7432        return Math.sqrt(xDelta ** 2 + yDelta ** 2);
7433    }
7434
7435    exports.AsyncMotionValueAnimation = AsyncMotionValueAnimation;
7436    exports.DOMKeyframesResolver = DOMKeyframesResolver;
7437    exports.GroupAnimation = GroupAnimation;
7438    exports.GroupAnimationWithThen = GroupAnimationWithThen;
7439    exports.JSAnimation = JSAnimation;
7440    exports.KeyframeResolver = KeyframeResolver;
7441    exports.MotionGlobalConfig = MotionGlobalConfig;
7442    exports.MotionValue = MotionValue;
7443    exports.NativeAnimation = NativeAnimation;
7444    exports.NativeAnimationExtended = NativeAnimationExtended;
7445    exports.NativeAnimationWrapper = NativeAnimationWrapper;
7446    exports.SubscriptionManager = SubscriptionManager;
7447    exports.ViewTransitionBuilder = ViewTransitionBuilder;
7448    exports.acceleratedValues = acceleratedValues;
7449    exports.activeAnimations = activeAnimations;
7450    exports.addAttrValue = addAttrValue;
7451    exports.addStyleValue = addStyleValue;
7452    exports.addUniqueItem = addUniqueItem;
7453    exports.alpha = alpha;
7454    exports.analyseComplexValue = analyseComplexValue;
7455    exports.animate = animate;
7456    exports.animateMini = animateMini;
7457    exports.animateValue = animateValue;
7458    exports.animateView = animateView;
7459    exports.animationMapKey = animationMapKey;
7460    exports.anticipate = anticipate;
7461    exports.applyGeneratorOptions = applyGeneratorOptions;
7462    exports.applyPxDefaults = applyPxDefaults;
7463    exports.attachSpring = attachSpring;
7464    exports.attrEffect = attrEffect;
7465    exports.backIn = backIn;
7466    exports.backInOut = backInOut;
7467    exports.backOut = backOut;
7468    exports.calcGeneratorDuration = calcGeneratorDuration;
7469    exports.cancelFrame = cancelFrame;
7470    exports.cancelMicrotask = cancelMicrotask;
7471    exports.cancelSync = cancelSync;
7472    exports.circIn = circIn;
7473    exports.circInOut = circInOut;
7474    exports.circOut = circOut;
7475    exports.clamp = clamp;
7476    exports.collectMotionValues = collectMotionValues;
7477    exports.color = color;
7478    exports.complex = complex;
7479    exports.convertOffsetToTimes = convertOffsetToTimes;
7480    exports.createGeneratorEasing = createGeneratorEasing;
7481    exports.createRenderBatcher = createRenderBatcher;
7482    exports.createScopedAnimate = createScopedAnimate;
7483    exports.cubicBezier = cubicBezier;
7484    exports.cubicBezierAsString = cubicBezierAsString;
7485    exports.defaultEasing = defaultEasing;
7486    exports.defaultOffset = defaultOffset$1;
7487    exports.defaultTransformValue = defaultTransformValue;
7488    exports.defaultValueTypes = defaultValueTypes;
7489    exports.degrees = degrees;
7490    exports.delay = delayInSeconds;
7491    exports.dimensionValueTypes = dimensionValueTypes;
7492    exports.distance = distance;
7493    exports.distance2D = distance2D;
7494    exports.easeIn = easeIn;
7495    exports.easeInOut = easeInOut;
7496    exports.easeOut = easeOut;
7497    exports.easingDefinitionToFunction = easingDefinitionToFunction;
7498    exports.fillOffset = fillOffset;
7499    exports.fillWildcards = fillWildcards;
7500    exports.findDimensionValueType = findDimensionValueType;
7501    exports.findValueType = findValueType;
7502    exports.flushKeyframeResolvers = flushKeyframeResolvers;
7503    exports.frame = frame;
7504    exports.frameData = frameData;
7505    exports.frameSteps = frameSteps;
7506    exports.generateLinearEasing = generateLinearEasing;
7507    exports.getAnimatableNone = getAnimatableNone;
7508    exports.getAnimationMap = getAnimationMap;
7509    exports.getComputedStyle = getComputedStyle$2;
7510    exports.getDefaultValueType = getDefaultValueType;
7511    exports.getEasingForSegment = getEasingForSegment;
7512    exports.getMixer = getMixer;
7513    exports.getOriginIndex = getOriginIndex;
7514    exports.getValueAsType = getValueAsType;
7515    exports.getValueTransition = getValueTransition$1;
7516    exports.getVariableValue = getVariableValue;
7517    exports.getViewAnimationLayerInfo = getViewAnimationLayerInfo;
7518    exports.getViewAnimations = getViewAnimations;
7519    exports.hasWarned = hasWarned;
7520    exports.hex = hex;
7521    exports.hover = hover;
7522    exports.hsla = hsla;
7523    exports.hslaToRgba = hslaToRgba;
7524    exports.inView = inView;
7525    exports.inertia = inertia;
7526    exports.interpolate = interpolate;
7527    exports.invisibleValues = invisibleValues;
7528    exports.isBezierDefinition = isBezierDefinition;
7529    exports.isCSSVariableName = isCSSVariableName;
7530    exports.isCSSVariableToken = isCSSVariableToken;
7531    exports.isDragActive = isDragActive;
7532    exports.isDragging = isDragging;
7533    exports.isEasingArray = isEasingArray;
7534    exports.isGenerator = isGenerator;
7535    exports.isHTMLElement = isHTMLElement;
7536    exports.isMotionValue = isMotionValue;
7537    exports.isNodeOrChild = isNodeOrChild;
7538    exports.isNumericalString = isNumericalString;
7539    exports.isObject = isObject;
7540    exports.isPrimaryPointer = isPrimaryPointer;
7541    exports.isSVGElement = isSVGElement;
7542    exports.isSVGSVGElement = isSVGSVGElement;
7543    exports.isWaapiSupportedEasing = isWaapiSupportedEasing;
7544    exports.isZeroValueString = isZeroValueString;
7545    exports.keyframes = keyframes;
7546    exports.makeAnimationInstant = makeAnimationInstant;
7547    exports.mapEasingToNativeEasing = mapEasingToNativeEasing;
7548    exports.mapValue = mapValue;
7549    exports.maxGeneratorDuration = maxGeneratorDuration;
7550    exports.memo = memo;
7551    exports.microtask = microtask;
7552    exports.millisecondsToSeconds = millisecondsToSeconds;
7553    exports.mirrorEasing = mirrorEasing;
7554    exports.mix = mix;
7555    exports.mixArray = mixArray;
7556    exports.mixColor = mixColor;
7557    exports.mixComplex = mixComplex;
7558    exports.mixImmediate = mixImmediate;
7559    exports.mixLinearColor = mixLinearColor;
7560    exports.mixNumber = mixNumber$1;
7561    exports.mixObject = mixObject;
7562    exports.mixVisibility = mixVisibility;
7563    exports.motionValue = motionValue;
7564    exports.moveItem = moveItem;
7565    exports.noop = noop;
7566    exports.number = number;
7567    exports.numberValueTypes = numberValueTypes;
7568    exports.observeTimeline = observeTimeline;
7569    exports.parseCSSVariable = parseCSSVariable;
7570    exports.parseValueFromTransform = parseValueFromTransform;
7571    exports.percent = percent;
7572    exports.pipe = pipe;
7573    exports.positionalKeys = positionalKeys;
7574    exports.press = press;
7575    exports.progress = progress;
7576    exports.progressPercentage = progressPercentage;
7577    exports.propEffect = propEffect;
7578    exports.px = px;
7579    exports.readTransformValue = readTransformValue;
7580    exports.recordStats = recordStats;
7581    exports.removeItem = removeItem;
7582    exports.resize = resize;
7583    exports.resolveElements = resolveElements;
7584    exports.reverseEasing = reverseEasing;
7585    exports.rgbUnit = rgbUnit;
7586    exports.rgba = rgba;
7587    exports.scale = scale;
7588    exports.scroll = scroll;
7589    exports.scrollInfo = scrollInfo;
7590    exports.secondsToMilliseconds = secondsToMilliseconds;
7591    exports.setDragLock = setDragLock;
7592    exports.setStyle = setStyle;
7593    exports.spring = spring;
7594    exports.springValue = springValue;
7595    exports.stagger = stagger;
7596    exports.startWaapiAnimation = startWaapiAnimation;
7597    exports.statsBuffer = statsBuffer;
7598    exports.steps = steps;
7599    exports.styleEffect = styleEffect;
7600    exports.supportedWaapiEasing = supportedWaapiEasing;
7601    exports.supportsBrowserAnimation = supportsBrowserAnimation;
7602    exports.supportsFlags = supportsFlags;
7603    exports.supportsLinearEasing = supportsLinearEasing;
7604    exports.supportsPartialKeyframes = supportsPartialKeyframes;
7605    exports.supportsScrollTimeline = supportsScrollTimeline;
7606    exports.svgEffect = svgEffect;
7607    exports.sync = sync;
7608    exports.testValueType = testValueType;
7609    exports.time = time;
7610    exports.transform = transform;
7611    exports.transformPropOrder = transformPropOrder;
7612    exports.transformProps = transformProps;
7613    exports.transformValue = transformValue;
7614    exports.transformValueTypes = transformValueTypes;
7615    exports.velocityPerSecond = velocityPerSecond;
7616    exports.vh = vh;
7617    exports.vw = vw;
7618    exports.warnOnce = warnOnce;
7619    exports.wrap = wrap;
7620
7621}));

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.