@streamoji/avatar-widget 0.3.1 → 0.3.2

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/README.md CHANGED
@@ -1,52 +1,6 @@
1
1
  # @streamoji/avatar-widget
2
2
 
3
- Plug-and-play React avatar widget package for websites.
4
-
5
- ## Install
6
-
7
- ```bash
8
- npm install @streamoji/avatar-widget
9
- ```
10
-
11
- ## Usage
12
-
13
- ```tsx
14
- import { AvatarWidget } from "@streamoji/avatar-widget";
15
- import "@streamoji/avatar-widget/styles.css";
16
-
17
- export default function App() {
18
- return <AvatarWidget token="YOUR_ENCRYPTED_AGENT_TOKEN" />;
19
- }
20
- ```
21
-
22
- ## Props
23
-
24
- - `token?: string` - encrypted agent token used for chat/STT requests.
25
- - `onNavigationRequested?: (url: string) => void` - intercept navigation instructions from the agent.
26
-
27
- ## Plain HTML (no build)
28
-
29
- Add the widget to any HTML page without React or a build step. Paste the snippet before `</body>`, replace `YOUR_TOKEN_HERE` with your encrypted agent token, and the widget appears fixed at the bottom-right of the page.
30
-
31
- ```html
32
- <link rel="stylesheet" href="https://unpkg.com/@streamoji/avatar-widget@0.1.0/dist/avatar-widget.umd.css">
33
- <script>window.process = { env: { NODE_ENV: "production" } };</script>
34
- <script src="https://unpkg.com/@streamoji/avatar-widget@0.1.0/dist/avatar-widget.umd.js"></script>
35
- <script>
36
- StreamojiLeadsAvatarWidget.init({ token: "YOUR_TOKEN_HERE" });
37
- </script>
38
- ```
39
-
40
- ## Publish Checklist
41
-
42
- 1. Set a final package name/version in `package.json`.
43
- 2. Build artifacts: `npm run build` from `packages/avatar-widget`.
44
- 3. Validate tarball contents: `npm pack --dry-run`.
45
- 4. Authenticate npm: `npm login`.
46
- 5. Publish: `npm publish --access public`.
47
- # @streamoji/avatar-widget
48
-
49
- Plug-and-play React avatar widget for [Streamoji Leads](https://streamoji.com). Add the widget to any website with a single component and an optional agent token.
3
+ Plug-and-play React avatar widget for token-based AI conversations. Add the widget to any website with a single component and an encrypted agent token.
50
4
 
51
5
  ## Installation
52
6
 
@@ -63,47 +17,71 @@ npm install react react-dom three @react-three/fiber @react-three/drei
63
17
  ## Usage
64
18
 
65
19
  ```tsx
66
- import { AvatarWidget } from '@streamoji/avatar-widget';
20
+ import { AvatarWidget } from "@streamoji/avatar-widget";
21
+ import "@streamoji/avatar-widget/styles.css";
67
22
 
68
23
  function App() {
69
- const agentToken = 'YOUR_AGENT_TOKEN'; // e.g. from URL, auth, or config
70
-
71
24
  return (
72
25
  <AvatarWidget
73
- agentToken={agentToken}
74
- onNavigationRequested={(url) => window.open(url, '_blank')}
26
+ token="YOUR_ENCRYPTED_AGENT_TOKEN"
27
+ onNavigationRequested={(url) => window.open(url, "_blank")}
75
28
  />
76
29
  );
77
30
  }
78
31
  ```
79
32
 
80
- Styles are included when you import the component. If your bundler does not include the package CSS, import it explicitly:
33
+ With optional user prefill and avatar gender:
81
34
 
82
35
  ```tsx
83
- import { AvatarWidget } from '@streamoji/avatar-widget';
84
- import '@streamoji/avatar-widget/styles.css';
36
+ import { AvatarWidget } from "@streamoji/avatar-widget";
37
+ import "@streamoji/avatar-widget/styles.css";
38
+
39
+ function App() {
40
+ const user = useCurrentUser(); // your auth
41
+
42
+ return (
43
+ <AvatarWidget
44
+ token="YOUR_ENCRYPTED_AGENT_TOKEN"
45
+ avatarGender="female"
46
+ presetUserDetails={
47
+ user
48
+ ? { name: user.displayName, email: user.email, phone: user.phone }
49
+ : undefined
50
+ }
51
+ onNavigationRequested={(url) => window.open(url, "_blank")}
52
+ />
53
+ );
54
+ }
85
55
  ```
86
56
 
87
57
  ## Props
88
58
 
89
59
  | Prop | Type | Description |
90
60
  |------|------|-------------|
91
- | `agentToken` | `string \| undefined` | Encrypted agent token for chat/STT API and for resolving the avatar GLB from R2. Omit for default avatar only. |
92
- | `onNavigationRequested` | `(url: string) => void` | Called when the agent requests a link; if not provided, links open in a new tab via `window.open`. |
93
- | `apiBase` | `string` | API base URL for chat and STT (default: `https://ai.streamoji.com`). |
94
- | `defaultAvatarUrl` | `string` | Fallback avatar GLB URL when no token or R2 lookup fails (default: `/test2.glb`). |
95
- | `avatarBase` | `string` | R2 base URL for avatar GLB lookup by token hash. |
96
- | `debug` | `boolean` | Enable debug logging to console (default: `false`). |
61
+ | `token` | `string \| undefined` | Encrypted agent token for chat/STT API. Omit for default avatar only. |
62
+ | `onNavigationRequested` | `(url: string) => void` | Called when the agent requests a link; if not provided, links open in a new tab. |
63
+ | `avatarGender` | `"male" \| "female"` | Gender of the avatar for idle animations. Defaults to `"male"`. |
64
+ | `presetUserDetails` | `UserDetails \| undefined` | Optional user details (name, email, phone) to identify logged-in users and skip lead capture. |
65
+
66
+ ### UserDetails
67
+
68
+ ```ts
69
+ interface UserDetails {
70
+ name?: string;
71
+ email?: string;
72
+ phone?: string;
73
+ }
74
+ ```
97
75
 
98
76
  ## Publishing
99
77
 
100
- This package is published to npm. To publish a new version from the repo:
78
+ From the repo root:
101
79
 
102
80
  ```bash
103
81
  cd packages/avatar-widget
104
82
  npm run build
105
- npm version patch # or minor/major
106
- npm publish
83
+ npm version patch # or minor / major
84
+ npm publish --access public
107
85
  ```
108
86
 
109
- Scoped packages require `--access public` for the first publish if the scope is not yet associated with a paid plan.
87
+ Scoped packages require `--access public` if the scope is not on a paid npm plan.
@@ -1,7 +1,7 @@
1
- "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const a=require("react/jsx-runtime"),Ge=require("@react-three/drei"),ct=require("@react-three/fiber"),e=require("react"),qt=require("three"),Jt=require("three/examples/jsm/loaders/GLTFLoader.js");function Gt(l){const b=Object.create(null,{[Symbol.toStringTag]:{value:"Module"}});if(l){for(const g in l)if(g!=="default"){const m=Object.getOwnPropertyDescriptor(l,g);Object.defineProperty(b,g,m.get?m:{enumerable:!0,get:()=>l[g]})}}return b.default=l,Object.freeze(b)}const Ue=Gt(qt),at="https://ai.streamoji.com",B=(...l)=>{},zt=(...l)=>{},kt=({analyser:l})=>{const b=e.useRef(null),g=e.useRef(null);return e.useEffect(()=>{const m=b.current;if(!m)return;const _=m.getContext("2d",{alpha:!0});if(!_)return;let C,W=null;l&&(l.fftSize=128,W=new Uint8Array(l.frequencyBinCount));const le=()=>{C=requestAnimationFrame(le),(m.width!==m.offsetWidth||m.height!==m.offsetHeight)&&(m.width=m.offsetWidth,m.height=m.offsetHeight);const Y=m.width,O=m.height;if(Y===0||O===0)return;const de=O/2;_.clearRect(0,0,Y,O),_.fillStyle="#1e293b";const T=2,R=T+2,A=Y*.95,F=Math.floor(A/R);(!g.current||g.current.length!==F)&&(g.current=new Float32Array(F).fill(2));const me=F*R,v=(Y-me)/2;l&&W&&l.getByteFrequencyData(W);const _e=W?W.length:0,q=Math.floor(_e*.7)/F,ie=new Float32Array(F);for(let I=0;I<F;I++){let j=0;if(W&&q>0){const ee=Math.floor(I*q),U=Math.floor((I+1)*q);for(let y=ee;y<U;y++){const x=W[y]||0;x>j&&(j=x)}}j<10&&(j=0);const V=j/255,D=j>0?Math.max(2,Math.pow(V,1.4)*O*.25):2;ie[I]=D}for(let I=0;I<F;I++){const j=F-1-I,V=Math.max(ie[I],ie[j]),D=g.current[I]+(V-g.current[I])*.3;g.current[I]=D;const ee=v+I*R,U=de-D/2;_.beginPath(),_.roundRect?_.roundRect(ee,U,T,D,4):_.fillRect(ee,U,T,D),_.fill()}};return le(),()=>{cancelAnimationFrame(C)}},[l]),a.jsx("canvas",{ref:b,style:{width:"100%",height:"100%",display:"block"}})},Yt="https://pub-48df6f7d60d6440bbd01676ea5d90e55.r2.dev",Et="https://pub-be53cae7bd99457a8c1f11b4d38f1672.r2.dev/default-models/fullbodyavatarmale.glb";async function Qt(l){const b=await crypto.subtle.digest("SHA-256",new TextEncoder().encode(l));return Array.from(new Uint8Array(b)).map(g=>g.toString(16).padStart(2,"0")).join("")}function Xt(l){const[b,g]=e.useState(null);return e.useEffect(()=>{if(!l){g(null);return}let m=!1;return Qt(l).then(_=>{if(m)return;const C=`${Yt}/${_}.glb`;fetch(C,{method:"HEAD"}).then(W=>{m||g(W.ok?C:Et)}).catch(()=>{m||g(Et)})}),()=>{m=!0}},[l]),b}const Kt=["https://pub-be53cae7bd99457a8c1f11b4d38f1672.r2.dev/masculine/idle/M_Standing_Idle_Variations_001.glb","https://pub-be53cae7bd99457a8c1f11b4d38f1672.r2.dev/masculine/idle/M_Standing_Idle_Variations_002.glb","https://pub-be53cae7bd99457a8c1f11b4d38f1672.r2.dev/masculine/idle/M_Standing_Idle_002.glb","https://pub-be53cae7bd99457a8c1f11b4d38f1672.r2.dev/masculine/idle/M_Standing_Idle_Variations_005.glb"],Zt=["https://pub-be53cae7bd99457a8c1f11b4d38f1672.r2.dev/masculine/idle/F_Standing_Idle_Variations_001.glb","https://pub-be53cae7bd99457a8c1f11b4d38f1672.r2.dev/masculine/idle/F_Standing_Idle_Variations_003.glb","https://pub-be53cae7bd99457a8c1f11b4d38f1672.r2.dev/masculine/idle/F_Standing_Idle_Variations_003.glb"],en=[{id:"m_expr_01",name:"Friendly Wave",url:"https://pub-be53cae7bd99457a8c1f11b4d38f1672.r2.dev/masculine/expression/M_Standing_Expressions_001.glb"},{id:"m_expr_02",name:"You There",url:"https://pub-be53cae7bd99457a8c1f11b4d38f1672.r2.dev/masculine/expression/M_Standing_Expressions_002.glb"},{id:"m_expr_04",name:"Awkward Agreement",url:"https://pub-be53cae7bd99457a8c1f11b4d38f1672.r2.dev/masculine/expression/M_Standing_Expressions_004.glb"},{id:"m_expr_05",name:"What's Going On?",url:"https://pub-be53cae7bd99457a8c1f11b4d38f1672.r2.dev/masculine/expression/M_Standing_Expressions_005.glb"},{id:"m_expr_06",name:"Tired Stretch",url:"https://pub-be53cae7bd99457a8c1f11b4d38f1672.r2.dev/masculine/expression/M_Standing_Expressions_006.glb"},{id:"m_expr_07",name:"Conceilied Laughter",url:"https://pub-be53cae7bd99457a8c1f11b4d38f1672.r2.dev/masculine/expression/M_Standing_Expressions_007.glb"},{id:"m_expr_08",name:"You Come Here",url:"https://pub-be53cae7bd99457a8c1f11b4d38f1672.r2.dev/masculine/expression/M_Standing_Expressions_008.glb"},{id:"m_expr_09",name:"Come Here Kid",url:"https://pub-be53cae7bd99457a8c1f11b4d38f1672.r2.dev/masculine/expression/M_Standing_Expressions_009.glb"},{id:"m_expr_10",name:"Come Here Everyone",url:"https://pub-be53cae7bd99457a8c1f11b4d38f1672.r2.dev/masculine/expression/M_Standing_Expressions_010.glb"},{id:"m_expr_11",name:"No Freaking Way",url:"https://pub-be53cae7bd99457a8c1f11b4d38f1672.r2.dev/masculine/expression/M_Standing_Expressions_011.glb"},{id:"m_expr_12",name:"Cheerful Approval",url:"https://pub-be53cae7bd99457a8c1f11b4d38f1672.r2.dev/masculine/expression/M_Standing_Expressions_012.glb"},{id:"m_expr_13",name:"Waving Hello",url:"https://pub-be53cae7bd99457a8c1f11b4d38f1672.r2.dev/masculine/expression/M_Standing_Expressions_013.glb"},{id:"m_expr_14",name:"Checking Surroundings",url:"https://pub-be53cae7bd99457a8c1f11b4d38f1672.r2.dev/masculine/expression/M_Standing_Expressions_014.glb"},{id:"m_expr_15",name:"Referee Warning",url:"https://pub-be53cae7bd99457a8c1f11b4d38f1672.r2.dev/masculine/expression/M_Standing_Expressions_015.glb"},{id:"m_expr_16",name:"You Thumbs Down",url:"https://pub-be53cae7bd99457a8c1f11b4d38f1672.r2.dev/masculine/expression/M_Standing_Expressions_016.glb"},{id:"m_expr_17",name:"Side Thumbs Down",url:"https://pub-be53cae7bd99457a8c1f11b4d38f1672.r2.dev/masculine/expression/M_Standing_Expressions_017.glb"},{id:"m_expr_18",name:"You're Finished",url:"https://pub-be53cae7bd99457a8c1f11b4d38f1672.r2.dev/masculine/expression/M_Standing_Expressions_018.glb"},{id:"m_talk_01",name:"Oh God, Why Me?",url:"https://pub-be53cae7bd99457a8c1f11b4d38f1672.r2.dev/masculine/expression/M_Talking_Variations_001.glb"},{id:"m_talk_02",name:"What Are You Doing?",url:"https://pub-be53cae7bd99457a8c1f11b4d38f1672.r2.dev/masculine/expression/M_Talking_Variations_002.glb"},{id:"m_talk_03",name:"What Am I doing?",url:"https://pub-be53cae7bd99457a8c1f11b4d38f1672.r2.dev/masculine/expression/M_Talking_Variations_003.glb"},{id:"m_talk_04",name:"No Way",url:"https://pub-be53cae7bd99457a8c1f11b4d38f1672.r2.dev/masculine/expression/M_Talking_Variations_004.glb"},{id:"m_talk_05",name:"What's Going On?",url:"https://pub-be53cae7bd99457a8c1f11b4d38f1672.r2.dev/masculine/expression/M_Talking_Variations_005.glb"},{id:"m_talk_06",name:"I have no idea",url:"https://pub-be53cae7bd99457a8c1f11b4d38f1672.r2.dev/masculine/expression/M_Talking_Variations_006.glb"},{id:"m_talk_07",name:"What's going on here?",url:"https://pub-be53cae7bd99457a8c1f11b4d38f1672.r2.dev/masculine/expression/M_Talking_Variations_007.glb"},{id:"m_talk_08",name:"Let's stop",url:"https://pub-be53cae7bd99457a8c1f11b4d38f1672.r2.dev/masculine/expression/M_Talking_Variations_008.glb"},{id:"m_talk_09",name:"Fed Up Moment",url:"https://pub-be53cae7bd99457a8c1f11b4d38f1672.r2.dev/masculine/expression/M_Talking_Variations_009.glb"},{id:"m_talk_10",name:"What's This? Hold On",url:"https://pub-be53cae7bd99457a8c1f11b4d38f1672.r2.dev/masculine/expression/M_Talking_Variations_010.glb"},{id:"f_talk_01",name:"Great Job Clap",url:"https://pub-be53cae7bd99457a8c1f11b4d38f1672.r2.dev/masculine/expression/F_Talking_Variations_001.glb"},{id:"f_talk_02",name:"Chill Stretch",url:"https://pub-be53cae7bd99457a8c1f11b4d38f1672.r2.dev/masculine/expression/F_Talking_Variations_002.glb"},{id:"f_talk_03",name:"This Is Me",url:"https://pub-be53cae7bd99457a8c1f11b4d38f1672.r2.dev/masculine/expression/F_Talking_Variations_003.glb"},{id:"f_talk_04",name:"Empathize",url:"https://pub-be53cae7bd99457a8c1f11b4d38f1672.r2.dev/masculine/expression/F_Talking_Variations_004.glb"},{id:"f_talk_05",name:"Loose Hands Stretch",url:"https://pub-be53cae7bd99457a8c1f11b4d38f1672.r2.dev/masculine/expression/F_Talking_Variations_005.glb"},{id:"f_talk_06",name:"Take It Easy",url:"https://pub-be53cae7bd99457a8c1f11b4d38f1672.r2.dev/masculine/expression/F_Talking_Variations_006.glb"}],tn=["https://pub-be53cae7bd99457a8c1f11b4d38f1672.r2.dev/masculine/expression/M_Talking_Variations_005.glb","https://pub-be53cae7bd99457a8c1f11b4d38f1672.r2.dev/masculine/expression/M_Talking_Variations_007.glb"],nn={zoom:.85,position:[.15,-.8,0],scale:1.5,rotation:[.15,.02,0]},rn=[-.45,1.9,.1],sn={browInnerUp:.2},ot=.18,an=1,Lt="__branding__",Je={neutral:{eyeLookDownLeft:.1,eyeLookDownRight:.1},happy:{mouthSmileLeft:.2,mouthSmileRight:.2,eyeLookDownLeft:.1,eyeLookDownRight:.1},sad:{eyeLookDownLeft:.2,eyeLookDownRight:.2,browDownRight:.1,browInnerUp:.6,browOuterUpRight:.2,eyeSquintLeft:.7,eyeSquintRight:.7,mouthFrownLeft:.8,mouthFrownRight:.8,mouthLeft:.2,mouthPucker:.5,mouthRollLower:.2,mouthRollUpper:.2,mouthShrugLower:.2,mouthShrugUpper:.2,mouthStretchLeft:.4},angry:{eyeLookDownLeft:.1,eyeLookDownRight:.1,browDownLeft:.6,browDownRight:.6,jawForward:.3,mouthFrownLeft:.7,mouthFrownRight:.7,mouthRollLower:.2,mouthShrugLower:.3},fear:{browInnerUp:.7,eyeSquintLeft:.5,eyeSquintRight:.5,eyeWideLeft:.6,eyeWideRight:.6,mouthClose:.1,mouthFunnel:.3,mouthShrugLower:.5,mouthShrugUpper:.5},disgust:{browDownLeft:.7,browDownRight:.1,browInnerUp:.3,eyeSquintLeft:1,eyeSquintRight:1,eyeWideLeft:.5,eyeWideRight:.5,mouthLeft:.4,mouthPressLeft:.3,mouthRollLower:.3,mouthShrugLower:.3,mouthShrugUpper:.8,mouthUpperUpLeft:.3,noseSneerLeft:1,noseSneerRight:.7},love:{browInnerUp:.4,browOuterUpLeft:.2,browOuterUpRight:.2,mouthSmileLeft:.2,mouthSmileRight:.2,eyeBlinkLeft:.6,eyeBlinkRight:.6,eyeWideLeft:.7,eyeWideRight:.7,mouthDimpleLeft:.1,mouthDimpleRight:.1,mouthPressLeft:.2,mouthShrugUpper:.2,mouthUpperUpLeft:.1,mouthUpperUpRight:.1}},on=[{key:"viseme_aa",mix:{jawOpen:.6}},{key:"viseme_E",mix:{mouthPressLeft:.8,mouthPressRight:.8,mouthDimpleLeft:1,mouthDimpleRight:1,jawOpen:.3}},{key:"viseme_I",mix:{mouthPressLeft:.6,mouthPressRight:.6,mouthDimpleLeft:.6,mouthDimpleRight:.6,jawOpen:.2}},{key:"viseme_O",mix:{mouthPucker:1,jawForward:.6,jawOpen:.2}},{key:"viseme_U",mix:{mouthFunnel:1}},{key:"viseme_PP",mix:{mouthRollLower:.3,mouthRollUpper:.3,mouthUpperUpLeft:.3,mouthUpperUpRight:.3}},{key:"viseme_FF",mix:{mouthPucker:1,mouthShrugUpper:1,mouthLowerDownLeft:.2,mouthLowerDownRight:.2,mouthDimpleLeft:1,mouthDimpleRight:1,mouthRollLower:.3}},{key:"viseme_DD",mix:{mouthPressLeft:.8,mouthPressRight:.8,mouthFunnel:.5,jawOpen:.2}},{key:"viseme_SS",mix:{mouthPressLeft:.8,mouthPressRight:.8,mouthLowerDownLeft:.5,mouthLowerDownRight:.5,jawOpen:.1}},{key:"viseme_TH",mix:{mouthRollUpper:.3,jawOpen:.2,tongueOut:.4}},{key:"viseme_CH",mix:{mouthPucker:.5,jawOpen:.2}},{key:"viseme_RR",mix:{mouthPucker:.5,jawOpen:.2}},{key:"viseme_kk",mix:{mouthLowerDownLeft:.4,mouthLowerDownRight:.4,mouthDimpleLeft:.3,mouthDimpleRight:.3,mouthFunnel:.3,mouthPucker:.3,jawOpen:.15}},{key:"viseme_nn",mix:{mouthLowerDownLeft:.4,mouthLowerDownRight:.4,mouthDimpleLeft:.3,mouthDimpleRight:.3,mouthFunnel:.3,mouthPucker:.3,jawOpen:.15,tongueOut:.2}},{key:"viseme_sil",mix:{}}],cn={aei:[{v:"E",w:.8},{v:"I",w:.2}],ee:[{v:"I",w:1}],oo:[{v:"O",w:1}],u:[{v:"U",w:1}],aa:[{v:"aa",w:1}],ah:[{v:"aa",w:.7},{v:"O",w:.3}],bmp:[{v:"PP",w:1}],fv:[{v:"FF",w:1}],th:[{v:"TH",w:1}],l:[{v:"nn",w:1}],r:[{v:"RR",w:1}],qw:[{v:"U",w:.6},{v:"O",w:.4}],chjsh:[{v:"CH",w:1}],cdgknstxyz:[{v:"DD",w:.6},{v:"SS",w:.4}],sil:[{v:"sil",w:1}]};function un(l){if(!l)return[{v:"sil",w:1}];const b=l.toLowerCase();return cn[b]??[{v:"sil",w:1}]}function ln({target:l}){const{camera:b}=ct.useThree();return e.useEffect(()=>{b.lookAt(...l)},[b,l]),null}function z(l,b,g){if(!l||!l.morphTargetDictionary)return;const m=l,_=m.morphTargetDictionary,C=m.morphTargetInfluences;if(C)for(const W in _)W.toLowerCase()===b.toLowerCase()&&(C[_[W]]=g)}function At(l,b=.97){if(!l)return;const g=l;if(g.morphTargetInfluences)for(let m=0;m<g.morphTargetInfluences.length;m++)g.morphTargetInfluences[m]*=b}const dn=e.memo(({avatarUrl:l,isPlayingRef:b,visemeQueueRef:g,audioContextRef:m,responseAudioStartTimeRef:_,adjustments:C,mood:W,expression:le,agentResponse:Y,isSpeaking:O,nextStartTimeRef:de,stopPlayback:T,setIsSpeaking:S,expressionUrl:R,onExpressionFinished:A,isNudgeResponse:F,avatarGender:me})=>{const{scene:v}=Ge.useGLTF(l),_e=me==="female"?Zt:Kt,Ce=Ge.useGLTF(_e),q=e.useMemo(()=>Ce.flatMap(d=>d.animations),[Ce]),ie=Ge.useGLTF(tn),I=e.useMemo(()=>ie.flatMap(d=>d.animations),[ie]),j=e.useRef(null),V=e.useRef(null),D=e.useRef(null),ee=e.useRef([]),[U]=e.useState(()=>new Ue.AnimationMixer(v)),y=e.useRef({}),x=e.useRef(null),we=e.useRef(0),ae=e.useRef(!1),Pe=e.useRef(0),te=e.useRef(null);e.useEffect(()=>{if(!(!q||!v)){if(q.forEach((d,f)=>{const o=`idle_${f}`;if(!y.current[o]){const s=U.clipAction(d,v);s.name=o,s.setLoop(Ue.LoopOnce,1),s.clampWhenFinished=!0,y.current[o]=s}}),I.forEach((d,f)=>{const o=`talk_${f}`;if(!y.current[o]){const s=U.clipAction(d,v);s.name=o,s.setLoop(Ue.LoopOnce,1),s.clampWhenFinished=!0,y.current[o]=s}}),q.length>0){const d=y.current.idle_0,f=x.current&&U.existingAction(x.current.getClip());d&&!f&&(d.reset().fadeIn(.5).play(),x.current=d)}return()=>{U.stopAllAction(),y.current={},x.current=null}}},[q,I,v,U]);const Se=e.useRef("");e.useEffect(()=>{if(!R||!v||R===Se.current)return;Se.current=R,te.current=R,new Jt.GLTFLoader().load(R,f=>{if(f.animations&&f.animations.length>0){const o=f.animations[0],s=U.clipAction(o,v);if(s.name=`EXPR_${R}`,s.setLoop(Ue.LoopOnce,1),s.clampWhenFinished=!0,y.current[`EXPR_${R}`]=s,O&&te.current===R){const p=x.current;s.reset().fadeIn(.3).play(),p&&p!==s&&p.crossFadeTo(s,.3,!0),x.current=s,te.current=null}}},void 0,f=>{console.error(`[ANIMATION] Failed to load ${R}`,f)})},[R,v,U,O]),e.useEffect(()=>{const d=f=>{const o=f.action,s=o.name||"";if(s.startsWith("idle_")){const J=(parseInt(s.split("_")[1])+1)%q.length,Q=y.current[`idle_${J}`];Q&&(Q.reset().fadeIn(.5).play(),o.crossFadeTo(Q,.5,!0),x.current=Q)}else if(s.startsWith("EXPR_")){if(O){const p=y.current.talk_0;p&&(p.reset().fadeIn(.5).play(),o.crossFadeTo(p,.5,!0),x.current=p)}else{const p=y.current.idle_0;p&&(p.reset().fadeIn(.5).play(),o.crossFadeTo(p,.5,!0),x.current=p)}A&&A()}else if(s.startsWith("talk_"))if(O&&!F){const J=(parseInt(s.split("_")[1])+1)%I.length,Q=y.current[`talk_${J}`];Q&&(Q.reset().fadeIn(.3).play(),o.crossFadeTo(Q,.3,!0),x.current=Q)}else{const p=y.current.idle_0;p&&(p.reset().fadeIn(.5).play(),o.crossFadeTo(p,.5,!0),x.current=p)}};return U.addEventListener("finished",d),()=>U.removeEventListener("finished",d)},[U,q,I,O,F,A]),e.useEffect(()=>{if(O&&v){const d=x.current,f=d?.name||"";if(f.startsWith("idle_")||f.startsWith("talk_")||f===""){const o=te.current;if(o){const s=y.current[`EXPR_${o}`];if(s){s.reset().fadeIn(.3).play(),d&&d!==s&&d.crossFadeTo(s,.3,!0),x.current=s,te.current=null;return}}if(f.startsWith("idle_")||f===""){const s=y.current.talk_0;s&&(s.reset().fadeIn(.5).play(),d&&d.crossFadeTo(s,.5,!0),x.current=s)}}}else if(!O&&v){const d=x.current,f=d?.name||"";if(f.startsWith("talk_")||f.startsWith("EXPR_")){const o=y.current.idle_0;o&&(o.reset().fadeIn(.5).play(),d&&d.crossFadeTo(o,.5,!0),x.current=o)}}},[O,v,R]),e.useEffect(()=>{if(!v)return;v.traverse(o=>{if(o.isMesh&&o.morphTargetDictionary){const s=o.name.toLowerCase();(s.includes("head")||s.includes("avatar"))&&(V.current=o,B(`[ANIMATION] Found head mesh: ${o.name}`)),s.includes("teeth")&&(D.current=o,B(`[ANIMATION] Found teeth mesh: ${o.name}`))}});const d=V.current?.morphTargetDictionary;d&&Object.keys(d).filter(o=>o.toLowerCase().includes("brow"));const f=[];v.traverse(o=>{if(o.isMesh){const p=o.morphTargetDictionary;p&&Object.keys(p).some(J=>J.toLowerCase().includes("brow"))&&f.push(o)}}),ee.current=f,f.length>0&&B("[ANIMATION] Meshes with brow morphs:",f.length)},[v]);const ve=(d,f=1)=>{const o=`viseme_${d}`.toLowerCase(),s=on.find(p=>p.key.toLowerCase()===o);if(s)for(const p in s.mix){const J=s.mix[p]*f;z(V.current,p,J),z(D.current,p,J)}},Oe=d=>{const f=Je[d]??Je.neutral;for(const o in f)z(V.current,o,f[o]),z(D.current,o,f[o])};return ct.useFrame((d,f)=>{const o=Math.pow(.88,60*f);At(V.current,o),At(D.current,o),Oe(W);const s=d.clock.elapsedTime;let p=0;if(Math.floor(s)%5===0&&Math.floor((s-f)%5)!==0){let H=null;v.traverse(Z=>{Z.name.toLowerCase().includes("hips")&&(H=Z)});const ne=H?`Hips Y: ${H.position.y.toFixed(4)}`:"Hips not found";B(`[ANIMATION] Mixer Time: ${U.time.toFixed(2)}, ${ne}`)}if(U.update(f),s>we.current&&!ae.current&&(ae.current=!0,Pe.current=s),ae.current){const H=O?.2:.3,ne=(s-Pe.current)/H;if(ne>=1){ae.current=!1;const Z=O?1:2.5;we.current=s+Z}else{const Z=ne<.5?ne*2:(1-ne)*2;z(V.current,"eyeBlinkLeft",Z),z(V.current,"eyeBlinkRight",Z),z(D.current,"eyeBlinkLeft",Z),z(D.current,"eyeBlinkRight",Z),p=Z*sn.browInnerUp}}const J=Je[W]??Je.neutral,Q=J.browInnerUp??0,ze=J.browOuterUpLeft??0,Ye=J.browOuterUpRight??0,Ae=s*an,Qe=ot*Math.sin(Ae),ye=ot*.7*Math.sin(Ae+.7),K=ot*.7*Math.sin(Ae+1.3),xe=H=>Math.max(0,Math.min(1,H)),pe=xe(Q+Qe),ge=xe(ze+ye),Re=xe(Ye+K),De=xe(pe+p);if(z(V.current,"browInnerUp",De),z(D.current,"browInnerUp",De),z(V.current,"browOuterUpLeft",ge),z(D.current,"browOuterUpLeft",ge),z(V.current,"browOuterUpRight",Re),z(D.current,"browOuterUpRight",Re),j.current){const H=b.current?0:C.rotation[1];j.current.rotation.y=Ue.MathUtils.lerp(j.current.rotation.y,H,.1),j.current.position.set(...C.position),j.current.scale.setScalar(C.scale),j.current.rotation.x=C.rotation[0],j.current.rotation.z=C.rotation[2]}if(b.current&&m.current){const H=m.current.currentTime,Be=(H-_.current)*1e3- -150;for(let ke=0;ke<g.current.length;ke++){const G=g.current[ke];Be>=G.vtime&&Be<G.vtime+G.vduration&&ve(G.viseme,G.weight??1)}H>de.current+.5&&(T(),S(!1))}}),a.jsx("group",{ref:j,children:a.jsx("primitive",{object:v})})});function fn(l){return l?l.charAt(0).toUpperCase()+l.slice(1).toLowerCase():""}const hn=({token:l,agentToken:b,onNavigationRequested:g,avatarGender:m,presetUserDetails:_}={})=>{const C=l??b??"",W=Xt(C||void 0),[le,Y]=e.useState(""),[O,de]=e.useState(""),[T,S]=e.useState("Ready"),[R,A]=e.useState(!1),[F,me]=e.useState(!1),[v,_e]=e.useState([]),[Ce,q]=e.useState(""),ie=e.useRef(null),[I,j]=e.useState(()=>typeof window<"u"?window.matchMedia("(max-width: 480px)").matches:!1);e.useEffect(()=>{const t=window.matchMedia("(max-width: 480px)"),n=()=>j(t.matches);return t.addEventListener("change",n),()=>t.removeEventListener("change",n)},[]);const V=I?80:600,D=e.useRef(!1),ee=e.useRef([]),U=e.useRef(0),y=e.useRef(!1),x=e.useRef([]),we=e.useRef(null),ae=e.useRef([]);e.useRef([]);const Pe=e.useRef([]),te=e.useRef(0),Se=e.useRef(0),ve=e.useRef(0),Oe=e.useRef(0),d=e.useRef(!1),[f,o]=e.useState(null),s=e.useRef(null),[p,J]=e.useState("neutral"),[Q,ze]=e.useState(""),[Ye,Ae]=e.useState(""),[Qe,ye]=e.useState("Chat with us"),[K,xe]=e.useState(null),[pe,ge]=e.useState("hidden"),[Re,De]=e.useState(""),H=e.useRef(null),ne=e.useRef(pe);ne.current=pe;const[Z,Be]=e.useState(null),ke=e.useRef(null),G=e.useRef(null),[Ne,ut]=e.useState(!1),lt=e.useRef(null),[oe,We]=e.useState("hidden"),[dt,Tt]=e.useState(""),Xe=e.useRef(oe);Xe.current=oe;const fe=e.useRef(""),Te=e.useRef(!1),Ie=e.useRef(""),ft=e.useRef(Date.now()),Ke=e.useRef([]),Fe=e.useRef(!1),[Ze,je]=e.useState(!1),[ht,mt]=e.useState(!1),be=e.useRef(null),Me=e.useMemo(()=>Ne?"Try again":T==="Busy"?"Busy":T==="Thinking..."||T==="Processing Voice..."?T:K!=null&&K!==""&&K!=="none"&&K!=="<none>"?`Enter ${fn(K)}`:oe!=="hidden"||!ht?null:Lt,[T,K,Ne,oe,ht]),pt=!Ne&&T!=="Busy"&&T!=="Thinking..."&&T!=="Processing Voice..."&&(K==null||K===""||K==="none"||K==="<none>");e.useEffect(()=>{if(oe!=="hidden"||!pt){mt(!1),be.current!=null&&(clearTimeout(be.current),be.current=null);return}return be.current=setTimeout(()=>{be.current=null,mt(!0)},400),()=>{be.current!=null&&(clearTimeout(be.current),be.current=null)}},[oe,pt]);const Ve=Me!=null&&Me!=="";e.useEffect(()=>{const t=ne.current;if(!(t==="exiting"||t==="entering")){if(t==="hidden"){Ve&&(De(Me??""),ge("entering"));return}t==="visible"&&(!Ve||Me!==Re)&&(H.current=Ve?Me:null,ge("exiting"))}},[Ve,Me,pe,Re]),e.useEffect(()=>{if(T!=="Busy"){G.current!=null&&(clearTimeout(G.current),G.current=null);return}return G.current=setTimeout(()=>{G.current=null,S("Ready"),ut(!0)},12e3),()=>{G.current!=null&&(clearTimeout(G.current),G.current=null)}},[T]),e.useEffect(()=>{if(!Ne)return;const t=setTimeout(()=>ut(!1),2500);return()=>clearTimeout(t)},[Ne]);const It=e.useCallback(()=>{const t=ne.current;if(t==="exiting"){ge("hidden");const n=H.current;H.current=null,n!=null&&n!==""&&(De(n),ge("entering"))}else t==="entering"&&ge("visible")},[]),Mt=t=>{if(!t)return;if(t.mood!=null){const r=String(t.mood).toLowerCase();J(r)}if(t.expression!=null){const r=String(t.expression).trim();ze(r);const u=en.find(h=>h.name.toLowerCase()===r.toLowerCase());B(`[STREAM] Animation match for "${r}": ${u?u.name:"NONE"}`),Ae(u?.url??"")}if(t.navigation!=null){const r=String(t.navigation).trim();r!==""&&(g?g(r):window.open(r,"_blank"))}const n=t.ask_for||t.lead_capture?.ask_for,i=n?String(n).trim().toLowerCase():"",c=i==="none"||i==="<none>";if(n&&!c){const r=i;if(_&&(r==="email"&&_.email||r==="name"&&_.name||r==="phone"&&_.phone))return;xe(r||null),ye(r==="email"?"Enter your email":r==="name"?"Enter your name":r==="phone"?"Enter your phone number":"Chat with us")}else(c||t.ask_for===null||t.lead_capture&&t.lead_capture.ask_for===null||t.ask_for==="none")&&(xe(null),Qe!=="Chat with us"&&ye("Chat with us"));t.collected,t.valid},Ct=t=>{const n=t.trim();if(!n)return null;if(n.startsWith("{"))try{return JSON.parse(n)}catch{return null}if(n.includes(":")){const i=n.split(":"),c=i[0].trim().toLowerCase(),r=i.slice(1).join(":").trim();return{[c]:r}}return null},Ot=e.useCallback(()=>{},[]),gt=t=>{if(Te.current)t==="§"?Te.current=!1:(Ie.current+=t,de(n=>n+t));else if(t==="§"){Te.current=!0;return}else for(fe.current+=t;fe.current.includes(`
1
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const a=require("react/jsx-runtime"),Ge=require("@react-three/drei"),ct=require("@react-three/fiber"),e=require("react"),qt=require("three"),Jt=require("three/examples/jsm/loaders/GLTFLoader.js");function Gt(l){const b=Object.create(null,{[Symbol.toStringTag]:{value:"Module"}});if(l){for(const g in l)if(g!=="default"){const m=Object.getOwnPropertyDescriptor(l,g);Object.defineProperty(b,g,m.get?m:{enumerable:!0,get:()=>l[g]})}}return b.default=l,Object.freeze(b)}const Ue=Gt(qt),at="https://ai.streamoji.com",P=(...l)=>{},zt=(...l)=>{},kt=({analyser:l})=>{const b=e.useRef(null),g=e.useRef(null);return e.useEffect(()=>{const m=b.current;if(!m)return;const _=m.getContext("2d",{alpha:!0});if(!_)return;let C,W=null;l&&(l.fftSize=128,W=new Uint8Array(l.frequencyBinCount));const le=()=>{C=requestAnimationFrame(le),(m.width!==m.offsetWidth||m.height!==m.offsetHeight)&&(m.width=m.offsetWidth,m.height=m.offsetHeight);const Y=m.width,O=m.height;if(Y===0||O===0)return;const de=O/2;_.clearRect(0,0,Y,O),_.fillStyle="#1e293b";const A=2,R=A+2,T=Y*.95,F=Math.floor(T/R);(!g.current||g.current.length!==F)&&(g.current=new Float32Array(F).fill(2));const me=F*R,v=(Y-me)/2;l&&W&&l.getByteFrequencyData(W);const _e=W?W.length:0,q=Math.floor(_e*.7)/F,ie=new Float32Array(F);for(let I=0;I<F;I++){let j=0;if(W&&q>0){const ee=Math.floor(I*q),U=Math.floor((I+1)*q);for(let x=ee;x<U;x++){const y=W[x]||0;y>j&&(j=y)}}j<10&&(j=0);const V=j/255,D=j>0?Math.max(2,Math.pow(V,1.4)*O*.25):2;ie[I]=D}for(let I=0;I<F;I++){const j=F-1-I,V=Math.max(ie[I],ie[j]),D=g.current[I]+(V-g.current[I])*.3;g.current[I]=D;const ee=v+I*R,U=de-D/2;_.beginPath(),_.roundRect?_.roundRect(ee,U,A,D,4):_.fillRect(ee,U,A,D),_.fill()}};return le(),()=>{cancelAnimationFrame(C)}},[l]),a.jsx("canvas",{ref:b,style:{width:"100%",height:"100%",display:"block"}})},Yt="https://pub-48df6f7d60d6440bbd01676ea5d90e55.r2.dev",Et="https://pub-be53cae7bd99457a8c1f11b4d38f1672.r2.dev/default-models/avatar-dSbBDKwvmOkpTCZcwdjs.glb";async function Qt(l){const b=await crypto.subtle.digest("SHA-256",new TextEncoder().encode(l));return Array.from(new Uint8Array(b)).map(g=>g.toString(16).padStart(2,"0")).join("")}function Kt(l){const[b,g]=e.useState(null);return e.useEffect(()=>{if(!l){g(null);return}let m=!1;return Qt(l).then(_=>{if(m)return;const C=`${Yt}/${_}.glb`;fetch(C,{method:"HEAD"}).then(W=>{m||g(W.ok?C:Et)}).catch(()=>{m||g(Et)})}),()=>{m=!0}},[l]),b}const Xt=["https://pub-be53cae7bd99457a8c1f11b4d38f1672.r2.dev/masculine/idle/M_Standing_Idle_Variations_001.glb","https://pub-be53cae7bd99457a8c1f11b4d38f1672.r2.dev/masculine/idle/M_Standing_Idle_Variations_002.glb","https://pub-be53cae7bd99457a8c1f11b4d38f1672.r2.dev/masculine/idle/M_Standing_Idle_002.glb","https://pub-be53cae7bd99457a8c1f11b4d38f1672.r2.dev/masculine/idle/M_Standing_Idle_Variations_005.glb"],Zt=["https://pub-be53cae7bd99457a8c1f11b4d38f1672.r2.dev/masculine/idle/F_Standing_Idle_Variations_001.glb","https://pub-be53cae7bd99457a8c1f11b4d38f1672.r2.dev/masculine/idle/F_Standing_Idle_Variations_003.glb","https://pub-be53cae7bd99457a8c1f11b4d38f1672.r2.dev/masculine/idle/F_Standing_Idle_Variations_003.glb"],en=[{id:"m_expr_01",name:"Friendly Wave",url:"https://pub-be53cae7bd99457a8c1f11b4d38f1672.r2.dev/masculine/expression/M_Standing_Expressions_001.glb"},{id:"m_expr_02",name:"You There",url:"https://pub-be53cae7bd99457a8c1f11b4d38f1672.r2.dev/masculine/expression/M_Standing_Expressions_002.glb"},{id:"m_expr_04",name:"Awkward Agreement",url:"https://pub-be53cae7bd99457a8c1f11b4d38f1672.r2.dev/masculine/expression/M_Standing_Expressions_004.glb"},{id:"m_expr_05",name:"What's Going On?",url:"https://pub-be53cae7bd99457a8c1f11b4d38f1672.r2.dev/masculine/expression/M_Standing_Expressions_005.glb"},{id:"m_expr_06",name:"Tired Stretch",url:"https://pub-be53cae7bd99457a8c1f11b4d38f1672.r2.dev/masculine/expression/M_Standing_Expressions_006.glb"},{id:"m_expr_07",name:"Conceilied Laughter",url:"https://pub-be53cae7bd99457a8c1f11b4d38f1672.r2.dev/masculine/expression/M_Standing_Expressions_007.glb"},{id:"m_expr_08",name:"You Come Here",url:"https://pub-be53cae7bd99457a8c1f11b4d38f1672.r2.dev/masculine/expression/M_Standing_Expressions_008.glb"},{id:"m_expr_09",name:"Come Here Kid",url:"https://pub-be53cae7bd99457a8c1f11b4d38f1672.r2.dev/masculine/expression/M_Standing_Expressions_009.glb"},{id:"m_expr_10",name:"Come Here Everyone",url:"https://pub-be53cae7bd99457a8c1f11b4d38f1672.r2.dev/masculine/expression/M_Standing_Expressions_010.glb"},{id:"m_expr_11",name:"No Freaking Way",url:"https://pub-be53cae7bd99457a8c1f11b4d38f1672.r2.dev/masculine/expression/M_Standing_Expressions_011.glb"},{id:"m_expr_12",name:"Cheerful Approval",url:"https://pub-be53cae7bd99457a8c1f11b4d38f1672.r2.dev/masculine/expression/M_Standing_Expressions_012.glb"},{id:"m_expr_13",name:"Waving Hello",url:"https://pub-be53cae7bd99457a8c1f11b4d38f1672.r2.dev/masculine/expression/M_Standing_Expressions_013.glb"},{id:"m_expr_14",name:"Checking Surroundings",url:"https://pub-be53cae7bd99457a8c1f11b4d38f1672.r2.dev/masculine/expression/M_Standing_Expressions_014.glb"},{id:"m_expr_15",name:"Referee Warning",url:"https://pub-be53cae7bd99457a8c1f11b4d38f1672.r2.dev/masculine/expression/M_Standing_Expressions_015.glb"},{id:"m_expr_16",name:"You Thumbs Down",url:"https://pub-be53cae7bd99457a8c1f11b4d38f1672.r2.dev/masculine/expression/M_Standing_Expressions_016.glb"},{id:"m_expr_17",name:"Side Thumbs Down",url:"https://pub-be53cae7bd99457a8c1f11b4d38f1672.r2.dev/masculine/expression/M_Standing_Expressions_017.glb"},{id:"m_expr_18",name:"You're Finished",url:"https://pub-be53cae7bd99457a8c1f11b4d38f1672.r2.dev/masculine/expression/M_Standing_Expressions_018.glb"},{id:"m_talk_01",name:"Oh God, Why Me?",url:"https://pub-be53cae7bd99457a8c1f11b4d38f1672.r2.dev/masculine/expression/M_Talking_Variations_001.glb"},{id:"m_talk_02",name:"What Are You Doing?",url:"https://pub-be53cae7bd99457a8c1f11b4d38f1672.r2.dev/masculine/expression/M_Talking_Variations_002.glb"},{id:"m_talk_03",name:"What Am I doing?",url:"https://pub-be53cae7bd99457a8c1f11b4d38f1672.r2.dev/masculine/expression/M_Talking_Variations_003.glb"},{id:"m_talk_04",name:"No Way",url:"https://pub-be53cae7bd99457a8c1f11b4d38f1672.r2.dev/masculine/expression/M_Talking_Variations_004.glb"},{id:"m_talk_05",name:"What's Going On?",url:"https://pub-be53cae7bd99457a8c1f11b4d38f1672.r2.dev/masculine/expression/M_Talking_Variations_005.glb"},{id:"m_talk_06",name:"I have no idea",url:"https://pub-be53cae7bd99457a8c1f11b4d38f1672.r2.dev/masculine/expression/M_Talking_Variations_006.glb"},{id:"m_talk_07",name:"What's going on here?",url:"https://pub-be53cae7bd99457a8c1f11b4d38f1672.r2.dev/masculine/expression/M_Talking_Variations_007.glb"},{id:"m_talk_08",name:"Let's stop",url:"https://pub-be53cae7bd99457a8c1f11b4d38f1672.r2.dev/masculine/expression/M_Talking_Variations_008.glb"},{id:"m_talk_09",name:"Fed Up Moment",url:"https://pub-be53cae7bd99457a8c1f11b4d38f1672.r2.dev/masculine/expression/M_Talking_Variations_009.glb"},{id:"m_talk_10",name:"What's This? Hold On",url:"https://pub-be53cae7bd99457a8c1f11b4d38f1672.r2.dev/masculine/expression/M_Talking_Variations_010.glb"},{id:"f_talk_01",name:"Great Job Clap",url:"https://pub-be53cae7bd99457a8c1f11b4d38f1672.r2.dev/masculine/expression/F_Talking_Variations_001.glb"},{id:"f_talk_02",name:"Chill Stretch",url:"https://pub-be53cae7bd99457a8c1f11b4d38f1672.r2.dev/masculine/expression/F_Talking_Variations_002.glb"},{id:"f_talk_03",name:"This Is Me",url:"https://pub-be53cae7bd99457a8c1f11b4d38f1672.r2.dev/masculine/expression/F_Talking_Variations_003.glb"},{id:"f_talk_04",name:"Empathize",url:"https://pub-be53cae7bd99457a8c1f11b4d38f1672.r2.dev/masculine/expression/F_Talking_Variations_004.glb"},{id:"f_talk_05",name:"Loose Hands Stretch",url:"https://pub-be53cae7bd99457a8c1f11b4d38f1672.r2.dev/masculine/expression/F_Talking_Variations_005.glb"},{id:"f_talk_06",name:"Take It Easy",url:"https://pub-be53cae7bd99457a8c1f11b4d38f1672.r2.dev/masculine/expression/F_Talking_Variations_006.glb"}],tn=["https://pub-be53cae7bd99457a8c1f11b4d38f1672.r2.dev/masculine/expression/M_Talking_Variations_005.glb","https://pub-be53cae7bd99457a8c1f11b4d38f1672.r2.dev/masculine/expression/M_Talking_Variations_007.glb"],nn={zoom:.85,position:[.15,-.8,0],scale:1.5,rotation:[.15,.02,0]},rn=[-.45,1.9,.1],sn={browInnerUp:.2},ot=.18,an=1,Lt="__branding__",Je={neutral:{eyeLookDownLeft:.1,eyeLookDownRight:.1},happy:{mouthSmileLeft:.2,mouthSmileRight:.2,eyeLookDownLeft:.1,eyeLookDownRight:.1},sad:{eyeLookDownLeft:.2,eyeLookDownRight:.2,browDownRight:.1,browInnerUp:.6,browOuterUpRight:.2,eyeSquintLeft:.7,eyeSquintRight:.7,mouthFrownLeft:.8,mouthFrownRight:.8,mouthLeft:.2,mouthPucker:.5,mouthRollLower:.2,mouthRollUpper:.2,mouthShrugLower:.2,mouthShrugUpper:.2,mouthStretchLeft:.4},angry:{eyeLookDownLeft:.1,eyeLookDownRight:.1,browDownLeft:.6,browDownRight:.6,jawForward:.3,mouthFrownLeft:.7,mouthFrownRight:.7,mouthRollLower:.2,mouthShrugLower:.3},fear:{browInnerUp:.7,eyeSquintLeft:.5,eyeSquintRight:.5,eyeWideLeft:.6,eyeWideRight:.6,mouthClose:.1,mouthFunnel:.3,mouthShrugLower:.5,mouthShrugUpper:.5},disgust:{browDownLeft:.7,browDownRight:.1,browInnerUp:.3,eyeSquintLeft:1,eyeSquintRight:1,eyeWideLeft:.5,eyeWideRight:.5,mouthLeft:.4,mouthPressLeft:.3,mouthRollLower:.3,mouthShrugLower:.3,mouthShrugUpper:.8,mouthUpperUpLeft:.3,noseSneerLeft:1,noseSneerRight:.7},love:{browInnerUp:.4,browOuterUpLeft:.2,browOuterUpRight:.2,mouthSmileLeft:.2,mouthSmileRight:.2,eyeBlinkLeft:.6,eyeBlinkRight:.6,eyeWideLeft:.7,eyeWideRight:.7,mouthDimpleLeft:.1,mouthDimpleRight:.1,mouthPressLeft:.2,mouthShrugUpper:.2,mouthUpperUpLeft:.1,mouthUpperUpRight:.1}},on=[{key:"viseme_aa",mix:{jawOpen:.6}},{key:"viseme_E",mix:{mouthPressLeft:.8,mouthPressRight:.8,mouthDimpleLeft:1,mouthDimpleRight:1,jawOpen:.3}},{key:"viseme_I",mix:{mouthPressLeft:.6,mouthPressRight:.6,mouthDimpleLeft:.6,mouthDimpleRight:.6,jawOpen:.2}},{key:"viseme_O",mix:{mouthPucker:1,jawForward:.6,jawOpen:.2}},{key:"viseme_U",mix:{mouthFunnel:1}},{key:"viseme_PP",mix:{mouthRollLower:.3,mouthRollUpper:.3,mouthUpperUpLeft:.3,mouthUpperUpRight:.3}},{key:"viseme_FF",mix:{mouthPucker:1,mouthShrugUpper:1,mouthLowerDownLeft:.2,mouthLowerDownRight:.2,mouthDimpleLeft:1,mouthDimpleRight:1,mouthRollLower:.3}},{key:"viseme_DD",mix:{mouthPressLeft:.8,mouthPressRight:.8,mouthFunnel:.5,jawOpen:.2}},{key:"viseme_SS",mix:{mouthPressLeft:.8,mouthPressRight:.8,mouthLowerDownLeft:.5,mouthLowerDownRight:.5,jawOpen:.1}},{key:"viseme_TH",mix:{mouthRollUpper:.3,jawOpen:.2,tongueOut:.4}},{key:"viseme_CH",mix:{mouthPucker:.5,jawOpen:.2}},{key:"viseme_RR",mix:{mouthPucker:.5,jawOpen:.2}},{key:"viseme_kk",mix:{mouthLowerDownLeft:.4,mouthLowerDownRight:.4,mouthDimpleLeft:.3,mouthDimpleRight:.3,mouthFunnel:.3,mouthPucker:.3,jawOpen:.15}},{key:"viseme_nn",mix:{mouthLowerDownLeft:.4,mouthLowerDownRight:.4,mouthDimpleLeft:.3,mouthDimpleRight:.3,mouthFunnel:.3,mouthPucker:.3,jawOpen:.15,tongueOut:.2}},{key:"viseme_sil",mix:{}}],cn={aei:[{v:"E",w:.8},{v:"I",w:.2}],ee:[{v:"I",w:1}],oo:[{v:"O",w:1}],u:[{v:"U",w:1}],aa:[{v:"aa",w:1}],ah:[{v:"aa",w:.7},{v:"O",w:.3}],bmp:[{v:"PP",w:1}],fv:[{v:"FF",w:1}],th:[{v:"TH",w:1}],l:[{v:"nn",w:1}],r:[{v:"RR",w:1}],qw:[{v:"U",w:.6},{v:"O",w:.4}],chjsh:[{v:"CH",w:1}],cdgknstxyz:[{v:"DD",w:.6},{v:"SS",w:.4}],sil:[{v:"sil",w:1}]};function un(l){if(!l)return[{v:"sil",w:1}];const b=l.toLowerCase();return cn[b]??[{v:"sil",w:1}]}function ln({target:l}){const{camera:b}=ct.useThree();return e.useEffect(()=>{b.lookAt(...l)},[b,l]),null}function z(l,b,g){if(!l||!l.morphTargetDictionary)return;const m=l,_=m.morphTargetDictionary,C=m.morphTargetInfluences;if(C)for(const W in _)W.toLowerCase()===b.toLowerCase()&&(C[_[W]]=g)}function Tt(l,b=.97){if(!l)return;const g=l;if(g.morphTargetInfluences)for(let m=0;m<g.morphTargetInfluences.length;m++)g.morphTargetInfluences[m]*=b}const dn=e.memo(({avatarUrl:l,isPlayingRef:b,visemeQueueRef:g,audioContextRef:m,responseAudioStartTimeRef:_,adjustments:C,mood:W,expression:le,agentResponse:Y,isSpeaking:O,nextStartTimeRef:de,stopPlayback:A,setIsSpeaking:S,expressionUrl:R,onExpressionFinished:T,isNudgeResponse:F,avatarGender:me})=>{const{scene:v}=Ge.useGLTF(l),_e=me==="female"?Zt:Xt,Ce=Ge.useGLTF(_e),q=e.useMemo(()=>Ce.flatMap(d=>d.animations),[Ce]),ie=Ge.useGLTF(tn),I=e.useMemo(()=>ie.flatMap(d=>d.animations),[ie]),j=e.useRef(null),V=e.useRef(null),D=e.useRef(null),ee=e.useRef([]),[U]=e.useState(()=>new Ue.AnimationMixer(v)),x=e.useRef({}),y=e.useRef(null),we=e.useRef(0),ae=e.useRef(!1),Be=e.useRef(0),te=e.useRef(null);e.useEffect(()=>{if(!(!q||!v)){if(q.forEach((d,f)=>{const o=`idle_${f}`;if(!x.current[o]){const s=U.clipAction(d,v);s.name=o,s.setLoop(Ue.LoopOnce,1),s.clampWhenFinished=!0,x.current[o]=s}}),I.forEach((d,f)=>{const o=`talk_${f}`;if(!x.current[o]){const s=U.clipAction(d,v);s.name=o,s.setLoop(Ue.LoopOnce,1),s.clampWhenFinished=!0,x.current[o]=s}}),q.length>0){const d=x.current.idle_0,f=y.current&&U.existingAction(y.current.getClip());d&&!f&&(d.reset().fadeIn(.5).play(),y.current=d)}return()=>{U.stopAllAction(),x.current={},y.current=null}}},[q,I,v,U]);const Se=e.useRef("");e.useEffect(()=>{if(!R||!v||R===Se.current)return;Se.current=R,te.current=R,new Jt.GLTFLoader().load(R,f=>{if(f.animations&&f.animations.length>0){const o=f.animations[0],s=U.clipAction(o,v);if(s.name=`EXPR_${R}`,s.setLoop(Ue.LoopOnce,1),s.clampWhenFinished=!0,x.current[`EXPR_${R}`]=s,O&&te.current===R){const p=y.current;s.reset().fadeIn(.3).play(),p&&p!==s&&p.crossFadeTo(s,.3,!0),y.current=s,te.current=null}}},void 0,f=>{console.error(`[ANIMATION] Failed to load ${R}`,f)})},[R,v,U,O]),e.useEffect(()=>{const d=f=>{const o=f.action,s=o.name||"";if(s.startsWith("idle_")){const J=(parseInt(s.split("_")[1])+1)%q.length,Q=x.current[`idle_${J}`];Q&&(Q.reset().fadeIn(.5).play(),o.crossFadeTo(Q,.5,!0),y.current=Q)}else if(s.startsWith("EXPR_")){if(O){const p=x.current.talk_0;p&&(p.reset().fadeIn(.5).play(),o.crossFadeTo(p,.5,!0),y.current=p)}else{const p=x.current.idle_0;p&&(p.reset().fadeIn(.5).play(),o.crossFadeTo(p,.5,!0),y.current=p)}T&&T()}else if(s.startsWith("talk_"))if(O&&!F){const J=(parseInt(s.split("_")[1])+1)%I.length,Q=x.current[`talk_${J}`];Q&&(Q.reset().fadeIn(.3).play(),o.crossFadeTo(Q,.3,!0),y.current=Q)}else{const p=x.current.idle_0;p&&(p.reset().fadeIn(.5).play(),o.crossFadeTo(p,.5,!0),y.current=p)}};return U.addEventListener("finished",d),()=>U.removeEventListener("finished",d)},[U,q,I,O,F,T]),e.useEffect(()=>{if(O&&v){const d=y.current,f=d?.name||"";if(f.startsWith("idle_")||f.startsWith("talk_")||f===""){const o=te.current;if(o){const s=x.current[`EXPR_${o}`];if(s){s.reset().fadeIn(.3).play(),d&&d!==s&&d.crossFadeTo(s,.3,!0),y.current=s,te.current=null;return}}if(f.startsWith("idle_")||f===""){const s=x.current.talk_0;s&&(s.reset().fadeIn(.5).play(),d&&d.crossFadeTo(s,.5,!0),y.current=s)}}}else if(!O&&v){const d=y.current,f=d?.name||"";if(f.startsWith("talk_")||f.startsWith("EXPR_")){const o=x.current.idle_0;o&&(o.reset().fadeIn(.5).play(),d&&d.crossFadeTo(o,.5,!0),y.current=o)}}},[O,v,R]),e.useEffect(()=>{if(!v)return;v.traverse(o=>{if(o.isMesh&&o.morphTargetDictionary){const s=o.name.toLowerCase();(s.includes("head")||s.includes("avatar"))&&(V.current=o,P(`[ANIMATION] Found head mesh: ${o.name}`)),s.includes("teeth")&&(D.current=o,P(`[ANIMATION] Found teeth mesh: ${o.name}`))}});const d=V.current?.morphTargetDictionary;d&&Object.keys(d).filter(o=>o.toLowerCase().includes("brow"));const f=[];v.traverse(o=>{if(o.isMesh){const p=o.morphTargetDictionary;p&&Object.keys(p).some(J=>J.toLowerCase().includes("brow"))&&f.push(o)}}),ee.current=f,f.length>0&&P("[ANIMATION] Meshes with brow morphs:",f.length)},[v]);const ve=(d,f=1)=>{const o=`viseme_${d}`.toLowerCase(),s=on.find(p=>p.key.toLowerCase()===o);if(s)for(const p in s.mix){const J=s.mix[p]*f;z(V.current,p,J),z(D.current,p,J)}},Oe=d=>{const f=Je[d]??Je.neutral;for(const o in f)z(V.current,o,f[o]),z(D.current,o,f[o])};return ct.useFrame((d,f)=>{const o=Math.pow(.88,60*f);Tt(V.current,o),Tt(D.current,o),Oe(W);const s=d.clock.elapsedTime;let p=0;if(Math.floor(s)%5===0&&Math.floor((s-f)%5)!==0){let H=null;v.traverse(Z=>{Z.name.toLowerCase().includes("hips")&&(H=Z)});const ne=H?`Hips Y: ${H.position.y.toFixed(4)}`:"Hips not found";P(`[ANIMATION] Mixer Time: ${U.time.toFixed(2)}, ${ne}`)}if(U.update(f),s>we.current&&!ae.current&&(ae.current=!0,Be.current=s),ae.current){const H=O?.2:.3,ne=(s-Be.current)/H;if(ne>=1){ae.current=!1;const Z=O?1:2.5;we.current=s+Z}else{const Z=ne<.5?ne*2:(1-ne)*2;z(V.current,"eyeBlinkLeft",Z),z(V.current,"eyeBlinkRight",Z),z(D.current,"eyeBlinkLeft",Z),z(D.current,"eyeBlinkRight",Z),p=Z*sn.browInnerUp}}const J=Je[W]??Je.neutral,Q=J.browInnerUp??0,ze=J.browOuterUpLeft??0,Ye=J.browOuterUpRight??0,Te=s*an,Qe=ot*Math.sin(Te),xe=ot*.7*Math.sin(Te+.7),X=ot*.7*Math.sin(Te+1.3),ye=H=>Math.max(0,Math.min(1,H)),pe=ye(Q+Qe),ge=ye(ze+xe),Re=ye(Ye+X),De=ye(pe+p);if(z(V.current,"browInnerUp",De),z(D.current,"browInnerUp",De),z(V.current,"browOuterUpLeft",ge),z(D.current,"browOuterUpLeft",ge),z(V.current,"browOuterUpRight",Re),z(D.current,"browOuterUpRight",Re),j.current){const H=b.current?0:C.rotation[1];j.current.rotation.y=Ue.MathUtils.lerp(j.current.rotation.y,H,.1),j.current.position.set(...C.position),j.current.scale.setScalar(C.scale),j.current.rotation.x=C.rotation[0],j.current.rotation.z=C.rotation[2]}if(b.current&&m.current){const H=m.current.currentTime,Pe=(H-_.current)*1e3- -150;for(let ke=0;ke<g.current.length;ke++){const G=g.current[ke];Pe>=G.vtime&&Pe<G.vtime+G.vduration&&ve(G.viseme,G.weight??1)}H>de.current+.5&&(A(),S(!1))}}),a.jsx("group",{ref:j,children:a.jsx("primitive",{object:v})})});function fn(l){return l?l.charAt(0).toUpperCase()+l.slice(1).toLowerCase():""}const hn=({token:l,agentToken:b,onNavigationRequested:g,avatarGender:m,presetUserDetails:_}={})=>{const C=l??b??"",W=Kt(C||void 0),[le,Y]=e.useState(""),[O,de]=e.useState(""),[A,S]=e.useState("Ready"),[R,T]=e.useState(!1),[F,me]=e.useState(!1),[v,_e]=e.useState([]),[Ce,q]=e.useState(""),ie=e.useRef(null),[I,j]=e.useState(()=>typeof window<"u"?window.matchMedia("(max-width: 480px)").matches:!1);e.useEffect(()=>{const t=window.matchMedia("(max-width: 480px)"),n=()=>j(t.matches);return t.addEventListener("change",n),()=>t.removeEventListener("change",n)},[]);const V=I?80:600,D=e.useRef(!1),ee=e.useRef([]),U=e.useRef(0),x=e.useRef(!1),y=e.useRef([]),we=e.useRef(null),ae=e.useRef([]);e.useRef([]);const Be=e.useRef([]),te=e.useRef(0),Se=e.useRef(0),ve=e.useRef(0),Oe=e.useRef(0),d=e.useRef(!1),[f,o]=e.useState(null),s=e.useRef(null),[p,J]=e.useState("neutral"),[Q,ze]=e.useState(""),[Ye,Te]=e.useState(""),[Qe,xe]=e.useState("Chat with us"),[X,ye]=e.useState(null),[pe,ge]=e.useState("hidden"),[Re,De]=e.useState(""),H=e.useRef(null),ne=e.useRef(pe);ne.current=pe;const[Z,Pe]=e.useState(null),ke=e.useRef(null),G=e.useRef(null),[Ne,ut]=e.useState(!1),lt=e.useRef(null),[oe,We]=e.useState("hidden"),[dt,At]=e.useState(""),Ke=e.useRef(oe);Ke.current=oe;const fe=e.useRef(""),Ae=e.useRef(!1),Ie=e.useRef(""),ft=e.useRef(Date.now()),Xe=e.useRef([]),Fe=e.useRef(!1),[Ze,je]=e.useState(!1),[ht,mt]=e.useState(!1),be=e.useRef(null),Me=e.useMemo(()=>Ne?"Try again":A==="Busy"?"Busy":A==="Thinking..."||A==="Processing Voice..."?A:X!=null&&X!==""&&X!=="none"&&X!=="<none>"?`Enter ${fn(X)}`:oe!=="hidden"||!ht?null:Lt,[A,X,Ne,oe,ht]),pt=!Ne&&A!=="Busy"&&A!=="Thinking..."&&A!=="Processing Voice..."&&(X==null||X===""||X==="none"||X==="<none>");e.useEffect(()=>{if(oe!=="hidden"||!pt){mt(!1),be.current!=null&&(clearTimeout(be.current),be.current=null);return}return be.current=setTimeout(()=>{be.current=null,mt(!0)},400),()=>{be.current!=null&&(clearTimeout(be.current),be.current=null)}},[oe,pt]);const Ve=Me!=null&&Me!=="";e.useEffect(()=>{const t=ne.current;if(!(t==="exiting"||t==="entering")){if(t==="hidden"){Ve&&(De(Me??""),ge("entering"));return}t==="visible"&&(!Ve||Me!==Re)&&(H.current=Ve?Me:null,ge("exiting"))}},[Ve,Me,pe,Re]),e.useEffect(()=>{if(A!=="Busy"){G.current!=null&&(clearTimeout(G.current),G.current=null);return}return G.current=setTimeout(()=>{G.current=null,S("Ready"),ut(!0)},12e3),()=>{G.current!=null&&(clearTimeout(G.current),G.current=null)}},[A]),e.useEffect(()=>{if(!Ne)return;const t=setTimeout(()=>ut(!1),2500);return()=>clearTimeout(t)},[Ne]);const It=e.useCallback(()=>{const t=ne.current;if(t==="exiting"){ge("hidden");const n=H.current;H.current=null,n!=null&&n!==""&&(De(n),ge("entering"))}else t==="entering"&&ge("visible")},[]),Mt=t=>{if(!t)return;if(t.mood!=null){const r=String(t.mood).toLowerCase();J(r)}if(t.expression!=null){const r=String(t.expression).trim();ze(r);const u=en.find(h=>h.name.toLowerCase()===r.toLowerCase());P(`[STREAM] Animation match for "${r}": ${u?u.name:"NONE"}`),Te(u?.url??"")}if(t.navigation!=null){const r=String(t.navigation).trim();r!==""&&(g?g(r):window.open(r,"_blank"))}const n=t.ask_for||t.lead_capture?.ask_for,i=n?String(n).trim().toLowerCase():"",c=i==="none"||i==="<none>";if(n&&!c){const r=i;if(_&&(r==="email"&&_.email||r==="name"&&_.name||r==="phone"&&_.phone))return;ye(r||null),xe(r==="email"?"Enter your email":r==="name"?"Enter your name":r==="phone"?"Enter your phone number":"Chat with us")}else(c||t.ask_for===null||t.lead_capture&&t.lead_capture.ask_for===null||t.ask_for==="none")&&(ye(null),Qe!=="Chat with us"&&xe("Chat with us"));t.collected,t.valid},Ct=t=>{const n=t.trim();if(!n)return null;if(n.startsWith("{"))try{return JSON.parse(n)}catch{return null}if(n.includes(":")){const i=n.split(":"),c=i[0].trim().toLowerCase(),r=i.slice(1).join(":").trim();return{[c]:r}}return null},Ot=e.useCallback(()=>{},[]),gt=t=>{if(Ae.current)t==="§"?Ae.current=!1:(Ie.current+=t,de(n=>n+t));else if(t==="§"){Ae.current=!0;return}else for(fe.current+=t;fe.current.includes(`
2
2
  `);){const n=fe.current.indexOf(`
3
- `),i=fe.current.slice(0,n).trim();fe.current=fe.current.slice(n+1);const c=Ct(i);c&&Mt(c)}};e.useEffect(()=>{(async()=>{if(!sessionStorage.getItem("STREAMOJI_LEADS_SESSION_LEAD_ID")){const r="secret",u=Math.floor(Date.now()/1e3).toString();try{const h=new TextEncoder,w=await crypto.subtle.importKey("raw",h.encode(r),{name:"HMAC",hash:"SHA-256"},!1,["sign"]),k=await crypto.subtle.sign("HMAC",w,h.encode(u)),L=Array.from(new Uint8Array(k)).map(P=>P.toString(16).padStart(2,"0")).join("");sessionStorage.setItem("STREAMOJI_LEADS_SESSION_LEAD_ID",L),B("[SESSION] New HMAC UID generated and saved:",L)}catch(h){console.error("[SESSION] HMAC generation failed:",h);const w=Math.random().toString(36)+Date.now().toString();sessionStorage.setItem("STREAMOJI_LEADS_SESSION_LEAD_ID",w)}}const i=sessionStorage.getItem("STREAMOJI_LEADS_SESSION_MESSAGES");let c=[];if(i)try{c=JSON.parse(i)}catch{c=[]}c.length===0&&_&&(_.name||_.email)?(c=[{role:"user",content:`PRESET_USER_DETAILS: Name is "${_.name||""}" , Email is "${_.email||""}"`}],sessionStorage.setItem("STREAMOJI_LEADS_SESSION_MESSAGES",JSON.stringify(c))):i||sessionStorage.setItem("STREAMOJI_LEADS_SESSION_MESSAGES",JSON.stringify([]))})()},[_]),e.useEffect(()=>{const t=()=>{ft.current=Date.now(),Fe.current&&(Fe.current=!1,je(!1),_e([]),q(""),de(""),me(!1))};window.addEventListener("mousemove",t),window.addEventListener("keydown",t),window.addEventListener("mousedown",t),window.addEventListener("touchstart",t);const n=setInterval(async()=>{if(Date.now()-ft.current>=3e4&&!F&&!R&&T==="Ready"&&!Fe.current)if(Fe.current=!0,Ke.current.length>0)je(!0),_e(Ke.current);else try{const r=`${at}/nudgeUser`,u={navigationUrl:window.location.href,token:C},h=await fetch(r,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(u)});if(h.ok){const k=(await h.json()).nudge_questions;k&&k.length>0&&(B("[NUDGE] Received nudge questions from API:",k),Ke.current=k,je(!0),_e(k))}}catch(r){console.error("[NUDGE] Error calling /nudgeUser:",r),Fe.current=!1}},1e3);return()=>{window.removeEventListener("mousemove",t),window.removeEventListener("keydown",t),window.removeEventListener("mousedown",t),window.removeEventListener("touchstart",t),clearInterval(n)}},[C,F,R,T]),e.useEffect(()=>{if(v.length===0)return;let t=0,n=0,i=!1,c=100;const r=()=>{const u=v[t];if(i){const h=u.substring(0,n-1);q(h),n--,c=50}else{const h=u.substring(0,n+1);q(h),n++,c=100}!i&&n===u.length?(i=!0,c=3e3):i&&n===0&&(i=!1,t=(t+1)%v.length,c=500),ie.current=setTimeout(r,c)};return r(),()=>{ie.current&&clearTimeout(ie.current)}},[v]);const bt=()=>{try{return JSON.parse(sessionStorage.getItem("STREAMOJI_LEADS_SESSION_MESSAGES")||"[]")}catch{return[]}},Dt=t=>{sessionStorage.setItem("STREAMOJI_LEADS_SESSION_MESSAGES",JSON.stringify(t))},[et,tt]=e.useState(!1),[_t,nt]=e.useState(0),ce=e.useRef(null),He=e.useRef([]),wt=e.useRef(0),[St,Nt]=e.useState(null),[Ft,rt]=e.useState(null),he=e.useRef(null),Ee=e.useRef(null),$e=e.useCallback((t=!1)=>{t&&(d.current=!0,A(!1),S("Ready")),x.current=[],ee.current=[],y.current=!1,me(!1),te.current=0,Se.current=0,ve.current=0,ae.current.forEach(n=>{try{n.stop()}catch{}}),ke.current&&(clearTimeout(ke.current),ke.current=null),Be(null),Ae(""),ae.current=[]},[]),jt=async()=>{try{const t=await navigator.mediaDevices.getUserMedia({audio:!0}),n=window.AudioContext||window.webkitAudioContext,i=new n,c=i.createMediaStreamSource(t),r=i.createAnalyser();r.fftSize=64,c.connect(r),he.current=i,Ee.current=c,rt(r);const u=new MediaRecorder(t);ce.current=u,He.current=[],u.ondataavailable=h=>{h.data.size>0&&He.current.push(h.data)},u.onstop=async()=>{const h=Date.now()-wt.current;if(rt(null),Ee.current&&(Ee.current.disconnect(),Ee.current=null),he.current&&he.current.state!=="closed"&&(he.current.close(),he.current=null),h<1e3){S("Recording too short. Hold or click longer."),A(!1);return}const w=new Blob(He.current,{type:"audio/wav"});await Wt(w)},wt.current=Date.now(),u.start(100),tt(!0),S("Listening...")}catch(t){console.error("Error accessing microphone:",t),S("Mic Access Error")}},Ut=()=>{ce.current&&ce.current.state!=="inactive"&&(ce.current.stop(),ce.current.stream.getTracks().forEach(t=>t.stop()),tt(!1))},Pt=()=>{ce.current&&ce.current.state!=="inactive"&&(ce.current.onstop=null,ce.current.stop(),ce.current.stream.getTracks().forEach(t=>t.stop()),rt(null),Ee.current&&(Ee.current.disconnect(),Ee.current=null),he.current&&he.current.state!=="closed"&&(he.current.close(),he.current=null),tt(!1),He.current=[],S("Ready"))};e.useEffect(()=>{if(!F)return;const t=()=>{const n=ve.current;if(n<=0)return;const i=we.current,c=te.current;if(!i)return;const r=i.currentTime-c,u=Math.min(Math.max(0,r),n),h=O.trim().length;if(h<=0)return;const w=Math.min(Math.round(u/n*h),h);o(w)};return clearInterval(s.current??void 0),s.current=setInterval(t,90),()=>clearInterval(s.current??void 0)},[F,O,ve.current]),e.useEffect(()=>{let t;return et?(nt(0),t=window.setInterval(()=>{nt(n=>n+1)},1e3)):nt(0),()=>clearInterval(t)},[et]);const Bt=t=>{const n=t.numberOfChannels,i=t.length*n*2+44,c=new ArrayBuffer(i),r=new DataView(c);let u=0;const h=L=>{r.setUint16(u,L,!0),u+=2},w=L=>{r.setUint32(u,L,!0),u+=4};w(1179011410),w(i-8),w(1163280727),w(544501094),w(16),h(1),h(n),w(t.sampleRate),w(t.sampleRate*2*n),h(n*2),h(16),w(1635017060),w(i-u-4);const k=[];for(let L=0;L<n;L++)k.push(t.getChannelData(L));let E=0;for(;u<i;){for(let L=0;L<n;L++){let P=Math.max(-1,Math.min(1,k[L][E]));P=P<0?P*32768:P*32767,r.setInt16(u,P,!0),u+=2}E++}return new Blob([c],{type:"audio/wav"})},st=async(t,n,i=!1)=>{if(!d.current){if(D.current){ee.current.push({audio:t,visemes:n,isNewSegment:i});return}D.current=!0;try{const c=window.AudioContext||window.webkitAudioContext,r=we.current??new c;r.state==="suspended"&&await r.resume(),we.current=r;const u=window.atob(t),h=new Uint8Array(u.length);for(let N=0;N<u.length;N++)h[N]=u.charCodeAt(N);const w=await r.decodeAudioData(h.buffer.slice(0));ve.current+=w.duration;const k=r.currentTime;let E=Se.current;const L=!y.current;E<k&&(E=k+.1),Se.current=E+w.duration;const P=r.createBufferSource();P.buffer=w;let $=St;if((!$||$.context!==r)&&($=r.createAnalyser(),$.fftSize=64,$.connect(r.destination),Nt($)),P.connect($),ae.current.push(P),d.current){ae.current=ae.current.filter(N=>N!==P);return}if(L){y.current=!0,me(!0),B(`[AUDIO] setIsSpeaking(true) - First chunk starting at ${E.toFixed(3)}`),te.current=E;const N=(E-k)*1e3;U.current=performance.now()+N,B(`[AUDIO] Response started. Initial startTime: ${E.toFixed(3)}, CT: ${k.toFixed(3)}`)}P.start(E);const X=(E-te.current)*1e3;i&&(Oe.current=X,B(`[AUDIO] New segment detected at +${X.toFixed(0)}ms. Resetting segment offset.`)),n.forEach((N,re)=>{const M=N.symbol??"";if(M){const se=un(M),ue=Math.round(N.start*1e3),Le=Math.round((N.duration??0)*1e3),xt=Oe.current+ue;re<3&&B(`[AUDIO] Viseme "${M}": segment_relative=${ue}ms, segment_offset=${Oe.current.toFixed(0)}ms => vtime=${xt}ms`),se.forEach(Rt=>{x.current.push({viseme:Rt.v,weight:Rt.w,vtime:xt,vduration:Le})})}}),S("Speaking...")}finally{if(D.current=!1,ee.current.length>0){const c=ee.current.shift();c&&st(c.audio,c.visemes,c.isNewSegment)}}}},Wt=async t=>{try{A(!0),je(!1),Ie.current="",de(""),S("Processing Voice...");const n=await t.arrayBuffer(),c=await new(window.AudioContext||window.webkitAudioContext)().decodeAudioData(n),r=Bt(c),u=new FileReader;u.readAsDataURL(r),u.onloadend=async()=>{const h=u.result.split(",")[1];$e(),Y(""),fe.current="",Te.current=!1;const w=`${at}/stt?token=${encodeURIComponent(C)}`,k=await fetch(w,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({audio_base64:h,audio_format:"wav"})});if(k.status===429){try{const re=await k.text(),M=JSON.parse(re);B("[STT] 429 agent at capacity:",M?.detail)}catch{}Y(""),S("Busy"),A(!1);return}if(!k.ok){const re=await k.text();let M="STT Failed";try{M=JSON.parse(re).error||M}catch{re&&(M=re.slice(0,200))}throw new Error(M)}const E=k.body;if(B("this is body"+E),!E){S("STT Failed"),A(!1);return}const L=E.getReader();d.current=!1;const P=new TextDecoder;let $="",X=!1;const N=async(re,M)=>{switch(re){case"transcript":M.transcript!=null&&Y(String(M.transcript));break;case"text":{const se=M.delta??M.text??"";se&&gt(se);break}case"audio":{const se=M.chunk,ue=M.visemes??[],Le=!!M.is_new_segment;se&&await st(se,ue,Le);break}case"done":{X=!0,S("Ready"),A(!1);break}case"error":{X=!0,S("STT Failed"),A(!1);break}default:break}};for(;;){const{done:re,value:M}=await L.read();M&&($+=P.decode(M,{stream:!0}));const se=$.split(`
3
+ `),i=fe.current.slice(0,n).trim();fe.current=fe.current.slice(n+1);const c=Ct(i);c&&Mt(c)}};e.useEffect(()=>{(async()=>{if(!sessionStorage.getItem("STREAMOJI_LEADS_SESSION_LEAD_ID")){const r="secret",u=Math.floor(Date.now()/1e3).toString();try{const h=new TextEncoder,w=await crypto.subtle.importKey("raw",h.encode(r),{name:"HMAC",hash:"SHA-256"},!1,["sign"]),k=await crypto.subtle.sign("HMAC",w,h.encode(u)),L=Array.from(new Uint8Array(k)).map(B=>B.toString(16).padStart(2,"0")).join("");sessionStorage.setItem("STREAMOJI_LEADS_SESSION_LEAD_ID",L),P("[SESSION] New HMAC UID generated and saved:",L)}catch(h){console.error("[SESSION] HMAC generation failed:",h);const w=Math.random().toString(36)+Date.now().toString();sessionStorage.setItem("STREAMOJI_LEADS_SESSION_LEAD_ID",w)}}const i=sessionStorage.getItem("STREAMOJI_LEADS_SESSION_MESSAGES");let c=[];if(i)try{c=JSON.parse(i)}catch{c=[]}c.length===0&&_&&(_.name||_.email)?(c=[{role:"user",content:`PRESET_USER_DETAILS: Name is "${_.name||""}" , Email is "${_.email||""}"`}],sessionStorage.setItem("STREAMOJI_LEADS_SESSION_MESSAGES",JSON.stringify(c))):i||sessionStorage.setItem("STREAMOJI_LEADS_SESSION_MESSAGES",JSON.stringify([]))})()},[_]),e.useEffect(()=>{const t=()=>{ft.current=Date.now(),Fe.current&&(Fe.current=!1,je(!1),_e([]),q(""),de(""),me(!1))};window.addEventListener("mousemove",t),window.addEventListener("keydown",t),window.addEventListener("mousedown",t),window.addEventListener("touchstart",t);const n=setInterval(async()=>{if(Date.now()-ft.current>=3e4&&!F&&!R&&A==="Ready"&&!Fe.current)if(Fe.current=!0,Xe.current.length>0)je(!0),_e(Xe.current);else try{const r=`${at}/nudgeUser`,u={navigationUrl:window.location.href,token:C},h=await fetch(r,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(u)});if(h.ok){const k=(await h.json()).nudge_questions;k&&k.length>0&&(P("[NUDGE] Received nudge questions from API:",k),Xe.current=k,je(!0),_e(k))}}catch(r){console.error("[NUDGE] Error calling /nudgeUser:",r),Fe.current=!1}},1e3);return()=>{window.removeEventListener("mousemove",t),window.removeEventListener("keydown",t),window.removeEventListener("mousedown",t),window.removeEventListener("touchstart",t),clearInterval(n)}},[C,F,R,A]),e.useEffect(()=>{if(v.length===0)return;let t=0,n=0,i=!1,c=100;const r=()=>{const u=v[t];if(i){const h=u.substring(0,n-1);q(h),n--,c=50}else{const h=u.substring(0,n+1);q(h),n++,c=100}!i&&n===u.length?(i=!0,c=3e3):i&&n===0&&(i=!1,t=(t+1)%v.length,c=500),ie.current=setTimeout(r,c)};return r(),()=>{ie.current&&clearTimeout(ie.current)}},[v]);const bt=()=>{try{return JSON.parse(sessionStorage.getItem("STREAMOJI_LEADS_SESSION_MESSAGES")||"[]")}catch{return[]}},Dt=t=>{sessionStorage.setItem("STREAMOJI_LEADS_SESSION_MESSAGES",JSON.stringify(t))},[et,tt]=e.useState(!1),[_t,nt]=e.useState(0),ce=e.useRef(null),He=e.useRef([]),wt=e.useRef(0),[St,Nt]=e.useState(null),[Ft,rt]=e.useState(null),he=e.useRef(null),Ee=e.useRef(null),$e=e.useCallback((t=!1)=>{t&&(d.current=!0,T(!1),S("Ready")),y.current=[],ee.current=[],x.current=!1,me(!1),te.current=0,Se.current=0,ve.current=0,ae.current.forEach(n=>{try{n.stop()}catch{}}),ke.current&&(clearTimeout(ke.current),ke.current=null),Pe(null),Te(""),ae.current=[]},[]),jt=async()=>{try{const t=await navigator.mediaDevices.getUserMedia({audio:!0}),n=window.AudioContext||window.webkitAudioContext,i=new n,c=i.createMediaStreamSource(t),r=i.createAnalyser();r.fftSize=64,c.connect(r),he.current=i,Ee.current=c,rt(r);const u=new MediaRecorder(t);ce.current=u,He.current=[],u.ondataavailable=h=>{h.data.size>0&&He.current.push(h.data)},u.onstop=async()=>{const h=Date.now()-wt.current;if(rt(null),Ee.current&&(Ee.current.disconnect(),Ee.current=null),he.current&&he.current.state!=="closed"&&(he.current.close(),he.current=null),h<1e3){S("Recording too short. Hold or click longer."),T(!1);return}const w=new Blob(He.current,{type:"audio/wav"});await Wt(w)},wt.current=Date.now(),u.start(100),tt(!0),S("Listening...")}catch(t){console.error("Error accessing microphone:",t),S("Mic Access Error")}},Ut=()=>{ce.current&&ce.current.state!=="inactive"&&(ce.current.stop(),ce.current.stream.getTracks().forEach(t=>t.stop()),tt(!1))},Bt=()=>{ce.current&&ce.current.state!=="inactive"&&(ce.current.onstop=null,ce.current.stop(),ce.current.stream.getTracks().forEach(t=>t.stop()),rt(null),Ee.current&&(Ee.current.disconnect(),Ee.current=null),he.current&&he.current.state!=="closed"&&(he.current.close(),he.current=null),tt(!1),He.current=[],S("Ready"))};e.useEffect(()=>{if(!F)return;const t=()=>{const n=ve.current;if(n<=0)return;const i=we.current,c=te.current;if(!i)return;const r=i.currentTime-c,u=Math.min(Math.max(0,r),n),h=O.trim().length;if(h<=0)return;const w=Math.min(Math.round(u/n*h),h);o(w)};return clearInterval(s.current??void 0),s.current=setInterval(t,90),()=>clearInterval(s.current??void 0)},[F,O,ve.current]),e.useEffect(()=>{let t;return et?(nt(0),t=window.setInterval(()=>{nt(n=>n+1)},1e3)):nt(0),()=>clearInterval(t)},[et]);const Pt=t=>{const n=t.numberOfChannels,i=t.length*n*2+44,c=new ArrayBuffer(i),r=new DataView(c);let u=0;const h=L=>{r.setUint16(u,L,!0),u+=2},w=L=>{r.setUint32(u,L,!0),u+=4};w(1179011410),w(i-8),w(1163280727),w(544501094),w(16),h(1),h(n),w(t.sampleRate),w(t.sampleRate*2*n),h(n*2),h(16),w(1635017060),w(i-u-4);const k=[];for(let L=0;L<n;L++)k.push(t.getChannelData(L));let E=0;for(;u<i;){for(let L=0;L<n;L++){let B=Math.max(-1,Math.min(1,k[L][E]));B=B<0?B*32768:B*32767,r.setInt16(u,B,!0),u+=2}E++}return new Blob([c],{type:"audio/wav"})},st=async(t,n,i=!1)=>{if(!d.current){if(D.current){ee.current.push({audio:t,visemes:n,isNewSegment:i});return}D.current=!0;try{const c=window.AudioContext||window.webkitAudioContext,r=we.current??new c;r.state==="suspended"&&await r.resume(),we.current=r;const u=window.atob(t),h=new Uint8Array(u.length);for(let N=0;N<u.length;N++)h[N]=u.charCodeAt(N);const w=await r.decodeAudioData(h.buffer.slice(0));ve.current+=w.duration;const k=r.currentTime;let E=Se.current;const L=!x.current;E<k&&(E=k+.1),Se.current=E+w.duration;const B=r.createBufferSource();B.buffer=w;let $=St;if((!$||$.context!==r)&&($=r.createAnalyser(),$.fftSize=64,$.connect(r.destination),Nt($)),B.connect($),ae.current.push(B),d.current){ae.current=ae.current.filter(N=>N!==B);return}if(L){x.current=!0,me(!0),P(`[AUDIO] setIsSpeaking(true) - First chunk starting at ${E.toFixed(3)}`),te.current=E;const N=(E-k)*1e3;U.current=performance.now()+N,P(`[AUDIO] Response started. Initial startTime: ${E.toFixed(3)}, CT: ${k.toFixed(3)}`)}B.start(E);const K=(E-te.current)*1e3;i&&(Oe.current=K,P(`[AUDIO] New segment detected at +${K.toFixed(0)}ms. Resetting segment offset.`)),n.forEach((N,re)=>{const M=N.symbol??"";if(M){const se=un(M),ue=Math.round(N.start*1e3),Le=Math.round((N.duration??0)*1e3),yt=Oe.current+ue;re<3&&P(`[AUDIO] Viseme "${M}": segment_relative=${ue}ms, segment_offset=${Oe.current.toFixed(0)}ms => vtime=${yt}ms`),se.forEach(Rt=>{y.current.push({viseme:Rt.v,weight:Rt.w,vtime:yt,vduration:Le})})}}),S("Speaking...")}finally{if(D.current=!1,ee.current.length>0){const c=ee.current.shift();c&&st(c.audio,c.visemes,c.isNewSegment)}}}},Wt=async t=>{try{T(!0),je(!1),Ie.current="",de(""),S("Processing Voice...");const n=await t.arrayBuffer(),c=await new(window.AudioContext||window.webkitAudioContext)().decodeAudioData(n),r=Pt(c),u=new FileReader;u.readAsDataURL(r),u.onloadend=async()=>{const h=u.result.split(",")[1];$e(),Y(""),fe.current="",Ae.current=!1;const w=`${at}/stt?token=${encodeURIComponent(C)}`,k=await fetch(w,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({audio_base64:h,audio_format:"wav"})});if(k.status===429){try{const re=await k.text(),M=JSON.parse(re);P("[STT] 429 agent at capacity:",M?.detail)}catch{}Y(""),S("Busy"),T(!1);return}if(!k.ok){const re=await k.text();let M="STT Failed";try{M=JSON.parse(re).error||M}catch{re&&(M=re.slice(0,200))}throw new Error(M)}const E=k.body;if(P("this is body"+E),!E){S("STT Failed"),T(!1);return}const L=E.getReader();d.current=!1;const B=new TextDecoder;let $="",K=!1;const N=async(re,M)=>{switch(re){case"transcript":M.transcript!=null&&Y(String(M.transcript));break;case"text":{const se=M.delta??M.text??"";se&&gt(se);break}case"audio":{const se=M.chunk,ue=M.visemes??[],Le=!!M.is_new_segment;se&&await st(se,ue,Le);break}case"done":{K=!0,S("Ready"),T(!1);break}case"error":{K=!0,S("STT Failed"),T(!1);break}default:break}};for(;;){const{done:re,value:M}=await L.read();M&&($+=B.decode(M,{stream:!0}));const se=$.split(`
4
4
 
5
- `);$=se.pop()??"";for(const ue of se){const Le=qe(ue);Le&&await N(Le.event,Le.data)}if(re){if($.trim()){const ue=qe($.trim());ue&&await N(ue.event,ue.data)}X||(S("Ready"),A(!1));break}}}}catch(n){console.error("Audio Submission Error:",n),S("STT Failed"),A(!1)}},Vt=async t=>{t&&t.preventDefault(),je(!1),Ie.current="",de(""),!(!le||R)&&await Ht(le)},qe=t=>{const n=t.split(/\r?\n/);let i="",c="";for(const u of n)u.startsWith("event:")?i=u.slice(6).trim():u.startsWith("data:")&&(c=u.slice(5).trim());if(!i)return null;let r={};if(c)try{r=JSON.parse(c)}catch{r={raw:c}}return{event:i,data:r}},vt=(t,n)=>{switch(t){case"connected":fe.current="",Te.current=!1;break;case"text":{const i=n.delta??"";i&&gt(i);break}case"audio":{const i=n.chunk,c=n.visemes??[];i&&st(i,c);break}case"done":{const i=bt(),c=Ie.current.trim(),r=[...i,{role:"user",content:le||"..."},{role:"assistant",content:c}];Dt(r),Pe.current=[...x.current],S("Ready"),A(!1),Y("");break}case"error":{const i=n.message??"Unknown error";Ie.current=i,de(i),S("Agent Failed"),A(!1);break}}},Ht=async t=>{A(!0),S("Thinking..."),Ie.current="",fe.current="",Te.current=!1,$e(),ve.current=0,o(0);const n=`${at}/agent/chat?token=${encodeURIComponent(C)}`;try{const i=bt();let c=sessionStorage.getItem("STREAMOJI_LEADS_SESSION_LEAD_ID");c||(zt("[CHAT] Session UID missing at send time! Generating emergency backup."),c="emergency-"+Math.random().toString(36).substring(7),sessionStorage.setItem("STREAMOJI_LEADS_SESSION_LEAD_ID",c));const r={history:i,question:t,lead_id:c};B("[CHAT] Sending payload:",r);const u=await fetch(n,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(r),cache:"default"});if(u.status===429){try{const L=await u.json();B("[CHAT] 429 agent at capacity:",L?.detail)}catch{}Y(""),S("Busy"),A(!1);return}if(!u.ok)throw new Error("Agent request failed");const h=u.body;if(!h){S("Agent Failed"),A(!1);return}const w=h.getReader();d.current=!1;const k=new TextDecoder;let E="";for(;;){const{done:L,value:P}=await w.read();B(`[SSE] Chunk received. done=${L}, length=${P?.length||0}`),P&&(E+=k.decode(P,{stream:!0}));const $=E.split(`
5
+ `);$=se.pop()??"";for(const ue of se){const Le=qe(ue);Le&&await N(Le.event,Le.data)}if(re){if($.trim()){const ue=qe($.trim());ue&&await N(ue.event,ue.data)}K||(S("Ready"),T(!1));break}}}}catch(n){console.error("Audio Submission Error:",n),S("STT Failed"),T(!1)}},Vt=async t=>{t&&t.preventDefault(),je(!1),Ie.current="",de(""),!(!le||R)&&await Ht(le)},qe=t=>{const n=t.split(/\r?\n/);let i="",c="";for(const u of n)u.startsWith("event:")?i=u.slice(6).trim():u.startsWith("data:")&&(c=u.slice(5).trim());if(!i)return null;let r={};if(c)try{r=JSON.parse(c)}catch{r={raw:c}}return{event:i,data:r}},vt=(t,n)=>{switch(t){case"connected":fe.current="",Ae.current=!1;break;case"text":{const i=n.delta??"";i&&gt(i);break}case"audio":{const i=n.chunk,c=n.visemes??[];i&&st(i,c);break}case"done":{const i=bt(),c=Ie.current.trim(),r=[...i,{role:"user",content:le||"..."},{role:"assistant",content:c}];Dt(r),Be.current=[...y.current],S("Ready"),T(!1),Y("");break}case"error":{const i=n.message??"Unknown error";Ie.current=i,de(i),S("Agent Failed"),T(!1);break}}},Ht=async t=>{T(!0),S("Thinking..."),Ie.current="",fe.current="",Ae.current=!1,$e(),ve.current=0,o(0);const n=`${at}/agent/chat?token=${encodeURIComponent(C)}`;try{const i=bt();let c=sessionStorage.getItem("STREAMOJI_LEADS_SESSION_LEAD_ID");c||(zt("[CHAT] Session UID missing at send time! Generating emergency backup."),c="emergency-"+Math.random().toString(36).substring(7),sessionStorage.setItem("STREAMOJI_LEADS_SESSION_LEAD_ID",c));const r={history:i,question:t,lead_id:c};P("[CHAT] Sending payload:",r);const u=await fetch(n,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(r),cache:"default"});if(u.status===429){try{const L=await u.json();P("[CHAT] 429 agent at capacity:",L?.detail)}catch{}Y(""),S("Busy"),T(!1);return}if(!u.ok)throw new Error("Agent request failed");const h=u.body;if(!h){S("Agent Failed"),T(!1);return}const w=h.getReader();d.current=!1;const k=new TextDecoder;let E="";for(;;){const{done:L,value:B}=await w.read();P(`[SSE] Chunk received. done=${L}, length=${B?.length||0}`),B&&(E+=k.decode(B,{stream:!0}));const $=E.split(`
6
6
 
7
- `);E=$.pop()??"";for(const X of $){B(`[SSE] Processing block: ${X.slice(0,50)}...`);const N=qe(X);N&&(B(`[SSE] Event: ${N.event}`),vt(N.event,N.data))}if(L){if(B("[SSE] Stream finished"),E.trim()){const X=qe(E.trim());X&&vt(X.event,X.data)}S("Ready"),A(!1),Y("");break}}}catch(i){console.error("Chat Error:",i),S("Agent Failed"),A(!1)}},yt=O.trim(),it=yt&&F?yt.slice(0,f!=null&&f>0?f:0):"";e.useEffect(()=>{const t=Xe.current;t!=="exiting"&&(it?(Tt(it),t==="hidden"&&We("entering")):(t==="visible"||t==="entering")&&We("exiting"))},[it,oe]);const $t=e.useCallback(()=>{const t=Xe.current;t==="entering"?We("visible"):t==="exiting"&&We("hidden")},[]);return e.useLayoutEffect(()=>{const t=lt.current;t&&(t.scrollTop=t.scrollHeight)},[dt]),a.jsxs("div",{className:"avatar-widget-container",children:[a.jsxs("div",{className:"avatar-input-area",children:[pe!=="hidden"?a.jsx("div",{className:`avatar-thinking-tab${pe==="exiting"?" avatar-thinking-tab--exiting":pe==="entering"?" avatar-thinking-tab--entering":""}`,onAnimationEnd:It,children:Re===Lt?a.jsx("a",{href:"https://leads.streamoji.com",target:"_blank",rel:"noopener noreferrer",children:"Made by Streamoji Leads"}):Re}):null,a.jsx("div",{className:"avatar-input-container",children:a.jsx("div",{style:{display:"flex",alignItems:"center",width:"100%",height:"100%"},children:et?a.jsxs("div",{className:"avatar-input-recording",children:[a.jsx("button",{type:"button",className:"avatar-recording-cancel",onClick:Pt,title:"Cancel",children:a.jsxs("svg",{width:"18",height:"18",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2.5",strokeLinecap:"round",strokeLinejoin:"round",style:{display:"block"},children:[a.jsx("line",{x1:"18",y1:"6",x2:"6",y2:"18"}),a.jsx("line",{x1:"6",y1:"6",x2:"18",y2:"18"})]})}),a.jsxs("div",{style:{flex:1,height:"100%",position:"relative",display:"flex",alignItems:"center",minWidth:0},children:[a.jsx("div",{style:{flex:1,height:"100%"},children:a.jsx(kt,{analyser:Ft})}),a.jsxs("span",{style:{fontSize:"0.75rem",color:"#64748b",fontWeight:500,marginLeft:"4px",minWidth:"32px",textAlign:"right",fontVariantNumeric:"tabular-nums"},children:[Math.floor(_t/60),":",String(_t%60).padStart(2,"0")]})]}),a.jsx("button",{type:"button",className:"avatar-recording-confirm",onClick:Ut,title:"Send",children:a.jsx("svg",{width:"18",height:"18",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2.5",strokeLinecap:"round",strokeLinejoin:"round",style:{display:"block"},children:a.jsx("polyline",{points:"20 6 9 17 4 12"})})})]}):F&&!Ze?a.jsxs("div",{className:"avatar-input-speaking",children:[a.jsx("div",{style:{flex:1,height:"100%",display:"flex",alignItems:"center",paddingRight:"8px"},children:a.jsx(kt,{analyser:St})}),a.jsx("button",{type:"button",className:"avatar-speaking-stop",onClick:()=>$e(!0),title:"Stop",children:a.jsx("span",{className:"avatar-speaking-stop__icon","aria-hidden":!0})})]}):R?a.jsx("div",{style:{flex:1,height:"100%",display:"flex",alignItems:"center",justifyContent:"center"},children:a.jsx("div",{className:"avatar-input-loader"})}):a.jsxs("form",{onSubmit:Vt,style:{flex:1,display:"flex",height:"100%",alignItems:"center"},children:[a.jsx("input",{id:"avatar-text-input",type:"text",value:le,onChange:t=>Y(t.target.value),placeholder:T==="Busy"?"Assisting another user":Ce||"Ask me anything",disabled:R||T==="Busy",autoComplete:"off",style:{width:"100%",height:"100%"}}),T==="Busy"?a.jsx("button",{type:"button",className:"mic-button",disabled:!0,style:{backgroundColor:"#1e4a5e"},title:"Agent at capacity",children:a.jsx("svg",{width:"24",height:"24",viewBox:"0 0 24 24",fill:"none",xmlns:"http://www.w3.org/2000/svg","aria-hidden":"true",children:a.jsx("path",{d:"M4 2L20 2L12 10L4 2z M12 14L4 22L20 22L12 14z",fill:"white"})})}):le.trim()===""?a.jsx("button",{type:"button",className:"mic-button",onClick:jt,disabled:R,style:{backgroundColor:"#1e4a5e"},children:a.jsxs("svg",{width:"28",height:"28",viewBox:"0 0 24 24",fill:"none",xmlns:"http://www.w3.org/2000/svg",children:[a.jsx("path",{d:"M12 14C13.66 14 15 12.66 15 11V5C15 3.34 13.66 2 12 2C10.34 2 9 3.34 9 5V11C9 12.66 10.34 14 12 14Z",fill:"white"}),a.jsx("path",{d:"M17 11C17 13.76 14.76 16 12 16C9.24 16 7 13.76 7 11H5C5 14.53 7.61 17.43 11 17.93V21H13V17.93C16.39 17.43 19 14.53 19 11H17Z",fill:"white"})]})}):a.jsx("button",{type:"submit",className:"mic-button",disabled:R,style:{backgroundColor:"#1e4a5e"},title:"Send",children:a.jsx("svg",{width:24,height:24,viewBox:"0 0 24 24",fill:"none","aria-hidden":"true",children:a.jsx("path",{d:"M19 12H5M19 12L14 17M19 12L14 7",stroke:"white",strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round"})})})]})})})]}),a.jsx("div",{className:"avatar-wrapper",children:a.jsxs("div",{className:"avatar-scene-wrapper",children:[oe!=="hidden"&&a.jsx("div",{className:`avatar-bubble${oe==="entering"?" avatar-bubble--entering":oe==="exiting"?" avatar-bubble--exiting":""}`,onAnimationEnd:$t,children:a.jsx("div",{ref:lt,className:`avatar-bubble__content${Ze?" avatar-bubble__content--nudge":""}`,children:dt})}),a.jsx("div",{className:"avatar-canvas-layer",style:{width:V,height:V},children:a.jsxs(ct.Canvas,{shadows:!0,camera:{position:[.2,1.4,3],fov:42},gl:{alpha:!0},dpr:1.8,style:{pointerEvents:"none",width:"100%",height:"100%"},children:[a.jsx(ln,{target:rn}),a.jsx("ambientLight",{intensity:.7}),a.jsx("directionalLight",{position:[0,2,2],intensity:1}),a.jsx(Ge.Environment,{preset:"city"}),a.jsx(e.Suspense,{fallback:null,children:W!==null&&a.jsx(dn,{avatarUrl:W,isPlayingRef:y,visemeQueueRef:x,audioContextRef:we,responseAudioStartTimeRef:te,adjustments:nn,mood:p,expression:Q,agentResponse:O,isSpeaking:F,nextStartTimeRef:Se,stopPlayback:$e,setIsSpeaking:me,expressionUrl:Ye,onExpressionFinished:Ot,isNudgeResponse:Ze,avatarGender:m})})]})})]})})]})},mn=({token:l,avatarGender:b,onNavigationRequested:g,presetUserDetails:m})=>a.jsx(hn,{token:l,onNavigationRequested:g,avatarGender:b,presetUserDetails:m});exports.AvatarWidget=mn;
7
+ `);E=$.pop()??"";for(const K of $){P(`[SSE] Processing block: ${K.slice(0,50)}...`);const N=qe(K);N&&(P(`[SSE] Event: ${N.event}`),vt(N.event,N.data))}if(L){if(P("[SSE] Stream finished"),E.trim()){const K=qe(E.trim());K&&vt(K.event,K.data)}S("Ready"),T(!1),Y("");break}}}catch(i){console.error("Chat Error:",i),S("Agent Failed"),T(!1)}},xt=O.trim(),it=xt&&F?xt.slice(0,f!=null&&f>0?f:0):"";e.useEffect(()=>{const t=Ke.current;t!=="exiting"&&(it?(At(it),t==="hidden"&&We("entering")):(t==="visible"||t==="entering")&&We("exiting"))},[it,oe]);const $t=e.useCallback(()=>{const t=Ke.current;t==="entering"?We("visible"):t==="exiting"&&We("hidden")},[]);return e.useLayoutEffect(()=>{const t=lt.current;t&&(t.scrollTop=t.scrollHeight)},[dt]),a.jsxs("div",{className:"avatar-widget-container",children:[a.jsxs("div",{className:"avatar-input-area",children:[pe!=="hidden"?a.jsx("div",{className:`avatar-thinking-tab${pe==="exiting"?" avatar-thinking-tab--exiting":pe==="entering"?" avatar-thinking-tab--entering":""}`,onAnimationEnd:It,children:Re===Lt?a.jsx("a",{href:"https://leads.streamoji.com",target:"_blank",rel:"noopener noreferrer",children:"Made by Streamoji Leads"}):Re}):null,a.jsx("div",{className:"avatar-input-container",children:a.jsx("div",{style:{display:"flex",alignItems:"center",width:"100%",height:"100%"},children:et?a.jsxs("div",{className:"avatar-input-recording",children:[a.jsx("button",{type:"button",className:"avatar-recording-cancel",onClick:Bt,title:"Cancel",children:a.jsxs("svg",{width:"18",height:"18",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2.5",strokeLinecap:"round",strokeLinejoin:"round",style:{display:"block"},children:[a.jsx("line",{x1:"18",y1:"6",x2:"6",y2:"18"}),a.jsx("line",{x1:"6",y1:"6",x2:"18",y2:"18"})]})}),a.jsxs("div",{style:{flex:1,height:"100%",position:"relative",display:"flex",alignItems:"center",minWidth:0},children:[a.jsx("div",{style:{flex:1,height:"100%"},children:a.jsx(kt,{analyser:Ft})}),a.jsxs("span",{style:{fontSize:"0.75rem",color:"#64748b",fontWeight:500,marginLeft:"4px",minWidth:"32px",textAlign:"right",fontVariantNumeric:"tabular-nums"},children:[Math.floor(_t/60),":",String(_t%60).padStart(2,"0")]})]}),a.jsx("button",{type:"button",className:"avatar-recording-confirm",onClick:Ut,title:"Send",children:a.jsx("svg",{width:"18",height:"18",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2.5",strokeLinecap:"round",strokeLinejoin:"round",style:{display:"block"},children:a.jsx("polyline",{points:"20 6 9 17 4 12"})})})]}):F&&!Ze?a.jsxs("div",{className:"avatar-input-speaking",children:[a.jsx("div",{style:{flex:1,height:"100%",display:"flex",alignItems:"center",paddingRight:"8px"},children:a.jsx(kt,{analyser:St})}),a.jsx("button",{type:"button",className:"avatar-speaking-stop",onClick:()=>$e(!0),title:"Stop",children:a.jsx("span",{className:"avatar-speaking-stop__icon","aria-hidden":!0})})]}):R?a.jsx("div",{style:{flex:1,height:"100%",display:"flex",alignItems:"center",justifyContent:"center"},children:a.jsx("div",{className:"avatar-input-loader"})}):a.jsxs("form",{onSubmit:Vt,style:{flex:1,display:"flex",height:"100%",alignItems:"center"},children:[a.jsx("input",{id:"avatar-text-input",type:"text",value:le,onChange:t=>Y(t.target.value),placeholder:A==="Busy"?"Assisting another user":Ce||"Ask me anything",disabled:R||A==="Busy",autoComplete:"off",style:{width:"100%",height:"100%"}}),A==="Busy"?a.jsx("button",{type:"button",className:"mic-button",disabled:!0,style:{backgroundColor:"#1e4a5e"},title:"Agent at capacity",children:a.jsx("svg",{width:"24",height:"24",viewBox:"0 0 24 24",fill:"none",xmlns:"http://www.w3.org/2000/svg","aria-hidden":"true",children:a.jsx("path",{d:"M4 2L20 2L12 10L4 2z M12 14L4 22L20 22L12 14z",fill:"white"})})}):le.trim()===""?a.jsx("button",{type:"button",className:"mic-button",onClick:jt,disabled:R,style:{backgroundColor:"#1e4a5e"},children:a.jsxs("svg",{width:"28",height:"28",viewBox:"0 0 24 24",fill:"none",xmlns:"http://www.w3.org/2000/svg",children:[a.jsx("path",{d:"M12 14C13.66 14 15 12.66 15 11V5C15 3.34 13.66 2 12 2C10.34 2 9 3.34 9 5V11C9 12.66 10.34 14 12 14Z",fill:"white"}),a.jsx("path",{d:"M17 11C17 13.76 14.76 16 12 16C9.24 16 7 13.76 7 11H5C5 14.53 7.61 17.43 11 17.93V21H13V17.93C16.39 17.43 19 14.53 19 11H17Z",fill:"white"})]})}):a.jsx("button",{type:"submit",className:"mic-button",disabled:R,style:{backgroundColor:"#1e4a5e"},title:"Send",children:a.jsx("svg",{width:24,height:24,viewBox:"0 0 24 24",fill:"none","aria-hidden":"true",children:a.jsx("path",{d:"M19 12H5M19 12L14 17M19 12L14 7",stroke:"white",strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round"})})})]})})})]}),a.jsx("div",{className:"avatar-wrapper",children:a.jsxs("div",{className:"avatar-scene-wrapper",children:[oe!=="hidden"&&a.jsx("div",{className:`avatar-bubble${oe==="entering"?" avatar-bubble--entering":oe==="exiting"?" avatar-bubble--exiting":""}`,onAnimationEnd:$t,children:a.jsx("div",{ref:lt,className:`avatar-bubble__content${Ze?" avatar-bubble__content--nudge":""}`,children:dt})}),a.jsx("div",{className:"avatar-canvas-layer",style:{width:V,height:V},children:a.jsxs(ct.Canvas,{shadows:!0,camera:{position:[.2,1.4,3],fov:42},gl:{alpha:!0},dpr:1.8,style:{pointerEvents:"none",width:"100%",height:"100%"},children:[a.jsx(ln,{target:rn}),a.jsx("ambientLight",{intensity:.7}),a.jsx("directionalLight",{position:[0,2,2],intensity:1}),a.jsx(Ge.Environment,{preset:"city"}),a.jsx(e.Suspense,{fallback:null,children:W!==null&&a.jsx(dn,{avatarUrl:W,isPlayingRef:x,visemeQueueRef:y,audioContextRef:we,responseAudioStartTimeRef:te,adjustments:nn,mood:p,expression:Q,agentResponse:O,isSpeaking:F,nextStartTimeRef:Se,stopPlayback:$e,setIsSpeaking:me,expressionUrl:Ye,onExpressionFinished:Ot,isNudgeResponse:Ze,avatarGender:m})})]})})]})})]})},mn=({token:l,avatarGender:b,onNavigationRequested:g,presetUserDetails:m})=>a.jsx(hn,{token:l,onNavigationRequested:g,avatarGender:b,presetUserDetails:m});exports.AvatarWidget=mn;
@@ -1,6 +1,6 @@
1
1
  import { jsx as l, jsxs as ae } from "react/jsx-runtime";
2
2
  import { useGLTF as lt, Environment as Yt } from "@react-three/drei";
3
- import { useFrame as Qt, Canvas as Xt, useThree as Kt } from "@react-three/fiber";
3
+ import { useFrame as Qt, Canvas as Kt, useThree as Xt } from "@react-three/fiber";
4
4
  import { memo as Zt, useMemo as ft, useRef as a, useState as g, useEffect as $, useCallback as Ye, useLayoutEffect as en, Suspense as tn } from "react";
5
5
  import * as Ve from "three";
6
6
  import { GLTFLoader as nn } from "three/examples/jsm/loaders/GLTFLoader.js";
@@ -17,13 +17,13 @@ const ut = "https://ai.streamoji.com", V = (...f) => {
17
17
  f && (f.fftSize = 128, H = new Uint8Array(f.frequencyBinCount));
18
18
  const he = () => {
19
19
  O = requestAnimationFrame(he), (p.width !== p.offsetWidth || p.height !== p.offsetHeight) && (p.width = p.offsetWidth, p.height = p.offsetHeight);
20
- const X = p.width, D = p.height;
21
- if (X === 0 || D === 0) return;
20
+ const K = p.width, D = p.height;
21
+ if (K === 0 || D === 0) return;
22
22
  const me = D / 2;
23
- _.clearRect(0, 0, X, D), _.fillStyle = "#1e293b";
24
- const I = 2, k = I + 2, E = X * 0.95, U = Math.floor(E / k);
23
+ _.clearRect(0, 0, K, D), _.fillStyle = "#1e293b";
24
+ const I = 2, k = I + 2, E = K * 0.95, U = Math.floor(E / k);
25
25
  (!b.current || b.current.length !== U) && (b.current = new Float32Array(U).fill(2));
26
- const be = U * k, y = (X - be) / 2;
26
+ const be = U * k, y = (K - be) / 2;
27
27
  f && H && f.getByteFrequencyData(H);
28
28
  const Ie = H ? H.length : 0, G = Math.floor(Ie * 0.7) / U, ce = new Float32Array(U);
29
29
  for (let M = 0; M < U; M++) {
@@ -56,7 +56,7 @@ const ut = "https://ai.streamoji.com", V = (...f) => {
56
56
  style: { width: "100%", height: "100%", display: "block" }
57
57
  }
58
58
  );
59
- }, sn = "https://pub-48df6f7d60d6440bbd01676ea5d90e55.r2.dev", It = "https://pub-be53cae7bd99457a8c1f11b4d38f1672.r2.dev/default-models/fullbodyavatarmale.glb";
59
+ }, sn = "https://pub-48df6f7d60d6440bbd01676ea5d90e55.r2.dev", It = "https://pub-be53cae7bd99457a8c1f11b4d38f1672.r2.dev/default-models/avatar-dSbBDKwvmOkpTCZcwdjs.glb";
60
60
  async function on(f) {
61
61
  const T = await crypto.subtle.digest(
62
62
  "SHA-256",
@@ -483,7 +483,7 @@ function _n(f) {
483
483
  return bn[T] ?? [{ v: "sil", w: 1 }];
484
484
  }
485
485
  function wn({ target: f }) {
486
- const { camera: T } = Kt();
486
+ const { camera: T } = Xt();
487
487
  return $(() => {
488
488
  T.lookAt(...f);
489
489
  }, [T, f]), null;
@@ -513,7 +513,7 @@ const vn = Zt(
513
513
  adjustments: O,
514
514
  mood: H,
515
515
  expression: he,
516
- agentResponse: X,
516
+ agentResponse: K,
517
517
  isSpeaking: D,
518
518
  nextStartTimeRef: me,
519
519
  stopPlayback: I,
@@ -576,8 +576,8 @@ const vn = Zt(
576
576
  const u = (d) => {
577
577
  const s = d.action, r = s.name || "";
578
578
  if (r.startsWith("idle_")) {
579
- const z = (parseInt(r.split("_")[1]) + 1) % G.length, K = S.current[`idle_${z}`];
580
- K && (K.reset().fadeIn(0.5).play(), s.crossFadeTo(K, 0.5, !0), x.current = K);
579
+ const z = (parseInt(r.split("_")[1]) + 1) % G.length, X = S.current[`idle_${z}`];
580
+ X && (X.reset().fadeIn(0.5).play(), s.crossFadeTo(X, 0.5, !0), x.current = X);
581
581
  } else if (r.startsWith("EXPR_")) {
582
582
  if (D) {
583
583
  const m = S.current.talk_0;
@@ -589,8 +589,8 @@ const vn = Zt(
589
589
  E && E();
590
590
  } else if (r.startsWith("talk_"))
591
591
  if (D && !U) {
592
- const z = (parseInt(r.split("_")[1]) + 1) % M.length, K = S.current[`talk_${z}`];
593
- K && (K.reset().fadeIn(0.3).play(), s.crossFadeTo(K, 0.3, !0), x.current = K);
592
+ const z = (parseInt(r.split("_")[1]) + 1) % M.length, X = S.current[`talk_${z}`];
593
+ X && (X.reset().fadeIn(0.3).play(), s.crossFadeTo(X, 0.3, !0), x.current = X);
594
594
  } else {
595
595
  const m = S.current.idle_0;
596
596
  m && (m.reset().fadeIn(0.5).play(), s.crossFadeTo(m, 0.5, !0), x.current = m);
@@ -684,7 +684,7 @@ const vn = Zt(
684
684
  Q(j.current, "eyeBlinkLeft", te), Q(j.current, "eyeBlinkRight", te), Q(N.current, "eyeBlinkLeft", te), Q(N.current, "eyeBlinkRight", te), m = te * mn.browInnerUp;
685
685
  }
686
686
  }
687
- const z = Qe[H] ?? Qe.neutral, K = z.browInnerUp ?? 0, Xe = z.browOuterUpLeft ?? 0, Ke = z.browOuterUpRight ?? 0, Me = r * pn, Ze = dt * Math.sin(Me), ke = dt * 0.7 * Math.sin(Me + 0.7), ee = dt * 0.7 * Math.sin(Me + 1.3), Ae = (J) => Math.max(0, Math.min(1, J)), _e = Ae(K + Ze), we = Ae(Xe + ke), Re = Ae(Ke + ee), Ue = Ae(_e + m);
687
+ const z = Qe[H] ?? Qe.neutral, X = z.browInnerUp ?? 0, Ke = z.browOuterUpLeft ?? 0, Xe = z.browOuterUpRight ?? 0, Me = r * pn, Ze = dt * Math.sin(Me), ke = dt * 0.7 * Math.sin(Me + 0.7), ee = dt * 0.7 * Math.sin(Me + 1.3), Ae = (J) => Math.max(0, Math.min(1, J)), _e = Ae(X + Ze), we = Ae(Ke + ke), Re = Ae(Xe + ee), Ue = Ae(_e + m);
688
688
  if (Q(j.current, "browInnerUp", Ue), Q(N.current, "browInnerUp", Ue), Q(j.current, "browOuterUpLeft", we), Q(N.current, "browOuterUpLeft", we), Q(j.current, "browOuterUpRight", Re), Q(N.current, "browOuterUpRight", Re), B.current) {
689
689
  const J = T.current ? 0 : O.rotation[1];
690
690
  B.current.rotation.y = Ve.MathUtils.lerp(
@@ -714,7 +714,7 @@ const Sn = ({
714
714
  avatarGender: p,
715
715
  presetUserDetails: _
716
716
  } = {}) => {
717
- const O = f ?? T ?? "", H = an(O || void 0), [he, X] = g(""), [D, me] = g(""), [I, v] = g("Ready"), [k, E] = g(!1), [U, be] = g(!1), [y, Ie] = g([]), [Ne, G] = g(""), ce = a(null), [M, B] = g(
717
+ const O = f ?? T ?? "", H = an(O || void 0), [he, K] = g(""), [D, me] = g(""), [I, v] = g("Ready"), [k, E] = g(!1), [U, be] = g(!1), [y, Ie] = g([]), [Ne, G] = g(""), ce = a(null), [M, B] = g(
718
718
  () => typeof window < "u" ? window.matchMedia("(max-width: 480px)").matches : !1
719
719
  );
720
720
  $(() => {
@@ -725,7 +725,7 @@ const Sn = ({
725
725
  a([]);
726
726
  const $e = a([]), re = a(0), Se = a(0), xe = a(0), Fe = a(0), u = a(!1), [d, s] = g(
727
727
  null
728
- ), r = a(null), [m, z] = g("neutral"), [K, Xe] = g(""), [Ke, Me] = g(""), [Ze, ke] = g("Chat with us"), [ee, Ae] = g(
728
+ ), r = a(null), [m, z] = g("neutral"), [X, Ke] = g(""), [Xe, Me] = g(""), [Ze, ke] = g("Chat with us"), [ee, Ae] = g(
729
729
  null
730
730
  ), [_e, we] = g("hidden"), [Re, Ue] = g(""), J = a(null), ie = a(_e);
731
731
  ie.current = _e;
@@ -788,7 +788,7 @@ const Sn = ({
788
788
  }
789
789
  if (e.expression != null) {
790
790
  const n = String(e.expression).trim();
791
- Xe(n);
791
+ Ke(n);
792
792
  const c = un.find(
793
793
  (h) => h.name.toLowerCase() === n.toLowerCase()
794
794
  );
@@ -1104,7 +1104,7 @@ const Sn = ({
1104
1104
  const t = await e.arrayBuffer(), o = await new (window.AudioContext || window.webkitAudioContext)().decodeAudioData(t), n = jt(o), c = new FileReader();
1105
1105
  c.readAsDataURL(n), c.onloadend = async () => {
1106
1106
  const h = c.result.split(",")[1];
1107
- Ge(), X(""), pe.current = "", Ce.current = !1;
1107
+ Ge(), K(""), pe.current = "", Ce.current = !1;
1108
1108
  const w = `${ut}/stt?token=${encodeURIComponent(
1109
1109
  O
1110
1110
  )}`, A = await fetch(w, {
@@ -1121,7 +1121,7 @@ const Sn = ({
1121
1121
  V("[STT] 429 agent at capacity:", C?.detail);
1122
1122
  } catch {
1123
1123
  }
1124
- X(""), v("Busy"), E(!1);
1124
+ K(""), v("Busy"), E(!1);
1125
1125
  return;
1126
1126
  }
1127
1127
  if (!A.ok) {
@@ -1146,7 +1146,7 @@ const Sn = ({
1146
1146
  const F = async (se, C) => {
1147
1147
  switch (se) {
1148
1148
  case "transcript":
1149
- C.transcript != null && X(String(C.transcript));
1149
+ C.transcript != null && K(String(C.transcript));
1150
1150
  break;
1151
1151
  case "text": {
1152
1152
  const oe = C.delta ?? C.text ?? "";
@@ -1231,7 +1231,7 @@ const Sn = ({
1231
1231
  { role: "user", content: he || "..." },
1232
1232
  { role: "assistant", content: o }
1233
1233
  ];
1234
- Bt(n), $e.current = [...x.current], v("Ready"), E(!1), X("");
1234
+ Bt(n), $e.current = [...x.current], v("Ready"), E(!1), K("");
1235
1235
  break;
1236
1236
  }
1237
1237
  case "error": {
@@ -1271,7 +1271,7 @@ const Sn = ({
1271
1271
  V("[CHAT] 429 agent at capacity:", L?.detail);
1272
1272
  } catch {
1273
1273
  }
1274
- X(""), v("Busy"), E(!1);
1274
+ K(""), v("Busy"), E(!1);
1275
1275
  return;
1276
1276
  }
1277
1277
  if (!c.ok)
@@ -1304,7 +1304,7 @@ const Sn = ({
1304
1304
  const Z = ze(R.trim());
1305
1305
  Z && At(Z.event, Z.data);
1306
1306
  }
1307
- v("Ready"), E(!1), X("");
1307
+ v("Ready"), E(!1), K("");
1308
1308
  break;
1309
1309
  }
1310
1310
  }
@@ -1493,7 +1493,7 @@ const Sn = ({
1493
1493
  id: "avatar-text-input",
1494
1494
  type: "text",
1495
1495
  value: he,
1496
- onChange: (e) => X(e.target.value),
1496
+ onChange: (e) => K(e.target.value),
1497
1497
  placeholder: I === "Busy" ? "Assisting another user" : Ne || "Ask me anything",
1498
1498
  disabled: k || I === "Busy",
1499
1499
  autoComplete: "off",
@@ -1613,7 +1613,7 @@ const Sn = ({
1613
1613
  className: "avatar-canvas-layer",
1614
1614
  style: { width: j, height: j },
1615
1615
  children: /* @__PURE__ */ ae(
1616
- Xt,
1616
+ Kt,
1617
1617
  {
1618
1618
  shadows: !0,
1619
1619
  camera: { position: [0.2, 1.4, 3], fov: 42 },
@@ -1635,13 +1635,13 @@ const Sn = ({
1635
1635
  responseAudioStartTimeRef: re,
1636
1636
  adjustments: fn,
1637
1637
  mood: m,
1638
- expression: K,
1638
+ expression: X,
1639
1639
  agentResponse: D,
1640
1640
  isSpeaking: U,
1641
1641
  nextStartTimeRef: Se,
1642
1642
  stopPlayback: Ge,
1643
1643
  setIsSpeaking: be,
1644
- expressionUrl: Ke,
1644
+ expressionUrl: Xe,
1645
1645
  onExpressionFinished: Ut,
1646
1646
  isNudgeResponse: nt,
1647
1647
  avatarGender: p