@vielzeug/necromancer 3.0.0 → 26.10.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (54) hide show
  1. package/README.md +1 -1
  2. package/dist/_elements.cjs +1 -1
  3. package/dist/_elements.cjs.map +1 -1
  4. package/dist/_elements.js +1 -7
  5. package/dist/_elements.js.map +1 -1
  6. package/dist/_handle.cjs +1 -1
  7. package/dist/_handle.cjs.map +1 -1
  8. package/dist/_handle.js +1 -54
  9. package/dist/_handle.js.map +1 -1
  10. package/dist/animate-each.cjs +1 -1
  11. package/dist/animate-each.cjs.map +1 -1
  12. package/dist/animate-each.js +1 -29
  13. package/dist/animate-each.js.map +1 -1
  14. package/dist/animate.cjs +1 -1
  15. package/dist/animate.cjs.map +1 -1
  16. package/dist/animate.js +1 -13
  17. package/dist/animate.js.map +1 -1
  18. package/dist/errors.cjs +1 -1
  19. package/dist/errors.cjs.map +1 -1
  20. package/dist/errors.js +1 -9
  21. package/dist/errors.js.map +1 -1
  22. package/dist/index.cjs +1 -1
  23. package/dist/index.d.ts +1 -0
  24. package/dist/index.d.ts.map +1 -1
  25. package/dist/index.js +1 -5
  26. package/dist/layout.cjs +1 -1
  27. package/dist/layout.cjs.map +1 -1
  28. package/dist/layout.d.ts +1 -1
  29. package/dist/layout.js +1 -96
  30. package/dist/layout.js.map +1 -1
  31. package/dist/motion.cjs +2 -0
  32. package/dist/motion.cjs.map +1 -0
  33. package/dist/{_motion.d.ts → motion.d.ts} +1 -1
  34. package/dist/motion.d.ts.map +1 -0
  35. package/dist/motion.js +2 -0
  36. package/dist/motion.js.map +1 -0
  37. package/dist/necromancer.cjs +1 -1
  38. package/dist/necromancer.cjs.map +1 -1
  39. package/dist/necromancer.iife.js +1 -1
  40. package/dist/necromancer.iife.js.map +1 -1
  41. package/dist/necromancer.js +1 -1
  42. package/dist/necromancer.js.map +1 -1
  43. package/dist/testing/index.d.ts +1 -1
  44. package/dist/testing.cjs +1 -1
  45. package/dist/testing.cjs.map +1 -1
  46. package/dist/testing.js +1 -48
  47. package/dist/testing.js.map +1 -1
  48. package/dist/types.d.ts +2 -2
  49. package/package.json +6 -6
  50. package/dist/_motion.cjs +0 -2
  51. package/dist/_motion.cjs.map +0 -1
  52. package/dist/_motion.d.ts.map +0 -1
  53. package/dist/_motion.js +0 -28
  54. package/dist/_motion.js.map +0 -1
