voice-ring 0.0.0-stage → 0.1.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.
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Jakub Antalik
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md CHANGED
@@ -1,3 +1,70 @@
1
- # Temporary Holding Version
1
+ # Voice ring
2
2
 
3
- This version is a temporary placeholder for this package. An operational version to replace this has been submitted for review and is awaiting a staged release.
3
+ A voice-reactive ring of light for AI voice interfaces: a few rings lean off the view axis and bundle into a glassy ribbon, a spectrum runs around it, and the voice bends every ring together. It takes the colour of the voice's emotion and leans toward whoever is speaking.
4
+
5
+ Voice ring is the `aura` type of the voice orbs, as a library of its own.
6
+
7
+ ## SwiftUI
8
+
9
+ The port lives in [`ports/ios/VoiceRingKit`](ports/ios/VoiceRingKit) and installs from the repository root with Swift Package Manager (iOS 17+ / macOS 14+, build through Xcode):
10
+
11
+ ```swift
12
+ .package(url: "https://github.com/Jakubantalik/Libraries.dev", branch: "main")
13
+ .product(name: "VoiceRingKit", package: "Libraries.dev")
14
+ ```
15
+
16
+ ```swift
17
+ import VoiceRingKit
18
+
19
+ struct VoiceScreen: View {
20
+ @State private var meter = VoiceMeter()
21
+
22
+ var body: some View {
23
+ VoiceRing(state: .listening, source: .meter(meter), size: 240)
24
+ .task { try? await meter.start() } // asks for the microphone
25
+ }
26
+ }
27
+ ```
28
+
29
+ Two models plug in:
30
+
31
+ - **Emotion** (`VoiceRingEmotion`, Pro): emotion2vec+ reads the tone of the voice, GoEmotions its words; pass `mood: emotion.mood`.
32
+ - **Direction** ([Voice direction](https://libraries.dev/voice-direction.html), free account): add `VoiceDirection.mfxl` to the app target and the ring leans toward the voice from the iPhone's stereo mics, no calibration.
33
+
34
+ Docs: https://libraries.dev/voice-ring.html
35
+
36
+ ## React
37
+
38
+ ```bash
39
+ npm install voice-ring
40
+ ```
41
+
42
+ ```tsx
43
+ import { VoiceRing, useMicrophone } from 'voice-ring';
44
+
45
+ function VoiceScreen() {
46
+ const mic = useMicrophone();
47
+ return (
48
+ <>
49
+ <VoiceRing size={240} state="listening" stream={mic.stream} />
50
+ <button onClick={mic.start}>Listen</button>
51
+ </>
52
+ );
53
+ }
54
+
55
+ // Drive it yourself instead of the microphone (0–1, read every frame):
56
+ <VoiceRing size={240} state="speaking" level={() => player.level} />
57
+ ```
58
+
59
+ - `state`: `idle`, `listening`, `speaking`, `processing`.
60
+ - `stream` (a `MediaStream`) or `level` (a number, or a getter read every frame).
61
+ - `emotion`: `positive`, `negative` or `calm` shifts the spectrum toward its colour.
62
+ - `direction`: −1 left … 1 right, a number or a getter. A browser microphone is mono, so the side comes from you: a stereo capture, a diarised speaker, or where that person sits in your UI. The ring barely drifts but leans toward it, and meets the screen's edge through a soft lens; the `direction…` props tune it.
63
+ - `hoverBend`: while the ring waits or works (`idle`, `processing`), it bends toward the cursor as it nears the rim, like a membrane, easing in and out. `true` bends at 0.55; a number 0–1 sets the strength. Desktop only (a fine pointer that hovers), and off with reduced motion.
64
+ - `sensitivity` (0.85), `speed`, `theme` (`auto`, `dark`, `light`), `paused`.
65
+
66
+ A 2D canvas with a small WebGL pass for the edge lens; React 18+.
67
+
68
+ `src/` is also what the libraries.dev preview and Studio draw. The engine is copied from the voice orbs project (`Voice orbs/src`); keep the two in step.
69
+
70
+ MIT License.
package/dist/index.cjs ADDED
@@ -0,0 +1,41 @@
1
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const zn=require("react/jsx-runtime"),$=require("react");let Dt=null;function $n(){if(typeof window>"u")return null;const t=window;return t.AudioContext??t.webkitAudioContext??null}function me(){return $n()!=null}function xn(){const t=$n();return t?(Dt||(Dt=new t),Dt.state==="suspended"&&Dt.resume().catch(()=>{}),Dt):null}const hn=new WeakMap;function Wn(t){const n=xn();if(!n||t.getAudioTracks().length===0)return null;let s=hn.get(t);s||(s={node:n.createMediaStreamSource(t),refs:0},hn.set(t,s)),s.refs+=1;const e=n.createAnalyser();e.fftSize=1024,e.smoothingTimeConstant=.5,s.node.connect(e);let o=!1;return{analyser:e,release:()=>{if(!o){o=!0;try{s.node.disconnect(e)}catch{}if(s.refs-=1,s.refs<=0){try{s.node.disconnect()}catch{}hn.delete(t)}}}}}const Gt={positive:{r:92,g:224,b:150},negative:{r:255,g:104,b:104},calm:{r:104,g:162,b:255}},Vn={green:Gt.positive,red:Gt.negative,blue:Gt.calm},Me=.7,ge=1.1,be=.6;class ve{constructor(){this.glow={r:0,g:0,b:0,amount:0,t:0,size:0}}step(n,s,e,o,r){const c=this.glow,l=a=>r?1:1-Math.exp(-n/a),i=s?1:0;if(c.amount+=(i-c.amount)*l(i>c.amount?Me:ge),s){const a=c.amount<.03?1:l(be);c.r+=(s.r-c.r)*a,c.g+=(s.g-c.g)*a,c.b+=(s.b-c.b)*a}return c.t=e,c.size=o,c}}const Xn=(t,n)=>{var s;return((s=t.light)==null?void 0:s.r)??n*.28};function xe(t,n,s){const o=(Xn(t,n)*.7)**2,r=.9*Math.min(1,Math.max(0,s.amount)),c=(l,i)=>{const a=s.x-l,p=s.y-i,h=r*Math.exp(-(a*a+p*p)/o);return[l+a*h,i+p*h]};return{...t,strokes:t.strokes.map(l=>{const i=l.pts.slice();for(let a=0;a<i.length;a+=2)[i[a],i[a+1]]=c(i[a],i[a+1]);return{...l,pts:i}}),dots:t.dots.map(l=>{const[i,a]=c(l.x,l.y);return{...l,x:i,y:a}})}}const ye=(t,n)=>Math.min(1,Math.max(0,(.8*n-t)/(.6*n))),xt={move:2,pull:.7,deform:.1,squash:.5,lens:.67,stretch:1,split:1,blur:1,bounce:1};function Se(t,n){const s=Math.abs(t.move)+Math.abs(t.pull)+2*Math.abs(t.deform);return s===0?0:Math.ceil(n*.36*s)+2}class we{constructor(){this.x=0,this.v=0,this.landed=!1}step(n,s){const r=Math.max(1,Math.ceil(s*240)),c=s/r;for(let i=0;i<r;i++)this.v+=(15*15*(n-this.x)-2*.3*15*this.v)*c,this.x+=this.v*c;const l=this.x-n;return n<=0?this.landed=!1:l>=0&&(this.landed=!0),l<0&&!this.landed?0:l}}function Ee(t,n,s,e,o=[1/0,1/0],r=0){if(Math.abs(n)<.002||e.move===0&&e.pull===0&&e.deform===0)return t;const c=s/2,l=s*.36,i=n<0?-1:1,a=Math.abs(n),p=(b,w)=>{const y=(b-c)/l,I=(w-c)/l,R=Math.max(0,Math.min(1,(y*i+1)/2)),B=Math.max(0,y*i);return n*l*(e.move+e.pull*R*R+e.deform*B*B*Math.exp(-I*I*1.5))},h=Math.max(0,Math.min(2,e.lens??1)),f=l*.9,m=i>0?o[1]:o[0],d=Number.isFinite(m)?Math.min(f*.45,l*.3*h*Math.max(0,e.stretch??1)):0;let M=1,v=1/0,_=1;if(Number.isFinite(m)){v=i>0?s+m:-m;const b=(w,y,I)=>{_=Math.max(_,I);const R=p(w,y)*i;R>1e-9&&(M=Math.min(M,Math.max(0,((v-w)*i-I-d)/R)))};for(const w of t.dots)b(w.x,w.y,w.r);for(const w of t.strokes)for(let y=0;y<w.pts.length;y+=2)b(w.pts[y],w.pts[y+1],1)}const u=M<1?Math.min(1,(1-M)/.35):0,g=u>0?r*(e.bounce??1):0,x=Math.min(1.4,u+Math.max(0,g)),O=l*.12*Math.max(0,-g),E=v-i*_,q=E-i*d,S=l*.55*x*(e.squash??0);let C=1/0,A=-1/0,D=!0;const U=(b,w)=>{const y=Math.max(0,Math.min(1,((b-c)/l*i+1)/2)),I=1-.15*e.deform*a*M*y;let R=b+p(b,w)*M+i*(S*.5-O),B=c+(w-c)*I;if(S>0){const k=(R-(q-i*S))*i;if(k>0){const F=k/S,T=S*(F/Math.sqrt(1+F*F));R=q-i*S+i*T,B=c+(B-c)*(1+.18*x*(e.squash??0)*(T/S))}}return D&&(q-R)*i<Math.max(S,f*.3)&&(C=Math.min(C,B),A=Math.max(A,B)),[R,B]};for(const b of t.dots)[b.x,b.y]=U(b.x,b.y);for(const b of t.strokes)for(let w=0;w<b.pts.length;w+=2){const[y,I]=U(b.pts[w],b.pts[w+1]);b.pts[w]=y,b.pts[w+1]=I}if(u>0&&A>C){const b=h*x;t.contact={side:i,x:E,y0:C,y1:A,depth:S,press:u,lens:b>.02?{zone:f,gap:d*Math.min(1,x),flare:.22*b*Math.max(0,e.stretch??1),split:f*.1*b*Math.max(0,e.split??1),blur:f*.075*b*Math.max(0,e.blur??1),cy:c}:void 0}}if(D=!1,t.light){const b=t.light;[b.cx,b.cy]=U(b.cx,b.cy);for(const w of b.spec)[w.x,w.y]=U(w.x,w.y)}return t}const bt=Math.PI*2;function kt(t,n,s){return t+(n-t)*s}function Z(t){return t<0?0:t>1?1:t}function yn(t,n,s){const e=Z((s-t)/(n-t));return e*e*(3-2*e)}const jt=t=>t<1e-6?1:Math.sin(t)/t,Te=Math.hypot(2.1,1.3),Re=Math.hypot(1.9,1.7),Ae=Math.hypot(4.3-2.9,-3.7,-3.1),Pe=Math.hypot(4.3+2.9,3.7,-3.1);function Sn(t,n,s,e=1){const o=1/Math.max(.05,e),r=.9*s,c=-.7*s+1.3,l=2.1*s,i=-1.6*s,a=t*(.55*Math.sin(r)*jt(Te*o)+.45*Math.sin(c)*jt(Re*o))+n*.5*(Math.cos(l-i)*jt(Ae*o)-Math.cos(l+i)*jt(Pe*o));return(p,h,f)=>(p*=o,h*=o,f*=o,t*(.55*Math.sin(2.1*p+1.3*h+r)+.45*Math.sin(1.7*f-1.9*h+c))+n*Math.sin(4.3*p-3.1*f+l)*Math.sin(3.7*h+2.9*p+i)-a)}function Tt(t,n){const s=Math.sin(t*12.9898+n*78.233)*43758.5453;return s-Math.floor(s)}function Et(t,n,s){const e=Math.sin(t*127.1+n*311.7+s*74.7)*43758.5453;return e-Math.floor(e)}function Ut(t,n,s){const e=Math.floor(t),o=Math.floor(n),r=Math.floor(s);let c=t-e,l=n-o,i=s-r;c=c*c*(3-2*c),l=l*l*(3-2*l),i=i*i*(3-2*i);const a=kt(Et(e,o,r),Et(e+1,o,r),c),p=kt(Et(e,o+1,r),Et(e+1,o+1,r),c),h=kt(Et(e,o,r+1),Et(e+1,o,r+1),c),f=kt(Et(e,o+1,r+1),Et(e+1,o+1,r+1),c);return kt(kt(a,p,l),kt(h,f,l),i)}function wn(t,n){const s=Math.PI*(3-Math.sqrt(5)),e=1-2*(t+.5)/n,o=Math.sqrt(1-e*e),r=t*s;return[o*Math.cos(r),e,o*Math.sin(r)]}function Qt(t,n,s,e,o){const r=Math.sin(n),c=Math.cos(n),l=Math.sin(t),i=Math.cos(t);return(a,p,h)=>{const f=a*i+h*l,m=-a*l+h*i,d=p*c-m*r,M=p*r+m*c;return[s+f*o,e-d*o,M]}}function zt(t,n=.6){return(t/200)**n}function Nt(t,n,s=.3){const e=[];for(const o of t)(o.a??1)<.02||(o.r=Math.max(s,o.r),e.push(o));return e.sort((o,r)=>o.z-r.z),{dots:e,strokes:n}}const Ht=32;function _e(t,n=0,s=0,e=1){const o=t.r/255,r=t.g/255,c=t.b/255,l=Math.max(o,r,c),i=Math.min(o,r,c);let a=(l+i)/2,p=l===i?0:(l-i)/(1-Math.abs(2*a-1)),h=0;if(l!==i){const M=l-i;h=l===o?(r-c)/M%6:l===r?(c-o)/M+2:(o-r)/M+4,h*=60}h=((h+n)%360+360)%360,p=Math.min(1,p*(1+s)),a=.5+(a-.5)*(1-.6*s),a=Math.max(0,Math.min(1,a*e));const f=M=>(M+h/30)%12,m=p*Math.min(a,1-a),d=M=>a-m*Math.max(-1,Math.min(f(M)-3,9-f(M),1));return[Math.round(d(0)*255),Math.round(d(8)*255),Math.round(d(4)*255)]}function Ce(t){const n=Math.max(0,Math.min(1,t.saturation)),s=Math.max(0,Math.min(1,t.neutral)),e=t.start??.1,o=Math.max(.05,t.width??.6),r=[];for(let h=0;h<Ht;h++){const f=h/(Ht-1),m=Math.max(0,Math.min(1,(f-e)/o)),d=m*m*(3-2*m);r.push(n*(1-s*(1-d)))}const c=t.angle*Math.PI/180,l=Math.cos(c),i=Math.sin(c),a=t.size/2,p=t.size*.8;return{rgb:_e(t.accent,t.hue,Math.max(0,Math.min(1,t.vivid??0)),t.brightness),mix:r,saturation:n,at:(h,f)=>{const m=((h-a)*l+(f-a)*i)/p+.5;return Math.max(0,Math.min(Ht-1,Math.round(m*(Ht-1))))}}}const ke=[120,232,214],Fe=[64,72,255];function On(t,n,s){t/=255,n/=255,s/=255;const e=Math.max(t,n,s),o=Math.min(t,n,s),r=(e+o)/2;if(e===o)return[0,0,r];const c=e-o,l=r>.5?c/(2-e-o):c/(e+o);return[(e===t?(n-s)/c+(n<s?6:0):e===n?(s-t)/c+2:(t-n)/c+4)/6,l,r]}function Ie(t,n,s){const e=c=>(c+t*12)%12,o=n*Math.min(s,1-s),r=c=>s-o*Math.max(-1,Math.min(e(c)-3,9-e(c),1));return[r(0)*255,r(8)*255,r(4)*255]}const un=t=>(t/=255)<=.04045?t/12.92:((t+.055)/1.055)**2.4,Ne=t=>255*(t<=.0031308?12.92*t:1.055*Math.max(0,t)**(1/2.4)-.055);function vn(t,n,s){const[e,o,r]=[un(t),un(n),un(s)],c=Math.cbrt(.4122214708*e+.5363325363*o+.0514459929*r),l=Math.cbrt(.2119034982*e+.6806995451*o+.1073969566*r),i=Math.cbrt(.0883024619*e+.2817188376*o+.6299787005*r);return[.2104542553*c+.793617785*l-.0040720468*i,1.9779984951*c-2.428592205*l+.4505937099*i,.0259040371*c+.7827717662*l-.808675766*i]}function Kn(t,n,s){const e=(t+.3963377774*n+.2158037573*s)**3,o=(t-.1055613458*n-.0638541728*s)**3,r=(t-.0894841775*n-1.291485548*s)**3,c=l=>Math.max(0,Math.min(255,Ne(l)));return[c(4.0767416621*e-3.3077115913*o+.2309699292*r),c(-1.2684380046*e+2.6097574011*o-.3413193965*r),c(-.0041960863*e-.7034186147*o+1.707614701*r)]}function Oe(t,n,s,e){const o=e&&e.amount>.005?e:void 0;return t.map(([r,c,l,i])=>{if(s&&(c+=(s.r-c)*.85,l+=(s.g-l)*.85,i+=(s.b-i)*.85),o){const[,p,h]=On(c,l,i),[f]=On(o.r,o.g,o.b),m=Ie((f+.1*Math.sin(2*Math.PI*r)+1)%1,p,h),d=vn(c,l,i),M=vn(m[0],m[1],m[2]),v=o.amount;[c,l,i]=Kn(d[0]+(M[0]-d[0])*v,d[1]+(M[1]-d[1])*v,d[2]+(M[2]-d[2])*v)}const a=n?1:.82;return[r,c*a,l*a,i*a]})}const Yn=(t,n,s)=>`rgb(${Math.round(t)},${Math.round(n)},${Math.round(s)})`;function Be(t,n=36){const s=t.filter(([a])=>a<1),e=s.length;if(e<3)return t;const o=s.map(([,a,p,h])=>vn(a,p,h)),r=a=>(a%e+e)%e,c=a=>s[r(a)][0]+Math.floor(a/e),l=a=>{const p=c(a+1)-c(a-1);return o[r(a+1)].map((h,f)=>(h-o[r(a-1)][f])/p)},i=[];for(let a=0;a<=n;a++){const p=a/n;let h=-1;for(;h<e-1&&c(h+1)<=p;)h++;const f=c(h+1)-c(h),m=(p-c(h))/f,d=m*m,M=d*m,v=o[r(h)],_=o[r(h+1)],u=l(h),g=l(h+1),x=[0,1,2].map(S=>(2*M-3*d+1)*v[S]+(M-2*d+m)*f*u[S]+(-2*M+3*d)*_[S]+(M-d)*f*g[S]),[O,E,q]=Kn(x[0],x[1],x[2]);i.push([p,O,E,q])}return i}const Le=1.5,jn=typeof CanvasRenderingContext2D=="function"&&"filter"in CanvasRenderingContext2D.prototype,Bn=new WeakMap;function fn(t,n){return(typeof OffscreenCanvas=="function"?new OffscreenCanvas(t,n):Object.assign(document.createElement("canvas"),{width:t,height:n})).getContext("2d")}function qe(t){const{width:n,height:s}=t.canvas;let e=Bn.get(t);return(!e||e.full.canvas.width!==n||e.full.canvas.height!==s)&&(e={full:fn(n,s)},jn||(e.half=fn(Math.ceil(n/2),Math.ceil(s/2)),e.quarter=fn(Math.ceil(n/4),Math.ceil(s/4))),Bn.set(t,e)),e.full.setTransform(1,0,0,1,0,0),e.full.clearRect(0,0,n,s),e.full.setTransform(t.getTransform()),e}function dn(t,n){t.globalCompositeOperation="copy",t.imageSmoothingEnabled=!0,t.imageSmoothingQuality="high",t.drawImage(n.canvas,0,0,t.canvas.width,t.canvas.height)}function De(t,n,s){const e=t.getTransform();t.save(),t.setTransform(1,0,0,1,0,0),t.globalCompositeOperation=s,t.globalAlpha=1,t.imageSmoothingEnabled=!0,t.imageSmoothingQuality="high",jn?(t.filter=`blur(${Le*Math.hypot(e.a,e.b)}px)`,t.drawImage(n.full.canvas,0,0)):n.half&&n.quarter&&(dn(n.half,n.full),dn(n.quarter,n.half),dn(n.half,n.quarter),t.drawImage(n.half.canvas,0,0,n.half.canvas.width*2,n.half.canvas.height*2)),t.restore()}function Ln(t,n,s){const e=typeof t.createConicGradient=="function"?t.createConicGradient(n.angle,n.cx,n.cy):t.createLinearGradient(n.cx-n.r,n.cy-n.r,n.cx+n.r,n.cy+n.r);for(const[o,r,c,l]of s)e.addColorStop(Z(o),Yn(r,c,l));return e}function Ge(t,n,s,e,o,r){const c=Be(Oe(s.stops,e,o,r)),l=Ln(t,s,c),i=n.strokes.map(u=>{const g=new Path2D,x=u.pts.length>>1;let O=0;for(let E=0;E<x;E++)E===0?g.moveTo(u.pts[0],u.pts[1]):g.lineTo(u.pts[2*E],u.pts[2*E+1]),O+=u.a[E];return u.closed&&g.closePath(),{p:g,a:x?O/x:1,w:u.w}}),a=Math.max(1,i.length),p=s.intensity,h=e?"lighter":"source-over",f=(u,g,x=t)=>{for(const O of i)x.lineWidth=u(O.w),x.globalAlpha=Z(g(O.a)),x.stroke(O.p)},m=(u,g)=>{u.lineCap="round",u.lineJoin="round",u.globalCompositeOperation=h,u.strokeStyle=g},d=qe(t),M=d.full;m(M,Ln(M,s,c));const v=s.halo*p*(e?1:.2)/a;for(const[u,g]of[[.7,.045],[.42,.075],[.24,.11],[.12,.16]])f(()=>s.r*u,()=>g*v,M);const _=p*(e?1:.6);for(const[u,g]of[[16,.05],[8,.11],[4,.2]])f(x=>x*u,x=>g*_*x,M);if(De(t,d,h),t.save(),m(t,l),e&&s.fringe>0){for(const[u,g,x]of[[1+s.fringe,ke,.16],[1-s.fringe,Fe,.22]])t.save(),t.translate(s.cx,s.cy),t.scale(u,u),t.translate(-s.cx,-s.cy),t.strokeStyle=Yn(g[0],g[1],g[2]),f(O=>O*1.4/u,O=>x*p*O),t.restore();t.strokeStyle=l}if(f(u=>u,u=>.7*u*(.75+.25*p)),e)for(const u of s.spec){const g=t.createRadialGradient(u.x,u.y,0,u.x,u.y,u.r);g.addColorStop(0,"rgba(255,255,255,1)"),g.addColorStop(.35,"rgba(255,255,255,0.45)"),g.addColorStop(1,"rgba(255,255,255,0)"),t.strokeStyle=g,f(x=>x*2.2,x=>u.a*x)}t.restore()}const Ue=`
2
+ attribute vec2 aPos;
3
+ varying vec2 vUv;
4
+ void main() {
5
+ vUv = vec2(aPos.x + 1.0, 1.0 - aPos.y) * 0.5;
6
+ gl_Position = vec4(aPos, 0.0, 1.0);
7
+ }`,ze=`
8
+ precision highp float;
9
+ uniform sampler2D uTex;
10
+ uniform vec2 uSize;
11
+ uniform float uWall, uSide, uZone, uGap, uFlare, uSplit, uBlur, uCy;
12
+ varying vec2 vUv;
13
+ const int TAPS = 16;
14
+ vec4 tap(vec2 p) { return texture2D(uTex, p / uSize); }
15
+ void main() {
16
+ vec2 p = vUv * uSize;
17
+ // 0 a zone back from the edge … 1 at it and past it
18
+ float t = clamp(1.0 - (uWall - p.x) * uSide / uZone, 0.0, 1.0);
19
+ if (t <= 0.0) { gl_FragColor = tap(p); return; }
20
+ float w = t * t;
21
+ // drawn out across the gap toward the edge, and opened a little taller
22
+ float d = (uWall - p.x) * uSide + uGap * w;
23
+ vec2 s = vec2(uWall - uSide * d, uCy + (p.y - uCy) / (1.0 + uFlare * w));
24
+ // dispersion: red bent further out than blue, along the stretch and the flare
25
+ vec2 split = vec2(uSide, 0.6 * (p.y - uCy) / uZone) * uSplit * w;
26
+ // the blur grows toward the edge, drawn out along the stretch
27
+ float b = uBlur * w;
28
+ vec3 rgb = vec3(0.0);
29
+ float a = 0.0;
30
+ for (int i = 0; i < TAPS; i++) {
31
+ float f = float(i);
32
+ float r = sqrt((f + 0.5) / float(TAPS)) * b;
33
+ vec2 o = vec2(cos(f * 2.39996) * 1.8, sin(f * 2.39996)) * r;
34
+ vec4 cr = tap(s + o + split);
35
+ vec4 cg = tap(s + o);
36
+ vec4 cb = tap(s + o - split);
37
+ rgb += vec3(cr.r, cg.g, cb.b);
38
+ a += max(cg.a, max(cr.a, cb.a));
39
+ }
40
+ gl_FragColor = vec4(rgb, a) / float(TAPS);
41
+ }`;let Zt;function $e(){if(typeof document>"u")return null;const t=document.createElement("canvas"),n=t.getContext("webgl",{premultipliedAlpha:!0,antialias:!1,depth:!1});if(!n)return null;const s=(i,a)=>{const p=n.createShader(i);return n.shaderSource(p,a),n.compileShader(p),p},e=n.createProgram();if(n.attachShader(e,s(n.VERTEX_SHADER,Ue)),n.attachShader(e,s(n.FRAGMENT_SHADER,ze)),n.linkProgram(e),!n.getProgramParameter(e,n.LINK_STATUS))return null;n.useProgram(e);const o=n.createBuffer();n.bindBuffer(n.ARRAY_BUFFER,o),n.bufferData(n.ARRAY_BUFFER,new Float32Array([-1,-1,1,-1,-1,1,1,1]),n.STATIC_DRAW);const r=n.getAttribLocation(e,"aPos");n.enableVertexAttribArray(r),n.vertexAttribPointer(r,2,n.FLOAT,!1,0,0);const c=n.createTexture();n.bindTexture(n.TEXTURE_2D,c),n.texParameteri(n.TEXTURE_2D,n.TEXTURE_WRAP_S,n.CLAMP_TO_EDGE),n.texParameteri(n.TEXTURE_2D,n.TEXTURE_WRAP_T,n.CLAMP_TO_EDGE),n.texParameteri(n.TEXTURE_2D,n.TEXTURE_MIN_FILTER,n.LINEAR),n.texParameteri(n.TEXTURE_2D,n.TEXTURE_MAG_FILTER,n.LINEAR),n.pixelStorei(n.UNPACK_PREMULTIPLY_ALPHA_WEBGL,!0);const l={};for(const i of["uSize","uWall","uSide","uZone","uGap","uFlare","uSplit","uBlur","uCy"])l[i]=n.getUniformLocation(e,i);return{gl:n,canvas:t,source:document.createElement("canvas"),tex:c,u:l}}function We(t,n,s,e){if(Zt===void 0&&(Zt=$e()),!Zt)return!1;const{gl:o,canvas:r,source:c,tex:l,u:i}=Zt,a=t.getTransform(),p=Math.hypot(a.a,a.b)||1,h=t.canvas.width,f=t.canvas.height,m=a.a*s+a.e,d=e.zone*p,M=e.blur*p,v=Math.max(0,Math.floor(n>0?m-d-2*M-4:0)),u=Math.min(h,Math.ceil(n>0?h:m+d+2*M+4))-v;if(u<2||f<2)return!1;(c.width!==u||c.height!==f)&&(c.width=u,c.height=f);const g=c.getContext("2d");return g.clearRect(0,0,u,f),g.drawImage(t.canvas,v,0,u,f,0,0,u,f),(r.width!==u||r.height!==f)&&(r.width=u,r.height=f),o.viewport(0,0,u,f),o.bindTexture(o.TEXTURE_2D,l),o.texImage2D(o.TEXTURE_2D,0,o.RGBA,o.RGBA,o.UNSIGNED_BYTE,c),o.uniform2f(i.uSize,u,f),o.uniform1f(i.uWall,m-v),o.uniform1f(i.uSide,n),o.uniform1f(i.uZone,d),o.uniform1f(i.uGap,e.gap*p),o.uniform1f(i.uFlare,e.flare),o.uniform1f(i.uSplit,e.split*p),o.uniform1f(i.uBlur,M),o.uniform1f(i.uCy,a.d*e.cy+a.f),o.clearColor(0,0,0,0),o.clear(o.COLOR_BUFFER_BIT),o.drawArrays(o.TRIANGLE_STRIP,0,4),t.save(),t.setTransform(1,0,0,1,0,0),t.globalCompositeOperation="copy",t.beginPath(),t.rect(v,0,u,f),t.clip(),t.drawImage(r,v,0),t.restore(),!0}function Hn(t,n,s,e){const o=2.2/e.size,r=Ut(t*o+e.t*.11,n*o-e.t*.08,e.t*.07),c=yn(.3,.75,r);return e.amount*(.2+.75*c)*Z(1.3-s)}function Zn(t,n,s,e,o,r=0,c,l=0){const i=Math.round(n*1e3)/1e3,a=d=>s?d*(1-t):d+(255-d)*t,p=(s?1-t:t)*255;let h=e?a(e.r):p,f=e?a(e.g):p,m=e?a(e.b):p;return c&&l>0&&(h+=(a(c[0])-h)*l,f+=(a(c[1])-f)*l,m+=(a(c[2])-m)*l),o&&r>0&&(h+=(a(o.r)-h)*r,f+=(a(o.g)-f)*r,m+=(a(o.b)-m)*r),`rgba(${Math.round(h)},${Math.round(f)},${Math.round(m)},${i})`}const qn=24,Dn=8;function Ve(t,n,s,e,o,r){const c=o&&o.amount>.005?o:void 0,l=r&&r.saturation>0?r:void 0,i=new Map;for(const a of n){const p=a.pts.length>>1,h=a.closed?p:p-1;let f="",m;for(let d=0;d<h;d++){const M=d+1===p?0:d+1,v=Math.round(Z((a.a[d]+a.a[M])/2)*qn);if(v===0){f="";continue}const _=c?Math.round(Hn((a.pts[2*d]+a.pts[2*M])/2,(a.pts[2*d+1]+a.pts[2*M+1])/2,a.white,c)*Dn):0,u=l?l.at((a.pts[2*d]+a.pts[2*M])/2,(a.pts[2*d+1]+a.pts[2*M+1])/2):0,g=`${v}|${a.white}|${Math.round(a.w*20)}|${_}|${u}`;if(g!==f){let x=i.get(g);x||(x={path:new Path2D,white:a.white,w:a.w,a:v/qn,gw:_/Dn,ci:u},i.set(g,x)),m=x,f=g,x.path.moveTo(a.pts[2*d],a.pts[2*d+1])}m.path.lineTo(a.pts[2*M],a.pts[2*M+1])}}t.lineCap="round",t.lineJoin="round";for(const a of i.values())t.strokeStyle=Zn(Z(a.white),a.a,s,e,c,a.gw,l==null?void 0:l.rgb,l==null?void 0:l.mix[a.ci]),t.lineWidth=a.w,t.stroke(a.path)}function Xe(t,n,s,e,o,r,c=!1){const l=o&&o.amount>.005?o:void 0,i=r&&r.saturation>0?r:void 0;for(const a of n){const p=Z(a.white),h=l?Hn(a.x,a.y,p,l):0,f=i?i.at(a.x,a.y):0;if(t.fillStyle=Zn(p,Z(a.a??1),s,e,l,h,i==null?void 0:i.rgb,i==null?void 0:i.mix[f]),c){t.fillRect(a.x-a.r,a.y-a.r,2*a.r,2*a.r);continue}t.beginPath(),t.arc(a.x,a.y,a.r,0,bt),t.fill()}}function Ke(t,n,s,e,o,r){var l;const c=r&&r.saturation>0&&!n.light?Ce(r):void 0;n.light?Ge(t,n,n.light,s,e,o):n.strokes.length&&Ve(t,n.strokes,s,e,o,c),Xe(t,n.dots,s,e,o,c,n.square),(l=n.contact)!=null&&l.lens&&We(t,n.contact.side,n.contact.x,n.contact.lens)}const Ye=[[0,255,150,90],[.12,255,110,120],[.24,255,80,170],[.4,190,80,255],[.58,90,92,255],[.74,60,132,255],[.84,170,90,255],[.93,240,104,165],[1,255,150,90]],je=(t,n,s,e)=>{const o=t/2,r=s.level,[c,l]=s.softBands,i=s.bands[2],a=s.drive,p=s.processing,h=.5*r+.5*s.soft,f=o*(e.radius??.56)*(1+(e.zoom??.17)*s.soft)*(1-.06*p),m=e.deform??1.45,d=.02+(.14*c+.06*r)*m,M=.01+(.07*l+.03*i)*m,v=Sn(d,M,a,e.deformRadius??1.75),_=Math.max(.6,(e.lineW??1.85)*zt(t,.5)),u=Math.max(1,Math.round(e.rings??6)),g=Math.max(24,Math.round(e.segs??140)),x=e.lean??.91,O=e.ringGap??.02,E=[];let q=0,S=0;for(let y=0;y<u;y++){const I=.16*(.5+Tt(y,2.1))*(y%2?1:-1),R=Math.max(.02,x*(.2+.8*Tt(y,3.1))+.03*Math.sin(n*.27+y*1.3)+.08*Math.sin(a*.35+y*1.7)),B=Tt(y,7.7)*bt+n*.05*(y%2?1:-1)+a*I,k=Math.sin(R)*Math.cos(B),F=Math.sin(R)*Math.sin(B),T=Math.cos(R),P=Math.hypot(k,T),N=T/P,G=-k/P,z=F*G,V=T*N-k*G,X=-F*N,tt=f*(1+O*(y-(u-1)/2)),J=Math.sin(R),K=[],ct=[],st=[];for(let Y=0;Y<g;Y++){const ot=Y/g*bt,W=Math.cos(ot),ut=Math.sin(ot),ft=N*W+z*ut,nt=V*ut,dt=G*W+X*ut,pt=v(ft,nt,dt);K.push(ft,nt),ct.push(pt),q+=pt,S++,st.push(.62+.38*Z((dt/J+1)/2))}E.push({dirs:K,f:ct,a:st,rk:tt})}const C=S?q/S:0;let A=0,D=0;for(const{dirs:y,f:I}of E)for(let R=0;R<I.length;R++){const B=y[2*R],k=y[2*R+1],F=Math.hypot(B,k)||1;A+=(I[R]-C)*(B/F),D+=(I[R]-C)*(k/F)}A=S?2*A/S:0,D=S?2*D/S:0;const U=E.map(({dirs:y,f:I,a:R,rk:B})=>{const k=[];for(let F=0;F<I.length;F++){const T=y[2*F],P=y[2*F+1],N=Math.hypot(T,P)||1,G=B*(1+I[F]-C-A*(T/N)-D*(P/N));k.push(o+T*G,o-P*G)}return{pts:k,a:R,white:0,w:_,closed:!0}}),b=2.3+.25*Math.sin(n*.21)+2*s.spin,w={cx:o,cy:o,r:f,stops:Ye,angle:-Math.PI/2-.35+.5*Math.sin(n*.07)+.4*Math.sin(a*.2)+s.spin,intensity:.62+.55*h+.5*p,halo:(e.halo??.5)*(1+.6*p),spec:[{x:o+Math.cos(b)*f,y:o+Math.sin(b)*f,r:f*(.5+.25*p),a:.5+.35*h+.4*p}],fringe:.016+.012*h};return{...Nt([],U),light:w}},Jn=-.45,Qn=.55,te=.7,He=Math.hypot(Jn,Qn,te),Ze=(t,n,s,e)=>{const o=t/2,r=s.level,[c,l,i]=s.bands,a=s.drive,p=s.processing,h=o*(e.radius??.72),f=h*(1+(e.zoom??.3)*r)*(1-.06*p),m=e.rMul??1,d=Math.max(4,Math.round(e.cells??17)),M=2*h/d,v=M/2-Math.max(.5,M*(e.gap??.24)/2),_=Math.ceil(f*1.25/M),u=(e.turn??.12)*n+.1*a+.5*s.spin,g=Math.sin(u),x=Math.cos(u),O=Math.sin(.35),E=Math.cos(.35),q=e.shade??.7,S=e.texture??.35,C=e.fade??1.3,A=e.strength??1.38,D=e.deform??1.7,U=.012+(.09*c+.03*r)*D,b=(.035*l+.025*i)*D,w=k=>U*(.55*Math.sin(2*k+.9*a)+.45*Math.sin(3*k-.7*a+1.3))+b*Math.sin(7*k+2.3*a)*Math.sin(5*k-1.7*a),y=.95*Math.sin(n*1.3),I=s.spectrum,R=I.length,B=[];for(let k=-_;k<=_;k++)for(let F=-_;F<=_;F++){const T=o+F*M,P=o+k*M,N=(T-o)/f,G=-(P-o)/f,z=w(Math.atan2(G,N)),V=Math.hypot(N,G)/(1+z);if(V>=1)continue;const X=1/(1+z),tt=N*X,J=G*X,K=Math.sqrt(Math.max(0,1-tt*tt-J*J)),ct=Z((tt*Jn+J*Qn+K*te)/He),st=1-q+q*ct,Y=J*E+K*O,ot=-J*O+K*E,W=tt*x-ot*g,ut=tt*g+ot*x,ft=.65*Ut(W*2.2+a*.15,Y*2.2,ut*2.2-a*.1)+.35*Ut(W*4.6-a*.2,Y*4.6+7.3,ut*4.6),nt=1-S+S*yn(.32,.68,ft),dt=R?I[Math.min(R-1,Math.floor(V*R))]:r,pt=.35*r+.85*dt,Rt=Math.exp(-((J-y)**2)/.01)*p,$t=1-.4*C*(1-K),rt=(.35+.75*st*nt+.3*pt+.2*Rt)*$t*m,At=.22+.62*st*nt+.22*pt+.3*Rt;B.push({x:T,y:P,z:K*f,r:v*Math.min(1,rt),white:Z(1-At*A),a:Z((1-.75*C*(1-Math.sqrt(K)))*A)})}return{...Nt(B,[],e.rMin??.4),square:!0}},Je=(t,n,s,e)=>{const o=t/2,r=t/2,c=.5*s.level+.5*s.soft,l=(1+(e.swell??.49)*c)*(1-.14*s.processing),i=t/2*(e.radius??.56),a=e.persp??.25,p=Qt(n*.12+s.drive*.03,.3,0,0,1),h=zt(t,e.rsPow??.9)*(e.rMul??1),f=[],m=e.orbitN??12,d=e.particles??6;for(let M=0;M<m;M++){const v=Tt(M,1.7),_=Tt(M,5.2),u=Tt(M,8.9),g=i*(.45+.52*v),x=v*bt,O=Math.acos(2*_-1),E=Math.sin(O)*Math.cos(x),q=Math.cos(O),S=Math.sin(O)*Math.sin(x);let C=-q,A=E;const D=Math.max(1e-6,Math.sqrt(C*C+A*A));C/=D,A/=D;const U=-S*A,b=S*C,w=E*A-q*C,y=(.25+.55*u)*(u>.5?1:-1);for(let I=0;I<d;I++){const R=s.drive*y+I/d*bt+_*6,B=Math.cos(R),k=Math.sin(R),[F,T,P]=p((C*B+U*k)*g,(A*B+b*k)*g,w*k*g),N=Z((P/i+1)/2),G=l/(1-a*P/i);f.push({x:o+F*G,y:r+T*G,z:P,r:((e.partR??.47)+(e.partRDepth??.65)*N)*h*G,white:.32-.24*N})}}return Nt(f,[],e.rMin)},Qe=(t,n,s,e)=>{const o=t/2,r=t/2,c=s.soft,[l,i]=s.softBands,a=t/2*(e.radius??.66)*(1+(e.zoom??.21)*s.level),p=s.drive,h=e.deform??1,f=e.wave??1,m=.015+(.1*l+.05*s.level)*h,d=.04*i*h,M=Sn(m,d,p),v=.55+.05*Math.sin(n*.37),_=Math.cos(v),u=Math.sin(v);let g=0;for(let T=0;T<48;T++){const P=T/48*bt;g+=M(Math.cos(P),Math.sin(P)*_,Math.sin(P)*u)}g/=48;const x=(T,P,N)=>1+M(T,P,N)-g,E=Qt(0,.3,o,r,1),q=zt(t,e.rsPow??.6)*(e.rMul??1),S=s.drive,C=[],A=e.ghostN??60;for(let T=0;T<A;T++){const P=wn(T,A),N=a*x(P[0],P[1],P[2]),[G,z,V]=E(P[0]*N,P[1]*N,P[2]*N),X=(V/a+1)/2;C.push({x:G,y:z,z:V,r:.65*q,white:.78,a:.1+.22*X})}const D=-u,U=_,b=Math.max(1,Math.round(e.lanes??10)),w=Math.max(8,Math.round(e.segs??56)),y=s.processing,I=(e.laneGap??.062)*(1+.25*c)*(1-.4*y),R=S*1.6,B=.15*(.55+.9*l*f)*(1-.6*y),k=.06*(.5+1.2*i*f),F=.05+.05*c;for(let T=0;T<b;T++){const P=(T-(b-1)/2)*I,N=Math.abs(T-(b-1)/2)/Math.max(1,(b-1)/2);for(let G=0;G<w;G++){const z=G/w*bt,V=B*Math.sin(z*3-S*.95+T*.18)+k*Math.sin(z*5+S*.6)+F*Math.sin(z*2+n*.31+Math.sin(n*.17)*1.5),X=P+V,tt=Math.cos(z),J=Math.sin(z),K=tt,ct=J*_+D*X,st=J*u+U*X,Y=Math.sqrt(K*K+ct*ct+st*st),ot=a*x(K/Y,ct/Y,st/Y)/Y,[W,ut,ft]=E(K*ot,ct*ot,st*ot),nt=(ft/a+1)/2,dt=Math.max(0,V)*c,pt=Math.atan2(Math.sin(z-R),Math.cos(z-R)),Rt=Math.exp(-(pt*pt)/.18)*y;C.push({x:W,y:ut,z:ft,r:((e.rBase??.49)+(e.rDepth??.78)*nt)*(1-.25*N)*(1+1.2*dt+.5*Rt)*q,white:.52-.44*nt+.18*N-.3*Rt,a:.4+.6*nt})}}return Nt(C,[],e.rMin)},ts=(t,n,s,e)=>{const o=t/2,r=s.level,[c,l]=s.softBands,i=s.bands[2],a=s.drive,p=o*(e.radius??.6)*(1+(e.zoom??.06)*s.soft)*(1-.08*s.processing),h=Qt((e.yaw??.42)+.08*Math.sin(n*.23),e.tilt??.32,o,o,1),f=Math.max(.4,(e.lineW??.6)*zt(t,.5)),m=E=>.06+.94*Z((E/p+1)/2)**2,d=e.deform??1,M=.02+(.14*c+.06*r)*d,v=.01+(.07*l+.03*i)*d,_=Sn(M,v,a),u=[],g=Math.max(24,Math.round(e.segs??96)),x=Math.max(0,Math.round(e.limbs??2));for(let E=0;E<x;E++){const q=.1+.05*Math.sin(n*.31+E*2.1),S=n*.17*(E%2?1:-1)+E*2.4,C=Math.sin(q)*Math.cos(S),A=Math.sin(q)*Math.sin(S),D=Math.cos(q),U=Math.hypot(C,D),b=D/U,w=-C/U,y=A*w,I=D*b-C*w,R=-A*b,B=[],k=[];for(let F=0;F<g;F++){const T=F/g*bt,P=b*Math.cos(T)+y*Math.sin(T),N=I*Math.sin(T),G=w*Math.cos(T)+R*Math.sin(T),z=p*(1+.006*E+_(P,N,G));B.push(o+P*z,o-N*z),k.push(.55+.35*Z((G/Math.sin(q)+1)/2))}u.push({pts:B,a:k,white:0,w:f,closed:!0})}const O=Math.max(2,Math.round(e.circles??8));for(let E=0;E<O;E++){const[q,S,C]=wn(E,O),A=a*.16*(.5+Tt(E,2.1))*(E%2?1:-1)+Tt(E,6.6)*bt,D=S*Math.cos(A)-C*Math.sin(A),U=S*Math.sin(A)+C*Math.cos(A),b=Math.max(1e-6,Math.hypot(U,q)),w=U/b,y=-q/b,I=D*y,R=U*w-q*y,B=-D*w,k=[],F=[];for(let T=0;T<g;T++){const P=T/g*bt,N=w*Math.cos(P)+I*Math.sin(P),G=R*Math.sin(P),z=y*Math.cos(P)+B*Math.sin(P),V=p*(1+_(N,G,z)),[X,tt,J]=h(N*V,G*V,z*V);k.push(X,tt),F.push(m(J))}u.push({pts:k,a:F,white:0,w:f,closed:!0})}return Nt([],u,e.rMin)},ns=(t,n,s,e)=>{const o=t/2,r=s.level,[c,l,i]=s.bands,a=s.drive,p=s.processing,h=o*(e.radius??.6)*(1+(e.zoom??.1)*r)*(1-.08*p),f=.95*Math.sin(n*1.3),m=Qt(n*.14,.32,o,o,1),d=zt(t,e.rsPow??.6)*(e.rMul??1),M=Math.max(40,Math.round(e.dotN??900)),v=e.cloudFreq??2.3,_=e.deform??1,u=.018+(.12*c+.04*r)*_,g=(.045*l+.03*i)*_,x=[],O=[];let E=0;for(let S=0;S<M;S++){const C=wn(S,M),[A,D,U]=C,b=.55*Math.sin(2.1*A+1.3*D+.9*a)+.45*Math.sin(1.7*U-1.9*D-.7*a+1.3),w=Math.sin(5.3*A-4.1*U+2.3*a)*Math.sin(4.7*D+3.1*A-1.7*a),y=u*b+g*w;x.push(C),O.push(y),E+=y/M}const q=[];for(let S=0;S<M;S++){const[C,A,D]=x[S],U=O[S]-E,b=h*(1+U),[w,y,I]=m(C*b,A*b,D*b),R=Z((I/h+1)/2),B=.65*Ut(C*v+a*.21,A*v-a*.15,D*v+a*.1)+.35*Ut(C*v*2.1-a*.29,A*v*2.1+7.3,D*v*2.1+a*.24),k=yn(.34,.68,B),F=Math.exp(-((A-f)**2)/.012)*p,T=Math.max(0,U)/.16;q.push({x:w,y,z:I,r:((e.rBase??.27)+(e.rDepth??.84)*R)*(.22+.95*k+.6*F)*(1+.5*T)*d,white:.62-.52*R-.16*k-.3*F,a:.3+.7*R})}return Nt(q,[],e.rMin??.25)},es=["orbit","sash","signal","swell","pixel","aura"],ss={orbit:Je,sash:Qe,signal:ts,swell:ns,pixel:Ze,aura:je},et={orbit:{speed:1.05,driveGain:.12,opts:{orbitN:12,particles:6},counts:{}},sash:{speed:1.5,driveGain:.8,gain:1.1,opts:{lanes:10,segs:56,ghostN:60},counts:{segs:.45,ghostN:.8}},signal:{speed:1.6,driveGain:2,opts:{circles:8,segs:96},counts:{circles:.5,segs:.5}},swell:{speed:1.4,driveGain:2.4,opts:{dotN:900},counts:{dotN:1}},pixel:{speed:1.2,driveGain:1.6,attack:.16,dotSize:.55,opts:{cells:17},counts:{cells:.5}},aura:{speed:1.6,driveGain:2,voiceSpeed:.9,lean:{move:.21,pull:.36,deform:.28,squash:0,bounce:.92,lens:.49,stretch:1.04,split:1.01,blur:1.24},opts:{rings:6,segs:140},counts:{segs:.5}}};function ne(t,n,s=1,e=1){const o=t in et?t:"orbit",r=et[o],c=Math.min(1.4,Math.max(.2,n/200))*Math.max(.1,s),l={...r.opts};for(const[i,a]of Object.entries(r.counts)){const p=l[i];p!=null&&(l[i]=Math.max(1,Math.round(p*c**a)))}return e!==1&&(l.rMul=Math.max(.1,e)),{frame:ss[o],speed:r.speed,driveGain:r.driveGain,gain:r.gain??1,opts:l}}function os(t){let n=t;for(;n;){const s=n.getAttribute("data-theme");if(s==="dark")return!0;if(s==="light")return!1;if(n.classList.contains("dark"))return!0;if(n.classList.contains("light"))return!1;n=n.parentElement}return null}function as(){return typeof matchMedia>"u"||matchMedia("(prefers-color-scheme: dark)").matches}function cs(t,n){const[s,e]=$.useState(!0);return $.useEffect(()=>{if(t==="dark"){e(!0);return}if(t==="light"){e(!1);return}const o=()=>{const i=os(n.current);e(i??as())};o();const r=typeof matchMedia<"u"?matchMedia("(prefers-color-scheme: dark)"):null,c=()=>o();r==null||r.addEventListener("change",c);let l=null;return typeof MutationObserver<"u"&&n.current&&(l=new MutationObserver(o),l.observe(document.documentElement,{attributes:!0,attributeFilter:["class","data-theme"],subtree:!0})),()=>{r==null||r.removeEventListener("change",c),l==null||l.disconnect()}},[t,n]),s}function rs(){const[t,n]=$.useState(!1);return $.useEffect(()=>{if(typeof matchMedia>"u")return;const s=matchMedia("(prefers-reduced-motion: reduce)");n(s.matches);const e=o=>n(o.matches);return s.addEventListener("change",e),()=>s.removeEventListener("change",e)},[]),t}const gt=16,is=2.1,ls=.3,hs=2.5,us=1.6,fs=5,Gn=2.2,Un=[[80,300],[300,2e3],[2e3,6e3]],pn=90,ds=7e3,mn=Math.PI*2,Mn=.35,gn=.9;function ee(t){return t<0?0:t>1?1:t}function bn(t,n){if(t<=n)return 0;const s=(t-n)/Math.max(.001,1-n);return ee((1-Math.exp(-3*s))/(1-Math.exp(-3)))}function Ft(t,n,s,e,o){const r=n>t?e:o;return t+(n-t)*(1-Math.exp(-s/Math.max(.001,r)))}class se{constructor(){this.clock=0,this.t=0,this.drive=0,this.level=0,this.bands=[0,0,0],this.spectrum=new Float32Array(gt),this.floor=new Float32Array(gt+3).fill(1),this.heard=0,this.proc=0,this.spin=0,this.pan=0,this.panVel=0,this.raw={level:0,bands:[0,0,0],spectrum:new Float32Array(gt)},this.timeBuf=null,this.freqBuf=null,this.out={level:0,bands:[0,0,0],soft:0,softBands:[0,0,0],spectrum:this.spectrum,drive:0,processing:0,spin:0,pan:0}}readAnalyser(n,s,e){(!this.timeBuf||this.timeBuf.length!==n.fftSize)&&(this.timeBuf=new Float32Array(n.fftSize)),(!this.freqBuf||this.freqBuf.length!==n.frequencyBinCount)&&(this.freqBuf=new Uint8Array(n.frequencyBinCount));const o=this.timeBuf,r=this.freqBuf;n.getFloatTimeDomainData(o);let c=0;for(let h=0;h<o.length;h++)c+=o[h]*o[h];this.raw.level=Math.sqrt(c/o.length)*fs*s,n.getByteFrequencyData(r);const l=n.context.sampleRate/n.fftSize,i=(h,f)=>{const m=Math.max(0,Math.floor(h/l)),d=Math.max(m,Math.min(r.length-1,Math.ceil(f/l)));let M=0;for(let v=m;v<=d;v++)M+=r[v];return M/(d-m+1)/255},a=(h,f)=>{const m=this.floor[h];return this.floor[h]=f<m?f:m+(f-m)*(1-Math.exp(-e/8)),Math.max(0,f-this.floor[h])/Math.max(.05,1-this.floor[h])};for(let h=0;h<3;h++)this.raw.bands[h]=a(h,i(Un[h][0],Un[h][1]))*Gn*s;const p=ds/pn;for(let h=0;h<gt;h++){const f=pn*p**(h/gt),m=pn*p**((h+1)/gt);this.raw.spectrum[h]=a(3+h,i(f,m))*Gn*s}}readLevel(n,s){const e=ee(n)*s,o=this.clock;this.raw.level=e,this.raw.bands[0]=e,this.raw.bands[1]=e*(.72+.28*Math.sin(o*2.3)),this.raw.bands[2]=e*(.6+.4*Math.sin(o*3.7+2));const r=.28+.1*Math.sin(o*2.3)+.05*Math.sin(o*5.1),c=.64+.1*Math.sin(o*1.7+1);for(let l=0;l<gt;l++){const i=l/(gt-1),a=Math.exp(-((i-r)**2)/.012)+.6*Math.exp(-((i-c)**2)/.008);this.raw.spectrum[l]=e*(.25+.75*a)*(1-.4*i)}}readSilence(){this.raw.level=0,this.raw.bands.fill(0),this.raw.spectrum.fill(0)}step(n,s,e){const{threshold:o,attack:r,release:c,rate:l}=s,i=this.proc=Ft(this.proc,s.processing?1:0,n,.35,.5),a=s.calm+(1-s.calm)*Math.min(1,Math.max(this.heard*2.5,i));e||(this.clock+=n,this.t+=n*l*a*(1+.5*i));const p=bn(this.raw.level,o);this.level=Ft(this.level,p,n,r,c),this.heard=Ft(this.heard,this.level,n,Mn,gn);for(let u=0;u<3;u++)this.bands[u]=Ft(this.bands[u],bn(this.raw.bands[u],o*.6),n,r,c*1.15);for(let u=0;u<gt;u++)this.spectrum[u]=Ft(this.spectrum[u],bn(this.raw.spectrum[u],o*.6),n,r,c);const h=this.clock,f=e?.5:.5+.5*Math.sin(mn*h/6),m=s.idle*f*(1-i),d=this.out;d.level=this.level+(1-this.level)*m;for(let u=0;u<3;u++)d.bands[u]=this.bands[u]+(1-this.bands[u])*m*.6;d.soft=Ft(d.soft,d.level,n,Mn,gn);for(let u=0;u<3;u++)d.softBands[u]=Ft(d.softBands[u],d.bands[u],n,Mn,gn);if(e||(this.drive+=n*l*(a+s.driveGain*this.level+1.3*i)),d.drive=this.drive,d.processing=i,!e){const u=Math.ceil(this.spin/mn-1e-6)*mn,g=Math.min(ls,(u-this.spin)*.6);this.spin+=n*(is*l*i+g*(1-i))}d.spin=this.spin;const M=Math.max(-1,Math.min(1,s.direction||0)),v=this.heard>.06&&!s.processing?M:0,_=Math.abs(v)>Math.abs(this.pan)?hs:us;return this.panVel+=(_*_*(v-this.pan)-2*_*this.panVel)*n,this.pan+=this.panVel*n,d.pan=this.pan,d}}function ps(t){if(!t)return;const n=t.trim().match(/^#([0-9a-f]{3}|[0-9a-f]{6})$/i);if(n){let e=n[1];e.length===3&&(e=e.replace(/./g,r=>r+r));const o=parseInt(e,16);return{r:o>>16&255,g:o>>8&255,b:o&255}}const s=t.trim().match(/^rgba?\(\s*([\d.]+)\s*,\s*([\d.]+)\s*,\s*([\d.]+)/i);if(s)return{r:Number(s[1]),g:Number(s[2]),b:Number(s[3])}}const ms={idle:"Waiting",listening:"Listening",speaking:"Speaking",processing:"Thinking"},Ms=.55,gs=1e3/62;function oe({type:t="orbit",state:n="listening",size:s=160,stream:e,analyser:o,level:r,sensitivity:c=.85,threshold:l=.04,attack:i,release:a=.32,idle:p=.1,calm:h=.4,voiceSpeed:f,emotion:m=null,emotionColors:d,saturation:M=2,accent:v=null,gradientAngle:_=99,gradientSpin:u=12,neutral:g=1,colorBrightness:x=1.02,colorHue:O=0,gradientStart:E=.1,gradientWidth:q=.6,direction:S,directionMove:C,directionPull:A,directionDeform:D,directionSquash:U,directionLens:b,directionStretch:w,directionSplit:y,directionBlur:I,directionBounce:R,directionMargin:B,directionBounds:k,hoverBend:F=!1,theme:T="auto",speed:P=1,paused:N=!1,color:G,dots:z=1,dotSize:V,opts:X,frame:tt,onLevel:J,style:K,"aria-label":ct,...st}){const Y=$.useRef(null),ot=cs(T,Y),W=rs(),ut=X?JSON.stringify(X):"",ft=!!(e||o||r!=null||n==="processing"),nt=$.useRef(null);nt.current||(nt.current=new se);const dt=$.useRef(null);dt.current||(dt.current=new ve);const pt=m?(d==null?void 0:d[m])??Gt[m]:null,Rt={saturation:Math.min(1,M),vivid:Math.max(0,Math.min(1,M-1)),brightness:x,hue:O,start:E,width:q,accent:v?Vn[v]:null,angle:_,spin:u,neutral:g,size:s},$t=V??et[t in et?t:"orbit"].dotSize??1,rt=et[t in et?t:"orbit"].lean??{},At=B??et[t in et?t:"orbit"].margin??32,Wt={state:n,level:r,analyser:o,sensitivity:c,threshold:l,attack:i??et[t in et?t:"orbit"].attack??.06,release:a,idle:p,calm:h,voiceSpeed:f??et[t in et?t:"orbit"].voiceSpeed??1,onLevel:J,emotionTint:pt,colors:Rt,direction:S,bounds:k,bend:F===!0?Ms:typeof F=="number"?Math.max(0,Math.min(1,F)):0,lean:{move:C??rt.move??xt.move,pull:A??rt.pull??xt.pull,deform:D??rt.deform??xt.deform,squash:U??rt.squash??xt.squash,lens:b??rt.lens??xt.lens,stretch:w??rt.stretch??xt.stretch,split:y??rt.split??xt.split,blur:I??rt.blur??xt.blur,bounce:R??rt.bounce??xt.bounce}},yt=$.useRef(Wt);yt.current=Wt;const It=S==null?0:Se(Wt.lean,s),[En,ae]=$.useState([1/0,1/0]),tn=Math.min(It,En[0]),nn=Math.min(It,En[1]),it=It?tn+At:0,Pt=It?nn+At:0,Vt=$.useRef({x:0,y:0,over:!1}),Tn=Wt.bend>0&&!W;$.useEffect(()=>{const j=Y.current;if(!Tn||!j||typeof matchMedia!="function"||!matchMedia("(hover: hover) and (pointer: fine)").matches)return;const St=lt=>{if(lt.pointerType==="touch")return;const Ot=j.getBoundingClientRect(),Xt=(s+it+Pt)/(Ot.width||1);Vt.current={x:(lt.clientX-Ot.left)*Xt-it,y:(lt.clientY-Ot.top)*Xt,over:!0}},_t=()=>{Vt.current.over=!1};return window.addEventListener("pointermove",St,{passive:!0}),document.documentElement.addEventListener("pointerleave",_t),()=>{window.removeEventListener("pointermove",St),document.documentElement.removeEventListener("pointerleave",_t),Vt.current.over=!1}},[Tn,s,it,Pt]);const en=$.useRef(null);return $.useEffect(()=>{if(!e)return;const j=Wn(e);return en.current=(j==null?void 0:j.analyser)??null,()=>{en.current=null,j==null||j.release()}},[e]),$.useEffect(()=>{const j=Y.current;if(!j)return;const St=Math.min(2,typeof devicePixelRatio<"u"&&devicePixelRatio||1);j.width=Math.round((s+it+Pt)*St),j.height=Math.round(s*St);const _t=j.getContext("2d");if(!_t)return;const lt=ne(t,s,z,$t),Ot=X?{...lt.opts,...X}:lt.opts,Xt=tt??lt.frame,ce=ps(G),wt=nt.current,re=dt.current,ie=new we;let Rn=0,Bt=0,sn=s/2,on=s/2;const le=(Q,H,L)=>{var Fn;_t.setTransform(St,0,0,St,it*St,0),_t.clearRect(-it,0,s+it+Pt,s);const Lt=N||W?0:ie.step(Rn,L);let ht=Ee(Xt(s,wt.t,Q,Ot),Q.pan,s,yt.current.lean,[tn,nn],Lt);Rn=((Fn=ht.contact)==null?void 0:Fn.press)??0;const vt=yt.current.bend;if(vt>0){const qt=Vt.current,In=Xn(ht,s),de=yt.current.state==="idle"||yt.current.state==="processing",pe=qt.over&&de&&!N&&!W?ye(Math.hypot(qt.x-s/2,qt.y-s/2)-In,In):0;Bt+=(pe-Bt)*(1-Math.exp(-L/.14));const Nn=Bt<.01?1:1-Math.exp(-L/.05);sn+=(qt.x-sn)*Nn,on+=(qt.y-on)*Nn,Bt>.002&&(ht=xe(ht,s,{x:sn,y:on,amount:Bt*vt}))}const mt=yt.current.colors,Mt=H.amount,at=mt.accent,ue=at?{r:at.r+(H.r-at.r)*Mt,g:at.g+(H.g-at.g)*Mt,b:at.b+(H.b-at.b)*Mt}:{r:H.r,g:H.g,b:H.b},fe={...mt,accent:ue,saturation:mt.saturation*(at?1:Mt),angle:mt.angle+mt.spin*wt.clock};Ke(_t,ht,ot,ce,ht.light?H:void 0,fe)};let An=-1/0;const he=Q=>{var mt,Mt;if(!It||Q-An<500)return;An=Q;const H=j.getBoundingClientRect().left+it,L=(Mt=(mt=yt.current.bounds)==null?void 0:mt.current)==null?void 0:Mt.getBoundingClientRect(),Lt=L?L.left:0,ht=L?L.right:document.documentElement.clientWidth,vt=[Math.max(0,Math.floor(H-Lt-At)),Math.max(0,Math.floor(ht-H-s-At))];ae(at=>Math.abs(at[0]-vt[0])>1||Math.abs(at[1]-vt[1])>1?vt:at)};let Kt=0;const Pn=Q=>{var Mt;he(Q);const H=Kt?Math.min(.05,(Q-Kt)/1e3):1/60;Kt=Q;const L=yt.current,Lt=L.state==="listening"||L.state==="speaking",ht=en.current??L.analyser??null;Lt?ht?wt.readAnalyser(ht,L.sensitivity*lt.gain,H):L.level!=null?wt.readLevel(typeof L.level=="function"?L.level():L.level,L.sensitivity*lt.gain):wt.readSilence():wt.readSilence();const vt=wt.step(H,{sensitivity:L.sensitivity,threshold:L.threshold,attack:L.attack,release:L.release,idle:L.idle,driveGain:lt.driveGain*L.voiceSpeed,calm:L.calm,rate:lt.speed*P,processing:L.state==="processing",direction:typeof L.direction=="function"?L.direction():L.direction??0},W);(Mt=L.onLevel)==null||Mt.call(L,vt.level);const mt=re.step(H,L.emotionTint,wt.clock,s,N||W);le(vt,mt,H)};if(Pn(performance.now()),N||W&&!ft)return;let an=0,Yt=!1,_n=0;const Cn=Q=>{Yt&&(an=requestAnimationFrame(Cn),!(Q-_n<gs)&&(_n=Q,Pn(Q)))},cn=()=>{Yt||(Yt=!0,Kt=0,an=requestAnimationFrame(Cn))},rn=()=>{Yt=!1,cancelAnimationFrame(an)};let ln=!0;const Ct=typeof IntersectionObserver<"u"?new IntersectionObserver(([Q])=>{ln=Q.isIntersecting,ln&&document.visibilityState!=="hidden"?cn():rn()}):null;Ct==null||Ct.observe(j);const kn=()=>{document.visibilityState==="hidden"?rn():ln&&cn()};return document.addEventListener("visibilitychange",kn),Ct||cn(),()=>{rn(),Ct==null||Ct.disconnect(),document.removeEventListener("visibilitychange",kn)}},[t,s,It,tn,nn,it,Pt,At,ot,P,N,W,ft,G,z,$t,ut,tt,N||W?m:null,N||W?`${M}|${v}|${_}|${u}|${g}|${x}|${O}|${E}|${q}`:null]),zn.jsx("canvas",{ref:Y,role:"img","aria-label":ct??ms[n],style:{width:s+it+Pt,height:s,display:"block",marginLeft:-it,marginRight:-Pt,...K},...st})}const bs={echoCancellation:!1,noiseSuppression:!1,autoGainControl:!1};function Jt(){return typeof navigator<"u"&&typeof navigator.mediaDevices<"u"&&typeof navigator.mediaDevices.getUserMedia=="function"}function vs(t={}){const{constraints:n,autoStart:s=!1}=t,[e,o]=$.useState(null),[r,c]=$.useState(()=>Jt()?"idle":"unsupported"),[l,i]=$.useState(null),a=$.useRef(null),p=$.useRef(n);p.current=n;const h=$.useCallback(()=>{const m=a.current;a.current=null,m&&m.getTracks().forEach(d=>d.stop()),o(null),c(Jt()?"idle":"unsupported")},[]),f=$.useCallback(async()=>{if(!Jt())return c("unsupported"),null;if(a.current)return a.current;xn(),c("requesting"),i(null);try{const m=await navigator.mediaDevices.getUserMedia({audio:{...bs,...p.current??{}}});a.current=m,o(m),c("live");const d=()=>{a.current===m&&(a.current=null,o(null),c("idle"))};return m.getAudioTracks().forEach(M=>M.addEventListener("ended",d)),m}catch(m){const d=m instanceof Error?m:new Error(String(m));return i(d),c(d.name==="NotAllowedError"||d.name==="SecurityError"?"denied":"error"),null}},[]);return $.useEffect(()=>{s&&f()},[s]),$.useEffect(()=>()=>{const m=a.current;a.current=null,m&&m.getTracks().forEach(d=>d.stop())},[]),{stream:e,state:r,error:l,supported:Jt(),start:f,stop:h}}function xs(t){return zn.jsx(oe,{...t,type:"aura"})}exports.ACCENT_COLORS=Vn;exports.EMOTION_COLORS=Gt;exports.PRESETS=et;exports.SPECTRUM_N=gt;exports.VOICE_ORB_TYPES=es;exports.VoiceFollower=se;exports.VoiceOrb=oe;exports.VoiceRing=xs;exports.acquireAnalyser=Wn;exports.getAudioContext=xn;exports.isAudioSupported=me;exports.resolvePreset=ne;exports.useMicrophone=vs;