@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 +21 -0
- package/README.md +74 -2
- package/dist/cx.js +356 -0
- package/dist/cx.js.map +1 -0
- package/dist/index.d.ts +102 -0
- package/dist/index.js +356 -0
- package/dist/index.js.map +1 -0
- package/package.json +47 -3
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
import { InitOptions, CharacterXYZ } from '@characterxyz/web';
|
|
2
|
+
export { CharacterXYZ, CxError } from '@characterxyz/web';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Everything a brand can set, from three places, later wins:
|
|
6
|
+
* 1. the key's `appearance` (the Embed designer in Character XYZ),
|
|
7
|
+
* 2. the element's attributes / `data-*` on the script tag,
|
|
8
|
+
* 3. options passed to `mount()`.
|
|
9
|
+
*/
|
|
10
|
+
type Position = 'bottom-right' | 'bottom-left';
|
|
11
|
+
type ColorMode = 'light' | 'dark' | 'auto';
|
|
12
|
+
/** `bubble`: just her portrait (opens the chat; calls are inside). `actions`: chat and call buttons beside it. */
|
|
13
|
+
type LauncherStyle = 'bubble' | 'actions';
|
|
14
|
+
/** How she is shown while closed: a round `bubble`, a `half` body cut-out, or her `full` body standing in the corner. */
|
|
15
|
+
type Display = 'bubble' | 'half' | 'full';
|
|
16
|
+
interface WidgetConfig {
|
|
17
|
+
position: Position;
|
|
18
|
+
mode: ColorMode;
|
|
19
|
+
launcher: LauncherStyle;
|
|
20
|
+
display: Display;
|
|
21
|
+
/** Any CSS colour. */
|
|
22
|
+
accent: string;
|
|
23
|
+
/** Corner radius of the panel, px. */
|
|
24
|
+
radius: number;
|
|
25
|
+
/** A CSS font-family; defaults to the system UI font. */
|
|
26
|
+
font: string;
|
|
27
|
+
/** The line under her name; defaults to the agent's tagline. */
|
|
28
|
+
subtitle: string | null;
|
|
29
|
+
/** Shown once per visitor above the launcher. Empty = none. */
|
|
30
|
+
greeting: string;
|
|
31
|
+
/** Seconds before the greeting appears. */
|
|
32
|
+
greetingDelay: number;
|
|
33
|
+
/** Suggested first messages in an empty chat. */
|
|
34
|
+
suggestions: string[];
|
|
35
|
+
/** Placeholder in the message box. */
|
|
36
|
+
placeholder: string;
|
|
37
|
+
showChat: boolean;
|
|
38
|
+
showCall: boolean;
|
|
39
|
+
/** The "Powered by Character XYZ" line. */
|
|
40
|
+
branding: boolean;
|
|
41
|
+
/** px from the corner. */
|
|
42
|
+
offsetX: number;
|
|
43
|
+
offsetY: number;
|
|
44
|
+
zIndex: number;
|
|
45
|
+
/** Open the panel on load. */
|
|
46
|
+
open: boolean;
|
|
47
|
+
/**
|
|
48
|
+
* Draw the agent's face in calls with Character XYZ's own renderer (lip
|
|
49
|
+
* sync, her own teeth and eyes), framed from `faceUrl`. Off = the portrait clips.
|
|
50
|
+
*/
|
|
51
|
+
face: boolean;
|
|
52
|
+
faceUrl: string;
|
|
53
|
+
}
|
|
54
|
+
declare const DEFAULTS: WidgetConfig;
|
|
55
|
+
/** Merge one layer of untrusted settings onto a config. Unknown or invalid values are dropped. */
|
|
56
|
+
declare function applyLayer(base: WidgetConfig, raw: Record<string, unknown> | null | undefined): WidgetConfig;
|
|
57
|
+
|
|
58
|
+
declare const TAG = "character-xyz";
|
|
59
|
+
interface MountOptions extends InitOptions, Partial<WidgetConfig> {
|
|
60
|
+
/** Where the element goes. Default `document.body`. */
|
|
61
|
+
container?: HTMLElement;
|
|
62
|
+
}
|
|
63
|
+
/** Ink that reads on the accent: white on dark accents, near-black on light ones. */
|
|
64
|
+
declare function inkFor(color: string): string;
|
|
65
|
+
/**
|
|
66
|
+
* `<character-xyz publishable-key="cxyz_pk_live_…"></character-xyz>`
|
|
67
|
+
*
|
|
68
|
+
* Events (bubbling, composed): `cx-ready` {agent}, `cx-open` {view},
|
|
69
|
+
* `cx-close`, `cx-call` {phase}, `cx-error` {code, message}.
|
|
70
|
+
* Methods: `open('chat' | 'call')`, `close()`; property `client` once ready.
|
|
71
|
+
*/
|
|
72
|
+
declare class CharacterXYZElement extends HTMLElement {
|
|
73
|
+
static get observedAttributes(): string[];
|
|
74
|
+
/** Set before the element connects (what `mount()` does). */
|
|
75
|
+
options: MountOptions | null;
|
|
76
|
+
client: CharacterXYZ | null;
|
|
77
|
+
private api;
|
|
78
|
+
private pendingOpen;
|
|
79
|
+
private booted;
|
|
80
|
+
private mq;
|
|
81
|
+
private stage;
|
|
82
|
+
connectedCallback(): void;
|
|
83
|
+
disconnectedCallback(): void;
|
|
84
|
+
open(view?: 'chat' | 'call'): void;
|
|
85
|
+
close(): void;
|
|
86
|
+
private fire;
|
|
87
|
+
private onSchemeChange;
|
|
88
|
+
private onScheme;
|
|
89
|
+
private boot;
|
|
90
|
+
private applyTokens;
|
|
91
|
+
}
|
|
92
|
+
declare function define(): void;
|
|
93
|
+
interface WidgetHandle {
|
|
94
|
+
element: CharacterXYZElement;
|
|
95
|
+
open(view?: 'chat' | 'call'): void;
|
|
96
|
+
close(): void;
|
|
97
|
+
destroy(): void;
|
|
98
|
+
}
|
|
99
|
+
/** Put the widget on the page. One per page is the norm; a second replaces nothing. */
|
|
100
|
+
declare function mount(options: MountOptions): WidgetHandle;
|
|
101
|
+
|
|
102
|
+
export { CharacterXYZElement, type ColorMode, DEFAULTS, type Display, type LauncherStyle, type MountOptions, type Position, TAG, type WidgetConfig, type WidgetHandle, applyLayer, define, inkFor, mount };
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,356 @@
|
|
|
1
|
+
var _n=Object.defineProperty;var bn=(t,e,n)=>e in t?_n(t,e,{enumerable:!0,configurable:!0,writable:!0,value:n}):t[e]=n;var Y=(t,e,n)=>bn(t,typeof e!="symbol"?e+"":e,n);var xn=Object.defineProperty,vn=(t,e,n)=>e in t?xn(t,e,{enumerable:!0,configurable:!0,writable:!0,value:n}):t[e]=n,b=(t,e,n)=>vn(t,typeof e!="symbol"?e+"":e,n),J=null;function st(){return(!J||J.state==="closed")&&(J=new AudioContext({latencyHint:"interactive"})),J.state==="suspended"&&J.resume().catch(()=>{}),J}var yn=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=st(),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?.())}},kn=`
|
|
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 wn(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 Cn(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,wn(d))},o,l;try{let d=URL.createObjectURL(new Blob([kn],{type:"application/javascript"}));try{await n.audioWorklet.addModule(d)}finally{URL.revokeObjectURL(d)}let u=new AudioWorkletNode(n,"cxyz-mic");u.port.onmessage=m=>r(m.data),o=u,l=()=>{u.port.onmessage=null}}catch{let d=n.createScriptProcessor(4096,1,1),u=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>=u){m-=u;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 p=n.createGain();return p.gain.value=0,o.connect(p).connect(n.destination),n.state==="suspended"&&await n.resume().catch(()=>{}),{get muted(){return a},setMuted(d){a=d;for(let u of e.getAudioTracks())u.enabled=!d},stop(){l();try{i.disconnect(),o.disconnect()}catch{}for(let d of e.getTracks())d.stop();n.close().catch(()=>{})}}}var Oe=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={}}},z=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 Sn(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 An(t){let e="";try{let n=await t.json();typeof n?.message=="string"&&(e=n.message)}catch{}return new z(Sn(t.status),e||`Request failed (${t.status})`,t.status)}async function he(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 z("network","Could not reach Character XYZ. Check your connection.")}if(!a.ok)throw await An(a);return a}async function te(t,e,n={}){return(await(await he(t,e,n)).json()).data}async function ot(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:p,done:d}=await a.read();if(d)break;o+=r.decode(p,{stream:!0}),o=at(o,e)}o+=r.decode(),at(o+`
|
|
34
|
+
|
|
35
|
+
`,e)}finally{n?.removeEventListener("abort",l)}}function at(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 u=d.indexOf(":"),m=u===-1?d:d.slice(0,u),c=u===-1?"":d.slice(u+1).replace(/^ /,"");m==="event"?r=c:m==="data"&&o.push(c)}if(!o.length)continue;let l=o.join(`
|
|
40
|
+
`),p=l;try{p=JSON.parse(l)}catch{}e({event:r,data:p})}return n}function Mn(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 Tn=.09,In=350,En=25e3,zn=()=>({phase:"idle",callId:null,position:null,etaSeconds:null,holdSeconds:null,maxSeconds:null,startedAt:null,endReason:null,muted:!1,speaking:!1,agentState:"idle",error:null}),$n=class extends Oe{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",zn()),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"}),st();try{this.mic=await Cn({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 te(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 z?t:new z("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 he(this.apiUrl,`/sdk/v1/calls/${encodeURIComponent(this.s.callId)}/events`,{token:e,signal:this.eventsAbort.signal});t=0,await ot(n,i=>this.onServerEvent(i.event,i.data),this.eventsAbort.signal)}catch(e){if(e?.name==="AbortError")return;if(e instanceof z&&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"}),En),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>Tn){if(this.loudSince??(this.loudSince=i),i-this.loudSince>=In){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=Mn(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 yn({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 he(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})}},Un=0,rt=t=>`${t}_${Date.now().toString(36)}_${(Un++).toString(36)}`,Ln=class extends Oe{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 te(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 z("invalid","Say something first.");if(this.busy)throw new z("rate_limited","Wait for the reply first.");this.setBusy(!0);let n={id:rt("local"),role:"visitor",text:e,createdAt:new Date().toISOString()},i={id:rt("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 he(this.apiUrl,"/sdk/v1/chat/messages",{method:"POST",body:{text:e},token:a,signal:this.abort.signal}),o=null,l=null;if(await ot(r,({event:d,data:u})=>{let m=u;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 z("unknown",l??"The reply was cut off. Try again.");let p=o;return this.replace(i.id,p),p}catch(a){let r=a instanceof z?a:new z("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 z("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)}},Pn=()=>{let t=new Map;return{get:e=>t.get(e)??null,set:(e,n)=>{t.set(e,n)}}},Rn=()=>({get(t){try{return globalThis.localStorage?.getItem(t)??null}catch{return null}},set(t,e){try{globalThis.localStorage?.setItem(t,e)}catch{}}}),Fn=60,Dn=class{constructor(t){if(b(this,"src",t),b(this,"current",null),b(this,"inflight",null),!t.publishableKey&&!t.getSessionToken)throw new z("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-Fn>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 te(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 te(this.src.apiUrl,"/sdk/v1/session",{token:t}),token:t}}},On="https://api.character.xyz",He=class lt extends Oe{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 Ln(e,n)}static async init(e){let n=(e.apiUrl??On).replace(/\/+$/,"");if(e.publishableKey&&/^cxyz_sk_/.test(e.publishableKey))throw new z("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"?Pn():e.storage&&typeof e.storage=="object"?e.storage:Rn(),a=new Dn({apiUrl:n,agentId:e.agentId,publishableKey:e.publishableKey,getSessionToken:e.getSessionToken,store:i}),r=await a.refresh();return new lt(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 te(this.apiUrl,"/sdk/v1/agent/video-avatar",{token:e})}async startCall(e={}){if(this.destroyed)throw new z("invalid","This client was destroyed.");if(!this.features.call)throw new z("forbidden","Calls are not available on this site.");if(this.call)return this.call;let n=new $n(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 ye,C,ht,Hn,V,ct,ft,gt,We,ge,ne,mt,qe,Ye,Ne,Wn,be={},xe=[],Yn=/acit|ex(?:s|g|n|p|$)|rph|grid|ows|mnc|ntw|ine[ch]|zoo|^ord|itera/i,ke=Array.isArray;function B(t,e){for(var n in e)t[n]=e[n];return t}function Be(t){t&&t.parentNode&&t.parentNode.removeChild(t)}function Nn(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?ye.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 me(t,o,i,a,null)}function me(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??++ht,__i:-1,__u:0};return a==null&&C.vnode!=null&&C.vnode(r),r}function M(t){return t.children}function _e(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 qn(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),Ve(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,yt(i,r,a),e.__e=e.__=null,r.__e!=n&&_t(r)}}function _t(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}),_t(t)}function dt(t){(!t.__d&&(t.__d=!0)&&V.push(t)&&!ve.__r++||ct!=C.debounceRendering)&&((ct=C.debounceRendering)||ft)(ve)}function ve(){try{for(var t,e=1;V.length;)V.length>e&&V.sort(gt),t=V.shift(),e=V.length,qn(t)}finally{V.length=ve.__r=0}}function bt(t,e,n,i,a,r,o,l,p,d,u){var m,c,h,_,v,g,x=i&&i.__k||xe,k=e.length;for(p=Bn(n,e,x,p,k),m=0;m<k;m++)(h=n.__k[m])!=null&&(c=h.__i!=-1&&x[h.__i]||be,h.__i=m,g=Ve(t,h,c,a,r,o,l,p,d,u),_=h.__e,h.ref&&c.ref!=h.ref&&(c.ref&&je(c.ref,null,h),u.push(h.ref,h.__c||_,h)),v==null&&_!=null&&(v=_),4&h.__u?(p=xt(h,p,t),c.__e&&(c.__e=null)):typeof h.type=="function"&&g!==void 0?p=g:_&&(p=_.nextSibling),h.__u&=-7);return n.__e=v,p}function Bn(t,e,n,i,a){var r,o,l,p,d,u=n.length,m=u,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]=me(null,o,null,null,null):ke(o)?o=t.__k[r]=me(M,{children:o},null,null,null):o.constructor===void 0&&o.__b>0?o=t.__k[r]=me(o.type,o.props,o.key,o.ref?o.ref:null,o.__v):t.__k[r]=o,p=r+c,o.__=t,o.__b=t.__b+1,l=null,(d=o.__i=Vn(o,n,p,m))!=-1&&(m--,(l=n[d])&&(l.__u|=2)),l==null||l.__v==null?(d==-1&&(a>u?c--:a<u&&c++),typeof o.type!="function"&&(o.__u|=4)):d!=p&&(d==p-1?c--:d==p+1?c++:(d>p?c--:c++,o.__u|=4))):t.__k[r]=null;if(m)for(r=0;r<u;r++)(l=n[r])!=null&&(2&l.__u)==0&&(l.__e==i&&(i=K(l)),wt(l,l));return i}function xt(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=xt(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 Vn(t,e,n,i){var a,r,o,l=t.key,p=t.type,d=e[n],u=d!=null&&(2&d.__u)==0;if(d===null&&l==null||u&&l==d.key&&p==d.type)return n;if(i>(u?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&&p==d.type)return o}return-1}function pt(t,e,n){e[0]=="-"?t.setProperty(e,n??""):t[e]=n==null?"":typeof n!="number"||Yn.test(e)?n:n+"px"}function fe(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||pt(t.style,e,"");if(n)for(e in n)i&&n[e]==i[e]||pt(t.style,e,n[e])}else if(e[0]=="o"&&e[1]=="n")r=e!=(e=e.replace(mt,"$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[ne]=i[ne]:(n[ne]=qe,t.addEventListener(e,r?Ne:Ye,r)):t.removeEventListener(e,r?Ne:Ye,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 ut(t){return function(e){if(this.l){var n=this.l[e.type+t];if(e[ge]==null)e[ge]=qe++;else if(e[ge]<n[ne])return;return n(C.event?C.event(e):e)}}}function Ve(t,e,n,i,a,r,o,l,p,d){var u,m,c,h,_,v,g,x,k,E,R,F,O,U,D,W,y=e.type;if(e.constructor!==void 0)return null;128&n.__u&&(p=!!(32&n.__u),r=[l=e.__e=n.__e]),(u=C.__b)&&u(e);e:if(typeof y=="function"){m=o.length;try{if(k=e.props,E=y.prototype&&y.prototype.render,R=(u=y.contextType)&&i[u.__c],F=u?R?R.props.value:u.__:i,n.__c?x=(c=e.__c=n.__c).__=c.__E:(E?e.__c=c=new y(k,F):(e.__c=c=new _e(k,F),c.constructor=y,c.render=Kn),R&&R.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(P){P&&(P.__=e)}),xe.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,U=0,E)c.state=c.__s,c.__d=!1,O&&O(e),u=c.render(c.props,c.state,c.context),xe.push.apply(c.__h,c._sb),c._sb=[];else do c.__d=!1,O&&O(e),u=c.render(c.props,c.state,c.context),c.state=c.__s;while(c.__d&&++U<25);c.state=c.__s,c.getChildContext!=null&&(i=B(B({},i),c.getChildContext())),E&&!h&&c.getSnapshotBeforeUpdate!=null&&(g=c.getSnapshotBeforeUpdate(_,v)),D=u!=null&&u.type===M&&u.key==null?kt(u.props.children):u,l=bt(t,ke(D)?D:[D],e,n,i,a,r,o,l,p,d),c.base=e.__e,e.__u&=-161,c.__h.length&&o.push(c),x&&(c.__E=c.__=null)}catch(P){if(o.length=m,e.__v=null,p||r!=null){if(P.then){for(e.__u|=p?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--;)Be(r[W])}else e.__e=n.__e;e.__k==null&&(e.__k=n.__k||[]),P.then||vt(e),C.__e(P,e,n)}}else r==null&&e.__v==n.__v?(e.__k=n.__k,e.__e=n.__e):l=e.__e=jn(n.__e,e,n,i,a,r,o,p,d);return(u=C.diffed)&&u(e),128&e.__u?void 0:l}function vt(t){t&&(t.__c&&(t.__c.__e=!0),t.__k&&t.__k.some(vt))}function yt(t,e,n){for(var i=0;i<n.length;i++)je(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 kt(t){return typeof t!="object"||t==null||t.__b>0?t:ke(t)?t.map(kt):t.constructor!==void 0?null:B({},t)}function jn(t,e,n,i,a,r,o,l,p){var d,u,m,c,h,_,v,g=n.props||be,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&&ye.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||fe(t,d,null,h,a);for(d in x)h=x[d],d=="children"?c=h:d=="dangerouslySetInnerHTML"?u=h:d=="value"?_=h:d=="checked"?v=h:l&&typeof h!="function"||g[d]===h||fe(t,d,h,g[d],a);if(u)l||m&&(u.__html==m.__html||u.__html==t.innerHTML)||(t.innerHTML=u.__html),e.__k=[];else if(m&&(t.innerHTML=""),bt(e.type=="template"?t.content:t,ke(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,p),r!=null)for(d=r.length;d--;)Be(r[d]);l&&k!="textarea"||(d="value",k=="progress"&&_==null?t.removeAttribute("value"):_!=null&&(_!==t[d]||k=="progress"&&!_||k=="option"&&_!=g[d])&&fe(t,d,_,g[d],a),d="checked",v!=null&&v!=t[d]&&fe(t,d,v,g[d],a))}return t}function je(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 wt(t,e,n){var i,a;if(C.unmount&&C.unmount(t),(i=t.ref)&&(i.current&&i.current!=t.__e||je(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]&&wt(i[a],e,n||typeof t.type!="function");n||Be(t.__e),t.__c=t.__=t.__e=void 0}function Kn(t,e,n){return this.constructor(t,n)}function Ke(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=[],Ve(e,t=(!i&&n||e).__k=Nn(M,null,[t]),a||be,be,e.namespaceURI,!i&&n?[n]:a?null:e.firstChild?ye.call(e.childNodes):null,r,!i&&n?n:a?a.__e:e.firstChild,i,o),yt(r,t,o),t.props.children=null}ye=xe.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}},ht=0,Hn=function(t){return t!=null&&t.constructor===void 0},_e.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),dt(this))},_e.prototype.forceUpdate=function(t){this.__v&&(this.__e=!0,t&&this.__h.push(t),dt(this))},_e.prototype.render=M,V=[],ft=typeof Promise=="function"?Promise.prototype.then.bind(Promise.resolve()):setTimeout,gt=function(t,e){return t.__v.__b-e.__v.__b},ve.__r=0,We=Math.random().toString(8),ge="__d"+We,ne="__a"+We,mt=/(PointerCapture)$|Capture$/i,qe=0,Ye=ut(!1),Ne=ut(!0),Wn=0;var Z,A,Xe,Ct,ie=0,$t=[],T=C,St=T.__b,At=T.__r,Mt=T.diffed,Tt=T.__c,It=T.unmount,Et=T.__;function Ce(t,e){T.__h&&T.__h(A,t,ie||e),ie=0;var n=A.__H||(A.__H={__:[],__h:[]});return t>=n.__.length&&n.__.push({}),n.__[t]}function $(t){return ie=1,Xn(Pt,t)}function Xn(t,e,n){var i=Ce(Z++,2);if(i.t=t,!i.__c&&(i.__=[n?n(e):Pt(void 0,e),function(l){var p=i.__N?i.__N[0]:i.__[0],d=i.t(p,l);p!==d&&(i.__N=[d,i.__[1]],i.__c.setState({}))}],i.__c=A,!A.__f)){var a=function(l,p,d){if(!i.__c.__H)return!0;var u=!1,m=i.__c.props!==l;if(i.__c.__H.__.some(function(h){if(h.__N){u=!0;var _=h.__[0];h.__=h.__N,h.__N=void 0,_!==h.__[0]&&(m=!0)}}),r){var c=r.call(this,l,p,d);return u?c||m:c}return!u||m};A.__f=!0;var r=A.shouldComponentUpdate,o=A.componentWillUpdate;A.componentWillUpdate=function(l,p,d){if(this.__e){var u=r;r=void 0,a(l,p,d),r=u}o&&o.call(this,l,p,d)},A.shouldComponentUpdate=a}return i.__N||i.__}function I(t,e){var n=Ce(Z++,3);!T.__s&&Ze(n.__H,e)&&(n.__=t,n.u=e,A.__H.__h.push(n))}function Ut(t,e){var n=Ce(Z++,4);!T.__s&&Ze(n.__H,e)&&(n.__=t,n.u=e,A.__h.push(n))}function H(t){return ie=5,Lt(function(){return{current:t}},[])}function Lt(t,e){var n=Ce(Z++,7);return Ze(n.__H,e)&&(n.__=t(),n.__H=e,n.__h=t),n.__}function Se(t,e){return ie=8,Lt(function(){return t},e)}function Jn(){for(var t;t=$t.shift();){var e=t.__H;if(t.__P&&e)try{e.__h.some(we),e.__h.some(Je),e.__h=[]}catch(n){e.__h=[],T.__e(n,t.__v)}}}T.__b=function(t){A=null,St&&St(t)},T.__=function(t,e){t&&e.__k&&e.__k.__m&&(t.__m=e.__k.__m),Et&&Et(t,e)},T.__r=function(t){At&&At(t),Z=0;var e=(A=t.__c).__H;e&&(Xe===A?(e.__h=[],A.__h=[],e.__.some(function(n){n.__N&&(n.__=n.__N),n.u=n.__N=void 0})):(e.__h.some(we),e.__h.some(Je),e.__h=[],Z=0)),Xe=A},T.diffed=function(t){Mt&&Mt(t);var e=t.__c;e&&e.__H&&(e.__H.__h.length&&($t.push(e)!==1&&Ct===T.requestAnimationFrame||((Ct=T.requestAnimationFrame)||Zn)(Jn)),e.__H.__.some(function(n){n.u&&(n.__H=n.u,n.u=void 0)})),Xe=A=null},T.__c=function(t,e){e.some(function(n){try{n.__h.some(we),n.__h=n.__h.filter(function(i){return!i.__||Je(i)})}catch(i){e.some(function(a){a.__h&&(a.__h=[])}),e=[],T.__e(i,n.__v)}}),Tt&&Tt(t,e)},T.unmount=function(t){It&&It(t);var e,n=t.__c;n&&n.__H&&(n.__H.__.some(function(i){try{we(i)}catch(a){e=a}}),n.__H=void 0,e&&T.__e(e,n.__v))};var zt=typeof requestAnimationFrame=="function";function Zn(t){var e,n=function(){clearTimeout(i),zt&&cancelAnimationFrame(e),setTimeout(t)},i=setTimeout(n,35);zt&&(e=requestAnimationFrame(n))}function we(t){var e=A,n=t.__c;typeof n=="function"&&(t.__c=void 0,n()),A=e}function Je(t){var e=A;t.__c=t.__(),A=e}function Ze(t,e){return!t||t.length!==e.length||e.some(function(n,i){return n!==t[i]})}function Pt(t,e){return typeof e=="function"?e(t):e}function j(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 Ae(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 Me(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 Ft(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 Rt(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 Dt(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=>Rt(a.replace(/^\s*[-*•]\s+/,"")))}):e.push({t:"p",parts:Rt(n)})}return e}var Ot={cx:.5,cy:.12,span:.06};function Ht(t,e,n){let i=t?.face?.eyes,a=t?.face?.chin;if(!i||!a||!e||!n)return Ot;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}:Ot}var Te={faceFraction:.26,at:{x:.5,y:.5}},Wt={faceFraction:.14,at:{x:.5,y:.34}},Yt={faceFraction:.16,at:{x:.5,y:.22}},Nt={fit:"height"};function qt(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 Gn=0;function s(t,e,n,i,a,r){e||(e={});var o,l,p=e;if("ref"in p)for(l in p={},e)l=="ref"?o=e[l]:p[l]=e[l];var d={type:t,props:p,key:n,ref:o,__k:null,__:null,__b:0,__e:null,__c:null,constructor:void 0,__v:--Gn,__i:-1,__u:0,__source:a,__self:r};if(typeof t=="function"&&(o=t.defaultProps))for(l in o)p[l]===void 0&&(p[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}),ae=({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"})),G=({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"})),Bt=({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"})),Vt=({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"})]})),Ie=({size:t=18})=>N(t,s("path",{d:"M6 6l12 12M18 6L6 18"})),Kt=({size:t=18})=>N(t,s("path",{d:"M12 19V5M5.5 11.5L12 5l6.5 6.5"})),Xt=({size:t=18})=>N(t,s("path",{d:"M15 5l-7 7 7 7"})),Jt=({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"})),Zt=({size:t=14})=>N(t,s("path",{d:"M4 12a8 8 0 1 0 2.3-5.6M4 4v4h4"}));var Ge={current:null};function Qn(t){return t?t.speaking?"speaking":t.agentState==="thinking"?"reasoning":t.agentState==="listening"||t.phase==="live"?"listening":"idle":"idle"}function Gt({client:t,call:e,state:n,src:i,onStatus:a}){let r=H(null),[o,l]=$(!1),p=H(!1),d=(()=>{try{return new URL(i).origin}catch{return null}})(),u=(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"?(p.current=!0,l(!0),t.videoAvatar().then(x=>{c||(x?u({type:"init",avatar:x}):a("unavailable"))}).catch(()=>!c&&a("unavailable"))):g.type==="ready"?(Ge.current=typeof g.faceEmotion=="string"?g.faceEmotion:null,a("ready")):g.type==="unavailable"&&a("unavailable"))};window.addEventListener("message",h);let _=setTimeout(()=>!c&&!p.current&&a("unavailable"),15e3);return()=>{c=!0,clearTimeout(_),window.removeEventListener("message",h)}},[t,d]);let m=Qn(n);return I(()=>{o&&u({type:"state",state:m})},[m,o]),I(()=>{if(!e||!o)return;let c=[e.on("face",({corr:v,payload:g})=>u({type:"batch",corr:v,payload:g},[g.buffer])),e.on("line",({corr:v,event:g})=>{u(g==="audible"?{type:"audible",corr:v,ms:e.audible()?.ms??0}:{type:"end",corr:v})})],h=0,_=()=>{let v=e.audible();v&&u({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 ei(){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 ti=()=>typeof matchMedia<"u"&&matchMedia("(prefers-reduced-motion: reduce)").matches;function re({agent:t,shot:e,talking:n=!1,still:i=!1,class:a}){let r=H(null),[o,l]=$({w:0,h:0}),[p,d]=$(null),[u,m]=$({}),c=t.video,h=c?.anchor?.alphaUrl??c?.anchor?.url??null,_=!i&&!ti()&&ei(),v=c?.clips.idle?.alphaUrl??null,g=c?.clips.talking?.alphaUrl??v;if(Ut(()=>{let U=r.current;if(!U)return;let D=()=>l({w:U.clientWidth,h:U.clientHeight});if(D(),typeof ResizeObserver>"u")return;let W=new ResizeObserver(D);return W.observe(U),()=>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=p?p.w/p.h:.75,k=Ht(c,p?.w??0,p?.h??0),E=o.w&&o.h?qt(k,x,o.w,o.h,e):null,R=E?{width:`${E.width}px`,height:`${E.height}px`,left:`${E.left}px`,top:`${E.top}px`}:{opacity:0},F=_&&!!v&&!!u.idle,O=_&&!!g&&g!==v&&!!u.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:{...R,opacity:E?F?0:1:0},onLoad:U=>{let D=U.currentTarget;d({w:D.naturalWidth,h:D.naturalHeight})}}),_&&v?s(Qt,{src:v,style:R,visible:F&&!O,onReady:()=>m(U=>({...U,idle:!0}))}):null,_&&g&&g!==v?s(Qt,{src:g,style:R,visible:O,onReady:()=>m(U=>({...U,talk:!0}))}):null]})}function Qt({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 Qe="cxyz:greeted",en="cxyz:introduced";function se(t,e){try{return e!==void 0&&localStorage.setItem(t,e),localStorage.getItem(t)}catch{return null}}function ni(){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 ii(t){let[e,n]=$(t.chat.messages),[i,a]=$(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 ai(t){let[e,n]=$(t.call),[i,a]=$(t.call?.state??null),[r,o]=$([]);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",p=>o(d=>[...d.filter(u=>u.id!==p.id),p].slice(-4))),e.on("captionRemoved",p=>o(d=>d.filter(u=>u.id!==p)))];return()=>l.forEach(p=>p())},[e]),{call:e,state:i,captions:r,reset:()=>n(null)}}function ri(t,e){let[n,i]=$(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 si(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 tn({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 oi({text:t}){return s(M,{children:Dt(t).map((e,n)=>e.t==="ul"?s("ul",{children:e.items.map((i,a)=>s("li",{children:s(tn,{parts:i})},a))},n):s("p",{children:s(tn,{parts:e.parts})},n))})}function nn({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,[p,d]=$(e.open?o?"chat":"call":"closed"),[u,m]=$(!1),[c,h]=$(!1),{messages:_,busy:v}=ii(t),{call:g,state:x,captions:k,reset:E}=ai(t),[R,F]=$(""),O=H(null),U=H(null),D=H(null),W=e.subtitle??a.tagline,y=a.name||"Assistant",P=Se(f=>{d(f),i(f)},[i]),X=Se(()=>{m(!0),setTimeout(()=>{m(!1),P("closed")},200)},[P]),q=Se((f=o?"chat":"call")=>{h(!1),se(Qe,"1"),P(f),f==="chat"&&t.chat.load().catch(()=>{})},[o,t,P]);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||se(Qe))return;let f=setTimeout(()=>h(!0),e.greetingDelay*1e3);return()=>clearTimeout(f)},[e.greeting,e.greetingDelay]);let[Ue,ln]=$(()=>!se(en));I(()=>{if(!Ue)return;let f=setTimeout(()=>{ln(!1),se(en,"1")},5e3);return()=>clearTimeout(f)},[Ue]),I(()=>{if(p==="closed")return;let f=L=>{L.key==="Escape"&&X()};return window.addEventListener("keydown",f),()=>window.removeEventListener("keydown",f)},[p,X]),I(()=>{let f=O.current;f&&(f.scrollTop=f.scrollHeight)},[_,p,x?.phase]),I(()=>{p==="chat"&&setTimeout(()=>U.current?.focus({preventScroll:!0}),60)},[p]);let Q=e.face&&!!a.video,[de,cn]=$("loading"),w=x?.phase??"idle";I(()=>{if(!(w!=="ready"||!g)){if(ni(),p==="call"){if(!Q||de!=="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 L=()=>{document.title=f,document.removeEventListener("visibilitychange",L)};document.addEventListener("visibilitychange",L)}}},[w,g,p,y,Q,de]);let nt=w==="live"||w==="connecting";si(g,D,nt&&p==="call");let pe=ri(x?.startedAt??null,w==="live"),Le=li(g,x?.position??1),ue=async()=>{P("call");try{await t.startCall({autoAccept:!1,...Q?{face:{emotion:()=>Ge.current}}:{}})}catch{}},Pe=async f=>{let L=f.trim();if(!(!L||v)){F(""),U.current&&(U.current.style.height="");try{await t.chat.send(L)}catch{}}},dn=_.length>0&&_[_.length-1].role==="agent"&&_[_.length-1].streaming;if(p==="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:L=>{L.stopPropagation(),h(!1),se(Qe,"1")},children:s(Ie,{size:14})})]}):null,s("button",{class:`presence presence--${e.display} ${f?"presence--live":""}`,part:"presence","aria-label":f?w==="queued"?`You are ${j(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(re,{agent:a,shot:e.display==="full"?Nt:e.display==="half"?Yt:Te})}),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"?`${j(x?.position??1)} in line`:"Back to your call":o?`Chat with ${y}`:`Call ${y}`}):null]}),e.launcher==="bubble"?null:s("div",{class:`acts ${Ue?"acts--labelled":""}`,part:"actions",children:[o?s("button",{class:"act","aria-label":`Chat with ${y}`,onClick:()=>q("chat"),children:[s(ae,{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 ${j(x?.position??1)} in line. Open your call`:"Back to your call":`Call ${y}`,onClick:()=>f?q("call"):void ue(),children:[s(G,{size:20}),s("span",{class:"act__label","aria-hidden":"true",children:f?w==="queued"?`${j(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 pn=s("div",{class:"head",part:"header",children:[s("div",{class:"head__face",children:s(re,{agent:a,shot:Te,talking:!!dn})}),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&&p==="chat"?s("button",{class:"icon-btn icon-btn--accent","aria-label":`Call ${y}`,title:`Call ${y}`,onClick:()=>g&&w!=="ended"?P("call"):void ue(),children:s(G,{size:18})}):null,s("button",{class:"icon-btn","aria-label":"Close",onClick:X,children:s(Ie,{})})]});if(p==="chat")return s("div",{class:`panel ${u?"is-closing":""}`,part:"panel",role:"dialog","aria-label":`Chat with ${y}`,children:[pn,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:j(x?.position??1)})," in line for a call \xB7 ",Ae(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(),P("call")},children:"Join"}):s("button",{class:"btn",onClick:()=>P("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(re,{agent:a,shot:Te})}),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"?P("call"):void ue(),children:[s(G,{size:17})," Call ",y]}):null,e.suggestions.length?s("div",{class:"chips",children:e.suggestions.map(f=>s("button",{class:"chip",onClick:()=>{Pe(f)},children:[s(Jt,{}),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(oi,{text:f.text}):f.text}),f.failed?s("button",{class:"msg__retry",onClick:()=>{t.chat.retry(f.id).catch(()=>{})},children:[s(Zt,{})," Not sent \xB7 Retry"]}):null]},f.id))]}),s("form",{class:"compose",part:"composer",onSubmit:f=>{f.preventDefault(),Pe(R)},children:s("div",{class:"compose__box",children:[s("textarea",{ref:U,rows:1,value:R,maxLength:2e3,placeholder:e.placeholder,"aria-label":"Message",onInput:f=>{let L=f.currentTarget;F(L.value),L.style.height="auto",L.style.height=`${Math.min(120,L.scrollHeight)}px`},onKeyDown:f=>{f.key==="Enter"&&!f.shiftKey&&!f.isComposing&&(f.preventDefault(),Pe(R))}}),s("button",{class:"send",type:"submit","aria-label":"Send",disabled:!R.trim()||v,children:s(Kt,{})})]})}),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,Re=S?.position??1,un=Le>1?(Le-Re)/(Le-1):0,Fe=74,it=2*Math.PI*Fe,ee=S?.maxSeconds?S.maxSeconds-pe:null,hn=S?.agentState??"idle",fn=S?.speaking?"Speaking":hn==="thinking"?"Thinking\u2026":"Listening",gn=!S||w==="ended"||w==="idle",De=Ft(S?.endReason??null,y);return s("div",{class:`panel ${u?"is-closing":""}`,part:"panel",role:"dialog","aria-label":`Call with ${y}`,children:s("div",{class:`stage ${Q&&de==="ready"?"stage--face":""}`,ref:D,children:[s("div",{class:"stage__figure",style:{opacity:w==="queued"?.35:1,transition:"opacity .6s"},children:[s(re,{agent:a,shot:Wt,talking:!!S?.speaking}),Q?s("div",{class:`stage__face ${de==="ready"?"is-ready":""}`,children:s(Gt,{client:t,call:g,state:S,src:e.faceUrl,onStatus:cn})}):null]}),nt?s("div",{class:"voice"}):null,s("div",{class:"stage__veil"}),s("div",{class:"stage__top",children:[w==="live"?s("span",{class:`badge ${ee!=null&&ee<=60?"badge--warn":""}`,role:"timer","aria-label":"Call time",children:[s("i",{}),ee!=null&&ee<=60?`${Me(ee)} left`:Me(pe)]}):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(ae,{size:18})}):null,s("button",{class:"icon-btn","aria-label":"Minimise",onClick:X,children:s(Ie,{})})]})]}),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 ${j(Re)} in line, ${Ae(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:Fe,fill:"none","stroke-width":"7"}),s("circle",{class:"line__fill",cx:"84",cy:"84",r:Fe,fill:"none","stroke-width":"7","stroke-linecap":"round","stroke-dasharray":it,"stroke-dashoffset":it*(1-Math.max(.06,un))})]}),s("div",{children:[s("div",{class:"line__num",children:j(Re)}),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 ",Ae(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(ae,{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(G,{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,L)=>s("i",{style:{"--k":f}},L))}):null,S?.muted?"You are muted":fn]}),s("div",{class:"captions",children:k.slice(-2).map((f,L,mn)=>s("div",{class:`captions__line ${L===mn.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(Vt,{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(Bt,{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(Xt,{size:22})}),s("span",{class:"round__label",children:"Interrupt"})]}):null]})]}):null,gn?s(M,{children:[s("div",{class:"title",children:S?De.title:`Call ${y}`}),s("div",{class:"note",children:S?S.endReason==="hangup"&&pe?`${Me(pe)} \xB7 ${De.body}`:S.error??De.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(),ue()},children:[s(G,{size:18})," ",S?"Call again":"Start call"]}):null,o?s("button",{class:"btn",onClick:()=>q("chat"),children:[s(ae,{size:18})," Chat"]}):null]})]}):null]})]})})}function li(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 tt={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"},oe=(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},le=t=>{if(typeof t=="boolean")return t;if(t==="true"||t===""||t==="1")return!0;if(t==="false"||t==="0")return!1},et=(t,e=200)=>typeof t=="string"?t.slice(0,e):void 0;function ci(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 di(t){if(typeof t!="string")return;let e=t.trim();return/^[\w\s,"'-]{1,120}$/.test(e)?e:void 0}function ce(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=ci(e.accent)??n.accent,n.radius=oe(e.radius,0,40)??n.radius,n.font=di(e.font)??n.font,e.subtitle===null?n.subtitle=null:n.subtitle=et(e.subtitle,80)??n.subtitle,n.greeting=et(e.greeting,160)??n.greeting,n.greetingDelay=oe(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=et(e.placeholder,60)??n.placeholder,n.showChat=le(e.showChat)??n.showChat,n.showCall=le(e.showCall)??n.showCall,n.branding=le(e.branding)??n.branding,n.offsetX=oe(e.offsetX,0,200)??n.offsetX,n.offsetY=oe(e.offsetY,0,200)??n.offsetY,n.zIndex=oe(e.zIndex,0,2147483647)??n.zIndex,n.open=le(e.open)??n.open,n.face=le(e.face)??n.face,typeof e.faceUrl=="string"&&/^https?:\/\/[^\s"'<>]+$/.test(e.faceUrl.trim())&&(n.faceUrl=e.faceUrl.trim()),n}function an(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 rn=`
|
|
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 Ee="character-xyz";function on(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 pi(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 sn(t){for(let e of[document.body,document.documentElement]){if(!e)continue;let n=pi(getComputedStyle(e).backgroundColor);if(n!==null)return n<.22}return!!t?.matches}var ui=["publishable-key","agent","api-url","position","mode","accent","greeting","open"],ze=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=sn(this.mq)?"dark":"light")})}static get observedAttributes(){return ui}connectedCallback(){if(this.booted)return;this.booted=!0;let n=this.shadowRoot??this.attachShadow({mode:"open"}),i=document.createElement("style");i.textContent=rn,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&&Ke(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=an(Array.from(this.attributes)),a=n.publishableKey??i.publishableKey;try{this.client=await He.init({publishableKey:a,getSessionToken:n.getSessionToken,agentId:n.agentId??i.agent,apiUrl:n.apiUrl??i.apiUrl,storage:n.storage})}catch(l){let p=l instanceof z?l:new z("unknown",String(l?.message??l));console.warn(`[characterxyz] widget not shown: ${p.message}`),this.fire("cx-error",{code:p.code,message:p.message});return}if(!this.isConnected){this.client.destroy();return}let r=this.client,o=ce(tt,r.appearance);if(o=ce(o,i),o=ce(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",p=>this.fire("cx-call",{phase:p.phase,position:p.position,endReason:p.endReason}))}),r.on("error",l=>this.fire("cx-error",{code:l.code,message:l.message})),this.style.display="",Ke(s(nn,{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=sn(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",on(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 $e(){typeof customElements<"u"&&!customElements.get(Ee)&&customElements.define(Ee,ze)}function hi(t){$e();let e=document.createElement(Ee);return e.options=t,(t.container??document.body).appendChild(e),{element:e,open:n=>e.open(n),close:()=>e.close(),destroy:()=>e.remove()}}$e();export{He as CharacterXYZ,ze as CharacterXYZElement,z as CxError,tt as DEFAULTS,Ee as TAG,ce as applyLayer,$e as define,on as inkFor,hi as mount};
|
|
356
|
+
//# sourceMappingURL=index.js.map
|