package/dist/testing.js CHANGED
@@ -1,49 +1,2 @@
1
- //#region src/testing/index.ts
2
- var e = class {
3
- #e;
4
- #t;
5
- cancelCallCount = 0;
6
- finishCallCount = 0;
7
- finished;
8
- constructor() {
9
- this.finished = new Promise((e, t) => {
10
- this.#t = e, this.#e = t;
11
- });
12
- }
13
- cancel = () => {
14
- this.cancelCallCount += 1, this.#e(new DOMException("The animation was canceled.", "AbortError"));
15
- };
16
- finish = () => {
17
- this.finishCallCount += 1, this.#t();
18
- };
19
- };
20
- function t() {
21
- let t = [], n = Object.getOwnPropertyDescriptor(Element.prototype, "animate"), r = !1;
22
- Object.defineProperty(Element.prototype, "animate", {
23
- configurable: !0,
24
- value: (n, r) => {
25
- let i = new e();
26
- return t.push({
27
- animation: i,
28
- keyframes: n,
29
- options: r
30
- }), i;
31
- },
32
- writable: !0
33
- });
34
- let i = () => {
35
- r || (r = !0, n ? Object.defineProperty(Element.prototype, "animate", n) : Reflect.deleteProperty(Element.prototype, "animate"));
36
- };
37
- return {
38
- calls: t,
39
- restore: i,
40
- [Symbol.dispose]: i
41
- };
42
- }
43
- function n(e, t, n = 20, r = 20) {
44
- return new DOMRect(e, t, n, r);
45
- }
46
- //#endregion
47
- export { e as FakeAnimation, n as createRect, t as installFakeAnimations };
48
-
1
+ var FakeAnimation=class{#e;#t;cancelCallCount=0;finishCallCount=0;finished;constructor(){this.finished=new Promise((e,t)=>{this.#t=e,this.#e=t})}cancel=()=>{this.cancelCallCount+=1,this.#e(new DOMException(`The animation was canceled.`,`AbortError`))};finish=()=>{this.finishCallCount+=1,this.#t()}};function installFakeAnimations(){let e=[],t=Object.getOwnPropertyDescriptor(Element.prototype,`animate`),n=!1;Object.defineProperty(Element.prototype,"animate",{configurable:!0,value:(t,n)=>{let r=new FakeAnimation;return e.push({animation:r,keyframes:t,options:n}),r},writable:!0});let restore=()=>{n||(n=!0,t?Object.defineProperty(Element.prototype,"animate",t):Reflect.deleteProperty(Element.prototype,`animate`))};return{calls:e,restore,[Symbol.dispose]:restore}}function createRect(e,t,n=20,r=20){return new DOMRect(e,t,n,r)}export{FakeAnimation,createRect,installFakeAnimations};
49
2
  //# sourceMappingURL=testing.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"testing.js","names":[],"sources":["../src/testing/index.ts"],"sourcesContent":["/**\n * Testing utilities for code that calls Necromancer's animation functions.\n *\n * jsdom (and most non-browser DOM environments) do not implement `Element.animate()`,\n * so any test that exercises `animate()`, `animateEach()`, or `captureLayout()` needs a\n * substitute. This module has no test-runner import — it works the same under Vitest,\n * Jest, or any other runner; use your runner's own spy/mock APIs on top if needed.\n */\n\nexport type AnimationCall = {\n readonly animation: FakeAnimation;\n readonly keyframes: Keyframe[] | PropertyIndexedKeyframes;\n readonly options?: KeyframeAnimationOptions;\n};\n\n/** A minimal `Animation` stand-in. Call `finish()`/`cancel()` to settle it like the real API would. */\nexport class FakeAnimation {\n #reject!: (reason?: unknown) => void;\n #resolve!: () => void;\n\n /** Number of times `cancel()` has been called. */\n cancelCallCount = 0;\n /** Number of times `finish()` has been called. */\n finishCallCount = 0;\n /** Mirrors the native `Animation.finished` promise. */\n finished: Promise<void>;\n\n constructor() {\n this.finished = new Promise<void>((resolve, reject) => {\n this.#resolve = resolve;\n this.#reject = reject;\n });\n }\n\n /** Rejects `finished` with an `AbortError`, like a real cancelled `Animation`. */\n cancel = (): void => {\n this.cancelCallCount += 1;\n this.#reject(new DOMException('The animation was canceled.', 'AbortError'));\n };\n\n /** Resolves `finished`, like a real completed `Animation`. */\n finish = (): void => {\n this.finishCallCount += 1;\n this.#resolve();\n };\n}\n\n/**\n * Replaces `Element.prototype.animate` with a deterministic lifecycle fake for a test.\n * Dispose the installation or call `restore()` to restore the original implementation.\n *\n * @example\n * using animations = installFakeAnimations();\n * const handle = animate(element, [{ opacity: 0 }, { opacity: 1 }]);\n * animations.calls[0]?.animation.finish();\n * await handle.result; // { status: 'finished' }\n */\nexport function installFakeAnimations(): {\n readonly calls: readonly AnimationCall[];\n restore(): void;\n [Symbol.dispose](): void;\n} {\n const calls: AnimationCall[] = [];\n const descriptor = Object.getOwnPropertyDescriptor(Element.prototype, 'animate');\n let restored = false;\n\n Object.defineProperty(Element.prototype, 'animate', {\n configurable: true,\n value: (keyframes: Keyframe[] | PropertyIndexedKeyframes, options?: KeyframeAnimationOptions) => {\n const animation = new FakeAnimation();\n\n calls.push({ animation, keyframes, options });\n\n // Necromancer only consumes the documented Animation surface represented by FakeAnimation.\n return animation as unknown as Animation;\n },\n writable: true,\n });\n\n const restore = (): void => {\n if (restored) return;\n\n restored = true;\n if (descriptor) Object.defineProperty(Element.prototype, 'animate', descriptor);\n else Reflect.deleteProperty(Element.prototype, 'animate');\n };\n\n return {\n calls,\n restore,\n [Symbol.dispose]: restore,\n };\n}\n\n/** Builds a `DOMRect` for mocking `Element.getBoundingClientRect()` in `captureLayout()` tests. */\nexport function createRect(x: number, y: number, width = 20, height = 20): DOMRect {\n return new DOMRect(x, y, width, height);\n}\n"],"mappings":";AAgBA,IAAa,IAAb,MAA2B;CACzB;CACA;CAGA,kBAAkB;CAElB,kBAAkB;CAElB;CAEA,cAAc;EACZ,KAAK,WAAW,IAAI,SAAe,GAAS,MAAW;GAErD,AADA,KAAK,KAAW,GAChB,KAAK,KAAU;EACjB,CAAC;CACH;CAGA,eAAqB;EAEnB,AADA,KAAK,mBAAmB,GACxB,KAAK,GAAQ,IAAI,aAAa,+BAA+B,YAAY,CAAC;CAC5E;CAGA,eAAqB;EAEnB,AADA,KAAK,mBAAmB,GACxB,KAAK,GAAS;CAChB;AACF;AAYA,SAAgB,IAId;CACA,IAAM,IAAyB,CAAC,GAC1B,IAAa,OAAO,yBAAyB,QAAQ,WAAW,SAAS,GAC3E,IAAW;CAEf,OAAO,eAAe,QAAQ,WAAW,WAAW;EAClD,cAAc;EACd,QAAQ,GAAkD,MAAuC;GAC/F,IAAM,IAAY,IAAI,EAAc;GAKpC,OAHA,EAAM,KAAK;IAAE;IAAW;IAAW;GAAQ,CAAC,GAGrC;EACT;EACA,UAAU;CACZ,CAAC;CAED,IAAM,UAAsB;EACtB,MAEJ,IAAW,IACP,IAAY,OAAO,eAAe,QAAQ,WAAW,WAAW,CAAU,IACzE,QAAQ,eAAe,QAAQ,WAAW,SAAS;CAC1D;CAEA,OAAO;EACL;EACA;GACC,OAAO,UAAU;CACpB;AACF;AAGA,SAAgB,EAAW,GAAW,GAAW,IAAQ,IAAI,IAAS,IAAa;CACjF,OAAO,IAAI,QAAQ,GAAG,GAAG,GAAO,CAAM;AACxC"}
1
+ {"version":3,"file":"testing.js","names":[],"sources":["../src/testing/index.ts"],"sourcesContent":["/**\n * Testing utilities for code that calls Necromancer's animation functions.\n *\n * jsdom (and most non-browser DOM environments) do not implement `Element.animate()`,\n * so any test that exercises `animate()`, `animateEach()`, or `captureLayout()` needs a\n * substitute. This module has no test-runner import: it works the same under Vitest,\n * Jest, or any other runner; use your runner's own spy/mock APIs on top if needed.\n */\n\nexport type AnimationCall = {\n readonly animation: FakeAnimation;\n readonly keyframes: Keyframe[] | PropertyIndexedKeyframes;\n readonly options?: KeyframeAnimationOptions;\n};\n\n/** A minimal `Animation` stand-in. Call `finish()`/`cancel()` to settle it like the real API would. */\nexport class FakeAnimation {\n #reject!: (reason?: unknown) => void;\n #resolve!: () => void;\n\n /** Number of times `cancel()` has been called. */\n cancelCallCount = 0;\n /** Number of times `finish()` has been called. */\n finishCallCount = 0;\n /** Mirrors the native `Animation.finished` promise. */\n finished: Promise<void>;\n\n constructor() {\n this.finished = new Promise<void>((resolve, reject) => {\n this.#resolve = resolve;\n this.#reject = reject;\n });\n }\n\n /** Rejects `finished` with an `AbortError`, like a real cancelled `Animation`. */\n cancel = (): void => {\n this.cancelCallCount += 1;\n this.#reject(new DOMException('The animation was canceled.', 'AbortError'));\n };\n\n /** Resolves `finished`, like a real completed `Animation`. */\n finish = (): void => {\n this.finishCallCount += 1;\n this.#resolve();\n };\n}\n\n/**\n * Replaces `Element.prototype.animate` with a deterministic lifecycle fake for a test.\n * Dispose the installation or call `restore()` to restore the original implementation.\n *\n * @example\n * using animations = installFakeAnimations();\n * const handle = animate(element, [{ opacity: 0 }, { opacity: 1 }]);\n * animations.calls[0]?.animation.finish();\n * await handle.result; // { status: 'finished' }\n */\nexport function installFakeAnimations(): {\n readonly calls: readonly AnimationCall[];\n restore(): void;\n [Symbol.dispose](): void;\n} {\n const calls: AnimationCall[] = [];\n const descriptor = Object.getOwnPropertyDescriptor(Element.prototype, 'animate');\n let restored = false;\n\n Object.defineProperty(Element.prototype, 'animate', {\n configurable: true,\n value: (keyframes: Keyframe[] | PropertyIndexedKeyframes, options?: KeyframeAnimationOptions) => {\n const animation = new FakeAnimation();\n\n calls.push({ animation, keyframes, options });\n\n // Necromancer only consumes the documented Animation surface represented by FakeAnimation.\n return animation as unknown as Animation;\n },\n writable: true,\n });\n\n const restore = (): void => {\n if (restored) return;\n\n restored = true;\n if (descriptor) Object.defineProperty(Element.prototype, 'animate', descriptor);\n else Reflect.deleteProperty(Element.prototype, 'animate');\n };\n\n return {\n calls,\n restore,\n [Symbol.dispose]: restore,\n };\n}\n\n/** Builds a `DOMRect` for mocking `Element.getBoundingClientRect()` in `captureLayout()` tests. */\nexport function createRect(x: number, y: number, width = 20, height = 20): DOMRect {\n return new DOMRect(x, y, width, height);\n}\n"],"mappings":"AAgBA,IAAa,cAAb,KAA2B,CACzB,GACA,GAGA,gBAAkB,EAElB,gBAAkB,EAElB,SAEA,aAAc,CACZ,KAAK,SAAW,IAAI,SAAe,EAAS,IAAW,CACrD,KAAK,GAAW,EAChB,KAAK,GAAU,CACjB,CAAC,CACH,CAGA,WAAqB,CACnB,KAAK,iBAAmB,EACxB,KAAK,GAAQ,IAAI,aAAa,8BAA+B,YAAY,CAAC,CAC5E,EAGA,WAAqB,CACnB,KAAK,iBAAmB,EACxB,KAAK,GAAS,CAChB,CACF,EAYA,SAAgB,uBAId,CACA,IAAM,EAAyB,CAAC,EAC1B,EAAa,OAAO,yBAAyB,QAAQ,UAAW,SAAS,EAC3E,EAAW,GAEf,OAAO,eAAe,QAAQ,UAAW,UAAW,CAClD,aAAc,GACd,OAAQ,EAAkD,IAAuC,CAC/F,IAAM,EAAY,IAAI,cAKtB,OAHA,EAAM,KAAK,CAAE,YAAW,YAAW,SAAQ,CAAC,EAGrC,CACT,EACA,SAAU,EACZ,CAAC,EAED,IAAM,YAAsB,CACtB,IAEJ,EAAW,GACP,EAAY,OAAO,eAAe,QAAQ,UAAW,UAAW,CAAU,EACzE,QAAQ,eAAe,QAAQ,UAAW,SAAS,EAC1D,EAEA,MAAO,CACL,QACA,SACC,OAAO,SAAU,OACpB,CACF,CAGA,SAAgB,WAAW,EAAW,EAAW,EAAQ,GAAI,EAAS,GAAa,CACjF,OAAO,IAAI,QAAQ,EAAG,EAAG,EAAO,CAAM,CACxC"}
package/dist/types.d.ts CHANGED
@@ -21,12 +21,12 @@ export type Keyframes = readonly Keyframe[] | PropertyIndexedKeyframes;
21
21
  * string `delay`/`duration`, etc.) reaches `element.animate()` unchanged unless reduced motion
