@sweberdev/lagrangian 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/dist/index.js ADDED
@@ -0,0 +1,1112 @@
1
+ var __typeError = (msg) => {
2
+ throw TypeError(msg);
3
+ };
4
+ var __accessCheck = (obj, member, msg) => member.has(obj) || __typeError("Cannot " + msg);
5
+ var __privateGet = (obj, member, getter) => (__accessCheck(obj, member, "read from private field"), getter ? getter.call(obj) : member.get(obj));
6
+ var __privateAdd = (obj, member, value2) => member.has(obj) ? __typeError("Cannot add the same private member more than once") : member instanceof WeakSet ? member.add(obj) : member.set(obj, value2);
7
+ var __privateSet = (obj, member, value2, setter) => (__accessCheck(obj, member, "write to private field"), setter ? setter.call(obj, value2) : member.set(obj, value2), value2);
8
+ var __privateMethod = (obj, member, method) => (__accessCheck(obj, member, "access private method"), method);
9
+
10
+ // src/spring.ts
11
+ function springParams(options = {}) {
12
+ const mass = options.mass ?? 1;
13
+ if (options.duration !== void 0 || options.bounce !== void 0) {
14
+ const duration = Math.max(options.duration ?? 0.5, 0.01);
15
+ const bounce = Math.min(Math.max(options.bounce ?? 0, -0.99), 1);
16
+ const omega = 2 * Math.PI / duration;
17
+ const zeta = bounce >= 0 ? 1 - bounce : 1 / (1 + bounce);
18
+ return { stiffness: mass * omega * omega, damping: 2 * mass * zeta * omega, mass };
19
+ }
20
+ return { stiffness: options.stiffness ?? 170, damping: options.damping ?? 26, mass };
21
+ }
22
+ function dampingRatio(options = {}) {
23
+ const { stiffness, damping, mass } = springParams(options);
24
+ return damping / (2 * Math.sqrt(stiffness * mass));
25
+ }
26
+ function restThresholds(from, to, options = {}) {
27
+ const span = Math.max(Math.abs(to - from), Math.abs(to) * 0.01, 1e-3);
28
+ const restDelta = options.restDelta ?? Math.min(Math.max(span * 1e-3, 1e-4), 0.5);
29
+ return { restDelta, restSpeed: options.restSpeed ?? restDelta * 10 };
30
+ }
31
+ function spring(from, to, velocity = 0, options = {}) {
32
+ const { stiffness: k, damping: c, mass: m } = springParams(options);
33
+ const { restDelta, restSpeed } = restThresholds(from, to, options);
34
+ const d0 = from - to;
35
+ const v0 = velocity;
36
+ const w0 = Math.sqrt(k / m);
37
+ const zeta = c / (2 * Math.sqrt(k * m));
38
+ let displacement;
39
+ if (zeta < 1 - 1e-6) {
40
+ const a = zeta * w0;
41
+ const wd = w0 * Math.sqrt(1 - zeta * zeta);
42
+ const B = (v0 + a * d0) / wd;
43
+ displacement = (t) => {
44
+ const e = Math.exp(-a * t);
45
+ const cos = Math.cos(wd * t);
46
+ const sin = Math.sin(wd * t);
47
+ return [e * (d0 * cos + B * sin), e * ((B * wd - a * d0) * cos - (a * B + d0 * wd) * sin)];
48
+ };
49
+ } else if (zeta <= 1 + 1e-6) {
50
+ const B = v0 + w0 * d0;
51
+ displacement = (t) => {
52
+ const e = Math.exp(-w0 * t);
53
+ return [e * (d0 + B * t), e * (v0 - w0 * B * t)];
54
+ };
55
+ } else {
56
+ const s = Math.sqrt(zeta * zeta - 1);
57
+ const r1 = -w0 * (zeta - s);
58
+ const r2 = -w0 * (zeta + s);
59
+ const c1 = (v0 - r2 * d0) / (r1 - r2);
60
+ const c2 = d0 - c1;
61
+ displacement = (t) => {
62
+ const e1 = Math.exp(r1 * t);
63
+ const e2 = Math.exp(r2 * t);
64
+ return [c1 * e1 + c2 * e2, c1 * r1 * e1 + c2 * r2 * e2];
65
+ };
66
+ }
67
+ return (t) => {
68
+ const [x, v] = displacement(Math.max(t, 0));
69
+ if (Math.abs(x) <= restDelta && Math.abs(v) <= restSpeed) {
70
+ return { value: to, velocity: 0, done: true };
71
+ }
72
+ return { value: to + x, velocity: v, done: false };
73
+ };
74
+ }
75
+ function settleTime(motion, limit = 30) {
76
+ for (let t = 0; t <= limit; t += 1 / 1e3) {
77
+ if (motion(t).done) return t;
78
+ }
79
+ return Number.POSITIVE_INFINITY;
80
+ }
81
+ function restValue(motion, limit = 30) {
82
+ for (let t = 0; t <= limit; t += 1 / 60) {
83
+ const state = motion(t);
84
+ if (state.done) return state.value;
85
+ }
86
+ return motion(limit).value;
87
+ }
88
+
89
+ // src/decay.ts
90
+ var EDGE_SPRING = { stiffness: 400, damping: 40 };
91
+ function timeConstant(deceleration = 0.998) {
92
+ const rate = Math.min(Math.max(deceleration, 0.5), 0.99999);
93
+ return -1 / (1e3 * Math.log(rate));
94
+ }
95
+ function projectRest(from, velocity, deceleration = 0.998) {
96
+ return from + velocity * timeConstant(deceleration);
97
+ }
98
+ function nearest(points, value2) {
99
+ let best = value2;
100
+ let distance = Number.POSITIVE_INFINITY;
101
+ for (const point of points) {
102
+ const d = Math.abs(point - value2);
103
+ if (d < distance) {
104
+ distance = d;
105
+ best = point;
106
+ }
107
+ }
108
+ return best;
109
+ }
110
+ function resolveSnap(snap, value2) {
111
+ return typeof snap === "function" ? snap(value2) : nearest(snap, value2);
112
+ }
113
+ function friction(from, v0, tau, end, restDelta) {
114
+ return (t) => {
115
+ const e = Math.exp(-Math.max(t, 0) / tau);
116
+ const value2 = from + v0 * tau * (1 - e);
117
+ const velocity = v0 * e;
118
+ if (Math.abs(end - value2) <= restDelta) return { value: end, velocity: 0, done: true };
119
+ return { value: value2, velocity, done: false };
120
+ };
121
+ }
122
+ function decay(from, options = {}) {
123
+ const v0 = options.velocity ?? 0;
124
+ const tau = timeConstant(options.deceleration);
125
+ const restDelta = options.restDelta ?? 0.5;
126
+ const min = options.min ?? Number.NEGATIVE_INFINITY;
127
+ const max = options.max ?? Number.POSITIVE_INFINITY;
128
+ const edge = { ...EDGE_SPRING, restDelta, ...options.bounce };
129
+ const clamp = (x) => Math.min(Math.max(x, min), max);
130
+ if (from < min || from > max) return spring(from, clamp(from), v0, edge);
131
+ const natural = from + v0 * tau;
132
+ if (options.snap !== void 0) {
133
+ const target = clamp(resolveSnap(options.snap, natural));
134
+ const distance = target - from;
135
+ const fitted = v0 !== 0 ? distance / v0 : -1;
136
+ if (fitted > tau / 4 && fitted < tau * 4) return friction(from, v0, fitted, target, restDelta);
137
+ return spring(from, target, v0, { ...edge, ...options.bounce });
138
+ }
139
+ if (natural >= min && natural <= max) return friction(from, v0, tau, natural, restDelta);
140
+ const bound = natural < min ? min : max;
141
+ const crossing = -tau * Math.log(1 - (bound - from) / (v0 * tau));
142
+ const glide = friction(from, v0, tau, natural, 0);
143
+ const vAtEdge = v0 * Math.exp(-crossing / tau);
144
+ const catcher = spring(bound, bound, vAtEdge, edge);
145
+ return (t) => t < crossing ? glide(t) : catcher(t - crossing);
146
+ }
147
+ function rubberband(distance, dimension, constant = 0.55) {
148
+ if (dimension <= 0 || constant <= 0) return 0;
149
+ const sign = Math.sign(distance);
150
+ const d = Math.abs(distance);
151
+ return sign * (1 - 1 / (d * constant / dimension + 1)) * dimension;
152
+ }
153
+ function rubberClamp(value2, min, max, dimension, constant = 0.55) {
154
+ if (value2 < min) return min + rubberband(value2 - min, dimension, constant);
155
+ if (value2 > max) return max + rubberband(value2 - max, dimension, constant);
156
+ return value2;
157
+ }
158
+
159
+ // src/loop.ts
160
+ var MAX_DT = 1 / 20;
161
+ var tasks = /* @__PURE__ */ new Set();
162
+ var scheduled = false;
163
+ var manual = false;
164
+ var last = -1;
165
+ var clock = 0;
166
+ var hasRaf = () => typeof requestAnimationFrame === "function";
167
+ function schedule() {
168
+ if (scheduled || manual || tasks.size === 0) return;
169
+ scheduled = true;
170
+ if (hasRaf()) requestAnimationFrame(frame);
171
+ else setTimeout(() => frame(now()), 16);
172
+ }
173
+ function frame(time) {
174
+ scheduled = false;
175
+ if (manual) return;
176
+ const dt = last < 0 ? 1 / 60 : Math.min(Math.max((time - last) / 1e3, 0), MAX_DT);
177
+ last = time;
178
+ run(dt, time);
179
+ if (tasks.size > 0) schedule();
180
+ else last = -1;
181
+ }
182
+ function run(dt, time) {
183
+ for (const task of [...tasks]) {
184
+ if (tasks.has(task)) task(dt, time);
185
+ }
186
+ }
187
+ function now() {
188
+ if (manual) return clock;
189
+ return typeof performance !== "undefined" ? performance.now() : Date.now();
190
+ }
191
+ var loop = {
192
+ /** Runs `task` on every frame until the returned function is called. */
193
+ add(task) {
194
+ tasks.add(task);
195
+ schedule();
196
+ return () => {
197
+ tasks.delete(task);
198
+ };
199
+ },
200
+ /**
201
+ * Switches to manual stepping (for tests, server rendering or video export) or back to
202
+ * requestAnimationFrame.
203
+ */
204
+ manual(on = true) {
205
+ manual = on;
206
+ last = -1;
207
+ if (!on) schedule();
208
+ },
209
+ /** Advances the manual clock by `ms` and runs one frame. Only has an effect in manual mode. */
210
+ step(ms = 1e3 / 60) {
211
+ if (!manual) return;
212
+ clock += ms;
213
+ run(Math.min(ms / 1e3, MAX_DT), clock);
214
+ },
215
+ /** Number of running tasks. */
216
+ get size() {
217
+ return tasks.size;
218
+ }
219
+ };
220
+
221
+ // src/reduced-motion.ts
222
+ var mode = "user";
223
+ function setReducedMotion(value2) {
224
+ mode = value2;
225
+ }
226
+ function reducedMotion() {
227
+ if (mode !== "user") return mode === "always";
228
+ return typeof matchMedia === "function" && matchMedia("(prefers-reduced-motion: reduce)").matches;
229
+ }
230
+
231
+ // src/velocity.ts
232
+ var WINDOW = 100;
233
+ var STALE = 60;
234
+ var _samples;
235
+ var VelocityTracker = class {
236
+ constructor() {
237
+ __privateAdd(this, _samples, []);
238
+ }
239
+ /** Adds a sample: `time` in milliseconds, `value` in any unit. */
240
+ add(time, value2) {
241
+ const samples = __privateGet(this, _samples);
242
+ const last2 = samples[samples.length - 1];
243
+ if (last2 && time <= last2.t) {
244
+ last2.x = value2;
245
+ return;
246
+ }
247
+ samples.push({ t: time, x: value2 });
248
+ while (samples.length > 2 && samples[0].t < time - WINDOW) samples.shift();
249
+ }
250
+ /** Velocity in units per second at `time` (ms). 0 when the pointer has been resting. */
251
+ velocity(time) {
252
+ const samples = __privateGet(this, _samples);
253
+ const last2 = samples[samples.length - 1];
254
+ if (!last2 || samples.length < 2) return 0;
255
+ if (time !== void 0 && time - last2.t > STALE) return 0;
256
+ const recent = samples.filter((s) => s.t >= last2.t - WINDOW);
257
+ if (recent.length < 2) return 0;
258
+ let mt = 0;
259
+ let mx = 0;
260
+ for (const s of recent) {
261
+ mt += s.t;
262
+ mx += s.x;
263
+ }
264
+ mt /= recent.length;
265
+ mx /= recent.length;
266
+ let num = 0;
267
+ let den = 0;
268
+ for (const s of recent) {
269
+ num += (s.t - mt) * (s.x - mx);
270
+ den += (s.t - mt) * (s.t - mt);
271
+ }
272
+ return den === 0 ? 0 : num / den * 1e3;
273
+ }
274
+ reset() {
275
+ __privateSet(this, _samples, []);
276
+ }
277
+ };
278
+ _samples = new WeakMap();
279
+
280
+ // src/value.ts
281
+ function settled(value2) {
282
+ const finished = Promise.resolve(value2);
283
+ return { finished, stop() {
284
+ } };
285
+ }
286
+ var _value, _velocity, _tracked, _listeners, _tracker, _cancel, _resolve, _PhysicsValue_instances, emit_fn, halt_fn;
287
+ var PhysicsValue = class {
288
+ constructor(initial2 = 0) {
289
+ __privateAdd(this, _PhysicsValue_instances);
290
+ __privateAdd(this, _value);
291
+ __privateAdd(this, _velocity, 0);
292
+ __privateAdd(this, _tracked, false);
293
+ __privateAdd(this, _listeners, /* @__PURE__ */ new Set());
294
+ __privateAdd(this, _tracker, new VelocityTracker());
295
+ __privateAdd(this, _cancel, null);
296
+ __privateAdd(this, _resolve, null);
297
+ __privateSet(this, _value, initial2);
298
+ }
299
+ get() {
300
+ return __privateGet(this, _value);
301
+ }
302
+ /** Units per second, from the running motion or from recent `set` calls. */
303
+ get velocity() {
304
+ return __privateGet(this, _tracked) ? __privateGet(this, _tracker).velocity(now()) : __privateGet(this, _velocity);
305
+ }
306
+ get animating() {
307
+ return __privateGet(this, _cancel) !== null;
308
+ }
309
+ /** Sets the value directly (e.g. while dragging). Stops any motion and tracks the velocity. */
310
+ set(value2) {
311
+ __privateMethod(this, _PhysicsValue_instances, halt_fn).call(this, false);
312
+ __privateSet(this, _tracked, true);
313
+ __privateGet(this, _tracker).add(now(), value2);
314
+ __privateSet(this, _velocity, __privateGet(this, _tracker).velocity());
315
+ __privateMethod(this, _PhysicsValue_instances, emit_fn).call(this, value2);
316
+ }
317
+ /** Sets the value and drops all momentum. */
318
+ jump(value2) {
319
+ __privateMethod(this, _PhysicsValue_instances, halt_fn).call(this, false);
320
+ __privateGet(this, _tracker).reset();
321
+ __privateSet(this, _tracked, false);
322
+ __privateSet(this, _velocity, 0);
323
+ __privateMethod(this, _PhysicsValue_instances, emit_fn).call(this, value2);
324
+ }
325
+ /** Springs to `target`, starting from the current position and velocity. */
326
+ to(target, options = {}) {
327
+ const from = __privateGet(this, _value);
328
+ return this.start(spring(from, target, options.velocity ?? this.velocity, options));
329
+ }
330
+ /** Throws the value with friction, optionally into bounds or onto snap points. */
331
+ throw(options = {}) {
332
+ return this.start(
333
+ decay(__privateGet(this, _value), { ...options, velocity: options.velocity ?? this.velocity })
334
+ );
335
+ }
336
+ /** Runs any motion. Elapsed time starts at 0 on the next frame. */
337
+ start(motion) {
338
+ __privateMethod(this, _PhysicsValue_instances, halt_fn).call(this, false);
339
+ if (reducedMotion()) {
340
+ this.jump(restValue(motion));
341
+ return settled(true);
342
+ }
343
+ let elapsed = 0;
344
+ let resolve;
345
+ const finished = new Promise((r) => {
346
+ resolve = r;
347
+ });
348
+ __privateSet(this, _resolve, resolve);
349
+ const remove = loop.add((dt) => {
350
+ elapsed += dt;
351
+ const state = motion(elapsed);
352
+ __privateSet(this, _velocity, state.velocity);
353
+ __privateMethod(this, _PhysicsValue_instances, emit_fn).call(this, state.value);
354
+ if (state.done) __privateMethod(this, _PhysicsValue_instances, halt_fn).call(this, true);
355
+ });
356
+ __privateSet(this, _cancel, remove);
357
+ __privateSet(this, _tracked, false);
358
+ __privateGet(this, _tracker).reset();
359
+ return {
360
+ finished,
361
+ stop: () => {
362
+ if (__privateGet(this, _resolve) === resolve) __privateMethod(this, _PhysicsValue_instances, halt_fn).call(this, false);
363
+ }
364
+ };
365
+ }
366
+ /** Stops where it is. The velocity is kept, so a following `to` or `throw` continues it. */
367
+ stop() {
368
+ __privateMethod(this, _PhysicsValue_instances, halt_fn).call(this, false);
369
+ }
370
+ /** Calls `listener` on every change. Returns the unsubscribe function. */
371
+ on(listener) {
372
+ __privateGet(this, _listeners).add(listener);
373
+ return () => {
374
+ __privateGet(this, _listeners).delete(listener);
375
+ };
376
+ }
377
+ };
378
+ _value = new WeakMap();
379
+ _velocity = new WeakMap();
380
+ _tracked = new WeakMap();
381
+ _listeners = new WeakMap();
382
+ _tracker = new WeakMap();
383
+ _cancel = new WeakMap();
384
+ _resolve = new WeakMap();
385
+ _PhysicsValue_instances = new WeakSet();
386
+ emit_fn = function(value2) {
387
+ __privateSet(this, _value, value2);
388
+ for (const listener of [...__privateGet(this, _listeners)]) listener(value2, __privateGet(this, _velocity));
389
+ };
390
+ halt_fn = function(completed) {
391
+ const cancel = __privateGet(this, _cancel);
392
+ const resolve = __privateGet(this, _resolve);
393
+ __privateSet(this, _cancel, null);
394
+ __privateSet(this, _resolve, null);
395
+ if (cancel) {
396
+ cancel();
397
+ if (completed) __privateSet(this, _velocity, 0);
398
+ }
399
+ resolve?.(completed);
400
+ };
401
+ function value(initial2 = 0) {
402
+ return new PhysicsValue(initial2);
403
+ }
404
+
405
+ // src/animate.ts
406
+ var TRANSFORMS = ["x", "y", "z", "rotate", "scale", "scaleX", "scaleY"];
407
+ var registry = /* @__PURE__ */ new WeakMap();
408
+ function initial(element, prop) {
409
+ if (prop === "scale" || prop === "scaleX" || prop === "scaleY") return 1;
410
+ if (prop === "opacity") {
411
+ const style = element.style;
412
+ const inline = style ? Number.parseFloat(style.opacity) : Number.NaN;
413
+ if (!Number.isNaN(inline)) return inline;
414
+ if (typeof getComputedStyle !== "function") return 1;
415
+ const computed = Number.parseFloat(getComputedStyle(element).opacity);
416
+ return Number.isNaN(computed) ? 1 : computed;
417
+ }
418
+ if (prop.startsWith("--") && typeof getComputedStyle === "function") {
419
+ const computed = Number.parseFloat(getComputedStyle(element).getPropertyValue(prop));
420
+ return Number.isNaN(computed) ? 0 : computed;
421
+ }
422
+ return 0;
423
+ }
424
+ function render(element, values) {
425
+ const style = element.style;
426
+ if (!style) return;
427
+ const get = (prop) => values.get(prop)?.get();
428
+ const parts = [];
429
+ const x = get("x");
430
+ const y = get("y");
431
+ const z = get("z");
432
+ if (x !== void 0 || y !== void 0 || z !== void 0) {
433
+ parts.push(`translate3d(${x ?? 0}px, ${y ?? 0}px, ${z ?? 0}px)`);
434
+ }
435
+ const rotate = get("rotate");
436
+ if (rotate !== void 0) parts.push(`rotate(${rotate}deg)`);
437
+ const scale = get("scale");
438
+ if (scale !== void 0) parts.push(`scale(${scale})`);
439
+ const scaleX = get("scaleX");
440
+ if (scaleX !== void 0) parts.push(`scaleX(${scaleX})`);
441
+ const scaleY = get("scaleY");
442
+ if (scaleY !== void 0) parts.push(`scaleY(${scaleY})`);
443
+ if (TRANSFORMS.some((prop) => values.has(prop))) style.transform = parts.join(" ");
444
+ const opacity = values.get("opacity");
445
+ if (opacity) style.opacity = String(Math.min(Math.max(opacity.get(), 0), 1));
446
+ for (const [prop, value2] of values) {
447
+ if (prop.startsWith("--")) style.setProperty(prop, String(value2.get()));
448
+ }
449
+ }
450
+ function getValue(element, prop) {
451
+ let values = registry.get(element);
452
+ if (!values) {
453
+ values = /* @__PURE__ */ new Map();
454
+ registry.set(element, values);
455
+ }
456
+ let v = values.get(prop);
457
+ if (!v) {
458
+ const map = values;
459
+ v = new PhysicsValue(initial(element, prop));
460
+ let queued = false;
461
+ v.on(() => {
462
+ if (queued) return;
463
+ queued = true;
464
+ queueMicrotask(() => {
465
+ queued = false;
466
+ render(element, map);
467
+ });
468
+ });
469
+ values.set(prop, v);
470
+ }
471
+ return v;
472
+ }
473
+ function elements(target) {
474
+ if (typeof target === "string") {
475
+ return typeof document === "undefined" ? [] : [...document.querySelectorAll(target)];
476
+ }
477
+ if (typeof Element !== "undefined" && target instanceof Element) return [target];
478
+ return Array.from(target);
479
+ }
480
+ function group(animations) {
481
+ const finished = Promise.all(animations.map((a) => a.finished)).then((all) => all.every(Boolean));
482
+ return {
483
+ finished,
484
+ stop: () => {
485
+ for (const a of animations) a.stop();
486
+ }
487
+ };
488
+ }
489
+ function delayed(seconds, start) {
490
+ if (seconds <= 0) return start();
491
+ let inner = null;
492
+ let stopped = false;
493
+ let resolve;
494
+ const finished = new Promise((r) => {
495
+ resolve = r;
496
+ });
497
+ const timer = setTimeout(() => {
498
+ if (stopped) return;
499
+ inner = start();
500
+ inner.finished.then(resolve);
501
+ }, seconds * 1e3);
502
+ return {
503
+ finished,
504
+ stop: () => {
505
+ stopped = true;
506
+ clearTimeout(timer);
507
+ if (inner) inner.stop();
508
+ else resolve(false);
509
+ }
510
+ };
511
+ }
512
+ function animate(target, props, options = {}) {
513
+ const { velocity, delay = 0, stagger = 0, ...spring2 } = options;
514
+ const animations = elements(target).map(
515
+ (element, index) => delayed(
516
+ delay + index * stagger,
517
+ () => group(
518
+ Object.keys(props).map(
519
+ (prop) => getValue(element, prop).to(props[prop], {
520
+ ...spring2,
521
+ ...velocity?.[prop] !== void 0 ? { velocity: velocity[prop] } : {}
522
+ })
523
+ )
524
+ )
525
+ )
526
+ );
527
+ return group(animations);
528
+ }
529
+ function set(target, props) {
530
+ for (const element of elements(target)) {
531
+ for (const prop of Object.keys(props)) {
532
+ getValue(element, prop).jump(props[prop]);
533
+ }
534
+ }
535
+ }
536
+
537
+ // src/drag.ts
538
+ var FREE = [Number.NEGATIVE_INFINITY, Number.POSITIVE_INFINITY];
539
+ function ranges(element, x, y, bounds) {
540
+ const b = typeof bounds === "function" ? bounds() : bounds;
541
+ if (!b) return { x: FREE, y: FREE };
542
+ if (typeof Element !== "undefined" && b instanceof Element) {
543
+ const outer = b.getBoundingClientRect();
544
+ const inner = element.getBoundingClientRect();
545
+ const left = inner.left - x;
546
+ const top = inner.top - y;
547
+ return {
548
+ x: [outer.left - left, outer.right - left - inner.width],
549
+ y: [outer.top - top, outer.bottom - top - inner.height]
550
+ };
551
+ }
552
+ const box = b;
553
+ return {
554
+ x: [box.left ?? FREE[0], box.right ?? FREE[1]],
555
+ y: [box.top ?? FREE[0], box.bottom ?? FREE[1]]
556
+ };
557
+ }
558
+ function draggable(element, options = {}) {
559
+ const axis = options.axis ?? "both";
560
+ const x = getValue(element, "x");
561
+ const y = getValue(element, "y");
562
+ const moveX = axis !== "y";
563
+ const moveY = axis !== "x";
564
+ let pointer = null;
565
+ let start = { px: 0, py: 0, x: 0, y: 0 };
566
+ let range = { x: FREE, y: FREE };
567
+ const info = () => ({
568
+ x: x.get(),
569
+ y: y.get(),
570
+ velocityX: x.velocity,
571
+ velocityY: y.velocity
572
+ });
573
+ const previousTouchAction = element.style.touchAction;
574
+ element.style.touchAction = axis === "x" ? "pan-y" : axis === "y" ? "pan-x" : "none";
575
+ const place = (value2, [min, max], dimension) => {
576
+ if (options.rubberband === false) return Math.min(Math.max(value2, min), max);
577
+ return rubberClamp(value2, min, max, dimension, options.rubberband ?? 0.55);
578
+ };
579
+ const down = (event) => {
580
+ if (pointer !== null || event.pointerType === "mouse" && event.button !== 0) return;
581
+ pointer = event.pointerId;
582
+ element.setPointerCapture?.(event.pointerId);
583
+ x.stop();
584
+ y.stop();
585
+ start = { px: event.clientX, py: event.clientY, x: x.get(), y: y.get() };
586
+ range = ranges(element, start.x, start.y, options.bounds);
587
+ x.jump(start.x);
588
+ y.jump(start.y);
589
+ if (moveX) x.set(start.x);
590
+ if (moveY) y.set(start.y);
591
+ options.onStart?.(info());
592
+ };
593
+ const move = (event) => {
594
+ if (event.pointerId !== pointer) return;
595
+ const viewport = typeof window !== "undefined" ? window : { innerWidth: 1e3, innerHeight: 1e3 };
596
+ if (moveX) x.set(place(start.x + event.clientX - start.px, range.x, viewport.innerWidth));
597
+ if (moveY) y.set(place(start.y + event.clientY - start.py, range.y, viewport.innerHeight));
598
+ options.onMove?.(info());
599
+ };
600
+ const release = (value2, [min, max], snap) => {
601
+ const throwOptions = {
602
+ min,
603
+ max,
604
+ bounce: options.spring,
605
+ ...options.deceleration !== void 0 ? { deceleration: options.deceleration } : {},
606
+ ...snap !== void 0 ? { snap } : {}
607
+ };
608
+ if (options.inertia !== false) {
609
+ value2.throw(throwOptions);
610
+ return;
611
+ }
612
+ value2.throw({ ...throwOptions, velocity: 0 });
613
+ };
614
+ const up = (event) => {
615
+ if (event.pointerId !== pointer) return;
616
+ pointer = null;
617
+ element.releasePointerCapture?.(event.pointerId);
618
+ options.onEnd?.(info());
619
+ if (moveX) release(x, range.x, options.snap?.x);
620
+ if (moveY) release(y, range.y, options.snap?.y);
621
+ };
622
+ element.addEventListener("pointerdown", down);
623
+ element.addEventListener("pointermove", move);
624
+ element.addEventListener("pointerup", up);
625
+ element.addEventListener("pointercancel", up);
626
+ return {
627
+ x,
628
+ y,
629
+ get dragging() {
630
+ return pointer !== null;
631
+ },
632
+ destroy() {
633
+ element.removeEventListener("pointerdown", down);
634
+ element.removeEventListener("pointermove", move);
635
+ element.removeEventListener("pointerup", up);
636
+ element.removeEventListener("pointercancel", up);
637
+ element.style.touchAction = previousTouchAction;
638
+ }
639
+ };
640
+ }
641
+
642
+ // src/integrate.ts
643
+ function rk4(state, t, dt, f) {
644
+ const n = state.length;
645
+ const add = (k, h) => state.map((s, i) => s + (k[i] ?? 0) * h);
646
+ const k1 = f(state, t);
647
+ const k2 = f(add(k1, dt / 2), t + dt / 2);
648
+ const k3 = f(add(k2, dt / 2), t + dt / 2);
649
+ const k4 = f(add(k3, dt), t + dt);
650
+ const next = new Array(n);
651
+ for (let i = 0; i < n; i++) {
652
+ next[i] = (state[i] ?? 0) + dt / 6 * ((k1[i] ?? 0) + 2 * (k2[i] ?? 0) + 2 * (k3[i] ?? 0) + (k4[i] ?? 0));
653
+ }
654
+ return next;
655
+ }
656
+ function system(f, initial2, step = 1 / 240) {
657
+ let state = [...initial2];
658
+ let time = 0;
659
+ let pending = 0;
660
+ return {
661
+ get state() {
662
+ return state;
663
+ },
664
+ get time() {
665
+ return time;
666
+ },
667
+ advance(seconds) {
668
+ pending += seconds;
669
+ while (pending >= step) {
670
+ state = rk4(state, time, step, f);
671
+ time += step;
672
+ pending -= step;
673
+ }
674
+ return state;
675
+ },
676
+ reset(next) {
677
+ state = [...next];
678
+ pending = 0;
679
+ }
680
+ };
681
+ }
682
+
683
+ // src/world.ts
684
+ var SLEEP_DISTANCE = 1;
685
+ var SLEEP_TIME = 1;
686
+ var _rate, _options, _container, _grabs, _stopLoop, _pending, _still, _snapshot, _observer, _running, _World_instances, frame_fn, moved_fn, draw_fn, spring_fn, contact_fn, walls_fn;
687
+ var World = class {
688
+ constructor(options = {}) {
689
+ __privateAdd(this, _World_instances);
690
+ this.bodies = [];
691
+ this.links = [];
692
+ this.bounds = null;
693
+ __privateAdd(this, _rate);
694
+ __privateAdd(this, _options);
695
+ __privateAdd(this, _container, null);
696
+ __privateAdd(this, _grabs, /* @__PURE__ */ new Set());
697
+ __privateAdd(this, _stopLoop, null);
698
+ __privateAdd(this, _pending, 0);
699
+ __privateAdd(this, _still, 0);
700
+ __privateAdd(this, _snapshot, []);
701
+ __privateAdd(this, _observer, null);
702
+ __privateAdd(this, _running, false);
703
+ __privateSet(this, _options, options);
704
+ this.gravity = options.gravity ?? { x: 0, y: 9.81 };
705
+ this.pixelsPerMeter = options.pixelsPerMeter ?? 500;
706
+ this.airDrag = options.airDrag ?? 0.05;
707
+ this.rollingResistance = options.rollingResistance ?? 0.05;
708
+ this.iterations = options.iterations ?? 4;
709
+ __privateSet(this, _rate, options.rate ?? 240);
710
+ this.setBounds(options.bounds ?? null);
711
+ }
712
+ /** Sets the walls. With an element, they follow its size. */
713
+ setBounds(bounds) {
714
+ __privateGet(this, _observer)?.disconnect();
715
+ __privateSet(this, _observer, null);
716
+ __privateSet(this, _container, null);
717
+ if (bounds && typeof HTMLElement !== "undefined" && bounds instanceof HTMLElement) {
718
+ __privateSet(this, _container, bounds);
719
+ const read = () => {
720
+ this.bounds = { left: 0, top: 0, right: bounds.clientWidth, bottom: bounds.clientHeight };
721
+ this.wake();
722
+ };
723
+ read();
724
+ if (typeof ResizeObserver === "function") {
725
+ __privateSet(this, _observer, new ResizeObserver(read));
726
+ __privateGet(this, _observer).observe(bounds);
727
+ }
728
+ } else {
729
+ this.bounds = bounds ?? null;
730
+ this.wake();
731
+ }
732
+ }
733
+ add(options) {
734
+ const ppm = this.pixelsPerMeter;
735
+ const r = options.radius;
736
+ const area = Math.PI * (r / ppm) ** 2;
737
+ const mass = options.fixed ? Number.POSITIVE_INFINITY : options.mass ?? area * (options.density ?? 1);
738
+ const body = {
739
+ x: options.x,
740
+ y: options.y,
741
+ vx: options.vx ?? 0,
742
+ vy: options.vy ?? 0,
743
+ angle: options.angle ?? 0,
744
+ spin: options.spin ?? 0,
745
+ radius: r,
746
+ mass,
747
+ restitution: options.restitution ?? 0.5,
748
+ friction: options.friction ?? 0.4,
749
+ fixed: options.fixed ?? false,
750
+ element: options.element ?? null,
751
+ invMass: options.fixed ? 0 : 1 / mass,
752
+ // Solid disc: I = ½·m·r², here with r in pixels so impulses stay in pixel units.
753
+ invInertia: options.fixed ? 0 : 2 / (mass * r * r)
754
+ };
755
+ this.bodies.push(body);
756
+ __privateMethod(this, _World_instances, draw_fn).call(this, body);
757
+ this.wake();
758
+ return body;
759
+ }
760
+ remove(body) {
761
+ const index = this.bodies.indexOf(body);
762
+ if (index >= 0) this.bodies.splice(index, 1);
763
+ for (let i = this.links.length - 1; i >= 0; i--) {
764
+ const link = this.links[i];
765
+ if (link.a === body || link.b === body) this.links.splice(i, 1);
766
+ }
767
+ for (const grab of __privateGet(this, _grabs)) if (grab.body === body) __privateGet(this, _grabs).delete(grab);
768
+ }
769
+ /** Connects two bodies with a damped spring. */
770
+ link(a, b, options = {}) {
771
+ const link = {
772
+ a,
773
+ b,
774
+ length: options.length ?? Math.hypot(b.x - a.x, b.y - a.y),
775
+ frequency: options.frequency ?? 4,
776
+ damping: options.damping ?? 0.3
777
+ };
778
+ this.links.push(link);
779
+ this.wake();
780
+ return link;
781
+ }
782
+ unlink(link) {
783
+ const index = this.links.indexOf(link);
784
+ if (index >= 0) this.links.splice(index, 1);
785
+ }
786
+ /** Body under a point, if any. */
787
+ bodyAt(x, y) {
788
+ for (let i = this.bodies.length - 1; i >= 0; i--) {
789
+ const body = this.bodies[i];
790
+ if ((body.x - x) ** 2 + (body.y - y) ** 2 <= body.radius ** 2) return body;
791
+ }
792
+ return null;
793
+ }
794
+ /** Pulls a body towards a moving point with a stiff spring. Released bodies keep their speed. */
795
+ grab(body, x, y) {
796
+ const grab = { body, target: { x, y } };
797
+ __privateGet(this, _grabs).add(grab);
798
+ this.wake();
799
+ return {
800
+ move: (nx, ny) => {
801
+ grab.target = { x: nx, y: ny };
802
+ this.wake();
803
+ },
804
+ release: () => {
805
+ __privateGet(this, _grabs).delete(grab);
806
+ }
807
+ };
808
+ }
809
+ /** Adds an impulse in kg·px/s at the centre (or `at` a point on the body for spin). */
810
+ push(body, impulse, at) {
811
+ body.vx += impulse.x * body.invMass;
812
+ body.vy += impulse.y * body.invMass;
813
+ if (at)
814
+ body.spin += ((at.x - body.x) * impulse.y - (at.y - body.y) * impulse.x) * body.invInertia;
815
+ this.wake();
816
+ }
817
+ /**
818
+ * Lets the pointer grab and throw bodies inside `element` (default: the bounds element).
819
+ * Returns a function that removes the listeners.
820
+ */
821
+ bindPointer(element = __privateGet(this, _container)) {
822
+ if (!element) return () => {
823
+ };
824
+ const active = /* @__PURE__ */ new Map();
825
+ const local = (event) => {
826
+ const rect = element.getBoundingClientRect();
827
+ return { x: event.clientX - rect.left, y: event.clientY - rect.top };
828
+ };
829
+ const down = (event) => {
830
+ const p = local(event);
831
+ const body = this.bodyAt(p.x, p.y);
832
+ if (!body || body.fixed) return;
833
+ event.preventDefault();
834
+ element.setPointerCapture?.(event.pointerId);
835
+ active.set(event.pointerId, this.grab(body, p.x, p.y));
836
+ };
837
+ const move = (event) => {
838
+ const grab = active.get(event.pointerId);
839
+ if (!grab) return;
840
+ const p = local(event);
841
+ grab.move(p.x, p.y);
842
+ };
843
+ const up = (event) => {
844
+ active.get(event.pointerId)?.release();
845
+ active.delete(event.pointerId);
846
+ };
847
+ const touchAction = element.style.touchAction;
848
+ element.style.touchAction = "none";
849
+ element.addEventListener("pointerdown", down);
850
+ element.addEventListener("pointermove", move);
851
+ element.addEventListener("pointerup", up);
852
+ element.addEventListener("pointercancel", up);
853
+ return () => {
854
+ for (const grab of active.values()) grab.release();
855
+ element.style.touchAction = touchAction;
856
+ element.removeEventListener("pointerdown", down);
857
+ element.removeEventListener("pointermove", move);
858
+ element.removeEventListener("pointerup", up);
859
+ element.removeEventListener("pointercancel", up);
860
+ };
861
+ }
862
+ /** Starts the simulation on the shared frame loop. */
863
+ start() {
864
+ __privateSet(this, _running, true);
865
+ this.wake();
866
+ return this;
867
+ }
868
+ /** Pauses the simulation. */
869
+ stop() {
870
+ var _a;
871
+ __privateSet(this, _running, false);
872
+ (_a = __privateGet(this, _stopLoop)) == null ? void 0 : _a.call(this);
873
+ __privateSet(this, _stopLoop, null);
874
+ return this;
875
+ }
876
+ /** True while the world runs and something moves. A resting world uses no CPU. */
877
+ get awake() {
878
+ return __privateGet(this, _stopLoop) !== null;
879
+ }
880
+ /** Resumes a resting world, e.g. after you changed bodies by hand. */
881
+ wake() {
882
+ __privateSet(this, _still, 0);
883
+ __privateSet(this, _snapshot, []);
884
+ if (!__privateGet(this, _running) || __privateGet(this, _stopLoop)) return;
885
+ __privateSet(this, _stopLoop, loop.add((dt) => __privateMethod(this, _World_instances, frame_fn).call(this, dt)));
886
+ }
887
+ destroy() {
888
+ this.stop();
889
+ __privateGet(this, _observer)?.disconnect();
890
+ this.bodies.length = 0;
891
+ this.links.length = 0;
892
+ __privateGet(this, _grabs).clear();
893
+ }
894
+ /** Advances the simulation by `dt` seconds. Called for you while the world runs. */
895
+ step(dt) {
896
+ const ppm = this.pixelsPerMeter;
897
+ const gx = this.gravity.x * ppm;
898
+ const gy = this.gravity.y * ppm;
899
+ const drag = Math.exp(-this.airDrag * dt);
900
+ for (const body of this.bodies) {
901
+ if (body.fixed) continue;
902
+ body.vx = (body.vx + gx * dt) * drag;
903
+ body.vy = (body.vy + gy * dt) * drag;
904
+ body.spin *= drag;
905
+ }
906
+ for (const link of this.links) __privateMethod(this, _World_instances, spring_fn).call(this, link, dt);
907
+ for (const { body, target } of __privateGet(this, _grabs)) {
908
+ const w = 2 * Math.PI * 8;
909
+ const k = w * w;
910
+ const c = 2 * w;
911
+ const den = 1 + dt * c + dt * dt * k;
912
+ body.vx = (body.vx + dt * k * (target.x - body.x)) / den;
913
+ body.vy = (body.vy + dt * k * (target.y - body.y)) / den;
914
+ body.spin *= 0.9;
915
+ }
916
+ for (const body of this.bodies) {
917
+ if (body.fixed) continue;
918
+ body.x += body.vx * dt;
919
+ body.y += body.vy * dt;
920
+ body.angle += body.spin * dt;
921
+ }
922
+ const bodies = [...this.bodies].sort((a, b) => a.x - a.radius - (b.x - b.radius));
923
+ const restingSpeed = 0.5 * ppm;
924
+ for (let pass = 0; pass < this.iterations; pass++) {
925
+ for (let i = 0; i < bodies.length; i++) {
926
+ const a = bodies[i];
927
+ for (let j = i + 1; j < bodies.length; j++) {
928
+ const b = bodies[j];
929
+ if (b.x - b.radius > a.x + a.radius) break;
930
+ const dx = b.x - a.x;
931
+ const dy = b.y - a.y;
932
+ const sum = a.radius + b.radius;
933
+ const d2 = dx * dx + dy * dy;
934
+ if (d2 >= sum * sum) continue;
935
+ const d = Math.sqrt(d2);
936
+ const nx = d > 1e-9 ? dx / d : 1;
937
+ const ny = d > 1e-9 ? dy / d : 0;
938
+ __privateMethod(this, _World_instances, contact_fn).call(this, a, b, nx, ny, sum - d, restingSpeed, pass === 0);
939
+ }
940
+ if (this.bounds && !a.fixed) __privateMethod(this, _World_instances, walls_fn).call(this, a, this.bounds, restingSpeed, pass === 0);
941
+ }
942
+ }
943
+ }
944
+ };
945
+ _rate = new WeakMap();
946
+ _options = new WeakMap();
947
+ _container = new WeakMap();
948
+ _grabs = new WeakMap();
949
+ _stopLoop = new WeakMap();
950
+ _pending = new WeakMap();
951
+ _still = new WeakMap();
952
+ _snapshot = new WeakMap();
953
+ _observer = new WeakMap();
954
+ _running = new WeakMap();
955
+ _World_instances = new WeakSet();
956
+ frame_fn = function(dt) {
957
+ var _a;
958
+ const h = 1 / __privateGet(this, _rate);
959
+ __privateSet(this, _pending, Math.min(__privateGet(this, _pending) + dt, h * 32));
960
+ while (__privateGet(this, _pending) >= h) {
961
+ this.step(h);
962
+ __privateSet(this, _pending, __privateGet(this, _pending) - h);
963
+ }
964
+ for (const body of this.bodies) __privateMethod(this, _World_instances, draw_fn).call(this, body);
965
+ __privateGet(this, _options).onFrame?.(this);
966
+ if (__privateGet(this, _grabs).size > 0 || __privateMethod(this, _World_instances, moved_fn).call(this)) {
967
+ __privateSet(this, _still, 0);
968
+ __privateSet(this, _snapshot, this.bodies.map((b) => [b.x, b.y, b.angle * b.radius]));
969
+ } else {
970
+ __privateSet(this, _still, __privateGet(this, _still) + dt);
971
+ }
972
+ if (__privateGet(this, _still) >= SLEEP_TIME) {
973
+ (_a = __privateGet(this, _stopLoop)) == null ? void 0 : _a.call(this);
974
+ __privateSet(this, _stopLoop, null);
975
+ }
976
+ };
977
+ moved_fn = function() {
978
+ const snapshot = __privateGet(this, _snapshot);
979
+ if (snapshot.length !== this.bodies.length) return true;
980
+ return this.bodies.some((b, i) => {
981
+ const [x, y, arc] = snapshot[i];
982
+ return Math.abs(b.x - x) > SLEEP_DISTANCE || Math.abs(b.y - y) > SLEEP_DISTANCE || Math.abs(b.angle * b.radius - arc) > SLEEP_DISTANCE;
983
+ });
984
+ };
985
+ draw_fn = function(body) {
986
+ const el = body.element;
987
+ if (!el) return;
988
+ const r = body.radius;
989
+ el.style.transform = `translate3d(${body.x - r}px, ${body.y - r}px, 0) rotate(${body.angle}rad)`;
990
+ };
991
+ spring_fn = function(link, dt) {
992
+ const { a, b } = link;
993
+ const inv = a.invMass + b.invMass;
994
+ if (inv === 0) return;
995
+ const dx = b.x - a.x;
996
+ const dy = b.y - a.y;
997
+ const d = Math.hypot(dx, dy) || 1e-9;
998
+ const nx = dx / d;
999
+ const ny = dy / d;
1000
+ const m = 1 / inv;
1001
+ const w = 2 * Math.PI * link.frequency;
1002
+ const k = m * w * w;
1003
+ const c = 2 * m * link.damping * w;
1004
+ const vn = (b.vx - a.vx) * nx + (b.vy - a.vy) * ny;
1005
+ const force = -k * (d - link.length) - c * vn;
1006
+ const j = force * dt;
1007
+ a.vx -= j * nx * a.invMass;
1008
+ a.vy -= j * ny * a.invMass;
1009
+ b.vx += j * nx * b.invMass;
1010
+ b.vy += j * ny * b.invMass;
1011
+ };
1012
+ // Resolves one contact. n points from a to b; a may be a wall (null).
1013
+ contact_fn = function(a, b, nx, ny, depth, restingSpeed, report) {
1014
+ const ima = a ? a.invMass : 0;
1015
+ const imb = b.invMass;
1016
+ const inv = ima + imb;
1017
+ if (inv === 0) return;
1018
+ const correction = Math.max(depth - 0.01, 0) / inv;
1019
+ if (a) {
1020
+ a.x -= nx * correction * ima;
1021
+ a.y -= ny * correction * ima;
1022
+ }
1023
+ b.x += nx * correction * imb;
1024
+ b.y += ny * correction * imb;
1025
+ const ra = a ? a.radius : 0;
1026
+ const rb = b.radius;
1027
+ const iia = a ? a.invInertia : 0;
1028
+ const iib = b.invInertia;
1029
+ const tx = -ny;
1030
+ const ty = nx;
1031
+ const relative = () => {
1032
+ const vax = a ? a.vx - a.spin * ra * ny : 0;
1033
+ const vay = a ? a.vy + a.spin * ra * nx : 0;
1034
+ const vbx = b.vx + b.spin * rb * ny;
1035
+ const vby = b.vy - b.spin * rb * nx;
1036
+ return { x: vbx - vax, y: vby - vay };
1037
+ };
1038
+ let rv = relative();
1039
+ const vn = rv.x * nx + rv.y * ny;
1040
+ if (vn >= 0) return;
1041
+ const e = -vn < restingSpeed ? 0 : Math.min(a ? a.restitution : 1, b.restitution);
1042
+ const jn = -(1 + e) * vn / inv;
1043
+ if (a) {
1044
+ a.vx -= jn * nx * ima;
1045
+ a.vy -= jn * ny * ima;
1046
+ }
1047
+ b.vx += jn * nx * imb;
1048
+ b.vy += jn * ny * imb;
1049
+ if (report && -vn > restingSpeed) __privateGet(this, _options).onCollide?.(b, a, -vn);
1050
+ rv = relative();
1051
+ const vt = rv.x * tx + rv.y * ty;
1052
+ const kt = inv + ra * ra * iia + rb * rb * iib;
1053
+ const mu = Math.sqrt((a ? a.friction : 1) * b.friction);
1054
+ const jt = Math.max(Math.min(-vt / kt, mu * jn), -mu * jn);
1055
+ if (a) {
1056
+ a.vx -= jt * tx * ima;
1057
+ a.vy -= jt * ty * ima;
1058
+ a.spin -= jt * ra * iia;
1059
+ }
1060
+ b.vx += jt * tx * imb;
1061
+ b.vy += jt * ty * imb;
1062
+ b.spin -= jt * rb * iib;
1063
+ const brake = (body, r) => {
1064
+ const limit = this.rollingResistance * jn * r * body.invInertia;
1065
+ body.spin = Math.abs(body.spin) <= limit ? 0 : body.spin - Math.sign(body.spin) * limit;
1066
+ };
1067
+ if (a) brake(a, ra);
1068
+ brake(b, rb);
1069
+ };
1070
+ walls_fn = function(body, walls, restingSpeed, report) {
1071
+ const r = body.radius;
1072
+ if (body.y + r > walls.bottom)
1073
+ __privateMethod(this, _World_instances, contact_fn).call(this, null, body, 0, -1, body.y + r - walls.bottom, restingSpeed, report);
1074
+ if (body.y - r < walls.top)
1075
+ __privateMethod(this, _World_instances, contact_fn).call(this, null, body, 0, 1, walls.top - (body.y - r), restingSpeed, report);
1076
+ if (body.x - r < walls.left)
1077
+ __privateMethod(this, _World_instances, contact_fn).call(this, null, body, 1, 0, walls.left - (body.x - r), restingSpeed, report);
1078
+ if (body.x + r > walls.right)
1079
+ __privateMethod(this, _World_instances, contact_fn).call(this, null, body, -1, 0, body.x + r - walls.right, restingSpeed, report);
1080
+ };
1081
+ function world(options = {}) {
1082
+ return new World(options);
1083
+ }
1084
+ export {
1085
+ PhysicsValue,
1086
+ VelocityTracker,
1087
+ World,
1088
+ animate,
1089
+ dampingRatio,
1090
+ decay,
1091
+ draggable,
1092
+ getValue,
1093
+ loop,
1094
+ nearest,
1095
+ now,
1096
+ projectRest,
1097
+ reducedMotion,
1098
+ restValue,
1099
+ rk4,
1100
+ rubberClamp,
1101
+ rubberband,
1102
+ set,
1103
+ setReducedMotion,
1104
+ settleTime,
1105
+ spring,
1106
+ springParams,
1107
+ system,
1108
+ timeConstant,
1109
+ value,
1110
+ world
1111
+ };
1112
+ //# sourceMappingURL=index.js.map