motionary 8.7.0 → 8.8.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/CHANGELOG.md CHANGED
@@ -7,6 +7,18 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
7
7
 
8
8
  ## [Unreleased]
9
9
 
10
+ ## [8.8.0] - 2026-10-09
11
+
12
+ ### Added
13
+ - **2 new components (8.8)** in `motionary/components/widgets` (also in `dist/widgets.umd.js`):
14
+ - `<usa-panorama>` — 360° panorama viewer: drag / swipe to look around with inertia, slow `autorotate` (°/s, `0` off, pauses on hover / focus), ← / → keys, compass, built-in procedural landscape when no `src`; "View in XR" badge when WebXR immersive sessions are offered (`usa:xr` { mode }, `usa:xr-request`); `yaw`, `lookAt(deg)`; `usa:look` { yaw }.
15
+ - `<usa-spatial-card>` — spatial-computing window: frosted glass floating in depth, gaze highlight following the pointer, `[data-depth]` layers, `[slot=ornament]` bar below the window; eases forward on hover / focus, sinks on press; `active`; `usa:focus-depth` { active }.
16
+ - **XR / spatial pack — `motionary/fx/spatial`** (= `motionary/components/fx-spatial`, `registerSpatialPack()`, also in `registerEffectPacks()`): `portal-open` (enter), `orbit-in` (enter), `spatial-float` (loop), `depth-pop` (attention). `yawToOffset()`, `xrSupport()` (WebXR session detection).
17
+ - Showcase: 4 new gallery cards with copyable code, live demos and live Store thumbnails.
18
+
19
+ ### Accessibility
20
+ - The panorama is a focusable `img` (roledescription "panorama") with your `label`; ← / → look around; auto-rotate pauses while hovered or focused. The spatial card keeps its content in reading order, the gaze layer is `aria-hidden`. Reduced motion: no auto-rotate, inertia or depth transitions; `portal-open` / `orbit-in` just show, `spatial-float` is skipped, `depth-pop` does nothing.
21
+
10
22
  ## [8.7.0] - 2026-10-09
11
23
 
12
24
  ### Added