22
22
  * normalizes timing. Callers already
23
23
  * fluent in the Web Animations API bring that knowledge here directly, instead of learning
24
- * a second, smaller timing vocabulary — the option chain below only ever *adds* ownership
24
+ * a second, smaller timing vocabulary: the option chain below only ever *adds* ownership
25
25
  * fields on top, never narrows what's already native.
26
26
  *
27
27
  * Option chain: `AnimateOptions` -> `AnimateEachOptions` (+`stagger`) -> `LayoutAnimationOptions`
28
28
  * (+`elements`). Each layer's implementation module strips only the field it added before
29
- * forwarding the rest down (see `animate-each.ts`, `layout.ts`, and `_motion.ts`'s
29
+ * forwarding the rest down (see `animate-each.ts`, `layout.ts`, and `motion.ts`'s
30
30
  * `resolveAnimationOptions()`, which is the last stop and strips `motion`/`signal`).
31
31
  */
32
32
  export type AnimateOptions = KeyframeAnimationOptions & {
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@vielzeug/necromancer",
3
- "version": "3.0.0",
4
- "description": "Dependency-free, lifecycle-owned animation primitives built on the Web Animations API",
3
+ "version": "26.10.1",
4
+ "description": "Lifecycle-owned Web Animations API primitives with native access, per-handle groups, and additive FLIP",
5
5
  "repository": {
6
6
  "type": "git",
7
7
  "url": "https://github.com/helmuthdu/vielzeug",
@@ -54,10 +54,10 @@
54
54
  },
55
55
  "devDependencies": {
56
56
  "@playwright/test": "^1.63.0",
57
- "@types/node": "^26.4.1",
58
- "jsdom": "^30.0.1",
57
+ "@types/node": "^26.6.2",
58
+ "jsdom": "^30.1.1",
59
59
  "typescript": "^6.0.3",
60
- "vite": "^8.2.2",
61
- "vitest": "^5.0.0"
60
+ "vite": "^8.3.0",
61
+ "vitest": "^5.0.1"
62
62
  }
63
63
  }
package/dist/_motion.cjs DELETED
@@ -1,2 +0,0 @@
1
- const e=require("./errors.cjs");function t(e){return e===`full`?!1:e===`reduced`||typeof matchMedia==`function`&&matchMedia(`(prefers-reduced-motion: reduce)`).matches}function n(e={},t=!1){let{motion:n,signal:r,...i}=e;return t?{...i,delay:0,duration:0,endDelay:0,iterations:1}:i}function r(t,n){if(n===0)return t;let r=t.delay??0;if(typeof r!=`number`)throw new e.NecromancerConfigError(`A non-zero stagger requires a numeric delay; received ${typeof r}.`);return{...t,delay:r+n}}exports.resolveAnimationOptions=n,exports.shouldReduceMotion=t,exports.withStaggeredDelay=r;
2
- //# sourceMappingURL=_motion.cjs.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"_motion.cjs","names":[],"sources":["../src/_motion.ts"],"sourcesContent":["import { NecromancerConfigError } from './errors';\nimport type { AnimateOptions, MotionMode } from './types';\n\n/** Reports whether the requested motion preference reduces visible movement. */\nexport function shouldReduceMotion(mode: MotionMode): boolean {\n if (mode === 'full') return false;\n\n if (mode === 'reduced') return true;\n\n return typeof matchMedia === 'function' && matchMedia('(prefers-reduced-motion: reduce)').matches;\n}\n\n/** Converts ownership options to native timing, collapsing reduced motion to an instant transition. */\nexport function resolveAnimationOptions(options: AnimateOptions = {}, reduced = false): KeyframeAnimationOptions {\n const { motion: _motion, signal: _signal, ...nativeOptions } = options;\n\n return reduced ? { ...nativeOptions, delay: 0, duration: 0, endDelay: 0, iterations: 1 } : nativeOptions;\n}\n\n/** Adds an element's stagger offset without changing native nonnumeric delays when no offset is needed. */\nexport function withStaggeredDelay(options: AnimateOptions, offset: number): AnimateOptions {\n if (offset === 0) return options;\n\n const delay = options.delay ?? 0;\n\n if (typeof delay !== 'number') {\n throw new NecromancerConfigError(`A non-zero stagger requires a numeric delay; received ${typeof delay}.`);\n }\n\n return { ...options, delay: delay + offset };\n}\n"],"mappings":"gCAIA,SAAgB,EAAmB,EAA2B,CAK5D,OAJI,IAAS,OAAe,GAExB,IAAS,WAEN,OAAO,YAAe,YAAc,WAAW,kCAAkC,CAAC,CAAC,OAC5F,CAGA,SAAgB,EAAwB,EAA0B,CAAC,EAAG,EAAU,GAAiC,CAC/G,GAAM,CAAE,OAAQ,EAAS,OAAQ,EAAS,GAAG,GAAkB,EAE/D,OAAO,EAAU,CAAE,GAAG,EAAe,MAAO,EAAG,SAAU,EAAG,SAAU,EAAG,WAAY,CAAE,EAAI,CAC7F,CAGA,SAAgB,EAAmB,EAAyB,EAAgC,CAC1F,GAAI,IAAW,EAAG,OAAO,EAEzB,IAAM,EAAQ,EAAQ,OAAS,EAE/B,GAAI,OAAO,GAAU,SACnB,MAAM,IAAI,EAAA,uBAAuB,yDAAyD,OAAO,EAAM,EAAE,EAG3G,MAAO,CAAE,GAAG,EAAS,MAAO,EAAQ,CAAO,CAC7C"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"_motion.d.ts","sourceRoot":"","sources":["../src/_motion.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,cAAc,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AAE1D,gFAAgF;AAChF,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,UAAU,GAAG,OAAO,CAM5D;AAED,uGAAuG;AACvG,wBAAgB,uBAAuB,CAAC,OAAO,GAAE,cAAmB,EAAE,OAAO,UAAQ,GAAG,wBAAwB,CAI/G;AAED,2GAA2G;AAC3G,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,cAAc,EAAE,MAAM,EAAE,MAAM,GAAG,cAAc,CAU1F"}
package/dist/_motion.js DELETED
@@ -1,28 +0,0 @@
1
- import { NecromancerConfigError as e } from "./errors.js";
2
- //#region src/_motion.ts
3
- function t(e) {
4
- return e === "full" ? !1 : e === "reduced" || typeof matchMedia == "function" && matchMedia("(prefers-reduced-motion: reduce)").matches;
5
- }
6
- function n(e = {}, t = !1) {
7
- let { motion: n, signal: r, ...i } = e;
8
- return t ? {
9
- ...i,
10
- delay: 0,
11
- duration: 0,
12
- endDelay: 0,
13
- iterations: 1
14
- } : i;
15
- }
16
- function r(t, n) {
17
- if (n === 0) return t;
18
- let r = t.delay ?? 0;
19
- if (typeof r != "number") throw new e(`A non-zero stagger requires a numeric delay; received ${typeof r}.`);
20
- return {
21
- ...t,
22
- delay: r + n
23
- };
24
- }
25
- //#endregion
26
- export { n as resolveAnimationOptions, t as shouldReduceMotion, r as withStaggeredDelay };
27
-
28
- //# sourceMappingURL=_motion.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"_motion.js","names":[],"sources":["../src/_motion.ts"],"sourcesContent":["import { NecromancerConfigError } from './errors';\nimport type { AnimateOptions, MotionMode } from './types';\n\n/** Reports whether the requested motion preference reduces visible movement. */\nexport function shouldReduceMotion(mode: MotionMode): boolean {\n if (mode === 'full') return false;\n\n if (mode === 'reduced') return true;\n\n return typeof matchMedia === 'function' && matchMedia('(prefers-reduced-motion: reduce)').matches;\n}\n\n/** Converts ownership options to native timing, collapsing reduced motion to an instant transition. */\nexport function resolveAnimationOptions(options: AnimateOptions = {}, reduced = false): KeyframeAnimationOptions {\n const { motion: _motion, signal: _signal, ...nativeOptions } = options;\n\n return reduced ? { ...nativeOptions, delay: 0, duration: 0, endDelay: 0, iterations: 1 } : nativeOptions;\n}\n\n/** Adds an element's stagger offset without changing native nonnumeric delays when no offset is needed. */\nexport function withStaggeredDelay(options: AnimateOptions, offset: number): AnimateOptions {\n if (offset === 0) return options;\n\n const delay = options.delay ?? 0;\n\n if (typeof delay !== 'number') {\n throw new NecromancerConfigError(`A non-zero stagger requires a numeric delay; received ${typeof delay}.`);\n }\n\n return { ...options, delay: delay + offset };\n}\n"],"mappings":";;AAIA,SAAgB,EAAmB,GAA2B;CAK5D,OAJI,MAAS,SAAe,KAExB,MAAS,aAEN,OAAO,cAAe,cAAc,WAAW,kCAAkC,CAAC,CAAC;AAC5F;AAGA,SAAgB,EAAwB,IAA0B,CAAC,GAAG,IAAU,IAAiC;CAC/G,IAAM,EAAE,QAAQ,GAAS,QAAQ,GAAS,GAAG,MAAkB;CAE/D,OAAO,IAAU;EAAE,GAAG;EAAe,OAAO;EAAG,UAAU;EAAG,UAAU;EAAG,YAAY;CAAE,IAAI;AAC7F;AAGA,SAAgB,EAAmB,GAAyB,GAAgC;CAC1F,IAAI,MAAW,GAAG,OAAO;CAEzB,IAAM,IAAQ,EAAQ,SAAS;CAE/B,IAAI,OAAO,KAAU,UACnB,MAAM,IAAI,EAAuB,yDAAyD,OAAO,EAAM,EAAE;CAG3G,OAAO;EAAE,GAAG;EAAS,OAAO,IAAQ;CAAO;AAC7C"}