@characterxyz/widget 0.0.0-stage → 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Charky Labs Pvt Ltd
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md CHANGED
@@ -1,3 +1,75 @@
1
- # Temporary Holding Version
1
+ # @characterxyz/widget
2
2
 
3
- This version is a temporary placeholder for this package. An operational version to replace this has been submitted for review and is awaiting a staged release.
3
+ Put your Character XYZ agent on any website: the character in the corner, text chat that streams,
4
+ and real-time voice calls with a fair queue when every line is busy. One Web Component in a Shadow
5
+ DOM, so it works in plain HTML, React, Vue, Svelte, Angular or anything else, and nothing of your
6
+ page's CSS leaks in or out. 28 KB gzipped, everything included; it starts once the page is idle.
7
+
8
+ Create a publishable key, choose the sites it may run on and pick the look in
9
+ **Character XYZ › Settings › Developers**.
10
+
11
+ ## Script tag (no build step)
12
+
13
+ ```html
14
+ <script src="https://unpkg.com/@characterxyz/widget@0/dist/cx.js" data-key="cxyz_pk_live_…" async></script>
15
+ ```
16
+
17
+ Settings go on the tag as `data-*` attributes: `data-display="full"`, `data-accent="#e11d48"`,
18
+ `data-position="bottom-left"`, `data-mode="dark"`, `data-show-call="false"`, `data-agent="agent_…"`.
19
+ Drive it from your own buttons with `CharacterXYZ.open('chat')` or `CharacterXYZ.open('call')`.
20
+
21
+ ## npm
22
+
23
+ ```bash
24
+ npm install @characterxyz/widget
25
+ ```
26
+
27
+ ```ts
28
+ import { mount } from '@characterxyz/widget';
29
+
30
+ const widget = mount({ publishableKey: 'cxyz_pk_live_…', accent: '#e11d48' });
31
+ widget.open('chat'); // or 'call'; widget.close(); widget.destroy()
32
+ ```
33
+
34
+ Using React or Next.js? Install [`@characterxyz/react`](https://www.npmjs.com/package/@characterxyz/react)
35
+ instead; it includes this package.
36
+
37
+ ## Settings
38
+
39
+ The defaults come from the key (set on the Embed page); anything passed here overrides them for this site.
40
+
41
+ | Setting | Values |
42
+ |---|---|
43
+ | `agentId` | Which of the key's agents. Default: the key's first |
44
+ | `display` | `bubble` · `half` · `full` (how much of her shows) |
45
+ | `launcher`, `position` | Launcher style; `bottom-right` · `bottom-left` |
46
+ | `accent`, `mode`, `radius`, `font` | Colour, `auto` · `light` · `dark`, corner radius, font family |
47
+ | `showChat`, `showCall`, `branding` | Turn chat, calls or the footer off |
48
+ | `offsetX`, `offsetY`, `zIndex`, `container` | Placement |
49
+
50
+ What the agent says (persona, knowledge, greeting) is the agent's own, set in Character XYZ.
51
+
52
+ ## Styling
53
+
54
+ CSS tokens on the element: `character-xyz { --cx-accent: …; --cx-font: …; --cx-radius: … }`. Parts:
55
+ `::part(launcher | presence | actions | panel | header | composer | banner | message | message-agent | message-visitor | greeting)`.
56
+
57
+ ## Events
58
+
59
+ The element fires bubbling events: `cx-ready`, `cx-open`, `cx-close`, `cx-call` (`{phase, position, endReason}`) and `cx-error`.
60
+
61
+ ## Signed-in visitors
62
+
63
+ Mint the session on your server with [`@characterxyz/server`](https://www.npmjs.com/package/@characterxyz/server),
64
+ then: `mount({ getSessionToken: () => fetch('/api/characterxyz/session').then((r) => r.json()) })`.
65
+ Their chat history then follows them across devices.
66
+
67
+ ## Security
68
+
69
+ A publishable key (`cxyz_pk_…`) is public by design: it works only from the sites listed on it and
70
+ exchanges for a 15-minute session bound to that site. Never put a secret key (`cxyz_sk_…`) in a page;
71
+ the SDK refuses to run with one.
72
+
73
+ ## License
74
+
75
+ MIT
package/dist/cx.js ADDED
@@ -0,0 +1,356 @@
1
+ "use strict";var CharacterXYZWidget=(()=>{var ge=Object.defineProperty;var vn=Object.getOwnPropertyDescriptor;var yn=Object.getOwnPropertyNames;var kn=Object.prototype.hasOwnProperty;var wn=(t,e,n)=>e in t?ge(t,e,{enumerable:!0,configurable:!0,writable:!0,value:n}):t[e]=n;var Cn=(t,e)=>{for(var n in e)ge(t,n,{get:e[n],enumerable:!0})},Sn=(t,e,n,i)=>{if(e&&typeof e=="object"||typeof e=="function")for(let a of yn(e))!kn.call(t,a)&&a!==n&&ge(t,a,{get:()=>e[a],enumerable:!(i=vn(e,a))||i.enumerable});return t};var An=t=>Sn(ge({},"__esModule",{value:!0}),t);var Y=(t,e,n)=>wn(t,typeof e!="symbol"?e+"":e,n);var Ci={};Cn(Ci,{mount:()=>Le});var ae={position:"bottom-right",mode:"auto",launcher:"bubble",display:"bubble",accent:"#7c5cff",radius:24,font:"",subtitle:null,greeting:"",greetingDelay:3,suggestions:[],placeholder:"Message",showChat:!0,showCall:!0,branding:!0,offsetX:20,offsetY:20,zIndex:2147483e3,open:!1,face:!0,faceUrl:"https://www.character.xyz/embed/face"},ne=(t,e,n)=>{let i=typeof t=="number"?t:typeof t=="string"&&t.trim()!==""?Number(t):NaN;return Number.isFinite(i)?Math.min(n,Math.max(e,i)):void 0},ie=t=>{if(typeof t=="boolean")return t;if(t==="true"||t===""||t==="1")return!0;if(t==="false"||t==="0")return!1},We=(t,e=200)=>typeof t=="string"?t.slice(0,e):void 0;function Mn(t){if(typeof t!="string")return;let e=t.trim();if(/^#([0-9a-f]{3,4}|[0-9a-f]{6}|[0-9a-f]{8})$/i.test(e)||/^(rgb|rgba|hsl|hsla|oklch|oklab)\([0-9.,%\s/+-]+\)$/i.test(e)||/^[a-z]{3,20}$/i.test(e))return e}function Tn(t){if(typeof t!="string")return;let e=t.trim();return/^[\w\s,"'-]{1,120}$/.test(e)?e:void 0}function J(t,e){if(!e||typeof e!="object")return t;let n={...t};return(e.position==="bottom-left"||e.position==="bottom-right")&&(n.position=e.position),(e.mode==="light"||e.mode==="dark"||e.mode==="auto")&&(n.mode=e.mode),(e.launcher==="bubble"||e.launcher==="actions")&&(n.launcher=e.launcher),(e.display==="bubble"||e.display==="half"||e.display==="full")&&(n.display=e.display),n.accent=Mn(e.accent)??n.accent,n.radius=ne(e.radius,0,40)??n.radius,n.font=Tn(e.font)??n.font,e.subtitle===null?n.subtitle=null:n.subtitle=We(e.subtitle,80)??n.subtitle,n.greeting=We(e.greeting,160)??n.greeting,n.greetingDelay=ne(e.greetingDelay,0,120)??n.greetingDelay,Array.isArray(e.suggestions)?n.suggestions=e.suggestions.filter(i=>typeof i=="string"&&i.trim()!=="").map(i=>i.slice(0,80)).slice(0,4):typeof e.suggestions=="string"&&(n.suggestions=e.suggestions.split("|").map(i=>i.trim()).filter(Boolean).slice(0,4)),n.placeholder=We(e.placeholder,60)??n.placeholder,n.showChat=ie(e.showChat)??n.showChat,n.showCall=ie(e.showCall)??n.showCall,n.branding=ie(e.branding)??n.branding,n.offsetX=ne(e.offsetX,0,200)??n.offsetX,n.offsetY=ne(e.offsetY,0,200)??n.offsetY,n.zIndex=ne(e.zIndex,0,2147483647)??n.zIndex,n.open=ie(e.open)??n.open,n.face=ie(e.face)??n.face,typeof e.faceUrl=="string"&&/^https?:\/\/[^\s"'<>]+$/.test(e.faceUrl.trim())&&(n.faceUrl=e.faceUrl.trim()),n}function me(t){let e={};for(let{name:n,value:i}of t){let a=n.replace(/^data-/,"").replace(/-([a-z])/g,(r,o)=>o.toUpperCase());e[a]=i}return e}var In=Object.defineProperty,En=(t,e,n)=>e in t?In(t,e,{enumerable:!0,configurable:!0,writable:!0,value:n}):t[e]=n,b=(t,e,n)=>En(t,typeof e!="symbol"?e+"":e,n),Z=null;function lt(){return(!Z||Z.state==="closed")&&(Z=new AudioContext({latencyHint:"interactive"})),Z.state==="suspended"&&Z.resume().catch(()=>{}),Z}var zn=class{constructor(t={}){b(this,"opts",t),b(this,"ctx"),b(this,"gain"),b(this,"analyser"),b(this,"data"),b(this,"nextAt",0),b(this,"started",!1),b(this,"ended",!1),b(this,"finishing",!1),b(this,"sources",new Set),b(this,"startedAt",0),b(this,"sampleRate"),this.ctx=lt(),this.sampleRate=t.sampleRate??16e3,this.gain=this.ctx.createGain(),this.gain.gain.value=t.volume??1,this.analyser=this.ctx.createAnalyser(),this.analyser.fftSize=512,this.data=new Uint8Array(new ArrayBuffer(this.analyser.fftSize)),this.gain.connect(this.analyser).connect(this.ctx.destination)}enqueue(t){if(this.ended||t.byteLength<2)return;let e=Math.floor(t.byteLength/2),n=new DataView(t.buffer,t.byteOffset,e*2),i=this.ctx.createBuffer(1,e,this.sampleRate),a=i.getChannelData(0);for(let l=0;l<e;l++)a[l]=n.getInt16(l*2,!0)/32768;let r=this.ctx.createBufferSource();r.buffer=i,r.connect(this.gain);let o=this.ctx.currentTime;if(this.nextAt<o&&(this.nextAt=o+(this.started?.02:.12)),r.start(this.nextAt),!this.started){this.started=!0;let l=Math.max(0,(this.nextAt-o)*1e3);this.startedAt=performance.now()+l,setTimeout(()=>this.opts.onStart?.(),l)}this.nextAt+=i.duration,this.sources.add(r),r.onended=()=>{this.sources.delete(r),this.finishing&&this.sources.size===0&&this.finish()}}end(){this.finishing=!0,this.sources.size===0&&this.finish()}stop(){this.ended=!0;for(let t of this.sources)try{t.stop()}catch{}this.sources.clear(),this.gain.disconnect()}playedMs(){return this.started?Math.max(0,performance.now()-this.startedAt):0}level(){this.analyser.getByteTimeDomainData(this.data);let t=0;for(let e=0;e<this.data.length;e++){let n=(this.data[e]-128)/128;t+=n*n}return Math.min(1,Math.sqrt(t/this.data.length)*3)}finish(){this.ended||(this.ended=!0,this.gain.disconnect(),this.opts.onEnd?.())}},$n=`
2
+ class CxyzMic extends AudioWorkletProcessor {
3
+ constructor(o) {
4
+ super();
5
+ this.ratio = sampleRate / 16000;
6
+ this.pos = 0;
7
+ this.lp = 0;
8
+ this.alpha = Math.min(1, 2 * Math.PI * 7000 / sampleRate / (1 + 2 * Math.PI * 7000 / sampleRate));
9
+ this.out = new Int16Array(480);
10
+ this.n = 0;
11
+ }
12
+ process(inputs) {
13
+ const ch = inputs[0] && inputs[0][0];
14
+ if (!ch) return true;
15
+ for (let i = 0; i < ch.length; i++) {
16
+ this.lp += this.alpha * (ch[i] - this.lp);
17
+ this.pos += 1;
18
+ if (this.pos >= this.ratio) {
19
+ this.pos -= this.ratio;
20
+ const s = Math.max(-1, Math.min(1, this.lp));
21
+ this.out[this.n++] = s < 0 ? s * 0x8000 : s * 0x7fff;
22
+ if (this.n === 480) {
23
+ this.port.postMessage(this.out.buffer, [this.out.buffer]);
24
+ this.out = new Int16Array(480);
25
+ this.n = 0;
26
+ }
27
+ }
28
+ }
29
+ return true;
30
+ }
31
+ }
32
+ registerProcessor('cxyz-mic', CxyzMic);
33
+ `;function Un(t){let e=new Int16Array(t);if(!e.length)return 0;let n=0;for(let i=0;i<e.length;i++){let a=e[i]/32768;n+=a*a}return Math.sqrt(n/e.length)}async function Ln(t){if(!navigator.mediaDevices?.getUserMedia)throw new Error("This browser cannot use a microphone here.");let e=await navigator.mediaDevices.getUserMedia({audio:{deviceId:t.deviceId?{exact:t.deviceId}:void 0,channelCount:1,echoCancellation:!0,noiseSuppression:!0,autoGainControl:!0}}),n=new AudioContext({latencyHint:"interactive"}),i=n.createMediaStreamSource(e),a=!1,r=d=>{if(a){t.onFrame(new ArrayBuffer(d.byteLength),0);return}t.onFrame(d,Un(d))},o,l;try{let d=URL.createObjectURL(new Blob([$n],{type:"application/javascript"}));try{await n.audioWorklet.addModule(d)}finally{URL.revokeObjectURL(d)}let p=new AudioWorkletNode(n,"cxyz-mic");p.port.onmessage=m=>r(m.data),o=p,l=()=>{p.port.onmessage=null}}catch{let d=n.createScriptProcessor(4096,1,1),p=n.sampleRate/16e3,m=0,c=new Int16Array(480),h=0;d.onaudioprocess=_=>{let v=_.inputBuffer.getChannelData(0);for(let g=0;g<v.length;g++)if(m+=1,m>=p){m-=p;let x=Math.max(-1,Math.min(1,v[g]));c[h++]=x<0?x*32768:x*32767,h===480&&(r(c.buffer),c=new Int16Array(480),h=0)}},o=d,l=()=>{d.onaudioprocess=null}}i.connect(o);let u=n.createGain();return u.gain.value=0,o.connect(u).connect(n.destination),n.state==="suspended"&&await n.resume().catch(()=>{}),{get muted(){return a},setMuted(d){a=d;for(let p of e.getAudioTracks())p.enabled=!d},stop(){l();try{i.disconnect(),o.disconnect()}catch{}for(let d of e.getTracks())d.stop();n.close().catch(()=>{})}}}var Ye=class{constructor(){b(this,"handlers",{})}on(t,e){var n;return((n=this.handlers)[t]??(n[t]=new Set)).add(e),()=>this.handlers[t]?.delete(e)}emit(t,e){for(let n of this.handlers[t]??[])try{n(e)}catch(i){console.error("[characterxyz] listener threw",i)}}clear(){this.handlers={}}},L=class extends Error{constructor(t,e,n=0){super(e),b(this,"code"),b(this,"status"),this.name="CxError",this.code=t,this.status=n}};function Rn(t){switch(t){case 401:return"unauthorized";case 403:return"forbidden";case 404:return"not_found";case 402:return"payment_required";case 422:return"invalid";case 429:return"rate_limited";case 503:return"unavailable";default:return"unknown"}}async function Pn(t){let e="";try{let n=await t.json();typeof n?.message=="string"&&(e=n.message)}catch{}return new L(Rn(t.status),e||`Request failed (${t.status})`,t.status)}async function _e(t,e,n={}){let i={};n.body!==void 0&&(i["Content-Type"]="application/json"),n.token&&(i.Authorization=`Bearer ${n.token}`);let a;try{a=await fetch(t+e,{method:n.method??(n.body===void 0?"GET":"POST"),headers:i,body:n.body===void 0?void 0:JSON.stringify(n.body),signal:n.signal,credentials:"omit",cache:"no-store"})}catch(r){throw r?.name==="AbortError"?r:new L("network","Could not reach Character XYZ. Check your connection.")}if(!a.ok)throw await Pn(a);return a}async function re(t,e,n={}){return(await(await _e(t,e,n)).json()).data}async function ct(t,e,n){let i=t.body;if(!i)return;let a=i.getReader(),r=new TextDecoder,o="",l=()=>{a.cancel().catch(()=>{})};n?.addEventListener("abort",l);try{for(;;){let{value:u,done:d}=await a.read();if(d)break;o+=r.decode(u,{stream:!0}),o=st(o,e)}o+=r.decode(),st(o+`
34
+
35
+ `,e)}finally{n?.removeEventListener("abort",l)}}function st(t,e){let n=t.replace(/\r\n/g,`
36
+ `),i;for(;(i=n.indexOf(`
37
+
38
+ `))!==-1;){let a=n.slice(0,i);n=n.slice(i+2);let r="message",o=[];for(let d of a.split(`
39
+ `)){if(!d||d.startsWith(":"))continue;let p=d.indexOf(":"),m=p===-1?d:d.slice(0,p),c=p===-1?"":d.slice(p+1).replace(/^ /,"");m==="event"?r=c:m==="data"&&o.push(c)}if(!o.length)continue;let l=o.join(`
40
+ `),u=l;try{u=JSON.parse(l)}catch{}e({event:r,data:u})}return n}function Fn(t){if(t.byteLength<25)return null;let e=new DataView(t);if(e.getUint8(0)!==67||e.getUint8(1)!==88||e.getUint8(2)!==89||e.getUint8(3)!==90||e.getUint8(4)!==1)return null;let n=e.getUint8(5),i=(e.getUint8(6)&1)!==0,a=7,r=e.getUint16(a,!0);if(a+=2,a+r+20>t.byteLength)return null;let o=new TextDecoder().decode(new Uint8Array(t,a,r));a+=r+4+8+4;let l=e.getUint32(a,!0);return a+=4,a+l>t.byteLength?null:{kind:n,final:i,corr:o,payload:new Uint8Array(t,a,l)}}var Dn=.09,On=350,Hn=25e3,Wn=()=>({phase:"idle",callId:null,position:null,etaSeconds:null,holdSeconds:null,maxSeconds:null,startedAt:null,endReason:null,muted:!1,speaking:!1,agentState:"idle",error:null}),Yn=class extends Ye{constructor(t,e,n,i={}){super(),b(this,"apiUrl",t),b(this,"session",e),b(this,"agentId",n),b(this,"opts",i),b(this,"s",Wn()),b(this,"ticket",null),b(this,"eventsAbort",null),b(this,"ws",null),b(this,"mic",null),b(this,"players",new Map),b(this,"sampleRates",new Map),b(this,"cancelled",new Set),b(this,"speakingCorr",null),b(this,"heartbeat",null),b(this,"loudSince",null)}get state(){return this.s}audible(){let t=this.speakingCorr,e=t?this.players.get(t):void 0;return t&&e?{corr:t,ms:e.playedMs()}:null}voiceLevel(){let t=this.speakingCorr?this.players.get(this.speakingCorr):void 0;return t?t.level():0}set(t){this.s={...this.s,...t},this.emit("state",this.s)}async start(){if(this.s.phase==="idle"){this.set({phase:"joining"}),lt();try{this.mic=await Ln({deviceId:this.opts.deviceId,onFrame:(t,e)=>this.onMicFrame(t,e)})}catch{this.finish("mic-denied","Allow the microphone to talk, or chat instead.");return}try{let t=await this.session.token(),e=await re(this.apiUrl,"/sdk/v1/calls",{method:"POST",body:{},token:t});this.set({callId:e.callId,phase:e.state==="ready"?"joining":"queued",position:e.position??null,etaSeconds:e.etaSeconds??null}),this.follow()}catch(t){let e=t instanceof L?t:new L("unknown","Could not start the call."),n=e.code==="rate_limited"?"busy":"unavailable";this.finish(n,e.message),this.emit("error",e)}}}async follow(){let t=0;for(;this.s.callId&&this.s.phase!=="ended"&&this.s.phase!=="idle";){this.eventsAbort=new AbortController;try{let e=await this.session.token(),n=await _e(this.apiUrl,`/sdk/v1/calls/${encodeURIComponent(this.s.callId)}/events`,{token:e,signal:this.eventsAbort.signal});t=0,await ct(n,i=>this.onServerEvent(i.event,i.data),this.eventsAbort.signal)}catch(e){if(e?.name==="AbortError")return;if(e instanceof L&&e.code==="not_found"){this.finish("failed","The call ended.");return}if(t+=1,t>5){this.finish("failed","Lost the connection to the call.");return}}if(this.ended())return;await new Promise(e=>setTimeout(e,Math.min(4e3,500*2**t)))}}onServerEvent(t,e){switch(t){case"queued":(this.s.phase==="joining"||this.s.phase==="queued")&&this.set({phase:"queued",position:Number(e.position)||1,etaSeconds:Number(e.etaSeconds)||null});break;case"ready":{typeof e.ticket=="string"&&e.ticket&&(this.ticket=e.ticket);let n=Number(e.holdSeconds)||0;this.s.phase!=="ready"&&this.s.phase!=="connecting"&&this.s.phase!=="live"?(this.set({phase:"ready",holdSeconds:n,position:null,etaSeconds:null}),this.emit("ready",{holdSeconds:n}),this.opts.autoAccept!==!1&&this.accept()):this.s.phase==="ready"&&this.set({holdSeconds:n});break}case"live":this.set({phase:"live",maxSeconds:Number(e.maxSeconds)||null,startedAt:this.s.startedAt??Date.now()-(Number(e.elapsedSeconds)||0)*1e3});break;case"ended":this.finish(String(e.reason||"hangup")||"hangup",null);break}}ended(){return this.s.phase==="ended"}accept(){if(this.s.phase!=="ready"||!this.ticket||this.ws)return;this.set({phase:"connecting"});let t=this.apiUrl.replace(/^http/,"ws")+"/sdk/v1/calls/socket",e=new WebSocket(t,[`cxyz-ticket.${this.ticket}`]);this.ticket=null,e.binaryType="arraybuffer",this.ws=e,e.onopen=()=>{let n=this.opts.face,i=n?.emotion?.()??null;e.send(JSON.stringify({type:"agent_identity",agent_id:this.agentId,skin_index:0,blendshapes:!!n,...n?{blendshape_stream:!0}:{},...n&&i?{face_emotion:i}:{}})),e.send(JSON.stringify({type:"mic_state",silero:"off",denoise:!1})),this.heartbeat=setInterval(()=>this.sendJson({type:"heartbeat"}),Hn),this.set({phase:"live",startedAt:this.s.startedAt??Date.now()})},e.onmessage=n=>this.onSocket(n.data),e.onclose=()=>{this.ws=null,setTimeout(()=>{(this.s.phase==="live"||this.s.phase==="connecting")&&this.finish("hangup",null)},1500)}}sendJson(t){this.ws?.readyState===WebSocket.OPEN&&this.ws.send(JSON.stringify(t))}onMicFrame(t,e){let n=this.ws;if(!(!n||n.readyState!==WebSocket.OPEN)){if(this.speakingCorr){let i=performance.now();if(e>Dn){if(this.loudSince??(this.loudSince=i),i-this.loudSince>=On){this.loudSince=null,this.interrupt(),n.send(t);return}}else this.loudSince=null;n.send(new ArrayBuffer(t.byteLength));return}n.send(t)}}onSocket(t){if(t instanceof ArrayBuffer){let n=Fn(t);if(!n||this.cancelled.has(n.corr))return;if(n.kind===3){this.opts.face&&this.emit("face",{corr:n.corr,payload:n.payload.slice()});return}if(n.kind!==1)return;let i=this.players.get(n.corr);if(!i){for(let[r,o]of this.players)o.stop(),this.players.delete(r);let a=n.corr;i=new zn({sampleRate:this.sampleRates.get(a)??16e3,onStart:()=>{this.speakingCorr=a,this.set({speaking:!0}),this.emit("line",{corr:a,event:"audible"}),this.sendJson({type:"playback_started",correlationId:a,timestampMs:Date.now()})},onEnd:()=>{this.players.delete(a),this.speakingCorr===a&&(this.speakingCorr=null),this.set({speaking:!1}),this.emit("line",{corr:a,event:"end"}),this.sendJson({type:"playback_ended",correlationId:a,timestampMs:Date.now(),reason:"natural"}),this.sendJson({type:"speech_ended"})}}),this.players.set(a,i)}i.enqueue(n.payload),n.final&&i.end();return}if(typeof t!="string")return;let e;try{e=JSON.parse(t)}catch{return}if("AgentSpeechMeta"in e){let n=e.AgentSpeechMeta;n?.correlation_id&&n.sample_rate&&this.sampleRates.set(n.correlation_id,n.sample_rate);return}if("InteractorTranscript"in e){let n=e.InteractorTranscript;n?.text&&this.emit("caption",{id:`v:${n.correlation_id}`,role:"visitor",text:n.text});return}if("AgentReplyTranscript"in e){let n=e.AgentReplyTranscript;n?.text&&!this.cancelled.has(n.correlation_id)&&this.emit("caption",{id:`a:${n.correlation_id}`,role:"agent",text:n.text});return}if(e.type==="turn_cancelled"&&typeof e.correlationId=="string"){let n=e.correlationId;this.cancelled.add(n),this.players.get(n)?.stop(),this.players.delete(n),this.emit("line",{corr:n,event:"end"}),this.speakingCorr===n&&(this.speakingCorr=null,this.set({speaking:!1})),this.emit("captionRemoved",`a:${n}`);return}e.kind==="agent_status"&&typeof e.state=="string"&&this.set({agentState:e.state.toLowerCase()})}interrupt(){let t=this.speakingCorr;if(!t)return;let e=this.players.get(t),n=Math.round(e?.playedMs()??0);e?.stop(),this.players.delete(t),this.cancelled.add(t),this.speakingCorr=null,this.set({speaking:!1}),this.emit("line",{corr:t,event:"end"}),this.sendJson({type:"playback_ended",correlationId:t,timestampMs:Date.now(),reason:"interrupted"}),this.sendJson({type:"interrupt",correlationId:t,heardMs:n,timestampMs:Date.now()})}setMuted(t){this.mic?.setMuted(t),this.set({muted:t})}async hangUp(){let t=this.s.callId,e=this.s.phase;if(this.finish(e==="live"?"hangup":"left",null),!!t)try{let n=await this.session.token();await _e(this.apiUrl,`/sdk/v1/calls/${encodeURIComponent(t)}`,{method:"DELETE",token:n})}catch{}}finish(t,e){if(this.s.phase==="ended")return;this.eventsAbort?.abort(),this.eventsAbort=null,this.heartbeat&&clearInterval(this.heartbeat),this.heartbeat=null;for(let i of this.players.values())i.stop();this.players.clear(),this.speakingCorr=null,this.mic?.stop(),this.mic=null;let n=this.ws;this.ws=null,n&&n.readyState<=WebSocket.OPEN&&n.close(1e3),this.ticket=null,this.set({phase:"ended",endReason:t,speaking:!1,holdSeconds:null,error:e})}},Nn=0,ot=t=>`${t}_${Date.now().toString(36)}_${(Nn++).toString(36)}`,qn=class extends Ye{constructor(t,e){super(),b(this,"apiUrl",t),b(this,"session",e),b(this,"list",[]),b(this,"loaded",!1),b(this,"busy",!1),b(this,"abort",null)}get messages(){return this.list}get isBusy(){return this.busy}publish(){this.list=[...this.list],this.emit("messages",this.list)}async load(){if(this.loaded)return this.list;let t=await this.session.token(),e=await re(this.apiUrl,"/sdk/v1/chat/messages?limit=50",{token:t}),n=this.list;return this.list=[...e?.messages??[],...n],this.loaded=!0,this.publish(),this.list}async send(t){let e=t.trim();if(!e)throw new L("invalid","Say something first.");if(this.busy)throw new L("rate_limited","Wait for the reply first.");this.setBusy(!0);let n={id:ot("local"),role:"visitor",text:e,createdAt:new Date().toISOString()},i={id:ot("reply"),role:"agent",text:"",createdAt:new Date().toISOString(),streaming:!0};this.list.push(n,i),this.publish(),this.abort=new AbortController;try{let a=await this.session.token(),r=await _e(this.apiUrl,"/sdk/v1/chat/messages",{method:"POST",body:{text:e},token:a,signal:this.abort.signal}),o=null,l=null;if(await ct(r,({event:d,data:p})=>{let m=p;d==="delta"&&typeof m?.text=="string"?(i.text+=m.text,this.publish()):d==="done"?o={id:String(m.id),role:"agent",text:String(m.text??i.text),createdAt:String(m.createdAt??i.createdAt)}:d==="error"&&(l=typeof m?.message=="string"?m.message:"Something went wrong.")},this.abort.signal),l||!o)throw new L("unknown",l??"The reply was cut off. Try again.");let u=o;return this.replace(i.id,u),u}catch(a){let r=a instanceof L?a:new L("network","The reply was cut off. Try again.");this.list=this.list.filter(l=>l.id!==i.id);let o=this.list.findIndex(l=>l.id===n.id);throw o!==-1&&(this.list[o]={...n,failed:!0}),this.publish(),a?.name!=="AbortError"&&this.emit("error",r),r}finally{this.abort=null,this.setBusy(!1)}}retry(t){let e=this.list.find(n=>n.id===t&&n.failed);if(!e)throw new L("not_found","Nothing to retry.");return this.list=this.list.filter(n=>n.id!==t),this.publish(),this.send(e.text)}stop(){this.abort?.abort()}replace(t,e){let n=this.list.findIndex(i=>i.id===t);n!==-1&&(this.list[n]=e),this.publish()}setBusy(t){this.busy=t,this.emit("busy",t)}},Bn=()=>{let t=new Map;return{get:e=>t.get(e)??null,set:(e,n)=>{t.set(e,n)}}},jn=()=>({get(t){try{return globalThis.localStorage?.getItem(t)??null}catch{return null}},set(t,e){try{globalThis.localStorage?.setItem(t,e)}catch{}}}),Vn=60,Kn=class{constructor(t){if(b(this,"src",t),b(this,"current",null),b(this,"inflight",null),!t.publishableKey&&!t.getSessionToken)throw new L("invalid","Pass a publishableKey, or getSessionToken for sessions your server mints.")}visitorKey(){return`cxyz:visitor:${(this.src.publishableKey??"server").slice(-12)}`}get info(){return this.current}async token(){let t=Date.now()/1e3;return this.current&&this.current.expiresAt-Vn>t?this.current.token:(await this.refresh()).token}refresh(){return this.inflight??(this.inflight=this.mint().finally(()=>{this.inflight=null})),this.inflight}async mint(){let t;if(this.src.getSessionToken){let e=await this.src.getSessionToken();typeof e=="string"?t=await this.describe(e):t=e}else{let e=this.src.store.get(this.visitorKey())??void 0;t=await re(this.src.apiUrl,"/sdk/v1/sessions",{method:"POST",body:{publishableKey:this.src.publishableKey,agentId:this.src.agentId,visitorId:e}}),this.src.store.set(this.visitorKey(),t.visitorId)}return this.current=t,t}async describe(t){return{...await re(this.src.apiUrl,"/sdk/v1/session",{token:t}),token:t}}},Xn="https://api.character.xyz",dt=class ut extends Ye{constructor(e,n,i){super(),b(this,"apiUrl",e),b(this,"session",n),b(this,"info",i),b(this,"chat"),b(this,"currentCall",null),b(this,"destroyed",!1),this.chat=new qn(e,n)}static async init(e){let n=(e.apiUrl??Xn).replace(/\/+$/,"");if(e.publishableKey&&/^cxyz_sk_/.test(e.publishableKey))throw new L("invalid","That is a SECRET key. Never put it in a web page: use a publishable key (cxyz_pk_\u2026). Revoke the secret key now.");let i=e.storage==="memory"?Bn():e.storage&&typeof e.storage=="object"?e.storage:jn(),a=new Kn({apiUrl:n,agentId:e.agentId,publishableKey:e.publishableKey,getSessionToken:e.getSessionToken,store:i}),r=await a.refresh();return new ut(n,a,r)}get agent(){return(this.session.info??this.info).agent}get features(){return(this.session.info??this.info).features}get appearance(){return(this.session.info??this.info).appearance??{}}get visitorId(){return(this.session.info??this.info).visitorId}get mode(){return(this.session.info??this.info).mode}get call(){return this.currentCall&&this.currentCall.state.phase!=="ended"?this.currentCall:null}async videoAvatar(){let e=await this.session.token();return re(this.apiUrl,"/sdk/v1/agent/video-avatar",{token:e})}async startCall(e={}){if(this.destroyed)throw new L("invalid","This client was destroyed.");if(!this.features.call)throw new L("forbidden","Calls are not available on this site.");if(this.call)return this.call;let n=new Yn(this.apiUrl,this.session,this.agent.id,e);return this.currentCall=n,n.on("state",i=>{i.phase==="ended"&&this.currentCall===n&&this.emit("call",null)}),n.on("error",i=>this.emit("error",i)),this.emit("call",n),await n.start(),n}destroy(){this.destroyed=!0,this.currentCall?.hangUp(),this.chat.stop(),this.chat.clear(),this.clear()}};var Se,C,mt,Jn,j,pt,_t,bt,Ne,xe,se,xt,je,qe,Be,Zn,ke={},we=[],Gn=/acit|ex(?:s|g|n|p|$)|rph|grid|ows|mnc|ntw|ine[ch]|zoo|^ord|itera/i,Ae=Array.isArray;function B(t,e){for(var n in e)t[n]=e[n];return t}function Ve(t){t&&t.parentNode&&t.parentNode.removeChild(t)}function Qn(t,e,n){var i,a,r,o={};for(r in e)r=="key"?i=e[r]:r=="ref"?a=e[r]:o[r]=e[r];if(arguments.length>2&&(o.children=arguments.length>3?Se.call(arguments,2):n),typeof t=="function"&&t.defaultProps!=null)for(r in t.defaultProps)o[r]===void 0&&(o[r]=t.defaultProps[r]);return ve(t,o,i,a,null)}function ve(t,e,n,i,a){var r={type:t,props:e,key:n,ref:i,__k:null,__:null,__b:0,__e:null,__c:null,constructor:void 0,__v:a??++mt,__i:-1,__u:0};return a==null&&C.vnode!=null&&C.vnode(r),r}function M(t){return t.children}function ye(t,e){this.props=t,this.context=e}function K(t,e){if(e==null)return t.__?K(t.__,t.__i+1):null;for(var n;e<t.__k.length;e++)if((n=t.__k[e])!=null&&n.__e!=null)return n.__e;return typeof t.type=="function"?K(t):null}function ei(t){if(t.__P&&t.__d){var e=t.__v,n=e.__e,i=[],a=[],r=B({},e);r.__v=e.__v+1,C.vnode&&C.vnode(r),Ke(t.__P,r,e,t.__n,t.__P.namespaceURI,32&e.__u?[n]:null,i,n??K(e),!!(32&e.__u),a),r.__v=e.__v,r.__.__k[r.__i]=r,Ct(i,r,a),e.__e=e.__=null,r.__e!=n&&vt(r)}}function vt(t){if((t=t.__)!=null&&t.__c!=null)return t.__e=t.__c.base=null,t.__k.some(function(e){if(e!=null&&e.__e!=null)return t.__e=t.__c.base=e.__e}),vt(t)}function ht(t){(!t.__d&&(t.__d=!0)&&j.push(t)&&!Ce.__r++||pt!=C.debounceRendering)&&((pt=C.debounceRendering)||_t)(Ce)}function Ce(){try{for(var t,e=1;j.length;)j.length>e&&j.sort(bt),t=j.shift(),e=j.length,ei(t)}finally{j.length=Ce.__r=0}}function yt(t,e,n,i,a,r,o,l,u,d,p){var m,c,h,_,v,g,x=i&&i.__k||we,k=e.length;for(u=ti(n,e,x,u,k),m=0;m<k;m++)(h=n.__k[m])!=null&&(c=h.__i!=-1&&x[h.__i]||ke,h.__i=m,g=Ke(t,h,c,a,r,o,l,u,d,p),_=h.__e,h.ref&&c.ref!=h.ref&&(c.ref&&Xe(c.ref,null,h),p.push(h.ref,h.__c||_,h)),v==null&&_!=null&&(v=_),4&h.__u?(u=kt(h,u,t),c.__e&&(c.__e=null)):typeof h.type=="function"&&g!==void 0?u=g:_&&(u=_.nextSibling),h.__u&=-7);return n.__e=v,u}function ti(t,e,n,i,a){var r,o,l,u,d,p=n.length,m=p,c=0;for(t.__k=new Array(a),r=0;r<a;r++)(o=e[r])!=null&&typeof o!="boolean"&&typeof o!="function"?(typeof o=="string"||typeof o=="number"||typeof o=="bigint"||o.constructor==String?o=t.__k[r]=ve(null,o,null,null,null):Ae(o)?o=t.__k[r]=ve(M,{children:o},null,null,null):o.constructor===void 0&&o.__b>0?o=t.__k[r]=ve(o.type,o.props,o.key,o.ref?o.ref:null,o.__v):t.__k[r]=o,u=r+c,o.__=t,o.__b=t.__b+1,l=null,(d=o.__i=ni(o,n,u,m))!=-1&&(m--,(l=n[d])&&(l.__u|=2)),l==null||l.__v==null?(d==-1&&(a>p?c--:a<p&&c++),typeof o.type!="function"&&(o.__u|=4)):d!=u&&(d==u-1?c--:d==u+1?c++:(d>u?c--:c++,o.__u|=4))):t.__k[r]=null;if(m)for(r=0;r<p;r++)(l=n[r])!=null&&(2&l.__u)==0&&(l.__e==i&&(i=K(l)),At(l,l));return i}function kt(t,e,n){var i,a;if(typeof t.type=="function"){for(i=t.__k,a=0;i&&a<i.length;a++)i[a]&&(i[a].__=t,e=kt(i[a],e,n));return e}t.__e!=e&&(e&&t.type&&!e.parentNode&&(e=K(t)),e=n.insertBefore(t.__e,e||null));do e=e&&e.nextSibling;while(e!=null&&e.nodeType==8);return e}function ni(t,e,n,i){var a,r,o,l=t.key,u=t.type,d=e[n],p=d!=null&&(2&d.__u)==0;if(d===null&&l==null||p&&l==d.key&&u==d.type)return n;if(i>(p?1:0)){for(a=n-1,r=n+1;a>=0||r<e.length;)if((d=e[o=a>=0?a--:r++])!=null&&(2&d.__u)==0&&l==d.key&&u==d.type)return o}return-1}function ft(t,e,n){e[0]=="-"?t.setProperty(e,n??""):t[e]=n==null?"":typeof n!="number"||Gn.test(e)?n:n+"px"}function be(t,e,n,i,a){var r,o;e:if(e=="style")if(typeof n=="string")t.style.cssText=n;else{if(typeof i=="string"&&(t.style.cssText=i=""),i)for(e in i)n&&e in n||ft(t.style,e,"");if(n)for(e in n)i&&n[e]==i[e]||ft(t.style,e,n[e])}else if(e[0]=="o"&&e[1]=="n")r=e!=(e=e.replace(xt,"$1")),o=e.toLowerCase(),e=o in t||e=="onFocusOut"||e=="onFocusIn"?o.slice(2):e.slice(2),t.l||(t.l={}),t.l[e+r]=n,n?i?n[se]=i[se]:(n[se]=je,t.addEventListener(e,r?Be:qe,r)):t.removeEventListener(e,r?Be:qe,r);else{if(a=="http://www.w3.org/2000/svg")e=e.replace(/xlink(H|:h)/,"h").replace(/sName$/,"s");else if(e!="width"&&e!="height"&&e!="href"&&e!="list"&&e!="form"&&e!="tabIndex"&&e!="download"&&e!="rowSpan"&&e!="colSpan"&&e!="role"&&e!="popover"&&e in t)try{t[e]=n??"";break e}catch{}typeof n=="function"||(n==null||n===!1&&e[4]!="-"?t.removeAttribute(e):t.setAttribute(e,e=="popover"&&n==1?"":n))}}function gt(t){return function(e){if(this.l){var n=this.l[e.type+t];if(e[xe]==null)e[xe]=je++;else if(e[xe]<n[se])return;return n(C.event?C.event(e):e)}}}function Ke(t,e,n,i,a,r,o,l,u,d){var p,m,c,h,_,v,g,x,k,E,P,F,O,$,D,W,y=e.type;if(e.constructor!==void 0)return null;128&n.__u&&(u=!!(32&n.__u),r=[l=e.__e=n.__e]),(p=C.__b)&&p(e);e:if(typeof y=="function"){m=o.length;try{if(k=e.props,E=y.prototype&&y.prototype.render,P=(p=y.contextType)&&i[p.__c],F=p?P?P.props.value:p.__:i,n.__c?x=(c=e.__c=n.__c).__=c.__E:(E?e.__c=c=new y(k,F):(e.__c=c=new ye(k,F),c.constructor=y,c.render=ai),P&&P.sub(c),c.state||(c.state={}),c.__n=i,h=c.__d=!0,c.__h=[],c._sb=[]),E&&c.__s==null&&(c.__s=c.state),E&&y.getDerivedStateFromProps!=null&&(c.__s==c.state&&(c.__s=B({},c.__s)),B(c.__s,y.getDerivedStateFromProps(k,c.__s))),_=c.props,v=c.state,c.__v=e,h)E&&y.getDerivedStateFromProps==null&&c.componentWillMount!=null&&c.componentWillMount(),E&&c.componentDidMount!=null&&c.__h.push(c.componentDidMount);else{if(E&&y.getDerivedStateFromProps==null&&k!==_&&c.componentWillReceiveProps!=null&&c.componentWillReceiveProps(k,F),e.__v==n.__v||!c.__e&&c.shouldComponentUpdate!=null&&c.shouldComponentUpdate(k,c.__s,F)===!1){e.__v!=n.__v&&(c.props=k,c.state=c.__s,c.__d=!1),e.__e=n.__e,e.__k=n.__k,e.__k.some(function(R){R&&(R.__=e)}),we.push.apply(c.__h,c._sb),c._sb=[],c.__h.length&&o.push(c),l=K(n);break e}c.componentWillUpdate!=null&&c.componentWillUpdate(k,c.__s,F),E&&c.componentDidUpdate!=null&&c.__h.push(function(){c.componentDidUpdate(_,v,g)})}if(c.context=F,c.props=k,c.__P=t,c.__e=!1,O=C.__r,$=0,E)c.state=c.__s,c.__d=!1,O&&O(e),p=c.render(c.props,c.state,c.context),we.push.apply(c.__h,c._sb),c._sb=[];else do c.__d=!1,O&&O(e),p=c.render(c.props,c.state,c.context),c.state=c.__s;while(c.__d&&++$<25);c.state=c.__s,c.getChildContext!=null&&(i=B(B({},i),c.getChildContext())),E&&!h&&c.getSnapshotBeforeUpdate!=null&&(g=c.getSnapshotBeforeUpdate(_,v)),D=p!=null&&p.type===M&&p.key==null?St(p.props.children):p,l=yt(t,Ae(D)?D:[D],e,n,i,a,r,o,l,u,d),c.base=e.__e,e.__u&=-161,c.__h.length&&o.push(c),x&&(c.__E=c.__=null)}catch(R){if(o.length=m,e.__v=null,u||r!=null){if(R.then){for(e.__u|=u?160:128;l&&l.nodeType==8&&l.nextSibling;)l=l.nextSibling;r!=null&&(r[r.indexOf(l)]=null),e.__e=l}else if(r!=null)for(W=r.length;W--;)Ve(r[W])}else e.__e=n.__e;e.__k==null&&(e.__k=n.__k||[]),R.then||wt(e),C.__e(R,e,n)}}else r==null&&e.__v==n.__v?(e.__k=n.__k,e.__e=n.__e):l=e.__e=ii(n.__e,e,n,i,a,r,o,u,d);return(p=C.diffed)&&p(e),128&e.__u?void 0:l}function wt(t){t&&(t.__c&&(t.__c.__e=!0),t.__k&&t.__k.some(wt))}function Ct(t,e,n){for(var i=0;i<n.length;i++)Xe(n[i],n[++i],n[++i]);C.__c&&C.__c(e,t),t.some(function(a){try{t=a.__h,a.__h=[],t.some(function(r){r.call(a)})}catch(r){C.__e(r,a.__v)}})}function St(t){return typeof t!="object"||t==null||t.__b>0?t:Ae(t)?t.map(St):t.constructor!==void 0?null:B({},t)}function ii(t,e,n,i,a,r,o,l,u){var d,p,m,c,h,_,v,g=n.props||ke,x=e.props,k=e.type;if(k=="svg"?a="http://www.w3.org/2000/svg":k=="math"?a="http://www.w3.org/1998/Math/MathML":a||(a="http://www.w3.org/1999/xhtml"),r!=null){for(d=0;d<r.length;d++)if((h=r[d])&&"setAttribute"in h==!!k&&(k?h.localName==k:h.nodeType==3)){t=h,r[d]=null;break}}if(t==null){if(k==null)return document.createTextNode(x);t=document.createElementNS(a,k,x.is&&x),l&&(C.__m&&C.__m(e,r),l=!1),r=null}if(k==null)g===x||l&&t.data==x||(t.data=x);else{if(r=k=="textarea"&&x.defaultValue!=null?null:r&&Se.call(t.childNodes),!l&&r!=null)for(g={},d=0;d<t.attributes.length;d++)g[(h=t.attributes[d]).name]=h.value;for(d in g)h=g[d],d=="dangerouslySetInnerHTML"?m=h:d=="children"||d in x||d=="value"&&"defaultValue"in x||d=="checked"&&"defaultChecked"in x||be(t,d,null,h,a);for(d in x)h=x[d],d=="children"?c=h:d=="dangerouslySetInnerHTML"?p=h:d=="value"?_=h:d=="checked"?v=h:l&&typeof h!="function"||g[d]===h||be(t,d,h,g[d],a);if(p)l||m&&(p.__html==m.__html||p.__html==t.innerHTML)||(t.innerHTML=p.__html),e.__k=[];else if(m&&(t.innerHTML=""),yt(e.type=="template"?t.content:t,Ae(c)?c:[c],e,n,i,k=="foreignObject"?"http://www.w3.org/1999/xhtml":a,r,o,r?r[0]:n.__k&&K(n,0),l,u),r!=null)for(d=r.length;d--;)Ve(r[d]);l&&k!="textarea"||(d="value",k=="progress"&&_==null?t.removeAttribute("value"):_!=null&&(_!==t[d]||k=="progress"&&!_||k=="option"&&_!=g[d])&&be(t,d,_,g[d],a),d="checked",v!=null&&v!=t[d]&&be(t,d,v,g[d],a))}return t}function Xe(t,e,n){try{if(typeof t=="function"){var i=typeof t.__u=="function";i&&t.__u(),i&&e==null||(t.__u=t(e))}else t.current=e}catch(a){C.__e(a,n)}}function At(t,e,n){var i,a;if(C.unmount&&C.unmount(t),(i=t.ref)&&(i.current&&i.current!=t.__e||Xe(i,null,e)),(i=t.__c)!=null){if(i.componentWillUnmount)try{i.componentWillUnmount()}catch(r){C.__e(r,e)}i.base=i.__P=i.__n=null}if(i=t.__k)for(a=0;a<i.length;a++)i[a]&&At(i[a],e,n||typeof t.type!="function");n||Ve(t.__e),t.__c=t.__=t.__e=void 0}function ai(t,e,n){return this.constructor(t,n)}function Je(t,e,n){var i,a,r,o;e==document&&(e=document.documentElement),C.__&&C.__(t,e),a=(i=typeof n=="function")?null:n&&n.__k||e.__k,r=[],o=[],Ke(e,t=(!i&&n||e).__k=Qn(M,null,[t]),a||ke,ke,e.namespaceURI,!i&&n?[n]:a?null:e.firstChild?Se.call(e.childNodes):null,r,!i&&n?n:a?a.__e:e.firstChild,i,o),Ct(r,t,o),t.props.children=null}Se=we.slice,C={__e:function(t,e,n,i){for(var a,r,o;e=e.__;)if((a=e.__c)&&!a.__)try{if((r=a.constructor)&&r.getDerivedStateFromError!=null&&(a.setState(r.getDerivedStateFromError(t)),o=a.__d),a.componentDidCatch!=null&&(a.componentDidCatch(t,i||{}),o=a.__d),o)return a.__E=a}catch(l){t=l}throw t}},mt=0,Jn=function(t){return t!=null&&t.constructor===void 0},ye.prototype.setState=function(t,e){var n;n=this.__s!=null&&this.__s!=this.state?this.__s:this.__s=B({},this.state),typeof t=="function"&&(t=t(B({},n),this.props)),t&&B(n,t),t!=null&&this.__v&&(e&&this._sb.push(e),ht(this))},ye.prototype.forceUpdate=function(t){this.__v&&(this.__e=!0,t&&this.__h.push(t),ht(this))},ye.prototype.render=M,j=[],_t=typeof Promise=="function"?Promise.prototype.then.bind(Promise.resolve()):setTimeout,bt=function(t,e){return t.__v.__b-e.__v.__b},Ce.__r=0,Ne=Math.random().toString(8),xe="__d"+Ne,se="__a"+Ne,xt=/(PointerCapture)$|Capture$/i,je=0,qe=gt(!1),Be=gt(!0),Zn=0;var G,A,Ze,Mt,oe=0,Rt=[],T=C,Tt=T.__b,It=T.__r,Et=T.diffed,zt=T.__c,$t=T.unmount,Ut=T.__;function Te(t,e){T.__h&&T.__h(A,t,oe||e),oe=0;var n=A.__H||(A.__H={__:[],__h:[]});return t>=n.__.length&&n.__.push({}),n.__[t]}function z(t){return oe=1,ri(Dt,t)}function ri(t,e,n){var i=Te(G++,2);if(i.t=t,!i.__c&&(i.__=[n?n(e):Dt(void 0,e),function(l){var u=i.__N?i.__N[0]:i.__[0],d=i.t(u,l);u!==d&&(i.__N=[d,i.__[1]],i.__c.setState({}))}],i.__c=A,!A.__f)){var a=function(l,u,d){if(!i.__c.__H)return!0;var p=!1,m=i.__c.props!==l;if(i.__c.__H.__.some(function(h){if(h.__N){p=!0;var _=h.__[0];h.__=h.__N,h.__N=void 0,_!==h.__[0]&&(m=!0)}}),r){var c=r.call(this,l,u,d);return p?c||m:c}return!p||m};A.__f=!0;var r=A.shouldComponentUpdate,o=A.componentWillUpdate;A.componentWillUpdate=function(l,u,d){if(this.__e){var p=r;r=void 0,a(l,u,d),r=p}o&&o.call(this,l,u,d)},A.shouldComponentUpdate=a}return i.__N||i.__}function I(t,e){var n=Te(G++,3);!T.__s&&Qe(n.__H,e)&&(n.__=t,n.u=e,A.__H.__h.push(n))}function Pt(t,e){var n=Te(G++,4);!T.__s&&Qe(n.__H,e)&&(n.__=t,n.u=e,A.__h.push(n))}function H(t){return oe=5,Ft(function(){return{current:t}},[])}function Ft(t,e){var n=Te(G++,7);return Qe(n.__H,e)&&(n.__=t(),n.__H=e,n.__h=t),n.__}function Ie(t,e){return oe=8,Ft(function(){return t},e)}function si(){for(var t;t=Rt.shift();){var e=t.__H;if(t.__P&&e)try{e.__h.some(Me),e.__h.some(Ge),e.__h=[]}catch(n){e.__h=[],T.__e(n,t.__v)}}}T.__b=function(t){A=null,Tt&&Tt(t)},T.__=function(t,e){t&&e.__k&&e.__k.__m&&(t.__m=e.__k.__m),Ut&&Ut(t,e)},T.__r=function(t){It&&It(t),G=0;var e=(A=t.__c).__H;e&&(Ze===A?(e.__h=[],A.__h=[],e.__.some(function(n){n.__N&&(n.__=n.__N),n.u=n.__N=void 0})):(e.__h.some(Me),e.__h.some(Ge),e.__h=[],G=0)),Ze=A},T.diffed=function(t){Et&&Et(t);var e=t.__c;e&&e.__H&&(e.__H.__h.length&&(Rt.push(e)!==1&&Mt===T.requestAnimationFrame||((Mt=T.requestAnimationFrame)||oi)(si)),e.__H.__.some(function(n){n.u&&(n.__H=n.u,n.u=void 0)})),Ze=A=null},T.__c=function(t,e){e.some(function(n){try{n.__h.some(Me),n.__h=n.__h.filter(function(i){return!i.__||Ge(i)})}catch(i){e.some(function(a){a.__h&&(a.__h=[])}),e=[],T.__e(i,n.__v)}}),zt&&zt(t,e)},T.unmount=function(t){$t&&$t(t);var e,n=t.__c;n&&n.__H&&(n.__H.__.some(function(i){try{Me(i)}catch(a){e=a}}),n.__H=void 0,e&&T.__e(e,n.__v))};var Lt=typeof requestAnimationFrame=="function";function oi(t){var e,n=function(){clearTimeout(i),Lt&&cancelAnimationFrame(e),setTimeout(t)},i=setTimeout(n,35);Lt&&(e=requestAnimationFrame(n))}function Me(t){var e=A,n=t.__c;typeof n=="function"&&(t.__c=void 0,n()),A=e}function Ge(t){var e=A;t.__c=t.__(),A=e}function Qe(t,e){return!t||t.length!==e.length||e.some(function(n,i){return n!==t[i]})}function Dt(t,e){return typeof e=="function"?e(t):e}function V(t){let e=t%100;if(e>=11&&e<=13)return`${t}th`;switch(t%10){case 1:return`${t}st`;case 2:return`${t}nd`;case 3:return`${t}rd`;default:return`${t}th`}}function Ee(t){if(t==null)return"";if(t<60)return"less than a minute";let e=Math.round(t/60);return e<60?`about ${e} min`:`about ${Math.round(e/60)} hr`}function ze(t){let e=Math.max(0,Math.floor(t)),n=Math.floor(e/3600),i=Math.floor(e%3600/60),a=String(e%60).padStart(2,"0");return n?`${n}:${String(i).padStart(2,"0")}:${a}`:`${i}:${a}`}function Ht(t,e){switch(t){case"hangup":return{title:"Call ended",body:`Thanks for talking with ${e}.`};case"left":return{title:"You left the line",body:"You can call again whenever you like."};case"missed":return{title:"You missed your turn",body:`${e} was ready, but the call wasn't joined in time.`};case"timeout":return{title:"Still busy",body:`Sorry for the wait. ${e} is still on other calls. Chat is open meanwhile.`};case"limit":return{title:"Time is up",body:"This call reached its time limit."};case"busy":return{title:"All lines are busy",body:"Try again in a few minutes, or keep chatting."};case"mic-denied":return{title:"Microphone needed",body:"Allow the microphone in your browser to talk, or keep chatting."};case"credits":case"unavailable":return{title:"Calls are unavailable",body:"Calls are not available right now. Chat is open."};default:return{title:"The call dropped",body:"Something interrupted the call. Try again."}}}function Ot(t){let e=[],n=/(\*\*[^*]+\*\*|`[^`]+`|\[[^\]]+\]\((https?:\/\/[^)\s]+)\)|https?:\/\/[^\s<>()]+[^\s<>().,;:!?'"]|\*[^*\s][^*]*\*)/g,i=0,a;for(;a=n.exec(t);){a.index>i&&e.push({t:"text",v:t.slice(i,a.index)});let r=a[0];r.startsWith("**")?e.push({t:"b",v:r.slice(2,-2)}):r.startsWith("`")?e.push({t:"code",v:r.slice(1,-1)}):r.startsWith("[")?e.push({t:"link",v:r.slice(1,r.indexOf("]")),href:a[2]}):r.startsWith("http")?e.push({t:"link",v:r,href:r}):e.push({t:"i",v:r.slice(1,-1)}),i=a.index+r.length}return i<t.length&&e.push({t:"text",v:t.slice(i)}),e}function Wt(t){let e=[];for(let n of t.split(/\n{2,}/)){let i=n.split(`
41
+ `);i.length&&i.every(a=>/^\s*[-*•]\s+/.test(a))?e.push({t:"ul",items:i.map(a=>Ot(a.replace(/^\s*[-*•]\s+/,"")))}):e.push({t:"p",parts:Ot(n)})}return e}var Yt={cx:.5,cy:.12,span:.06};function Nt(t,e,n){let i=t?.face?.eyes,a=t?.face?.chin;if(!i||!a||!e||!n)return Yt;let r=(i.left.x+i.right.x)/2,o=(i.left.y+i.right.y)/2,l=(a.y-o)/n;return l>.005&&l<.5?{cx:r/e,cy:(o+a.y)/2/n,span:l}:Yt}var $e={faceFraction:.26,at:{x:.5,y:.5}},qt={faceFraction:.14,at:{x:.5,y:.34}},Bt={faceFraction:.16,at:{x:.5,y:.22}},jt={fit:"height"};function Vt(t,e,n,i,a){if("fit"in a){let l=i*e;return{width:l,height:i,left:n/2-t.cx*l,top:0}}let r=i*a.faceFraction/t.span,o=r*e;return{width:o,height:r,left:n*a.at.x-t.cx*o,top:i*a.at.y-t.cy*r}}var li=0;function s(t,e,n,i,a,r){e||(e={});var o,l,u=e;if("ref"in u)for(l in u={},e)l=="ref"?o=e[l]:u[l]=e[l];var d={type:t,props:u,key:n,ref:o,__k:null,__:null,__b:0,__e:null,__c:null,constructor:void 0,__v:--li,__i:-1,__u:0,__source:a,__self:r};if(typeof t=="function"&&(o=t.defaultProps))for(l in o)u[l]===void 0&&(u[l]=o[l]);return C.vnode&&C.vnode(d),d}var N=(t,e)=>s("svg",{width:t,height:t,viewBox:"0 0 24 24",fill:"none",stroke:"currentColor","stroke-width":"1.9","stroke-linecap":"round","stroke-linejoin":"round","aria-hidden":"true",focusable:"false",children:e}),le=({size:t=20})=>N(t,s("path",{d:"M4 5.5A2.5 2.5 0 0 1 6.5 3h11A2.5 2.5 0 0 1 20 5.5v8a2.5 2.5 0 0 1-2.5 2.5H10l-4.2 3.6a.5.5 0 0 1-.8-.4V16h0A2.5 2.5 0 0 1 4 13.5z"})),Q=({size:t=20})=>N(t,s("path",{d:"M5.2 3.5h3l1.6 4.2-2 1.4a12 12 0 0 0 7.1 7.1l1.4-2 4.2 1.6v3a1.7 1.7 0 0 1-1.8 1.7A16.6 16.6 0 0 1 3.5 5.3 1.7 1.7 0 0 1 5.2 3.5z"})),Kt=({size:t=22})=>N(t,s("path",{d:"M3 13.6c5-4.4 13-4.4 18 0l-1.7 2.6-3.6-1.3v-2.6a11 11 0 0 0-7.4 0v2.6l-3.6 1.3z"})),Xt=({size:t=20})=>N(t,s(M,{children:[s("rect",{x:"9",y:"3",width:"6",height:"11",rx:"3"}),s("path",{d:"M5.5 11a6.5 6.5 0 0 0 13 0M12 17.5V21"})]})),Jt=({size:t=20})=>N(t,s(M,{children:[s("path",{d:"M9 9v2a3 3 0 0 0 5.1 2.1M15 9.4V6a3 3 0 0 0-5.7-1.3"}),s("path",{d:"M5.5 11a6.5 6.5 0 0 0 10.6 5M18.4 12.5a6.5 6.5 0 0 0 .1-1.5M12 17.5V21M3 3l18 18"})]})),Ue=({size:t=18})=>N(t,s("path",{d:"M6 6l12 12M18 6L6 18"})),Zt=({size:t=18})=>N(t,s("path",{d:"M12 19V5M5.5 11.5L12 5l6.5 6.5"})),Gt=({size:t=18})=>N(t,s("path",{d:"M15 5l-7 7 7 7"})),Qt=({size:t=14})=>N(t,s("path",{d:"M12 3l1.8 5.2L19 10l-5.2 1.8L12 17l-1.8-5.2L5 10l5.2-1.8z"})),en=({size:t=14})=>N(t,s("path",{d:"M4 12a8 8 0 1 0 2.3-5.6M4 4v4h4"}));var et={current:null};function ci(t){return t?t.speaking?"speaking":t.agentState==="thinking"?"reasoning":t.agentState==="listening"||t.phase==="live"?"listening":"idle":"idle"}function tn({client:t,call:e,state:n,src:i,onStatus:a}){let r=H(null),[o,l]=z(!1),u=H(!1),d=(()=>{try{return new URL(i).origin}catch{return null}})(),p=(c,h)=>{let _=r.current?.contentWindow;_&&d&&_.postMessage({cx:"face",...c},d,h??[])};I(()=>{if(!d){a("unavailable");return}let c=!1,h=v=>{if(v.source!==r.current?.contentWindow||v.origin!==d)return;let g=v.data;g?.cx==="face"&&(g.type==="loaded"?(u.current=!0,l(!0),t.videoAvatar().then(x=>{c||(x?p({type:"init",avatar:x}):a("unavailable"))}).catch(()=>!c&&a("unavailable"))):g.type==="ready"?(et.current=typeof g.faceEmotion=="string"?g.faceEmotion:null,a("ready")):g.type==="unavailable"&&a("unavailable"))};window.addEventListener("message",h);let _=setTimeout(()=>!c&&!u.current&&a("unavailable"),15e3);return()=>{c=!0,clearTimeout(_),window.removeEventListener("message",h)}},[t,d]);let m=ci(n);return I(()=>{o&&p({type:"state",state:m})},[m,o]),I(()=>{if(!e||!o)return;let c=[e.on("face",({corr:v,payload:g})=>p({type:"batch",corr:v,payload:g},[g.buffer])),e.on("line",({corr:v,event:g})=>{p(g==="audible"?{type:"audible",corr:v,ms:e.audible()?.ms??0}:{type:"end",corr:v})})],h=0,_=()=>{let v=e.audible();v&&p({type:"clock",corr:v.corr,ms:v.ms}),h=requestAnimationFrame(_)};return h=requestAnimationFrame(_),()=>{c.forEach(v=>v()),cancelAnimationFrame(h)}},[e,o]),d?s("iframe",{ref:r,class:"face-frame",src:i,title:"","aria-hidden":"true",tabIndex:-1,allow:"autoplay",sandbox:"allow-scripts allow-same-origin",referrerpolicy:"strict-origin"}):null}function di(){if(typeof document>"u")return!1;let t=navigator.userAgent;return/Safari\//.test(t)&&!/(Chrome|Chromium|Edg|OPR|Firefox)\//.test(t)?!1:document.createElement("video").canPlayType('video/webm; codecs="vp9"')!==""}var ui=()=>typeof matchMedia<"u"&&matchMedia("(prefers-reduced-motion: reduce)").matches;function ce({agent:t,shot:e,talking:n=!1,still:i=!1,class:a}){let r=H(null),[o,l]=z({w:0,h:0}),[u,d]=z(null),[p,m]=z({}),c=t.video,h=c?.anchor?.alphaUrl??c?.anchor?.url??null,_=!i&&!ui()&&di(),v=c?.clips.idle?.alphaUrl??null,g=c?.clips.talking?.alphaUrl??v;if(Pt(()=>{let $=r.current;if(!$)return;let D=()=>l({w:$.clientWidth,h:$.clientHeight});if(D(),typeof ResizeObserver>"u")return;let W=new ResizeObserver(D);return W.observe($),()=>W.disconnect()},[]),!c||!h)return s("div",{ref:r,class:`portrait portrait--initial ${a??""}`,"aria-hidden":"true",children:s("span",{children:(t.name||"?").slice(0,1).toUpperCase()})});let x=u?u.w/u.h:.75,k=Nt(c,u?.w??0,u?.h??0),E=o.w&&o.h?Vt(k,x,o.w,o.h,e):null,P=E?{width:`${E.width}px`,height:`${E.height}px`,left:`${E.left}px`,top:`${E.top}px`}:{opacity:0},F=_&&!!v&&!!p.idle,O=_&&!!g&&g!==v&&!!p.talk&&n;return s("div",{ref:r,class:`portrait ${a??""}`,"aria-hidden":"true",children:[s("img",{class:"portrait__media",src:h,alt:"",draggable:!1,style:{...P,opacity:E?F?0:1:0},onLoad:$=>{let D=$.currentTarget;d({w:D.naturalWidth,h:D.naturalHeight})}}),_&&v?s(nn,{src:v,style:P,visible:F&&!O,onReady:()=>m($=>({...$,idle:!0}))}):null,_&&g&&g!==v?s(nn,{src:g,style:P,visible:O,onReady:()=>m($=>({...$,talk:!0}))}):null]})}function nn({src:t,style:e,visible:n,onReady:i}){let a=H(null);return I(()=>{let r=a.current;r&&(n?r.play().catch(()=>{}):r.pause())},[n]),s("video",{ref:a,class:"portrait__media portrait__clip",src:t,muted:!0,loop:!0,playsInline:!0,preload:"auto",style:{...e,opacity:n?1:0},onLoadedData:i})}var tt="cxyz:greeted",an="cxyz:introduced";function de(t,e){try{return e!==void 0&&localStorage.setItem(t,e),localStorage.getItem(t)}catch{return null}}function pi(){try{let t=window.AudioContext??window.webkitAudioContext,e=new t,n=e.currentTime;[660,880].forEach((i,a)=>{let r=e.createOscillator(),o=e.createGain();r.type="sine",r.frequency.value=i,o.gain.setValueAtTime(0,n+a*.16),o.gain.linearRampToValueAtTime(.18,n+a*.16+.02),o.gain.exponentialRampToValueAtTime(1e-4,n+a*.16+.5),r.connect(o).connect(e.destination),r.start(n+a*.16),r.stop(n+a*.16+.55)}),setTimeout(()=>{e.close()},1200)}catch{}}function hi(t){let[e,n]=z(t.chat.messages),[i,a]=z(t.chat.isBusy);return I(()=>{let r=t.chat.on("messages",n),o=t.chat.on("busy",a);return()=>{r(),o()}},[t]),{messages:e,busy:i}}function fi(t){let[e,n]=z(t.call),[i,a]=z(t.call?.state??null),[r,o]=z([]);return I(()=>t.on("call",l=>l&&n(l)),[t]),I(()=>{if(!e)return;a(e.state),o([]);let l=[e.on("state",a),e.on("caption",u=>o(d=>[...d.filter(p=>p.id!==u.id),u].slice(-4))),e.on("captionRemoved",u=>o(d=>d.filter(p=>p.id!==u)))];return()=>l.forEach(u=>u())},[e]),{call:e,state:i,captions:r,reset:()=>n(null)}}function gi(t,e){let[n,i]=z(Date.now());return I(()=>{if(!e)return;let a=setInterval(()=>i(Date.now()),1e3);return()=>clearInterval(a)},[e]),t?Math.max(0,(n-t)/1e3):0}function mi(t,e,n){I(()=>{if(!t||!n)return;let i=0,a=0,r=()=>{let o=t.voiceLevel();a=a*.7+o*.3,e.current?.style.setProperty("--cx-lvl",a.toFixed(3)),i=requestAnimationFrame(r)};return i=requestAnimationFrame(r),()=>cancelAnimationFrame(i)},[t,n,e])}function rn({parts:t}){return s(M,{children:t.map((e,n)=>e.t==="b"?s("strong",{children:e.v},n):e.t==="i"?s("em",{children:e.v},n):e.t==="code"?s("code",{children:e.v},n):e.t==="link"?s("a",{href:e.href,target:"_blank",rel:"noopener noreferrer nofollow",children:e.v},n):e.v.split(`
42
+ `).map((i,a,r)=>s(M,{children:[i,a<r.length-1?s("br",{}):null]},`${n}.${a}`)))})}function _i({text:t}){return s(M,{children:Wt(t).map((e,n)=>e.t==="ul"?s("ul",{children:e.items.map((i,a)=>s("li",{children:s(rn,{parts:i})},a))},n):s("p",{children:s(rn,{parts:e.parts})},n))})}function sn({client:t,config:e,bind:n,onView:i}){let a=t.agent,r=t.features,o=e.showChat&&r.chat,l=e.showCall&&r.call,[u,d]=z(e.open?o?"chat":"call":"closed"),[p,m]=z(!1),[c,h]=z(!1),{messages:_,busy:v}=hi(t),{call:g,state:x,captions:k,reset:E}=fi(t),[P,F]=z(""),O=H(null),$=H(null),D=H(null),W=e.subtitle??a.tagline,y=a.name||"Assistant",R=Ie(f=>{d(f),i(f)},[i]),X=Ie(()=>{m(!0),setTimeout(()=>{m(!1),R("closed")},200)},[R]),q=Ie((f=o?"chat":"call")=>{h(!1),de(tt,"1"),R(f),f==="chat"&&t.chat.load().catch(()=>{})},[o,t,R]);I(()=>n({open:q,close:X}),[n,q,X]),I(()=>{e.open&&o&&t.chat.load().catch(()=>{})},[t,e.open,o]),I(()=>{if(!e.greeting||de(tt))return;let f=setTimeout(()=>h(!0),e.greetingDelay*1e3);return()=>clearTimeout(f)},[e.greeting,e.greetingDelay]);let[Re,un]=z(()=>!de(an));I(()=>{if(!Re)return;let f=setTimeout(()=>{un(!1),de(an,"1")},5e3);return()=>clearTimeout(f)},[Re]),I(()=>{if(u==="closed")return;let f=U=>{U.key==="Escape"&&X()};return window.addEventListener("keydown",f),()=>window.removeEventListener("keydown",f)},[u,X]),I(()=>{let f=O.current;f&&(f.scrollTop=f.scrollHeight)},[_,u,x?.phase]),I(()=>{u==="chat"&&setTimeout(()=>$.current?.focus({preventScroll:!0}),60)},[u]);let ee=e.face&&!!a.video,[pe,pn]=z("loading"),w=x?.phase??"idle";I(()=>{if(!(w!=="ready"||!g)){if(pi(),u==="call"){if(!ee||pe!=="loading"){g.accept();return}let f=setTimeout(()=>g.accept(),3e3);return()=>clearTimeout(f)}if(typeof document<"u"&&document.hidden){let f=document.title;document.title=`\u25CF ${y} is ready for you`;let U=()=>{document.title=f,document.removeEventListener("visibilitychange",U)};document.addEventListener("visibilitychange",U)}}},[w,g,u,y,ee,pe]);let at=w==="live"||w==="connecting";mi(g,D,at&&u==="call");let he=gi(x?.startedAt??null,w==="live"),Pe=bi(g,x?.position??1),fe=async()=>{R("call");try{await t.startCall({autoAccept:!1,...ee?{face:{emotion:()=>et.current}}:{}})}catch{}},Fe=async f=>{let U=f.trim();if(!(!U||v)){F(""),$.current&&($.current.style.height="");try{await t.chat.send(U)}catch{}}},hn=_.length>0&&_[_.length-1].role==="agent"&&_[_.length-1].streaming;if(u==="closed"){let f=w==="queued"||w==="ready"||w==="live"||w==="connecting";return s("div",{class:`dock dock--${e.display}`,part:"launcher",children:[c?s("div",{class:"greeting",part:"greeting",role:"status",onClick:()=>q(),children:[e.greeting,s("button",{class:"greeting__close","aria-label":"Dismiss",onClick:U=>{U.stopPropagation(),h(!1),de(tt,"1")},children:s(Ue,{size:14})})]}):null,s("button",{class:`presence presence--${e.display} ${f?"presence--live":""}`,part:"presence","aria-label":f?w==="queued"?`You are ${V(x?.position??1)} in line to call ${y}. Open`:`Back to your call with ${y}`:o?`Chat with ${y}`:`Call ${y}`,onClick:()=>q(f||!o?"call":"chat"),children:[e.display==="bubble"?s("span",{class:"presence__ring"}):null,s("span",{class:"presence__face",children:s(ce,{agent:a,shot:e.display==="full"?jt:e.display==="half"?Bt:$e})}),s("span",{class:"presence__dot"}),t.mode==="test"?s("span",{class:"testmode",title:"Test mode: this key only works on development sites",children:"TEST"}):null,w==="queued"?s("span",{class:"presence__badge","aria-hidden":"true",children:x?.position??1}):null,e.launcher==="bubble"&&!c?s("span",{class:"presence__label","aria-hidden":"true",children:f?w==="queued"?`${V(x?.position??1)} in line`:"Back to your call":o?`Chat with ${y}`:`Call ${y}`}):null]}),e.launcher==="bubble"?null:s("div",{class:`acts ${Re?"acts--labelled":""}`,part:"actions",children:[o?s("button",{class:"act","aria-label":`Chat with ${y}`,onClick:()=>q("chat"),children:[s(le,{size:20}),s("span",{class:"act__label","aria-hidden":"true",children:"Chat"})]}):null,l?s("button",{class:`act act--call ${f?"act--live":""}`,"aria-label":f?w==="queued"?`You are ${V(x?.position??1)} in line. Open your call`:"Back to your call":`Call ${y}`,onClick:()=>f?q("call"):void fe(),children:[s(Q,{size:20}),s("span",{class:"act__label","aria-hidden":"true",children:f?w==="queued"?`${V(x?.position??1)} in line`:"On call":"Call"}),w==="queued"?s("span",{class:"act__badge","aria-hidden":"true",children:x?.position??1}):null]}):null]})]})}let fn=s("div",{class:"head",part:"header",children:[s("div",{class:"head__face",children:s(ce,{agent:a,shot:$e,talking:!!hn})}),s("div",{class:"head__who",children:[s("div",{class:"head__name",children:y}),s("div",{class:"head__sub",children:[s("i",{}),v?"Typing\u2026":W||"Online"]})]}),l&&u==="chat"?s("button",{class:"icon-btn icon-btn--accent","aria-label":`Call ${y}`,title:`Call ${y}`,onClick:()=>g&&w!=="ended"?R("call"):void fe(),children:s(Q,{size:18})}):null,s("button",{class:"icon-btn","aria-label":"Close",onClick:X,children:s(Ue,{})})]});if(u==="chat")return s("div",{class:`panel ${p?"is-closing":""}`,part:"panel",role:"dialog","aria-label":`Chat with ${y}`,children:[fn,g&&(w==="queued"||w==="ready")?s("div",{class:"banner",part:"banner",role:"status",children:[s("div",{class:"banner__text",children:w==="queued"?s(M,{children:["You're ",s("b",{children:V(x?.position??1)})," in line for a call \xB7 ",Ee(x?.etaSeconds??null)]}):s(M,{children:[s("b",{children:[y," is ready for you"]})," \xB7 ",x?.holdSeconds??30,"s to join"]})}),w==="ready"?s("button",{class:"btn btn--accent btn--glow",onClick:()=>{g.accept(),R("call")},children:"Join"}):s("button",{class:"btn",onClick:()=>R("call"),children:"View"})]}):null,s("div",{class:"log",ref:O,role:"log","aria-live":"polite","aria-relevant":"additions",children:[_.length===0?s("div",{class:"empty",children:[s("div",{class:"empty__face",children:s(ce,{agent:a,shot:$e})}),s("div",{class:"empty__title",children:["Hi, I'm ",y]}),s("div",{class:"empty__body",children:[W?`${W}. `:"","Ask me anything",l?", or call me to talk":"","."]}),l?s("button",{class:"btn btn--accent empty__call",onClick:()=>g&&w!=="ended"?R("call"):void fe(),children:[s(Q,{size:17})," Call ",y]}):null,e.suggestions.length?s("div",{class:"chips",children:e.suggestions.map(f=>s("button",{class:"chip",onClick:()=>{Fe(f)},children:[s(Qt,{}),f]},f))}):null]}):null,_.map(f=>f.role==="agent"&&f.streaming&&!f.text?s("div",{class:"msg msg--agent typing","aria-label":`${y} is typing`,children:[s("i",{}),s("i",{}),s("i",{})]},f.id):s(M,{children:[s("div",{class:`msg msg--${f.role} ${f.failed?"msg--failed":""} ${f.streaming?"caret":""}`,part:`message message-${f.role}`,children:f.role==="agent"?s(_i,{text:f.text}):f.text}),f.failed?s("button",{class:"msg__retry",onClick:()=>{t.chat.retry(f.id).catch(()=>{})},children:[s(en,{})," Not sent \xB7 Retry"]}):null]},f.id))]}),s("form",{class:"compose",part:"composer",onSubmit:f=>{f.preventDefault(),Fe(P)},children:s("div",{class:"compose__box",children:[s("textarea",{ref:$,rows:1,value:P,maxLength:2e3,placeholder:e.placeholder,"aria-label":"Message",onInput:f=>{let U=f.currentTarget;F(U.value),U.style.height="auto",U.style.height=`${Math.min(120,U.scrollHeight)}px`},onKeyDown:f=>{f.key==="Enter"&&!f.shiftKey&&!f.isComposing&&(f.preventDefault(),Fe(P))}}),s("button",{class:"send",type:"submit","aria-label":"Send",disabled:!P.trim()||v,children:s(Zt,{})})]})}),e.branding?s("div",{class:"foot",children:["Powered by"," ",s("a",{href:"https://character.xyz",target:"_blank",rel:"noopener noreferrer",children:"Character XYZ"})]}):null]});let S=x,De=S?.position??1,gn=Pe>1?(Pe-De)/(Pe-1):0,Oe=74,rt=2*Math.PI*Oe,te=S?.maxSeconds?S.maxSeconds-he:null,mn=S?.agentState??"idle",_n=S?.speaking?"Speaking":mn==="thinking"?"Thinking\u2026":"Listening",bn=!S||w==="ended"||w==="idle",He=Ht(S?.endReason??null,y);return s("div",{class:`panel ${p?"is-closing":""}`,part:"panel",role:"dialog","aria-label":`Call with ${y}`,children:s("div",{class:`stage ${ee&&pe==="ready"?"stage--face":""}`,ref:D,children:[s("div",{class:"stage__figure",style:{opacity:w==="queued"?.35:1,transition:"opacity .6s"},children:[s(ce,{agent:a,shot:qt,talking:!!S?.speaking}),ee?s("div",{class:`stage__face ${pe==="ready"?"is-ready":""}`,children:s(tn,{client:t,call:g,state:S,src:e.faceUrl,onStatus:pn})}):null]}),at?s("div",{class:"voice"}):null,s("div",{class:"stage__veil"}),s("div",{class:"stage__top",children:[w==="live"?s("span",{class:`badge ${te!=null&&te<=60?"badge--warn":""}`,role:"timer","aria-label":"Call time",children:[s("i",{}),te!=null&&te<=60?`${ze(te)} left`:ze(he)]}):s("span",{}),s("div",{style:{display:"flex",gap:"6px"},children:[o?s("button",{class:"icon-btn","aria-label":"Chat",title:"Chat",onClick:()=>q("chat"),children:s(le,{size:18})}):null,s("button",{class:"icon-btn","aria-label":"Minimise",onClick:X,children:s(Ue,{})})]})]}),s("div",{class:"stage__bottom","aria-live":"polite",children:[w==="joining"||w==="connecting"?s(M,{children:[s("div",{class:"stage__name",children:y}),s("div",{class:"stage__status",children:[s("span",{class:"spinner"})," ",w==="joining"?"Connecting\u2026":"Joining\u2026"]})]}):null,w==="queued"?s(M,{children:[s("div",{class:"line",role:"status","aria-label":`You are ${V(De)} in line, ${Ee(S?.etaSeconds??null)}`,children:[s("svg",{width:"168",height:"168",viewBox:"0 0 168 168",children:[s("circle",{class:"line__track",cx:"84",cy:"84",r:Oe,fill:"none","stroke-width":"7"}),s("circle",{class:"line__fill",cx:"84",cy:"84",r:Oe,fill:"none","stroke-width":"7","stroke-linecap":"round","stroke-dasharray":rt,"stroke-dashoffset":rt*(1-Math.max(.06,gn))})]}),s("div",{children:[s("div",{class:"line__num",children:V(De)}),s("div",{class:"line__lbl",children:"in line"})]})]}),s("div",{class:"title",children:[y," is on other calls"]}),s("div",{class:"note",children:["Your turn in ",Ee(S?.etaSeconds??null),". We'll chime when it's time",o?", so feel free to keep chatting.":"."]}),s("div",{class:"btn-row",children:[o?s("button",{class:"btn btn--accent",onClick:()=>q("chat"),children:[s(le,{size:18})," Keep chatting"]}):null,s("button",{class:"btn",onClick:()=>{g?.hangUp()},children:"Leave line"})]})]}):null,w==="ready"?s(M,{children:[s("div",{class:"title",children:[y," is ready for you"]}),s("div",{class:"note",children:["Join within ",S?.holdSeconds??30," seconds."]}),s("button",{class:"btn btn--accent btn--glow",onClick:()=>g?.accept(),children:[s(Q,{size:18})," Join call"]})]}):null,w==="live"?s(M,{children:[s("div",{class:"stage__name",children:y}),s("div",{class:"stage__status",children:[S?.speaking?s("span",{class:"wave","aria-hidden":"true",children:[.6,1,.75,1,.55].map((f,U)=>s("i",{style:{"--k":f}},U))}):null,S?.muted?"You are muted":_n]}),s("div",{class:"captions",children:k.slice(-2).map((f,U,xn)=>s("div",{class:`captions__line ${U===xn.length-1?"captions__line--now":""}`,children:f.role==="visitor"?`You: ${f.text}`:f.text},f.id))}),s("div",{class:"controls",children:[s("div",{class:"ctl",children:[s("button",{class:`round ${S?.muted?"round--on":""}`,"aria-pressed":S?.muted,"aria-label":S?.muted?"Unmute":"Mute",onClick:()=>g?.setMuted(!S?.muted),children:S?.muted?s(Jt,{size:22}):s(Xt,{size:22})}),s("span",{class:"round__label",children:S?.muted?"Unmute":"Mute"})]}),s("div",{class:"ctl",children:[s("button",{class:"round round--end","aria-label":"End call",onClick:()=>{g?.hangUp()},children:s(Kt,{size:26})}),s("span",{class:"round__label",children:"End"})]}),S?.speaking?s("div",{class:"ctl",children:[s("button",{class:"round","aria-label":`Interrupt ${y}`,onClick:()=>g?.interrupt(),children:s(Gt,{size:22})}),s("span",{class:"round__label",children:"Interrupt"})]}):null]})]}):null,bn?s(M,{children:[s("div",{class:"title",children:S?He.title:`Call ${y}`}),s("div",{class:"note",children:S?S.endReason==="hangup"&&he?`${ze(he)} \xB7 ${He.body}`:S.error??He.body:`Talk with ${y} in real time.`}),s("div",{class:"btn-row",children:[l&&S?.endReason!=="credits"&&S?.endReason!=="unavailable"?s("button",{class:"btn btn--accent",onClick:()=>{E(),fe()},children:[s(Q,{size:18})," ",S?"Call again":"Start call"]}):null,o?s("button",{class:"btn",onClick:()=>q("chat"),children:[s(le,{size:18})," Chat"]}):null]})]}):null]})]})})}function bi(t,e){let n=H({call:null,start:e});return n.current.call!==t&&(n.current={call:t,start:e}),e>n.current.start&&(n.current.start=e),n.current.start}var on=`
43
+ :host {
44
+ --cx-accent: #7c5cff;
45
+ --cx-accent-ink: #fff;
46
+ --cx-radius: 24px;
47
+ --cx-font: ui-sans-serif, system-ui, -apple-system, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
48
+ --cx-bg: rgba(255, 255, 255, 0.82);
49
+ --cx-solid: #ffffff;
50
+ --cx-ink: #14121a;
51
+ --cx-ink-2: #5b5866;
52
+ --cx-ink-3: #8d8a98;
53
+ --cx-line: rgba(20, 18, 26, 0.08);
54
+ --cx-bubble: rgba(20, 18, 26, 0.05);
55
+ --cx-shadow: 0 24px 64px -12px rgba(23, 16, 52, 0.28), 0 4px 16px -4px rgba(23, 16, 52, 0.12);
56
+ --cx-danger: #ef4444;
57
+ --cx-ok: #22c55e;
58
+ --cx-ease: cubic-bezier(0.22, 1, 0.36, 1);
59
+ --cx-spring: cubic-bezier(0.34, 1.4, 0.64, 1);
60
+ all: initial;
61
+ position: fixed;
62
+ z-index: var(--cx-z, 2147483000);
63
+ bottom: var(--cx-oy, 20px);
64
+ font-family: var(--cx-font);
65
+ color: var(--cx-ink);
66
+ -webkit-font-smoothing: antialiased;
67
+ line-height: 1.45;
68
+ }
69
+ :host([data-side="right"]) { right: var(--cx-ox, 20px); }
70
+ :host([data-side="left"]) { left: var(--cx-ox, 20px); }
71
+ :host([data-theme="dark"]) {
72
+ --cx-bg: rgba(22, 20, 30, 0.78);
73
+ --cx-solid: #16141e;
74
+ --cx-ink: #f4f2fa;
75
+ --cx-ink-2: #b7b3c6;
76
+ --cx-ink-3: #85819a;
77
+ --cx-line: rgba(255, 255, 255, 0.09);
78
+ --cx-bubble: rgba(255, 255, 255, 0.07);
79
+ --cx-shadow: 0 24px 64px -12px rgba(0, 0, 0, 0.6), 0 4px 16px -4px rgba(0, 0, 0, 0.4);
80
+ }
81
+ *, *::before, *::after { box-sizing: border-box; }
82
+ button { font: inherit; color: inherit; background: none; border: 0; padding: 0; cursor: pointer; }
83
+ button:focus-visible, textarea:focus-visible, a:focus-visible { outline: 2px solid var(--cx-accent); outline-offset: 2px; }
84
+ .sr { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; }
85
+
86
+ /* ------------------------------------------------------------ launcher */
87
+ .dock { display: flex; align-items: flex-end; gap: 10px; }
88
+ /* She sits in the corner and never moves; the buttons grow away from her. */
89
+ :host([data-side="right"]) .dock { flex-direction: row-reverse; }
90
+ .presence {
91
+ position: relative; width: 60px; height: 60px; border-radius: 50%; flex: none;
92
+ transition: transform .5s var(--cx-spring);
93
+ }
94
+ .presence:hover { transform: translateY(-2px) scale(1.05); }
95
+ /* ---- display: half body \u2014 her cut-out from the waist up, no frame, fading out at the waist */
96
+ .presence--half { width: 128px; height: 170px; border-radius: 0; filter: drop-shadow(0 10px 18px rgba(15, 10, 30, 0.28)); }
97
+ .presence--half .presence__face { border-radius: 0; background: none; box-shadow: none;
98
+ -webkit-mask-image: linear-gradient(to bottom, #000 70%, transparent 98%); mask-image: linear-gradient(to bottom, #000 70%, transparent 98%); }
99
+ /* ---- display: full body \u2014 she stands in the corner, feet on the edge, a soft shadow under her */
100
+ .presence--full { width: 132px; height: 300px; border-radius: 0; filter: drop-shadow(0 6px 14px rgba(15, 10, 30, 0.22)); }
101
+ .presence--full .presence__face { border-radius: 0; background: none; box-shadow: none; }
102
+ .presence--full::before { content: ""; position: absolute; left: 22%; right: 22%; bottom: -4px; height: 10px; border-radius: 50%;
103
+ background: radial-gradient(closest-side, rgba(15, 10, 30, 0.35), transparent); }
104
+ .presence--half:hover, .presence--full:hover { transform: translateY(-3px); }
105
+ .presence--half .presence__dot { top: 10px; bottom: auto; right: 26px; }
106
+ .presence--full .presence__dot { top: 6px; bottom: auto; right: 34px; }
107
+ .presence--half .testmode, .presence--full .testmode { top: -6px; bottom: auto; }
108
+ .presence--full .presence__label { top: 22%; }
109
+ .presence--half .presence__badge, .presence--full .presence__badge { top: 0; right: 4px; }
110
+ .presence--half.presence--live::after, .presence--full.presence--live::after { display: none; }
111
+ .presence--half.presence--live, .presence--full.presence--live { animation: cx-figure-glow 1.8s ease-in-out infinite; }
112
+ .dock--half .greeting { bottom: 186px; }
113
+ .dock--full .greeting { bottom: 316px; }
114
+
115
+ /* What a tap does, on hover and keyboard focus. */
116
+ .presence__label {
117
+ position: absolute; top: 50%; transform: translate(6px, -50%); opacity: 0; pointer-events: none; white-space: nowrap;
118
+ padding: 7px 12px; border-radius: 999px; font-size: 13px; font-weight: 600; letter-spacing: -0.005em;
119
+ color: var(--cx-ink); background: var(--cx-solid); border: 1px solid var(--cx-line); box-shadow: var(--cx-shadow);
120
+ transition: opacity .2s, transform .3s var(--cx-ease);
121
+ }
122
+ :host([data-side="right"]) .presence__label { right: calc(100% + 10px); }
123
+ :host([data-side="left"]) .presence__label { left: calc(100% + 10px); transform: translate(-6px, -50%); }
124
+ .presence:hover .presence__label, .presence:focus-visible .presence__label { opacity: 1; transform: translate(0, -50%); }
125
+ /* Waiting in line: the place, on her. */
126
+ .presence__badge {
127
+ position: absolute; top: -4px; right: -4px; min-width: 22px; height: 22px; padding: 0 6px; border-radius: 11px;
128
+ display: grid; place-items: center; font-size: 12px; font-weight: 800; font-variant-numeric: tabular-nums;
129
+ background: var(--cx-accent); color: var(--cx-accent-ink); box-shadow: 0 0 0 2px var(--cx-solid);
130
+ }
131
+ /* A call is open (or waiting): she breathes, so the way back is obvious. */
132
+ .presence--live::after { content: ""; position: absolute; inset: -5px; border-radius: 50%; border: 2px solid var(--cx-accent); animation: cx-glow-ring 1.8s ease-out infinite; }
133
+ .empty__call { margin-top: 4px; height: 40px; }
134
+ .presence__ring {
135
+ position: absolute; inset: -3px; border-radius: 50%;
136
+ background: conic-gradient(from var(--cx-angle, 0deg), var(--cx-accent), color-mix(in oklab, var(--cx-accent) 30%, #fff), var(--cx-accent));
137
+ animation: cx-spin 6s linear infinite;
138
+ }
139
+ .presence__face {
140
+ position: absolute; inset: 0; border-radius: 50%; overflow: hidden;
141
+ background: radial-gradient(120% 90% at 50% 10%, color-mix(in oklab, var(--cx-accent) 22%, var(--cx-solid)), var(--cx-solid));
142
+ box-shadow: inset 0 0 0 3px var(--cx-solid);
143
+ }
144
+ .presence__dot {
145
+ position: absolute; right: 3px; bottom: 3px; width: 14px; height: 14px; border-radius: 50%;
146
+ background: var(--cx-ok); box-shadow: 0 0 0 3px var(--cx-solid);
147
+ }
148
+ .acts { display: flex; gap: 8px; align-items: center; margin-bottom: 12px; }
149
+ /* Call, the primary action, sits next to her on either side. */
150
+ :host([data-side="left"]) .acts { flex-direction: row-reverse; }
151
+ .act {
152
+ position: relative; display: inline-flex; align-items: center; justify-content: center;
153
+ height: 44px; min-width: 44px; padding: 0 12px; border-radius: 999px;
154
+ color: var(--cx-ink); background: var(--cx-bg);
155
+ backdrop-filter: blur(18px) saturate(1.6); -webkit-backdrop-filter: blur(18px) saturate(1.6);
156
+ border: 1px solid var(--cx-line); box-shadow: var(--cx-shadow);
157
+ animation: cx-rise .6s var(--cx-ease) both;
158
+ transition: transform .35s var(--cx-spring), background .2s, box-shadow .2s;
159
+ }
160
+ .act + .act { animation-delay: .06s; }
161
+ .act:hover { transform: translateY(-2px); }
162
+ .act:active { transform: scale(.94); }
163
+ .act--call { background: var(--cx-accent); color: var(--cx-accent-ink); border-color: transparent; }
164
+ .act--call:hover { background: color-mix(in oklab, var(--cx-accent) 88%, #000); }
165
+ /* The word folds away to an icon; hover, keyboard focus and a first visit unfold it. */
166
+ .act__label {
167
+ max-width: 0; opacity: 0; overflow: hidden; white-space: nowrap;
168
+ font-size: 14px; font-weight: 600; letter-spacing: -0.005em;
169
+ transition: max-width .35s var(--cx-ease), opacity .2s, margin .35s var(--cx-ease);
170
+ }
171
+ .act:hover .act__label, .act:focus-visible .act__label, .acts--labelled .act__label { max-width: 120px; opacity: 1; margin-left: 7px; }
172
+ /* Waiting in line: the place, on the button. */
173
+ .act__badge {
174
+ position: absolute; top: -5px; right: -5px; min-width: 20px; height: 20px; padding: 0 5px; border-radius: 10px;
175
+ display: grid; place-items: center; font-size: 11px; font-weight: 800; font-variant-numeric: tabular-nums;
176
+ background: var(--cx-solid); color: var(--cx-ink); box-shadow: 0 0 0 2px var(--cx-accent);
177
+ }
178
+ /* On a call (or ready): the button breathes so the way back is obvious. */
179
+ .act--live::after { content: ""; position: absolute; inset: -4px; border-radius: inherit; border: 2px solid var(--cx-accent); opacity: .5; animation: cx-glow-ring 1.8s ease-out infinite; }
180
+ .greeting {
181
+ position: absolute; bottom: 76px; max-width: 260px; padding: 12px 34px 12px 14px; border-radius: 18px;
182
+ background: var(--cx-solid); box-shadow: var(--cx-shadow); border: 1px solid var(--cx-line);
183
+ font-size: 14px; color: var(--cx-ink); animation: cx-pop .55s var(--cx-spring) both; cursor: pointer;
184
+ }
185
+ :host([data-side="right"]) .greeting { right: 0; border-bottom-right-radius: 6px; }
186
+ :host([data-side="left"]) .greeting { left: 0; border-bottom-left-radius: 6px; }
187
+ .greeting__close { position: absolute; top: 6px; right: 6px; width: 24px; height: 24px; border-radius: 50%; display: grid; place-items: center; color: var(--cx-ink-3); }
188
+ .greeting__close:hover { background: var(--cx-bubble); color: var(--cx-ink); }
189
+
190
+ /* ------------------------------------------------------------ panel */
191
+ .panel {
192
+ position: absolute; bottom: 0; width: 392px; height: min(640px, calc(100vh - 40px));
193
+ display: flex; flex-direction: column; overflow: hidden;
194
+ border-radius: var(--cx-radius); background: var(--cx-bg); border: 1px solid var(--cx-line);
195
+ backdrop-filter: blur(24px) saturate(1.7); -webkit-backdrop-filter: blur(24px) saturate(1.7);
196
+ box-shadow: var(--cx-shadow);
197
+ transform-origin: bottom right;
198
+ animation: cx-open .5s var(--cx-ease) both;
199
+ }
200
+ :host([data-side="right"]) .panel { right: 0; }
201
+ :host([data-side="left"]) .panel { left: 0; transform-origin: bottom left; }
202
+ .panel.is-closing { animation: cx-close .22s ease-in both; }
203
+
204
+ .head { display: flex; align-items: center; gap: 12px; padding: 14px 14px 12px 16px; border-bottom: 1px solid var(--cx-line); }
205
+ .head__face { position: relative; width: 42px; height: 42px; border-radius: 50%; overflow: hidden; flex: none;
206
+ background: radial-gradient(120% 90% at 50% 10%, color-mix(in oklab, var(--cx-accent) 22%, var(--cx-solid)), var(--cx-solid)); }
207
+ .head__who { flex: 1; min-width: 0; }
208
+ .head__name { font-size: 15px; font-weight: 650; letter-spacing: -0.01em; }
209
+ .head__sub { font-size: 12.5px; color: var(--cx-ink-2); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; display: flex; align-items: center; gap: 6px; }
210
+ .head__sub i { width: 7px; height: 7px; border-radius: 50%; background: var(--cx-ok); flex: none; }
211
+ .icon-btn { width: 38px; height: 38px; border-radius: 12px; display: grid; place-items: center; color: var(--cx-ink-2); transition: background .2s, color .2s; }
212
+ .icon-btn:hover { background: var(--cx-bubble); color: var(--cx-ink); }
213
+ .icon-btn--accent { background: var(--cx-accent); color: var(--cx-accent-ink); }
214
+ .icon-btn--accent:hover { background: color-mix(in oklab, var(--cx-accent) 88%, #000); color: var(--cx-accent-ink); }
215
+
216
+ /* ------------------------------------------------------------ chat */
217
+ .log { flex: 1; overflow-y: auto; padding: 18px 16px 8px; display: flex; flex-direction: column; gap: 6px; scroll-behavior: smooth; overscroll-behavior: contain; }
218
+ .log::-webkit-scrollbar { width: 8px; } .log::-webkit-scrollbar-thumb { background: var(--cx-line); border-radius: 8px; }
219
+ .msg { max-width: 84%; padding: 9px 13px; border-radius: 18px; font-size: 14.5px; word-wrap: break-word; animation: cx-msg .35s var(--cx-ease) both; }
220
+ .msg p { margin: 0; } .msg p + p, .msg p + ul, .msg ul + p { margin-top: 8px; }
221
+ .msg ul { margin: 0; padding-left: 18px; }
222
+ .msg code { font-family: ui-monospace, SFMono-Regular, Menlo, monospace; font-size: .9em; padding: 1px 5px; border-radius: 6px; background: var(--cx-bubble); }
223
+ .msg a { color: inherit; text-decoration: underline; text-underline-offset: 2px; }
224
+ .msg--agent { align-self: flex-start; background: var(--cx-bubble); border-bottom-left-radius: 6px; }
225
+ .msg--visitor { align-self: flex-end; background: var(--cx-accent); color: var(--cx-accent-ink); border-bottom-right-radius: 6px; }
226
+ .msg--visitor + .msg--visitor, .msg--agent + .msg--agent { margin-top: -2px; }
227
+ .msg--failed { opacity: .65; }
228
+ .msg__retry { display: inline-flex; align-items: center; gap: 4px; margin-top: 4px; font-size: 12px; color: var(--cx-danger); align-self: flex-end; }
229
+ .caret::after { content: ""; display: inline-block; width: 7px; height: 1.05em; margin-left: 2px; vertical-align: -2px; border-radius: 2px; background: currentColor; opacity: .55; animation: cx-blink 1s steps(2) infinite; }
230
+ .typing { display: inline-flex; gap: 4px; padding: 13px 14px; }
231
+ .typing i { width: 7px; height: 7px; border-radius: 50%; background: var(--cx-ink-3); animation: cx-bounce 1.2s var(--cx-ease) infinite; }
232
+ .typing i:nth-child(2) { animation-delay: .15s; } .typing i:nth-child(3) { animation-delay: .3s; }
233
+ .empty { margin: auto 0 8px; display: flex; flex-direction: column; align-items: center; text-align: center; gap: 10px; padding: 10px 8px 4px; }
234
+ .empty__face { width: 96px; height: 96px; border-radius: 50%; overflow: hidden; position: relative; box-shadow: 0 0 0 4px var(--cx-solid), 0 0 0 6px color-mix(in oklab, var(--cx-accent) 45%, transparent);
235
+ background: radial-gradient(120% 90% at 50% 10%, color-mix(in oklab, var(--cx-accent) 22%, var(--cx-solid)), var(--cx-solid)); }
236
+ .empty__title { font-size: 17px; font-weight: 650; letter-spacing: -0.015em; }
237
+ .empty__body { font-size: 13.5px; color: var(--cx-ink-2); max-width: 280px; }
238
+ .chips { display: flex; flex-wrap: wrap; gap: 6px; justify-content: center; margin-top: 4px; }
239
+ .chip { display: inline-flex; align-items: center; gap: 6px; padding: 7px 12px; border-radius: 999px; font-size: 13px; border: 1px solid var(--cx-line); background: var(--cx-solid); transition: border-color .2s, transform .3s var(--cx-spring); }
240
+ .chip:hover { border-color: color-mix(in oklab, var(--cx-accent) 55%, transparent); transform: translateY(-1px); }
241
+ .chip svg { color: var(--cx-accent); }
242
+
243
+ .compose { padding: 10px 12px 12px; }
244
+ .compose__box { display: flex; align-items: flex-end; gap: 8px; padding: 6px 6px 6px 14px; border-radius: 20px; background: var(--cx-solid); border: 1px solid var(--cx-line); transition: border-color .2s, box-shadow .2s; }
245
+ .compose__box:focus-within { border-color: color-mix(in oklab, var(--cx-accent) 60%, transparent); box-shadow: 0 0 0 4px color-mix(in oklab, var(--cx-accent) 14%, transparent); }
246
+ .compose textarea { flex: 1; resize: none; border: 0; outline: 0; background: transparent; font: inherit; font-size: 14.5px; color: var(--cx-ink); max-height: 120px; padding: 7px 0; line-height: 1.4; }
247
+ .compose textarea::placeholder { color: var(--cx-ink-3); }
248
+ .send { width: 34px; height: 34px; border-radius: 50%; display: grid; place-items: center; background: var(--cx-accent); color: var(--cx-accent-ink); flex: none; transition: transform .3s var(--cx-spring), opacity .2s; }
249
+ .send:disabled { opacity: .35; cursor: default; }
250
+ .send:not(:disabled):active { transform: scale(.9); }
251
+ .foot { text-align: center; font-size: 11px; color: var(--cx-ink-3); padding: 0 0 10px; }
252
+ .foot a { color: inherit; text-decoration: none; font-weight: 600; }
253
+
254
+ /* ------------------------------------------------------------ banners (queue / ready while chatting) */
255
+ .banner { margin: 10px 12px 0; padding: 10px 10px 10px 14px; border-radius: 16px; display: flex; align-items: center; gap: 10px; font-size: 13px;
256
+ background: color-mix(in oklab, var(--cx-accent) 12%, var(--cx-solid)); border: 1px solid color-mix(in oklab, var(--cx-accent) 25%, transparent); animation: cx-rise .4s var(--cx-ease) both; }
257
+ .banner__text { flex: 1; min-width: 0; } .banner__text b { font-weight: 650; }
258
+ .banner .btn { height: 32px; padding: 0 12px; font-size: 13px; }
259
+
260
+ /* ------------------------------------------------------------ call */
261
+ .stage { flex: 1; position: relative; display: flex; flex-direction: column; overflow: hidden;
262
+ background: radial-gradient(120% 70% at 50% 18%, color-mix(in oklab, var(--cx-accent) 26%, var(--cx-solid)) 0%, var(--cx-solid) 70%); }
263
+ .stage__figure { position: absolute; inset: 0; }
264
+ .stage__figure .portrait { position: absolute; inset: 0; }
265
+ /* The app's own face renderer, faded in over the portrait once it is drawing. */
266
+ .stage__face { position: absolute; inset: 0; opacity: 0; transition: opacity .5s ease; pointer-events: none; }
267
+ .stage__face.is-ready { opacity: 1; }
268
+ /* Over the skin's own (usually dark) backdrop the top controls go light. */
269
+ .stage--face .stage__top .icon-btn { color: rgba(255, 255, 255, 0.85); }
270
+ .stage--face .stage__top .icon-btn:hover { color: #fff; background: rgba(255, 255, 255, 0.14); }
271
+ .stage--face .badge { background: rgba(10, 8, 16, 0.45); color: #fff; border-color: rgba(255, 255, 255, 0.12); }
272
+ .face-frame { position: absolute; inset: 0; width: 100%; height: 100%; border: 0; background: transparent; color-scheme: normal; }
273
+ .stage__veil { position: absolute; left: 0; right: 0; bottom: 0; height: 58%; background: linear-gradient(to top, var(--cx-solid) 18%, color-mix(in oklab, var(--cx-solid) 0%, transparent)); pointer-events: none; }
274
+ .stage__top { position: relative; display: flex; justify-content: space-between; align-items: center; padding: 14px 14px 0 16px; }
275
+ .badge { display: inline-flex; align-items: center; gap: 7px; height: 28px; padding: 0 11px; border-radius: 999px; font-size: 12.5px; font-weight: 600; background: var(--cx-bg); backdrop-filter: blur(12px); border: 1px solid var(--cx-line); font-variant-numeric: tabular-nums; }
276
+ .badge i { width: 7px; height: 7px; border-radius: 50%; background: var(--cx-danger); animation: cx-pulse 1.6s ease-in-out infinite; }
277
+ .badge--warn { color: var(--cx-danger); }
278
+ .stage__bottom { position: relative; margin-top: auto; padding: 0 18px 18px; display: flex; flex-direction: column; align-items: center; gap: 12px; text-align: center; }
279
+ .stage__name { font-size: 21px; font-weight: 700; letter-spacing: -0.02em; }
280
+ .stage__status { font-size: 13.5px; color: var(--cx-ink-2); min-height: 20px; display: inline-flex; align-items: center; gap: 8px; }
281
+ .wave { display: inline-flex; align-items: center; gap: 3px; height: 16px; }
282
+ .wave i { width: 3px; border-radius: 3px; background: var(--cx-accent); height: calc(4px + var(--cx-lvl, 0) * 12px * var(--k, 1)); transition: height .08s linear; }
283
+ .captions { width: 100%; min-height: 44px; font-size: 14.5px; color: var(--cx-ink); display: flex; flex-direction: column; gap: 2px; }
284
+ .captions__line { opacity: .55; font-size: 13px; } .captions__line--now { opacity: 1; font-size: 15px; font-weight: 500; }
285
+ .controls { display: flex; gap: 14px; align-items: center; justify-content: center; margin-top: 4px; }
286
+ .round { width: 56px; height: 56px; border-radius: 50%; display: grid; place-items: center; background: var(--cx-bg); border: 1px solid var(--cx-line); backdrop-filter: blur(12px); transition: transform .3s var(--cx-spring), background .2s; }
287
+ .round:hover { transform: translateY(-2px); }
288
+ .round:active { transform: scale(.94); }
289
+ .round--on { background: var(--cx-ink); color: var(--cx-solid); }
290
+ .round--end { background: var(--cx-danger); color: #fff; border-color: transparent; width: 64px; height: 64px; }
291
+ .round__label { font-size: 11.5px; color: var(--cx-ink-2); margin-top: 6px; }
292
+ .ctl { display: flex; flex-direction: column; align-items: center; }
293
+
294
+ .voice { position: absolute; left: 50%; top: 34%; width: 240px; height: 240px; margin: -120px 0 0 -120px; border-radius: 50%; pointer-events: none;
295
+ background: radial-gradient(closest-side, color-mix(in oklab, var(--cx-accent) 30%, transparent), transparent);
296
+ transform: scale(calc(0.85 + var(--cx-lvl, 0) * 0.5)); opacity: calc(0.25 + var(--cx-lvl, 0) * 0.75); transition: transform .1s linear, opacity .1s linear; }
297
+
298
+ /* queue */
299
+ .line { position: relative; width: 168px; height: 168px; display: grid; place-items: center; margin: 4px auto 0; }
300
+ .line svg { position: absolute; inset: 0; transform: rotate(-90deg); }
301
+ .line__track { stroke: var(--cx-line); }
302
+ .line__fill { stroke: var(--cx-accent); transition: stroke-dashoffset .8s var(--cx-ease); }
303
+ .line__num { font-size: 46px; font-weight: 750; letter-spacing: -0.04em; line-height: 1; font-variant-numeric: tabular-nums; }
304
+ .line__lbl { font-size: 12px; color: var(--cx-ink-2); text-transform: uppercase; letter-spacing: .08em; margin-top: 4px; }
305
+ .btn { display: inline-flex; align-items: center; justify-content: center; gap: 8px; height: 44px; padding: 0 18px; border-radius: 999px; font-size: 14.5px; font-weight: 600; background: var(--cx-bubble); transition: transform .3s var(--cx-spring), background .2s; }
306
+ .btn:hover { background: color-mix(in oklab, var(--cx-ink) 10%, transparent); }
307
+ .btn:active { transform: scale(.97); }
308
+ .btn--accent { background: var(--cx-accent); color: var(--cx-accent-ink); }
309
+ .btn--accent:hover { background: color-mix(in oklab, var(--cx-accent) 88%, #000); }
310
+ .btn--glow { box-shadow: 0 0 0 0 color-mix(in oklab, var(--cx-accent) 55%, transparent); animation: cx-glow 1.6s ease-out infinite; }
311
+ .btn-row { display: flex; gap: 10px; justify-content: center; flex-wrap: wrap; }
312
+ .note { font-size: 13.5px; color: var(--cx-ink-2); max-width: 300px; }
313
+ .title { font-size: 19px; font-weight: 700; letter-spacing: -0.02em; }
314
+ .spinner { width: 22px; height: 22px; border-radius: 50%; border: 2.5px solid var(--cx-line); border-top-color: var(--cx-accent); animation: cx-spin 0.8s linear infinite; }
315
+
316
+ /* ------------------------------------------------------------ portrait */
317
+ .portrait { position: relative; width: 100%; height: 100%; overflow: hidden; }
318
+ .portrait__media { position: absolute; max-width: none; transition: opacity .35s ease; user-select: none; -webkit-user-drag: none; }
319
+ .portrait--initial { display: grid; place-items: center; font-size: 26px; font-weight: 700; color: var(--cx-accent); }
320
+
321
+ /* ------------------------------------------------------------ test-mode ribbon */
322
+ .dock { position: relative; }
323
+ /* A small tag on the portrait's lower edge: present, never in the way. */
324
+ .testmode { position: absolute; left: 50%; bottom: -7px; transform: translateX(-50%); font-size: 8.5px; font-weight: 800; letter-spacing: .08em; line-height: 1; padding: 3px 5px; border-radius: 5px; background: #f59e0b; color: #1c1206; box-shadow: 0 0 0 2px var(--cx-solid); pointer-events: none; }
325
+
326
+ /* ------------------------------------------------------------ phones: a bottom sheet */
327
+ @media (max-width: 520px) {
328
+ :host([data-open]) { left: 0 !important; right: 0 !important; bottom: 0 !important; }
329
+ .panel { position: fixed; left: 0; right: 0; bottom: 0; width: 100%; height: min(92dvh, 760px); border-radius: var(--cx-radius) var(--cx-radius) 0 0; padding-bottom: env(safe-area-inset-bottom); animation-name: cx-sheet; }
330
+ .presence { width: 56px; height: 56px; }
331
+ .presence--half { width: 104px; height: 138px; }
332
+ .presence--full { width: 100px; height: 228px; }
333
+ .dock--half .greeting { bottom: 152px; }
334
+ .dock--full .greeting { bottom: 242px; }
335
+ }
336
+
337
+ @keyframes cx-spin { to { transform: rotate(360deg); } }
338
+ @keyframes cx-rise { from { opacity: 0; transform: translateY(8px); } to { opacity: 1; transform: none; } }
339
+ @keyframes cx-pop { from { opacity: 0; transform: translateY(8px) scale(.92); } to { opacity: 1; transform: none; } }
340
+ @keyframes cx-open { from { opacity: 0; transform: translateY(14px) scale(.94); filter: blur(4px); } to { opacity: 1; transform: none; filter: none; } }
341
+ @keyframes cx-close { to { opacity: 0; transform: translateY(10px) scale(.96); } }
342
+ @keyframes cx-sheet { from { transform: translateY(100%); } to { transform: none; } }
343
+ @keyframes cx-msg { from { opacity: 0; transform: translateY(6px); } to { opacity: 1; transform: none; } }
344
+ @keyframes cx-blink { 50% { opacity: 0; } }
345
+ @keyframes cx-bounce { 0%, 60%, 100% { transform: translateY(0); opacity: .45; } 30% { transform: translateY(-4px); opacity: 1; } }
346
+ @keyframes cx-pulse { 50% { opacity: .35; } }
347
+ @keyframes cx-figure-glow { 0%, 100% { filter: drop-shadow(0 0 0 transparent); } 50% { filter: drop-shadow(0 0 12px var(--cx-accent)); } }
348
+ @keyframes cx-glow-ring { 0% { transform: scale(1); opacity: .55; } 100% { transform: scale(1.35); opacity: 0; } }
349
+ @keyframes cx-glow { 0% { box-shadow: 0 0 0 0 color-mix(in oklab, var(--cx-accent) 50%, transparent); } 100% { box-shadow: 0 0 0 16px transparent; } }
350
+
351
+ @media (prefers-reduced-motion: reduce) {
352
+ *, *::before, *::after { animation-duration: .01ms !important; animation-iteration-count: 1 !important; transition-duration: .01ms !important; }
353
+ .presence__ring { animation: none; }
354
+ }
355
+ `;var nt="character-xyz";function xi(t){let e=/^#([0-9a-f]{3}|[0-9a-f]{6})$/i.exec(t.trim());if(!e)return"#ffffff";let n=e[1].length===3?e[1].replace(/./g,l=>l+l):e[1],[i,a,r]=[0,2,4].map(l=>parseInt(n.slice(l,l+2),16)/255).map(l=>l<=.03928?l/12.92:((l+.055)/1.055)**2.4);return .2126*i+.7152*a+.0722*r>.45?"#14121a":"#ffffff"}function vi(t){let e=/rgba?\(\s*([\d.]+)[,\s]+([\d.]+)[,\s]+([\d.]+)(?:[,\s/]+([\d.]+%?))?\s*\)/.exec(t);if(!e||(e[4]===void 0?1:e[4].endsWith("%")?parseFloat(e[4])/100:parseFloat(e[4]))<.5)return null;let[i,a,r]=[e[1],e[2],e[3]].map(o=>Number(o)/255).map(o=>o<=.03928?o/12.92:((o+.055)/1.055)**2.4);return .2126*i+.7152*a+.0722*r}function ln(t){for(let e of[document.body,document.documentElement]){if(!e)continue;let n=vi(getComputedStyle(e).backgroundColor);if(n!==null)return n<.22}return!!t?.matches}var yi=["publishable-key","agent","api-url","position","mode","accent","greeting","open"],it=class extends HTMLElement{constructor(){super(...arguments);Y(this,"options",null);Y(this,"client",null);Y(this,"api",null);Y(this,"pendingOpen",null);Y(this,"booted",!1);Y(this,"mq",null);Y(this,"stage",null);Y(this,"onSchemeChange",()=>requestAnimationFrame(this.onScheme));Y(this,"onScheme",()=>{this.dataset.mode==="auto"&&(this.dataset.theme=ln(this.mq)?"dark":"light")})}static get observedAttributes(){return yi}connectedCallback(){if(this.booted)return;this.booted=!0;let n=this.shadowRoot??this.attachShadow({mode:"open"}),i=document.createElement("style");i.textContent=on,this.stage=document.createElement("div"),n.replaceChildren(i,this.stage),this.style.display="none";let a=window.requestIdleCallback;a?a(()=>{this.boot()},{timeout:2e3}):setTimeout(()=>{this.boot()},200)}disconnectedCallback(){this.stage&&Je(null,this.stage),this.client?.destroy(),this.client=null,this.mq?.removeEventListener("change",this.onSchemeChange),this.booted=!1}open(n="chat"){this.api?this.api.open(n):this.pendingOpen=n}close(){this.api?.close()}fire(n,i){this.dispatchEvent(new CustomEvent(n,{detail:i,bubbles:!0,composed:!0}))}async boot(){let n={...this.options??{}},i=me(Array.from(this.attributes)),a=n.publishableKey??i.publishableKey;try{this.client=await dt.init({publishableKey:a,getSessionToken:n.getSessionToken,agentId:n.agentId??i.agent,apiUrl:n.apiUrl??i.apiUrl,storage:n.storage})}catch(l){let u=l instanceof L?l:new L("unknown",String(l?.message??l));console.warn(`[characterxyz] widget not shown: ${u.message}`),this.fire("cx-error",{code:u.code,message:u.message});return}if(!this.isConnected){this.client.destroy();return}let r=this.client,o=J(ae,r.appearance);if(o=J(o,i),o=J(o,n),!(o.showChat&&r.features.chat)&&!(o.showCall&&r.features.call)){console.warn("[characterxyz] widget not shown: neither chat nor calls are enabled for this site");return}this.applyTokens(o),r.on("call",l=>{l&&l.on("state",u=>this.fire("cx-call",{phase:u.phase,position:u.position,endReason:u.endReason}))}),r.on("error",l=>this.fire("cx-error",{code:l.code,message:l.message})),this.style.display="",Je(s(sn,{client:r,config:o,bind:l=>{this.api=l,this.pendingOpen&&this.pendingOpen!=="closed"&&(l.open(this.pendingOpen),this.pendingOpen=null)},onView:l=>{l==="closed"?(this.removeAttribute("data-open"),this.fire("cx-close")):(this.setAttribute("data-open",""),this.fire("cx-open",{view:l}))}}),this.stage),o.open&&this.setAttribute("data-open",""),this.fire("cx-ready",{agent:{id:r.agent.id,name:r.agent.name},features:r.features})}applyTokens(n){this.dataset.side=n.position==="bottom-left"?"left":"right",this.dataset.mode=n.mode,n.mode==="auto"?(this.mq=matchMedia("(prefers-color-scheme: dark)"),this.mq.addEventListener("change",this.onSchemeChange),this.dataset.theme=ln(this.mq)?"dark":"light"):this.dataset.theme=n.mode;let i=(a,r)=>this.style.setProperty(a,r);i("--cx-accent",n.accent),i("--cx-accent-ink",xi(n.accent)),i("--cx-radius",`${n.radius}px`),n.font&&i("--cx-font",n.font),i("--cx-ox",`${n.offsetX}px`),i("--cx-oy",`${n.offsetY}px`),i("--cx-z",String(n.zIndex))}};function ki(){typeof customElements<"u"&&!customElements.get(nt)&&customElements.define(nt,it)}function Le(t){ki();let e=document.createElement(nt);return e.options=t,(t.container??document.body).appendChild(e),{element:e,open:n=>e.open(n),close:()=>e.close(),destroy:()=>e.remove()}}var cn=document.currentScript,ue=null;function dn(){if(!cn)return;let t=me(Array.from(cn.attributes).filter(o=>o.name.startsWith("data-"))),e=o=>typeof o=="string"&&o.trim()?o.trim():void 0,n=e(t.key)??e(t.publishableKey);if(!n)return;let i=J(ae,t),r={...Object.fromEntries(Object.entries(i).filter(([o,l])=>o in t&&l!==ae[o])),publishableKey:n,agentId:e(t.agent),apiUrl:e(t.apiUrl)};ue=Le(r)}document.readyState==="loading"?document.addEventListener("DOMContentLoaded",dn,{once:!0}):dn();var wi={mount:t=>ue=Le(t),open:t=>ue?.open(t),close:()=>ue?.close(),get widget(){return ue}};window.CharacterXYZ=wi;return An(Ci);})();
356
+ //# sourceMappingURL=cx.js.map