@@ -0,0 +1,100 @@
1
+ 'use strict';
2
+
3
+ var registry = require('../chunks/registry-BVklOepd.cjs');
4
+ require('../chunks/base-DoRUZBy-.cjs');
5
+
6
+ /** Horizontal background offset (px) of a 360° panorama `width` px wide for a `yaw` in degrees (wraps) (8.8). */
7
+ function yawToOffset(yaw, width) {
8
+ if (!width)
9
+ return 0;
10
+ const y = ((yaw % 360) + 360) % 360;
11
+ return -Math.round((y / 360) * width * 100) / 100;
12
+ }
13
+ /** Which WebXR session the browser offers: `'immersive-vr'`, `'immersive-ar'`, `'inline'` or `'none'` (8.8). */
14
+ async function xrSupport() {
15
+ const xr = typeof navigator !== 'undefined' ? navigator.xr : undefined;
16
+ if (!xr?.isSessionSupported)
17
+ return 'none';
18
+ for (const m of ['immersive-vr', 'immersive-ar', 'inline']) {
19
+ try {
20
+ if (await xr.isSessionSupported(m))
21
+ return m;
22
+ }
23
+ catch {
24
+ /* blocked by policy */
25
+ }
26
+ }
27
+ return 'none';
28
+ }
29
+ const SPATIAL_FX = [
30
+ {
31
+ name: 'portal-open',
32
+ kind: 'enter',
33
+ description: 'The element opens like a portal: a ring of light expands and the content comes through from depth (`color`).',
34
+ defaults: { color: '#a78bfa', duration: 1100 },
35
+ run: (el, o, ctx) => {
36
+ if (ctx.reduced)
37
+ return;
38
+ if (getComputedStyle(el).position === 'static') {
39
+ const prev = el.style.position;
40
+ el.style.position = 'relative';
41
+ ctx.onCleanup(() => (el.style.position = prev));
42
+ }
43
+ const ring = document.createElement('span');
44
+ ring.setAttribute('aria-hidden', 'true');
45
+ Object.assign(ring.style, { position: 'absolute', left: '50%', top: '50%', width: '20px', height: '20px', margin: '-10px 0 0 -10px', borderRadius: '50%', border: `3px solid ${o.color}`, boxShadow: `0 0 18px 4px ${o.color}, inset 0 0 12px ${o.color}`, pointerEvents: 'none' });
46
+ el.appendChild(ring);
47
+ ctx.onCleanup(() => ring.remove());
48
+ const big = Math.max(el.offsetWidth, el.offsetHeight, 80) / 10;
49
+ const a = ctx.animate(ring, [{ transform: 'scale(0)', opacity: 1 }, { transform: `scale(${big})`, opacity: 0.9, offset: 0.6 }, { transform: `scale(${big * 1.2})`, opacity: 0 }], { duration: o.duration, easing: 'cubic-bezier(.2,.8,.2,1)' });
50
+ const b = ctx.animate(el, [{ clipPath: 'circle(0% at 50% 50%)', transform: 'perspective(700px) translateZ(-200px)' }, { clipPath: 'circle(75% at 50% 50%)', transform: 'none' }], { duration: o.duration, easing: 'cubic-bezier(.2,.8,.2,1)', fill: 'backwards' });
51
+ const end = () => ring.remove();
52
+ return Promise.all([a?.finished.catch(() => undefined), b?.finished.catch(() => undefined)]).then(end, end);
53
+ },
54
+ },
55
+ {
56
+ name: 'orbit-in',
57
+ kind: 'enter',
58
+ description: 'The element swings in around the vertical axis like a spatial window placed beside you (`from`).',
59
+ defaults: { from: 'left', duration: 900 },
60
+ run: (el, o, ctx) => {
61
+ if (ctx.reduced)
62
+ return;
63
+ const s = o.from === 'right' ? 1 : -1;
64
+ return ctx.animate(el, [{ transform: `perspective(900px) translateX(${s * 60}%) rotateY(${-s * 70}deg) translateZ(-120px)`, opacity: 0 }, { transform: 'none', opacity: 1 }], { duration: o.duration, easing: 'cubic-bezier(.2,.9,.25,1)', fill: 'backwards' })?.finished.catch(() => undefined);
65
+ },
66
+ },
67
+ {
68
+ name: 'spatial-float',
69
+ kind: 'loop',
70
+ description: 'A gentle floating in depth with a breathing shadow, until the cleanup runs.',
71
+ defaults: { duration: 4200 },
72
+ run: (el, o, ctx) => {
73
+ if (ctx.reduced)
74
+ return;
75
+ const a = ctx.animate(el, [{ transform: 'perspective(800px) translateZ(0) translateY(0)', boxShadow: '0 14px 30px -18px rgba(15,23,42,.5)' }, { transform: 'perspective(800px) translateZ(24px) translateY(-6px)', boxShadow: '0 30px 50px -22px rgba(15,23,42,.45)' }, { transform: 'perspective(800px) translateZ(0) translateY(0)', boxShadow: '0 14px 30px -18px rgba(15,23,42,.5)' }], { duration: o.duration, iterations: Infinity, easing: 'ease-in-out' });
76
+ return () => a?.cancel();
77
+ },
78
+ },
79
+ {
80
+ name: 'depth-pop',
81
+ kind: 'attention',
82
+ description: 'The element pops forward towards the viewer and settles back.',
83
+ defaults: { duration: 600 },
84
+ run: (el, o, ctx) => {
85
+ if (ctx.reduced)
86
+ return;
87
+ return ctx.animate(el, [{ transform: 'perspective(700px) translateZ(0)' }, { transform: 'perspective(700px) translateZ(90px)', filter: 'brightness(1.1)', offset: 0.35 }, { transform: 'perspective(700px) translateZ(-10px)', offset: 0.7 }, { transform: 'perspective(700px) translateZ(0)' }], { duration: o.duration, easing: 'ease-out' })?.finished.catch(() => undefined);
88
+ },
89
+ },
90
+ ];
91
+ /** Register portal-open, orbit-in, spatial-float and depth-pop (8.8). */
92
+ function registerSpatialPack() {
93
+ registry.registerEffects(SPATIAL_FX);
94
+ }
95
+
96
+ exports.SPATIAL_FX = SPATIAL_FX;
97
+ exports.registerSpatialPack = registerSpatialPack;
98
+ exports.xrSupport = xrSupport;
99
+ exports.yawToOffset = yawToOffset;
100
+ //# sourceMappingURL=fx-spatial.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"fx-spatial.cjs","sources":["../../src/components/fx2/spatial.ts"],"sourcesContent":["/**\n * 8.8 — XR / spatial pack (`motionary/fx/spatial`, also `motionary/components/fx-spatial`):\n *\n * - `portal-open` (enter) — the element opens like a portal: a ring of\n * light expands and the content comes through from depth (`color`).\n * - `orbit-in` (enter) — the element swings in around the vertical axis\n * like a spatial window placed beside you (`from` left|right).\n * - `spatial-float` (loop) — a gentle floating in depth with a breathing\n * shadow; the cleanup stops it.\n * - `depth-pop` (attention) — the element pops forward towards the viewer\n * and settles back.\n *\n * Reduced motion: portal-open / orbit-in just show, spatial-float is\n * skipped, depth-pop does nothing.\n */\nimport type { EffectContext, EffectDefinition } from '../fx/registry';\nimport { registerEffects } from '../fx/registry';\n\n/** Horizontal background offset (px) of a 360° panorama `width` px wide for a `yaw` in degrees (wraps) (8.8). */\nexport function yawToOffset(yaw: number, width: number): number {\n if (!width) return 0;\n const y = ((yaw % 360) + 360) % 360;\n return -Math.round((y / 360) * width * 100) / 100;\n}\n\n/** Which WebXR session the browser offers: `'immersive-vr'`, `'immersive-ar'`, `'inline'` or `'none'` (8.8). */\nexport async function xrSupport(): Promise<'immersive-vr' | 'immersive-ar' | 'inline' | 'none'> {\n const xr = typeof navigator !== 'undefined' ? (navigator as any).xr : undefined;\n if (!xr?.isSessionSupported) return 'none';\n for (const m of ['immersive-vr', 'immersive-ar', 'inline'] as const) {\n try {\n if (await xr.isSessionSupported(m)) return m;\n } catch {\n /* blocked by policy */\n }\n }\n return 'none';\n}\n\nexport const SPATIAL_FX: EffectDefinition[] = [\n {\n name: 'portal-open',\n kind: 'enter',\n description: 'The element opens like a portal: a ring of light expands and the content comes through from depth (`color`).',\n defaults: { color: '#a78bfa', duration: 1100 },\n run: (el: HTMLElement, o: any, ctx: EffectContext) => {\n if (ctx.reduced) return;\n if (getComputedStyle(el).position === 'static') {\n const prev = el.style.position;\n el.style.position = 'relative';\n ctx.onCleanup(() => (el.style.position = prev));\n }\n const ring = document.createElement('span');\n ring.setAttribute('aria-hidden', 'true');\n Object.assign(ring.style, { position: 'absolute', left: '50%', top: '50%', width: '20px', height: '20px', margin: '-10px 0 0 -10px', borderRadius: '50%', border: `3px solid ${o.color}`, boxShadow: `0 0 18px 4px ${o.color}, inset 0 0 12px ${o.color}`, pointerEvents: 'none' });\n el.appendChild(ring);\n ctx.onCleanup(() => ring.remove());\n const big = Math.max(el.offsetWidth, el.offsetHeight, 80) / 10;\n const a = ctx.animate(ring, [{ transform: 'scale(0)', opacity: 1 }, { transform: `scale(${big})`, opacity: 0.9, offset: 0.6 }, { transform: `scale(${big * 1.2})`, opacity: 0 }], { duration: o.duration, easing: 'cubic-bezier(.2,.8,.2,1)' });\n const b = ctx.animate(el, [{ clipPath: 'circle(0% at 50% 50%)', transform: 'perspective(700px) translateZ(-200px)' }, { clipPath: 'circle(75% at 50% 50%)', transform: 'none' }], { duration: o.duration, easing: 'cubic-bezier(.2,.8,.2,1)', fill: 'backwards' });\n const end = () => ring.remove();\n return Promise.all([a?.finished.catch(() => undefined), b?.finished.catch(() => undefined)]).then(end, end);\n },\n },\n {\n name: 'orbit-in',\n kind: 'enter',\n description: 'The element swings in around the vertical axis like a spatial window placed beside you (`from`).',\n defaults: { from: 'left', duration: 900 },\n run: (el: HTMLElement, o: any, ctx: EffectContext) => {\n if (ctx.reduced) return;\n const s = o.from === 'right' ? 1 : -1;\n return ctx.animate(el, [{ transform: `perspective(900px) translateX(${s * 60}%) rotateY(${-s * 70}deg) translateZ(-120px)`, opacity: 0 }, { transform: 'none', opacity: 1 }], { duration: o.duration, easing: 'cubic-bezier(.2,.9,.25,1)', fill: 'backwards' })?.finished.catch(() => undefined);\n },\n },\n {\n name: 'spatial-float',\n kind: 'loop',\n description: 'A gentle floating in depth with a breathing shadow, until the cleanup runs.',\n defaults: { duration: 4200 },\n run: (el: HTMLElement, o: any, ctx: EffectContext) => {\n if (ctx.reduced) return;\n const a = ctx.animate(el, [{ transform: 'perspective(800px) translateZ(0) translateY(0)', boxShadow: '0 14px 30px -18px rgba(15,23,42,.5)' }, { transform: 'perspective(800px) translateZ(24px) translateY(-6px)', boxShadow: '0 30px 50px -22px rgba(15,23,42,.45)' }, { transform: 'perspective(800px) translateZ(0) translateY(0)', boxShadow: '0 14px 30px -18px rgba(15,23,42,.5)' }], { duration: o.duration, iterations: Infinity, easing: 'ease-in-out' });\n return () => a?.cancel();\n },\n },\n {\n name: 'depth-pop',\n kind: 'attention',\n description: 'The element pops forward towards the viewer and settles back.',\n defaults: { duration: 600 },\n run: (el: HTMLElement, o: any, ctx: EffectContext) => {\n if (ctx.reduced) return;\n return ctx.animate(el, [{ transform: 'perspective(700px) translateZ(0)' }, { transform: 'perspective(700px) translateZ(90px)', filter: 'brightness(1.1)', offset: 0.35 }, { transform: 'perspective(700px) translateZ(-10px)', offset: 0.7 }, { transform: 'perspective(700px) translateZ(0)' }], { duration: o.duration, easing: 'ease-out' })?.finished.catch(() => undefined);\n },\n },\n];\n\n/** Register portal-open, orbit-in, spatial-float and depth-pop (8.8). */\nexport function registerSpatialPack(): void {\n registerEffects(SPATIAL_FX);\n}\n"],"names":["registerEffects"],"mappings":"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"}
@@ -0,0 +1,68 @@
1
+ type MotionSensitivity = 'full' | 'gentle' | 'minimal' | 'static';
2
+ type Cleanup = () => void;
3
+
4
+ /**
5
+ * 5.0 — unified plugin-style effect registration. Every effect (built-in or
6
+ * yours) is a plain object registered once and played the same way:
7
+ * `playEffect(el, name)`, `bindEffect(el, name, { trigger })` or
8
+ * `<usa-fx effect="name" trigger="click">`. Effects get a context that
9
+ * already applies reduced motion, motion sensitivity, intensity and the
10
+ * animation budget.
11
+ */
12
+
13
+ declare const EFFECT_KINDS: readonly ["enter", "exit", "attention", "click", "hover", "card", "loop", "page", "background", "text", "cursor", "scroll"];
14
+ type EffectKind = (typeof EFFECT_KINDS)[number];
15
+ interface EffectContext {
16
+ /** Reduced motion applies (OS setting, `minimal` / `static` sensitivity). */
17
+ readonly reduced: boolean;
18
+ readonly sensitivity: MotionSensitivity;
19
+ /** The triggering event (pointer position for click effects), if any. */
20
+ readonly event?: Event;
21
+ /** `el.animate()` with the library's motion rules (may return `null`). */
22
+ animate(el: Element, keyframes: Keyframe[], options: KeyframeAnimationOptions): Animation | null;
23
+ /** Register teardown for long-running effects (loops, listeners). */
24
+ onCleanup(fn: Cleanup): void;
25
+ }
26
+ interface EffectDefinition<O extends Record<string, unknown> = Record<string, any>> {
27
+ /** Unique, kebab-case. */
28
+ name: string;
29
+ kind: EffectKind;
30
+ /** One line for docs and the gallery. */
31
+ description?: string;
32
+ /** Option defaults (merged under the caller's options). */
33
+ defaults?: Partial<O>;
34
+ /**
35
+ * Under reduced motion: `'skip'` (do nothing — default for loop, background
36
+ * and cursor effects) or `'run'` (run with `ctx.reduced === true`, the
37
+ * effect degrades itself — default for everything else).
38
+ */
39
+ reduced?: 'skip' | 'run';
40
+ /** Play the effect. Return an Animation / Promise to be awaited, or a cleanup. */
41
+ run(el: HTMLElement, options: O, ctx: EffectContext): void | Cleanup | Animation | null | Promise<unknown>;
42
+ }
43
+
44
+ /**
45
+ * 8.8 — XR / spatial pack (`motionary/fx/spatial`, also `motionary/components/fx-spatial`):
46
+ *
47
+ * - `portal-open` (enter) — the element opens like a portal: a ring of
48
+ * light expands and the content comes through from depth (`color`).
49
+ * - `orbit-in` (enter) — the element swings in around the vertical axis
50
+ * like a spatial window placed beside you (`from` left|right).
51
+ * - `spatial-float` (loop) — a gentle floating in depth with a breathing
52
+ * shadow; the cleanup stops it.
53
+ * - `depth-pop` (attention) — the element pops forward towards the viewer
54
+ * and settles back.
55
+ *
56
+ * Reduced motion: portal-open / orbit-in just show, spatial-float is
57
+ * skipped, depth-pop does nothing.
58
+ */
59
+
60
+ /** Horizontal background offset (px) of a 360° panorama `width` px wide for a `yaw` in degrees (wraps) (8.8). */
61
+ declare function yawToOffset(yaw: number, width: number): number;
62
+ /** Which WebXR session the browser offers: `'immersive-vr'`, `'immersive-ar'`, `'inline'` or `'none'` (8.8). */
63
+ declare function xrSupport(): Promise<'immersive-vr' | 'immersive-ar' | 'inline' | 'none'>;
64
+ declare const SPATIAL_FX: EffectDefinition[];
65
+ /** Register portal-open, orbit-in, spatial-float and depth-pop (8.8). */
66
+ declare function registerSpatialPack(): void;
67
+
68
+ export { SPATIAL_FX, registerSpatialPack, xrSupport, yawToOffset };
@@ -0,0 +1,68 @@
1
+ type MotionSensitivity = 'full' | 'gentle' | 'minimal' | 'static';
2
+ type Cleanup = () => void;
3
+
4
+ /**
5
+ * 5.0 — unified plugin-style effect registration. Every effect (built-in or
6
+ * yours) is a plain object registered once and played the same way:
7
+ * `playEffect(el, name)`, `bindEffect(el, name, { trigger })` or
8
+ * `<usa-fx effect="name" trigger="click">`. Effects get a context that
9
+ * already applies reduced motion, motion sensitivity, intensity and the
10
+ * animation budget.
11
+ */
12
+
13
+ declare const EFFECT_KINDS: readonly ["enter", "exit", "attention", "click", "hover", "card", "loop", "page", "background", "text", "cursor", "scroll"];
14
+ type EffectKind = (typeof EFFECT_KINDS)[number];
15
+ interface EffectContext {
16
+ /** Reduced motion applies (OS setting, `minimal` / `static` sensitivity). */
17
+ readonly reduced: boolean;
18
+ readonly sensitivity: MotionSensitivity;
19
+ /** The triggering event (pointer position for click effects), if any. */
20
+ readonly event?: Event;
21
+ /** `el.animate()` with the library's motion rules (may return `null`). */
22
+ animate(el: Element, keyframes: Keyframe[], options: KeyframeAnimationOptions): Animation | null;
23
+ /** Register teardown for long-running effects (loops, listeners). */
24
+ onCleanup(fn: Cleanup): void;
25
+ }
26
+ interface EffectDefinition<O extends Record<string, unknown> = Record<string, any>> {
27
+ /** Unique, kebab-case. */
28
+ name: string;
29
+ kind: EffectKind;
30
+ /** One line for docs and the gallery. */
31
+ description?: string;
32
+ /** Option defaults (merged under the caller's options). */
33
+ defaults?: Partial<O>;
34
+ /**
35
+ * Under reduced motion: `'skip'` (do nothing — default for loop, background
36
+ * and cursor effects) or `'run'` (run with `ctx.reduced === true`, the
37
+ * effect degrades itself — default for everything else).
38
+ */
39
+ reduced?: 'skip' | 'run';
40
+ /** Play the effect. Return an Animation / Promise to be awaited, or a cleanup. */
41
+ run(el: HTMLElement, options: O, ctx: EffectContext): void | Cleanup | Animation | null | Promise<unknown>;
42
+ }
43
+
44
+ /**
45
+ * 8.8 — XR / spatial pack (`motionary/fx/spatial`, also `motionary/components/fx-spatial`):
46
+ *
47
+ * - `portal-open` (enter) — the element opens like a portal: a ring of
48
+ * light expands and the content comes through from depth (`color`).
49
+ * - `orbit-in` (enter) — the element swings in around the vertical axis
50
+ * like a spatial window placed beside you (`from` left|right).
51
+ * - `spatial-float` (loop) — a gentle floating in depth with a breathing
52
+ * shadow; the cleanup stops it.
53
+ * - `depth-pop` (attention) — the element pops forward towards the viewer
54
+ * and settles back.
55
+ *
56
+ * Reduced motion: portal-open / orbit-in just show, spatial-float is
57
+ * skipped, depth-pop does nothing.
58
+ */
59
+
60
+ /** Horizontal background offset (px) of a 360° panorama `width` px wide for a `yaw` in degrees (wraps) (8.8). */
61
+ declare function yawToOffset(yaw: number, width: number): number;
62
+ /** Which WebXR session the browser offers: `'immersive-vr'`, `'immersive-ar'`, `'inline'` or `'none'` (8.8). */
63
+ declare function xrSupport(): Promise<'immersive-vr' | 'immersive-ar' | 'inline' | 'none'>;
64
+ declare const SPATIAL_FX: EffectDefinition[];
65
+ /** Register portal-open, orbit-in, spatial-float and depth-pop (8.8). */
66
+ declare function registerSpatialPack(): void;
67
+
68
+ export { SPATIAL_FX, registerSpatialPack, xrSupport, yawToOffset };
@@ -0,0 +1,95 @@
1
+ import { registerEffects } from '../chunks/registry-CnO7ZVPK.js';
2
+ import '../chunks/base-CLuqlLfG.js';
3
+
4
+ /** Horizontal background offset (px) of a 360° panorama `width` px wide for a `yaw` in degrees (wraps) (8.8). */
5
+ function yawToOffset(yaw, width) {
6
+ if (!width)
7
+ return 0;
8
+ const y = ((yaw % 360) + 360) % 360;
9
+ return -Math.round((y / 360) * width * 100) / 100;
10
+ }
11
+ /** Which WebXR session the browser offers: `'immersive-vr'`, `'immersive-ar'`, `'inline'` or `'none'` (8.8). */
12
+ async function xrSupport() {
13
+ const xr = typeof navigator !== 'undefined' ? navigator.xr : undefined;
14
+ if (!xr?.isSessionSupported)
15
+ return 'none';
16
+ for (const m of ['immersive-vr', 'immersive-ar', 'inline']) {
17
+ try {
18
+ if (await xr.isSessionSupported(m))
19
+ return m;
20
+ }
21
+ catch {
22
+ /* blocked by policy */
23
+ }
24
+ }
25
+ return 'none';
26
+ }
27
+ const SPATIAL_FX = [
28
+ {
29
+ name: 'portal-open',
30
+ kind: 'enter',
31
+ description: 'The element opens like a portal: a ring of light expands and the content comes through from depth (`color`).',
32
+ defaults: { color: '#a78bfa', duration: 1100 },
33
+ run: (el, o, ctx) => {
34
+ if (ctx.reduced)
35
+ return;
36
+ if (getComputedStyle(el).position === 'static') {
37
+ const prev = el.style.position;
38
+ el.style.position = 'relative';
39
+ ctx.onCleanup(() => (el.style.position = prev));
40
+ }
41
+ const ring = document.createElement('span');
42
+ ring.setAttribute('aria-hidden', 'true');
43
+ Object.assign(ring.style, { position: 'absolute', left: '50%', top: '50%', width: '20px', height: '20px', margin: '-10px 0 0 -10px', borderRadius: '50%', border: `3px solid ${o.color}`, boxShadow: `0 0 18px 4px ${o.color}, inset 0 0 12px ${o.color}`, pointerEvents: 'none' });
44
+ el.appendChild(ring);
45
+ ctx.onCleanup(() => ring.remove());
46
+ const big = Math.max(el.offsetWidth, el.offsetHeight, 80) / 10;
47
+ const a = ctx.animate(ring, [{ transform: 'scale(0)', opacity: 1 }, { transform: `scale(${big})`, opacity: 0.9, offset: 0.6 }, { transform: `scale(${big * 1.2})`, opacity: 0 }], { duration: o.duration, easing: 'cubic-bezier(.2,.8,.2,1)' });
48
+ const b = ctx.animate(el, [{ clipPath: 'circle(0% at 50% 50%)', transform: 'perspective(700px) translateZ(-200px)' }, { clipPath: 'circle(75% at 50% 50%)', transform: 'none' }], { duration: o.duration, easing: 'cubic-bezier(.2,.8,.2,1)', fill: 'backwards' });
49
+ const end = () => ring.remove();
50
+ return Promise.all([a?.finished.catch(() => undefined), b?.finished.catch(() => undefined)]).then(end, end);
51
+ },
52
+ },
53
+ {
54
+ name: 'orbit-in',
55
+ kind: 'enter',
56
+ description: 'The element swings in around the vertical axis like a spatial window placed beside you (`from`).',
57
+ defaults: { from: 'left', duration: 900 },
58
+ run: (el, o, ctx) => {
59
+ if (ctx.reduced)
60
+ return;
61
+ const s = o.from === 'right' ? 1 : -1;
62
+ return ctx.animate(el, [{ transform: `perspective(900px) translateX(${s * 60}%) rotateY(${-s * 70}deg) translateZ(-120px)`, opacity: 0 }, { transform: 'none', opacity: 1 }], { duration: o.duration, easing: 'cubic-bezier(.2,.9,.25,1)', fill: 'backwards' })?.finished.catch(() => undefined);
63
+ },
64
+ },
65
+ {
66
+ name: 'spatial-float',
67
+ kind: 'loop',
68
+ description: 'A gentle floating in depth with a breathing shadow, until the cleanup runs.',
69
+ defaults: { duration: 4200 },
70
+ run: (el, o, ctx) => {
71
+ if (ctx.reduced)
72
+ return;
73
+ const a = ctx.animate(el, [{ transform: 'perspective(800px) translateZ(0) translateY(0)', boxShadow: '0 14px 30px -18px rgba(15,23,42,.5)' }, { transform: 'perspective(800px) translateZ(24px) translateY(-6px)', boxShadow: '0 30px 50px -22px rgba(15,23,42,.45)' }, { transform: 'perspective(800px) translateZ(0) translateY(0)', boxShadow: '0 14px 30px -18px rgba(15,23,42,.5)' }], { duration: o.duration, iterations: Infinity, easing: 'ease-in-out' });
74
+ return () => a?.cancel();
75
+ },
76
+ },
77
+ {
78
+ name: 'depth-pop',
79
+ kind: 'attention',
80
+ description: 'The element pops forward towards the viewer and settles back.',
81
+ defaults: { duration: 600 },
82
+ run: (el, o, ctx) => {
83
+ if (ctx.reduced)
84
+ return;
85
+ return ctx.animate(el, [{ transform: 'perspective(700px) translateZ(0)' }, { transform: 'perspective(700px) translateZ(90px)', filter: 'brightness(1.1)', offset: 0.35 }, { transform: 'perspective(700px) translateZ(-10px)', offset: 0.7 }, { transform: 'perspective(700px) translateZ(0)' }], { duration: o.duration, easing: 'ease-out' })?.finished.catch(() => undefined);
86
+ },
87
+ },
88
+ ];
89
+ /** Register portal-open, orbit-in, spatial-float and depth-pop (8.8). */
90
+ function registerSpatialPack() {
91
+ registerEffects(SPATIAL_FX);
92
+ }
93
+
94
+ export { SPATIAL_FX, registerSpatialPack, xrSupport, yawToOffset };
95
+ //# sourceMappingURL=fx-spatial.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"fx-spatial.js","sources":["../../src/components/fx2/spatial.ts"],"sourcesContent":["/**\n * 8.8 — XR / spatial pack (`motionary/fx/spatial`, also `motionary/components/fx-spatial`):\n *\n * - `portal-open` (enter) — the element opens like a portal: a ring of\n * light expands and the content comes through from depth (`color`).\n * - `orbit-in` (enter) — the element swings in around the vertical axis\n * like a spatial window placed beside you (`from` left|right).\n * - `spatial-float` (loop) — a gentle floating in depth with a breathing\n * shadow; the cleanup stops it.\n * - `depth-pop` (attention) — the element pops forward towards the viewer\n * and settles back.\n *\n * Reduced motion: portal-open / orbit-in just show, spatial-float is\n * skipped, depth-pop does nothing.\n */\nimport type { EffectContext, EffectDefinition } from '../fx/registry';\nimport { registerEffects } from '../fx/registry';\n\n/** Horizontal background offset (px) of a 360° panorama `width` px wide for a `yaw` in degrees (wraps) (8.8). */\nexport function yawToOffset(yaw: number, width: number): number {\n if (!width) return 0;\n const y = ((yaw % 360) + 360) % 360;\n return -Math.round((y / 360) * width * 100) / 100;\n}\n\n/** Which WebXR session the browser offers: `'immersive-vr'`, `'immersive-ar'`, `'inline'` or `'none'` (8.8). */\nexport async function xrSupport(): Promise<'immersive-vr' | 'immersive-ar' | 'inline' | 'none'> {\n const xr = typeof navigator !== 'undefined' ? (navigator as any).xr : undefined;\n if (!xr?.isSessionSupported) return 'none';\n for (const m of ['immersive-vr', 'immersive-ar', 'inline'] as const) {\n try {\n if (await xr.isSessionSupported(m)) return m;\n } catch {\n /* blocked by policy */\n }\n }\n return 'none';\n}\n\nexport const SPATIAL_FX: EffectDefinition[] = [\n {\n name: 'portal-open',\n kind: 'enter',\n description: 'The element opens like a portal: a ring of light expands and the content comes through from depth (`color`).',\n defaults: { color: '#a78bfa', duration: 1100 },\n run: (el: HTMLElement, o: any, ctx: EffectContext) => {\n if (ctx.reduced) return;\n if (getComputedStyle(el).position === 'static') {\n const prev = el.style.position;\n el.style.position = 'relative';\n ctx.onCleanup(() => (el.style.position = prev));\n }\n const ring = document.createElement('span');\n ring.setAttribute('aria-hidden', 'true');\n Object.assign(ring.style, { position: 'absolute', left: '50%', top: '50%', width: '20px', height: '20px', margin: '-10px 0 0 -10px', borderRadius: '50%', border: `3px solid ${o.color}`, boxShadow: `0 0 18px 4px ${o.color}, inset 0 0 12px ${o.color}`, pointerEvents: 'none' });\n el.appendChild(ring);\n ctx.onCleanup(() => ring.remove());\n const big = Math.max(el.offsetWidth, el.offsetHeight, 80) / 10;\n const a = ctx.animate(ring, [{ transform: 'scale(0)', opacity: 1 }, { transform: `scale(${big})`, opacity: 0.9, offset: 0.6 }, { transform: `scale(${big * 1.2})`, opacity: 0 }], { duration: o.duration, easing: 'cubic-bezier(.2,.8,.2,1)' });\n const b = ctx.animate(el, [{ clipPath: 'circle(0% at 50% 50%)', transform: 'perspective(700px) translateZ(-200px)' }, { clipPath: 'circle(75% at 50% 50%)', transform: 'none' }], { duration: o.duration, easing: 'cubic-bezier(.2,.8,.2,1)', fill: 'backwards' });\n const end = () => ring.remove();\n return Promise.all([a?.finished.catch(() => undefined), b?.finished.catch(() => undefined)]).then(end, end);\n },\n },\n {\n name: 'orbit-in',\n kind: 'enter',\n description: 'The element swings in around the vertical axis like a spatial window placed beside you (`from`).',\n defaults: { from: 'left', duration: 900 },\n run: (el: HTMLElement, o: any, ctx: EffectContext) => {\n if (ctx.reduced) return;\n const s = o.from === 'right' ? 1 : -1;\n return ctx.animate(el, [{ transform: `perspective(900px) translateX(${s * 60}%) rotateY(${-s * 70}deg) translateZ(-120px)`, opacity: 0 }, { transform: 'none', opacity: 1 }], { duration: o.duration, easing: 'cubic-bezier(.2,.9,.25,1)', fill: 'backwards' })?.finished.catch(() => undefined);\n },\n },\n {\n name: 'spatial-float',\n kind: 'loop',\n description: 'A gentle floating in depth with a breathing shadow, until the cleanup runs.',\n defaults: { duration: 4200 },\n run: (el: HTMLElement, o: any, ctx: EffectContext) => {\n if (ctx.reduced) return;\n const a = ctx.animate(el, [{ transform: 'perspective(800px) translateZ(0) translateY(0)', boxShadow: '0 14px 30px -18px rgba(15,23,42,.5)' }, { transform: 'perspective(800px) translateZ(24px) translateY(-6px)', boxShadow: '0 30px 50px -22px rgba(15,23,42,.45)' }, { transform: 'perspective(800px) translateZ(0) translateY(0)', boxShadow: '0 14px 30px -18px rgba(15,23,42,.5)' }], { duration: o.duration, iterations: Infinity, easing: 'ease-in-out' });\n return () => a?.cancel();\n },\n },\n {\n name: 'depth-pop',\n kind: 'attention',\n description: 'The element pops forward towards the viewer and settles back.',\n defaults: { duration: 600 },\n run: (el: HTMLElement, o: any, ctx: EffectContext) => {\n if (ctx.reduced) return;\n return ctx.animate(el, [{ transform: 'perspective(700px) translateZ(0)' }, { transform: 'perspective(700px) translateZ(90px)', filter: 'brightness(1.1)', offset: 0.35 }, { transform: 'perspective(700px) translateZ(-10px)', offset: 0.7 }, { transform: 'perspective(700px) translateZ(0)' }], { duration: o.duration, easing: 'ease-out' })?.finished.catch(() => undefined);\n },\n },\n];\n\n/** Register portal-open, orbit-in, spatial-float and depth-pop (8.8). */\nexport function registerSpatialPack(): void {\n registerEffects(SPATIAL_FX);\n}\n"],"names":[],"mappings":"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"}
@@ -25,6 +25,7 @@ var components_fxCyber = require('./fx-cyber.cjs');
25
25
  var components_fxPaper = require('./fx-paper.cjs');
