> =>\n is.und(a) ? [] : is.arr(a) ? (a as any) : [a]\n\n/** Copy the `queue`, then iterate it after the `queue` is cleared */\nexport function flush(\n queue: Map
,\n iterator: (entry: [P, T]) => void\n): void\nexport function flush(queue: Set, iterator: (value: T) => void): void\nexport function flush(queue: any, iterator: any) {\n if (queue.size) {\n const items = Array.from(queue)\n queue.clear()\n each(items, iterator)\n }\n}\n\n/** Call every function in the queue with the same arguments. */\nexport const flushCalls = (\n queue: Set,\n ...args: Parameters\n) => flush(queue, fn => fn(...args))\n\n// For server-side rendering: https://github.com/react-spring/zustand/pull/34\n// Deno support: https://github.com/pmndrs/zustand/issues/347\n\nexport const isSSR = () =>\n typeof window === 'undefined' ||\n !window.navigator ||\n /ServerSideRendering|^Deno\\//.test(window.navigator.userAgent)\n","import { raf } from '@react-spring/rafz'\nimport * as G from './globals'\n\nexport interface OpaqueAnimation {\n idle: boolean\n priority: number\n advance(dt: number): void\n}\n\n// Animations starting on the next frame\nconst startQueue = new Set()\n\n// The animations being updated in the current frame, sorted by lowest\n// priority first. These two arrays are swapped at the end of each frame.\nlet currentFrame: OpaqueAnimation[] = []\nlet prevFrame: OpaqueAnimation[] = []\n\n// The priority of the currently advancing animation.\n// To protect against a race condition whenever a frame is being processed,\n// where the filtering of `animations` is corrupted with a shifting index,\n// causing animations to potentially advance 2x faster than intended.\nlet priority = 0\n\n/**\n * The frameloop executes its animations in order of lowest priority first.\n * Animations are retained until idle.\n */\nexport const frameLoop = {\n get idle() {\n return !startQueue.size && !currentFrame.length\n },\n\n /** Advance the given animation on every frame until idle. */\n start(animation: OpaqueAnimation) {\n // An animation can be added while a frame is being processed,\n // unless its priority is lower than the animation last updated.\n if (priority > animation.priority) {\n startQueue.add(animation)\n raf.onStart(flushStartQueue)\n } else {\n startSafely(animation)\n raf(advance)\n }\n },\n\n /** Advance all animations by the given time. */\n advance,\n\n /** Call this when an animation's priority changes. */\n sort(animation: OpaqueAnimation) {\n if (priority) {\n raf.onFrame(() => frameLoop.sort(animation))\n } else {\n const prevIndex = currentFrame.indexOf(animation)\n if (~prevIndex) {\n currentFrame.splice(prevIndex, 1)\n startUnsafely(animation)\n }\n }\n },\n\n /**\n * Clear all animations. For testing purposes.\n *\n * ā ļø Never call this from within the frameloop.\n */\n clear() {\n currentFrame = []\n startQueue.clear()\n },\n}\n\nfunction flushStartQueue() {\n startQueue.forEach(startSafely)\n startQueue.clear()\n raf(advance)\n}\n\nfunction startSafely(animation: OpaqueAnimation) {\n if (!currentFrame.includes(animation)) startUnsafely(animation)\n}\n\nfunction startUnsafely(animation: OpaqueAnimation) {\n currentFrame.splice(\n findIndex(currentFrame, other => other.priority > animation.priority),\n 0,\n animation\n )\n}\n\nfunction advance(dt: number) {\n const nextFrame = prevFrame\n\n for (let i = 0; i < currentFrame.length; i++) {\n const animation = currentFrame[i]\n priority = animation.priority\n\n // Animations may go idle before advancing.\n if (!animation.idle) {\n G.willAdvance(animation)\n animation.advance(dt)\n if (!animation.idle) {\n nextFrame.push(animation)\n }\n }\n }\n priority = 0\n\n // Reuse the `currentFrame` array to avoid garbage collection.\n prevFrame = currentFrame\n prevFrame.length = 0\n\n // Set `currentFrame` for next frame, so the `start` function\n // adds new animations to the proper array.\n currentFrame = nextFrame\n\n return currentFrame.length > 0\n}\n\n/** Like `Array.prototype.findIndex` but returns `arr.length` instead of `-1` */\nfunction findIndex(arr: T[], test: (value: T) => boolean) {\n const index = arr.findIndex(test)\n return index < 0 ? arr.length : index\n}\n","export const clamp = (min: number, max: number, v: number) =>\n Math.min(Math.max(v, min), max)\n","// const INTEGER = '[-+]?\\\\d+';\nconst NUMBER = '[-+]?\\\\d*\\\\.?\\\\d+'\nconst PERCENTAGE = NUMBER + '%'\n\nfunction call(...parts: string[]) {\n return '\\\\(\\\\s*(' + parts.join(')\\\\s*,\\\\s*(') + ')\\\\s*\\\\)'\n}\n\nexport const rgb = new RegExp('rgb' + call(NUMBER, NUMBER, NUMBER))\nexport const rgba = new RegExp('rgba' + call(NUMBER, NUMBER, NUMBER, NUMBER))\nexport const hsl = new RegExp('hsl' + call(NUMBER, PERCENTAGE, PERCENTAGE))\nexport const hsla = new RegExp(\n 'hsla' + call(NUMBER, PERCENTAGE, PERCENTAGE, NUMBER)\n)\nexport const hex3 = /^#([0-9a-fA-F]{1})([0-9a-fA-F]{1})([0-9a-fA-F]{1})$/\nexport const hex4 =\n /^#([0-9a-fA-F]{1})([0-9a-fA-F]{1})([0-9a-fA-F]{1})([0-9a-fA-F]{1})$/\nexport const hex6 = /^#([0-9a-fA-F]{6})$/\nexport const hex8 = /^#([0-9a-fA-F]{8})$/\n","/*\nhttps://github.com/react-community/normalize-css-color\n\nBSD 3-Clause License\n\nCopyright (c) 2016, React Community\nAll rights reserved.\n\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions are met:\n\n* Redistributions of source code must retain the above copyright notice, this\n list of conditions and the following disclaimer.\n\n* Redistributions in binary form must reproduce the above copyright notice,\n this list of conditions and the following disclaimer in the documentation\n and/or other materials provided with the distribution.\n\n* Neither the name of the copyright holder nor the names of its\n contributors may be used to endorse or promote products derived from\n this software without specific prior written permission.\n\nTHIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\"\nAND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\nIMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE\nDISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE\nFOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\nDAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR\nSERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER\nCAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,\nOR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\nOF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n*/\n\nimport * as matchers from './colorMatchers'\nimport * as G from './globals'\n\nexport function normalizeColor(color: number | string) {\n let match\n\n if (typeof color === 'number') {\n return color >>> 0 === color && color >= 0 && color <= 0xffffffff\n ? color\n : null\n }\n\n // Ordered based on occurrences on Facebook codebase\n if ((match = matchers.hex6.exec(color)))\n return parseInt(match[1] + 'ff', 16) >>> 0\n\n if (G.colors && G.colors[color] !== undefined) {\n return G.colors[color]\n }\n\n if ((match = matchers.rgb.exec(color))) {\n return (\n ((parse255(match[1]) << 24) | // r\n (parse255(match[2]) << 16) | // g\n (parse255(match[3]) << 8) | // b\n 0x000000ff) >>> // a\n 0\n )\n }\n\n if ((match = matchers.rgba.exec(color))) {\n return (\n ((parse255(match[1]) << 24) | // r\n (parse255(match[2]) << 16) | // g\n (parse255(match[3]) << 8) | // b\n parse1(match[4])) >>> // a\n 0\n )\n }\n\n if ((match = matchers.hex3.exec(color))) {\n return (\n parseInt(\n match[1] +\n match[1] + // r\n match[2] +\n match[2] + // g\n match[3] +\n match[3] + // b\n 'ff', // a\n 16\n ) >>> 0\n )\n }\n\n // https://drafts.csswg.org/css-color-4/#hex-notation\n if ((match = matchers.hex8.exec(color))) return parseInt(match[1], 16) >>> 0\n\n if ((match = matchers.hex4.exec(color))) {\n return (\n parseInt(\n match[1] +\n match[1] + // r\n match[2] +\n match[2] + // g\n match[3] +\n match[3] + // b\n match[4] +\n match[4], // a\n 16\n ) >>> 0\n )\n }\n\n if ((match = matchers.hsl.exec(color))) {\n return (\n (hslToRgb(\n parse360(match[1]), // h\n parsePercentage(match[2]), // s\n parsePercentage(match[3]) // l\n ) |\n 0x000000ff) >>> // a\n 0\n )\n }\n\n if ((match = matchers.hsla.exec(color))) {\n return (\n (hslToRgb(\n parse360(match[1]), // h\n parsePercentage(match[2]), // s\n parsePercentage(match[3]) // l\n ) |\n parse1(match[4])) >>> // a\n 0\n )\n }\n return null\n}\n\nfunction hue2rgb(p: number, q: number, t: number) {\n if (t < 0) t += 1\n if (t > 1) t -= 1\n if (t < 1 / 6) return p + (q - p) * 6 * t\n if (t < 1 / 2) return q\n if (t < 2 / 3) return p + (q - p) * (2 / 3 - t) * 6\n return p\n}\n\nfunction hslToRgb(h: number, s: number, l: number) {\n const q = l < 0.5 ? l * (1 + s) : l + s - l * s\n const p = 2 * l - q\n const r = hue2rgb(p, q, h + 1 / 3)\n const g = hue2rgb(p, q, h)\n const b = hue2rgb(p, q, h - 1 / 3)\n return (\n (Math.round(r * 255) << 24) |\n (Math.round(g * 255) << 16) |\n (Math.round(b * 255) << 8)\n )\n}\n\nfunction parse255(str: string) {\n const int = parseInt(str, 10)\n if (int < 0) return 0\n if (int > 255) return 255\n return int\n}\n\nfunction parse360(str: string) {\n const int = parseFloat(str)\n return (((int % 360) + 360) % 360) / 360\n}\n\nfunction parse1(str: string) {\n const num = parseFloat(str)\n if (num < 0) return 0\n if (num > 1) return 255\n return Math.round(num * 255)\n}\n\nfunction parsePercentage(str: string) {\n // parseFloat conveniently ignores the final %\n const int = parseFloat(str)\n if (int < 0) return 0\n if (int > 100) return 1\n return int / 100\n}\n","import { normalizeColor } from './normalizeColor'\n\nexport function colorToRgba(input: string) {\n let int32Color = normalizeColor(input)\n if (int32Color === null) return input\n int32Color = int32Color || 0\n const r = (int32Color & 0xff000000) >>> 24\n const g = (int32Color & 0x00ff0000) >>> 16\n const b = (int32Color & 0x0000ff00) >>> 8\n const a = (int32Color & 0x000000ff) / 255\n return `rgba(${r}, ${g}, ${b}, ${a})`\n}\n","import * as G from './globals'\nimport { is } from './helpers'\nimport {\n Animatable,\n InterpolatorFn,\n EasingFunction,\n ExtrapolateType,\n InterpolatorConfig,\n InterpolatorFactory,\n} from '@react-spring/types'\n\nexport const createInterpolator: InterpolatorFactory = (\n range: readonly number[] | InterpolatorFn | InterpolatorConfig,\n output?: readonly Animatable[],\n extrapolate?: ExtrapolateType\n) => {\n if (is.fun(range)) {\n return range\n }\n\n if (is.arr(range)) {\n return createInterpolator({\n range,\n output: output!,\n extrapolate,\n })\n }\n\n if (is.str(range.output[0])) {\n return G.createStringInterpolator(range as any) as any\n }\n\n const config = range as InterpolatorConfig\n const outputRange = config.output\n const inputRange = config.range || [0, 1]\n\n const extrapolateLeft =\n config.extrapolateLeft || config.extrapolate || 'extend'\n const extrapolateRight =\n config.extrapolateRight || config.extrapolate || 'extend'\n const easing = config.easing || (t => t)\n\n return (input: number) => {\n const range = findRange(input, inputRange)\n return interpolate(\n input,\n inputRange[range],\n inputRange[range + 1],\n outputRange[range],\n outputRange[range + 1],\n easing,\n extrapolateLeft,\n extrapolateRight,\n config.map\n )\n }\n}\n\nfunction interpolate(\n input: number,\n inputMin: number,\n inputMax: number,\n outputMin: number,\n outputMax: number,\n easing: EasingFunction,\n extrapolateLeft: ExtrapolateType,\n extrapolateRight: ExtrapolateType,\n map?: (x: number) => number\n) {\n let result = map ? map(input) : input\n // Extrapolate\n if (result < inputMin) {\n if (extrapolateLeft === 'identity') return result\n else if (extrapolateLeft === 'clamp') result = inputMin\n }\n if (result > inputMax) {\n if (extrapolateRight === 'identity') return result\n else if (extrapolateRight === 'clamp') result = inputMax\n }\n if (outputMin === outputMax) return outputMin\n if (inputMin === inputMax) return input <= inputMin ? outputMin : outputMax\n // Input Range\n if (inputMin === -Infinity) result = -result\n else if (inputMax === Infinity) result = result - inputMin\n else result = (result - inputMin) / (inputMax - inputMin)\n // Easing\n result = easing(result)\n // Output Range\n if (outputMin === -Infinity) result = -result\n else if (outputMax === Infinity) result = result + outputMin\n else result = result * (outputMax - outputMin) + outputMin\n return result\n}\n\nfunction findRange(input: number, inputRange: readonly number[]) {\n // eslint-disable-next-line no-var\n for (var i = 1; i < inputRange.length - 1; ++i)\n if (inputRange[i] >= input) break\n return i - 1\n}\n","import { EasingFunction } from '@react-spring/types'\n\nimport { clamp } from './clamp'\n\nexport type Direction = 'start' | 'end'\n\ntype StepsEasing = (steps: number, direction?: Direction) => EasingFunction\n\nconst steps: StepsEasing =\n (steps: number, direction: Direction = 'end') =>\n (progress: number) => {\n progress =\n direction === 'end'\n ? Math.min(progress, 0.999)\n : Math.max(progress, 0.001)\n const expanded = progress * steps\n const rounded =\n direction === 'end' ? Math.floor(expanded) : Math.ceil(expanded)\n\n return clamp(0, 1, rounded / steps)\n }\n\n/**\n * With thanks to ai easings.net\n * https://github.com/ai/easings.net/blob/master/src/easings/easingsFunctions.ts\n */\ninterface EasingDictionary {\n linear: (t: number) => number\n easeInQuad: (t: number) => number\n easeOutQuad: (t: number) => number\n easeInOutQuad: (t: number) => number\n easeInCubic: (t: number) => number\n easeOutCubic: (t: number) => number\n easeInOutCubic: (t: number) => number\n easeInQuart: (t: number) => number\n easeOutQuart: (t: number) => number\n easeInOutQuart: (t: number) => number\n easeInQuint: (t: number) => number\n easeOutQuint: (t: number) => number\n easeInOutQuint: (t: number) => number\n easeInSine: (t: number) => number\n easeOutSine: (t: number) => number\n easeInOutSine: (t: number) => number\n easeInExpo: (t: number) => number\n easeOutExpo: (t: number) => number\n easeInOutExpo: (t: number) => number\n easeInCirc: (t: number) => number\n easeOutCirc: (t: number) => number\n easeInOutCirc: (t: number) => number\n easeInBack: (t: number) => number\n easeOutBack: (t: number) => number\n easeInOutBack: (t: number) => number\n easeInElastic: (t: number) => number\n easeOutElastic: (t: number) => number\n easeInOutElastic: (t: number) => number\n easeInBounce: (t: number) => number\n easeOutBounce: (t: number) => number\n easeInOutBounce: (t: number) => number\n steps: StepsEasing\n}\n\nconst c1 = 1.70158\nconst c2 = c1 * 1.525\nconst c3 = c1 + 1\nconst c4 = (2 * Math.PI) / 3\nconst c5 = (2 * Math.PI) / 4.5\n\nconst bounceOut: EasingFunction = x => {\n const n1 = 7.5625\n const d1 = 2.75\n\n if (x < 1 / d1) {\n return n1 * x * x\n } else if (x < 2 / d1) {\n return n1 * (x -= 1.5 / d1) * x + 0.75\n } else if (x < 2.5 / d1) {\n return n1 * (x -= 2.25 / d1) * x + 0.9375\n } else {\n return n1 * (x -= 2.625 / d1) * x + 0.984375\n }\n}\n\nexport const easings: EasingDictionary = {\n linear: x => x,\n easeInQuad: x => x * x,\n easeOutQuad: x => 1 - (1 - x) * (1 - x),\n easeInOutQuad: x => (x < 0.5 ? 2 * x * x : 1 - Math.pow(-2 * x + 2, 2) / 2),\n easeInCubic: x => x * x * x,\n easeOutCubic: x => 1 - Math.pow(1 - x, 3),\n easeInOutCubic: x =>\n x < 0.5 ? 4 * x * x * x : 1 - Math.pow(-2 * x + 2, 3) / 2,\n easeInQuart: x => x * x * x * x,\n easeOutQuart: x => 1 - Math.pow(1 - x, 4),\n easeInOutQuart: x =>\n x < 0.5 ? 8 * x * x * x * x : 1 - Math.pow(-2 * x + 2, 4) / 2,\n easeInQuint: x => x * x * x * x * x,\n easeOutQuint: x => 1 - Math.pow(1 - x, 5),\n easeInOutQuint: x =>\n x < 0.5 ? 16 * x * x * x * x * x : 1 - Math.pow(-2 * x + 2, 5) / 2,\n easeInSine: x => 1 - Math.cos((x * Math.PI) / 2),\n easeOutSine: x => Math.sin((x * Math.PI) / 2),\n easeInOutSine: x => -(Math.cos(Math.PI * x) - 1) / 2,\n easeInExpo: x => (x === 0 ? 0 : Math.pow(2, 10 * x - 10)),\n easeOutExpo: x => (x === 1 ? 1 : 1 - Math.pow(2, -10 * x)),\n easeInOutExpo: x =>\n x === 0\n ? 0\n : x === 1\n ? 1\n : x < 0.5\n ? Math.pow(2, 20 * x - 10) / 2\n : (2 - Math.pow(2, -20 * x + 10)) / 2,\n easeInCirc: x => 1 - Math.sqrt(1 - Math.pow(x, 2)),\n easeOutCirc: x => Math.sqrt(1 - Math.pow(x - 1, 2)),\n easeInOutCirc: x =>\n x < 0.5\n ? (1 - Math.sqrt(1 - Math.pow(2 * x, 2))) / 2\n : (Math.sqrt(1 - Math.pow(-2 * x + 2, 2)) + 1) / 2,\n easeInBack: x => c3 * x * x * x - c1 * x * x,\n easeOutBack: x => 1 + c3 * Math.pow(x - 1, 3) + c1 * Math.pow(x - 1, 2),\n easeInOutBack: x =>\n x < 0.5\n ? (Math.pow(2 * x, 2) * ((c2 + 1) * 2 * x - c2)) / 2\n : (Math.pow(2 * x - 2, 2) * ((c2 + 1) * (x * 2 - 2) + c2) + 2) / 2,\n easeInElastic: x =>\n x === 0\n ? 0\n : x === 1\n ? 1\n : -Math.pow(2, 10 * x - 10) * Math.sin((x * 10 - 10.75) * c4),\n easeOutElastic: x =>\n x === 0\n ? 0\n : x === 1\n ? 1\n : Math.pow(2, -10 * x) * Math.sin((x * 10 - 0.75) * c4) + 1,\n easeInOutElastic: x =>\n x === 0\n ? 0\n : x === 1\n ? 1\n : x < 0.5\n ? -(Math.pow(2, 20 * x - 10) * Math.sin((20 * x - 11.125) * c5)) / 2\n : (Math.pow(2, -20 * x + 10) * Math.sin((20 * x - 11.125) * c5)) / 2 + 1,\n easeInBounce: x => 1 - bounceOut(1 - x),\n easeOutBounce: bounceOut,\n easeInOutBounce: x =>\n x < 0.5 ? (1 - bounceOut(1 - 2 * x)) / 2 : (1 + bounceOut(2 * x - 1)) / 2,\n steps,\n} as const\n","/**\n * MIT License\n * Copyright (c) Alec Larson\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to deal\n * in the Software without restriction, including without limitation the rights\n * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n * copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in all\n * copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n * SOFTWARE.\n */\n\nconst $get = Symbol.for('FluidValue.get')\nconst $observers = Symbol.for('FluidValue.observers')\n\nexport {\n FluidValue,\n hasFluidValue,\n getFluidValue,\n getFluidObservers,\n callFluidObserver,\n callFluidObservers,\n // Mutations\n setFluidGetter,\n addFluidObserver,\n removeFluidObserver,\n}\n\n/** Returns true if `arg` can be observed. */\nconst hasFluidValue = (arg: any): arg is FluidValue => Boolean(arg && arg[$get])\n\n/**\n * Get the current value.\n * If `arg` is not observable, `arg` is returned.\n */\nconst getFluidValue: GetFluidValue = (arg: any) =>\n arg && arg[$get] ? arg[$get]() : arg\n\n/** Get the current observer set. Never mutate it directly! */\nconst getFluidObservers: GetFluidObservers = (target: any) =>\n target[$observers] || null\n\n/** Send an event to an observer. */\nfunction callFluidObserver(\n observer: FluidObserver,\n event: E\n): void\n\nfunction callFluidObserver(observer: any, event: FluidEvent) {\n if (observer.eventObserved) {\n observer.eventObserved(event)\n } else {\n observer(event)\n }\n}\n\n/** Send an event to all observers. */\nfunction callFluidObservers(\n target: FluidValue,\n event: E\n): void\n\nfunction callFluidObservers(target: object, event: FluidEvent): void\n\nfunction callFluidObservers(target: any, event: FluidEvent) {\n const observers: Set = target[$observers]\n if (observers) {\n observers.forEach(observer => {\n callFluidObserver(observer, event)\n })\n }\n}\n\ntype GetFluidValue = {\n (target: T | FluidValue): Exclude | U\n}\n\ntype GetFluidObservers = {\n (target: FluidValue): ReadonlySet<\n FluidObserver\n > | null\n (target: object): ReadonlySet | null\n}\n\n/** An event sent to `FluidObserver` objects. */\nexport interface FluidEvent {\n type: string\n parent: FluidValue\n}\n\n/**\n * Extend this class for automatic TypeScript support when passing this\n * value to `fluids`-compatible libraries.\n */\nabstract class FluidValue = any> {\n // @ts-expect-error (TS 4.4)\n private [$get]: () => T\n // @ts-expect-error (TS 4.4)\n private [$observers]?: Set>\n\n constructor(get?: () => T) {\n if (!get && !(get = this.get)) {\n throw Error('Unknown getter')\n }\n setFluidGetter(this, get)\n }\n\n /** Get the current value. */\n protected get?(): T\n /** Called after an observer is added. */\n protected observerAdded?(count: number, observer: FluidObserver): void\n /** Called after an observer is removed. */\n protected observerRemoved?(count: number, observer: FluidObserver): void\n}\n\n/** An observer of `FluidValue` objects. */\nexport type FluidObserver =\n | { eventObserved(event: E): void }\n | { (event: E): void }\n\n/** Add the `FluidValue` type to every property. */\nexport type FluidProps = T extends object\n ? { [P in keyof T]: T[P] | FluidValue> }\n : unknown\n\n/** Remove the `FluidValue` type from every property. */\nexport type StaticProps = {\n [P in keyof T]: T[P] extends FluidValue ? U : T[P]\n}\n\n/** Define the getter called by `getFluidValue`. */\nconst setFluidGetter = (target: object, get: () => any) =>\n setHidden(target, $get, get)\n\n/** Observe a `fluids`-compatible object. */\nfunction addFluidObserver(\n target: FluidValue,\n observer: FluidObserver\n): typeof observer\n\nfunction addFluidObserver(\n target: object,\n observer: FluidObserver\n): typeof observer\n\nfunction addFluidObserver(target: any, observer: FluidObserver) {\n if (target[$get]) {\n let observers: Set = target[$observers]\n if (!observers) {\n setHidden(target, $observers, (observers = new Set()))\n }\n if (!observers.has(observer)) {\n observers.add(observer)\n if (target.observerAdded) {\n target.observerAdded(observers.size, observer)\n }\n }\n }\n return observer\n}\n\n/** Stop observing a `fluids`-compatible object. */\nfunction removeFluidObserver(\n target: FluidValue,\n observer: FluidObserver\n): void\n\nfunction removeFluidObserver(\n target: object,\n observer: FluidObserver\n): void\n\nfunction removeFluidObserver(target: any, observer: FluidObserver) {\n const observers: Set = target[$observers]\n if (observers && observers.has(observer)) {\n const count = observers.size - 1\n if (count) {\n observers.delete(observer)\n } else {\n target[$observers] = null\n }\n if (target.observerRemoved) {\n target.observerRemoved(count, observer)\n }\n }\n}\n\nconst setHidden = (target: any, key: any, value: any) =>\n Object.defineProperty(target, key, {\n value,\n writable: true,\n configurable: true,\n })\n","import { InterpolatorConfig } from '@react-spring/types'\n\nimport { getFluidValue } from './fluids'\nimport { createInterpolator } from './createInterpolator'\nimport { colorToRgba } from './colorToRgba'\nimport * as G from './globals'\nimport {\n cssVariableRegex,\n colorRegex,\n unitRegex,\n numberRegex,\n rgbaRegex,\n} from './regexs'\nimport { variableToRgba } from './variableToRgba'\n\n// Covers color names (transparent, blue, etc.)\nlet namedColorRegex: RegExp\n\n// rgba requires that the r,g,b are integers.... so we want to round them,\n// but we *dont* want to round the opacity (4th column).\nconst rgbaRound = (_: any, p1: number, p2: number, p3: number, p4: number) =>\n `rgba(${Math.round(p1)}, ${Math.round(p2)}, ${Math.round(p3)}, ${p4})`\n\n/**\n * Supports string shapes by extracting numbers so new values can be computed,\n * and recombines those values into new strings of the same shape. Supports\n * things like:\n *\n * \"rgba(123, 42, 99, 0.36)\" // colors\n * \"-45deg\" // values with units\n * \"0 2px 2px 0px rgba(0, 0, 0, 0.12)\" // CSS box-shadows\n * \"rotate(0deg) translate(2px, 3px)\" // CSS transforms\n */\nexport const createStringInterpolator = (\n config: InterpolatorConfig\n) => {\n if (!namedColorRegex)\n namedColorRegex = G.colors\n ? // match color names, ignore partial matches\n new RegExp(`(${Object.keys(G.colors).join('|')})(?!\\\\w)`, 'g')\n : // never match\n /^\\b$/\n\n // Convert colors to rgba(...)\n const output = config.output.map(value => {\n return getFluidValue(value)\n .replace(cssVariableRegex, variableToRgba)\n .replace(colorRegex, colorToRgba)\n .replace(namedColorRegex, colorToRgba)\n })\n\n // Convert [\"1px 2px\", \"0px 0px\"] into [[1, 2], [0, 0]]\n const keyframes = output.map(value => value.match(numberRegex)!.map(Number))\n\n // Convert [\"1px 2px\", \"0px 0px\"] into [[1, 0], [2, 0]]\n const outputRanges = keyframes[0].map((_, i) =>\n keyframes.map(values => {\n if (!(i in values)) {\n throw Error('The arity of each \"output\" value must be equal')\n }\n return values[i]\n })\n )\n\n // Create an interpolator for each animated number\n const interpolators = outputRanges.map(output =>\n createInterpolator({ ...config, output })\n )\n\n // Use the first `output` as a template for each call\n return (input: number) => {\n // Convert numbers to units if available (allows for [\"0\", \"100%\"])\n const missingUnit =\n !unitRegex.test(output[0]) &&\n output.find(value => unitRegex.test(value))?.replace(numberRegex, '')\n\n let i = 0\n return output[0]\n .replace(\n numberRegex,\n () => `${interpolators[i++](input)}${missingUnit || ''}`\n )\n .replace(rgbaRegex, rgbaRound)\n }\n}\n","// Problem: https://github.com/animatedjs/animated/pull/102\n// Solution: https://stackoverflow.com/questions/638565/parsing-scientific-notation-sensibly/658662\nexport const numberRegex = /[+\\-]?(?:0|[1-9]\\d*)(?:\\.\\d*)?(?:[eE][+\\-]?\\d+)?/g\n\n// Covers rgb, rgba, hsl, hsla\n// Taken from https://gist.github.com/olmokramer/82ccce673f86db7cda5e\nexport const colorRegex =\n /(#(?:[0-9a-f]{2}){2,4}|(#[0-9a-f]{3})|(rgb|hsl)a?\\((-?\\d+%?[,\\s]+){2,3}\\s*[\\d\\.]+%?\\))/gi\n\n// Gets numbers with units when specified\nexport const unitRegex = new RegExp(`(${numberRegex.source})(%|[a-z]+)`, 'i')\n\n// get values of rgba string\nexport const rgbaRegex =\n /rgba\\(([0-9\\.-]+), ([0-9\\.-]+), ([0-9\\.-]+), ([0-9\\.-]+)\\)/gi\n\n/**\n * Parse special CSS variable format into a CSS token and a fallback.\n *\n * ```\n * `var(--foo, #fff)` => [`--foo`, '#fff']\n * ```\n *\n */\nexport const cssVariableRegex =\n /var\\((--[a-zA-Z0-9-_]+),? ?([a-zA-Z0-9 ()%#.,-]+)?\\)/\n","import { isSSR } from './helpers'\nimport { cssVariableRegex } from './regexs'\n\n/**\n * takes a CSS variable and attempts\n * to turn it into a RGBA value\n *\n * ```\n * 'var(--white)' => 'rgba(255,255,255,1)'\n * ```\n *\n * @param input string\n * @returns string\n */\nexport const variableToRgba = (input: string): string => {\n const [token, fallback] = parseCSSVariable(input)\n\n if (!token || isSSR()) {\n return input\n }\n\n const value = window\n .getComputedStyle(document.documentElement)\n .getPropertyValue(token)\n\n if (value) {\n /**\n * We have a valid variable returned\n * trim and return\n */\n return value.trim()\n } else if (fallback && fallback.startsWith('--')) {\n /**\n * fallback is something like --my-variable\n * so we try get property value\n */\n const value = window\n .getComputedStyle(document.documentElement)\n .getPropertyValue(fallback)\n\n /**\n * if it exists, return else nothing was found so just return the input\n */\n if (value) {\n return value\n } else {\n return input\n }\n } else if (fallback && cssVariableRegex.test(fallback)) {\n /**\n * We have a fallback and it's another CSS variable\n */\n return variableToRgba(fallback)\n } else if (fallback) {\n /**\n * We have a fallback and it's not a CSS variable\n */\n return fallback\n }\n\n /**\n * Nothing worked so just return the input\n * like our other FluidValue replace functions do\n */\n return input\n}\n\nconst parseCSSVariable = (current: string) => {\n const match = cssVariableRegex.exec(current)\n if (!match) return [,]\n\n const [, token, fallback] = match\n return [token, fallback]\n}\n","declare const console: any\n\nexport const prefix = 'react-spring: '\n\nexport const once = any>(fn: TFunc) => {\n const func = fn\n let called = false\n\n if (typeof func != 'function') {\n throw new TypeError(`${prefix}once requires a function parameter`)\n }\n\n return (...args: any) => {\n if (!called) {\n func(...args)\n called = true\n }\n }\n}\n\nconst warnInterpolate = once(console.warn)\nexport function deprecateInterpolate() {\n warnInterpolate(\n `${prefix}The \"interpolate\" function is deprecated in v9 (use \"to\" instead)`\n )\n}\n\nconst warnDirectCall = once(console.warn)\nexport function deprecateDirectCall() {\n warnDirectCall(\n `${prefix}Directly calling start instead of using the api object is deprecated in v9 (use \".start\" instead), this will be removed in later 0.X.0 versions`\n )\n}\n","import * as G from './globals'\nimport { is, isSSR } from './helpers'\nimport { cssVariableRegex } from './regexs'\n\n// Not all strings can be animated (eg: {display: \"none\"})\nexport function isAnimatedString(value: unknown): value is string {\n return (\n is.str(value) &&\n (value[0] == '#' ||\n /\\d/.test(value) ||\n // Do not identify a CSS variable as an AnimatedString if its SSR\n (!isSSR() && cssVariableRegex.test(value)) ||\n value in (G.colors || {}))\n )\n}\n","import { useEffect, useLayoutEffect } from 'react'\n\nimport { isSSR } from '../helpers'\n\n/**\n * Use this to read layout from the DOM and synchronously\n * re-render if the isSSR returns true. Updates scheduled\n * inside `useIsomorphicLayoutEffect` will be flushed\n * synchronously in the browser, before the browser has\n * a chance to paint.\n */\nexport const useIsomorphicLayoutEffect = isSSR() ? useEffect : useLayoutEffect\n","import { useRef } from 'react'\nimport { useIsomorphicLayoutEffect } from './useIsomorphicLayoutEffect'\n\nexport const useIsMounted = () => {\n const isMounted = useRef(false)\n useIsomorphicLayoutEffect(() => {\n isMounted.current = true\n\n return () => {\n isMounted.current = false\n }\n }, [])\n\n return isMounted\n}\n","import { useState } from 'react'\nimport { useIsMounted } from './useIsMounted'\n\n/** Return a function that re-renders this component, if still mounted */\nexport function useForceUpdate() {\n const update = useState()[1]\n const isMounted = useIsMounted()\n return () => {\n if (isMounted.current) {\n update(Math.random())\n }\n }\n}\n","/* eslint-disable react-hooks/exhaustive-deps */\nimport { useEffect, EffectCallback } from 'react'\n\nexport const useOnce = (effect: EffectCallback) => useEffect(effect, emptyDeps)\n\nconst emptyDeps: any[] = []\n","import { useEffect, useRef } from 'react'\n\n/** Use a value from the previous render */\nexport function usePrev(value: T): T | undefined {\n const prevRef = useRef()\n useEffect(() => {\n prevRef.current = value\n })\n return prevRef.current\n}\n","import { useState } from 'react'\n\nimport { assign } from '../globals'\nimport { useIsomorphicLayoutEffect } from './useIsomorphicLayoutEffect'\n\n/**\n * Returns `boolean` or `null`, used to automatically\n * set skipAnimations to the value of the user's\n * `prefers-reduced-motion` query.\n *\n * The return value, post-effect, is the value of their prefered setting\n */\nexport const useReducedMotion = () => {\n const [reducedMotion, setReducedMotion] = useState(null)\n\n useIsomorphicLayoutEffect(() => {\n const mql = window.matchMedia('(prefers-reduced-motion)')\n\n const handleMediaChange = (e: MediaQueryListEvent | MediaQueryList) => {\n setReducedMotion(e.matches)\n\n assign({\n skipAnimation: e.matches,\n })\n }\n\n handleMediaChange(mql)\n\n mql.addEventListener('change', handleMediaChange)\n\n return () => {\n mql.removeEventListener('change', handleMediaChange)\n }\n }, [])\n\n return reducedMotion\n}\n","import { defineHidden } from '@react-spring/shared'\nimport { AnimatedValue } from './AnimatedValue'\n\nconst $node: any = Symbol.for('Animated:node')\n\nexport const isAnimated = (value: any): value is Animated =>\n !!value && value[$node] === value\n\n/** Get the owner's `Animated` node. */\nexport const getAnimated = (owner: any): Animated | undefined =>\n owner && owner[$node]\n\n/** Set the owner's `Animated` node. */\nexport const setAnimated = (owner: any, node: Animated) =>\n defineHidden(owner, $node, node)\n\n/** Get every `AnimatedValue` in the owner's `Animated` node. */\nexport const getPayload = (owner: any): AnimatedValue[] | undefined =>\n owner && owner[$node] && owner[$node].getPayload()\n\nexport abstract class Animated {\n /** The cache of animated values */\n protected payload?: Payload\n\n constructor() {\n // This makes \"isAnimated\" return true.\n setAnimated(this, this)\n }\n\n /** Get the current value. Pass `true` for only animated values. */\n abstract getValue(animated?: boolean): T\n\n /** Set the current value. Returns `true` if the value changed. */\n abstract setValue(value: T): boolean | void\n\n /** Reset any animation state. */\n abstract reset(goal?: T): void\n\n /** Get every `AnimatedValue` used by this node. */\n getPayload(): Payload {\n return this.payload || []\n }\n}\n\nexport type Payload = readonly AnimatedValue[]\n","import { is } from '@react-spring/shared'\nimport { Animated, Payload } from './Animated'\n\n/** An animated number or a native attribute value */\nexport class AnimatedValue extends Animated {\n done = true\n elapsedTime!: number\n lastPosition!: number\n lastVelocity?: number | null\n v0?: number | null\n durationProgress = 0\n\n constructor(protected _value: T) {\n super()\n if (is.num(this._value)) {\n this.lastPosition = this._value\n }\n }\n\n /** @internal */\n static create(value: any) {\n return new AnimatedValue(value)\n }\n\n getPayload(): Payload {\n return [this]\n }\n\n getValue() {\n return this._value\n }\n\n setValue(value: T, step?: number) {\n if (is.num(value)) {\n this.lastPosition = value\n if (step) {\n value = (Math.round(value / step) * step) as any\n if (this.done) {\n this.lastPosition = value as any\n }\n }\n }\n if (this._value === value) {\n return false\n }\n this._value = value\n return true\n }\n\n reset() {\n const { done } = this\n this.done = false\n if (is.num(this._value)) {\n this.elapsedTime = 0\n this.durationProgress = 0\n this.lastPosition = this._value\n if (done) this.lastVelocity = null\n this.v0 = null\n }\n }\n}\n","import { AnimatedValue } from './AnimatedValue'\nimport { is, createInterpolator } from '@react-spring/shared'\n\ntype Value = string | number\n\nexport class AnimatedString extends AnimatedValue {\n protected declare _value: number\n protected _string: string | null = null\n protected _toString: (input: number) => string\n\n constructor(value: string) {\n super(0)\n this._toString = createInterpolator({\n output: [value, value],\n })\n }\n\n /** @internal */\n static create(value: string) {\n return new AnimatedString(value)\n }\n\n getValue() {\n const value = this._string\n return value == null ? (this._string = this._toString(this._value)) : value\n }\n\n setValue(value: Value) {\n if (is.str(value)) {\n if (value == this._string) {\n return false\n }\n this._string = value\n this._value = 1\n } else if (super.setValue(value)) {\n this._string = null\n } else {\n return false\n }\n return true\n }\n\n reset(goal?: string) {\n if (goal) {\n this._toString = createInterpolator({\n output: [this.getValue(), goal],\n })\n }\n this._value = 0\n super.reset()\n }\n}\n","import { FluidValue } from '@react-spring/shared'\n\nexport type TreeContext = {\n /**\n * Any animated values found when updating the payload of an `AnimatedObject`\n * are also added to this `Set` to be observed by an animated component.\n */\n dependencies: Set | null\n}\n\nexport const TreeContext: TreeContext = { dependencies: null }\n","import { Lookup } from '@react-spring/types'\nimport {\n each,\n eachProp,\n getFluidValue,\n hasFluidValue,\n} from '@react-spring/shared'\nimport { Animated, isAnimated, getPayload } from './Animated'\nimport { AnimatedValue } from './AnimatedValue'\nimport { TreeContext } from './context'\n\n/** An object containing `Animated` nodes */\nexport class AnimatedObject extends Animated {\n constructor(protected source: Lookup) {\n super()\n this.setValue(source)\n }\n\n getValue(animated?: boolean) {\n const values: Lookup = {}\n eachProp(this.source, (source, key) => {\n if (isAnimated(source)) {\n values[key] = source.getValue(animated)\n } else if (hasFluidValue(source)) {\n values[key] = getFluidValue(source)\n } else if (!animated) {\n values[key] = source\n }\n })\n return values\n }\n\n /** Replace the raw object data */\n setValue(source: Lookup) {\n this.source = source\n this.payload = this._makePayload(source)\n }\n\n reset() {\n if (this.payload) {\n each(this.payload, node => node.reset())\n }\n }\n\n /** Create a payload set. */\n protected _makePayload(source: Lookup) {\n if (source) {\n const payload = new Set()\n eachProp(source, this._addToPayload, payload)\n return Array.from(payload)\n }\n }\n\n /** Add to a payload set. */\n protected _addToPayload(this: Set, source: any) {\n if (TreeContext.dependencies && hasFluidValue(source)) {\n TreeContext.dependencies.add(source)\n }\n const payload = getPayload(source)\n if (payload) {\n each(payload, node => this.add(node))\n }\n }\n}\n","import { isAnimatedString } from '@react-spring/shared'\nimport { AnimatedObject } from './AnimatedObject'\nimport { AnimatedString } from './AnimatedString'\nimport { AnimatedValue } from './AnimatedValue'\n\ntype Value = number | string\ntype Source = AnimatedValue[]\n\n/** An array of animated nodes */\nexport class AnimatedArray<\n T extends ReadonlyArray = Value[]\n> extends AnimatedObject {\n protected declare source: Source\n constructor(source: T) {\n super(source)\n }\n\n /** @internal */\n static create>(source: T) {\n return new AnimatedArray(source)\n }\n\n getValue(): T {\n return this.source.map(node => node.getValue()) as any\n }\n\n setValue(source: T) {\n const payload = this.getPayload()\n // Reuse the payload when lengths are equal.\n if (source.length == payload.length) {\n return payload.map((node, i) => node.setValue(source[i])).some(Boolean)\n }\n // Remake the payload when length changes.\n super.setValue(source.map(makeAnimated))\n return true\n }\n}\n\nfunction makeAnimated(value: any) {\n const nodeType = isAnimatedString(value) ? AnimatedString : AnimatedValue\n return nodeType.create(value)\n}\n","import { is, isAnimatedString } from '@react-spring/shared'\nimport { AnimatedType } from './types'\nimport { AnimatedArray } from './AnimatedArray'\nimport { AnimatedString } from './AnimatedString'\nimport { AnimatedValue } from './AnimatedValue'\nimport { getAnimated } from './Animated'\n\n/** Return the `Animated` node constructor for a given value */\nexport function getAnimatedType(value: any): AnimatedType {\n const parentNode = getAnimated(value)\n return parentNode\n ? (parentNode.constructor as any)\n : is.arr(value)\n ? AnimatedArray\n : isAnimatedString(value)\n ? AnimatedString\n : AnimatedValue\n}\n","import * as React from 'react'\nimport { forwardRef, useRef, Ref, useCallback, useEffect } from 'react'\nimport {\n is,\n each,\n raf,\n useForceUpdate,\n useOnce,\n FluidEvent,\n FluidValue,\n addFluidObserver,\n removeFluidObserver,\n useIsomorphicLayoutEffect,\n} from '@react-spring/shared'\nimport { ElementType } from '@react-spring/types'\n\nimport { AnimatedObject } from './AnimatedObject'\nimport { TreeContext } from './context'\nimport { HostConfig } from './createHost'\n\nexport type AnimatableComponent = string | Exclude\n\nexport const withAnimated = (Component: any, host: HostConfig) => {\n const hasInstance: boolean =\n // Function components must use \"forwardRef\" to avoid being\n // re-rendered on every animation frame.\n !is.fun(Component) ||\n (Component.prototype && Component.prototype.isReactComponent)\n\n return forwardRef((givenProps: any, givenRef: Ref) => {\n const instanceRef = useRef(null)\n\n // The `hasInstance` value is constant, so we can safely avoid\n // the `useCallback` invocation when `hasInstance` is false.\n const ref =\n hasInstance &&\n // eslint-disable-next-line react-hooks/rules-of-hooks\n useCallback(\n (value: any) => {\n instanceRef.current = updateRef(givenRef, value)\n },\n [givenRef]\n )\n\n const [props, deps] = getAnimatedState(givenProps, host)\n\n const forceUpdate = useForceUpdate()\n\n const callback = () => {\n const instance = instanceRef.current\n if (hasInstance && !instance) {\n // Either this component was unmounted before changes could be\n // applied, or the wrapped component forgot to forward its ref.\n return\n }\n\n const didUpdate = instance\n ? host.applyAnimatedValues(instance, props.getValue(true))\n : false\n\n // Re-render the component when native updates fail.\n if (didUpdate === false) {\n forceUpdate()\n }\n }\n\n const observer = new PropsObserver(callback, deps)\n\n const observerRef = useRef()\n useIsomorphicLayoutEffect(() => {\n observerRef.current = observer\n\n // Observe the latest dependencies.\n each(deps, dep => addFluidObserver(dep, observer))\n\n return () => {\n // Stop observing previous dependencies.\n if (observerRef.current) {\n each(observerRef.current.deps, dep =>\n removeFluidObserver(dep, observerRef.current!)\n )\n raf.cancel(observerRef.current.update)\n }\n }\n })\n\n // eslint-disable-next-line react-hooks/exhaustive-deps\n useEffect(callback, [])\n // Stop observing on unmount.\n useOnce(() => () => {\n const observer = observerRef.current!\n each(observer.deps, dep => removeFluidObserver(dep, observer))\n })\n\n const usedProps = host.getComponentProps(props.getValue())\n return \n })\n}\n\nclass PropsObserver {\n constructor(readonly update: () => void, readonly deps: Set) {}\n eventObserved(event: FluidEvent) {\n if (event.type == 'change') {\n raf.write(this.update)\n }\n }\n}\n\ntype AnimatedState = [props: AnimatedObject, dependencies: Set]\n\nfunction getAnimatedState(props: any, host: HostConfig): AnimatedState {\n const dependencies = new Set()\n TreeContext.dependencies = dependencies\n\n // Search the style for dependencies.\n if (props.style)\n props = {\n ...props,\n style: host.createAnimatedStyle(props.style),\n }\n\n // Search the props for dependencies.\n props = new AnimatedObject(props)\n\n TreeContext.dependencies = null\n return [props, dependencies]\n}\n\nfunction updateRef(ref: Ref, value: T) {\n if (ref) {\n if (is.fun(ref)) ref(value)\n else (ref as any).current = value\n }\n return value\n}\n","import { Lookup } from '@react-spring/types'\nimport { is, eachProp } from '@react-spring/shared'\nimport { AnimatableComponent, withAnimated } from './withAnimated'\nimport { Animated } from './Animated'\nimport { AnimatedObject } from './AnimatedObject'\n\nexport interface HostConfig {\n /** Provide custom logic for native updates */\n applyAnimatedValues: (node: any, props: Lookup) => boolean | void\n /** Wrap the `style` prop with an animated node */\n createAnimatedStyle: (style: Lookup) => Animated\n /** Intercept props before they're passed to an animated component */\n getComponentProps: (props: Lookup) => typeof props\n}\n\n// A stub type that gets replaced by @react-spring/web and others.\ntype WithAnimated = {\n (Component: AnimatableComponent): any\n [key: string]: any\n}\n\n// For storing the animated version on the original component\nconst cacheKey = Symbol.for('AnimatedComponent')\n\nexport const createHost = (\n components: AnimatableComponent[] | { [key: string]: AnimatableComponent },\n {\n applyAnimatedValues = () => false,\n createAnimatedStyle = style => new AnimatedObject(style),\n getComponentProps = props => props,\n }: Partial = {}\n) => {\n const hostConfig: HostConfig = {\n applyAnimatedValues,\n createAnimatedStyle,\n getComponentProps,\n }\n\n const animated: WithAnimated = (Component: any) => {\n const displayName = getDisplayName(Component) || 'Anonymous'\n\n if (is.str(Component)) {\n Component =\n animated[Component] ||\n (animated[Component] = withAnimated(Component, hostConfig))\n } else {\n Component =\n Component[cacheKey] ||\n (Component[cacheKey] = withAnimated(Component, hostConfig))\n }\n\n Component.displayName = `Animated(${displayName})`\n return Component\n }\n\n eachProp(components, (Component, key) => {\n if (is.arr(components)) {\n key = getDisplayName(Component)!\n }\n animated[key] = animated(Component)\n })\n\n return {\n animated,\n }\n}\n\nconst getDisplayName = (arg: AnimatableComponent) =>\n is.str(arg)\n ? arg\n : arg && is.str(arg.displayName)\n ? arg.displayName\n : (is.fun(arg) && arg.name) || null\n","import {\n is,\n toArray,\n eachProp,\n getFluidValue,\n isAnimatedString,\n FluidValue,\n Globals as G,\n} from '@react-spring/shared'\nimport { AnyFn, OneOrMore, Lookup } from '@react-spring/types'\nimport { ReservedProps, ForwardProps, InferTo } from './types'\nimport type { Controller } from './Controller'\nimport type { SpringRef } from './SpringRef'\n\nexport function callProp(\n value: T,\n ...args: T extends AnyFn ? Parameters : unknown[]\n): T extends AnyFn ? U : T {\n return is.fun(value) ? value(...args) : value\n}\n\n/** Try to coerce the given value into a boolean using the given key */\nexport const matchProp = (\n value: boolean | OneOrMore | ((key: any) => boolean) | undefined,\n key: string | undefined\n) =>\n value === true ||\n !!(\n key &&\n value &&\n (is.fun(value) ? value(key) : toArray(value).includes(key))\n )\n\nexport const resolveProp = (\n prop: T | Lookup | undefined,\n key: string | undefined\n) => (is.obj(prop) ? key && (prop as any)[key] : prop)\n\nexport const concatFn = (first: T | undefined, last: T) =>\n first ? (...args: Parameters) => (first(...args), last(...args)) : last\n\n/** Returns `true` if the given prop is having its default value set. */\nexport const hasDefaultProp = (props: T, key: keyof T) =>\n !is.und(getDefaultProp(props, key))\n\n/** Get the default value being set for the given `key` */\nexport const getDefaultProp = (\n props: T,\n key: P\n): T[P] =>\n props.default === true\n ? props[key]\n : props.default\n ? props.default[key]\n : undefined\n\nconst noopTransform = (value: any) => value\n\n/**\n * Extract the default props from an update.\n *\n * When the `default` prop is falsy, this function still behaves as if\n * `default: true` was used. The `default` prop is always respected when\n * truthy.\n */\nexport const getDefaultProps = (\n props: Lookup,\n transform: (value: any, key: string) => any = noopTransform\n): T => {\n let keys: readonly string[] = DEFAULT_PROPS\n if (props.default && props.default !== true) {\n props = props.default\n keys = Object.keys(props)\n }\n const defaults: any = {}\n for (const key of keys) {\n const value = transform(props[key], key)\n if (!is.und(value)) {\n defaults[key] = value\n }\n }\n return defaults\n}\n\n/**\n * These props are implicitly used as defaults when defined in a\n * declarative update (eg: render-based) or any update with `default: true`.\n *\n * Use `default: {}` or `default: false` to opt-out of these implicit defaults\n * for any given update.\n *\n * Note: These are not the only props with default values. For example, the\n * `pause`, `cancel`, and `immediate` props. But those must be updated with\n * the object syntax (eg: `default: { immediate: true }`).\n */\nexport const DEFAULT_PROPS = [\n 'config',\n 'onProps',\n 'onStart',\n 'onChange',\n 'onPause',\n 'onResume',\n 'onRest',\n] as const\n\nconst RESERVED_PROPS: {\n [key: string]: 1 | undefined\n} = {\n config: 1,\n from: 1,\n to: 1,\n ref: 1,\n loop: 1,\n reset: 1,\n pause: 1,\n cancel: 1,\n reverse: 1,\n immediate: 1,\n default: 1,\n delay: 1,\n onProps: 1,\n onStart: 1,\n onChange: 1,\n onPause: 1,\n onResume: 1,\n onRest: 1,\n onResolve: 1,\n\n // Transition props\n items: 1,\n trail: 1,\n sort: 1,\n expires: 1,\n initial: 1,\n enter: 1,\n update: 1,\n leave: 1,\n children: 1,\n onDestroyed: 1,\n\n // Internal props\n keys: 1,\n callId: 1,\n parentId: 1,\n}\n\n/**\n * Extract any properties whose keys are *not* reserved for customizing your\n * animations. All hooks use this function, which means `useTransition` props\n * are reserved for `useSpring` calls, etc.\n */\nfunction getForwardProps(\n props: Props\n): ForwardProps | undefined {\n const forward: any = {}\n\n let count = 0\n eachProp(props, (value, prop) => {\n if (!RESERVED_PROPS[prop]) {\n forward[prop] = value\n count++\n }\n })\n\n if (count) {\n return forward\n }\n}\n\n/**\n * Clone the given `props` and move all non-reserved props\n * into the `to` prop.\n */\nexport function inferTo(props: T): InferTo {\n const to = getForwardProps(props)\n if (to) {\n const out: any = { to }\n eachProp(props, (val, key) => key in to || (out[key] = val))\n return out\n }\n return { ...props } as any\n}\n\n// Compute the goal value, converting \"red\" to \"rgba(255, 0, 0, 1)\" in the process\nexport function computeGoal(value: T | FluidValue): T {\n value = getFluidValue(value)\n return is.arr(value)\n ? value.map(computeGoal)\n : isAnimatedString(value)\n ? (G.createStringInterpolator({\n range: [0, 1],\n output: [value, value] as any,\n })(1) as any)\n : value\n}\n\nexport function hasProps(props: object) {\n for (const _ in props) return true\n return false\n}\n\nexport function isAsyncTo(to: any) {\n return is.fun(to) || (is.arr(to) && is.obj(to[0]))\n}\n\n/** Detach `ctrl` from `ctrl.ref` and (optionally) the given `ref` */\nexport function detachRefs(ctrl: Controller, ref?: SpringRef) {\n ctrl.ref?.delete(ctrl)\n ref?.delete(ctrl)\n}\n\n/** Replace `ctrl.ref` with the given `ref` (if defined) */\nexport function replaceRef(ctrl: Controller, ref?: SpringRef) {\n if (ref && ctrl.ref !== ref) {\n ctrl.ref?.delete(ctrl)\n ref.add(ctrl)\n ctrl.ref = ref\n }\n}\n","// The `mass` prop defaults to 1\nexport const config = {\n default: { tension: 170, friction: 26 },\n gentle: { tension: 120, friction: 14 },\n wobbly: { tension: 180, friction: 12 },\n stiff: { tension: 210, friction: 20 },\n slow: { tension: 280, friction: 60 },\n molasses: { tension: 280, friction: 120 },\n} as const\n","import { is, easings } from '@react-spring/shared'\nimport { EasingFunction } from '@react-spring/types'\nimport { config as configs } from './constants'\n\nconst defaults: any = {\n ...configs.default,\n mass: 1,\n damping: 1,\n easing: easings.linear,\n clamp: false,\n}\n\nexport class AnimationConfig {\n /**\n * With higher tension, the spring will resist bouncing and try harder to stop at its end value.\n *\n * When tension is zero, no animation occurs.\n *\n * @default 170\n */\n tension!: number\n\n /**\n * The damping ratio coefficient, or just the damping ratio when `speed` is defined.\n *\n * When `speed` is defined, this value should be between 0 and 1.\n *\n * Higher friction means the spring will slow down faster.\n *\n * @default 26\n */\n friction!: number\n\n /**\n * The natural frequency (in seconds), which dictates the number of bounces\n * per second when no damping exists.\n *\n * When defined, `tension` is derived from this, and `friction` is derived\n * from `tension` and `damping`.\n */\n frequency?: number\n\n /**\n * The damping ratio, which dictates how the spring slows down.\n *\n * Set to `0` to never slow down. Set to `1` to slow down without bouncing.\n * Between `0` and `1` is for you to explore.\n *\n * Only works when `frequency` is defined.\n *\n * @default 1\n */\n damping!: number\n\n /**\n * Higher mass means more friction is required to slow down.\n *\n * Defaults to 1, which works fine most of the time.\n *\n * @default 1\n */\n mass!: number\n\n /**\n * The initial velocity of one or more values.\n *\n * @default 0\n */\n velocity: number | number[] = 0\n\n /**\n * The smallest velocity before the animation is considered \"not moving\".\n *\n * When undefined, `precision` is used instead.\n */\n restVelocity?: number\n\n /**\n * The smallest distance from a value before that distance is essentially zero.\n *\n * This helps in deciding when a spring is \"at rest\". The spring must be within\n * this distance from its final value, and its velocity must be lower than this\n * value too (unless `restVelocity` is defined).\n *\n * @default 0.01\n */\n precision?: number\n\n /**\n * For `duration` animations only. Note: The `duration` is not affected\n * by this property.\n *\n * Defaults to `0`, which means \"start from the beginning\".\n *\n * Setting to `1+` makes an immediate animation.\n *\n * Setting to `0.5` means \"start from the middle of the easing function\".\n *\n * Any number `>= 0` and `<= 1` makes sense here.\n */\n progress?: number\n\n /**\n * Animation length in number of milliseconds.\n */\n duration?: number\n\n /**\n * The animation curve. Only used when `duration` is defined.\n *\n * Defaults to quadratic ease-in-out.\n */\n easing!: EasingFunction\n\n /**\n * Avoid overshooting by ending abruptly at the goal value.\n *\n * @default false\n */\n clamp!: boolean\n\n /**\n * When above zero, the spring will bounce instead of overshooting when\n * exceeding its goal value. Its velocity is multiplied by `-1 + bounce`\n * whenever its current value equals or exceeds its goal. For example,\n * setting `bounce` to `0.5` chops the velocity in half on each bounce,\n * in addition to any friction.\n */\n bounce?: number\n\n /**\n * \"Decay animations\" decelerate without an explicit goal value.\n * Useful for scrolling animations.\n *\n * Use `true` for the default exponential decay factor (`0.998`).\n *\n * When a `number` between `0` and `1` is given, a lower number makes the\n * animation slow down faster. And setting to `1` would make an unending\n * animation.\n *\n * @default false\n */\n decay?: boolean | number\n\n /**\n * While animating, round to the nearest multiple of this number.\n * The `from` and `to` values are never rounded, as well as any value\n * passed to the `set` method of an animated value.\n */\n round?: number\n\n constructor() {\n Object.assign(this, defaults)\n }\n}\n\nexport function mergeConfig(\n config: AnimationConfig,\n newConfig: Partial,\n defaultConfig?: Partial\n): typeof config\n\nexport function mergeConfig(\n config: any,\n newConfig: object,\n defaultConfig?: object\n) {\n if (defaultConfig) {\n defaultConfig = { ...defaultConfig }\n sanitizeConfig(defaultConfig, newConfig)\n newConfig = { ...defaultConfig, ...newConfig }\n }\n\n sanitizeConfig(config, newConfig)\n Object.assign(config, newConfig)\n\n for (const key in defaults) {\n if (config[key] == null) {\n config[key] = defaults[key]\n }\n }\n\n let { frequency, damping } = config\n const { mass } = config\n if (!is.und(frequency)) {\n if (frequency < 0.01) frequency = 0.01\n if (damping < 0) damping = 0\n config.tension = Math.pow((2 * Math.PI) / frequency, 2) * mass\n config.friction = (4 * Math.PI * damping * mass) / frequency\n }\n\n return config\n}\n\n// Prevent a config from accidentally overriding new props.\n// This depends on which \"config\" props take precedence when defined.\nfunction sanitizeConfig(\n config: Partial,\n props: Partial\n) {\n if (!is.und(props.decay)) {\n config.duration = undefined\n } else {\n const isTensionConfig = !is.und(props.tension) || !is.und(props.friction)\n if (\n isTensionConfig ||\n !is.und(props.frequency) ||\n !is.und(props.damping) ||\n !is.und(props.mass)\n ) {\n config.duration = undefined\n config.decay = undefined\n }\n if (isTensionConfig) {\n config.frequency = undefined\n }\n }\n}\n","import { AnimatedValue } from '@react-spring/animated'\nimport { FluidValue } from '@react-spring/shared'\nimport { AnimationConfig } from './AnimationConfig'\nimport { PickEventFns } from './types/internal'\nimport { SpringProps } from './types'\n\nconst emptyArray: readonly any[] = []\n\n/** An animation being executed by the frameloop */\nexport class Animation {\n changed = false\n values: readonly AnimatedValue[] = emptyArray\n toValues: readonly number[] | null = null\n fromValues: readonly number[] = emptyArray\n\n to!: T | FluidValue\n from!: T | FluidValue\n config = new AnimationConfig()\n immediate = false\n}\n\nexport interface Animation extends PickEventFns> {}\n","import { Timeout, is, raf, Globals as G } from '@react-spring/shared'\nimport { matchProp, callProp } from './helpers'\nimport { AsyncResult, MatchProp } from './types'\nimport { RunAsyncState, RunAsyncProps } from './runAsync'\nimport {\n AnimationResolver,\n AnimationTarget,\n InferProps,\n InferState,\n} from './types/internal'\n\n// The `scheduleProps` function only handles these defaults.\ntype DefaultProps = { cancel?: MatchProp; pause?: MatchProp }\n\ninterface ScheduledProps {\n key?: string\n props: InferProps\n defaultProps?: DefaultProps>\n state: RunAsyncState\n actions: {\n pause: () => void\n resume: () => void\n start: (props: RunAsyncProps, resolve: AnimationResolver) => void\n }\n}\n\n/**\n * This function sets a timeout if both the `delay` prop exists and\n * the `cancel` prop is not `true`.\n *\n * The `actions.start` function must handle the `cancel` prop itself,\n * but the `pause` prop is taken care of.\n */\nexport function scheduleProps(\n callId: number,\n { key, props, defaultProps, state, actions }: ScheduledProps\n): AsyncResult {\n return new Promise((resolve, reject) => {\n let delay: number\n let timeout: Timeout\n\n let cancel = matchProp(props.cancel ?? defaultProps?.cancel, key)\n if (cancel) {\n onStart()\n } else {\n // The `pause` prop updates the paused flag.\n if (!is.und(props.pause)) {\n state.paused = matchProp(props.pause, key)\n }\n // The default `pause` takes precedence when true,\n // which allows `SpringContext` to work as expected.\n let pause = defaultProps?.pause\n if (pause !== true) {\n pause = state.paused || matchProp(pause, key)\n }\n\n delay = callProp(props.delay || 0, key)\n if (pause) {\n state.resumeQueue.add(onResume)\n actions.pause()\n } else {\n actions.resume()\n onResume()\n }\n }\n\n function onPause() {\n state.resumeQueue.add(onResume)\n state.timeouts.delete(timeout)\n timeout.cancel()\n // Cache the remaining delay.\n delay = timeout.time - raf.now()\n }\n\n function onResume() {\n if (delay > 0 && !G.skipAnimation) {\n state.delayed = true\n timeout = raf.setTimeout(onStart, delay)\n state.pauseQueue.add(onPause)\n state.timeouts.add(timeout)\n } else {\n onStart()\n }\n }\n\n function onStart() {\n if (state.delayed) {\n state.delayed = false\n }\n\n state.pauseQueue.delete(onPause)\n state.timeouts.delete(timeout)\n\n // Maybe cancelled during its delay.\n if (callId <= (state.cancelId || 0)) {\n cancel = true\n }\n\n try {\n actions.start({ ...props, callId, cancel }, resolve)\n } catch (err) {\n reject(err)\n }\n }\n })\n}\n","import { AnimationResult } from './types'\nimport { Readable } from './types/internal'\n\n/** @internal */\nexport const getCombinedResult = (\n target: T,\n results: AnimationResult[]\n): AnimationResult =>\n results.length == 1\n ? results[0]\n : results.some(result => result.cancelled)\n ? getCancelledResult(target.get())\n : results.every(result => result.noop)\n ? getNoopResult(target.get())\n : getFinishedResult(\n target.get(),\n results.every(result => result.finished)\n )\n\n/** No-op results are for updates that never start an animation. */\nexport const getNoopResult = (value: any) => ({\n value,\n noop: true,\n finished: true,\n cancelled: false,\n})\n\nexport const getFinishedResult = (\n value: any,\n finished: boolean,\n cancelled = false\n) => ({\n value,\n finished,\n cancelled,\n})\n\nexport const getCancelledResult = (value: any) => ({\n value,\n cancelled: true,\n finished: false,\n})\n","import {\n is,\n raf,\n flush,\n eachProp,\n Timeout,\n Globals as G,\n} from '@react-spring/shared'\nimport { Falsy } from '@react-spring/types'\n\nimport { getDefaultProps } from './helpers'\nimport { AnimationTarget, InferState, InferProps } from './types/internal'\nimport { AnimationResult, AsyncResult, SpringChain, SpringToFn } from './types'\nimport { getCancelledResult, getFinishedResult } from './AnimationResult'\n\ntype AsyncTo = SpringChain | SpringToFn\n\n/** @internal */\nexport type RunAsyncProps = InferProps & {\n callId: number\n parentId?: number\n cancel: boolean\n to?: any\n}\n\n/** @internal */\nexport interface RunAsyncState {\n paused: boolean\n pauseQueue: Set<() => void>\n resumeQueue: Set<() => void>\n timeouts: Set\n delayed?: boolean\n asyncId?: number\n asyncTo?: AsyncTo>\n promise?: AsyncResult\n cancelId?: number\n}\n\n/**\n * Start an async chain or an async script.\n *\n * Always call `runAsync` in the action callback of a `scheduleProps` call.\n *\n * The `T` parameter can be a set of animated values (as an object type)\n * or a primitive type for a single animated value.\n */\nexport function runAsync(\n to: AsyncTo>,\n props: RunAsyncProps,\n state: RunAsyncState,\n target: T\n): AsyncResult {\n const { callId, parentId, onRest } = props\n const { asyncTo: prevTo, promise: prevPromise } = state\n\n if (!parentId && to === prevTo && !props.reset) {\n return prevPromise!\n }\n\n return (state.promise = (async () => {\n state.asyncId = callId\n state.asyncTo = to\n\n // The default props of any `animate` calls.\n const defaultProps = getDefaultProps>(props, (value, key) =>\n // The `onRest` prop is only called when the `runAsync` promise is resolved.\n key === 'onRest' ? undefined : value\n )\n\n let preventBail!: () => void\n let bail: (error: any) => void\n\n // This promise is rejected when the animation is interrupted.\n const bailPromise = new Promise(\n (resolve, reject) => ((preventBail = resolve), (bail = reject))\n )\n\n const bailIfEnded = (bailSignal: BailSignal) => {\n const bailResult =\n // The `cancel` prop or `stop` method was used.\n (callId <= (state.cancelId || 0) && getCancelledResult(target)) ||\n // The async `to` prop was replaced.\n (callId !== state.asyncId && getFinishedResult(target, false))\n\n if (bailResult) {\n bailSignal.result = bailResult\n\n // Reject the `bailPromise` to ensure the `runAsync` promise\n // is not relying on the caller to rethrow the error for us.\n bail(bailSignal)\n throw bailSignal\n }\n }\n\n const animate: any = (arg1: any, arg2?: any) => {\n // Create the bail signal outside the returned promise,\n // so the generated stack trace is relevant.\n const bailSignal = new BailSignal()\n const skipAnimationSignal = new SkipAnimationSignal()\n\n return (async () => {\n if (G.skipAnimation) {\n /**\n * We need to stop animations if `skipAnimation`\n * is set in the Globals\n *\n */\n stopAsync(state)\n\n // create the rejection error that's handled gracefully\n skipAnimationSignal.result = getFinishedResult(target, false)\n bail(skipAnimationSignal)\n throw skipAnimationSignal\n }\n\n bailIfEnded(bailSignal)\n\n const props: any = is.obj(arg1) ? { ...arg1 } : { ...arg2, to: arg1 }\n props.parentId = callId\n\n eachProp(defaultProps, (value, key) => {\n if (is.und(props[key])) {\n props[key] = value\n }\n })\n\n const result = await target.start(props)\n bailIfEnded(bailSignal)\n\n if (state.paused) {\n await new Promise(resume => {\n state.resumeQueue.add(resume)\n })\n }\n\n return result\n })()\n }\n\n let result!: AnimationResult\n\n if (G.skipAnimation) {\n /**\n * We need to stop animations if `skipAnimation`\n * is set in the Globals\n */\n stopAsync(state)\n return getFinishedResult(target, false)\n }\n\n try {\n let animating!: Promise\n\n // Async sequence\n if (is.arr(to)) {\n animating = (async (queue: any[]) => {\n for (const props of queue) {\n await animate(props)\n }\n })(to)\n }\n\n // Async script\n else {\n animating = Promise.resolve(to(animate, target.stop.bind(target)))\n }\n\n await Promise.all([animating.then(preventBail), bailPromise])\n result = getFinishedResult(target.get(), true, false)\n\n // Bail handling\n } catch (err) {\n if (err instanceof BailSignal) {\n result = err.result\n } else if (err instanceof SkipAnimationSignal) {\n result = err.result\n } else {\n throw err\n }\n\n // Reset the async state.\n } finally {\n if (callId == state.asyncId) {\n state.asyncId = parentId\n state.asyncTo = parentId ? prevTo : undefined\n state.promise = parentId ? prevPromise : undefined\n }\n }\n\n if (is.fun(onRest)) {\n raf.batchedUpdates(() => {\n onRest(result, target, target.item)\n })\n }\n\n return result\n })())\n}\n\n/** Stop the current `runAsync` call with `finished: false` (or with `cancelled: true` when `cancelId` is defined) */\nexport function stopAsync(state: RunAsyncState, cancelId?: number | Falsy) {\n flush(state.timeouts, t => t.cancel())\n state.pauseQueue.clear()\n state.resumeQueue.clear()\n state.asyncId = state.asyncTo = state.promise = undefined\n if (cancelId) state.cancelId = cancelId\n}\n\n/** This error is thrown to signal an interrupted async animation. */\nexport class BailSignal extends Error {\n result!: AnimationResult\n constructor() {\n super(\n 'An async animation has been interrupted. You see this error because you ' +\n 'forgot to use `await` or `.catch(...)` on its returned promise.'\n )\n }\n}\n\nexport class SkipAnimationSignal extends Error {\n result!: AnimationResult\n\n constructor() {\n super('SkipAnimationSignal')\n }\n}\n","import {\n deprecateInterpolate,\n frameLoop,\n FluidValue,\n Globals as G,\n callFluidObservers,\n} from '@react-spring/shared'\nimport { InterpolatorArgs } from '@react-spring/types'\nimport { getAnimated } from '@react-spring/animated'\n\nimport { Interpolation } from './Interpolation'\n\nexport const isFrameValue = (value: any): value is FrameValue =>\n value instanceof FrameValue\n\nlet nextId = 1\n\n/**\n * A kind of `FluidValue` that manages an `AnimatedValue` node.\n *\n * Its underlying value can be accessed and even observed.\n */\nexport abstract class FrameValue extends FluidValue<\n T,\n FrameValue.Event\n> {\n readonly id = nextId++\n\n abstract key?: string\n abstract get idle(): boolean\n\n protected _priority = 0\n\n get priority() {\n return this._priority\n }\n set priority(priority: number) {\n if (this._priority != priority) {\n this._priority = priority\n this._onPriorityChange(priority)\n }\n }\n\n /** Get the current value */\n get(): T {\n const node = getAnimated(this)\n return node && node.getValue()\n }\n\n /** Create a spring that maps our value to another value */\n to(...args: InterpolatorArgs) {\n return G.to(this, args) as Interpolation\n }\n\n /** @deprecated Use the `to` method instead. */\n interpolate(...args: InterpolatorArgs) {\n deprecateInterpolate()\n return G.to(this, args) as Interpolation\n }\n\n toJSON() {\n return this.get()\n }\n\n protected observerAdded(count: number) {\n if (count == 1) this._attach()\n }\n\n protected observerRemoved(count: number) {\n if (count == 0) this._detach()\n }\n\n /** @internal */\n abstract advance(dt: number): void\n\n /** @internal */\n abstract eventObserved(_event: FrameValue.Event): void\n\n /** Called when the first child is added. */\n protected _attach() {}\n\n /** Called when the last child is removed. */\n protected _detach() {}\n\n /** Tell our children about our new value */\n protected _onChange(value: T, idle = false) {\n callFluidObservers(this, {\n type: 'change',\n parent: this,\n value,\n idle,\n })\n }\n\n /** Tell our children about our new priority */\n protected _onPriorityChange(priority: number) {\n if (!this.idle) {\n frameLoop.sort(this)\n }\n callFluidObservers(this, {\n type: 'priority',\n parent: this,\n priority,\n })\n }\n}\n\n// eslint-disable-next-line @typescript-eslint/no-namespace\nexport declare namespace FrameValue {\n /** A parent changed its value */\n interface ChangeEvent {\n parent: FrameValue\n type: 'change'\n value: T\n idle: boolean\n }\n\n /** A parent changed its priority */\n interface PriorityEvent {\n parent: FrameValue\n type: 'priority'\n priority: number\n }\n\n /** A parent is done animating */\n interface IdleEvent {\n parent: FrameValue\n type: 'idle'\n }\n\n /** Events sent to children of `FrameValue` objects */\n export type Event = ChangeEvent | PriorityEvent | IdleEvent\n}\n","/** The property symbol of the current animation phase. */\nconst $P = Symbol.for('SpringPhase')\n\nconst HAS_ANIMATED = 1\nconst IS_ANIMATING = 2\nconst IS_PAUSED = 4\n\n/** Returns true if the `target` has ever animated. */\nexport const hasAnimated = (target: any) => (target[$P] & HAS_ANIMATED) > 0\n\n/** Returns true if the `target` is animating (even if paused). */\nexport const isAnimating = (target: any) => (target[$P] & IS_ANIMATING) > 0\n\n/** Returns true if the `target` is paused (even if idle). */\nexport const isPaused = (target: any) => (target[$P] & IS_PAUSED) > 0\n\n/** Set the active bit of the `target` phase. */\nexport const setActiveBit = (target: any, active: boolean) =>\n active\n ? (target[$P] |= IS_ANIMATING | HAS_ANIMATED)\n : (target[$P] &= ~IS_ANIMATING)\n\nexport const setPausedBit = (target: any, paused: boolean) =>\n paused ? (target[$P] |= IS_PAUSED) : (target[$P] &= ~IS_PAUSED)\n","import {\n is,\n raf,\n each,\n isEqual,\n toArray,\n eachProp,\n frameLoop,\n flushCalls,\n getFluidValue,\n isAnimatedString,\n FluidValue,\n Globals as G,\n callFluidObservers,\n hasFluidValue,\n addFluidObserver,\n removeFluidObserver,\n getFluidObservers,\n} from '@react-spring/shared'\nimport {\n Animated,\n AnimatedValue,\n AnimatedString,\n getPayload,\n getAnimated,\n setAnimated,\n getAnimatedType,\n} from '@react-spring/animated'\nimport { Lookup } from '@react-spring/types'\n\nimport { Animation } from './Animation'\nimport { mergeConfig } from './AnimationConfig'\nimport { scheduleProps } from './scheduleProps'\nimport { runAsync, RunAsyncState, RunAsyncProps, stopAsync } from './runAsync'\nimport {\n callProp,\n computeGoal,\n matchProp,\n inferTo,\n getDefaultProps,\n getDefaultProp,\n isAsyncTo,\n resolveProp,\n} from './helpers'\nimport { FrameValue, isFrameValue } from './FrameValue'\nimport {\n isAnimating,\n isPaused,\n setPausedBit,\n hasAnimated,\n setActiveBit,\n} from './SpringPhase'\nimport {\n AnimationRange,\n AnimationResolver,\n EventKey,\n PickEventFns,\n} from './types/internal'\nimport { AsyncResult, SpringUpdate, VelocityProp, SpringProps } from './types'\nimport {\n getCombinedResult,\n getCancelledResult,\n getFinishedResult,\n getNoopResult,\n} from './AnimationResult'\n\ndeclare const console: any\n\ninterface DefaultSpringProps\n extends Pick, 'pause' | 'cancel' | 'immediate' | 'config'>,\n PickEventFns> {}\n\n/**\n * Only numbers, strings, and arrays of numbers/strings are supported.\n * Non-animatable strings are also supported.\n */\nexport class SpringValue extends FrameValue {\n /** The property name used when `to` or `from` is an object. Useful when debugging too. */\n key?: string\n\n /** The animation state */\n animation = new Animation()\n\n /** The queue of pending props */\n queue?: SpringUpdate[]\n\n /** Some props have customizable default values */\n defaultProps: DefaultSpringProps = {}\n\n /** The state for `runAsync` calls */\n protected _state: RunAsyncState> = {\n paused: false,\n delayed: false,\n pauseQueue: new Set(),\n resumeQueue: new Set(),\n timeouts: new Set(),\n }\n\n /** The promise resolvers of pending `start` calls */\n protected _pendingCalls = new Set>()\n\n /** The counter for tracking `scheduleProps` calls */\n protected _lastCallId = 0\n\n /** The last `scheduleProps` call that changed the `to` prop */\n protected _lastToId = 0\n\n protected _memoizedDuration = 0\n\n constructor(from: Exclude, props?: SpringUpdate)\n constructor(props?: SpringUpdate)\n constructor(arg1?: any, arg2?: any) {\n super()\n if (!is.und(arg1) || !is.und(arg2)) {\n const props = is.obj(arg1) ? { ...arg1 } : { ...arg2, from: arg1 }\n if (is.und(props.default)) {\n props.default = true\n }\n this.start(props)\n }\n }\n\n /** Equals true when not advancing on each frame. */\n get idle() {\n return !(isAnimating(this) || this._state.asyncTo) || isPaused(this)\n }\n\n get goal() {\n return getFluidValue(this.animation.to) as T\n }\n\n get velocity(): VelocityProp {\n const node = getAnimated(this)!\n return (\n node instanceof AnimatedValue\n ? node.lastVelocity || 0\n : node.getPayload().map(node => node.lastVelocity || 0)\n ) as any\n }\n\n /**\n * When true, this value has been animated at least once.\n */\n get hasAnimated() {\n return hasAnimated(this)\n }\n\n /**\n * When true, this value has an unfinished animation,\n * which is either active or paused.\n */\n get isAnimating() {\n return isAnimating(this)\n }\n\n /**\n * When true, all current and future animations are paused.\n */\n get isPaused() {\n return isPaused(this)\n }\n\n /**\n *\n *\n */\n get isDelayed() {\n return this._state.delayed\n }\n\n /** Advance the current animation by a number of milliseconds */\n advance(dt: number) {\n let idle = true\n let changed = false\n\n const anim = this.animation\n let { toValues } = anim\n const { config } = anim\n\n const payload = getPayload(anim.to)\n if (!payload && hasFluidValue(anim.to)) {\n toValues = toArray(getFluidValue(anim.to)) as any\n }\n\n anim.values.forEach((node, i) => {\n if (node.done) return\n\n const to =\n // Animated strings always go from 0 to 1.\n node.constructor == AnimatedString\n ? 1\n : payload\n ? payload[i].lastPosition\n : toValues![i]\n\n let finished = anim.immediate\n let position = to\n\n if (!finished) {\n position = node.lastPosition\n\n // Loose springs never move.\n if (config.tension <= 0) {\n node.done = true\n return\n }\n\n let elapsed = (node.elapsedTime += dt)\n const from = anim.fromValues[i]\n\n const v0 =\n node.v0 != null\n ? node.v0\n : (node.v0 = is.arr(config.velocity)\n ? config.velocity[i]\n : config.velocity)\n\n let velocity: number\n\n /** The smallest distance from a value before being treated like said value. */\n /**\n * TODO: make this value ~0.0001 by default in next breaking change\n * for more info see ā https://github.com/pmndrs/react-spring/issues/1389\n */\n const precision =\n config.precision ||\n (from == to ? 0.005 : Math.min(1, Math.abs(to - from) * 0.001))\n\n // Duration easing\n if (!is.und(config.duration)) {\n let p = 1\n if (config.duration > 0) {\n /**\n * Here we check if the duration has changed in the config\n * and if so update the elapsed time to the percentage\n * of completition so there is no jank in the animation\n * https://github.com/pmndrs/react-spring/issues/1163\n */\n if (this._memoizedDuration !== config.duration) {\n // update the memoized version to the new duration\n this._memoizedDuration = config.duration\n\n // if the value has started animating we need to update it\n if (node.durationProgress > 0) {\n // set elapsed time to be the same percentage of progress as the previous duration\n node.elapsedTime = config.duration * node.durationProgress\n // add the delta so the below updates work as expected\n elapsed = node.elapsedTime += dt\n }\n }\n\n // calculate the new progress\n p = (config.progress || 0) + elapsed / this._memoizedDuration\n // p is clamped between 0-1\n p = p > 1 ? 1 : p < 0 ? 0 : p\n // store our new progress\n node.durationProgress = p\n }\n\n position = from + config.easing(p) * (to - from)\n velocity = (position - node.lastPosition) / dt\n\n finished = p == 1\n }\n\n // Decay easing\n else if (config.decay) {\n const decay = config.decay === true ? 0.998 : config.decay\n const e = Math.exp(-(1 - decay) * elapsed)\n\n position = from + (v0 / (1 - decay)) * (1 - e)\n finished = Math.abs(node.lastPosition - position) <= precision\n\n // derivative of position\n velocity = v0 * e\n }\n\n // Spring easing\n else {\n velocity = node.lastVelocity == null ? v0 : node.lastVelocity\n\n /** The velocity at which movement is essentially none */\n const restVelocity = config.restVelocity || precision / 10\n\n // Bouncing is opt-in (not to be confused with overshooting)\n const bounceFactor = config.clamp ? 0 : config.bounce!\n const canBounce = !is.und(bounceFactor)\n\n /** When `true`, the value is increasing over time */\n const isGrowing = from == to ? node.v0 > 0 : from < to\n\n /** When `true`, the velocity is considered moving */\n let isMoving!: boolean\n\n /** When `true`, the velocity is being deflected or clamped */\n let isBouncing = false\n\n const step = 1 // 1ms\n const numSteps = Math.ceil(dt / step)\n for (let n = 0; n < numSteps; ++n) {\n isMoving = Math.abs(velocity) > restVelocity\n\n if (!isMoving) {\n finished = Math.abs(to - position) <= precision\n if (finished) {\n break\n }\n }\n\n if (canBounce) {\n isBouncing = position == to || position > to == isGrowing\n\n // Invert the velocity with a magnitude, or clamp it.\n if (isBouncing) {\n velocity = -velocity * bounceFactor\n position = to\n }\n }\n\n const springForce = -config.tension * 0.000001 * (position - to)\n const dampingForce = -config.friction * 0.001 * velocity\n const acceleration = (springForce + dampingForce) / config.mass // pt/ms^2\n\n velocity = velocity + acceleration * step // pt/ms\n position = position + velocity * step\n }\n }\n\n node.lastVelocity = velocity\n\n if (Number.isNaN(position)) {\n console.warn(`Got NaN while animating:`, this)\n finished = true\n }\n }\n\n // Parent springs must finish before their children can.\n if (payload && !payload[i].done) {\n finished = false\n }\n\n if (finished) {\n node.done = true\n } else {\n idle = false\n }\n\n if (node.setValue(position, config.round)) {\n changed = true\n }\n })\n\n const node = getAnimated(this)!\n /**\n * Get the node's current value, this will be different\n * to anim.to when config.decay is true\n */\n const currVal = node.getValue()\n if (idle) {\n // get our final fluid val from the anim.to\n const finalVal = getFluidValue(anim.to)\n /**\n * check if they're not equal, or if they're\n * change and if there's no config.decay set\n */\n if ((currVal !== finalVal || changed) && !config.decay) {\n // set the value to anim.to\n node.setValue(finalVal)\n this._onChange(finalVal)\n } else if (changed && config.decay) {\n /**\n * if it's changed but there is a config.decay,\n * just call _onChange with currrent value\n */\n this._onChange(currVal)\n }\n // call stop because the spring has stopped.\n this._stop()\n } else if (changed) {\n /**\n * if the spring has changed, but is not idle,\n * just call the _onChange handler\n */\n this._onChange(currVal)\n }\n }\n\n /** Set the current value, while stopping the current animation */\n set(value: T | FluidValue) {\n raf.batchedUpdates(() => {\n this._stop()\n\n // These override the current value and goal value that may have\n // been updated by `onRest` handlers in the `_stop` call above.\n this._focus(value)\n this._set(value)\n })\n return this\n }\n\n /**\n * Freeze the active animation in time, as well as any updates merged\n * before `resume` is called.\n */\n pause() {\n this._update({ pause: true })\n }\n\n /** Resume the animation if paused. */\n resume() {\n this._update({ pause: false })\n }\n\n /** Skip to the end of the current animation. */\n finish() {\n if (isAnimating(this)) {\n const { to, config } = this.animation\n raf.batchedUpdates(() => {\n // Ensure the \"onStart\" and \"onRest\" props are called.\n this._onStart()\n\n // Jump to the goal value, except for decay animations\n // which have an undefined goal value.\n if (!config.decay) {\n this._set(to, false)\n }\n\n this._stop()\n })\n }\n return this\n }\n\n /** Push props into the pending queue. */\n update(props: SpringUpdate) {\n const queue = this.queue || (this.queue = [])\n queue.push(props)\n return this\n }\n\n /**\n * Update this value's animation using the queue of pending props,\n * and unpause the current animation (if one is frozen).\n *\n * When arguments are passed, a new animation is created, and the\n * queued animations are left alone.\n */\n start(): AsyncResult\n\n start(props: SpringUpdate): AsyncResult\n\n start(to: T, props?: SpringProps): AsyncResult\n\n start(to?: any, arg2?: any) {\n let queue: SpringUpdate[]\n if (!is.und(to)) {\n queue = [is.obj(to) ? to : { ...arg2, to }]\n } else {\n queue = this.queue || []\n this.queue = []\n }\n\n return Promise.all(\n queue.map(props => {\n const up = this._update(props)\n return up\n })\n ).then(results => getCombinedResult(this, results))\n }\n\n /**\n * Stop the current animation, and cancel any delayed updates.\n *\n * Pass `true` to call `onRest` with `cancelled: true`.\n */\n stop(cancel?: boolean) {\n const { to } = this.animation\n\n // The current value becomes the goal value.\n this._focus(this.get())\n\n stopAsync(this._state, cancel && this._lastCallId)\n raf.batchedUpdates(() => this._stop(to, cancel))\n\n return this\n }\n\n /** Restart the animation. */\n reset() {\n this._update({ reset: true })\n }\n\n /** @internal */\n eventObserved(event: FrameValue.Event) {\n if (event.type == 'change') {\n this._start()\n } else if (event.type == 'priority') {\n this.priority = event.priority + 1\n }\n }\n\n /**\n * Parse the `to` and `from` range from the given `props` object.\n *\n * This also ensures the initial value is available to animated components\n * during the render phase.\n */\n protected _prepareNode(props: {\n to?: any\n from?: any\n reverse?: boolean\n default?: any\n }) {\n const key = this.key || ''\n\n let { to, from } = props\n\n to = is.obj(to) ? to[key] : to\n if (to == null || isAsyncTo(to)) {\n to = undefined\n }\n\n from = is.obj(from) ? from[key] : from\n if (from == null) {\n from = undefined\n }\n\n // Create the range now to avoid \"reverse\" logic.\n const range = { to, from }\n\n // Before ever animating, this method ensures an `Animated` node\n // exists and keeps its value in sync with the \"from\" prop.\n if (!hasAnimated(this)) {\n if (props.reverse) [to, from] = [from, to]\n\n from = getFluidValue(from)\n if (!is.und(from)) {\n this._set(from)\n }\n // Use the \"to\" value if our node is undefined.\n else if (!getAnimated(this)) {\n this._set(to)\n }\n }\n\n return range\n }\n\n /** Every update is processed by this method before merging. */\n protected _update(\n { ...props }: SpringProps,\n isLoop?: boolean\n ): AsyncResult> {\n const { key, defaultProps } = this\n\n // Update the default props immediately.\n if (props.default)\n Object.assign(\n defaultProps,\n getDefaultProps(props, (value, prop) =>\n /^on/.test(prop) ? resolveProp(value, key) : value\n )\n )\n\n mergeActiveFn(this, props, 'onProps')\n sendEvent(this, 'onProps', props, this)\n\n // Ensure the initial value can be accessed by animated components.\n const range = this._prepareNode(props)\n\n if (Object.isFrozen(this)) {\n throw Error(\n 'Cannot animate a `SpringValue` object that is frozen. ' +\n 'Did you forget to pass your component to `animated(...)` before animating its props?'\n )\n }\n\n const state = this._state\n\n return scheduleProps(++this._lastCallId, {\n key,\n props,\n defaultProps,\n state,\n actions: {\n pause: () => {\n if (!isPaused(this)) {\n setPausedBit(this, true)\n flushCalls(state.pauseQueue)\n sendEvent(\n this,\n 'onPause',\n getFinishedResult(this, checkFinished(this, this.animation.to)),\n this\n )\n }\n },\n resume: () => {\n if (isPaused(this)) {\n setPausedBit(this, false)\n if (isAnimating(this)) {\n this._resume()\n }\n flushCalls(state.resumeQueue)\n sendEvent(\n this,\n 'onResume',\n getFinishedResult(this, checkFinished(this, this.animation.to)),\n this\n )\n }\n },\n start: this._merge.bind(this, range),\n },\n }).then(result => {\n if (props.loop && result.finished && !(isLoop && result.noop)) {\n const nextProps = createLoopUpdate(props)\n if (nextProps) {\n return this._update(nextProps, true)\n }\n }\n return result\n })\n }\n\n /** Merge props into the current animation */\n protected _merge(\n range: AnimationRange,\n props: RunAsyncProps>,\n resolve: AnimationResolver>\n ): void {\n // The \"cancel\" prop cancels all pending delays and it forces the\n // active animation to stop where it is.\n if (props.cancel) {\n this.stop(true)\n return resolve(getCancelledResult(this))\n }\n\n /** The \"to\" prop is defined. */\n const hasToProp = !is.und(range.to)\n\n /** The \"from\" prop is defined. */\n const hasFromProp = !is.und(range.from)\n\n // Avoid merging other props if implicitly prevented, except\n // when both the \"to\" and \"from\" props are undefined.\n if (hasToProp || hasFromProp) {\n if (props.callId > this._lastToId) {\n this._lastToId = props.callId\n } else {\n return resolve(getCancelledResult(this))\n }\n }\n\n const { key, defaultProps, animation: anim } = this\n const { to: prevTo, from: prevFrom } = anim\n let { to = prevTo, from = prevFrom } = range\n\n // Focus the \"from\" value if changing without a \"to\" value.\n // For default updates, do this only if no \"to\" value exists.\n if (hasFromProp && !hasToProp && (!props.default || is.und(to))) {\n to = from\n }\n\n // Flip the current range if \"reverse\" is true.\n if (props.reverse) [to, from] = [from, to]\n\n /** The \"from\" value is changing. */\n const hasFromChanged = !isEqual(from, prevFrom)\n\n if (hasFromChanged) {\n anim.from = from\n }\n\n // Coerce \"from\" into a static value.\n from = getFluidValue(from)\n\n /** The \"to\" value is changing. */\n const hasToChanged = !isEqual(to, prevTo)\n\n if (hasToChanged) {\n this._focus(to)\n }\n\n /** The \"to\" prop is async. */\n const hasAsyncTo = isAsyncTo(props.to)\n\n const { config } = anim\n const { decay, velocity } = config\n\n // Reset to default velocity when goal values are defined.\n if (hasToProp || hasFromProp) {\n config.velocity = 0\n }\n\n // The \"runAsync\" function treats the \"config\" prop as a default,\n // so we must avoid merging it when the \"to\" prop is async.\n if (props.config && !hasAsyncTo) {\n mergeConfig(\n config,\n callProp(props.config, key!),\n // Avoid calling the same \"config\" prop twice.\n props.config !== defaultProps.config\n ? callProp(defaultProps.config, key!)\n : void 0\n )\n }\n\n // This instance might not have its Animated node yet. For example,\n // the constructor can be given props without a \"to\" or \"from\" value.\n let node = getAnimated(this)\n if (!node || is.und(to)) {\n return resolve(getFinishedResult(this, true))\n }\n\n /** When true, start at the \"from\" value. */\n const reset =\n // When `reset` is undefined, the `from` prop implies `reset: true`,\n // except for declarative updates. When `reset` is defined, there\n // must exist a value to animate from.\n is.und(props.reset)\n ? hasFromProp && !props.default\n : !is.und(from) && matchProp(props.reset, key)\n\n // The current value, where the animation starts from.\n const value = reset ? (from as T) : this.get()\n\n // The animation ends at this value, unless \"to\" is fluid.\n const goal = computeGoal(to)\n\n // Only specific types can be animated to/from.\n const isAnimatable = is.num(goal) || is.arr(goal) || isAnimatedString(goal)\n\n // When true, the value changes instantly on the next frame.\n const immediate =\n !hasAsyncTo &&\n (!isAnimatable ||\n matchProp(defaultProps.immediate || props.immediate, key))\n\n if (hasToChanged) {\n const nodeType = getAnimatedType(to)\n if (nodeType !== node.constructor) {\n if (immediate) {\n node = this._set(goal)!\n } else\n throw Error(\n `Cannot animate between ${node.constructor.name} and ${nodeType.name}, as the \"to\" prop suggests`\n )\n }\n }\n\n // The type of Animated node for the goal value.\n const goalType = node.constructor\n\n // When the goal value is fluid, we don't know if its value\n // will change before the next animation frame, so it always\n // starts the animation to be safe.\n let started = hasFluidValue(to)\n let finished = false\n\n if (!started) {\n // When true, the current value has probably changed.\n const hasValueChanged = reset || (!hasAnimated(this) && hasFromChanged)\n\n // When the \"to\" value or current value are changed,\n // start animating if not already finished.\n if (hasToChanged || hasValueChanged) {\n finished = isEqual(computeGoal(value), goal)\n started = !finished\n }\n\n // Changing \"decay\" or \"velocity\" starts the animation.\n if (\n (!isEqual(anim.immediate, immediate) && !immediate) ||\n !isEqual(config.decay, decay) ||\n !isEqual(config.velocity, velocity)\n ) {\n started = true\n }\n }\n\n // Was the goal value set to the current value while animating?\n if (finished && isAnimating(this)) {\n // If the first frame has passed, allow the animation to\n // overshoot instead of stopping abruptly.\n if (anim.changed && !reset) {\n started = true\n }\n // Stop the animation before its first frame.\n else if (!started) {\n this._stop(prevTo)\n }\n }\n\n if (!hasAsyncTo) {\n // Make sure our \"toValues\" are updated even if our previous\n // \"to\" prop is a fluid value whose current value is also ours.\n if (started || hasFluidValue(prevTo)) {\n anim.values = node.getPayload()\n anim.toValues = hasFluidValue(to)\n ? null\n : goalType == AnimatedString\n ? [1]\n : toArray(goal)\n }\n\n if (anim.immediate != immediate) {\n anim.immediate = immediate\n\n // Ensure the immediate goal is used as from value.\n if (!immediate && !reset) {\n this._set(prevTo)\n }\n }\n\n if (started) {\n const { onRest } = anim\n\n // Set the active handlers when an animation starts.\n each(ACTIVE_EVENTS, type => mergeActiveFn(this, props, type))\n\n const result = getFinishedResult(this, checkFinished(this, prevTo))\n flushCalls(this._pendingCalls, result)\n this._pendingCalls.add(resolve)\n\n if (anim.changed)\n raf.batchedUpdates(() => {\n // Ensure `onStart` can be called after a reset.\n anim.changed = !reset\n\n // Call the active `onRest` handler from the interrupted animation.\n onRest?.(result, this)\n\n // Notify the default `onRest` of the reset, but wait for the\n // first frame to pass before sending an `onStart` event.\n if (reset) {\n callProp(defaultProps.onRest, result)\n }\n // Call the active `onStart` handler here since the first frame\n // has already passed, which means this is a goal update and not\n // an entirely new animation.\n else {\n anim.onStart?.(result, this)\n }\n })\n }\n }\n\n if (reset) {\n this._set(value)\n }\n\n if (hasAsyncTo) {\n resolve(runAsync(props.to, props, this._state, this))\n }\n\n // Start an animation\n else if (started) {\n this._start()\n }\n\n // Postpone promise resolution until the animation is finished,\n // so that no-op updates still resolve at the expected time.\n else if (isAnimating(this) && !hasToChanged) {\n this._pendingCalls.add(resolve)\n }\n\n // Resolve our promise immediately.\n else {\n resolve(getNoopResult(value))\n }\n }\n\n /** Update the `animation.to` value, which might be a `FluidValue` */\n protected _focus(value: T | FluidValue) {\n const anim = this.animation\n if (value !== anim.to) {\n if (getFluidObservers(this)) {\n this._detach()\n }\n anim.to = value\n if (getFluidObservers(this)) {\n this._attach()\n }\n }\n }\n\n protected _attach() {\n let priority = 0\n\n const { to } = this.animation\n if (hasFluidValue(to)) {\n addFluidObserver(to, this)\n if (isFrameValue(to)) {\n priority = to.priority + 1\n }\n }\n\n this.priority = priority\n }\n\n protected _detach() {\n const { to } = this.animation\n if (hasFluidValue(to)) {\n removeFluidObserver(to, this)\n }\n }\n\n /**\n * Update the current value from outside the frameloop,\n * and return the `Animated` node.\n */\n protected _set(arg: T | FluidValue, idle = true): Animated | undefined {\n const value = getFluidValue(arg)\n if (!is.und(value)) {\n const oldNode = getAnimated(this)\n if (!oldNode || !isEqual(value, oldNode.getValue())) {\n // Create a new node or update the existing node.\n const nodeType = getAnimatedType(value)\n if (!oldNode || oldNode.constructor != nodeType) {\n setAnimated(this, nodeType.create(value))\n } else {\n oldNode.setValue(value)\n }\n // Never emit a \"change\" event for the initial value.\n if (oldNode) {\n raf.batchedUpdates(() => {\n this._onChange(value, idle)\n })\n }\n }\n }\n return getAnimated(this)\n }\n\n protected _onStart() {\n const anim = this.animation\n if (!anim.changed) {\n anim.changed = true\n sendEvent(\n this,\n 'onStart',\n getFinishedResult(this, checkFinished(this, anim.to)),\n this\n )\n }\n }\n\n protected _onChange(value: T, idle?: boolean) {\n if (!idle) {\n this._onStart()\n callProp(this.animation.onChange, value, this)\n }\n callProp(this.defaultProps.onChange, value, this)\n super._onChange(value, idle)\n }\n\n // This method resets the animation state (even if already animating) to\n // ensure the latest from/to range is used, and it also ensures this spring\n // is added to the frameloop.\n protected _start() {\n const anim = this.animation\n\n // Reset the state of each Animated node.\n getAnimated(this)!.reset(getFluidValue(anim.to))\n\n // Use the current values as the from values.\n if (!anim.immediate) {\n anim.fromValues = anim.values.map(node => node.lastPosition)\n }\n\n if (!isAnimating(this)) {\n setActiveBit(this, true)\n if (!isPaused(this)) {\n this._resume()\n }\n }\n }\n\n protected _resume() {\n // The \"skipAnimation\" global avoids the frameloop.\n if (G.skipAnimation) {\n this.finish()\n } else {\n frameLoop.start(this)\n }\n }\n\n /**\n * Exit the frameloop and notify `onRest` listeners.\n *\n * Always wrap `_stop` calls with `batchedUpdates`.\n */\n protected _stop(goal?: any, cancel?: boolean) {\n if (isAnimating(this)) {\n setActiveBit(this, false)\n\n const anim = this.animation\n each(anim.values, node => {\n node.done = true\n })\n\n // These active handlers must be reset to undefined or else\n // they could be called while idle. But keep them defined\n // when the goal value is dynamic.\n if (anim.toValues) {\n anim.onChange = anim.onPause = anim.onResume = undefined\n }\n\n callFluidObservers(this, {\n type: 'idle',\n parent: this,\n })\n\n const result = cancel\n ? getCancelledResult(this.get())\n : getFinishedResult(this.get(), checkFinished(this, goal ?? anim.to))\n\n flushCalls(this._pendingCalls, result)\n if (anim.changed) {\n anim.changed = false\n sendEvent(this, 'onRest', result, this)\n }\n }\n }\n}\n\n/** Returns true when the current value and goal value are equal. */\nfunction checkFinished