@vishinvents/aerostat 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Aerostat Contributors
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,260 @@
1
+ # Aerostat
2
+
3
+ **The missing physics the browser forgot to give you.**
4
+
5
+ ~3KB • Zero dependencies • Spring-first motion
6
+
7
+ Aerostat is the animation primitive for modern frameworks. While Svelte, React, and Solid handle the DOM, Aerostat handles **time and physics** — with automatic interrupt handling, velocity catching, and a unified spring engine.
8
+
9
+ ---
10
+
11
+ ## Why Aerostat?
12
+
13
+ | Feature | Aerostat | CSS/Web Animations | GSAP |
14
+ |---------|----------|-------------------|------|
15
+ | **Size** | ~3KB | 0KB | ~60KB |
16
+ | **Spring Physics** | Native | Needs JS | Plugin |
17
+ | **Interrupt Handling** | Automatic (WeakMap) | Manual | Manual |
18
+ | **Velocity Catching** | Built-in | None | Manual |
19
+ | **Modern Framework DX** | Svelte actions, React hooks | Generic | Generic |
20
+
21
+ **Optimized for the Modern Stack** — where the framework owns the DOM and you need physics-based motion without the bloat.
22
+
23
+ ---
24
+
25
+ ## Features
26
+
27
+ - 🎯 **Singleton Scheduler** - Single global rAF loop prevents layout thrashing
28
+ - ⚡️ **Spring Physics** - Realistic damped harmonic oscillator with velocity catching
29
+ - 🔄 **Automatic Interrupts** - WeakMap-based collision detection for smooth transitions
30
+ - 🎨 **Framework Adapters** - Tree-shakeable actions/hooks for Svelte, React, SolidJS
31
+ - 📦 **Tiny Bundle** - Core library under 3KB gzipped
32
+ - 🛠️ **TypeScript** - Full type safety with strict mode
33
+
34
+ ---
35
+
36
+ ## Installation
37
+
38
+ ```bash
39
+ npm install aerostat
40
+ ```
41
+
42
+ ---
43
+
44
+ ## Quick Start
45
+
46
+ ### Vanilla JS / TypeScript
47
+
48
+ ```ts
49
+ import { aerostat } from 'aerostat';
50
+
51
+ // Spring animation (default)
52
+ aerostat({
53
+ from: 0,
54
+ to: 100,
55
+ onUpdate: (value) => {
56
+ element.style.opacity = value / 100;
57
+ }
58
+ });
59
+
60
+ // Duration-based with easing
61
+ aerostat({
62
+ from: 0,
63
+ to: 100,
64
+ type: 'duration',
65
+ duration: 300,
66
+ easing: easeOutExpo,
67
+ onUpdate: (value) => {
68
+ element.style.transform = `translateX(${value}px)`;
69
+ }
70
+ });
71
+ ```
72
+
73
+ ### Svelte
74
+
75
+ ```svelte
76
+ <script>
77
+ import { squish } from 'aerostat/svelte';
78
+ </script>
79
+
80
+ <button use:squish>Click me</button>
81
+ ```
82
+
83
+ ### React / Next.js
84
+
85
+ ```tsx
86
+ import { createUseAnimate } from 'aerostat/react';
87
+ import * as React from 'react';
88
+
89
+ const useAnimate = createUseAnimate(React);
90
+
91
+ function Component() {
92
+ const [opacity, setOpacity] = React.useState(0);
93
+
94
+ useAnimate({
95
+ from: 0,
96
+ to: 1,
97
+ duration: 300,
98
+ onUpdate: setOpacity
99
+ });
100
+
101
+ return <div style={{ opacity }}>Fading in...</div>;
102
+ }
103
+ ```
104
+
105
+ ### SolidJS
106
+
107
+ ```tsx
108
+ import { createReactiveAnimation } from 'aerostat/solid';
109
+ import { createSignal, createEffect, onCleanup } from 'solid-js';
110
+
111
+ function Component() {
112
+ const [value, setValue] = createSignal(0);
113
+
114
+ createEffect(() => {
115
+ const controller = createReactiveAnimation({
116
+ from: 0,
117
+ to: 100,
118
+ onUpdate: setValue
119
+ });
120
+
121
+ onCleanup(() => controller.stop());
122
+ });
123
+
124
+ return <div>{value()}</div>;
125
+ }
126
+ ```
127
+
128
+ ---
129
+
130
+ ## Documentation
131
+
132
+ - [Core API Reference](./docs/API.md) - Main animation functions and types
133
+ - [Framework Adapters](./docs/FRAMEWORKS.md) - Svelte, React, and SolidJS integrations
134
+ - [Examples & Patterns](./docs/EXAMPLES.md) - Common use cases and recipes
135
+
136
+ ---
137
+
138
+ ## Core Concepts
139
+
140
+ ### Spring Physics
141
+
142
+ Springs create natural, momentum-based animations:
143
+
144
+ ```ts
145
+ aerostat({
146
+ from: 0,
147
+ to: 100,
148
+ stiffness: 170, // Higher = faster
149
+ damping: 12, // Lower = more bounce
150
+ onUpdate: (v) => element.style.left = `${v}px`
151
+ });
152
+ ```
153
+
154
+ ### Automatic Interrupts
155
+
156
+ Calling a new animation on the same target automatically stops the previous one:
157
+
158
+ ```ts
159
+ const controller = aerostat({
160
+ from: 0,
161
+ to: 100,
162
+ onUpdate: (v) => element.style.opacity = v / 100
163
+ });
164
+
165
+ // Later - this will stop the first animation
166
+ aerostat({
167
+ from: controller.getValue(),
168
+ to: 0,
169
+ velocity: controller.getVelocity(), // Catch momentum!
170
+ onUpdate: (v) => element.style.opacity = v / 100
171
+ });
172
+ ```
173
+
174
+ ### Key-Based Registry
175
+
176
+ Name animations to interrupt by key:
177
+
178
+ ```ts
179
+ aerostat({
180
+ key: 'my-animation',
181
+ from: 0,
182
+ to: 100,
183
+ onUpdate: (v) => element.style.left = `${v}px`
184
+ });
185
+
186
+ // Later - stops 'my-animation'
187
+ aerostat({
188
+ key: 'my-animation',
189
+ from: 100,
190
+ to: 200,
191
+ onUpdate: (v) => element.style.left = `${v}px`
192
+ });
193
+ ```
194
+
195
+ ---
196
+
197
+ ## Spring Presets
198
+
199
+ Four built-in presets tuned for common use cases:
200
+
201
+ ```ts
202
+ import { snappy, bouncy, smooth, heavy } from 'aerostat';
203
+
204
+ // Use directly
205
+ aerostat({ from: 0, to: 100, ...snappy, onUpdate });
206
+
207
+ // Or set globally
208
+ import { setDefaultPreset } from 'aerostat';
209
+ setDefaultPreset('snappy'); // All animations now use snappy
210
+ ```
211
+
212
+ | Preset | Stiffness | Damping | Feel |
213
+ |--------|-----------|---------|------|
214
+ | `snappy` | 400 | 30 | Quick, responsive, minimal overshoot |
215
+ | `bouncy` | 180 | 12 | Energetic, playful overshoot |
216
+ | `smooth` | 120 | 20 | Gentle, elegant, no overshoot |
217
+ | `heavy` | 100 | 18 | Weighty, deliberate, slow settle |
218
+
219
+ ---
220
+
221
+ ## Bundle Size
222
+
223
+ | Import | Size (gzipped) |
224
+ |--------|---------------|
225
+ | Core (`aerostat`) | ~2.9 KB |
226
+ | Svelte adapter | +402 B |
227
+ | React adapter | +459 B |
228
+ | SolidJS adapter | +426 B |
229
+ | Squish utility | +500 B |
230
+
231
+ Tree-shakeable - only bundle what you import.
232
+
233
+ ---
234
+
235
+ ## Browser Support
236
+
237
+ - Chrome/Edge 90+
238
+ - Firefox 88+
239
+ - Safari 14+
240
+ - All modern mobile browsers
241
+
242
+ ---
243
+
244
+ ## Contributing
245
+
246
+ PRs welcome! Please open an issue first to discuss what you'd like to change.
247
+
248
+ ---
249
+
250
+ ## License
251
+
252
+ MIT © 2026
253
+
254
+ ---
255
+
256
+ ## Credits
257
+
258
+ Built with ❤️ for the micro-interaction community.
259
+
260
+ Inspired by the physics of real-world motion and the elegance of minimal APIs.
@@ -0,0 +1,332 @@
1
+ /** Available preset names */
2
+ type PresetName = 'snappy' | 'bouncy' | 'smooth' | 'heavy';
3
+ /** Preset configuration (read-only) */
4
+ type PresetConfig = Readonly<Required<SpringConfig>>;
5
+ /**
6
+ * Snappy - Quick, responsive, minimal overshoot.
7
+ * Best for: UI state changes, toggles, micro-interactions.
8
+ * Feel: "Instant but alive"
9
+ */
10
+ declare const PRESET_SNAPPY: PresetConfig;
11
+ /**
12
+ * Bouncy - Energetic, playful overshoot.
13
+ * Best for: Success states, notifications, attention-grabbers.
14
+ * Feel: "Pop and settle"
15
+ */
16
+ declare const PRESET_BOUNCY: PresetConfig;
17
+ /**
18
+ * Smooth - Gentle, elegant, no overshoot.
19
+ * Best for: Page transitions, modals, content reveals.
20
+ * Feel: "Glide into place"
21
+ */
22
+ declare const PRESET_SMOOTH: PresetConfig;
23
+ /**
24
+ * Heavy - Weighty, deliberate, slow settle.
25
+ * Best for: Large elements, dramatic reveals, emphasis.
26
+ * Feel: "Massive and powerful"
27
+ */
28
+ declare const PRESET_HEAVY: PresetConfig;
29
+ /**
30
+ * All presets as a lookup object.
31
+ * Use individual constants (PRESET_SNAPPY, etc.) for best tree-shaking.
32
+ */
33
+ declare const presets: Readonly<Record<PresetName, PresetConfig>>;
34
+ /** Quick, responsive, minimal overshoot */
35
+ declare const snappy: Readonly<Required<SpringConfig>>;
36
+ /** Energetic, playful overshoot */
37
+ declare const bouncy: Readonly<Required<SpringConfig>>;
38
+ /** Gentle, elegant, no overshoot */
39
+ declare const smooth: Readonly<Required<SpringConfig>>;
40
+ /** Weighty, deliberate, slow settle */
41
+ declare const heavy: Readonly<Required<SpringConfig>>;
42
+ /**
43
+ * Get the current default preset configuration.
44
+ */
45
+ declare function getDefaultPreset(): PresetConfig;
46
+ /**
47
+ * Get the current default preset name.
48
+ */
49
+ declare function getDefaultPresetName(): PresetName;
50
+ /**
51
+ * Set the default preset for all animations.
52
+ * Call this at app initialization to change the global feel.
53
+ *
54
+ * @example
55
+ * ```ts
56
+ * // At app startup
57
+ * import { setDefaultPreset } from 'aerostat';
58
+ * setDefaultPreset('snappy');
59
+ *
60
+ * // All subsequent animations will use 'snappy' by default
61
+ * aerostat({ from: 0, to: 100, onUpdate: ... });
62
+ * ```
63
+ */
64
+ declare function setDefaultPreset(preset: PresetName): void;
65
+ /**
66
+ * Resolve a preset name to its configuration.
67
+ * Returns undefined if the preset doesn't exist.
68
+ */
69
+ declare function resolvePreset(name: PresetName): PresetConfig | undefined;
70
+
71
+ /**
72
+ * Spring configuration for physics-based animations.
73
+ * These values create a single "universal" spring feel.
74
+ */
75
+ interface SpringConfig {
76
+ /** Stiffness of the spring (default: 180) */
77
+ stiffness?: number;
78
+ /** Damping of the spring (default: 12) */
79
+ damping?: number;
80
+ /** Mass of the animated object (default: 1) */
81
+ mass?: number;
82
+ /** Velocity threshold to consider animation complete (default: 0.001) */
83
+ restVelocity?: number;
84
+ }
85
+ /**
86
+ * Duration-based animation configuration.
87
+ */
88
+ interface DurationConfig {
89
+ /** Duration in milliseconds (default: 300) */
90
+ duration?: number;
91
+ /** Easing function name (default: 'easeOut') */
92
+ easing?: EasingFunction;
93
+ }
94
+ /**
95
+ * Core animation configuration - the public API input.
96
+ */
97
+ interface AnimationConfig {
98
+ /** Starting value */
99
+ from: number;
100
+ /** Target value */
101
+ to: number;
102
+ /** Called on each frame with interpolated value */
103
+ onUpdate: (value: number) => void;
104
+ /** Called when animation completes naturally */
105
+ onComplete?: () => void;
106
+ /** Initial velocity (for spring animations) */
107
+ velocity?: number;
108
+ /** Delay before animation starts, in milliseconds */
109
+ delay?: number;
110
+ /** Unique key for interrupt handling - new animations with same key will stop previous ones */
111
+ key?: string | symbol;
112
+ }
113
+ /**
114
+ * Spring-based animation configuration.
115
+ */
116
+ interface SpringAnimationConfig extends AnimationConfig, SpringConfig {
117
+ /** Animation type discriminator */
118
+ type?: 'spring';
119
+ /** Use a preset instead of raw stiffness/damping values */
120
+ preset?: PresetName;
121
+ }
122
+ /**
123
+ * Duration-based animation configuration.
124
+ */
125
+ interface DurationAnimationConfig extends AnimationConfig, DurationConfig {
126
+ /** Animation type discriminator */
127
+ type: 'duration';
128
+ }
129
+ /**
130
+ * Combined animation config - accepts either spring or duration.
131
+ */
132
+ type AerostatConfig = SpringAnimationConfig | DurationAnimationConfig;
133
+ /**
134
+ * Easing function - maps progress (0-1) to eased progress (0-1).
135
+ */
136
+ type EasingFunction = (t: number) => number;
137
+ /**
138
+ * Named easing functions available in the library.
139
+ */
140
+ type EasingName = 'linear' | 'easeOutExpo' | 'easeInOutCubic';
141
+ /**
142
+ * Internal job representation for the scheduler.
143
+ * Uses mutable state for zero-allocation hot path.
144
+ */
145
+ interface AnimationJob {
146
+ /** Starting value (for duration-based interpolation) */
147
+ fromValue: number;
148
+ /** Current value */
149
+ value: number;
150
+ /** Target value */
151
+ to: number;
152
+ /** Current velocity (used by spring) */
153
+ velocity: number;
154
+ /** Update callback */
155
+ onUpdate: (value: number) => void;
156
+ /** Completion callback */
157
+ onComplete?: () => void;
158
+ /** Animation configuration */
159
+ config: ResolvedConfig;
160
+ /** Whether animation is active */
161
+ active: boolean;
162
+ /** Delay remaining (ms) */
163
+ delayRemaining: number;
164
+ /** Animation status */
165
+ status: AnimationStatus;
166
+ /** Start time (timestamp when animation began) */
167
+ startTime: number;
168
+ /** Elapsed time (accumulated, for pause/resume) */
169
+ elapsed: number;
170
+ /** Pause time (timestamp when paused, for calculating elapsed) */
171
+ pauseTime: number;
172
+ }
173
+ /**
174
+ * Internally resolved configuration with defaults applied.
175
+ */
176
+ interface ResolvedConfig {
177
+ /** Animation type */
178
+ type: 'spring' | 'duration';
179
+ /** Spring stiffness (if spring type) */
180
+ stiffness: number;
181
+ /** Spring damping (if spring type) */
182
+ damping: number;
183
+ /** Spring mass (if spring type) */
184
+ mass: number;
185
+ /** Rest velocity threshold (if spring type) */
186
+ restVelocity: number;
187
+ /** Duration in ms (if duration type) */
188
+ duration: number;
189
+ /** Easing function (if duration type) */
190
+ easing: EasingFunction;
191
+ /** Start time (if duration type) */
192
+ startTime: number;
193
+ }
194
+ /**
195
+ * Animation status.
196
+ */
197
+ type AnimationStatus = 'idle' | 'running' | 'paused' | 'completed';
198
+ /**
199
+ * Controller for an active animation.
200
+ * Provides full control over animation lifecycle.
201
+ */
202
+ interface AnimationController {
203
+ /** Stop the animation immediately and remove from scheduler */
204
+ stop: () => void;
205
+ /** Update the target value mid-animation (for spring) */
206
+ setTarget: (to: number) => void;
207
+ /** Pause the animation (maintains current state) */
208
+ pause: () => void;
209
+ /** Resume a paused animation */
210
+ resume: () => void;
211
+ /** Get current animation status */
212
+ getStatus: () => AnimationStatus;
213
+ /** Get elapsed time in milliseconds */
214
+ getElapsed: () => number;
215
+ /** Get current value */
216
+ getValue: () => number;
217
+ /** Get current velocity */
218
+ getVelocity: () => number;
219
+ /** Whether animation is currently active */
220
+ readonly active: boolean;
221
+ /** Promise-like interface for chaining animations */
222
+ then: (callback: () => void) => AnimationController;
223
+ /** Get the underlying promise for async/await */
224
+ readonly finished: Promise<void>;
225
+ }
226
+ /**
227
+ * Options for the animate() function.
228
+ * Simplified API for object-based animations.
229
+ */
230
+ interface TweenOptions {
231
+ /** Starting value */
232
+ from: number;
233
+ /** Target value - number or relative string like '+=100' or '-=50' */
234
+ to: number | string;
235
+ /** Duration in milliseconds (default: 300) */
236
+ duration?: number;
237
+ /** Delay before animation starts in milliseconds (default: 0) */
238
+ delay?: number;
239
+ /** Easing function (default: easeOutExpo) */
240
+ easing?: EasingFunction;
241
+ /** Called on each frame with interpolated value */
242
+ onUpdate: (value: number) => void;
243
+ /** Called when animation completes naturally */
244
+ onComplete?: () => void;
245
+ }
246
+ /**
247
+ * Internal task representation for WeakMap registry.
248
+ * Captures closure state for the animation.
249
+ */
250
+ interface AnimationTask {
251
+ /** Start timestamp (set after delay) */
252
+ startTime: number;
253
+ /** Duration in ms */
254
+ duration: number;
255
+ /** Delay remaining in ms */
256
+ delayRemaining: number;
257
+ /** Starting value */
258
+ from: number;
259
+ /** Target value (resolved to number) */
260
+ to: number;
261
+ /** Easing function */
262
+ easing: EasingFunction;
263
+ /** Update callback */
264
+ onUpdate: (value: number) => void;
265
+ /** Completion callback */
266
+ onComplete?: () => void;
267
+ /** Whether task is active */
268
+ active: boolean;
269
+ /** Reference to the target object */
270
+ target: object;
271
+ /** Promise resolve function for .then() chaining */
272
+ resolve?: () => void;
273
+ }
274
+
275
+ /**
276
+ * Animate a target object with automatic interrupt.
277
+ *
278
+ * If the target already has an active animation,
279
+ * it is immediately stopped (Kill-on-Collision).
280
+ *
281
+ * @param target - The object to animate (used as WeakMap key)
282
+ * @param options - Animation options
283
+ * @returns Controller for the animation
284
+ *
285
+ * @example
286
+ * ```ts
287
+ * const element = document.querySelector('.box');
288
+ *
289
+ * // Basic animation
290
+ * animate(element, {
291
+ * from: 0, to: 100,
292
+ * duration: 300,
293
+ * onUpdate: (v) => element.style.transform = `translateX(${v}px)`
294
+ * });
295
+ *
296
+ * // With delay (staggered menu items)
297
+ * animate(element, {
298
+ * from: 0, to: 1,
299
+ * duration: 200,
300
+ * delay: 100,
301
+ * onUpdate: (v) => element.style.opacity = String(v)
302
+ * });
303
+ *
304
+ * // Relative values
305
+ * animate(element, {
306
+ * from: 50, to: '+=100', // Animates to 150
307
+ * onUpdate: (v) => element.style.left = `${v}px`
308
+ * });
309
+ *
310
+ * // Chaining with .then()
311
+ * animate(element, { from: 0, to: 100, onUpdate: ... })
312
+ * .then(() => animate(element, { from: 100, to: 0, onUpdate: ... }));
313
+ *
314
+ * // Or with async/await
315
+ * await animate(element, { from: 0, to: 100, onUpdate: ... }).finished;
316
+ * ```
317
+ */
318
+ declare function animate(target: object, options: TweenOptions): AnimationController;
319
+ /**
320
+ * Check if a target has an active animation.
321
+ */
322
+ declare function hasAnimation(target: object): boolean;
323
+ /**
324
+ * Stop animation on a specific target.
325
+ */
326
+ declare function stopAnimation(target: object): void;
327
+ /**
328
+ * Get the number of active animations.
329
+ */
330
+ declare function getActiveAnimationCount(): number;
331
+
332
+ export { type AnimationController as A, type DurationAnimationConfig as D, type EasingFunction as E, PRESET_BOUNCY as P, type ResolvedConfig as R, type SpringAnimationConfig as S, type TweenOptions as T, animate as a, type EasingName as b, type AerostatConfig as c, type AnimationJob as d, type AnimationConfig as e, type AnimationStatus as f, type AnimationTask as g, type DurationConfig as h, PRESET_HEAVY as i, PRESET_SMOOTH as j, PRESET_SNAPPY as k, type PresetConfig as l, type PresetName as m, type SpringConfig as n, bouncy as o, getActiveAnimationCount as p, getDefaultPreset as q, getDefaultPresetName as r, hasAnimation as s, heavy as t, presets as u, resolvePreset as v, setDefaultPreset as w, smooth as x, snappy as y, stopAnimation as z };
@@ -0,0 +1,14 @@
1
+ import {i,d,a}from'./chunk-W7GGS6ZY.js';var C=[],O=false,E=null,h=0;function J(e){let s=h===0?0:Math.min((e-h)/1e3,.064);h=e;for(let r=C.length-1;r>=0;r--){let n=C[r];if(n.status==="paused")continue;if(n.delayRemaining>0){n.delayRemaining-=s*1e3;continue}if(n.startTime===0&&(n.startTime=e),!n.active){n.status="completed",C.splice(r,1);continue}n.elapsed=e-n.startTime;let u=false;n.config.type==="spring"?u=X(n,s):u=I(n),n.onUpdate(n.value),u||(n.active=false,n.status="completed",C.splice(r,1),n.onComplete?.());}C.length>0?E=requestAnimationFrame(J):(O=false,E=null,h=0);}function X(e,s){let{stiffness:r,damping:n,mass:u}=e.config;return d({get value(){return e.value},set value(i){e.value=i;},get velocity(){return e.velocity},set velocity(i){e.velocity=i;}},e.to,{stiffness:r,damping:n,mass:u},s)}function I(e){let{duration:s,easing:r}=e.config,n=e.elapsed,u=Math.min(n/s,1),a$1=r(u);e.value=a(e.fromValue,e.to,a$1);let i=r(Math.max(0,(n-16)/s));return e.velocity=(e.to-e.fromValue)*(a$1-i)/.016,n<s}function L(e){C.push(e),O||(O=true,h=0,E=requestAnimationFrame(J));}function U(e){let s=C.indexOf(e);s!==-1&&(C.splice(s,1),e.active=false,e.status="completed"),C.length===0&&E!==null&&(cancelAnimationFrame(E),E=null,O=false,h=0);}function M(e){e.status==="running"&&(e.status="paused",e.pauseTime=performance.now());}function N(e){if(e.status==="paused"){let s=performance.now()-e.pauseTime;e.startTime+=s,e.status="running";}}function Q(){return C.length}var w=Object.freeze({stiffness:400,damping:30,mass:1,restVelocity:.001}),$=Object.freeze({stiffness:180,damping:12,mass:1,restVelocity:.001}),H=Object.freeze({stiffness:120,damping:20,mass:1,restVelocity:.001}),q=Object.freeze({stiffness:100,damping:18,mass:2,restVelocity:.001}),z=Object.freeze({snappy:w,bouncy:$,smooth:H,heavy:q}),Z=w,j=$,ee=H,te=q,k="bouncy";function V(){return z[k]}function ne(){return k}function oe(e){k=e;}function F(e){return z[e]}var W={duration:300},b=new Map;function g(e){if(e.key!==void 0){let o=b.get(e.key);o&&o.stop();}let s=e.type??"spring",r=e.from,n=e.to,u=e.velocity??0,a=e.delay??0,i$1;if(s==="spring"){let o=e,d=(o.preset?F(o.preset):void 0)??V();i$1={type:"spring",stiffness:o.stiffness??d.stiffness,damping:o.damping??d.damping,mass:o.mass??d.mass,restVelocity:o.restVelocity??d.restVelocity,duration:0,easing:i,startTime:0};}else {let o=e;i$1={type:"duration",stiffness:0,damping:0,mass:0,restVelocity:0,duration:o.duration??W.duration,easing:o.easing??i,startTime:0};}let t={fromValue:r,value:r,to:n,velocity:u,onUpdate:e.onUpdate,...e.onComplete?{onComplete:e.onComplete}:{},config:i$1,active:true,delayRemaining:a,status:"running",startTime:0,elapsed:0,pauseTime:0};L(t);let p=true,f,l=new Promise(o=>{f=o;}),y={stop:()=>{p&&(p=false,U(t),e.key!==void 0&&b.delete(e.key),f());},setTarget:o=>{if(t.to=o,t.config.type==="duration"){let v=V();t.config.type="spring",t.config.stiffness=v.stiffness,t.config.damping=v.damping,t.config.mass=v.mass,t.config.restVelocity=v.restVelocity;}!t.active&&p&&(t.active=true,t.status="running",t.startTime=0,L(t));},pause:()=>{M(t);},resume:()=>{N(t);},getStatus:()=>t.status,getElapsed:()=>t.elapsed,getValue:()=>t.value,getVelocity:()=>t.velocity,get active(){return p&&t.active},then:o=>(l.then(o),y),get finished(){return l}};e.key!==void 0&&b.set(e.key,y);let m=t.onComplete;return t.onComplete=()=>{e.key!==void 0&&b.delete(e.key),p=false,m?.(),f();},y}function fe(e){let s=b.get(e);s&&s.stop();}function me(){for(let e of b.values())e.stop();}function de(){return b.size}var Y=e=>1-Math.pow(1-e,4);function Ce(e,s={}){let{pressScale:r=.92,pressDuration:n=80,releaseStiffness:u=500,releaseDamping:a=20}=s,i=1,t=null,p=false;function f(x){i=x,e.style.transform=`scale(${x})`;}function l(){p||(p=true,t?.stop(),t=g({from:i,to:r,type:"duration",duration:n,easing:Y,onUpdate:f}));}function y(){if(!p)return;p=false;let x=t?.getVelocity()??0;t?.stop(),t=g({from:i,to:1,type:"spring",stiffness:u,damping:a,velocity:x,onUpdate:f});}function m(x){e.setPointerCapture(x.pointerId),l();}function o(){y();}function v(){p&&y();}function d(){y();}function P(){l();}function A(){y();}function S(){l();}function c(){y();}return e.addEventListener("pointerdown",m),e.addEventListener("pointerup",o),e.addEventListener("pointerleave",v),e.addEventListener("pointercancel",d),e.addEventListener("mousedown",P),e.addEventListener("mouseup",A),e.addEventListener("touchstart",S,{passive:true}),e.addEventListener("touchend",c,{passive:true}),e.style.transformOrigin="center center",{destroy(){t?.stop(),e.removeEventListener("pointerdown",m),e.removeEventListener("pointerup",o),e.removeEventListener("pointerleave",v),e.removeEventListener("pointercancel",d),e.removeEventListener("mousedown",P),e.removeEventListener("mouseup",A),e.removeEventListener("touchstart",S),e.removeEventListener("touchend",c),e.style.transform="";}}}function he(e,s={}){let{amplitude:r=12,stiffness:n=1200,damping:u=20}=s,a=null,i=0;function t(){let f=a?.getVelocity()??0;a?.active?i:r;a?.stop();let y=a?.active?i+(i>=0?r:-r):r;a=g({from:y,to:0,velocity:f,stiffness:n,damping:u,mass:1,onUpdate:m=>{i=m,e.style.transform=`translateX(${m}px)`;},onComplete:()=>{e.style.transform="",i=0;}});}function p(){a?.stop(),e.style.transform="",i=0;}return {stop:p,shake:t,get active(){return a?.active??false}}}function Ee(e,s={}){let{amplitude:r=12,stiffness:n=1200,damping:u=20}=s;return g({from:r,to:0,stiffness:n,damping:u,mass:1,onUpdate:a=>{e.style.transform=`translateX(${a}px)`;},onComplete:()=>{e.style.transform="";}})}function Se(e,s={}){let {maxScale:r=1.05,peakOpacity:n=.6,stiffness:u=150,damping:a=25,color:i="#10b981",borderWidth:t=2}=s,p=null,f=null,l=null,m=1,o=0;function v(){if(l)return;let c=e.parentElement;if(!c)return;getComputedStyle(c).position==="static"&&(c.style.position="relative");let _=getComputedStyle(e).borderRadius||"0px";l=document.createElement("div"),l.style.cssText=`
2
+ position: absolute;
3
+ top: ${e.offsetTop-t}px;
4
+ left: ${e.offsetLeft-t}px;
5
+ width: ${e.offsetWidth+t*2}px;
6
+ height: ${e.offsetHeight+t*2}px;
7
+ border: ${t}px solid ${i};
8
+ border-radius: ${_};
9
+ pointer-events: none;
10
+ transform: scale(1);
11
+ opacity: 0;
12
+ box-sizing: border-box;
13
+ `,c.appendChild(l);}function d(){l&&(l.style.transform=`scale(${m})`,l.style.opacity=`${o}`);}function P(){v(),p?.stop(),f?.stop(),m=1,o=0,p=g({from:1,to:r,stiffness:u,damping:a,onUpdate:c=>{m=c,d();},onComplete:()=>{p=g({from:m,to:1,stiffness:u*.8,damping:a*1.2,onUpdate:c=>{m=c,d();}});}}),f=g({from:0,to:n,type:"duration",duration:100,onUpdate:c=>{o=c,d();},onComplete:()=>{f=g({from:n,to:0,type:"duration",duration:400,onUpdate:c=>{o=c,d();}});}});}function A(){p?.stop(),f?.stop(),m=1,o=0,d();}function S(){A(),l&&l.parentNode&&l.parentNode.removeChild(l),l=null;}return {pulse:P,stop:A,destroy:S,get active(){return (p?.active??false)||(f?.active??false)}}}export{L as a,U as b,M as c,N as d,Q as e,w as f,$ as g,H as h,q as i,z as j,Z as k,j as l,ee as m,te as n,V as o,ne as p,oe as q,F as r,g as s,fe as t,me as u,de as v,Ce as w,he as x,Ee as y,Se as z};//# sourceMappingURL=chunk-GZKQYUY7.js.map
14
+ //# sourceMappingURL=chunk-GZKQYUY7.js.map