26
26
  var components_fxSurface = require('./fx-surface.cjs');
27
27
  var components_fxGesture = require('./fx-gesture.cjs');
28
+ var components_fxSpatial = require('./fx-spatial.cjs');
28
29
  require('../chunks/registry-BVklOepd.cjs');
29
30
  require('../chunks/base-DoRUZBy-.cjs');
30
31
  require('../chunks/generative-BHIj-NU0.cjs');
@@ -57,6 +58,7 @@ const EFFECT_PACKS = {
57
58
  paper: components_fxPaper.PAPER_FX,
58
59
  surface: components_fxSurface.SURFACE_FX,
59
60
  gesture3: components_fxGesture.GESTURE3_FX,
61
+ spatial: components_fxSpatial.SPATIAL_FX,
60
62
  };
61
63
  /** Register every 6.x effect pack (idempotent). */
62
64
  function registerEffectPacks() {
@@ -84,6 +86,7 @@ function registerEffectPacks() {
84
86
  components_fxPaper.registerPaperPack();
85
87
  components_fxSurface.registerSurfacePack();
86
88
  components_fxGesture.registerGesture3Pack();
89
+ components_fxSpatial.registerSpatialPack();
87
90
  }
88
91
 
89
92
  exports.EFFECT_PACK_FORMAT = components_marketplace.EFFECT_PACK_FORMAT;
@@ -175,6 +178,10 @@ exports.orientationToTilt = components_fxGesture.orientationToTilt;
175
178
  exports.pinchAngle = components_fxGesture.pinchAngle;
176
179
  exports.pinchScale = components_fxGesture.pinchScale;
177
180
  exports.registerGesture3Pack = components_fxGesture.registerGesture3Pack;
181
+ exports.SPATIAL_FX = components_fxSpatial.SPATIAL_FX;
182
+ exports.registerSpatialPack = components_fxSpatial.registerSpatialPack;
183
+ exports.xrSupport = components_fxSpatial.xrSupport;
184
+ exports.yawToOffset = components_fxSpatial.yawToOffset;
178
185
  exports.EFFECT_PACKS = EFFECT_PACKS;
179
186
  exports.registerEffectPacks = registerEffectPacks;
180
187
  //# sourceMappingURL=fx2.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"fx2.cjs","sources":["../../src/components/fx2/index.ts"],"sourcesContent":["/**\n * The 6.x effect packs, one entry each (`motionary/components/fx-gpu`, …) so\n * their size budgets stay separate. This module (`registerFx2()`) registers\n * them all — used by dist/widgets.umd.js and the showcase.\n */\nimport type { EffectDefinition } from '../fx/registry';\nexport { EFFECT_PACK_FORMAT, packManifest, validateManifest, loadEffectPack } from './manifest';\nexport type { EffectPackManifest } from './manifest';\nimport { GPU_FX, registerGpuPack } from './gpu';\nimport { TEXT3_FX, registerTextPack, splitChars } from './text3';\nimport { LIGHT_FX, registerLightPack, trackPointer } from './light';\nimport { DEPTH3_FX, register3dPack } from './depth3';\nimport { MORPH2_FX, registerMorphPack, samplePath, pointsToPath } from './morph2';\nimport { TRANSITIONS2_FX, registerTransitionsPack, pageTransition, crossDocumentTransitions } from './transitions2';\nimport { WEATHER_FX, registerWeatherPack, skyAt } from './weather';\nimport { PHYSICS2_FX, registerPhysicsPack, VerletWorld } from './physics2';\nimport { FOCUS_FX, registerFocusPack } from './focus';\nimport { MUSIC_FX, registerMusicPack, syntheticSample, musicSample } from './music';\nimport { CHART_FX, registerChartPack, parseFigure } from './chart';\nimport { SHOP_FX, registerShopPack, arcPath } from './shop';\nimport { SOCIAL_FX, registerSocialPack, fanAngles } from './social';\nimport { GAME_FX, registerGamePack, throwPath } from './game';\nimport { GEO_FX, registerGeoPack, routeLength } from './geo';\nimport { FORM_FX, registerFormPack, shakeFrames } from './form';\nimport { AI_FX, registerAiPack, splitWords } from './ai';\nimport { FESTIVAL_FX, registerFestivalPack, sparkVectors } from './festival';\nimport { RETRO_FX, registerRetroPack, pixelSteps } from './retro2';\nimport { ORGANIC_FX, registerOrganicPack, blobRadius } from './organic';\nimport { CYBER_FX, registerCyberPack, decodeFrame } from './cyber';\nimport { PAPER_FX, registerPaperPack, roughLine, paperRandom } from './paper';\nimport { SURFACE_FX, registerSurfacePack, SURFACE_THEMES, applySurfaceTheme } from './themefx';\nimport { GESTURE3_FX, registerGesture3Pack, pinchScale, pinchAngle, orientationToTilt } from './gesture3';\n\nexport { GPU_FX, registerGpuPack, TEXT3_FX, registerTextPack, splitChars };\nexport { shaderBackground, supportsWebGL2, fieldFallback, GLSL_HEAD } from './gl';\nexport { supportsWebGPU, glslToWgsl, wgslModule, webgpuBackground, WGSL_HEAD } from './webgpu';\nexport type { ShaderSpec } from './gl';\n\nexport { LIGHT_FX, registerLightPack, trackPointer };\n\nexport { DEPTH3_FX, register3dPack };\n\nexport { MORPH2_FX, registerMorphPack, samplePath, pointsToPath };\n\nexport { TRANSITIONS2_FX, registerTransitionsPack, pageTransition, crossDocumentTransitions };\n\nexport { WEATHER_FX, registerWeatherPack, skyAt };\n\nexport { PHYSICS2_FX, registerPhysicsPack, VerletWorld };\n\nexport { FOCUS_FX, registerFocusPack };\n\nexport { MUSIC_FX, registerMusicPack, syntheticSample, musicSample };\n\nexport { CHART_FX, registerChartPack, parseFigure };\n\nexport { SHOP_FX, registerShopPack, arcPath };\n\nexport { SOCIAL_FX, registerSocialPack, fanAngles };\n\nexport { GAME_FX, registerGamePack, throwPath };\n\nexport { GEO_FX, registerGeoPack, routeLength };\n\nexport { FORM_FX, registerFormPack, shakeFrames };\n\nexport { AI_FX, registerAiPack, splitWords };\n\nexport { FESTIVAL_FX, registerFestivalPack, sparkVectors };\n\nexport { RETRO_FX, registerRetroPack, pixelSteps };\n\nexport { ORGANIC_FX, registerOrganicPack, blobRadius };\n\nexport { CYBER_FX, registerCyberPack, decodeFrame };\n\nexport { PAPER_FX, registerPaperPack, roughLine, paperRandom };\n\nexport { SURFACE_FX, registerSurfacePack, SURFACE_THEMES, applySurfaceTheme };\n\nexport { GESTURE3_FX, registerGesture3Pack, pinchScale, pinchAngle, orientationToTilt };\n\n/** The 6.x effect packs by name. */\nexport const EFFECT_PACKS: Record<string, EffectDefinition[]> = {\n gpu: GPU_FX,\n text: TEXT3_FX,\n light: LIGHT_FX,\n depth: DEPTH3_FX,\n morph: MORPH2_FX,\n transitions: TRANSITIONS2_FX,\n weather: WEATHER_FX,\n physics: PHYSICS2_FX,\n focus: FOCUS_FX,\n music: MUSIC_FX,\n chart: CHART_FX,\n shop: SHOP_FX,\n social: SOCIAL_FX,\n game: GAME_FX,\n geo: GEO_FX,\n form: FORM_FX,\n ai: AI_FX,\n festival: FESTIVAL_FX,\n retro: RETRO_FX,\n organic: ORGANIC_FX,\n cyber: CYBER_FX,\n paper: PAPER_FX,\n surface: SURFACE_FX,\n gesture3: GESTURE3_FX,\n};\n\n/** Register every 6.x effect pack (idempotent). */\nexport function registerEffectPacks(): void {\n registerGpuPack();\n registerTextPack();\n registerLightPack();\n register3dPack();\n registerMorphPack();\n registerTransitionsPack();\n registerWeatherPack();\n registerPhysicsPack();\n registerFocusPack();\n registerMusicPack();\n registerChartPack();\n registerShopPack();\n registerSocialPack();\n registerGamePack();\n registerGeoPack();\n registerFormPack();\n registerAiPack();\n registerFestivalPack();\n registerRetroPack();\n registerOrganicPack();\n registerCyberPack();\n registerPaperPack();\n registerSurfacePack();\n registerGesture3Pack();\n}\n\n\n"],"names":["GPU_FX","TEXT3_FX","LIGHT_FX","DEPTH3_FX","MORPH2_FX","TRANSITIONS2_FX","WEATHER_FX","PHYSICS2_FX","FOCUS_FX","MUSIC_FX","CHART_FX","SHOP_FX","SOCIAL_FX","GAME_FX","GEO_FX","FORM_FX","AI_FX","FESTIVAL_FX","RETRO_FX","ORGANIC_FX","CYBER_FX","PAPER_FX","SURFACE_FX","GESTURE3_FX","registerGpuPack","registerTextPack","registerLightPack","register3dPack","registerMorphPack","registerTransitionsPack","registerWeatherPack","registerPhysicsPack","registerFocusPack","registerMusicPack","registerChartPack","registerShopPack","registerSocialPack","registerGamePack","registerGeoPack","registerFormPack","registerAiPack","registerFestivalPack","registerRetroPack","registerOrganicPack","registerCyberPack","registerPaperPack","registerSurfacePack","registerGesture3Pack"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAkFA;AACO,MAAM,YAAY,GAAuC;AAC9D,IAAA,GAAG,EAAEA,uBAAM;AACX,IAAA,IAAI,EAAEC,0BAAQ;AACd,IAAA,KAAK,EAAEC,2BAAQ;AACf,IAAA,KAAK,EAAEC,yBAAS;AAChB,IAAA,KAAK,EAAEC,4BAAS;AAChB,IAAA,WAAW,EAAEC,wCAAe;AAC5B,IAAA,OAAO,EAAEC,+BAAU;AACnB,IAAA,OAAO,EAAEC,gCAAW;AACpB,IAAA,KAAK,EAAEC,2BAAQ;AACf,IAAA,KAAK,EAAEC,2BAAQ;AACf,IAAA,KAAK,EAAEC,2BAAQ;AACf,IAAA,IAAI,EAAEC,yBAAO;AACb,IAAA,MAAM,EAAEC,6BAAS;AACjB,IAAA,IAAI,EAAEC,yBAAO;AACb,IAAA,GAAG,EAAEC,uBAAM;AACX,IAAA,IAAI,EAAEC,yBAAO;AACb,IAAA,EAAE,EAAEC,qBAAK;AACT,IAAA,QAAQ,EAAEC,iCAAW;AACrB,IAAA,KAAK,EAAEC,2BAAQ;AACf,IAAA,OAAO,EAAEC,+BAAU;AACnB,IAAA,KAAK,EAAEC,2BAAQ;AACf,IAAA,KAAK,EAAEC,2BAAQ;AACf,IAAA,OAAO,EAAEC,+BAAU;AACnB,IAAA,QAAQ,EAAEC,gCAAW;;AAGvB;SACgB,mBAAmB,GAAA;AACjC,IAAAC,gCAAe,EAAE;AACjB,IAAAC,kCAAgB,EAAE;AAClB,IAAAC,oCAAiB,EAAE;AACnB,IAAAC,8BAAc,EAAE;AAChB,IAAAC,oCAAiB,EAAE;AACnB,IAAAC,gDAAuB,EAAE;AACzB,IAAAC,wCAAmB,EAAE;AACrB,IAAAC,wCAAmB,EAAE;AACrB,IAAAC,oCAAiB,EAAE;AACnB,IAAAC,oCAAiB,EAAE;AACnB,IAAAC,oCAAiB,EAAE;AACnB,IAAAC,kCAAgB,EAAE;AAClB,IAAAC,sCAAkB,EAAE;AACpB,IAAAC,kCAAgB,EAAE;AAClB,IAAAC,gCAAe,EAAE;AACjB,IAAAC,kCAAgB,EAAE;AAClB,IAAAC,8BAAc,EAAE;AAChB,IAAAC,0CAAoB,EAAE;AACtB,IAAAC,oCAAiB,EAAE;AACnB,IAAAC,wCAAmB,EAAE;AACrB,IAAAC,oCAAiB,EAAE;AACnB,IAAAC,oCAAiB,EAAE;AACnB,IAAAC,wCAAmB,EAAE;AACrB,IAAAC,yCAAoB,EAAE;AACxB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
1
+ {"version":3,"file":"fx2.cjs","sources":["../../src/components/fx2/index.ts"],"sourcesContent":["/**\n * The 6.x effect packs, one entry each (`motionary/components/fx-gpu`, …) so\n * their size budgets stay separate. This module (`registerFx2()`) registers\n * them all — used by dist/widgets.umd.js and the showcase.\n */\nimport type { EffectDefinition } from '../fx/registry';\nexport { EFFECT_PACK_FORMAT, packManifest, validateManifest, loadEffectPack } from './manifest';\nexport type { EffectPackManifest } from './manifest';\nimport { GPU_FX, registerGpuPack } from './gpu';\nimport { TEXT3_FX, registerTextPack, splitChars } from './text3';\nimport { LIGHT_FX, registerLightPack, trackPointer } from './light';\nimport { DEPTH3_FX, register3dPack } from './depth3';\nimport { MORPH2_FX, registerMorphPack, samplePath, pointsToPath } from './morph2';\nimport { TRANSITIONS2_FX, registerTransitionsPack, pageTransition, crossDocumentTransitions } from './transitions2';\nimport { WEATHER_FX, registerWeatherPack, skyAt } from './weather';\nimport { PHYSICS2_FX, registerPhysicsPack, VerletWorld } from './physics2';\nimport { FOCUS_FX, registerFocusPack } from './focus';\nimport { MUSIC_FX, registerMusicPack, syntheticSample, musicSample } from './music';\nimport { CHART_FX, registerChartPack, parseFigure } from './chart';\nimport { SHOP_FX, registerShopPack, arcPath } from './shop';\nimport { SOCIAL_FX, registerSocialPack, fanAngles } from './social';\nimport { GAME_FX, registerGamePack, throwPath } from './game';\nimport { GEO_FX, registerGeoPack, routeLength } from './geo';\nimport { FORM_FX, registerFormPack, shakeFrames } from './form';\nimport { AI_FX, registerAiPack, splitWords } from './ai';\nimport { FESTIVAL_FX, registerFestivalPack, sparkVectors } from './festival';\nimport { RETRO_FX, registerRetroPack, pixelSteps } from './retro2';\nimport { ORGANIC_FX, registerOrganicPack, blobRadius } from './organic';\nimport { CYBER_FX, registerCyberPack, decodeFrame } from './cyber';\nimport { PAPER_FX, registerPaperPack, roughLine, paperRandom } from './paper';\nimport { SURFACE_FX, registerSurfacePack, SURFACE_THEMES, applySurfaceTheme } from './themefx';\nimport { GESTURE3_FX, registerGesture3Pack, pinchScale, pinchAngle, orientationToTilt } from './gesture3';\nimport { SPATIAL_FX, registerSpatialPack, yawToOffset, xrSupport } from './spatial';\n\nexport { GPU_FX, registerGpuPack, TEXT3_FX, registerTextPack, splitChars };\nexport { shaderBackground, supportsWebGL2, fieldFallback, GLSL_HEAD } from './gl';\nexport { supportsWebGPU, glslToWgsl, wgslModule, webgpuBackground, WGSL_HEAD } from './webgpu';\nexport type { ShaderSpec } from './gl';\n\nexport { LIGHT_FX, registerLightPack, trackPointer };\n\nexport { DEPTH3_FX, register3dPack };\n\nexport { MORPH2_FX, registerMorphPack, samplePath, pointsToPath };\n\nexport { TRANSITIONS2_FX, registerTransitionsPack, pageTransition, crossDocumentTransitions };\n\nexport { WEATHER_FX, registerWeatherPack, skyAt };\n\nexport { PHYSICS2_FX, registerPhysicsPack, VerletWorld };\n\nexport { FOCUS_FX, registerFocusPack };\n\nexport { MUSIC_FX, registerMusicPack, syntheticSample, musicSample };\n\nexport { CHART_FX, registerChartPack, parseFigure };\n\nexport { SHOP_FX, registerShopPack, arcPath };\n\nexport { SOCIAL_FX, registerSocialPack, fanAngles };\n\nexport { GAME_FX, registerGamePack, throwPath };\n\nexport { GEO_FX, registerGeoPack, routeLength };\n\nexport { FORM_FX, registerFormPack, shakeFrames };\n\nexport { AI_FX, registerAiPack, splitWords };\n\nexport { FESTIVAL_FX, registerFestivalPack, sparkVectors };\n\nexport { RETRO_FX, registerRetroPack, pixelSteps };\n\nexport { ORGANIC_FX, registerOrganicPack, blobRadius };\n\nexport { CYBER_FX, registerCyberPack, decodeFrame };\n\nexport { PAPER_FX, registerPaperPack, roughLine, paperRandom };\n\nexport { SURFACE_FX, registerSurfacePack, SURFACE_THEMES, applySurfaceTheme };\n\nexport { GESTURE3_FX, registerGesture3Pack, pinchScale, pinchAngle, orientationToTilt };\n\nexport { SPATIAL_FX, registerSpatialPack, yawToOffset, xrSupport };\n\n/** The 6.x effect packs by name. */\nexport const EFFECT_PACKS: Record<string, EffectDefinition[]> = {\n gpu: GPU_FX,\n text: TEXT3_FX,\n light: LIGHT_FX,\n depth: DEPTH3_FX,\n morph: MORPH2_FX,\n transitions: TRANSITIONS2_FX,\n weather: WEATHER_FX,\n physics: PHYSICS2_FX,\n focus: FOCUS_FX,\n music: MUSIC_FX,\n chart: CHART_FX,\n shop: SHOP_FX,\n social: SOCIAL_FX,\n game: GAME_FX,\n geo: GEO_FX,\n form: FORM_FX,\n ai: AI_FX,\n festival: FESTIVAL_FX,\n retro: RETRO_FX,\n organic: ORGANIC_FX,\n cyber: CYBER_FX,\n paper: PAPER_FX,\n surface: SURFACE_FX,\n gesture3: GESTURE3_FX,\n spatial: SPATIAL_FX,\n};\n\n/** Register every 6.x effect pack (idempotent). */\nexport function registerEffectPacks(): void {\n registerGpuPack();\n registerTextPack();\n registerLightPack();\n register3dPack();\n registerMorphPack();\n registerTransitionsPack();\n registerWeatherPack();\n registerPhysicsPack();\n registerFocusPack();\n registerMusicPack();\n registerChartPack();\n registerShopPack();\n registerSocialPack();\n registerGamePack();\n registerGeoPack();\n registerFormPack();\n registerAiPack();\n registerFestivalPack();\n registerRetroPack();\n registerOrganicPack();\n registerCyberPack();\n registerPaperPack();\n registerSurfacePack();\n registerGesture3Pack();\n registerSpatialPack();\n}\n\n\n"],"names":["GPU_FX","TEXT3_FX","LIGHT_FX","DEPTH3_FX","MORPH2_FX","TRANSITIONS2_FX","WEATHER_FX","PHYSICS2_FX","FOCUS_FX","MUSIC_FX","CHART_FX","SHOP_FX","SOCIAL_FX","GAME_FX","GEO_FX","FORM_FX","AI_FX","FESTIVAL_FX","RETRO_FX","ORGANIC_FX","CYBER_FX","PAPER_FX","SURFACE_FX","GESTURE3_FX","SPATIAL_FX","registerGpuPack","registerTextPack","registerLightPack","register3dPack","registerMorphPack","registerTransitionsPack","registerWeatherPack","registerPhysicsPack","registerFocusPack","registerMusicPack","registerChartPack","registerShopPack","registerSocialPack","registerGamePack","registerGeoPack","registerFormPack","registerAiPack","registerFestivalPack","registerRetroPack","registerOrganicPack","registerCyberPack","registerPaperPack","registerSurfacePack","registerGesture3Pack","registerSpatialPack"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAqFA;AACO,MAAM,YAAY,GAAuC;AAC9D,IAAA,GAAG,EAAEA,uBAAM;AACX,IAAA,IAAI,EAAEC,0BAAQ;AACd,IAAA,KAAK,EAAEC,2BAAQ;AACf,IAAA,KAAK,EAAEC,yBAAS;AAChB,IAAA,KAAK,EAAEC,4BAAS;AAChB,IAAA,WAAW,EAAEC,wCAAe;AAC5B,IAAA,OAAO,EAAEC,+BAAU;AACnB,IAAA,OAAO,EAAEC,gCAAW;AACpB,IAAA,KAAK,EAAEC,2BAAQ;AACf,IAAA,KAAK,EAAEC,2BAAQ;AACf,IAAA,KAAK,EAAEC,2BAAQ;AACf,IAAA,IAAI,EAAEC,yBAAO;AACb,IAAA,MAAM,EAAEC,6BAAS;AACjB,IAAA,IAAI,EAAEC,yBAAO;AACb,IAAA,GAAG,EAAEC,uBAAM;AACX,IAAA,IAAI,EAAEC,yBAAO;AACb,IAAA,EAAE,EAAEC,qBAAK;AACT,IAAA,QAAQ,EAAEC,iCAAW;AACrB,IAAA,KAAK,EAAEC,2BAAQ;AACf,IAAA,OAAO,EAAEC,+BAAU;AACnB,IAAA,KAAK,EAAEC,2BAAQ;AACf,IAAA,KAAK,EAAEC,2BAAQ;AACf,IAAA,OAAO,EAAEC,+BAAU;AACnB,IAAA,QAAQ,EAAEC,gCAAW;AACrB,IAAA,OAAO,EAAEC,+BAAU;;AAGrB;SACgB,mBAAmB,GAAA;AACjC,IAAAC,gCAAe,EAAE;AACjB,IAAAC,kCAAgB,EAAE;AAClB,IAAAC,oCAAiB,EAAE;AACnB,IAAAC,8BAAc,EAAE;AAChB,IAAAC,oCAAiB,EAAE;AACnB,IAAAC,gDAAuB,EAAE;AACzB,IAAAC,wCAAmB,EAAE;AACrB,IAAAC,wCAAmB,EAAE;AACrB,IAAAC,oCAAiB,EAAE;AACnB,IAAAC,oCAAiB,EAAE;AACnB,IAAAC,oCAAiB,EAAE;AACnB,IAAAC,kCAAgB,EAAE;AAClB,IAAAC,sCAAkB,EAAE;AACpB,IAAAC,kCAAgB,EAAE;AAClB,IAAAC,gCAAe,EAAE;AACjB,IAAAC,kCAAgB,EAAE;AAClB,IAAAC,8BAAc,EAAE;AAChB,IAAAC,0CAAoB,EAAE;AACtB,IAAAC,oCAAiB,EAAE;AACnB,IAAAC,wCAAmB,EAAE;AACrB,IAAAC,oCAAiB,EAAE;AACnB,IAAAC,oCAAiB,EAAE;AACnB,IAAAC,wCAAmB,EAAE;AACrB,IAAAC,yCAAoB,EAAE;AACtB,IAAAC,wCAAmB,EAAE;AACvB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
@@ -756,6 +756,30 @@ declare const GESTURE3_FX: EffectDefinition[];
756
756
  /** Register swipe-hint, pinch-hint, tilt-wobble and depth-in (8.7). */
757
757
  declare function registerGesture3Pack(): void;
758
758
 
759
+ /**
760
+ * 8.8 — XR / spatial pack (`motionary/fx/spatial`, also `motionary/components/fx-spatial`):
761
+ *
762
+ * - `portal-open` (enter) — the element opens like a portal: a ring of
763
+ * light expands and the content comes through from depth (`color`).
764
+ * - `orbit-in` (enter) — the element swings in around the vertical axis
765
+ * like a spatial window placed beside you (`from` left|right).
766
+ * - `spatial-float` (loop) — a gentle floating in depth with a breathing
767
+ * shadow; the cleanup stops it.
768
+ * - `depth-pop` (attention) — the element pops forward towards the viewer
769
+ * and settles back.
770
+ *
771
+ * Reduced motion: portal-open / orbit-in just show, spatial-float is
772
+ * skipped, depth-pop does nothing.
773
+ */
774
+
775
+ /** Horizontal background offset (px) of a 360° panorama `width` px wide for a `yaw` in degrees (wraps) (8.8). */
776
+ declare function yawToOffset(yaw: number, width: number): number;
777
+ /** Which WebXR session the browser offers: `'immersive-vr'`, `'immersive-ar'`, `'inline'` or `'none'` (8.8). */
778
+ declare function xrSupport(): Promise<'immersive-vr' | 'immersive-ar' | 'inline' | 'none'>;
779
+ declare const SPATIAL_FX: EffectDefinition[];
780
+ /** Register portal-open, orbit-in, spatial-float and depth-pop (8.8). */
781
+ declare function registerSpatialPack(): void;
782
+
759
783
  /**
760
784
  * 5.5 — generative backgrounds on Canvas 2D, registered through
761
785
  * `registerEffect()` (kind `background`): `flow-field`, `voronoi`,
@@ -865,5 +889,5 @@ declare const EFFECT_PACKS: Record<string, EffectDefinition[]>;
865
889
  /** Register every 6.x effect pack (idempotent). */
866
890
  declare function registerEffectPacks(): void;
867
891
 
868
- export { AI_FX, CHART_FX, CYBER_FX, DEPTH3_FX, EFFECT_PACKS, EFFECT_PACK_FORMAT, FESTIVAL_FX, FOCUS_FX, FORM_FX, GAME_FX, GEO_FX, GESTURE3_FX, GLSL_HEAD, GPU_FX, LIGHT_FX, MORPH2_FX, MUSIC_FX, ORGANIC_FX, PAPER_FX, PHYSICS2_FX, RETRO_FX, SHOP_FX, SOCIAL_FX, SURFACE_FX, SURFACE_THEMES, TEXT3_FX, TRANSITIONS2_FX, VerletWorld, WEATHER_FX, WGSL_HEAD, applySurfaceTheme, arcPath, blobRadius, crossDocumentTransitions, decodeFrame, fanAngles, fieldFallback, glslToWgsl, loadEffectPack, musicSample, orientationToTilt, packManifest, pageTransition, paperRandom, parseFigure, pinchAngle, pinchScale, pixelSteps, pointsToPath, register3dPack, registerAiPack, registerChartPack, registerCyberPack, registerEffectPacks, registerFestivalPack, registerFocusPack, registerFormPack, registerGamePack, registerGeoPack, registerGesture3Pack, registerGpuPack, registerLightPack, registerMorphPack, registerMusicPack, registerOrganicPack, registerPaperPack, registerPhysicsPack, registerRetroPack, registerShopPack, registerSocialPack, registerSurfacePack, registerTextPack, registerTransitionsPack, registerWeatherPack, roughLine, routeLength, samplePath, shaderBackground, shakeFrames, skyAt, sparkVectors, splitChars, splitWords, supportsWebGL2, supportsWebGPU, syntheticSample, throwPath, trackPointer, validateManifest, webgpuBackground, wgslModule };
892
+ export { AI_FX, CHART_FX, CYBER_FX, DEPTH3_FX, EFFECT_PACKS, EFFECT_PACK_FORMAT, FESTIVAL_FX, FOCUS_FX, FORM_FX, GAME_FX, GEO_FX, GESTURE3_FX, GLSL_HEAD, GPU_FX, LIGHT_FX, MORPH2_FX, MUSIC_FX, ORGANIC_FX, PAPER_FX, PHYSICS2_FX, RETRO_FX, SHOP_FX, SOCIAL_FX, SPATIAL_FX, SURFACE_FX, SURFACE_THEMES, TEXT3_FX, TRANSITIONS2_FX, VerletWorld, WEATHER_FX, WGSL_HEAD, applySurfaceTheme, arcPath, blobRadius, crossDocumentTransitions, decodeFrame, fanAngles, fieldFallback, glslToWgsl, loadEffectPack, musicSample, orientationToTilt, packManifest, pageTransition, paperRandom, parseFigure, pinchAngle, pinchScale, pixelSteps, pointsToPath, register3dPack, registerAiPack, registerChartPack, registerCyberPack, registerEffectPacks, registerFestivalPack, registerFocusPack, registerFormPack, registerGamePack, registerGeoPack, registerGesture3Pack, registerGpuPack, registerLightPack, registerMorphPack, registerMusicPack, registerOrganicPack, registerPaperPack, registerPhysicsPack, registerRetroPack, registerShopPack, registerSocialPack, registerSpatialPack, registerSurfacePack, registerTextPack, registerTransitionsPack, registerWeatherPack, roughLine, routeLength, samplePath, shaderBackground, shakeFrames, skyAt, sparkVectors, splitChars, splitWords, supportsWebGL2, supportsWebGPU, syntheticSample, throwPath, trackPointer, validateManifest, webgpuBackground, wgslModule, xrSupport, yawToOffset };
869
893
  export type { EffectPackManifest, ShaderSpec };
@@ -756,6 +756,30 @@ declare const GESTURE3_FX: EffectDefinition[];
756
756
  /** Register swipe-hint, pinch-hint, tilt-wobble and depth-in (8.7). */
757
757
  declare function registerGesture3Pack(): void;
758
758
 
759
+ /**
760
+ * 8.8 — XR / spatial pack (`motionary/fx/spatial`, also `motionary/components/fx-spatial`):
761
+ *
762
+ * - `portal-open` (enter) — the element opens like a portal: a ring of
763
+ * light expands and the content comes through from depth (`color`).
764
+ * - `orbit-in` (enter) — the element swings in around the vertical axis
765
+ * like a spatial window placed beside you (`from` left|right).
766
+ * - `spatial-float` (loop) — a gentle floating in depth with a breathing
767
+ * shadow; the cleanup stops it.
768
+ * - `depth-pop` (attention) — the element pops forward towards the viewer
769
+ * and settles back.
770
+ *
771
+ * Reduced motion: portal-open / orbit-in just show, spatial-float is
772
+ * skipped, depth-pop does nothing.
773
+ */
774
+
775
+ /** Horizontal background offset (px) of a 360° panorama `width` px wide for a `yaw` in degrees (wraps) (8.8). */
776
+ declare function yawToOffset(yaw: number, width: number): number;
777
+ /** Which WebXR session the browser offers: `'immersive-vr'`, `'immersive-ar'`, `'inline'` or `'none'` (8.8). */
778
+ declare function xrSupport(): Promise<'immersive-vr' | 'immersive-ar' | 'inline' | 'none'>;
779
+ declare const SPATIAL_FX: EffectDefinition[];
780
+ /** Register portal-open, orbit-in, spatial-float and depth-pop (8.8). */
781
+ declare function registerSpatialPack(): void;
782
+
759
783
  /**
760
784
  * 5.5 — generative backgrounds on Canvas 2D, registered through
761
785
  * `registerEffect()` (kind `background`): `flow-field`, `voronoi`,
@@ -865,5 +889,5 @@ declare const EFFECT_PACKS: Record<string, EffectDefinition[]>;
865
889
  /** Register every 6.x effect pack (idempotent). */
866
890
  declare function registerEffectPacks(): void;
867
891
 
868
- export { AI_FX, CHART_FX, CYBER_FX, DEPTH3_FX, EFFECT_PACKS, EFFECT_PACK_FORMAT, FESTIVAL_FX, FOCUS_FX, FORM_FX, GAME_FX, GEO_FX, GESTURE3_FX, GLSL_HEAD, GPU_FX, LIGHT_FX, MORPH2_FX, MUSIC_FX, ORGANIC_FX, PAPER_FX, PHYSICS2_FX, RETRO_FX, SHOP_FX, SOCIAL_FX, SURFACE_FX, SURFACE_THEMES, TEXT3_FX, TRANSITIONS2_FX, VerletWorld, WEATHER_FX, WGSL_HEAD, applySurfaceTheme, arcPath, blobRadius, crossDocumentTransitions, decodeFrame, fanAngles, fieldFallback, glslToWgsl, loadEffectPack, musicSample, orientationToTilt, packManifest, pageTransition, paperRandom, parseFigure, pinchAngle, pinchScale, pixelSteps, pointsToPath, register3dPack, registerAiPack, registerChartPack, registerCyberPack, registerEffectPacks, registerFestivalPack, registerFocusPack, registerFormPack, registerGamePack, registerGeoPack, registerGesture3Pack, registerGpuPack, registerLightPack, registerMorphPack, registerMusicPack, registerOrganicPack, registerPaperPack, registerPhysicsPack, registerRetroPack, registerShopPack, registerSocialPack, registerSurfacePack, registerTextPack, registerTransitionsPack, registerWeatherPack, roughLine, routeLength, samplePath, shaderBackground, shakeFrames, skyAt, sparkVectors, splitChars, splitWords, supportsWebGL2, supportsWebGPU, syntheticSample, throwPath, trackPointer, validateManifest, webgpuBackground, wgslModule };
892
+ export { AI_FX, CHART_FX, CYBER_FX, DEPTH3_FX, EFFECT_PACKS, EFFECT_PACK_FORMAT, FESTIVAL_FX, FOCUS_FX, FORM_FX, GAME_FX, GEO_FX, GESTURE3_FX, GLSL_HEAD, GPU_FX, LIGHT_FX, MORPH2_FX, MUSIC_FX, ORGANIC_FX, PAPER_FX, PHYSICS2_FX, RETRO_FX, SHOP_FX, SOCIAL_FX, SPATIAL_FX, SURFACE_FX, SURFACE_THEMES, TEXT3_FX, TRANSITIONS2_FX, VerletWorld, WEATHER_FX, WGSL_HEAD, applySurfaceTheme, arcPath, blobRadius, crossDocumentTransitions, decodeFrame, fanAngles, fieldFallback, glslToWgsl, loadEffectPack, musicSample, orientationToTilt, packManifest, pageTransition, paperRandom, parseFigure, pinchAngle, pinchScale, pixelSteps, pointsToPath, register3dPack, registerAiPack, registerChartPack, registerCyberPack, registerEffectPacks, registerFestivalPack, registerFocusPack, registerFormPack, registerGamePack, registerGeoPack, registerGesture3Pack, registerGpuPack, registerLightPack, registerMorphPack, registerMusicPack, registerOrganicPack, registerPaperPack, registerPhysicsPack, registerRetroPack, registerShopPack, registerSocialPack, registerSpatialPack, registerSurfacePack, registerTextPack, registerTransitionsPack, registerWeatherPack, roughLine, routeLength, samplePath, shaderBackground, shakeFrames, skyAt, sparkVectors, splitChars, splitWords, supportsWebGL2, supportsWebGPU, syntheticSample, throwPath, trackPointer, validateManifest, webgpuBackground, wgslModule, xrSupport, yawToOffset };
869
893
  export type { EffectPackManifest, ShaderSpec };
@@ -45,6 +45,8 @@ import { SURFACE_FX, registerSurfacePack } from './fx-surface.js';
45
45
  export { SURFACE_THEMES, applySurfaceTheme } from './fx-surface.js';
46
46
  import { GESTURE3_FX, registerGesture3Pack } from './fx-gesture.js';
47
47
  export { orientationToTilt, pinchAngle, pinchScale } from './fx-gesture.js';
48
+ import { SPATIAL_FX, registerSpatialPack } from './fx-spatial.js';
49
+ export { xrSupport, yawToOffset } from './fx-spatial.js';
48
50
  import '../chunks/registry-CnO7ZVPK.js';
49
51
  import '../chunks/base-CLuqlLfG.js';
50
52
  import '../chunks/generative-2LhxG5BJ.js';
@@ -77,6 +79,7 @@ const EFFECT_PACKS = {
77
79
  paper: PAPER_FX,
78
80
  surface: SURFACE_FX,
79
81
  gesture3: GESTURE3_FX,
82
+ spatial: SPATIAL_FX,
80
83
  };
81
84
  /** Register every 6.x effect pack (idempotent). */
82
85
  function registerEffectPacks() {
@@ -104,7 +107,8 @@ function registerEffectPacks() {
104
107
  registerPaperPack();
105
108
  registerSurfacePack();
106
109
  registerGesture3Pack();
110
+ registerSpatialPack();
107
111
  }
108
112
 
109
- export { AI_FX, CHART_FX, CYBER_FX, DEPTH3_FX, EFFECT_PACKS, FESTIVAL_FX, FOCUS_FX, FORM_FX, GAME_FX, GEO_FX, GESTURE3_FX, GPU_FX, LIGHT_FX, MORPH2_FX, MUSIC_FX, ORGANIC_FX, PAPER_FX, PHYSICS2_FX, RETRO_FX, SHOP_FX, SOCIAL_FX, SURFACE_FX, TEXT3_FX, TRANSITIONS2_FX, WEATHER_FX, register3dPack, registerAiPack, registerChartPack, registerCyberPack, registerEffectPacks, registerFestivalPack, registerFocusPack, registerFormPack, registerGamePack, registerGeoPack, registerGesture3Pack, registerGpuPack, registerLightPack, registerMorphPack, registerMusicPack, registerOrganicPack, registerPaperPack, registerPhysicsPack, registerRetroPack, registerShopPack, registerSocialPack, registerSurfacePack, registerTextPack, registerTransitionsPack, registerWeatherPack };
113
+ export { AI_FX, CHART_FX, CYBER_FX, DEPTH3_FX, EFFECT_PACKS, FESTIVAL_FX, FOCUS_FX, FORM_FX, GAME_FX, GEO_FX, GESTURE3_FX, GPU_FX, LIGHT_FX, MORPH2_FX, MUSIC_FX, ORGANIC_FX, PAPER_FX, PHYSICS2_FX, RETRO_FX, SHOP_FX, SOCIAL_FX, SPATIAL_FX, SURFACE_FX, TEXT3_FX, TRANSITIONS2_FX, WEATHER_FX, register3dPack, registerAiPack, registerChartPack, registerCyberPack, registerEffectPacks, registerFestivalPack, registerFocusPack, registerFormPack, registerGamePack, registerGeoPack, registerGesture3Pack, registerGpuPack, registerLightPack, registerMorphPack, registerMusicPack, registerOrganicPack, registerPaperPack, registerPhysicsPack, registerRetroPack, registerShopPack, registerSocialPack, registerSpatialPack, registerSurfacePack, registerTextPack, registerTransitionsPack, registerWeatherPack };
110
114
  //# sourceMappingURL=fx2.js.map