@prodantix/sdk 0.2.0-beta.378 → 0.3.0-beta.379

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/dist/chat.cjs CHANGED
@@ -1,4 +1,10 @@
1
- 'use strict';var K=Object.defineProperty;var G=(n,e,t)=>e in n?K(n,e,{enumerable:true,configurable:true,writable:true,value:t}):n[e]=t;var c=(n,e,t)=>G(n,typeof e!="symbol"?e+"":e,t);function I(n){if(n)return n;let e=globalThis.fetch;if(typeof e=="function")return e.bind(globalThis)}function F(n){return n.replace(/\/+$/,"")}var q="X-Prodantix-Conversation-Token",L="prodantix.chat.handle";function Y(){let n=globalThis.localStorage;if(n)return {get:e=>n.getItem(e),remove:e=>n.removeItem(e),set:(e,t)=>n.setItem(e,t)}}var k=class{constructor(e){this.options=e;c(this,"fetchImpl");c(this,"host");c(this,"storage");c(this,"handle");c(this,"identity",null);this.fetchImpl=I(e.fetchImpl),this.host=F(e.host),this.storage=e.storage??Y(),this.handle=this.readHandle();}get hasThread(){return this.handle!==null}avatarUrl(e){return e.startsWith("/")?`${this.host}${e}?api_key=${encodeURIComponent(this.options.apiKey)}`:e}get socketAuth(){return this.handle?{conversationId:this.handle.conversationId,conversationToken:this.handle.token,projectKey:this.options.apiKey}:null}identify(e){this.identity=e;}async ensureThread(e){if(this.handle)return true;let t=await this.request("POST","/v1/conversations",{body:{distinctId:this.options.distinctId,subject:e,userHash:this.identity?.userHash,userId:this.identity?.userId}});return !t?.conversationId||!t.token?false:(this.handle={conversationId:t.conversationId,token:t.token},this.storage?.set(L,JSON.stringify(this.handle)),true)}async send(e,t){if(!await this.ensureThread())return null;let r=this.handle;return r?(await this.request("POST",`/v1/conversations/${encodeURIComponent(r.conversationId)}/turns`,{body:{body:e,pageContext:t},token:r.token}))?.turn??null:null}async load(){let e=this.handle;return e?this.request("GET",`/v1/conversations/${encodeURIComponent(e.conversationId)}`,{token:e.token}):null}readHandle(){let e=this.storage?.get(L);if(!e)return null;try{let t=JSON.parse(e);if(typeof t.conversationId=="string"&&typeof t.token=="string")return {conversationId:t.conversationId,token:t.token}}catch{}return this.storage?.remove(L),null}async request(e,t,r={}){let a=this.fetchImpl;if(!a)return this.options.onError?.(new Error("no fetch available for prodantix chat")),null;let s={authorization:`Bearer ${this.options.apiKey}`,"content-type":"application/json"};r.token&&(s[q]=r.token);try{let o=await a(`${this.host}${t}`,{body:r.body===void 0?void 0:JSON.stringify(r.body),headers:s,method:e}),i=await o.text();return o.ok?i?JSON.parse(i):{}:(this.options.onError?.(new Error(`prodantix chat ${t}: ${o.status}`)),null)}catch(o){return this.options.onError?.(o),null}}};var W={Fri:"fri",Mon:"mon",Sat:"sat",Sun:"sun",Thu:"thu",Tue:"tue",Wed:"wed"};function E(n,e){let t=new Intl.DateTimeFormat(void 0,{hour:"2-digit",hour12:false,minute:"2-digit",timeZone:n.timezone,weekday:"short"}).formatToParts(e),r=W[t.find(i=>i.type==="weekday")?.value??""];if(!r)return false;let a=t.find(i=>i.type==="hour")?.value??"",s=t.find(i=>i.type==="minute")?.value??"",o=`${a}:${s}`;return n.windows.some(i=>i.days.includes(r)&&i.open<=o&&o<i.close)}var h={bubbleFill:"filled",bubbleShape:"tailed",composerShape:"round",dayDividers:true,launcherContent:"glyph",launcherFill:"outlined",launcherShape:"circle",launcherSize:"small",nameAvatar:true,namePlacement:"hidden",skin:"standard",stampContent:"time",stampPlacement:"none"},j=["quiet","standard"],J=["round","square"],V=["rounded","tailed"],X=["filled","outlined"],Z=["circle","pill","squircle"],Q=["filled","outlined"],ee=["avatar","glyph","team_faces"],te=["large","medium","small"],ne=["above","hidden","inline"],re=["beside_name","none","under_turn"],ae=["time","time_and_latency"],f=(n,e,t)=>typeof n=="string"&&e.includes(n)?n:t,H=(n,e)=>typeof n=="boolean"?n:e,ie={avatar_circle:["circle","outlined","avatar","large"],circle_filled:["circle","filled","glyph","medium"],circle_outlined:["circle","outlined","glyph","small"],pill_labelled:["pill","filled","glyph","medium"],pill_team:["pill","outlined","team_faces","medium"],squircle_filled:["squircle","filled","glyph","medium"]},oe={above:["above",false],avatar_only:["hidden",true],gutter:["above",true],hidden:["hidden",false],inline:["inline",false]},se={cluster:[true,"none","time"],latency:[false,"beside_name","time_and_latency"],none:[false,"none","time"],trailing:[false,"under_turn","time"],with_name:[false,"beside_name","time"]},le={concierge:["standard","round"],console:["standard","square"],quiet:["quiet","square"]},ce={hairline:["rounded","outlined"],outlined:["rounded","outlined"],rounded:["rounded","filled"],tailed:["tailed","filled"]};function T(n){let e=typeof n=="object"&&n!==null?n:{},t=typeof e.launcherStyle=="string"?e.launcherStyle:void 0,r=t===void 0?void 0:ie[t],a=typeof e.namePlacement=="string"?e.namePlacement:void 0,s=a===void 0?void 0:oe[a],o=typeof e.timestampStyle=="string"?e.timestampStyle:void 0,i=o===void 0?void 0:se[o],u=typeof e.skin=="string"?e.skin:void 0,d=u===void 0?void 0:le[u],l=typeof e.bubbleStyle=="string"?e.bubbleStyle:void 0,p=l===void 0?void 0:ce[l],m={bubbleFill:f(e.bubbleFill,X,p?.[1]??h.bubbleFill),bubbleShape:f(e.bubbleShape,V,p?.[0]??h.bubbleShape),composerShape:f(e.composerShape,J,d?.[1]??h.composerShape),dayDividers:H(e.dayDividers,i?.[0]??h.dayDividers),launcherContent:f(e.launcherContent,ee,r?.[2]??h.launcherContent),launcherFill:f(e.launcherFill,Q,r?.[1]??h.launcherFill),launcherShape:f(e.launcherShape,Z,r?.[0]??h.launcherShape),launcherSize:f(e.launcherSize,te,r?.[3]??h.launcherSize),nameAvatar:H(e.nameAvatar,s?.[1]??h.nameAvatar),namePlacement:f(e.namePlacement,ne,s?.[0]??h.namePlacement),skin:f(e.skin,j,d?.[0]??h.skin),stampContent:f(e.stampContent,ae,i?.[2]??h.stampContent),stampPlacement:f(e.stampPlacement,re,i?.[1]??h.stampPlacement)};return m.stampPlacement==="beside_name"&&m.namePlacement==="hidden"&&(m.stampPlacement="under_turn"),m}function R(n){let e=n.split(/\s+/).filter(r=>r.length>0);return (e.length>1?`${e[0]?.slice(0,1)}${e[1]?.slice(0,1)}`:e[0]?.slice(0,2)??"").toUpperCase()}var de="M20 11.6a7.4 7.4 0 0 1-7.4 7.4H8.2L4 21.8l1-4.1A7.4 7.4 0 1 1 20 11.6Z",pe={large:66,medium:56,small:46},ue={circle:"width:var(--fab-size);height:var(--fab-size);border-radius:calc(var(--fab-size) / 2);",pill:"width:auto;height:var(--fab-size);border-radius:calc(var(--fab-size) / 2);padding:0 22px;gap:10px;",squircle:"width:var(--fab-size);height:var(--fab-size);border-radius:16px;"},he={filled:"background:var(--a);color:#fff;",outlined:"background:var(--paper);border:1px solid var(--hairline);color:var(--ink-2);box-shadow:0 1px 2px rgba(0,0,0,.08);"},me={avatar:"",glyph:".launcher svg{width:calc(var(--fab-size) * 0.375);height:calc(var(--fab-size) * 0.375);}",team_faces:".launcher .faces{display:flex;}.launcher .faces .av{box-shadow:0 0 0 2px var(--paper);}.launcher .faces .av+.av{margin-left:-10px;}"},ge=".launcher .live{width:10px;height:10px;position:absolute;right:3px;bottom:3px;border-radius:50%;background:var(--online);box-shadow:0 0 0 2px var(--paper);}.launcher.closed .live{display:none}",fe={circle:"",pill:".badge{position:static;box-shadow:none}",squircle:""},be={filled:"",outlined:".badge{background:var(--a);top:-7px;right:-7px;min-width:19px;height:19px;font-size:11.5px}"},ye={circle:"",pill:".launcher .label{font-size:14px;font-weight:600;white-space:nowrap;}",squircle:""},xe={circle:"",pill:"@media (max-width:480px){.launcher{width:var(--fab-size);padding:0}.launcher .label{display:none}}",squircle:""};function O(n,e,t,r){return `.launcher{--fab-size:${pe[r]}px;${ue[n]}${he[e]}}${me[t]}${ge}${fe[n]}${be[e]}${ye[n]}${xe[n]}`}function M(n,e,t,r=a=>a){let a=document.createDocumentFragment();if(n==="glyph"||t.length===0){let s=document.createElement("span");return s.innerHTML=`<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="${de}"/></svg>`,a.append(...s.childNodes,N()),a}return n==="avatar"?(a.append($(t[0],e,r),N()),a):(a.append(_(t,e,r),N()),a)}function _(n,e,t=r=>r){let r=document.createElement("span");r.className="faces";for(let a of n.slice(0,2))r.append($(a,e,t));return r}function $(n,e,t){let r=document.createElement("span");if(r.className="av",r.setAttribute("aria-hidden","true"),n&&(r.style.background=n.tone),n?.avatarUrl){let a=document.createElement("img");return a.alt="",a.src=t(n.avatarUrl),r.append(a),r}return r.textContent=n?n.initials:e.agentLabel.slice(0,2).toUpperCase(),r}function N(){let n=document.createElement("span");return n.className="live",n.setAttribute("aria-hidden","true"),n}var ve={agentLabel:"Agent",aiLabel:"AI",awayBody:"We are away right now, but we will reply as soon as we are back.",closeLabel:"Close chat",emptyBody:"We usually reply within a few minutes.",emptyTitle:"Ask us anything.",inputPlaceholder:"Type a message",launcherLabel:"Chat with us",replyTime:"Usually replying in a few minutes",sendLabel:"Send",timeLabel:n=>{let e=new Date(n);return Number.isNaN(e.getTime())?"":`${String(e.getHours()).padStart(2,"0")}:${String(e.getMinutes()).padStart(2,"0")}`},title:"Support",unreadLabel:n=>`${n} unread`},x={accentColor:"#5b5bff",availability:{timezone:"UTC",windows:[]},awayMessage:"",greeting:"",launcherOffsetX:20,launcherOffsetY:20,launcherPosition:"bottom_right",starterPrompts:[],team:[],...h},Se={quiet:".composer{position:relative;padding:10px 12px 12px}.composer input{padding-right:42px}.composer button{position:absolute;top:50%;right:16px;width:34px;min-width:34px;height:34px;padding:0;background:transparent;color:var(--ink);border-radius:7px;transform:translateY(-50%)}.composer button .sendglyph{display:block;width:18px;height:18px}.composer button .sendtext{display:none}.panel{border-radius:8px;box-shadow:0 2px 8px rgba(0,0,0,.12)}.header{background:var(--paper);color:var(--ink);height:44px;padding:0 8px 0 16px;border-bottom:1px solid var(--hairline)}.header h2{font-size:11px;letter-spacing:.11em;text-transform:uppercase;color:var(--ink-3)}.header .status{color:var(--ink-3)}.header .av,.header .status .live{box-shadow:0 0 0 2px var(--paper)}.close{color:var(--ink-2)}",standard:".panel{border-radius:16px;box-shadow:0 16px 40px rgba(0,0,0,.2)}.header{background:var(--a);color:#fff;flex-direction:column;align-items:flex-start;gap:14px;padding:18px 14px 20px 20px}.header h2{font-size:19px;font-weight:640}"},ke={round:".composer{padding:12px 12px 14px;gap:8px}.composer input{height:46px;border-radius:23px;padding:0 16px}.composer button{width:46px;min-width:46px;height:46px;padding:0;border-radius:23px}.composer button .sendglyph{display:block}.composer button .sendtext{display:none}",square:".composer input{height:44px;border-radius:8px;padding:0 12px}"},Ce={rounded:".turn{border-radius:18px;padding:10px 15px}",tailed:".turn.agent,.turn.ai{border-radius:12px 12px 12px 4px}.turn.end_user{border-radius:12px 12px 4px 12px}"},Ee={filled:"",outlined:".turn{background:none;border:1px solid var(--hairline)}.turn.end_user{background:none;border-color:var(--a);color:var(--ink)}"},Te={above:"",hidden:".turn.agent .author,.turn.ai .author:not(.ai){display:none}",inline:".body .author.below{display:block;margin:4px 0 0;font-size:11.5px;font-weight:500;color:var(--ink-2);text-transform:none;letter-spacing:0;opacity:1}"},we=".turn.agent,.turn.ai{display:flex;gap:10px;max-width:100%;background:none;padding:0}.turn .body{background:var(--fill);padding:9px 13px;border-radius:inherit}.author{text-transform:none;letter-spacing:0;font-size:12.5px;font-weight:600;opacity:1}",Ae='.divider{display:flex;align-items:center;gap:10px;margin:0;font-size:11px;opacity:.6}.divider:before,.divider:after{content:"";flex:1;height:1px;background:var(--hairline)}',Le={beside_name:".stamp{font-size:11px;opacity:.7;margin-left:6px}",none:"",under_turn:".stamp{display:block;font-size:11px;opacity:.7;margin-top:4px}.turn.end_user .stamp{text-align:right}"},Ne=".lat{font-size:11px;opacity:.7;margin-left:6px}";function z(n){let e=T(n),t=n.launcherPosition==="bottom_left"?"left":"right",r=n.accentColor;return `${`
1
+ 'use strict';var G=Object.defineProperty;var q=(n,e,t)=>e in n?G(n,e,{enumerable:true,configurable:true,writable:true,value:t}):n[e]=t;var l=(n,e,t)=>q(n,typeof e!="symbol"?e+"":e,t);function F(n){if(n)return n;let e=globalThis.fetch;if(typeof e=="function")return e.bind(globalThis)}function H(n){return n.replace(/\/+$/,"")}var Y="X-Prodantix-Conversation-Token",L="prodantix.chat.handle";function j(){let n=globalThis.localStorage;if(n)return {get:e=>n.getItem(e),remove:e=>n.removeItem(e),set:(e,t)=>n.setItem(e,t)}}var k=class{constructor(e){this.options=e;l(this,"fetchImpl");l(this,"host");l(this,"storage");l(this,"handle");l(this,"identity",null);this.fetchImpl=F(e.fetchImpl),this.host=H(e.host),this.storage=e.storage??j(),this.handle=this.readHandle();}get hasThread(){return this.handle!==null}avatarUrl(e){return e.startsWith("/")?`${this.host}${e}?api_key=${encodeURIComponent(this.options.apiKey)}`:e}get socketAuth(){return this.handle?{conversationId:this.handle.conversationId,conversationToken:this.handle.token,projectKey:this.options.apiKey}:null}identify(e){this.identity=e;}async ensureThread(e){if(this.handle)return true;let t=await this.request("POST","/v1/conversations",{body:{distinctId:this.options.distinctId,subject:e,userHash:this.identity?.userHash,userId:this.identity?.userId}});return !t?.conversationId||!t.token?false:(this.handle={conversationId:t.conversationId,token:t.token},this.storage?.set(L,JSON.stringify(this.handle)),true)}async send(e,t){if(!await this.ensureThread())return null;let a=this.handle;return a?(await this.request("POST",`/v1/conversations/${encodeURIComponent(a.conversationId)}/turns`,{body:{body:e,pageContext:t},token:a.token}))?.turn??null:null}async load(){let e=this.handle;return e?this.request("GET",`/v1/conversations/${encodeURIComponent(e.conversationId)}`,{token:e.token}):null}readHandle(){let e=this.storage?.get(L);if(!e)return null;try{let t=JSON.parse(e);if(typeof t.conversationId=="string"&&typeof t.token=="string")return {conversationId:t.conversationId,token:t.token}}catch{}return this.storage?.remove(L),null}async request(e,t,a={}){let r=this.fetchImpl;if(!r)return this.options.onError?.(new Error("no fetch available for prodantix chat")),null;let o={authorization:`Bearer ${this.options.apiKey}`,"content-type":"application/json"};a.token&&(o[Y]=a.token);try{let s=await r(`${this.host}${t}`,{body:a.body===void 0?void 0:JSON.stringify(a.body),headers:o,method:e}),i=await s.text();return s.ok?i?JSON.parse(i):{}:(this.options.onError?.(new Error(`prodantix chat ${t}: ${s.status}`)),null)}catch(s){return this.options.onError?.(s),null}}};var W={Fri:"fri",Mon:"mon",Sat:"sat",Sun:"sun",Thu:"thu",Tue:"tue",Wed:"wed"};function w(n,e){let t=new Intl.DateTimeFormat(void 0,{hour:"2-digit",hour12:false,minute:"2-digit",timeZone:n.timezone,weekday:"short"}).formatToParts(e),a=W[t.find(i=>i.type==="weekday")?.value??""];if(!a)return false;let r=t.find(i=>i.type==="hour")?.value??"",o=t.find(i=>i.type==="minute")?.value??"",s=`${r}:${o}`;return n.windows.some(i=>i.days.includes(a)&&i.open<=s&&s<i.close)}var u={bubbleFill:"filled",bubbleShape:"tailed",composerShape:"round",dayDividers:true,launcherContent:"glyph",launcherFill:"outlined",launcherShape:"circle",launcherSize:"small",nameAvatar:true,namePlacement:"hidden",skin:"standard",stampContent:"time",stampPlacement:"none"},J=["quiet","standard"],V=["round","square"],X=["rounded","tailed"],Z=["filled","outlined"],Q=["circle","pill","squircle"],ee=["filled","outlined"],te=["avatar","glyph","team_faces"],ne=["large","medium","small"],ae=["above","hidden","inline"],re=["beside_name","none","under_turn"],ie=["time","time_and_latency"],f=(n,e,t)=>typeof n=="string"&&e.includes(n)?n:t,R=(n,e)=>typeof n=="boolean"?n:e,oe={avatar_circle:["circle","outlined","avatar","large"],circle_filled:["circle","filled","glyph","medium"],circle_outlined:["circle","outlined","glyph","small"],pill_labelled:["pill","filled","glyph","medium"],pill_team:["pill","outlined","team_faces","medium"],squircle_filled:["squircle","filled","glyph","medium"]},se={above:["above",false],avatar_only:["hidden",true],gutter:["above",true],hidden:["hidden",false],inline:["inline",false]},le={cluster:[true,"none","time"],latency:[false,"beside_name","time_and_latency"],none:[false,"none","time"],trailing:[false,"under_turn","time"],with_name:[false,"beside_name","time"]},ce={concierge:["standard","round"],console:["standard","square"],quiet:["quiet","square"]},de={hairline:["rounded","outlined"],outlined:["rounded","outlined"],rounded:["rounded","filled"],tailed:["tailed","filled"]};function C(n){let e=typeof n=="object"&&n!==null?n:{},t=typeof e.launcherStyle=="string"?e.launcherStyle:void 0,a=t===void 0?void 0:oe[t],r=typeof e.namePlacement=="string"?e.namePlacement:void 0,o=r===void 0?void 0:se[r],s=typeof e.timestampStyle=="string"?e.timestampStyle:void 0,i=s===void 0?void 0:le[s],h=typeof e.skin=="string"?e.skin:void 0,d=h===void 0?void 0:ce[h],c=typeof e.bubbleStyle=="string"?e.bubbleStyle:void 0,p=c===void 0?void 0:de[c],m={bubbleFill:f(e.bubbleFill,Z,p?.[1]??u.bubbleFill),bubbleShape:f(e.bubbleShape,X,p?.[0]??u.bubbleShape),composerShape:f(e.composerShape,V,d?.[1]??u.composerShape),dayDividers:R(e.dayDividers,i?.[0]??u.dayDividers),launcherContent:f(e.launcherContent,te,a?.[2]??u.launcherContent),launcherFill:f(e.launcherFill,ee,a?.[1]??u.launcherFill),launcherShape:f(e.launcherShape,Q,a?.[0]??u.launcherShape),launcherSize:f(e.launcherSize,ne,a?.[3]??u.launcherSize),nameAvatar:R(e.nameAvatar,o?.[1]??u.nameAvatar),namePlacement:f(e.namePlacement,ae,o?.[0]??u.namePlacement),skin:f(e.skin,J,d?.[0]??u.skin),stampContent:f(e.stampContent,ie,i?.[2]??u.stampContent),stampPlacement:f(e.stampPlacement,re,i?.[1]??u.stampPlacement)};return m.stampPlacement==="beside_name"&&m.namePlacement==="hidden"&&(m.stampPlacement="under_turn"),m}function O(n){let e=n.split(/\s+/).filter(a=>a.length>0);return (e.length>1?`${e[0]?.slice(0,1)}${e[1]?.slice(0,1)}`:e[0]?.slice(0,2)??"").toUpperCase()}var pe="M20 11.6a7.4 7.4 0 0 1-7.4 7.4H8.2L4 21.8l1-4.1A7.4 7.4 0 1 1 20 11.6Z",he={large:66,medium:56,small:46},ue={circle:"width:var(--fab-size);height:var(--fab-size);border-radius:calc(var(--fab-size) / 2);",pill:"width:auto;height:var(--fab-size);border-radius:calc(var(--fab-size) / 2);padding:0 22px;gap:10px;",squircle:"width:var(--fab-size);height:var(--fab-size);border-radius:16px;"},me={filled:"background:var(--a);color:#fff;",outlined:"background:var(--paper);border:1px solid var(--hairline);color:var(--ink-2);box-shadow:0 1px 2px rgba(0,0,0,.08);"},ge={avatar:"",glyph:".launcher svg{width:calc(var(--fab-size) * 0.375);height:calc(var(--fab-size) * 0.375);}",team_faces:".launcher .faces{display:flex;}.launcher .faces .av{box-shadow:0 0 0 2px var(--paper);}.launcher .faces .av+.av{margin-left:-10px;}"},fe=".launcher .live{width:10px;height:10px;position:absolute;right:3px;bottom:3px;border-radius:50%;background:var(--online);box-shadow:0 0 0 2px var(--paper);}.launcher.closed .live{display:none}",be={circle:"",pill:".badge{position:static;box-shadow:none}",squircle:""},ye={filled:"",outlined:".badge{background:var(--a);top:-7px;right:-7px;min-width:19px;height:19px;font-size:11.5px}"},xe={circle:"",pill:".launcher .label{font-size:14px;font-weight:600;white-space:nowrap;}",squircle:""},ve={circle:"",pill:"@media (max-width:480px){.launcher{width:var(--fab-size);padding:0}.launcher .label{display:none}}",squircle:""};function M(n,e,t,a){return `.launcher{--fab-size:${he[a]}px;${ue[n]}${me[e]}}${ge[t]}${fe}${be[n]}${ye[e]}${xe[n]}${ve[n]}`}function $(n,e,t,a=r=>r){let r=document.createDocumentFragment();if(n==="glyph"||t.length===0){let o=document.createElement("span");return o.innerHTML=`<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="${pe}"/></svg>`,r.append(...o.childNodes,N()),r}return n==="avatar"?(r.append(z(t[0],e,a),N()),r):(r.append(P(t,e,a),N()),r)}function P(n,e,t=a=>a){let a=document.createElement("span");a.className="faces";for(let r of n.slice(0,2))a.append(z(r,e,t));return a}function z(n,e,t){let a=document.createElement("span");if(a.className="av",a.setAttribute("aria-hidden","true"),n&&(a.style.background=n.tone),n?.avatarUrl){let r=document.createElement("img");return r.alt="",r.src=t(n.avatarUrl),a.append(r),a}return a.textContent=n?n.initials:e.agentLabel.slice(0,2).toUpperCase(),a}function N(){let n=document.createElement("span");return n.className="live",n.setAttribute("aria-hidden","true"),n}var Se={agentLabel:"Agent",aiLabel:"AI",awayBody:"We are away right now, but we will reply as soon as we are back.",closeLabel:"Close chat",emptyBody:"We usually reply within a few minutes.",emptyTitle:"Ask us anything.",inputPlaceholder:"Type a message",launcherLabel:"Chat with us",replyTime:"Usually replying in a few minutes",sendLabel:"Send",timeLabel:n=>{let e=new Date(n);return Number.isNaN(e.getTime())?"":`${String(e.getHours()).padStart(2,"0")}:${String(e.getMinutes()).padStart(2,"0")}`},title:"Support",unreadLabel:n=>`${n} unread`},x={accentColor:"#5b5bff",availability:{timezone:"UTC",windows:[]},awayMessage:"",greeting:"",launcherOffsetX:20,launcherOffsetY:20,launcherPosition:"bottom_right",starterPrompts:[],team:[],...u},ke={quiet:".composer{position:relative;padding:10px 12px 12px}.composer input{padding-right:42px}.composer button{position:absolute;top:50%;right:16px;width:34px;min-width:34px;height:34px;padding:0;background:transparent;color:var(--ink);border-radius:7px;transform:translateY(-50%)}.composer button .sendglyph{display:block;width:18px;height:18px}.composer button .sendtext{display:none}.panel{border-radius:8px;box-shadow:0 2px 8px rgba(0,0,0,.12)}.header{background:var(--paper);color:var(--ink);height:44px;padding:0 8px 0 16px;border-bottom:1px solid var(--hairline)}.header h2{font-size:11px;letter-spacing:.11em;text-transform:uppercase;color:var(--ink-3)}.header .status{color:var(--ink-3)}.header .av,.header .status .live{box-shadow:0 0 0 2px var(--paper)}.close{color:var(--ink-2)}",standard:".panel{border-radius:16px;box-shadow:0 16px 40px rgba(0,0,0,.2)}.header{background:var(--a);color:#fff;flex-direction:column;align-items:flex-start;gap:14px;padding:18px 14px 20px 20px}.header h2{font-size:19px;font-weight:640}"},Ce={round:".composer{padding:12px 12px 14px;gap:8px}.composer input{height:46px;border-radius:23px;padding:0 16px}.composer button{width:46px;min-width:46px;height:46px;padding:0;border-radius:23px}.composer button .sendglyph{display:block}.composer button .sendtext{display:none}",square:".composer input{height:44px;border-radius:8px;padding:0 12px}"},Ee={rounded:".turn{border-radius:18px;padding:10px 15px}",tailed:".turn.agent,.turn.ai{border-radius:12px 12px 12px 4px}.turn.end_user{border-radius:12px 12px 4px 12px}"},we={filled:"",outlined:".turn{background:none;border:1px solid var(--hairline)}.turn.end_user{background:none;border-color:var(--a);color:var(--ink)}"},Te={above:"",hidden:".turn.agent .author,.turn.ai .author:not(.ai){display:none}",inline:".body .author.below{display:block;margin:4px 0 0;font-size:11.5px;font-weight:500;color:var(--ink-2);text-transform:none;letter-spacing:0;opacity:1}"},Ae=".turn.agent,.turn.ai{display:flex;gap:10px;max-width:100%;background:none;padding:0}.turn.agent .body,.turn.ai .body{background:var(--fill);padding:9px 13px;border-radius:inherit}.author{text-transform:none;letter-spacing:0;font-size:12.5px;font-weight:600;opacity:1}",Le='.divider{display:flex;align-items:center;gap:10px;margin:0;font-size:11px;opacity:.6}.divider:before,.divider:after{content:"";flex:1;height:1px;background:var(--hairline)}',Ne={beside_name:".stamp{font-size:11px;opacity:.7;margin-left:6px}",none:"",under_turn:".stamp{display:block;font-size:11px;opacity:.7;margin-top:4px}.turn.end_user .stamp{text-align:right}"},Pe=".lat{font-size:11px;opacity:.7;margin-left:6px}",U=`--paper: oklch(24.6% 0.015 257); --ink: #fff; --ink-3: rgba(255,255,255,.55);
2
+ --fill: rgba(255,255,255,.06); --hairline: rgba(255,255,255,.13); --ink-2: rgba(255,255,255,.70);
3
+ --online: oklch(72% 0.13 163.23);`;function _e(n){return n==="light"?"":n==="dark"?`:host { ${U} }`:`@media (prefers-color-scheme: dark) {
4
+ :host {
5
+ ${U}
6
+ }
7
+ }`}function _(n,e="system"){let t=C(n),a=n.launcherPosition==="bottom_left"?"left":"right",r=n.accentColor;return `${`
2
8
  :host {
3
9
  /* The widget sits above the host page's own furniture. The reset above sends
4
10
  z-index back to auto, so without this the launcher and panel stack at the
@@ -10,18 +16,12 @@
10
16
  --paper: #fff; --ink: #0f172a; --ink-3: var(--ink-3);
11
17
  --fill: #f1f5f9; --hairline: #e2e8f0; --ink-2: rgba(0,0,0,.72);
12
18
  --online: oklch(53.8% 0.1274 163.23);
13
- color-scheme: light dark;
14
- }
15
- @media (prefers-color-scheme: dark) {
16
- :host {
17
- --paper: oklch(24.6% 0.015 257); --ink: #fff; --ink-3: rgba(255,255,255,.55);
18
- --fill: rgba(255,255,255,.06); --hairline: rgba(255,255,255,.13); --ink-2: rgba(255,255,255,.70);
19
- --online: oklch(72% 0.13 163.23);
20
- }
19
+ color-scheme: ${e==="system"?"light dark":e};
21
20
  }
21
+ ${_e(e)}
22
22
  * { box-sizing: border-box; font-family: system-ui, sans-serif; }
23
23
  .launcher {
24
- z-index: 2147483000; position: fixed; ${t}: ${n.launcherOffsetX}px; bottom: ${n.launcherOffsetY}px; width: 56px; height: 56px;
24
+ z-index: 2147483000; position: fixed; ${a}: ${n.launcherOffsetX}px; bottom: ${n.launcherOffsetY}px; width: 56px; height: 56px;
25
25
  border-radius: 28px; border: none; cursor: pointer;
26
26
  display: inline-flex; align-items: center; justify-content: center;
27
27
  background: ${r}; color: #fff; font-size: 24px;
@@ -52,7 +52,7 @@
52
52
  the one that needs it. */
53
53
  .badge[hidden] { display: none; }
54
54
  .panel {
55
- z-index: 2147483001; position: fixed; ${t}: ${n.launcherOffsetX}px; bottom: ${n.launcherOffsetY+68}px; width: 360px; max-width: calc(100vw - 40px);
55
+ z-index: 2147483001; position: fixed; ${a}: ${n.launcherOffsetX}px; bottom: ${n.launcherOffsetY+68}px; width: 360px; max-width: calc(100vw - 40px);
56
56
  height: 520px; max-height: calc(100vh - 120px); background: var(--paper); color: var(--ink);
57
57
  border-radius: 12px; box-shadow: 0 8px 32px rgba(0,0,0,.24);
58
58
  display: flex; flex-direction: column; overflow: hidden;
@@ -67,7 +67,17 @@
67
67
  .header .av + .av { margin-left: -12px; }
68
68
  .headmain { display: flex; flex-direction: column; }
69
69
  .header .status { display: flex; align-items: center; gap: 6px; margin: 5px 0 0; font-size: 12.5px; color: rgb(255 255 255 / 80%); }
70
- .header .status .live { flex: none; width: 10px; height: 10px; border-radius: 50%; background: var(--online); box-shadow: 0 0 0 2px var(--a); }
70
+ /* The dot's ring is the PAPER, not the accent. An accent ring on the standard
71
+ skin is the header's own background and draws nothing, which is how this
72
+ shipped looking ringless beside a preview that had one. The faces above keep
73
+ the accent ring, which is a different job: separating two overlapping discs
74
+ from each other and from the header. */
75
+ .header .status .live { flex: none; width: 10px; height: 10px; border-radius: 50%; background: var(--online); box-shadow: 0 0 0 2px var(--paper); }
76
+ /* Hours, the same fact the launcher's dot carries. A green dot and a sentence
77
+ promising a reply in minutes are both claims about somebody being there, so
78
+ outside the project's hours neither is drawn: the away message in the thread
79
+ is what speaks then. */
80
+ .panel.closed .status { display: none; }
71
81
  /* Pinned rather than laid out: the standard skin turns this header into a
72
82
  column so the title can carry a line under it, and a close button that is
73
83
  merely a flex sibling then stacks BELOW the title on the left, which is where
@@ -109,11 +119,13 @@
109
119
  .composer input { flex: 1; min-width: 0; height: 44px; padding: 0 12px; border: 0; border-radius: 8px; font-size: 14px; background: var(--fill); color: var(--ink); }
110
120
  .composer input:focus-visible { outline: 2px solid ${r}; }
111
121
  .composer button { display: inline-flex; align-items: center; justify-content: center; gap: 0; min-width: 64px; height: 44px; padding: 0 16px; background: ${r}; color: #fff; border: none; border-radius: 8px; cursor: pointer; font-family: inherit; font-size: 14.5px; font-weight: 550; }
122
+ .composer button:hover { background: color-mix(in srgb, #000 12%, ${r}); }
123
+ .composer button:focus-visible { outline: 2px solid var(--ink); outline-offset: 2px; }
112
124
  .composer button .sendglyph { display: none; width: 19px; height: 19px; }
113
125
  .composer button:focus-visible { outline: 2px solid #0b0e14; }
114
126
  @media (prefers-reduced-motion: no-preference) {
115
127
  .panel { animation: rise 180ms ease-out; }
116
128
  @keyframes rise { from { transform: translateY(8px); opacity: 0; } to { transform: none; opacity: 1; } }
117
129
  }
118
- `}${ke[e.composerShape]}${Se[e.skin]}${O(e.launcherShape,e.launcherFill,e.launcherContent,e.launcherSize)}${Ce[e.bubbleShape]}${Ee[e.bubbleFill]}${Te[e.namePlacement]}${e.nameAvatar?we:""}${e.dayDividers?Ae:""}${Le[e.stampPlacement]}${e.stampContent==="time_and_latency"?Ne:""}`}var _e=["end_user","agent","ai"];function Pe(){let n=globalThis.location;if(n)return {host:n.host,path:n.pathname,title:document.title}}var C=class{constructor(e,t,r={},a={}){this.host=e;this.client=t;c(this,"root");c(this,"strings");c(this,"settings");c(this,"appearance");c(this,"launcher");c(this,"badge");c(this,"panel",null);c(this,"lastFocused",null);c(this,"unread",0);this.strings={...ve,...r},this.appearance={...x,...a},this.settings=T({...x,...a}),this.root=e.attachShadow({mode:"closed"});let s=document.createElement("style");if(s.textContent=z({...x,...a}),this.root.append(s),this.launcher=document.createElement("button"),this.launcher.className="launcher",this.launcher.type="button",this.launcher.setAttribute("aria-haspopup","dialog"),this.launcher.setAttribute("aria-label",this.strings.launcherLabel),this.launcher.append(M(this.settings.launcherContent,this.strings,this.appearance.team,o=>this.client.avatarUrl(o))),this.settings.launcherShape==="pill"){let o=document.createElement("span");o.className="label",o.textContent=this.settings.launcherContent==="team_faces"?this.strings.agentLabel:this.strings.launcherLabel,this.launcher.append(o);}this.launcher.addEventListener("click",()=>this.toggle()),this.badge=document.createElement("span"),this.badge.className="badge",this.badge.hidden=true,this.launcher.append(this.badge),this.root.append(this.launcher);}toggle(){this.panel?this.close():this.open();}setOpenNow(e){this.launcher.classList.toggle("closed",!e);}async open(){if(this.panel)return;this.lastFocused=this.host.ownerDocument.activeElement,this.unread=0,this.renderBadge();let e=document.createElement("section");e.className="panel",e.setAttribute("role","dialog"),e.setAttribute("aria-modal","true"),e.setAttribute("aria-label",this.strings.title);let t=document.createElement("div");t.className="header";let r=this.appearance.team??[];r.length>0&&t.append(_(r,this.strings,b=>this.client.avatarUrl(b)));let a=document.createElement("div");a.className="headmain";let s=document.createElement("h2");s.textContent=this.strings.title;let o=document.createElement("p");o.className="status";let i=document.createElement("span");i.className="live",i.setAttribute("aria-hidden","true"),o.append(i,this.strings.replyTime),a.append(s,o);let u=document.createElement("button");u.className="close",u.type="button",u.setAttribute("aria-label",this.strings.closeLabel),u.textContent="\xD7",u.addEventListener("click",()=>this.close()),t.append(a,u);let d=document.createElement("div");d.className="log",d.setAttribute("role","log"),d.setAttribute("aria-live","polite"),d.setAttribute("aria-label",this.strings.title);let l=document.createElement("form");l.className="composer";let p=document.createElement("input");p.type="text",p.setAttribute("aria-label",this.strings.inputPlaceholder),p.placeholder=this.strings.inputPlaceholder;let m=document.createElement("button");m.type="submit",m.setAttribute("aria-label",this.strings.sendLabel),m.innerHTML='<svg class="sendglyph" aria-hidden="true" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M4.5 12 20 4.5 15 20l-3.6-5.4L4.5 12Z"/></svg>';let v=document.createElement("span");v.className="sendtext",v.textContent=this.strings.sendLabel,m.append(v),l.append(p,m),l.addEventListener("submit",b=>{b.preventDefault(),this.submit(p,d);}),e.append(t,d,l),e.addEventListener("keydown",b=>this.onKeydown(b,e,u)),this.root.append(e),this.panel=e,p.focus();let y=await this.client.load();y&&y.turns.length>0?this.renderThread(d,y):this.renderFirstRun(d,p),E(this.appearance.availability,new Date)||this.renderAway(d);}renderFirstRun(e,t){let r=document.createElement("div");r.className="empty";let a=document.createElement("h3");a.textContent=this.appearance.greeting.trim()||this.strings.emptyTitle;let s=document.createElement("p");s.textContent=this.strings.emptyBody,r.append(a,s);for(let o of this.appearance.starterPrompts){let i=document.createElement("button");i.className="prompt",i.type="button",i.textContent=o,i.addEventListener("click",()=>{t.value=o,this.submit(t,e);}),r.append(i);}e.replaceChildren(r);}renderAway(e){let t=document.createElement("div");t.className="away",t.textContent=this.appearance.awayMessage.trim()||this.strings.awayBody,e.prepend(t);}close(){this.panel&&(this.panel.remove(),this.panel=null,this.lastFocused instanceof HTMLElement?this.lastFocused.focus():this.launcher.focus());}onIncomingTurn(e){if(this.panel){let t=this.panel.querySelector(".log");t instanceof HTMLElement&&this.appendTurn(t,e);return}e.authorKind!=="end_user"&&(this.unread+=1,this.renderBadge());}async submit(e,t){let r=e.value.trim();if(!r)return;e.value="",t.querySelector(".empty")?.remove();let a=await this.client.send(r,Pe());a&&this.appendTurn(t,a);}renderThread(e,t){e.replaceChildren();for(let r of t.turns)this.appendTurn(e,r);}appendTurn(e,t){e.querySelector(".empty")?.remove();let r=_e.includes(t.authorKind)?t.authorKind:"agent",a=this.settings,s=document.createElement("div");if(s.className=`turn ${r}`,r!=="end_user"&&a.nameAvatar){let l=document.createElement("span");if(l.className=r==="ai"?"av bot":"av",l.setAttribute("aria-hidden","true"),r==="agent"&&t.authorAvatarUrl){let p=document.createElement("img");p.alt="",p.src=this.client.avatarUrl(t.authorAvatarUrl),l.append(p);}else l.textContent=r==="ai"?this.strings.aiLabel:R(this.agentName(t));s.append(l);}let i=document.createElement("div");i.className="body";let u=r!=="end_user"&&a.namePlacement!=="hidden",d=document.createElement("div");if(d.textContent=t.body,u||r==="ai"&&a.namePlacement==="hidden"){let l=document.createElement("div");l.className=r==="ai"?"author ai":"author",l.textContent=r==="ai"?this.strings.aiLabel:this.agentName(t),a.stampPlacement==="beside_name"&&l.append(this.stamp(t)),a.namePlacement==="inline"?(l.classList.add("below"),i.append(d,l)):i.append(l,d);}else i.append(d);a.stampPlacement==="under_turn"&&i.append(this.stamp(t)),s.append(i),e.append(s),e.scrollTop=e.scrollHeight;}agentName(e){return e.authorName||this.strings.agentLabel}stamp(e){let t=document.createElement("span");return t.className="stamp",t.textContent=this.strings.timeLabel(e.createdAt),t}onKeydown(e,t,r){if(e.key==="Escape"){e.preventDefault(),this.close();return}if(e.key!=="Tab")return;let a=t.querySelectorAll('button, input, [tabindex]:not([tabindex="-1"])');if(a.length===0)return;let s=a[0],o=a[a.length-1],i=this.root.activeElement;e.shiftKey&&i===s?(e.preventDefault(),o.focus()):!e.shiftKey&&i===o?(e.preventDefault(),s.focus()):i===null&&(e.preventDefault(),r.focus());}renderBadge(){this.unread>0?(this.badge.hidden=false,this.badge.textContent=String(this.unread),this.launcher.setAttribute("aria-label",`${this.strings.launcherLabel}, ${this.strings.unreadLabel(this.unread)}`)):(this.badge.hidden=true,this.badge.textContent="",this.launcher.setAttribute("aria-label",this.strings.launcherLabel));}};function B(n){return `40${JSON.stringify(n)}`}function U(){return "3"}function D(n){let e=n.charAt(0),t=n.slice(1);if(e==="2")return {kind:"ping"};if(e==="1")return {kind:"disconnect"};if(e==="0"){let o=P(t);return {kind:"open",pingInterval:typeof o?.pingInterval=="number"?o.pingInterval:25e3,pingTimeout:typeof o?.pingTimeout=="number"?o.pingTimeout:2e4}}if(e!=="4")return {kind:"other"};let r=t.charAt(0),a=t.slice(1);if(r==="0")return {kind:"connected"};if(r==="1")return {kind:"disconnect"};if(r==="4"){let o=P(a);return {kind:"connectError",message:typeof o?.message=="string"?o.message:"refused"}}if(r!=="2")return {kind:"other"};let s=P(a);return !Array.isArray(s)||typeof s[0]!="string"?{kind:"other"}:{kind:"event",name:s[0],payload:s[1]}}function P(n){try{return JSON.parse(n)}catch{return null}}var Ie="/socket.io/?EIO=4&transport=websocket",w=class{constructor(e){this.options=e;c(this,"socket",null);c(this,"heartbeat",null);c(this,"ready",false);c(this,"closed",false);c(this,"heartbeatWindow",45e3);c(this,"factory");c(this,"setTimer");c(this,"clearTimer");this.factory=e.socketFactory??Fe,this.setTimer=e.setTimer??((t,r)=>setTimeout(t,r)),this.clearTimer=e.clearTimer??(t=>clearTimeout(t));}open(){if(this.socket||this.closed)return;let e=`${this.options.host.replace(/^http/,"ws").replace(/\/+$/,"")}${Ie}`,t;try{t=this.factory(e);}catch{this.options.onClosed(false);return}this.socket=t,t.onmessage=r=>this.receive(String(r.data)),t.onerror=()=>t.close(),t.onclose=()=>this.fell();}close(){this.closed=true,this.stopHeartbeat();let e=this.socket;this.socket=null,e?.close();}receive(e){let t=D(e);if(t.kind==="open"){this.armHeartbeat(t.pingInterval+t.pingTimeout),this.socket?.send(B(this.options.auth));return}if(t.kind==="ping"){this.armHeartbeat(),this.socket?.send(U());return}if(t.kind==="connectError"||t.kind==="disconnect"){this.stopHeartbeat(),this.socket?.close();return}if(t.kind==="event"){if(t.name==="ready"){this.ready=true,this.options.onReady();return}if(t.name==="conversation.turn"){let r=t.payload?.turn;r&&this.options.onTurn(r);}}}fell(){this.stopHeartbeat();let e=this.ready;this.socket=null,this.ready=false,this.closed||this.options.onClosed(e);}armHeartbeat(e){e!==void 0&&(this.heartbeatWindow=e),this.stopHeartbeat(),this.heartbeat=this.setTimer(()=>this.socket?.close(),this.heartbeatWindow);}stopHeartbeat(){this.heartbeat!==null&&this.clearTimer(this.heartbeat),this.heartbeat=null;}};function Fe(n){let e=globalThis.WebSocket;if(!e)throw new Error("no WebSocket");return new e(n)}var He=6e4;function nt(n){let e=globalThis.document;if(!e)throw new Error("prodantix chat requires a document; mount it in the browser");let t=n.mountPoint??e.createElement("div");n.mountPoint||e.body.append(t);let r=new k(n),a=new C(t,r,n.strings,n.appearance),s=n.appearance?.availability??x.availability,o,i=()=>{a.setOpenNow(E(s,new Date)),o=setTimeout(i,He);};i();let u=new Set,d,l=null,p=n.pollIntervalMs??15e3,m=g=>{u.has(g.id)||g.authorKind==="end_user"||(u.add(g.id),a.onIncomingTurn(g));},v=async()=>{if(!r.hasThread)return;let g=await r.load();if(g){for(let S of g.turns)m(S);u=new Set(g.turns.map(S=>S.id));}},y=()=>{d||p<=0||(d=setInterval(()=>void v(),p));},b=()=>{d&&clearInterval(d),d=void 0;},A=()=>{if(l||!n.socketHost)return;let g=r.socketAuth;g&&(l=new w({auth:g,host:n.socketHost,onClosed:S=>{l=null,y(),S&&A();},onReady:b,onTurn:m,socketFactory:n.socketFactory}),l.open());};return y(),A(),{close:()=>a.close(),destroy:()=>{b(),clearTimeout(o),l?.close(),l=null,a.close(),t.remove();},identify:g=>r.identify(g),open:()=>{a.open().then(A);}}}exports.ChatClient=k;exports.ChatPanel=C;exports.DEFAULT_APPEARANCE=x;exports.DEFAULT_APPEARANCE_SETTINGS=h;exports.mountChat=nt;exports.panelStyles=z;exports.resolveAppearance=T;//# sourceMappingURL=chat.cjs.map
130
+ `}${Ce[t.composerShape]}${ke[t.skin]}${M(t.launcherShape,t.launcherFill,t.launcherContent,t.launcherSize)}${Ee[t.bubbleShape]}${we[t.bubbleFill]}${Te[t.namePlacement]}${t.nameAvatar?Ae:""}${t.dayDividers?Le:""}${Ne[t.stampPlacement]}${t.stampContent==="time_and_latency"?Pe:""}`}var Ie=["end_user","agent","ai"];function Fe(){let n=globalThis.location;if(n)return {host:n.host,path:n.pathname,title:document.title}}var E=class{constructor(e,t,a={},r={},o={}){this.host=e;this.client=t;l(this,"root");l(this,"strings");l(this,"settings");l(this,"appearance");l(this,"launcher");l(this,"badge");l(this,"panel",null);l(this,"lastFocused",null);l(this,"unread",0);l(this,"openNow");l(this,"style");l(this,"scheme");this.strings={...Se,...a},this.appearance={...x,...r},this.settings=C({...x,...r}),this.root=e.attachShadow({mode:o.shadowMode??"closed"}),this.openNow=w(this.appearance.availability,new Date),this.scheme=o.scheme,this.style=document.createElement("style"),this.style.textContent=_(this.appearance,this.scheme),this.root.append(this.style),this.launcher=document.createElement("button"),this.launcher.className="launcher",this.launcher.type="button",this.launcher.setAttribute("aria-haspopup","dialog"),this.launcher.addEventListener("click",()=>this.toggle()),this.badge=document.createElement("span"),this.badge.className="badge",this.badge.hidden=true,this.drawLauncher(),this.root.append(this.launcher);}drawLauncher(){if(this.launcher.setAttribute("aria-label",this.strings.launcherLabel),this.launcher.replaceChildren(),this.launcher.append($(this.settings.launcherContent,this.strings,this.appearance.team,e=>this.client.avatarUrl(e))),this.settings.launcherShape==="pill"){let e=document.createElement("span");e.className="label",e.textContent=this.settings.launcherContent==="team_faces"?this.strings.agentLabel:this.strings.launcherLabel,this.launcher.append(e);}this.launcher.append(this.badge),this.launcher.classList.toggle("closed",!this.openNow);}update(e,t){this.appearance={...x,...e},this.settings=C(this.appearance),t!==void 0&&(this.scheme=t),this.style.textContent=_(this.appearance,this.scheme),this.drawLauncher(),this.panel&&(this.close(),this.open());}toggle(){this.panel?this.close():this.open();}setOpenNow(e){this.openNow=e,this.launcher.classList.toggle("closed",!e),this.panel?.classList.toggle("closed",!e);}async open(){if(this.panel)return;this.lastFocused=this.host.ownerDocument.activeElement,this.unread=0,this.renderBadge();let e=document.createElement("section");e.className=this.openNow?"panel":"panel closed",e.setAttribute("role","dialog"),e.setAttribute("aria-modal","true"),e.setAttribute("aria-label",this.strings.title);let t=document.createElement("div");t.className="header";let a=this.appearance.team??[];a.length>0&&t.append(P(a,this.strings,b=>this.client.avatarUrl(b)));let r=document.createElement("div");r.className="headmain";let o=document.createElement("h2");o.textContent=this.strings.title;let s=document.createElement("p");s.className="status";let i=document.createElement("span");i.className="live",i.setAttribute("aria-hidden","true"),s.append(i,this.strings.replyTime),r.append(o,s);let h=document.createElement("button");h.className="close",h.type="button",h.setAttribute("aria-label",this.strings.closeLabel),h.textContent="\xD7",h.addEventListener("click",()=>this.close()),t.append(r,h);let d=document.createElement("div");d.className="log",d.setAttribute("role","log"),d.setAttribute("aria-live","polite"),d.setAttribute("aria-label",this.strings.title);let c=document.createElement("form");c.className="composer";let p=document.createElement("input");p.type="text",p.setAttribute("aria-label",this.strings.inputPlaceholder),p.placeholder=this.strings.inputPlaceholder;let m=document.createElement("button");m.type="submit",m.setAttribute("aria-label",this.strings.sendLabel),m.innerHTML='<svg class="sendglyph" aria-hidden="true" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M4.5 12 20 4.5 15 20l-3.6-5.4L4.5 12Z"/></svg>';let v=document.createElement("span");v.className="sendtext",v.textContent=this.strings.sendLabel,m.append(v),c.append(p,m),c.addEventListener("submit",b=>{b.preventDefault(),this.submit(p,d);}),e.append(t,d,c),e.addEventListener("keydown",b=>this.onKeydown(b,e,h)),this.root.append(e),this.panel=e,p.focus();let y=await this.client.load();y&&y.turns.length>0?this.renderThread(d,y):this.renderFirstRun(d,p),this.openNow||this.renderAway(d);}renderFirstRun(e,t){let a=document.createElement("div");a.className="empty";let r=document.createElement("h3");r.textContent=this.appearance.greeting.trim()||this.strings.emptyTitle;let o=document.createElement("p");o.textContent=this.strings.emptyBody,a.append(r,o);for(let s of this.appearance.starterPrompts){let i=document.createElement("button");i.className="prompt",i.type="button",i.textContent=s,i.addEventListener("click",()=>{t.value=s,this.submit(t,e);}),a.append(i);}e.replaceChildren(a);}renderAway(e){let t=document.createElement("div");t.className="away",t.textContent=this.appearance.awayMessage.trim()||this.strings.awayBody,e.prepend(t);}close(){this.panel&&(this.panel.remove(),this.panel=null,this.lastFocused instanceof HTMLElement?this.lastFocused.focus():this.launcher.focus());}onIncomingTurn(e){if(this.panel){let t=this.panel.querySelector(".log");t instanceof HTMLElement&&this.appendTurn(t,e);return}e.authorKind!=="end_user"&&(this.unread+=1,this.renderBadge());}async submit(e,t){let a=e.value.trim();if(!a)return;e.value="",t.querySelector(".empty")?.remove();let r=await this.client.send(a,Fe());r&&this.appendTurn(t,r);}renderThread(e,t){e.replaceChildren();for(let a of t.turns)this.appendTurn(e,a);}appendTurn(e,t){e.querySelector(".empty")?.remove();let a=Ie.includes(t.authorKind)?t.authorKind:"agent",r=this.settings,o=document.createElement("div");if(o.className=`turn ${a}`,a!=="end_user"&&r.nameAvatar){let c=document.createElement("span");if(c.className=a==="ai"?"av bot":"av",c.setAttribute("aria-hidden","true"),a==="agent"&&t.authorAvatarUrl){let p=document.createElement("img");p.alt="",p.src=this.client.avatarUrl(t.authorAvatarUrl),c.append(p);}else c.textContent=a==="ai"?this.strings.aiLabel:O(this.agentName(t));o.append(c);}let i=document.createElement("div");i.className="body";let h=a!=="end_user"&&r.namePlacement!=="hidden",d=document.createElement("div");if(d.textContent=t.body,h||a==="ai"&&r.namePlacement==="hidden"){let c=document.createElement("div");c.className=a==="ai"?"author ai":"author",c.textContent=a==="ai"?this.strings.aiLabel:this.agentName(t),r.stampPlacement==="beside_name"&&c.append(this.stamp(t)),r.namePlacement==="inline"?(c.classList.add("below"),i.append(d,c)):i.append(c,d);}else i.append(d);r.stampPlacement==="under_turn"&&i.append(this.stamp(t)),o.append(i),e.append(o),e.scrollTop=e.scrollHeight;}agentName(e){return e.authorName||this.strings.agentLabel}stamp(e){let t=document.createElement("span");return t.className="stamp",t.textContent=this.strings.timeLabel(e.createdAt),t}onKeydown(e,t,a){if(e.key==="Escape"){e.preventDefault(),this.close();return}if(e.key!=="Tab")return;let r=t.querySelectorAll('button, input, [tabindex]:not([tabindex="-1"])');if(r.length===0)return;let o=r[0],s=r[r.length-1],i=this.root.activeElement;e.shiftKey&&i===o?(e.preventDefault(),s.focus()):!e.shiftKey&&i===s?(e.preventDefault(),o.focus()):i===null&&(e.preventDefault(),a.focus());}renderBadge(){this.unread>0?(this.badge.hidden=false,this.badge.textContent=String(this.unread),this.launcher.setAttribute("aria-label",`${this.strings.launcherLabel}, ${this.strings.unreadLabel(this.unread)}`)):(this.badge.hidden=true,this.badge.textContent="",this.launcher.setAttribute("aria-label",this.strings.launcherLabel));}};function B(n){return `40${JSON.stringify(n)}`}function D(){return "3"}function K(n){let e=n.charAt(0),t=n.slice(1);if(e==="2")return {kind:"ping"};if(e==="1")return {kind:"disconnect"};if(e==="0"){let s=I(t);return {kind:"open",pingInterval:typeof s?.pingInterval=="number"?s.pingInterval:25e3,pingTimeout:typeof s?.pingTimeout=="number"?s.pingTimeout:2e4}}if(e!=="4")return {kind:"other"};let a=t.charAt(0),r=t.slice(1);if(a==="0")return {kind:"connected"};if(a==="1")return {kind:"disconnect"};if(a==="4"){let s=I(r);return {kind:"connectError",message:typeof s?.message=="string"?s.message:"refused"}}if(a!=="2")return {kind:"other"};let o=I(r);return !Array.isArray(o)||typeof o[0]!="string"?{kind:"other"}:{kind:"event",name:o[0],payload:o[1]}}function I(n){try{return JSON.parse(n)}catch{return null}}var He="/socket.io/?EIO=4&transport=websocket",T=class{constructor(e){this.options=e;l(this,"socket",null);l(this,"heartbeat",null);l(this,"ready",false);l(this,"closed",false);l(this,"heartbeatWindow",45e3);l(this,"factory");l(this,"setTimer");l(this,"clearTimer");this.factory=e.socketFactory??Re,this.setTimer=e.setTimer??((t,a)=>setTimeout(t,a)),this.clearTimer=e.clearTimer??(t=>clearTimeout(t));}open(){if(this.socket||this.closed)return;let e=`${this.options.host.replace(/^http/,"ws").replace(/\/+$/,"")}${He}`,t;try{t=this.factory(e);}catch{this.options.onClosed(false);return}this.socket=t,t.onmessage=a=>this.receive(String(a.data)),t.onerror=()=>t.close(),t.onclose=()=>this.fell();}close(){this.closed=true,this.stopHeartbeat();let e=this.socket;this.socket=null,e?.close();}receive(e){let t=K(e);if(t.kind==="open"){this.armHeartbeat(t.pingInterval+t.pingTimeout),this.socket?.send(B(this.options.auth));return}if(t.kind==="ping"){this.armHeartbeat(),this.socket?.send(D());return}if(t.kind==="connectError"||t.kind==="disconnect"){this.stopHeartbeat(),this.socket?.close();return}if(t.kind==="event"){if(t.name==="ready"){this.ready=true,this.options.onReady();return}if(t.name==="conversation.turn"){let a=t.payload?.turn;a&&this.options.onTurn(a);}}}fell(){this.stopHeartbeat();let e=this.ready;this.socket=null,this.ready=false,this.closed||this.options.onClosed(e);}armHeartbeat(e){e!==void 0&&(this.heartbeatWindow=e),this.stopHeartbeat(),this.heartbeat=this.setTimer(()=>this.socket?.close(),this.heartbeatWindow);}stopHeartbeat(){this.heartbeat!==null&&this.clearTimer(this.heartbeat),this.heartbeat=null;}};function Re(n){let e=globalThis.WebSocket;if(!e)throw new Error("no WebSocket");return new e(n)}var Oe=6e4;function rt(n){let e=globalThis.document;if(!e)throw new Error("prodantix chat requires a document; mount it in the browser");let t=n.mountPoint??e.createElement("div");n.mountPoint||e.body.append(t);let a=new k(n),r=new E(t,a,n.strings,n.appearance),o=n.appearance?.availability??x.availability,s,i=()=>{r.setOpenNow(w(o,new Date)),s=setTimeout(i,Oe);};i();let h=new Set,d,c=null,p=n.pollIntervalMs??15e3,m=g=>{h.has(g.id)||g.authorKind==="end_user"||(h.add(g.id),r.onIncomingTurn(g));},v=async()=>{if(!a.hasThread)return;let g=await a.load();if(g){for(let S of g.turns)m(S);h=new Set(g.turns.map(S=>S.id));}},y=()=>{d||p<=0||(d=setInterval(()=>void v(),p));},b=()=>{d&&clearInterval(d),d=void 0;},A=()=>{if(c||!n.socketHost)return;let g=a.socketAuth;g&&(c=new T({auth:g,host:n.socketHost,onClosed:S=>{c=null,y(),S&&A();},onReady:b,onTurn:m,socketFactory:n.socketFactory}),c.open());};return y(),A(),{close:()=>r.close(),destroy:()=>{b(),clearTimeout(s),c?.close(),c=null,r.close(),t.remove();},identify:g=>a.identify(g),open:()=>{r.open().then(A);}}}exports.ChatClient=k;exports.ChatPanel=E;exports.DEFAULT_APPEARANCE=x;exports.DEFAULT_APPEARANCE_SETTINGS=u;exports.mountChat=rt;exports.panelStyles=_;exports.resolveAppearance=C;//# sourceMappingURL=chat.cjs.map
119
131
  //# sourceMappingURL=chat.cjs.map
package/dist/chat.d.cts CHANGED
@@ -1,5 +1,5 @@
1
- import { C as ChatClient, M as MessengerConfig, A as AppearanceSettings, a as ChatTurn, b as ChatIdentity, c as ChatClientOptions } from './config-Cz1JyPLj.cjs';
2
- export { B as BubbleFill, d as BubbleShape, e as ChatStorage, f as ChatThread, g as ComposerShape, D as DEFAULT_APPEARANCE_SETTINGS, L as LauncherContent, h as LauncherFill, i as LauncherShape, j as LauncherSize, k as MessengerSkin, N as NamePlacement, S as StampContent, l as StampPlacement, r as resolveAppearance } from './config-Cz1JyPLj.cjs';
1
+ import { C as ChatThread, P as PageContext, a as ChatTurn, M as MessengerConfig, A as AppearanceSettings, b as ChatIdentity, c as ChatClientOptions } from './config-D8-uiWM8.cjs';
2
+ export { B as BubbleFill, d as BubbleShape, e as ChatClient, f as ChatStorage, g as ComposerShape, D as DEFAULT_APPEARANCE_SETTINGS, L as LauncherContent, h as LauncherFill, i as LauncherShape, j as LauncherSize, k as MessengerSkin, N as NamePlacement, S as StampContent, l as StampPlacement, r as resolveAppearance } from './config-D8-uiWM8.cjs';
3
3
  import { S as SocketFactory } from './types-DjMXp6Wg.cjs';
4
4
  import './http-BCh716Vs.cjs';
5
5
 
@@ -20,20 +20,35 @@ interface ChatStrings {
20
20
  }
21
21
  type MessengerAppearance = Pick<MessengerConfig, 'accentColor' | 'availability' | 'awayMessage' | 'greeting' | 'launcherOffsetX' | 'launcherOffsetY' | 'launcherPosition' | 'starterPrompts' | 'team'> & AppearanceSettings;
22
22
  declare const DEFAULT_APPEARANCE: MessengerAppearance;
23
- declare function panelStyles(appearance: MessengerAppearance): string;
23
+ interface ChatSource {
24
+ avatarUrl(url: string): string;
25
+ load(): Promise<ChatThread | null>;
26
+ send(body: string, pageContext?: PageContext): Promise<ChatTurn | null>;
27
+ }
28
+ type ChatScheme = 'dark' | 'light' | 'system';
29
+ interface ChatPanelOptions {
30
+ scheme?: ChatScheme;
31
+ shadowMode?: 'closed' | 'open';
32
+ }
33
+ declare function panelStyles(appearance: MessengerAppearance, scheme?: ChatScheme): string;
24
34
  declare class ChatPanel {
25
35
  private readonly host;
26
36
  private readonly client;
27
37
  private readonly root;
28
38
  private readonly strings;
29
- private readonly settings;
30
- private readonly appearance;
39
+ private settings;
40
+ private appearance;
31
41
  private readonly launcher;
32
42
  private readonly badge;
33
43
  private panel;
34
44
  private lastFocused;
35
45
  private unread;
36
- constructor(host: HTMLElement, client: ChatClient, strings?: Partial<ChatStrings>, appearance?: Partial<MessengerAppearance>);
46
+ private openNow;
47
+ private readonly style;
48
+ private scheme;
49
+ constructor(host: HTMLElement, client: ChatSource, strings?: Partial<ChatStrings>, appearance?: Partial<MessengerAppearance>, options?: ChatPanelOptions);
50
+ private drawLauncher;
51
+ update(appearance: Partial<MessengerAppearance>, scheme?: ChatScheme): void;
37
52
  private toggle;
38
53
  setOpenNow(open: boolean): void;
39
54
  open(): Promise<void>;
@@ -66,4 +81,4 @@ interface ChatHandle {
66
81
  }
67
82
  declare function mountChat(options: MountChatOptions): ChatHandle;
68
83
 
69
- export { AppearanceSettings, ChatClient, ChatClientOptions, type ChatHandle, ChatIdentity, ChatPanel, type ChatStrings, ChatTurn, DEFAULT_APPEARANCE, type MessengerAppearance, type MountChatOptions, mountChat, panelStyles };
84
+ export { AppearanceSettings, ChatClientOptions, type ChatHandle, ChatIdentity, ChatPanel, type ChatStrings, ChatThread, ChatTurn, DEFAULT_APPEARANCE, type MessengerAppearance, type MountChatOptions, mountChat, panelStyles };
package/dist/chat.d.ts CHANGED
@@ -1,5 +1,5 @@
1
- import { C as ChatClient, M as MessengerConfig, A as AppearanceSettings, a as ChatTurn, b as ChatIdentity, c as ChatClientOptions } from './config-B1Sp94B-.js';
2
- export { B as BubbleFill, d as BubbleShape, e as ChatStorage, f as ChatThread, g as ComposerShape, D as DEFAULT_APPEARANCE_SETTINGS, L as LauncherContent, h as LauncherFill, i as LauncherShape, j as LauncherSize, k as MessengerSkin, N as NamePlacement, S as StampContent, l as StampPlacement, r as resolveAppearance } from './config-B1Sp94B-.js';
1
+ import { C as ChatThread, P as PageContext, a as ChatTurn, M as MessengerConfig, A as AppearanceSettings, b as ChatIdentity, c as ChatClientOptions } from './config-DGUsxWOL.js';
2
+ export { B as BubbleFill, d as BubbleShape, e as ChatClient, f as ChatStorage, g as ComposerShape, D as DEFAULT_APPEARANCE_SETTINGS, L as LauncherContent, h as LauncherFill, i as LauncherShape, j as LauncherSize, k as MessengerSkin, N as NamePlacement, S as StampContent, l as StampPlacement, r as resolveAppearance } from './config-DGUsxWOL.js';
3
3
  import { S as SocketFactory } from './types-DjMXp6Wg.js';
4
4
  import './http-BCh716Vs.js';
5
5
 
@@ -20,20 +20,35 @@ interface ChatStrings {
20
20
  }
21
21
  type MessengerAppearance = Pick<MessengerConfig, 'accentColor' | 'availability' | 'awayMessage' | 'greeting' | 'launcherOffsetX' | 'launcherOffsetY' | 'launcherPosition' | 'starterPrompts' | 'team'> & AppearanceSettings;
22
22
  declare const DEFAULT_APPEARANCE: MessengerAppearance;
23
- declare function panelStyles(appearance: MessengerAppearance): string;
23
+ interface ChatSource {
24
+ avatarUrl(url: string): string;
25
+ load(): Promise<ChatThread | null>;
26
+ send(body: string, pageContext?: PageContext): Promise<ChatTurn | null>;
27
+ }
28
+ type ChatScheme = 'dark' | 'light' | 'system';
29
+ interface ChatPanelOptions {
30
+ scheme?: ChatScheme;
31
+ shadowMode?: 'closed' | 'open';
32
+ }
33
+ declare function panelStyles(appearance: MessengerAppearance, scheme?: ChatScheme): string;
24
34
  declare class ChatPanel {
25
35
  private readonly host;
26
36
  private readonly client;
27
37
  private readonly root;
28
38
  private readonly strings;
29
- private readonly settings;
30
- private readonly appearance;
39
+ private settings;
40
+ private appearance;
31
41
  private readonly launcher;
32
42
  private readonly badge;
33
43
  private panel;
34
44
  private lastFocused;
35
45
  private unread;
36
- constructor(host: HTMLElement, client: ChatClient, strings?: Partial<ChatStrings>, appearance?: Partial<MessengerAppearance>);
46
+ private openNow;
47
+ private readonly style;
48
+ private scheme;
49
+ constructor(host: HTMLElement, client: ChatSource, strings?: Partial<ChatStrings>, appearance?: Partial<MessengerAppearance>, options?: ChatPanelOptions);
50
+ private drawLauncher;
51
+ update(appearance: Partial<MessengerAppearance>, scheme?: ChatScheme): void;
37
52
  private toggle;
38
53
  setOpenNow(open: boolean): void;
39
54
  open(): Promise<void>;
@@ -66,4 +81,4 @@ interface ChatHandle {
66
81
  }
67
82
  declare function mountChat(options: MountChatOptions): ChatHandle;
68
83
 
69
- export { AppearanceSettings, ChatClient, ChatClientOptions, type ChatHandle, ChatIdentity, ChatPanel, type ChatStrings, ChatTurn, DEFAULT_APPEARANCE, type MessengerAppearance, type MountChatOptions, mountChat, panelStyles };
84
+ export { AppearanceSettings, ChatClientOptions, type ChatHandle, ChatIdentity, ChatPanel, type ChatStrings, ChatThread, ChatTurn, DEFAULT_APPEARANCE, type MessengerAppearance, type MountChatOptions, mountChat, panelStyles };
package/dist/chat.js CHANGED
@@ -1,4 +1,10 @@
1
- import {c,a as a$2,b}from'./chunk-V77KYPOF.js';import {a as a$1,d}from'./chunk-VG77TYVX.js';import {a}from'./chunk-5XGN7UAV.js';var D="X-Prodantix-Conversation-Token",L="prodantix.chat.handle";function q(){let a=globalThis.localStorage;if(a)return {get:e=>a.getItem(e),remove:e=>a.removeItem(e),set:(e,t)=>a.setItem(e,t)}}var k=class{constructor(e){this.options=e;a(this,"fetchImpl");a(this,"host");a(this,"storage");a(this,"handle");a(this,"identity",null);this.fetchImpl=a$1(e.fetchImpl),this.host=d(e.host),this.storage=e.storage??q(),this.handle=this.readHandle();}get hasThread(){return this.handle!==null}avatarUrl(e){return e.startsWith("/")?`${this.host}${e}?api_key=${encodeURIComponent(this.options.apiKey)}`:e}get socketAuth(){return this.handle?{conversationId:this.handle.conversationId,conversationToken:this.handle.token,projectKey:this.options.apiKey}:null}identify(e){this.identity=e;}async ensureThread(e){if(this.handle)return true;let t=await this.request("POST","/v1/conversations",{body:{distinctId:this.options.distinctId,subject:e,userHash:this.identity?.userHash,userId:this.identity?.userId}});return !t?.conversationId||!t.token?false:(this.handle={conversationId:t.conversationId,token:t.token},this.storage?.set(L,JSON.stringify(this.handle)),true)}async send(e,t){if(!await this.ensureThread())return null;let n=this.handle;return n?(await this.request("POST",`/v1/conversations/${encodeURIComponent(n.conversationId)}/turns`,{body:{body:e,pageContext:t},token:n.token}))?.turn??null:null}async load(){let e=this.handle;return e?this.request("GET",`/v1/conversations/${encodeURIComponent(e.conversationId)}`,{token:e.token}):null}readHandle(){let e=this.storage?.get(L);if(!e)return null;try{let t=JSON.parse(e);if(typeof t.conversationId=="string"&&typeof t.token=="string")return {conversationId:t.conversationId,token:t.token}}catch{}return this.storage?.remove(L),null}async request(e,t,n={}){let r=this.fetchImpl;if(!r)return this.options.onError?.(new Error("no fetch available for prodantix chat")),null;let s={authorization:`Bearer ${this.options.apiKey}`,"content-type":"application/json"};n.token&&(s[D]=n.token);try{let o=await r(`${this.host}${t}`,{body:n.body===void 0?void 0:JSON.stringify(n.body),headers:s,method:e}),i=await o.text();return o.ok?i?JSON.parse(i):{}:(this.options.onError?.(new Error(`prodantix chat ${t}: ${o.status}`)),null)}catch(o){return this.options.onError?.(o),null}}};var K={Fri:"fri",Mon:"mon",Sat:"sat",Sun:"sun",Thu:"thu",Tue:"tue",Wed:"wed"};function w(a,e){let t=new Intl.DateTimeFormat(void 0,{hour:"2-digit",hour12:false,minute:"2-digit",timeZone:a.timezone,weekday:"short"}).formatToParts(e),n=K[t.find(i=>i.type==="weekday")?.value??""];if(!n)return false;let r=t.find(i=>i.type==="hour")?.value??"",s=t.find(i=>i.type==="minute")?.value??"",o=`${r}:${s}`;return a.windows.some(i=>i.days.includes(n)&&i.open<=o&&o<i.close)}var u={bubbleFill:"filled",bubbleShape:"tailed",composerShape:"round",dayDividers:true,launcherContent:"glyph",launcherFill:"outlined",launcherShape:"circle",launcherSize:"small",nameAvatar:true,namePlacement:"hidden",skin:"standard",stampContent:"time",stampPlacement:"none"},Y=["quiet","standard"],W=["round","square"],G=["rounded","tailed"],j=["filled","outlined"],X=["circle","pill","squircle"],Z=["filled","outlined"],J=["avatar","glyph","team_faces"],V=["large","medium","small"],Q=["above","hidden","inline"],ee=["beside_name","none","under_turn"],te=["time","time_and_latency"],f=(a,e,t)=>typeof a=="string"&&e.includes(a)?a:t,M=(a,e)=>typeof a=="boolean"?a:e,ne={avatar_circle:["circle","outlined","avatar","large"],circle_filled:["circle","filled","glyph","medium"],circle_outlined:["circle","outlined","glyph","small"],pill_labelled:["pill","filled","glyph","medium"],pill_team:["pill","outlined","team_faces","medium"],squircle_filled:["squircle","filled","glyph","medium"]},ae={above:["above",false],avatar_only:["hidden",true],gutter:["above",true],hidden:["hidden",false],inline:["inline",false]},re={cluster:[true,"none","time"],latency:[false,"beside_name","time_and_latency"],none:[false,"none","time"],trailing:[false,"under_turn","time"],with_name:[false,"beside_name","time"]},ie={concierge:["standard","round"],console:["standard","square"],quiet:["quiet","square"]},oe={hairline:["rounded","outlined"],outlined:["rounded","outlined"],rounded:["rounded","filled"],tailed:["tailed","filled"]};function E(a){let e=typeof a=="object"&&a!==null?a:{},t=typeof e.launcherStyle=="string"?e.launcherStyle:void 0,n=t===void 0?void 0:ne[t],r=typeof e.namePlacement=="string"?e.namePlacement:void 0,s=r===void 0?void 0:ae[r],o=typeof e.timestampStyle=="string"?e.timestampStyle:void 0,i=o===void 0?void 0:re[o],h=typeof e.skin=="string"?e.skin:void 0,d=h===void 0?void 0:ie[h],l=typeof e.bubbleStyle=="string"?e.bubbleStyle:void 0,p=l===void 0?void 0:oe[l],m={bubbleFill:f(e.bubbleFill,j,p?.[1]??u.bubbleFill),bubbleShape:f(e.bubbleShape,G,p?.[0]??u.bubbleShape),composerShape:f(e.composerShape,W,d?.[1]??u.composerShape),dayDividers:M(e.dayDividers,i?.[0]??u.dayDividers),launcherContent:f(e.launcherContent,J,n?.[2]??u.launcherContent),launcherFill:f(e.launcherFill,Z,n?.[1]??u.launcherFill),launcherShape:f(e.launcherShape,X,n?.[0]??u.launcherShape),launcherSize:f(e.launcherSize,V,n?.[3]??u.launcherSize),nameAvatar:M(e.nameAvatar,s?.[1]??u.nameAvatar),namePlacement:f(e.namePlacement,Q,s?.[0]??u.namePlacement),skin:f(e.skin,Y,d?.[0]??u.skin),stampContent:f(e.stampContent,te,i?.[2]??u.stampContent),stampPlacement:f(e.stampPlacement,ee,i?.[1]??u.stampPlacement)};return m.stampPlacement==="beside_name"&&m.namePlacement==="hidden"&&(m.stampPlacement="under_turn"),m}function $(a){let e=a.split(/\s+/).filter(n=>n.length>0);return (e.length>1?`${e[0]?.slice(0,1)}${e[1]?.slice(0,1)}`:e[0]?.slice(0,2)??"").toUpperCase()}var se="M20 11.6a7.4 7.4 0 0 1-7.4 7.4H8.2L4 21.8l1-4.1A7.4 7.4 0 1 1 20 11.6Z",le={large:66,medium:56,small:46},ce={circle:"width:var(--fab-size);height:var(--fab-size);border-radius:calc(var(--fab-size) / 2);",pill:"width:auto;height:var(--fab-size);border-radius:calc(var(--fab-size) / 2);padding:0 22px;gap:10px;",squircle:"width:var(--fab-size);height:var(--fab-size);border-radius:16px;"},de={filled:"background:var(--a);color:#fff;",outlined:"background:var(--paper);border:1px solid var(--hairline);color:var(--ink-2);box-shadow:0 1px 2px rgba(0,0,0,.08);"},pe={avatar:"",glyph:".launcher svg{width:calc(var(--fab-size) * 0.375);height:calc(var(--fab-size) * 0.375);}",team_faces:".launcher .faces{display:flex;}.launcher .faces .av{box-shadow:0 0 0 2px var(--paper);}.launcher .faces .av+.av{margin-left:-10px;}"},he=".launcher .live{width:10px;height:10px;position:absolute;right:3px;bottom:3px;border-radius:50%;background:var(--online);box-shadow:0 0 0 2px var(--paper);}.launcher.closed .live{display:none}",ue={circle:"",pill:".badge{position:static;box-shadow:none}",squircle:""},me={filled:"",outlined:".badge{background:var(--a);top:-7px;right:-7px;min-width:19px;height:19px;font-size:11.5px}"},ge={circle:"",pill:".launcher .label{font-size:14px;font-weight:600;white-space:nowrap;}",squircle:""},fe={circle:"",pill:"@media (max-width:480px){.launcher{width:var(--fab-size);padding:0}.launcher .label{display:none}}",squircle:""};function z(a,e,t,n){return `.launcher{--fab-size:${le[n]}px;${ce[a]}${de[e]}}${pe[t]}${he}${ue[a]}${me[e]}${ge[a]}${fe[a]}`}function B(a,e,t,n=r=>r){let r=document.createDocumentFragment();if(a==="glyph"||t.length===0){let s=document.createElement("span");return s.innerHTML=`<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="${se}"/></svg>`,r.append(...s.childNodes,P()),r}return a==="avatar"?(r.append(U(t[0],e,n),P()),r):(r.append(_(t,e,n),P()),r)}function _(a,e,t=n=>n){let n=document.createElement("span");n.className="faces";for(let r of a.slice(0,2))n.append(U(r,e,t));return n}function U(a,e,t){let n=document.createElement("span");if(n.className="av",n.setAttribute("aria-hidden","true"),a&&(n.style.background=a.tone),a?.avatarUrl){let r=document.createElement("img");return r.alt="",r.src=t(a.avatarUrl),n.append(r),n}return n.textContent=a?a.initials:e.agentLabel.slice(0,2).toUpperCase(),n}function P(){let a=document.createElement("span");return a.className="live",a.setAttribute("aria-hidden","true"),a}var be={agentLabel:"Agent",aiLabel:"AI",awayBody:"We are away right now, but we will reply as soon as we are back.",closeLabel:"Close chat",emptyBody:"We usually reply within a few minutes.",emptyTitle:"Ask us anything.",inputPlaceholder:"Type a message",launcherLabel:"Chat with us",replyTime:"Usually replying in a few minutes",sendLabel:"Send",timeLabel:a=>{let e=new Date(a);return Number.isNaN(e.getTime())?"":`${String(e.getHours()).padStart(2,"0")}:${String(e.getMinutes()).padStart(2,"0")}`},title:"Support",unreadLabel:a=>`${a} unread`},y={accentColor:"#5b5bff",availability:{timezone:"UTC",windows:[]},awayMessage:"",greeting:"",launcherOffsetX:20,launcherOffsetY:20,launcherPosition:"bottom_right",starterPrompts:[],team:[],...u},xe={quiet:".composer{position:relative;padding:10px 12px 12px}.composer input{padding-right:42px}.composer button{position:absolute;top:50%;right:16px;width:34px;min-width:34px;height:34px;padding:0;background:transparent;color:var(--ink);border-radius:7px;transform:translateY(-50%)}.composer button .sendglyph{display:block;width:18px;height:18px}.composer button .sendtext{display:none}.panel{border-radius:8px;box-shadow:0 2px 8px rgba(0,0,0,.12)}.header{background:var(--paper);color:var(--ink);height:44px;padding:0 8px 0 16px;border-bottom:1px solid var(--hairline)}.header h2{font-size:11px;letter-spacing:.11em;text-transform:uppercase;color:var(--ink-3)}.header .status{color:var(--ink-3)}.header .av,.header .status .live{box-shadow:0 0 0 2px var(--paper)}.close{color:var(--ink-2)}",standard:".panel{border-radius:16px;box-shadow:0 16px 40px rgba(0,0,0,.2)}.header{background:var(--a);color:#fff;flex-direction:column;align-items:flex-start;gap:14px;padding:18px 14px 20px 20px}.header h2{font-size:19px;font-weight:640}"},ye={round:".composer{padding:12px 12px 14px;gap:8px}.composer input{height:46px;border-radius:23px;padding:0 16px}.composer button{width:46px;min-width:46px;height:46px;padding:0;border-radius:23px}.composer button .sendglyph{display:block}.composer button .sendtext{display:none}",square:".composer input{height:44px;border-radius:8px;padding:0 12px}"},ve={rounded:".turn{border-radius:18px;padding:10px 15px}",tailed:".turn.agent,.turn.ai{border-radius:12px 12px 12px 4px}.turn.end_user{border-radius:12px 12px 4px 12px}"},Se={filled:"",outlined:".turn{background:none;border:1px solid var(--hairline)}.turn.end_user{background:none;border-color:var(--a);color:var(--ink)}"},ke={above:"",hidden:".turn.agent .author,.turn.ai .author:not(.ai){display:none}",inline:".body .author.below{display:block;margin:4px 0 0;font-size:11.5px;font-weight:500;color:var(--ink-2);text-transform:none;letter-spacing:0;opacity:1}"},Ce=".turn.agent,.turn.ai{display:flex;gap:10px;max-width:100%;background:none;padding:0}.turn .body{background:var(--fill);padding:9px 13px;border-radius:inherit}.author{text-transform:none;letter-spacing:0;font-size:12.5px;font-weight:600;opacity:1}",we='.divider{display:flex;align-items:center;gap:10px;margin:0;font-size:11px;opacity:.6}.divider:before,.divider:after{content:"";flex:1;height:1px;background:var(--hairline)}',Ee={beside_name:".stamp{font-size:11px;opacity:.7;margin-left:6px}",none:"",under_turn:".stamp{display:block;font-size:11px;opacity:.7;margin-top:4px}.turn.end_user .stamp{text-align:right}"},Ae=".lat{font-size:11px;opacity:.7;margin-left:6px}";function O(a){let e=E(a),t=a.launcherPosition==="bottom_left"?"left":"right",n=a.accentColor;return `${`
1
+ import {c,a as a$2,b}from'./chunk-V77KYPOF.js';import {a as a$1,d}from'./chunk-VG77TYVX.js';import {a}from'./chunk-5XGN7UAV.js';var q="X-Prodantix-Conversation-Token",L="prodantix.chat.handle";function K(){let a=globalThis.localStorage;if(a)return {get:e=>a.getItem(e),remove:e=>a.removeItem(e),set:(e,t)=>a.setItem(e,t)}}var k=class{constructor(e){this.options=e;a(this,"fetchImpl");a(this,"host");a(this,"storage");a(this,"handle");a(this,"identity",null);this.fetchImpl=a$1(e.fetchImpl),this.host=d(e.host),this.storage=e.storage??K(),this.handle=this.readHandle();}get hasThread(){return this.handle!==null}avatarUrl(e){return e.startsWith("/")?`${this.host}${e}?api_key=${encodeURIComponent(this.options.apiKey)}`:e}get socketAuth(){return this.handle?{conversationId:this.handle.conversationId,conversationToken:this.handle.token,projectKey:this.options.apiKey}:null}identify(e){this.identity=e;}async ensureThread(e){if(this.handle)return true;let t=await this.request("POST","/v1/conversations",{body:{distinctId:this.options.distinctId,subject:e,userHash:this.identity?.userHash,userId:this.identity?.userId}});return !t?.conversationId||!t.token?false:(this.handle={conversationId:t.conversationId,token:t.token},this.storage?.set(L,JSON.stringify(this.handle)),true)}async send(e,t){if(!await this.ensureThread())return null;let n=this.handle;return n?(await this.request("POST",`/v1/conversations/${encodeURIComponent(n.conversationId)}/turns`,{body:{body:e,pageContext:t},token:n.token}))?.turn??null:null}async load(){let e=this.handle;return e?this.request("GET",`/v1/conversations/${encodeURIComponent(e.conversationId)}`,{token:e.token}):null}readHandle(){let e=this.storage?.get(L);if(!e)return null;try{let t=JSON.parse(e);if(typeof t.conversationId=="string"&&typeof t.token=="string")return {conversationId:t.conversationId,token:t.token}}catch{}return this.storage?.remove(L),null}async request(e,t,n={}){let r=this.fetchImpl;if(!r)return this.options.onError?.(new Error("no fetch available for prodantix chat")),null;let o={authorization:`Bearer ${this.options.apiKey}`,"content-type":"application/json"};n.token&&(o[q]=n.token);try{let c=await r(`${this.host}${t}`,{body:n.body===void 0?void 0:JSON.stringify(n.body),headers:o,method:e}),i=await c.text();return c.ok?i?JSON.parse(i):{}:(this.options.onError?.(new Error(`prodantix chat ${t}: ${c.status}`)),null)}catch(c){return this.options.onError?.(c),null}}};var Y={Fri:"fri",Mon:"mon",Sat:"sat",Sun:"sun",Thu:"thu",Tue:"tue",Wed:"wed"};function T(a,e){let t=new Intl.DateTimeFormat(void 0,{hour:"2-digit",hour12:false,minute:"2-digit",timeZone:a.timezone,weekday:"short"}).formatToParts(e),n=Y[t.find(i=>i.type==="weekday")?.value??""];if(!n)return false;let r=t.find(i=>i.type==="hour")?.value??"",o=t.find(i=>i.type==="minute")?.value??"",c=`${r}:${o}`;return a.windows.some(i=>i.days.includes(n)&&i.open<=c&&c<i.close)}var u={bubbleFill:"filled",bubbleShape:"tailed",composerShape:"round",dayDividers:true,launcherContent:"glyph",launcherFill:"outlined",launcherShape:"circle",launcherSize:"small",nameAvatar:true,namePlacement:"hidden",skin:"standard",stampContent:"time",stampPlacement:"none"},W=["quiet","standard"],j=["round","square"],G=["rounded","tailed"],X=["filled","outlined"],Z=["circle","pill","squircle"],J=["filled","outlined"],V=["avatar","glyph","team_faces"],Q=["large","medium","small"],ee=["above","hidden","inline"],te=["beside_name","none","under_turn"],ne=["time","time_and_latency"],f=(a,e,t)=>typeof a=="string"&&e.includes(a)?a:t,$=(a,e)=>typeof a=="boolean"?a:e,ae={avatar_circle:["circle","outlined","avatar","large"],circle_filled:["circle","filled","glyph","medium"],circle_outlined:["circle","outlined","glyph","small"],pill_labelled:["pill","filled","glyph","medium"],pill_team:["pill","outlined","team_faces","medium"],squircle_filled:["squircle","filled","glyph","medium"]},re={above:["above",false],avatar_only:["hidden",true],gutter:["above",true],hidden:["hidden",false],inline:["inline",false]},ie={cluster:[true,"none","time"],latency:[false,"beside_name","time_and_latency"],none:[false,"none","time"],trailing:[false,"under_turn","time"],with_name:[false,"beside_name","time"]},oe={concierge:["standard","round"],console:["standard","square"],quiet:["quiet","square"]},se={hairline:["rounded","outlined"],outlined:["rounded","outlined"],rounded:["rounded","filled"],tailed:["tailed","filled"]};function C(a){let e=typeof a=="object"&&a!==null?a:{},t=typeof e.launcherStyle=="string"?e.launcherStyle:void 0,n=t===void 0?void 0:ae[t],r=typeof e.namePlacement=="string"?e.namePlacement:void 0,o=r===void 0?void 0:re[r],c=typeof e.timestampStyle=="string"?e.timestampStyle:void 0,i=c===void 0?void 0:ie[c],h=typeof e.skin=="string"?e.skin:void 0,d=h===void 0?void 0:oe[h],l=typeof e.bubbleStyle=="string"?e.bubbleStyle:void 0,p=l===void 0?void 0:se[l],m={bubbleFill:f(e.bubbleFill,X,p?.[1]??u.bubbleFill),bubbleShape:f(e.bubbleShape,G,p?.[0]??u.bubbleShape),composerShape:f(e.composerShape,j,d?.[1]??u.composerShape),dayDividers:$(e.dayDividers,i?.[0]??u.dayDividers),launcherContent:f(e.launcherContent,V,n?.[2]??u.launcherContent),launcherFill:f(e.launcherFill,J,n?.[1]??u.launcherFill),launcherShape:f(e.launcherShape,Z,n?.[0]??u.launcherShape),launcherSize:f(e.launcherSize,Q,n?.[3]??u.launcherSize),nameAvatar:$(e.nameAvatar,o?.[1]??u.nameAvatar),namePlacement:f(e.namePlacement,ee,o?.[0]??u.namePlacement),skin:f(e.skin,W,d?.[0]??u.skin),stampContent:f(e.stampContent,ne,i?.[2]??u.stampContent),stampPlacement:f(e.stampPlacement,te,i?.[1]??u.stampPlacement)};return m.stampPlacement==="beside_name"&&m.namePlacement==="hidden"&&(m.stampPlacement="under_turn"),m}function z(a){let e=a.split(/\s+/).filter(n=>n.length>0);return (e.length>1?`${e[0]?.slice(0,1)}${e[1]?.slice(0,1)}`:e[0]?.slice(0,2)??"").toUpperCase()}var le="M20 11.6a7.4 7.4 0 0 1-7.4 7.4H8.2L4 21.8l1-4.1A7.4 7.4 0 1 1 20 11.6Z",ce={large:66,medium:56,small:46},de={circle:"width:var(--fab-size);height:var(--fab-size);border-radius:calc(var(--fab-size) / 2);",pill:"width:auto;height:var(--fab-size);border-radius:calc(var(--fab-size) / 2);padding:0 22px;gap:10px;",squircle:"width:var(--fab-size);height:var(--fab-size);border-radius:16px;"},pe={filled:"background:var(--a);color:#fff;",outlined:"background:var(--paper);border:1px solid var(--hairline);color:var(--ink-2);box-shadow:0 1px 2px rgba(0,0,0,.08);"},he={avatar:"",glyph:".launcher svg{width:calc(var(--fab-size) * 0.375);height:calc(var(--fab-size) * 0.375);}",team_faces:".launcher .faces{display:flex;}.launcher .faces .av{box-shadow:0 0 0 2px var(--paper);}.launcher .faces .av+.av{margin-left:-10px;}"},ue=".launcher .live{width:10px;height:10px;position:absolute;right:3px;bottom:3px;border-radius:50%;background:var(--online);box-shadow:0 0 0 2px var(--paper);}.launcher.closed .live{display:none}",me={circle:"",pill:".badge{position:static;box-shadow:none}",squircle:""},ge={filled:"",outlined:".badge{background:var(--a);top:-7px;right:-7px;min-width:19px;height:19px;font-size:11.5px}"},fe={circle:"",pill:".launcher .label{font-size:14px;font-weight:600;white-space:nowrap;}",squircle:""},be={circle:"",pill:"@media (max-width:480px){.launcher{width:var(--fab-size);padding:0}.launcher .label{display:none}}",squircle:""};function U(a,e,t,n){return `.launcher{--fab-size:${ce[n]}px;${de[a]}${pe[e]}}${he[t]}${ue}${me[a]}${ge[e]}${fe[a]}${be[a]}`}function B(a,e,t,n=r=>r){let r=document.createDocumentFragment();if(a==="glyph"||t.length===0){let o=document.createElement("span");return o.innerHTML=`<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="${le}"/></svg>`,r.append(...o.childNodes,P()),r}return a==="avatar"?(r.append(O(t[0],e,n),P()),r):(r.append(_(t,e,n),P()),r)}function _(a,e,t=n=>n){let n=document.createElement("span");n.className="faces";for(let r of a.slice(0,2))n.append(O(r,e,t));return n}function O(a,e,t){let n=document.createElement("span");if(n.className="av",n.setAttribute("aria-hidden","true"),a&&(n.style.background=a.tone),a?.avatarUrl){let r=document.createElement("img");return r.alt="",r.src=t(a.avatarUrl),n.append(r),n}return n.textContent=a?a.initials:e.agentLabel.slice(0,2).toUpperCase(),n}function P(){let a=document.createElement("span");return a.className="live",a.setAttribute("aria-hidden","true"),a}var ye={agentLabel:"Agent",aiLabel:"AI",awayBody:"We are away right now, but we will reply as soon as we are back.",closeLabel:"Close chat",emptyBody:"We usually reply within a few minutes.",emptyTitle:"Ask us anything.",inputPlaceholder:"Type a message",launcherLabel:"Chat with us",replyTime:"Usually replying in a few minutes",sendLabel:"Send",timeLabel:a=>{let e=new Date(a);return Number.isNaN(e.getTime())?"":`${String(e.getHours()).padStart(2,"0")}:${String(e.getMinutes()).padStart(2,"0")}`},title:"Support",unreadLabel:a=>`${a} unread`},x={accentColor:"#5b5bff",availability:{timezone:"UTC",windows:[]},awayMessage:"",greeting:"",launcherOffsetX:20,launcherOffsetY:20,launcherPosition:"bottom_right",starterPrompts:[],team:[],...u},xe={quiet:".composer{position:relative;padding:10px 12px 12px}.composer input{padding-right:42px}.composer button{position:absolute;top:50%;right:16px;width:34px;min-width:34px;height:34px;padding:0;background:transparent;color:var(--ink);border-radius:7px;transform:translateY(-50%)}.composer button .sendglyph{display:block;width:18px;height:18px}.composer button .sendtext{display:none}.panel{border-radius:8px;box-shadow:0 2px 8px rgba(0,0,0,.12)}.header{background:var(--paper);color:var(--ink);height:44px;padding:0 8px 0 16px;border-bottom:1px solid var(--hairline)}.header h2{font-size:11px;letter-spacing:.11em;text-transform:uppercase;color:var(--ink-3)}.header .status{color:var(--ink-3)}.header .av,.header .status .live{box-shadow:0 0 0 2px var(--paper)}.close{color:var(--ink-2)}",standard:".panel{border-radius:16px;box-shadow:0 16px 40px rgba(0,0,0,.2)}.header{background:var(--a);color:#fff;flex-direction:column;align-items:flex-start;gap:14px;padding:18px 14px 20px 20px}.header h2{font-size:19px;font-weight:640}"},ve={round:".composer{padding:12px 12px 14px;gap:8px}.composer input{height:46px;border-radius:23px;padding:0 16px}.composer button{width:46px;min-width:46px;height:46px;padding:0;border-radius:23px}.composer button .sendglyph{display:block}.composer button .sendtext{display:none}",square:".composer input{height:44px;border-radius:8px;padding:0 12px}"},Se={rounded:".turn{border-radius:18px;padding:10px 15px}",tailed:".turn.agent,.turn.ai{border-radius:12px 12px 12px 4px}.turn.end_user{border-radius:12px 12px 4px 12px}"},ke={filled:"",outlined:".turn{background:none;border:1px solid var(--hairline)}.turn.end_user{background:none;border-color:var(--a);color:var(--ink)}"},Ce={above:"",hidden:".turn.agent .author,.turn.ai .author:not(.ai){display:none}",inline:".body .author.below{display:block;margin:4px 0 0;font-size:11.5px;font-weight:500;color:var(--ink-2);text-transform:none;letter-spacing:0;opacity:1}"},we=".turn.agent,.turn.ai{display:flex;gap:10px;max-width:100%;background:none;padding:0}.turn.agent .body,.turn.ai .body{background:var(--fill);padding:9px 13px;border-radius:inherit}.author{text-transform:none;letter-spacing:0;font-size:12.5px;font-weight:600;opacity:1}",Te='.divider{display:flex;align-items:center;gap:10px;margin:0;font-size:11px;opacity:.6}.divider:before,.divider:after{content:"";flex:1;height:1px;background:var(--hairline)}',Ae={beside_name:".stamp{font-size:11px;opacity:.7;margin-left:6px}",none:"",under_turn:".stamp{display:block;font-size:11px;opacity:.7;margin-top:4px}.turn.end_user .stamp{text-align:right}"},Ee=".lat{font-size:11px;opacity:.7;margin-left:6px}",D=`--paper: oklch(24.6% 0.015 257); --ink: #fff; --ink-3: rgba(255,255,255,.55);
2
+ --fill: rgba(255,255,255,.06); --hairline: rgba(255,255,255,.13); --ink-2: rgba(255,255,255,.70);
3
+ --online: oklch(72% 0.13 163.23);`;function Le(a){return a==="light"?"":a==="dark"?`:host { ${D} }`:`@media (prefers-color-scheme: dark) {
4
+ :host {
5
+ ${D}
6
+ }
7
+ }`}function N(a,e="system"){let t=C(a),n=a.launcherPosition==="bottom_left"?"left":"right",r=a.accentColor;return `${`
2
8
  :host {
3
9
  /* The widget sits above the host page's own furniture. The reset above sends
4
10
  z-index back to auto, so without this the launcher and panel stack at the
@@ -6,25 +12,19 @@ import {c,a as a$2,b}from'./chunk-V77KYPOF.js';import {a as a$1,d}from'./chunk-V
6
12
  draws over them: the WebMCP chip covered the launcher on clepit's landing.
7
13
  Below the 32-bit ceiling so a host can still put something over us
8
14
  deliberately. */
9
- all: initial; z-index: 2147483000; --a: ${n};
15
+ all: initial; z-index: 2147483000; --a: ${r};
10
16
  --paper: #fff; --ink: #0f172a; --ink-3: var(--ink-3);
11
17
  --fill: #f1f5f9; --hairline: #e2e8f0; --ink-2: rgba(0,0,0,.72);
12
18
  --online: oklch(53.8% 0.1274 163.23);
13
- color-scheme: light dark;
14
- }
15
- @media (prefers-color-scheme: dark) {
16
- :host {
17
- --paper: oklch(24.6% 0.015 257); --ink: #fff; --ink-3: rgba(255,255,255,.55);
18
- --fill: rgba(255,255,255,.06); --hairline: rgba(255,255,255,.13); --ink-2: rgba(255,255,255,.70);
19
- --online: oklch(72% 0.13 163.23);
20
- }
19
+ color-scheme: ${e==="system"?"light dark":e};
21
20
  }
21
+ ${Le(e)}
22
22
  * { box-sizing: border-box; font-family: system-ui, sans-serif; }
23
23
  .launcher {
24
- z-index: 2147483000; position: fixed; ${t}: ${a.launcherOffsetX}px; bottom: ${a.launcherOffsetY}px; width: 56px; height: 56px;
24
+ z-index: 2147483000; position: fixed; ${n}: ${a.launcherOffsetX}px; bottom: ${a.launcherOffsetY}px; width: 56px; height: 56px;
25
25
  border-radius: 28px; border: none; cursor: pointer;
26
26
  display: inline-flex; align-items: center; justify-content: center;
27
- background: ${n}; color: #fff; font-size: 24px;
27
+ background: ${r}; color: #fff; font-size: 24px;
28
28
  box-shadow: 0 4px 12px rgba(0,0,0,.2);
29
29
  }
30
30
  .launcher:focus-visible { outline: 3px solid #0b0e14; outline-offset: 2px; }
@@ -34,8 +34,8 @@ import {c,a as a$2,b}from'./chunk-V77KYPOF.js';import {a as a$1,d}from'./chunk-V
34
34
  control a visitor is meant to click the only element in the product that
35
35
  shifted when pointed at. */
36
36
  .launcher { transition: background-color 120ms ease; }
37
- .launcher:hover { background: color-mix(in srgb, #000 12%, ${n}); }
38
- .launcher:active { background: color-mix(in srgb, #000 20%, ${n}); }
37
+ .launcher:hover { background: color-mix(in srgb, #000 12%, ${r}); }
38
+ .launcher:active { background: color-mix(in srgb, #000 20%, ${r}); }
39
39
  @media (prefers-reduced-motion: reduce) {
40
40
  .launcher { transition: none; }
41
41
  }
@@ -52,7 +52,7 @@ import {c,a as a$2,b}from'./chunk-V77KYPOF.js';import {a as a$1,d}from'./chunk-V
52
52
  the one that needs it. */
53
53
  .badge[hidden] { display: none; }
54
54
  .panel {
55
- z-index: 2147483001; position: fixed; ${t}: ${a.launcherOffsetX}px; bottom: ${a.launcherOffsetY+68}px; width: 360px; max-width: calc(100vw - 40px);
55
+ z-index: 2147483001; position: fixed; ${n}: ${a.launcherOffsetX}px; bottom: ${a.launcherOffsetY+68}px; width: 360px; max-width: calc(100vw - 40px);
56
56
  height: 520px; max-height: calc(100vh - 120px); background: var(--paper); color: var(--ink);
57
57
  border-radius: 12px; box-shadow: 0 8px 32px rgba(0,0,0,.24);
58
58
  display: flex; flex-direction: column; overflow: hidden;
@@ -67,7 +67,17 @@ import {c,a as a$2,b}from'./chunk-V77KYPOF.js';import {a as a$1,d}from'./chunk-V
67
67
  .header .av + .av { margin-left: -12px; }
68
68
  .headmain { display: flex; flex-direction: column; }
69
69
  .header .status { display: flex; align-items: center; gap: 6px; margin: 5px 0 0; font-size: 12.5px; color: rgb(255 255 255 / 80%); }
70
- .header .status .live { flex: none; width: 10px; height: 10px; border-radius: 50%; background: var(--online); box-shadow: 0 0 0 2px var(--a); }
70
+ /* The dot's ring is the PAPER, not the accent. An accent ring on the standard
71
+ skin is the header's own background and draws nothing, which is how this
72
+ shipped looking ringless beside a preview that had one. The faces above keep
73
+ the accent ring, which is a different job: separating two overlapping discs
74
+ from each other and from the header. */
75
+ .header .status .live { flex: none; width: 10px; height: 10px; border-radius: 50%; background: var(--online); box-shadow: 0 0 0 2px var(--paper); }
76
+ /* Hours, the same fact the launcher's dot carries. A green dot and a sentence
77
+ promising a reply in minutes are both claims about somebody being there, so
78
+ outside the project's hours neither is drawn: the away message in the thread
79
+ is what speaks then. */
80
+ .panel.closed .status { display: none; }
71
81
  /* Pinned rather than laid out: the standard skin turns this header into a
72
82
  column so the title can carry a line under it, and a close button that is
73
83
  merely a flex sibling then stacks BELOW the title on the left, which is where
@@ -89,7 +99,7 @@ import {c,a as a$2,b}from'./chunk-V77KYPOF.js';import {a as a$1,d}from'./chunk-V
89
99
  .close:focus-visible { outline: 2px solid currentColor; outline-offset: 1px; }
90
100
  .log { flex: 1; overflow-y: auto; padding: 12px; display: flex; flex-direction: column; gap: 8px; }
91
101
  .turn { max-width: 80%; padding: 8px 12px; border-radius: 12px; font-size: 14px; }
92
- .turn.end_user { align-self: flex-end; background: ${n}; color: #fff; }
102
+ .turn.end_user { align-self: flex-end; background: ${r}; color: #fff; }
93
103
  .turn.agent, .turn.ai { align-self: flex-start; background: var(--fill); color: var(--ink); }
94
104
  .author { font-size: 11px; opacity: .7; margin-bottom: 2px; }
95
105
  .away { background: var(--fill); border: 1px solid var(--hairline); border-radius: 8px; padding: 8px 12px; font-size: 13.5px; color: var(--ink-2); }
@@ -101,19 +111,21 @@ import {c,a as a$2,b}from'./chunk-V77KYPOF.js';import {a as a$1,d}from'./chunk-V
101
111
  font-family: inherit; font-size: 13.5px; font-weight: 500; color: var(--ink);
102
112
  background: none; border: 1px solid var(--hairline); border-radius: 8px; cursor: pointer;
103
113
  }
104
- .prompt:focus-visible { outline: 2px solid ${n}; outline-offset: 2px; }
114
+ .prompt:focus-visible { outline: 2px solid ${r}; outline-offset: 2px; }
105
115
  .av { width: 30px; height: 30px; border-radius: 50%; flex: none; display: inline-flex; align-items: center; justify-content: center; font-size: 11.5px; font-weight: 650; color: #fff; background: #7c3f3f; }
106
116
  .av.bot { border-radius: 9px; background: var(--fill); color: var(--ink); }
107
117
  .av img { width: 100%; height: 100%; display: block; object-fit: cover; border-radius: inherit; }
108
118
  .composer { display: flex; gap: 8px; padding: 12px; border-top: 1px solid var(--hairline); }
109
119
  .composer input { flex: 1; min-width: 0; height: 44px; padding: 0 12px; border: 0; border-radius: 8px; font-size: 14px; background: var(--fill); color: var(--ink); }
110
- .composer input:focus-visible { outline: 2px solid ${n}; }
111
- .composer button { display: inline-flex; align-items: center; justify-content: center; gap: 0; min-width: 64px; height: 44px; padding: 0 16px; background: ${n}; color: #fff; border: none; border-radius: 8px; cursor: pointer; font-family: inherit; font-size: 14.5px; font-weight: 550; }
120
+ .composer input:focus-visible { outline: 2px solid ${r}; }
121
+ .composer button { display: inline-flex; align-items: center; justify-content: center; gap: 0; min-width: 64px; height: 44px; padding: 0 16px; background: ${r}; color: #fff; border: none; border-radius: 8px; cursor: pointer; font-family: inherit; font-size: 14.5px; font-weight: 550; }
122
+ .composer button:hover { background: color-mix(in srgb, #000 12%, ${r}); }
123
+ .composer button:focus-visible { outline: 2px solid var(--ink); outline-offset: 2px; }
112
124
  .composer button .sendglyph { display: none; width: 19px; height: 19px; }
113
125
  .composer button:focus-visible { outline: 2px solid #0b0e14; }
114
126
  @media (prefers-reduced-motion: no-preference) {
115
127
  .panel { animation: rise 180ms ease-out; }
116
128
  @keyframes rise { from { transform: translateY(8px); opacity: 0; } to { transform: none; opacity: 1; } }
117
129
  }
118
- `}${ye[e.composerShape]}${xe[e.skin]}${z(e.launcherShape,e.launcherFill,e.launcherContent,e.launcherSize)}${ve[e.bubbleShape]}${Se[e.bubbleFill]}${ke[e.namePlacement]}${e.nameAvatar?Ce:""}${e.dayDividers?we:""}${Ee[e.stampPlacement]}${e.stampContent==="time_and_latency"?Ae:""}`}var Te=["end_user","agent","ai"];function Le(){let a=globalThis.location;if(a)return {host:a.host,path:a.pathname,title:document.title}}var C=class{constructor(e,t,n={},r={}){this.host=e;this.client=t;a(this,"root");a(this,"strings");a(this,"settings");a(this,"appearance");a(this,"launcher");a(this,"badge");a(this,"panel",null);a(this,"lastFocused",null);a(this,"unread",0);this.strings={...be,...n},this.appearance={...y,...r},this.settings=E({...y,...r}),this.root=e.attachShadow({mode:"closed"});let s=document.createElement("style");if(s.textContent=O({...y,...r}),this.root.append(s),this.launcher=document.createElement("button"),this.launcher.className="launcher",this.launcher.type="button",this.launcher.setAttribute("aria-haspopup","dialog"),this.launcher.setAttribute("aria-label",this.strings.launcherLabel),this.launcher.append(B(this.settings.launcherContent,this.strings,this.appearance.team,o=>this.client.avatarUrl(o))),this.settings.launcherShape==="pill"){let o=document.createElement("span");o.className="label",o.textContent=this.settings.launcherContent==="team_faces"?this.strings.agentLabel:this.strings.launcherLabel,this.launcher.append(o);}this.launcher.addEventListener("click",()=>this.toggle()),this.badge=document.createElement("span"),this.badge.className="badge",this.badge.hidden=true,this.launcher.append(this.badge),this.root.append(this.launcher);}toggle(){this.panel?this.close():this.open();}setOpenNow(e){this.launcher.classList.toggle("closed",!e);}async open(){if(this.panel)return;this.lastFocused=this.host.ownerDocument.activeElement,this.unread=0,this.renderBadge();let e=document.createElement("section");e.className="panel",e.setAttribute("role","dialog"),e.setAttribute("aria-modal","true"),e.setAttribute("aria-label",this.strings.title);let t=document.createElement("div");t.className="header";let n=this.appearance.team??[];n.length>0&&t.append(_(n,this.strings,b=>this.client.avatarUrl(b)));let r=document.createElement("div");r.className="headmain";let s=document.createElement("h2");s.textContent=this.strings.title;let o=document.createElement("p");o.className="status";let i=document.createElement("span");i.className="live",i.setAttribute("aria-hidden","true"),o.append(i,this.strings.replyTime),r.append(s,o);let h=document.createElement("button");h.className="close",h.type="button",h.setAttribute("aria-label",this.strings.closeLabel),h.textContent="\xD7",h.addEventListener("click",()=>this.close()),t.append(r,h);let d=document.createElement("div");d.className="log",d.setAttribute("role","log"),d.setAttribute("aria-live","polite"),d.setAttribute("aria-label",this.strings.title);let l=document.createElement("form");l.className="composer";let p=document.createElement("input");p.type="text",p.setAttribute("aria-label",this.strings.inputPlaceholder),p.placeholder=this.strings.inputPlaceholder;let m=document.createElement("button");m.type="submit",m.setAttribute("aria-label",this.strings.sendLabel),m.innerHTML='<svg class="sendglyph" aria-hidden="true" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M4.5 12 20 4.5 15 20l-3.6-5.4L4.5 12Z"/></svg>';let v=document.createElement("span");v.className="sendtext",v.textContent=this.strings.sendLabel,m.append(v),l.append(p,m),l.addEventListener("submit",b=>{b.preventDefault(),this.submit(p,d);}),e.append(t,d,l),e.addEventListener("keydown",b=>this.onKeydown(b,e,h)),this.root.append(e),this.panel=e,p.focus();let x=await this.client.load();x&&x.turns.length>0?this.renderThread(d,x):this.renderFirstRun(d,p),w(this.appearance.availability,new Date)||this.renderAway(d);}renderFirstRun(e,t){let n=document.createElement("div");n.className="empty";let r=document.createElement("h3");r.textContent=this.appearance.greeting.trim()||this.strings.emptyTitle;let s=document.createElement("p");s.textContent=this.strings.emptyBody,n.append(r,s);for(let o of this.appearance.starterPrompts){let i=document.createElement("button");i.className="prompt",i.type="button",i.textContent=o,i.addEventListener("click",()=>{t.value=o,this.submit(t,e);}),n.append(i);}e.replaceChildren(n);}renderAway(e){let t=document.createElement("div");t.className="away",t.textContent=this.appearance.awayMessage.trim()||this.strings.awayBody,e.prepend(t);}close(){this.panel&&(this.panel.remove(),this.panel=null,this.lastFocused instanceof HTMLElement?this.lastFocused.focus():this.launcher.focus());}onIncomingTurn(e){if(this.panel){let t=this.panel.querySelector(".log");t instanceof HTMLElement&&this.appendTurn(t,e);return}e.authorKind!=="end_user"&&(this.unread+=1,this.renderBadge());}async submit(e,t){let n=e.value.trim();if(!n)return;e.value="",t.querySelector(".empty")?.remove();let r=await this.client.send(n,Le());r&&this.appendTurn(t,r);}renderThread(e,t){e.replaceChildren();for(let n of t.turns)this.appendTurn(e,n);}appendTurn(e,t){e.querySelector(".empty")?.remove();let n=Te.includes(t.authorKind)?t.authorKind:"agent",r=this.settings,s=document.createElement("div");if(s.className=`turn ${n}`,n!=="end_user"&&r.nameAvatar){let l=document.createElement("span");if(l.className=n==="ai"?"av bot":"av",l.setAttribute("aria-hidden","true"),n==="agent"&&t.authorAvatarUrl){let p=document.createElement("img");p.alt="",p.src=this.client.avatarUrl(t.authorAvatarUrl),l.append(p);}else l.textContent=n==="ai"?this.strings.aiLabel:$(this.agentName(t));s.append(l);}let i=document.createElement("div");i.className="body";let h=n!=="end_user"&&r.namePlacement!=="hidden",d=document.createElement("div");if(d.textContent=t.body,h||n==="ai"&&r.namePlacement==="hidden"){let l=document.createElement("div");l.className=n==="ai"?"author ai":"author",l.textContent=n==="ai"?this.strings.aiLabel:this.agentName(t),r.stampPlacement==="beside_name"&&l.append(this.stamp(t)),r.namePlacement==="inline"?(l.classList.add("below"),i.append(d,l)):i.append(l,d);}else i.append(d);r.stampPlacement==="under_turn"&&i.append(this.stamp(t)),s.append(i),e.append(s),e.scrollTop=e.scrollHeight;}agentName(e){return e.authorName||this.strings.agentLabel}stamp(e){let t=document.createElement("span");return t.className="stamp",t.textContent=this.strings.timeLabel(e.createdAt),t}onKeydown(e,t,n){if(e.key==="Escape"){e.preventDefault(),this.close();return}if(e.key!=="Tab")return;let r=t.querySelectorAll('button, input, [tabindex]:not([tabindex="-1"])');if(r.length===0)return;let s=r[0],o=r[r.length-1],i=this.root.activeElement;e.shiftKey&&i===s?(e.preventDefault(),o.focus()):!e.shiftKey&&i===o?(e.preventDefault(),s.focus()):i===null&&(e.preventDefault(),n.focus());}renderBadge(){this.unread>0?(this.badge.hidden=false,this.badge.textContent=String(this.unread),this.launcher.setAttribute("aria-label",`${this.strings.launcherLabel}, ${this.strings.unreadLabel(this.unread)}`)):(this.badge.hidden=true,this.badge.textContent="",this.launcher.setAttribute("aria-label",this.strings.launcherLabel));}};var Pe="/socket.io/?EIO=4&transport=websocket",A=class{constructor(e){this.options=e;a(this,"socket",null);a(this,"heartbeat",null);a(this,"ready",false);a(this,"closed",false);a(this,"heartbeatWindow",45e3);a(this,"factory");a(this,"setTimer");a(this,"clearTimer");this.factory=e.socketFactory??_e,this.setTimer=e.setTimer??((t,n)=>setTimeout(t,n)),this.clearTimer=e.clearTimer??(t=>clearTimeout(t));}open(){if(this.socket||this.closed)return;let e=`${this.options.host.replace(/^http/,"ws").replace(/\/+$/,"")}${Pe}`,t;try{t=this.factory(e);}catch{this.options.onClosed(false);return}this.socket=t,t.onmessage=n=>this.receive(String(n.data)),t.onerror=()=>t.close(),t.onclose=()=>this.fell();}close(){this.closed=true,this.stopHeartbeat();let e=this.socket;this.socket=null,e?.close();}receive(e){let t=c(e);if(t.kind==="open"){this.armHeartbeat(t.pingInterval+t.pingTimeout),this.socket?.send(a$2(this.options.auth));return}if(t.kind==="ping"){this.armHeartbeat(),this.socket?.send(b());return}if(t.kind==="connectError"||t.kind==="disconnect"){this.stopHeartbeat(),this.socket?.close();return}if(t.kind==="event"){if(t.name==="ready"){this.ready=true,this.options.onReady();return}if(t.name==="conversation.turn"){let n=t.payload?.turn;n&&this.options.onTurn(n);}}}fell(){this.stopHeartbeat();let e=this.ready;this.socket=null,this.ready=false,this.closed||this.options.onClosed(e);}armHeartbeat(e){e!==void 0&&(this.heartbeatWindow=e),this.stopHeartbeat(),this.heartbeat=this.setTimer(()=>this.socket?.close(),this.heartbeatWindow);}stopHeartbeat(){this.heartbeat!==null&&this.clearTimer(this.heartbeat),this.heartbeat=null;}};function _e(a){let e=globalThis.WebSocket;if(!e)throw new Error("no WebSocket");return new e(a)}var Ne=6e4;function Ze(a){let e=globalThis.document;if(!e)throw new Error("prodantix chat requires a document; mount it in the browser");let t=a.mountPoint??e.createElement("div");a.mountPoint||e.body.append(t);let n=new k(a),r=new C(t,n,a.strings,a.appearance),s=a.appearance?.availability??y.availability,o,i=()=>{r.setOpenNow(w(s,new Date)),o=setTimeout(i,Ne);};i();let h=new Set,d,l=null,p=a.pollIntervalMs??15e3,m=g=>{h.has(g.id)||g.authorKind==="end_user"||(h.add(g.id),r.onIncomingTurn(g));},v=async()=>{if(!n.hasThread)return;let g=await n.load();if(g){for(let S of g.turns)m(S);h=new Set(g.turns.map(S=>S.id));}},x=()=>{d||p<=0||(d=setInterval(()=>void v(),p));},b=()=>{d&&clearInterval(d),d=void 0;},T=()=>{if(l||!a.socketHost)return;let g=n.socketAuth;g&&(l=new A({auth:g,host:a.socketHost,onClosed:S=>{l=null,x(),S&&T();},onReady:b,onTurn:m,socketFactory:a.socketFactory}),l.open());};return x(),T(),{close:()=>r.close(),destroy:()=>{b(),clearTimeout(o),l?.close(),l=null,r.close(),t.remove();},identify:g=>n.identify(g),open:()=>{r.open().then(T);}}}export{k as ChatClient,C as ChatPanel,y as DEFAULT_APPEARANCE,u as DEFAULT_APPEARANCE_SETTINGS,Ze as mountChat,O as panelStyles,E as resolveAppearance};//# sourceMappingURL=chat.js.map
130
+ `}${ve[t.composerShape]}${xe[t.skin]}${U(t.launcherShape,t.launcherFill,t.launcherContent,t.launcherSize)}${Se[t.bubbleShape]}${ke[t.bubbleFill]}${Ce[t.namePlacement]}${t.nameAvatar?we:""}${t.dayDividers?Te:""}${Ae[t.stampPlacement]}${t.stampContent==="time_and_latency"?Ee:""}`}var Pe=["end_user","agent","ai"];function _e(){let a=globalThis.location;if(a)return {host:a.host,path:a.pathname,title:document.title}}var w=class{constructor(e,t,n={},r={},o={}){this.host=e;this.client=t;a(this,"root");a(this,"strings");a(this,"settings");a(this,"appearance");a(this,"launcher");a(this,"badge");a(this,"panel",null);a(this,"lastFocused",null);a(this,"unread",0);a(this,"openNow");a(this,"style");a(this,"scheme");this.strings={...ye,...n},this.appearance={...x,...r},this.settings=C({...x,...r}),this.root=e.attachShadow({mode:o.shadowMode??"closed"}),this.openNow=T(this.appearance.availability,new Date),this.scheme=o.scheme,this.style=document.createElement("style"),this.style.textContent=N(this.appearance,this.scheme),this.root.append(this.style),this.launcher=document.createElement("button"),this.launcher.className="launcher",this.launcher.type="button",this.launcher.setAttribute("aria-haspopup","dialog"),this.launcher.addEventListener("click",()=>this.toggle()),this.badge=document.createElement("span"),this.badge.className="badge",this.badge.hidden=true,this.drawLauncher(),this.root.append(this.launcher);}drawLauncher(){if(this.launcher.setAttribute("aria-label",this.strings.launcherLabel),this.launcher.replaceChildren(),this.launcher.append(B(this.settings.launcherContent,this.strings,this.appearance.team,e=>this.client.avatarUrl(e))),this.settings.launcherShape==="pill"){let e=document.createElement("span");e.className="label",e.textContent=this.settings.launcherContent==="team_faces"?this.strings.agentLabel:this.strings.launcherLabel,this.launcher.append(e);}this.launcher.append(this.badge),this.launcher.classList.toggle("closed",!this.openNow);}update(e,t){this.appearance={...x,...e},this.settings=C(this.appearance),t!==void 0&&(this.scheme=t),this.style.textContent=N(this.appearance,this.scheme),this.drawLauncher(),this.panel&&(this.close(),this.open());}toggle(){this.panel?this.close():this.open();}setOpenNow(e){this.openNow=e,this.launcher.classList.toggle("closed",!e),this.panel?.classList.toggle("closed",!e);}async open(){if(this.panel)return;this.lastFocused=this.host.ownerDocument.activeElement,this.unread=0,this.renderBadge();let e=document.createElement("section");e.className=this.openNow?"panel":"panel closed",e.setAttribute("role","dialog"),e.setAttribute("aria-modal","true"),e.setAttribute("aria-label",this.strings.title);let t=document.createElement("div");t.className="header";let n=this.appearance.team??[];n.length>0&&t.append(_(n,this.strings,b=>this.client.avatarUrl(b)));let r=document.createElement("div");r.className="headmain";let o=document.createElement("h2");o.textContent=this.strings.title;let c=document.createElement("p");c.className="status";let i=document.createElement("span");i.className="live",i.setAttribute("aria-hidden","true"),c.append(i,this.strings.replyTime),r.append(o,c);let h=document.createElement("button");h.className="close",h.type="button",h.setAttribute("aria-label",this.strings.closeLabel),h.textContent="\xD7",h.addEventListener("click",()=>this.close()),t.append(r,h);let d=document.createElement("div");d.className="log",d.setAttribute("role","log"),d.setAttribute("aria-live","polite"),d.setAttribute("aria-label",this.strings.title);let l=document.createElement("form");l.className="composer";let p=document.createElement("input");p.type="text",p.setAttribute("aria-label",this.strings.inputPlaceholder),p.placeholder=this.strings.inputPlaceholder;let m=document.createElement("button");m.type="submit",m.setAttribute("aria-label",this.strings.sendLabel),m.innerHTML='<svg class="sendglyph" aria-hidden="true" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M4.5 12 20 4.5 15 20l-3.6-5.4L4.5 12Z"/></svg>';let v=document.createElement("span");v.className="sendtext",v.textContent=this.strings.sendLabel,m.append(v),l.append(p,m),l.addEventListener("submit",b=>{b.preventDefault(),this.submit(p,d);}),e.append(t,d,l),e.addEventListener("keydown",b=>this.onKeydown(b,e,h)),this.root.append(e),this.panel=e,p.focus();let y=await this.client.load();y&&y.turns.length>0?this.renderThread(d,y):this.renderFirstRun(d,p),this.openNow||this.renderAway(d);}renderFirstRun(e,t){let n=document.createElement("div");n.className="empty";let r=document.createElement("h3");r.textContent=this.appearance.greeting.trim()||this.strings.emptyTitle;let o=document.createElement("p");o.textContent=this.strings.emptyBody,n.append(r,o);for(let c of this.appearance.starterPrompts){let i=document.createElement("button");i.className="prompt",i.type="button",i.textContent=c,i.addEventListener("click",()=>{t.value=c,this.submit(t,e);}),n.append(i);}e.replaceChildren(n);}renderAway(e){let t=document.createElement("div");t.className="away",t.textContent=this.appearance.awayMessage.trim()||this.strings.awayBody,e.prepend(t);}close(){this.panel&&(this.panel.remove(),this.panel=null,this.lastFocused instanceof HTMLElement?this.lastFocused.focus():this.launcher.focus());}onIncomingTurn(e){if(this.panel){let t=this.panel.querySelector(".log");t instanceof HTMLElement&&this.appendTurn(t,e);return}e.authorKind!=="end_user"&&(this.unread+=1,this.renderBadge());}async submit(e,t){let n=e.value.trim();if(!n)return;e.value="",t.querySelector(".empty")?.remove();let r=await this.client.send(n,_e());r&&this.appendTurn(t,r);}renderThread(e,t){e.replaceChildren();for(let n of t.turns)this.appendTurn(e,n);}appendTurn(e,t){e.querySelector(".empty")?.remove();let n=Pe.includes(t.authorKind)?t.authorKind:"agent",r=this.settings,o=document.createElement("div");if(o.className=`turn ${n}`,n!=="end_user"&&r.nameAvatar){let l=document.createElement("span");if(l.className=n==="ai"?"av bot":"av",l.setAttribute("aria-hidden","true"),n==="agent"&&t.authorAvatarUrl){let p=document.createElement("img");p.alt="",p.src=this.client.avatarUrl(t.authorAvatarUrl),l.append(p);}else l.textContent=n==="ai"?this.strings.aiLabel:z(this.agentName(t));o.append(l);}let i=document.createElement("div");i.className="body";let h=n!=="end_user"&&r.namePlacement!=="hidden",d=document.createElement("div");if(d.textContent=t.body,h||n==="ai"&&r.namePlacement==="hidden"){let l=document.createElement("div");l.className=n==="ai"?"author ai":"author",l.textContent=n==="ai"?this.strings.aiLabel:this.agentName(t),r.stampPlacement==="beside_name"&&l.append(this.stamp(t)),r.namePlacement==="inline"?(l.classList.add("below"),i.append(d,l)):i.append(l,d);}else i.append(d);r.stampPlacement==="under_turn"&&i.append(this.stamp(t)),o.append(i),e.append(o),e.scrollTop=e.scrollHeight;}agentName(e){return e.authorName||this.strings.agentLabel}stamp(e){let t=document.createElement("span");return t.className="stamp",t.textContent=this.strings.timeLabel(e.createdAt),t}onKeydown(e,t,n){if(e.key==="Escape"){e.preventDefault(),this.close();return}if(e.key!=="Tab")return;let r=t.querySelectorAll('button, input, [tabindex]:not([tabindex="-1"])');if(r.length===0)return;let o=r[0],c=r[r.length-1],i=this.root.activeElement;e.shiftKey&&i===o?(e.preventDefault(),c.focus()):!e.shiftKey&&i===c?(e.preventDefault(),o.focus()):i===null&&(e.preventDefault(),n.focus());}renderBadge(){this.unread>0?(this.badge.hidden=false,this.badge.textContent=String(this.unread),this.launcher.setAttribute("aria-label",`${this.strings.launcherLabel}, ${this.strings.unreadLabel(this.unread)}`)):(this.badge.hidden=true,this.badge.textContent="",this.launcher.setAttribute("aria-label",this.strings.launcherLabel));}};var Ne="/socket.io/?EIO=4&transport=websocket",A=class{constructor(e){this.options=e;a(this,"socket",null);a(this,"heartbeat",null);a(this,"ready",false);a(this,"closed",false);a(this,"heartbeatWindow",45e3);a(this,"factory");a(this,"setTimer");a(this,"clearTimer");this.factory=e.socketFactory??He,this.setTimer=e.setTimer??((t,n)=>setTimeout(t,n)),this.clearTimer=e.clearTimer??(t=>clearTimeout(t));}open(){if(this.socket||this.closed)return;let e=`${this.options.host.replace(/^http/,"ws").replace(/\/+$/,"")}${Ne}`,t;try{t=this.factory(e);}catch{this.options.onClosed(false);return}this.socket=t,t.onmessage=n=>this.receive(String(n.data)),t.onerror=()=>t.close(),t.onclose=()=>this.fell();}close(){this.closed=true,this.stopHeartbeat();let e=this.socket;this.socket=null,e?.close();}receive(e){let t=c(e);if(t.kind==="open"){this.armHeartbeat(t.pingInterval+t.pingTimeout),this.socket?.send(a$2(this.options.auth));return}if(t.kind==="ping"){this.armHeartbeat(),this.socket?.send(b());return}if(t.kind==="connectError"||t.kind==="disconnect"){this.stopHeartbeat(),this.socket?.close();return}if(t.kind==="event"){if(t.name==="ready"){this.ready=true,this.options.onReady();return}if(t.name==="conversation.turn"){let n=t.payload?.turn;n&&this.options.onTurn(n);}}}fell(){this.stopHeartbeat();let e=this.ready;this.socket=null,this.ready=false,this.closed||this.options.onClosed(e);}armHeartbeat(e){e!==void 0&&(this.heartbeatWindow=e),this.stopHeartbeat(),this.heartbeat=this.setTimer(()=>this.socket?.close(),this.heartbeatWindow);}stopHeartbeat(){this.heartbeat!==null&&this.clearTimer(this.heartbeat),this.heartbeat=null;}};function He(a){let e=globalThis.WebSocket;if(!e)throw new Error("no WebSocket");return new e(a)}var Fe=6e4;function Ve(a){let e=globalThis.document;if(!e)throw new Error("prodantix chat requires a document; mount it in the browser");let t=a.mountPoint??e.createElement("div");a.mountPoint||e.body.append(t);let n=new k(a),r=new w(t,n,a.strings,a.appearance),o=a.appearance?.availability??x.availability,c,i=()=>{r.setOpenNow(T(o,new Date)),c=setTimeout(i,Fe);};i();let h=new Set,d,l=null,p=a.pollIntervalMs??15e3,m=g=>{h.has(g.id)||g.authorKind==="end_user"||(h.add(g.id),r.onIncomingTurn(g));},v=async()=>{if(!n.hasThread)return;let g=await n.load();if(g){for(let S of g.turns)m(S);h=new Set(g.turns.map(S=>S.id));}},y=()=>{d||p<=0||(d=setInterval(()=>void v(),p));},b=()=>{d&&clearInterval(d),d=void 0;},E=()=>{if(l||!a.socketHost)return;let g=n.socketAuth;g&&(l=new A({auth:g,host:a.socketHost,onClosed:S=>{l=null,y(),S&&E();},onReady:b,onTurn:m,socketFactory:a.socketFactory}),l.open());};return y(),E(),{close:()=>r.close(),destroy:()=>{b(),clearTimeout(c),l?.close(),l=null,r.close(),t.remove();},identify:g=>n.identify(g),open:()=>{r.open().then(E);}}}export{k as ChatClient,w as ChatPanel,x as DEFAULT_APPEARANCE,u as DEFAULT_APPEARANCE_SETTINGS,Ve as mountChat,N as panelStyles,C as resolveAppearance};//# sourceMappingURL=chat.js.map
119
131
  //# sourceMappingURL=chat.js.map
@@ -131,4 +131,4 @@ declare const MESSENGER_CACHE_KEY = "prodantix.messenger.config";
131
131
  declare function cachedMessengerConfig(storage: ChatStorage | undefined, apiKey: string): MessengerConfig | null;
132
132
  declare function fetchMessengerConfig(options: MessengerConfigOptions): Promise<MessengerConfig | null>;
133
133
 
134
- export { type AppearanceSettings as A, type BubbleFill as B, ChatClient as C, DEFAULT_APPEARANCE_SETTINGS as D, type LauncherContent as L, type MessengerConfig as M, type NamePlacement as N, type StampContent as S, type ChatTurn as a, type ChatIdentity as b, type ChatClientOptions as c, type BubbleShape as d, type ChatStorage as e, type ChatThread as f, type ComposerShape as g, type LauncherFill as h, type LauncherShape as i, type LauncherSize as j, type MessengerSkin as k, type StampPlacement as l, MESSENGER_CACHE_KEY as m, type MessengerConfigOptions as n, cachedMessengerConfig as o, fetchMessengerConfig as p, resolveAppearance as r };
134
+ export { type AppearanceSettings as A, type BubbleFill as B, type ChatThread as C, DEFAULT_APPEARANCE_SETTINGS as D, type LauncherContent as L, type MessengerConfig as M, type NamePlacement as N, type PageContext as P, type StampContent as S, type ChatTurn as a, type ChatIdentity as b, type ChatClientOptions as c, type BubbleShape as d, ChatClient as e, type ChatStorage as f, type ComposerShape as g, type LauncherFill as h, type LauncherShape as i, type LauncherSize as j, type MessengerSkin as k, type StampPlacement as l, MESSENGER_CACHE_KEY as m, type MessengerConfigOptions as n, cachedMessengerConfig as o, fetchMessengerConfig as p, resolveAppearance as r };
@@ -131,4 +131,4 @@ declare const MESSENGER_CACHE_KEY = "prodantix.messenger.config";
131
131
  declare function cachedMessengerConfig(storage: ChatStorage | undefined, apiKey: string): MessengerConfig | null;
132
132
  declare function fetchMessengerConfig(options: MessengerConfigOptions): Promise<MessengerConfig | null>;
133
133
 
134
- export { type AppearanceSettings as A, type BubbleFill as B, ChatClient as C, DEFAULT_APPEARANCE_SETTINGS as D, type LauncherContent as L, type MessengerConfig as M, type NamePlacement as N, type StampContent as S, type ChatTurn as a, type ChatIdentity as b, type ChatClientOptions as c, type BubbleShape as d, type ChatStorage as e, type ChatThread as f, type ComposerShape as g, type LauncherFill as h, type LauncherShape as i, type LauncherSize as j, type MessengerSkin as k, type StampPlacement as l, MESSENGER_CACHE_KEY as m, type MessengerConfigOptions as n, cachedMessengerConfig as o, fetchMessengerConfig as p, resolveAppearance as r };
134
+ export { type AppearanceSettings as A, type BubbleFill as B, type ChatThread as C, DEFAULT_APPEARANCE_SETTINGS as D, type LauncherContent as L, type MessengerConfig as M, type NamePlacement as N, type PageContext as P, type StampContent as S, type ChatTurn as a, type ChatIdentity as b, type ChatClientOptions as c, type BubbleShape as d, ChatClient as e, type ChatStorage as f, type ComposerShape as g, type LauncherFill as h, type LauncherShape as i, type LauncherSize as j, type MessengerSkin as k, type StampPlacement as l, MESSENGER_CACHE_KEY as m, type MessengerConfigOptions as n, cachedMessengerConfig as o, fetchMessengerConfig as p, resolveAppearance as r };
@@ -1,2 +1,2 @@
1
- export { m as MESSENGER_CACHE_KEY, M as MessengerConfig, n as MessengerConfigOptions, o as cachedMessengerConfig, p as fetchMessengerConfig } from './config-Cz1JyPLj.cjs';
1
+ export { m as MESSENGER_CACHE_KEY, M as MessengerConfig, n as MessengerConfigOptions, o as cachedMessengerConfig, p as fetchMessengerConfig } from './config-D8-uiWM8.cjs';
2
2
  import './http-BCh716Vs.cjs';
@@ -1,2 +1,2 @@
1
- export { m as MESSENGER_CACHE_KEY, M as MessengerConfig, n as MessengerConfigOptions, o as cachedMessengerConfig, p as fetchMessengerConfig } from './config-B1Sp94B-.js';
1
+ export { m as MESSENGER_CACHE_KEY, M as MessengerConfig, n as MessengerConfigOptions, o as cachedMessengerConfig, p as fetchMessengerConfig } from './config-DGUsxWOL.js';
2
2
  import './http-BCh716Vs.js';
@@ -1,4 +1,10 @@
1
- (function(){'use strict';var ne=Object.defineProperty;var re=(n,e,t)=>e in n?ne(n,e,{enumerable:true,configurable:true,writable:true,value:t}):n[e]=t;var h=(n,e,t)=>re(n,typeof e!="symbol"?e+"":e,t);function L(n){if(n)return n;let e=globalThis.fetch;if(typeof e=="function")return e.bind(globalThis)}function N(n){return n.replace(/\/+$/,"")}var ae="X-Prodantix-Conversation-Token",M="prodantix.chat.handle";function ie(){let n=globalThis.localStorage;if(n)return {get:e=>n.getItem(e),remove:e=>n.removeItem(e),set:(e,t)=>n.setItem(e,t)}}var _=class{constructor(e){this.options=e;h(this,"fetchImpl");h(this,"host");h(this,"storage");h(this,"handle");h(this,"identity",null);var t;this.fetchImpl=L(e.fetchImpl),this.host=N(e.host),this.storage=(t=e.storage)!=null?t:ie(),this.handle=this.readHandle();}get hasThread(){return this.handle!==null}avatarUrl(e){return e.startsWith("/")?`${this.host}${e}?api_key=${encodeURIComponent(this.options.apiKey)}`:e}get socketAuth(){return this.handle?{conversationId:this.handle.conversationId,conversationToken:this.handle.token,projectKey:this.options.apiKey}:null}identify(e){this.identity=e;}async ensureThread(e){var r,a,i;if(this.handle)return true;let t=await this.request("POST","/v1/conversations",{body:{distinctId:this.options.distinctId,subject:e,userHash:(r=this.identity)==null?void 0:r.userHash,userId:(a=this.identity)==null?void 0:a.userId}});return !(t!=null&&t.conversationId)||!t.token?false:(this.handle={conversationId:t.conversationId,token:t.token},(i=this.storage)==null||i.set(M,JSON.stringify(this.handle)),true)}async send(e,t){var i;if(!await this.ensureThread())return null;let r=this.handle;if(!r)return null;let a=await this.request("POST",`/v1/conversations/${encodeURIComponent(r.conversationId)}/turns`,{body:{body:e,pageContext:t},token:r.token});return (i=a==null?void 0:a.turn)!=null?i:null}async load(){let e=this.handle;return e?this.request("GET",`/v1/conversations/${encodeURIComponent(e.conversationId)}`,{token:e.token}):null}readHandle(){var t,r;let e=(t=this.storage)==null?void 0:t.get(M);if(!e)return null;try{let a=JSON.parse(e);if(typeof a.conversationId=="string"&&typeof a.token=="string")return {conversationId:a.conversationId,token:a.token}}catch(a){}return (r=this.storage)==null||r.remove(M),null}async request(e,t,r={}){var o,s,p,l,d,c;let a=this.fetchImpl;if(!a)return (s=(o=this.options).onError)==null||s.call(o,new Error("no fetch available for prodantix chat")),null;let i={authorization:`Bearer ${this.options.apiKey}`,"content-type":"application/json"};r.token&&(i[ae]=r.token);try{let u=await a(`${this.host}${t}`,{body:r.body===void 0?void 0:JSON.stringify(r.body),headers:i,method:e}),g=await u.text();return u.ok?g?JSON.parse(g):{}:((l=(p=this.options).onError)==null||l.call(p,new Error(`prodantix chat ${t}: ${u.status}`)),null)}catch(u){return (c=(d=this.options).onError)==null||c.call(d,u),null}}};var oe={Fri:"fri",Mon:"mon",Sat:"sat",Sun:"sun",Thu:"thu",Tue:"tue",Wed:"wed"};function P(n,e){var s,p,l,d,c,u;let t=new Intl.DateTimeFormat(void 0,{hour:"2-digit",hour12:false,minute:"2-digit",timeZone:n.timezone,weekday:"short"}).formatToParts(e),r=oe[(p=(s=t.find(g=>g.type==="weekday"))==null?void 0:s.value)!=null?p:""];if(!r)return false;let a=(d=(l=t.find(g=>g.type==="hour"))==null?void 0:l.value)!=null?d:"",i=(u=(c=t.find(g=>g.type==="minute"))==null?void 0:c.value)!=null?u:"",o=`${a}:${i}`;return n.windows.some(g=>g.days.includes(r)&&g.open<=o&&o<g.close)}var y={bubbleFill:"filled",bubbleShape:"tailed",composerShape:"round",dayDividers:true,launcherContent:"glyph",launcherFill:"outlined",launcherShape:"circle",launcherSize:"small",nameAvatar:true,namePlacement:"hidden",skin:"standard",stampContent:"time",stampPlacement:"none"},se=["quiet","standard"],le=["round","square"],ce=["rounded","tailed"],de=["filled","outlined"],pe=["circle","pill","squircle"],ue=["filled","outlined"],he=["avatar","glyph","team_faces"],ge=["large","medium","small"],me=["above","hidden","inline"],fe=["beside_name","none","under_turn"],be=["time","time_and_latency"],S=(n,e,t)=>typeof n=="string"&&e.includes(n)?n:t,D=(n,e)=>typeof n=="boolean"?n:e,ye={avatar_circle:["circle","outlined","avatar","large"],circle_filled:["circle","filled","glyph","medium"],circle_outlined:["circle","outlined","glyph","small"],pill_labelled:["pill","filled","glyph","medium"],pill_team:["pill","outlined","team_faces","medium"],squircle_filled:["squircle","filled","glyph","medium"]},xe={above:["above",false],avatar_only:["hidden",true],gutter:["above",true],hidden:["hidden",false],inline:["inline",false]},ve={cluster:[true,"none","time"],latency:[false,"beside_name","time_and_latency"],none:[false,"none","time"],trailing:[false,"under_turn","time"],with_name:[false,"beside_name","time"]},Se={concierge:["standard","round"],console:["standard","square"],quiet:["quiet","square"]},Ce={hairline:["rounded","outlined"],outlined:["rounded","outlined"],rounded:["rounded","filled"],tailed:["tailed","filled"]};function H(n){var g,x,v,b,m,C,k,w,f,E,U,B,K;let e=typeof n=="object"&&n!==null?n:{},t=typeof e.launcherStyle=="string"?e.launcherStyle:void 0,r=t===void 0?void 0:ye[t],a=typeof e.namePlacement=="string"?e.namePlacement:void 0,i=a===void 0?void 0:xe[a],o=typeof e.timestampStyle=="string"?e.timestampStyle:void 0,s=o===void 0?void 0:ve[o],p=typeof e.skin=="string"?e.skin:void 0,l=p===void 0?void 0:Se[p],d=typeof e.bubbleStyle=="string"?e.bubbleStyle:void 0,c=d===void 0?void 0:Ce[d],u={bubbleFill:S(e.bubbleFill,de,(g=c==null?void 0:c[1])!=null?g:y.bubbleFill),bubbleShape:S(e.bubbleShape,ce,(x=c==null?void 0:c[0])!=null?x:y.bubbleShape),composerShape:S(e.composerShape,le,(v=l==null?void 0:l[1])!=null?v:y.composerShape),dayDividers:D(e.dayDividers,(b=s==null?void 0:s[0])!=null?b:y.dayDividers),launcherContent:S(e.launcherContent,he,(m=r==null?void 0:r[2])!=null?m:y.launcherContent),launcherFill:S(e.launcherFill,ue,(C=r==null?void 0:r[1])!=null?C:y.launcherFill),launcherShape:S(e.launcherShape,pe,(k=r==null?void 0:r[0])!=null?k:y.launcherShape),launcherSize:S(e.launcherSize,ge,(w=r==null?void 0:r[3])!=null?w:y.launcherSize),nameAvatar:D(e.nameAvatar,(f=i==null?void 0:i[1])!=null?f:y.nameAvatar),namePlacement:S(e.namePlacement,me,(E=i==null?void 0:i[0])!=null?E:y.namePlacement),skin:S(e.skin,se,(U=l==null?void 0:l[0])!=null?U:y.skin),stampContent:S(e.stampContent,be,(B=s==null?void 0:s[2])!=null?B:y.stampContent),stampPlacement:S(e.stampPlacement,fe,(K=s==null?void 0:s[1])!=null?K:y.stampPlacement)};return u.stampPlacement==="beside_name"&&u.namePlacement==="hidden"&&(u.stampPlacement="under_turn"),u}function G(n){var r,a,i,o;let e=n.split(/\s+/).filter(s=>s.length>0);return (e.length>1?`${(r=e[0])==null?void 0:r.slice(0,1)}${(a=e[1])==null?void 0:a.slice(0,1)}`:(o=(i=e[0])==null?void 0:i.slice(0,2))!=null?o:"").toUpperCase()}var ke="M20 11.6a7.4 7.4 0 0 1-7.4 7.4H8.2L4 21.8l1-4.1A7.4 7.4 0 1 1 20 11.6Z",Ee={large:66,medium:56,small:46},we={circle:"width:var(--fab-size);height:var(--fab-size);border-radius:calc(var(--fab-size) / 2);",pill:"width:auto;height:var(--fab-size);border-radius:calc(var(--fab-size) / 2);padding:0 22px;gap:10px;",squircle:"width:var(--fab-size);height:var(--fab-size);border-radius:16px;"},Te={filled:"background:var(--a);color:#fff;",outlined:"background:var(--paper);border:1px solid var(--hairline);color:var(--ink-2);box-shadow:0 1px 2px rgba(0,0,0,.08);"},Ae={avatar:"",glyph:".launcher svg{width:calc(var(--fab-size) * 0.375);height:calc(var(--fab-size) * 0.375);}",team_faces:".launcher .faces{display:flex;}.launcher .faces .av{box-shadow:0 0 0 2px var(--paper);}.launcher .faces .av+.av{margin-left:-10px;}"},Le=".launcher .live{width:10px;height:10px;position:absolute;right:3px;bottom:3px;border-radius:50%;background:var(--online);box-shadow:0 0 0 2px var(--paper);}.launcher.closed .live{display:none}",Ne={circle:"",pill:".badge{position:static;box-shadow:none}",squircle:""},_e={filled:"",outlined:".badge{background:var(--a);top:-7px;right:-7px;min-width:19px;height:19px;font-size:11.5px}"},Pe={circle:"",pill:".launcher .label{font-size:14px;font-weight:600;white-space:nowrap;}",squircle:""},Ie={circle:"",pill:"@media (max-width:480px){.launcher{width:var(--fab-size);padding:0}.launcher .label{display:none}}",squircle:""};function q(n,e,t,r){return `.launcher{--fab-size:${Ee[r]}px;${we[n]}${Te[e]}}${Ae[t]}${Le}${Ne[n]}${_e[e]}${Pe[n]}${Ie[n]}`}function W(n,e,t,r=a=>a){let a=document.createDocumentFragment();if(n==="glyph"||t.length===0){let i=document.createElement("span");return i.innerHTML=`<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="${ke}"/></svg>`,a.append(...i.childNodes,R()),a}return n==="avatar"?(a.append(Y(t[0],e,r),R()),a):(a.append(O(t,e,r),R()),a)}function O(n,e,t=r=>r){let r=document.createElement("span");r.className="faces";for(let a of n.slice(0,2))r.append(Y(a,e,t));return r}function Y(n,e,t){let r=document.createElement("span");if(r.className="av",r.setAttribute("aria-hidden","true"),n&&(r.style.background=n.tone),n!=null&&n.avatarUrl){let a=document.createElement("img");return a.alt="",a.src=t(n.avatarUrl),r.append(a),r}return r.textContent=n?n.initials:e.agentLabel.slice(0,2).toUpperCase(),r}function R(){let n=document.createElement("span");return n.className="live",n.setAttribute("aria-hidden","true"),n}var Fe={agentLabel:"Agent",aiLabel:"AI",awayBody:"We are away right now, but we will reply as soon as we are back.",closeLabel:"Close chat",emptyBody:"We usually reply within a few minutes.",emptyTitle:"Ask us anything.",inputPlaceholder:"Type a message",launcherLabel:"Chat with us",replyTime:"Usually replying in a few minutes",sendLabel:"Send",timeLabel:n=>{let e=new Date(n);return Number.isNaN(e.getTime())?"":`${String(e.getHours()).padStart(2,"0")}:${String(e.getMinutes()).padStart(2,"0")}`},title:"Support",unreadLabel:n=>`${n} unread`},T={accentColor:"#5b5bff",availability:{timezone:"UTC",windows:[]},awayMessage:"",greeting:"",launcherOffsetX:20,launcherOffsetY:20,launcherPosition:"bottom_right",starterPrompts:[],team:[],...y},Me={quiet:".composer{position:relative;padding:10px 12px 12px}.composer input{padding-right:42px}.composer button{position:absolute;top:50%;right:16px;width:34px;min-width:34px;height:34px;padding:0;background:transparent;color:var(--ink);border-radius:7px;transform:translateY(-50%)}.composer button .sendglyph{display:block;width:18px;height:18px}.composer button .sendtext{display:none}.panel{border-radius:8px;box-shadow:0 2px 8px rgba(0,0,0,.12)}.header{background:var(--paper);color:var(--ink);height:44px;padding:0 8px 0 16px;border-bottom:1px solid var(--hairline)}.header h2{font-size:11px;letter-spacing:.11em;text-transform:uppercase;color:var(--ink-3)}.header .status{color:var(--ink-3)}.header .av,.header .status .live{box-shadow:0 0 0 2px var(--paper)}.close{color:var(--ink-2)}",standard:".panel{border-radius:16px;box-shadow:0 16px 40px rgba(0,0,0,.2)}.header{background:var(--a);color:#fff;flex-direction:column;align-items:flex-start;gap:14px;padding:18px 14px 20px 20px}.header h2{font-size:19px;font-weight:640}"},He={round:".composer{padding:12px 12px 14px;gap:8px}.composer input{height:46px;border-radius:23px;padding:0 16px}.composer button{width:46px;min-width:46px;height:46px;padding:0;border-radius:23px}.composer button .sendglyph{display:block}.composer button .sendtext{display:none}",square:".composer input{height:44px;border-radius:8px;padding:0 12px}"},Re={rounded:".turn{border-radius:18px;padding:10px 15px}",tailed:".turn.agent,.turn.ai{border-radius:12px 12px 12px 4px}.turn.end_user{border-radius:12px 12px 4px 12px}"},Oe={filled:"",outlined:".turn{background:none;border:1px solid var(--hairline)}.turn.end_user{background:none;border-color:var(--a);color:var(--ink)}"},$e={above:"",hidden:".turn.agent .author,.turn.ai .author:not(.ai){display:none}",inline:".body .author.below{display:block;margin:4px 0 0;font-size:11.5px;font-weight:500;color:var(--ink-2);text-transform:none;letter-spacing:0;opacity:1}"},ze=".turn.agent,.turn.ai{display:flex;gap:10px;max-width:100%;background:none;padding:0}.turn .body{background:var(--fill);padding:9px 13px;border-radius:inherit}.author{text-transform:none;letter-spacing:0;font-size:12.5px;font-weight:600;opacity:1}",Ue='.divider{display:flex;align-items:center;gap:10px;margin:0;font-size:11px;opacity:.6}.divider:before,.divider:after{content:"";flex:1;height:1px;background:var(--hairline)}',Be={beside_name:".stamp{font-size:11px;opacity:.7;margin-left:6px}",none:"",under_turn:".stamp{display:block;font-size:11px;opacity:.7;margin-top:4px}.turn.end_user .stamp{text-align:right}"},Ke=".lat{font-size:11px;opacity:.7;margin-left:6px}";function De(n){let e=H(n),t=n.launcherPosition==="bottom_left"?"left":"right",r=n.accentColor;return `${`
1
+ (function(){'use strict';var ae=Object.defineProperty;var ie=(n,e,t)=>e in n?ae(n,e,{enumerable:true,configurable:true,writable:true,value:t}):n[e]=t;var u=(n,e,t)=>ie(n,typeof e!="symbol"?e+"":e,t);function L(n){if(n)return n;let e=globalThis.fetch;if(typeof e=="function")return e.bind(globalThis)}function N(n){return n.replace(/\/+$/,"")}var oe="X-Prodantix-Conversation-Token",H="prodantix.chat.handle";function se(){let n=globalThis.localStorage;if(n)return {get:e=>n.getItem(e),remove:e=>n.removeItem(e),set:(e,t)=>n.setItem(e,t)}}var P=class{constructor(e){this.options=e;u(this,"fetchImpl");u(this,"host");u(this,"storage");u(this,"handle");u(this,"identity",null);var t;this.fetchImpl=L(e.fetchImpl),this.host=N(e.host),this.storage=(t=e.storage)!=null?t:se(),this.handle=this.readHandle();}get hasThread(){return this.handle!==null}avatarUrl(e){return e.startsWith("/")?`${this.host}${e}?api_key=${encodeURIComponent(this.options.apiKey)}`:e}get socketAuth(){return this.handle?{conversationId:this.handle.conversationId,conversationToken:this.handle.token,projectKey:this.options.apiKey}:null}identify(e){this.identity=e;}async ensureThread(e){var r,a,i;if(this.handle)return true;let t=await this.request("POST","/v1/conversations",{body:{distinctId:this.options.distinctId,subject:e,userHash:(r=this.identity)==null?void 0:r.userHash,userId:(a=this.identity)==null?void 0:a.userId}});return !(t!=null&&t.conversationId)||!t.token?false:(this.handle={conversationId:t.conversationId,token:t.token},(i=this.storage)==null||i.set(H,JSON.stringify(this.handle)),true)}async send(e,t){var i;if(!await this.ensureThread())return null;let r=this.handle;if(!r)return null;let a=await this.request("POST",`/v1/conversations/${encodeURIComponent(r.conversationId)}/turns`,{body:{body:e,pageContext:t},token:r.token});return (i=a==null?void 0:a.turn)!=null?i:null}async load(){let e=this.handle;return e?this.request("GET",`/v1/conversations/${encodeURIComponent(e.conversationId)}`,{token:e.token}):null}readHandle(){var t,r;let e=(t=this.storage)==null?void 0:t.get(H);if(!e)return null;try{let a=JSON.parse(e);if(typeof a.conversationId=="string"&&typeof a.token=="string")return {conversationId:a.conversationId,token:a.token}}catch(a){}return (r=this.storage)==null||r.remove(H),null}async request(e,t,r={}){var o,s,p,l,d,c;let a=this.fetchImpl;if(!a)return (s=(o=this.options).onError)==null||s.call(o,new Error("no fetch available for prodantix chat")),null;let i={authorization:`Bearer ${this.options.apiKey}`,"content-type":"application/json"};r.token&&(i[oe]=r.token);try{let h=await a(`${this.host}${t}`,{body:r.body===void 0?void 0:JSON.stringify(r.body),headers:i,method:e}),g=await h.text();return h.ok?g?JSON.parse(g):{}:((l=(p=this.options).onError)==null||l.call(p,new Error(`prodantix chat ${t}: ${h.status}`)),null)}catch(h){return (c=(d=this.options).onError)==null||c.call(d,h),null}}};var le={Fri:"fri",Mon:"mon",Sat:"sat",Sun:"sun",Thu:"thu",Tue:"tue",Wed:"wed"};function _(n,e){var s,p,l,d,c,h;let t=new Intl.DateTimeFormat(void 0,{hour:"2-digit",hour12:false,minute:"2-digit",timeZone:n.timezone,weekday:"short"}).formatToParts(e),r=le[(p=(s=t.find(g=>g.type==="weekday"))==null?void 0:s.value)!=null?p:""];if(!r)return false;let a=(d=(l=t.find(g=>g.type==="hour"))==null?void 0:l.value)!=null?d:"",i=(h=(c=t.find(g=>g.type==="minute"))==null?void 0:c.value)!=null?h:"",o=`${a}:${i}`;return n.windows.some(g=>g.days.includes(r)&&g.open<=o&&o<g.close)}var y={bubbleFill:"filled",bubbleShape:"tailed",composerShape:"round",dayDividers:true,launcherContent:"glyph",launcherFill:"outlined",launcherShape:"circle",launcherSize:"small",nameAvatar:true,namePlacement:"hidden",skin:"standard",stampContent:"time",stampPlacement:"none"},ce=["quiet","standard"],de=["round","square"],pe=["rounded","tailed"],he=["filled","outlined"],ue=["circle","pill","squircle"],ge=["filled","outlined"],me=["avatar","glyph","team_faces"],fe=["large","medium","small"],be=["above","hidden","inline"],ye=["beside_name","none","under_turn"],xe=["time","time_and_latency"],S=(n,e,t)=>typeof n=="string"&&e.includes(n)?n:t,D=(n,e)=>typeof n=="boolean"?n:e,ve={avatar_circle:["circle","outlined","avatar","large"],circle_filled:["circle","filled","glyph","medium"],circle_outlined:["circle","outlined","glyph","small"],pill_labelled:["pill","filled","glyph","medium"],pill_team:["pill","outlined","team_faces","medium"],squircle_filled:["squircle","filled","glyph","medium"]},Se={above:["above",false],avatar_only:["hidden",true],gutter:["above",true],hidden:["hidden",false],inline:["inline",false]},Ce={cluster:[true,"none","time"],latency:[false,"beside_name","time_and_latency"],none:[false,"none","time"],trailing:[false,"under_turn","time"],with_name:[false,"beside_name","time"]},ke={concierge:["standard","round"],console:["standard","square"],quiet:["quiet","square"]},Ee={hairline:["rounded","outlined"],outlined:["rounded","outlined"],rounded:["rounded","filled"],tailed:["tailed","filled"]};function I(n){var g,x,v,b,m,C,k,w,f,E,U,K,B;let e=typeof n=="object"&&n!==null?n:{},t=typeof e.launcherStyle=="string"?e.launcherStyle:void 0,r=t===void 0?void 0:ve[t],a=typeof e.namePlacement=="string"?e.namePlacement:void 0,i=a===void 0?void 0:Se[a],o=typeof e.timestampStyle=="string"?e.timestampStyle:void 0,s=o===void 0?void 0:Ce[o],p=typeof e.skin=="string"?e.skin:void 0,l=p===void 0?void 0:ke[p],d=typeof e.bubbleStyle=="string"?e.bubbleStyle:void 0,c=d===void 0?void 0:Ee[d],h={bubbleFill:S(e.bubbleFill,he,(g=c==null?void 0:c[1])!=null?g:y.bubbleFill),bubbleShape:S(e.bubbleShape,pe,(x=c==null?void 0:c[0])!=null?x:y.bubbleShape),composerShape:S(e.composerShape,de,(v=l==null?void 0:l[1])!=null?v:y.composerShape),dayDividers:D(e.dayDividers,(b=s==null?void 0:s[0])!=null?b:y.dayDividers),launcherContent:S(e.launcherContent,me,(m=r==null?void 0:r[2])!=null?m:y.launcherContent),launcherFill:S(e.launcherFill,ge,(C=r==null?void 0:r[1])!=null?C:y.launcherFill),launcherShape:S(e.launcherShape,ue,(k=r==null?void 0:r[0])!=null?k:y.launcherShape),launcherSize:S(e.launcherSize,fe,(w=r==null?void 0:r[3])!=null?w:y.launcherSize),nameAvatar:D(e.nameAvatar,(f=i==null?void 0:i[1])!=null?f:y.nameAvatar),namePlacement:S(e.namePlacement,be,(E=i==null?void 0:i[0])!=null?E:y.namePlacement),skin:S(e.skin,ce,(U=l==null?void 0:l[0])!=null?U:y.skin),stampContent:S(e.stampContent,xe,(K=s==null?void 0:s[2])!=null?K:y.stampContent),stampPlacement:S(e.stampPlacement,ye,(B=s==null?void 0:s[1])!=null?B:y.stampPlacement)};return h.stampPlacement==="beside_name"&&h.namePlacement==="hidden"&&(h.stampPlacement="under_turn"),h}function G(n){var r,a,i,o;let e=n.split(/\s+/).filter(s=>s.length>0);return (e.length>1?`${(r=e[0])==null?void 0:r.slice(0,1)}${(a=e[1])==null?void 0:a.slice(0,1)}`:(o=(i=e[0])==null?void 0:i.slice(0,2))!=null?o:"").toUpperCase()}var we="M20 11.6a7.4 7.4 0 0 1-7.4 7.4H8.2L4 21.8l1-4.1A7.4 7.4 0 1 1 20 11.6Z",Te={large:66,medium:56,small:46},Ae={circle:"width:var(--fab-size);height:var(--fab-size);border-radius:calc(var(--fab-size) / 2);",pill:"width:auto;height:var(--fab-size);border-radius:calc(var(--fab-size) / 2);padding:0 22px;gap:10px;",squircle:"width:var(--fab-size);height:var(--fab-size);border-radius:16px;"},Le={filled:"background:var(--a);color:#fff;",outlined:"background:var(--paper);border:1px solid var(--hairline);color:var(--ink-2);box-shadow:0 1px 2px rgba(0,0,0,.08);"},Ne={avatar:"",glyph:".launcher svg{width:calc(var(--fab-size) * 0.375);height:calc(var(--fab-size) * 0.375);}",team_faces:".launcher .faces{display:flex;}.launcher .faces .av{box-shadow:0 0 0 2px var(--paper);}.launcher .faces .av+.av{margin-left:-10px;}"},Pe=".launcher .live{width:10px;height:10px;position:absolute;right:3px;bottom:3px;border-radius:50%;background:var(--online);box-shadow:0 0 0 2px var(--paper);}.launcher.closed .live{display:none}",_e={circle:"",pill:".badge{position:static;box-shadow:none}",squircle:""},Ie={filled:"",outlined:".badge{background:var(--a);top:-7px;right:-7px;min-width:19px;height:19px;font-size:11.5px}"},Me={circle:"",pill:".launcher .label{font-size:14px;font-weight:600;white-space:nowrap;}",squircle:""},Fe={circle:"",pill:"@media (max-width:480px){.launcher{width:var(--fab-size);padding:0}.launcher .label{display:none}}",squircle:""};function q(n,e,t,r){return `.launcher{--fab-size:${Te[r]}px;${Ae[n]}${Le[e]}}${Ne[t]}${Pe}${_e[n]}${Ie[e]}${Me[n]}${Fe[n]}`}function W(n,e,t,r=a=>a){let a=document.createDocumentFragment();if(n==="glyph"||t.length===0){let i=document.createElement("span");return i.innerHTML=`<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="${we}"/></svg>`,a.append(...i.childNodes,O()),a}return n==="avatar"?(a.append(j(t[0],e,r),O()),a):(a.append(R(t,e,r),O()),a)}function R(n,e,t=r=>r){let r=document.createElement("span");r.className="faces";for(let a of n.slice(0,2))r.append(j(a,e,t));return r}function j(n,e,t){let r=document.createElement("span");if(r.className="av",r.setAttribute("aria-hidden","true"),n&&(r.style.background=n.tone),n!=null&&n.avatarUrl){let a=document.createElement("img");return a.alt="",a.src=t(n.avatarUrl),r.append(a),r}return r.textContent=n?n.initials:e.agentLabel.slice(0,2).toUpperCase(),r}function O(){let n=document.createElement("span");return n.className="live",n.setAttribute("aria-hidden","true"),n}var He={agentLabel:"Agent",aiLabel:"AI",awayBody:"We are away right now, but we will reply as soon as we are back.",closeLabel:"Close chat",emptyBody:"We usually reply within a few minutes.",emptyTitle:"Ask us anything.",inputPlaceholder:"Type a message",launcherLabel:"Chat with us",replyTime:"Usually replying in a few minutes",sendLabel:"Send",timeLabel:n=>{let e=new Date(n);return Number.isNaN(e.getTime())?"":`${String(e.getHours()).padStart(2,"0")}:${String(e.getMinutes()).padStart(2,"0")}`},title:"Support",unreadLabel:n=>`${n} unread`},T={accentColor:"#5b5bff",availability:{timezone:"UTC",windows:[]},awayMessage:"",greeting:"",launcherOffsetX:20,launcherOffsetY:20,launcherPosition:"bottom_right",starterPrompts:[],team:[],...y},Oe={quiet:".composer{position:relative;padding:10px 12px 12px}.composer input{padding-right:42px}.composer button{position:absolute;top:50%;right:16px;width:34px;min-width:34px;height:34px;padding:0;background:transparent;color:var(--ink);border-radius:7px;transform:translateY(-50%)}.composer button .sendglyph{display:block;width:18px;height:18px}.composer button .sendtext{display:none}.panel{border-radius:8px;box-shadow:0 2px 8px rgba(0,0,0,.12)}.header{background:var(--paper);color:var(--ink);height:44px;padding:0 8px 0 16px;border-bottom:1px solid var(--hairline)}.header h2{font-size:11px;letter-spacing:.11em;text-transform:uppercase;color:var(--ink-3)}.header .status{color:var(--ink-3)}.header .av,.header .status .live{box-shadow:0 0 0 2px var(--paper)}.close{color:var(--ink-2)}",standard:".panel{border-radius:16px;box-shadow:0 16px 40px rgba(0,0,0,.2)}.header{background:var(--a);color:#fff;flex-direction:column;align-items:flex-start;gap:14px;padding:18px 14px 20px 20px}.header h2{font-size:19px;font-weight:640}"},Re={round:".composer{padding:12px 12px 14px;gap:8px}.composer input{height:46px;border-radius:23px;padding:0 16px}.composer button{width:46px;min-width:46px;height:46px;padding:0;border-radius:23px}.composer button .sendglyph{display:block}.composer button .sendtext{display:none}",square:".composer input{height:44px;border-radius:8px;padding:0 12px}"},$e={rounded:".turn{border-radius:18px;padding:10px 15px}",tailed:".turn.agent,.turn.ai{border-radius:12px 12px 12px 4px}.turn.end_user{border-radius:12px 12px 4px 12px}"},ze={filled:"",outlined:".turn{background:none;border:1px solid var(--hairline)}.turn.end_user{background:none;border-color:var(--a);color:var(--ink)}"},Ue={above:"",hidden:".turn.agent .author,.turn.ai .author:not(.ai){display:none}",inline:".body .author.below{display:block;margin:4px 0 0;font-size:11.5px;font-weight:500;color:var(--ink-2);text-transform:none;letter-spacing:0;opacity:1}"},Ke=".turn.agent,.turn.ai{display:flex;gap:10px;max-width:100%;background:none;padding:0}.turn.agent .body,.turn.ai .body{background:var(--fill);padding:9px 13px;border-radius:inherit}.author{text-transform:none;letter-spacing:0;font-size:12.5px;font-weight:600;opacity:1}",Be='.divider{display:flex;align-items:center;gap:10px;margin:0;font-size:11px;opacity:.6}.divider:before,.divider:after{content:"";flex:1;height:1px;background:var(--hairline)}',De={beside_name:".stamp{font-size:11px;opacity:.7;margin-left:6px}",none:"",under_turn:".stamp{display:block;font-size:11px;opacity:.7;margin-top:4px}.turn.end_user .stamp{text-align:right}"},Ge=".lat{font-size:11px;opacity:.7;margin-left:6px}",Y=`--paper: oklch(24.6% 0.015 257); --ink: #fff; --ink-3: rgba(255,255,255,.55);
2
+ --fill: rgba(255,255,255,.06); --hairline: rgba(255,255,255,.13); --ink-2: rgba(255,255,255,.70);
3
+ --online: oklch(72% 0.13 163.23);`;function qe(n){return n==="light"?"":n==="dark"?`:host { ${Y} }`:`@media (prefers-color-scheme: dark) {
4
+ :host {
5
+ ${Y}
6
+ }
7
+ }`}function J(n,e="system"){let t=I(n),r=n.launcherPosition==="bottom_left"?"left":"right",a=n.accentColor;return `${`
2
8
  :host {
3
9
  /* The widget sits above the host page's own furniture. The reset above sends
4
10
  z-index back to auto, so without this the launcher and panel stack at the
@@ -6,25 +12,19 @@
6
12
  draws over them: the WebMCP chip covered the launcher on clepit's landing.
7
13
  Below the 32-bit ceiling so a host can still put something over us
8
14
  deliberately. */
9
- all: initial; z-index: 2147483000; --a: ${r};
15
+ all: initial; z-index: 2147483000; --a: ${a};
10
16
  --paper: #fff; --ink: #0f172a; --ink-3: var(--ink-3);
11
17
  --fill: #f1f5f9; --hairline: #e2e8f0; --ink-2: rgba(0,0,0,.72);
12
18
  --online: oklch(53.8% 0.1274 163.23);
13
- color-scheme: light dark;
14
- }
15
- @media (prefers-color-scheme: dark) {
16
- :host {
17
- --paper: oklch(24.6% 0.015 257); --ink: #fff; --ink-3: rgba(255,255,255,.55);
18
- --fill: rgba(255,255,255,.06); --hairline: rgba(255,255,255,.13); --ink-2: rgba(255,255,255,.70);
19
- --online: oklch(72% 0.13 163.23);
20
- }
19
+ color-scheme: ${e==="system"?"light dark":e};
21
20
  }
21
+ ${qe(e)}
22
22
  * { box-sizing: border-box; font-family: system-ui, sans-serif; }
23
23
  .launcher {
24
- z-index: 2147483000; position: fixed; ${t}: ${n.launcherOffsetX}px; bottom: ${n.launcherOffsetY}px; width: 56px; height: 56px;
24
+ z-index: 2147483000; position: fixed; ${r}: ${n.launcherOffsetX}px; bottom: ${n.launcherOffsetY}px; width: 56px; height: 56px;
25
25
  border-radius: 28px; border: none; cursor: pointer;
26
26
  display: inline-flex; align-items: center; justify-content: center;
27
- background: ${r}; color: #fff; font-size: 24px;
27
+ background: ${a}; color: #fff; font-size: 24px;
28
28
  box-shadow: 0 4px 12px rgba(0,0,0,.2);
29
29
  }
30
30
  .launcher:focus-visible { outline: 3px solid #0b0e14; outline-offset: 2px; }
@@ -34,8 +34,8 @@
34
34
  control a visitor is meant to click the only element in the product that
35
35
  shifted when pointed at. */
36
36
  .launcher { transition: background-color 120ms ease; }
37
- .launcher:hover { background: color-mix(in srgb, #000 12%, ${r}); }
38
- .launcher:active { background: color-mix(in srgb, #000 20%, ${r}); }
37
+ .launcher:hover { background: color-mix(in srgb, #000 12%, ${a}); }
38
+ .launcher:active { background: color-mix(in srgb, #000 20%, ${a}); }
39
39
  @media (prefers-reduced-motion: reduce) {
40
40
  .launcher { transition: none; }
41
41
  }
@@ -52,7 +52,7 @@
52
52
  the one that needs it. */
53
53
  .badge[hidden] { display: none; }
54
54
  .panel {
55
- z-index: 2147483001; position: fixed; ${t}: ${n.launcherOffsetX}px; bottom: ${n.launcherOffsetY+68}px; width: 360px; max-width: calc(100vw - 40px);
55
+ z-index: 2147483001; position: fixed; ${r}: ${n.launcherOffsetX}px; bottom: ${n.launcherOffsetY+68}px; width: 360px; max-width: calc(100vw - 40px);
56
56
  height: 520px; max-height: calc(100vh - 120px); background: var(--paper); color: var(--ink);
57
57
  border-radius: 12px; box-shadow: 0 8px 32px rgba(0,0,0,.24);
58
58
  display: flex; flex-direction: column; overflow: hidden;
@@ -67,7 +67,17 @@
67
67
  .header .av + .av { margin-left: -12px; }
68
68
  .headmain { display: flex; flex-direction: column; }
69
69
  .header .status { display: flex; align-items: center; gap: 6px; margin: 5px 0 0; font-size: 12.5px; color: rgb(255 255 255 / 80%); }
70
- .header .status .live { flex: none; width: 10px; height: 10px; border-radius: 50%; background: var(--online); box-shadow: 0 0 0 2px var(--a); }
70
+ /* The dot's ring is the PAPER, not the accent. An accent ring on the standard
71
+ skin is the header's own background and draws nothing, which is how this
72
+ shipped looking ringless beside a preview that had one. The faces above keep
73
+ the accent ring, which is a different job: separating two overlapping discs
74
+ from each other and from the header. */
75
+ .header .status .live { flex: none; width: 10px; height: 10px; border-radius: 50%; background: var(--online); box-shadow: 0 0 0 2px var(--paper); }
76
+ /* Hours, the same fact the launcher's dot carries. A green dot and a sentence
77
+ promising a reply in minutes are both claims about somebody being there, so
78
+ outside the project's hours neither is drawn: the away message in the thread
79
+ is what speaks then. */
80
+ .panel.closed .status { display: none; }
71
81
  /* Pinned rather than laid out: the standard skin turns this header into a
72
82
  column so the title can carry a line under it, and a close button that is
73
83
  merely a flex sibling then stacks BELOW the title on the left, which is where
@@ -89,7 +99,7 @@
89
99
  .close:focus-visible { outline: 2px solid currentColor; outline-offset: 1px; }
90
100
  .log { flex: 1; overflow-y: auto; padding: 12px; display: flex; flex-direction: column; gap: 8px; }
91
101
  .turn { max-width: 80%; padding: 8px 12px; border-radius: 12px; font-size: 14px; }
92
- .turn.end_user { align-self: flex-end; background: ${r}; color: #fff; }
102
+ .turn.end_user { align-self: flex-end; background: ${a}; color: #fff; }
93
103
  .turn.agent, .turn.ai { align-self: flex-start; background: var(--fill); color: var(--ink); }
94
104
  .author { font-size: 11px; opacity: .7; margin-bottom: 2px; }
95
105
  .away { background: var(--fill); border: 1px solid var(--hairline); border-radius: 8px; padding: 8px 12px; font-size: 13.5px; color: var(--ink-2); }
@@ -101,19 +111,21 @@
101
111
  font-family: inherit; font-size: 13.5px; font-weight: 500; color: var(--ink);
102
112
  background: none; border: 1px solid var(--hairline); border-radius: 8px; cursor: pointer;
103
113
  }
104
- .prompt:focus-visible { outline: 2px solid ${r}; outline-offset: 2px; }
114
+ .prompt:focus-visible { outline: 2px solid ${a}; outline-offset: 2px; }
105
115
  .av { width: 30px; height: 30px; border-radius: 50%; flex: none; display: inline-flex; align-items: center; justify-content: center; font-size: 11.5px; font-weight: 650; color: #fff; background: #7c3f3f; }
106
116
  .av.bot { border-radius: 9px; background: var(--fill); color: var(--ink); }
107
117
  .av img { width: 100%; height: 100%; display: block; object-fit: cover; border-radius: inherit; }
108
118
  .composer { display: flex; gap: 8px; padding: 12px; border-top: 1px solid var(--hairline); }
109
119
  .composer input { flex: 1; min-width: 0; height: 44px; padding: 0 12px; border: 0; border-radius: 8px; font-size: 14px; background: var(--fill); color: var(--ink); }
110
- .composer input:focus-visible { outline: 2px solid ${r}; }
111
- .composer button { display: inline-flex; align-items: center; justify-content: center; gap: 0; min-width: 64px; height: 44px; padding: 0 16px; background: ${r}; color: #fff; border: none; border-radius: 8px; cursor: pointer; font-family: inherit; font-size: 14.5px; font-weight: 550; }
120
+ .composer input:focus-visible { outline: 2px solid ${a}; }
121
+ .composer button { display: inline-flex; align-items: center; justify-content: center; gap: 0; min-width: 64px; height: 44px; padding: 0 16px; background: ${a}; color: #fff; border: none; border-radius: 8px; cursor: pointer; font-family: inherit; font-size: 14.5px; font-weight: 550; }
122
+ .composer button:hover { background: color-mix(in srgb, #000 12%, ${a}); }
123
+ .composer button:focus-visible { outline: 2px solid var(--ink); outline-offset: 2px; }
112
124
  .composer button .sendglyph { display: none; width: 19px; height: 19px; }
113
125
  .composer button:focus-visible { outline: 2px solid #0b0e14; }
114
126
  @media (prefers-reduced-motion: no-preference) {
115
127
  .panel { animation: rise 180ms ease-out; }
116
128
  @keyframes rise { from { transform: translateY(8px); opacity: 0; } to { transform: none; opacity: 1; } }
117
129
  }
118
- `}${He[e.composerShape]}${Me[e.skin]}${q(e.launcherShape,e.launcherFill,e.launcherContent,e.launcherSize)}${Re[e.bubbleShape]}${Oe[e.bubbleFill]}${$e[e.namePlacement]}${e.nameAvatar?ze:""}${e.dayDividers?Ue:""}${Be[e.stampPlacement]}${e.stampContent==="time_and_latency"?Ke:""}`}var Ge=["end_user","agent","ai"];function qe(){let n=globalThis.location;if(n)return {host:n.host,path:n.pathname,title:document.title}}var I=class{constructor(e,t,r={},a={}){this.host=e;this.client=t;h(this,"root");h(this,"strings");h(this,"settings");h(this,"appearance");h(this,"launcher");h(this,"badge");h(this,"panel",null);h(this,"lastFocused",null);h(this,"unread",0);this.strings={...Fe,...r},this.appearance={...T,...a},this.settings=H({...T,...a}),this.root=e.attachShadow({mode:"closed"});let i=document.createElement("style");if(i.textContent=De({...T,...a}),this.root.append(i),this.launcher=document.createElement("button"),this.launcher.className="launcher",this.launcher.type="button",this.launcher.setAttribute("aria-haspopup","dialog"),this.launcher.setAttribute("aria-label",this.strings.launcherLabel),this.launcher.append(W(this.settings.launcherContent,this.strings,this.appearance.team,o=>this.client.avatarUrl(o))),this.settings.launcherShape==="pill"){let o=document.createElement("span");o.className="label",o.textContent=this.settings.launcherContent==="team_faces"?this.strings.agentLabel:this.strings.launcherLabel,this.launcher.append(o);}this.launcher.addEventListener("click",()=>this.toggle()),this.badge=document.createElement("span"),this.badge.className="badge",this.badge.hidden=true,this.launcher.append(this.badge),this.root.append(this.launcher);}toggle(){this.panel?this.close():this.open();}setOpenNow(e){this.launcher.classList.toggle("closed",!e);}async open(){var v;if(this.panel)return;this.lastFocused=this.host.ownerDocument.activeElement,this.unread=0,this.renderBadge();let e=document.createElement("section");e.className="panel",e.setAttribute("role","dialog"),e.setAttribute("aria-modal","true"),e.setAttribute("aria-label",this.strings.title);let t=document.createElement("div");t.className="header";let r=(v=this.appearance.team)!=null?v:[];r.length>0&&t.append(O(r,this.strings,b=>this.client.avatarUrl(b)));let a=document.createElement("div");a.className="headmain";let i=document.createElement("h2");i.textContent=this.strings.title;let o=document.createElement("p");o.className="status";let s=document.createElement("span");s.className="live",s.setAttribute("aria-hidden","true"),o.append(s,this.strings.replyTime),a.append(i,o);let p=document.createElement("button");p.className="close",p.type="button",p.setAttribute("aria-label",this.strings.closeLabel),p.textContent="\xD7",p.addEventListener("click",()=>this.close()),t.append(a,p);let l=document.createElement("div");l.className="log",l.setAttribute("role","log"),l.setAttribute("aria-live","polite"),l.setAttribute("aria-label",this.strings.title);let d=document.createElement("form");d.className="composer";let c=document.createElement("input");c.type="text",c.setAttribute("aria-label",this.strings.inputPlaceholder),c.placeholder=this.strings.inputPlaceholder;let u=document.createElement("button");u.type="submit",u.setAttribute("aria-label",this.strings.sendLabel),u.innerHTML='<svg class="sendglyph" aria-hidden="true" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M4.5 12 20 4.5 15 20l-3.6-5.4L4.5 12Z"/></svg>';let g=document.createElement("span");g.className="sendtext",g.textContent=this.strings.sendLabel,u.append(g),d.append(c,u),d.addEventListener("submit",b=>{b.preventDefault(),this.submit(c,l);}),e.append(t,l,d),e.addEventListener("keydown",b=>this.onKeydown(b,e,p)),this.root.append(e),this.panel=e,c.focus();let x=await this.client.load();x&&x.turns.length>0?this.renderThread(l,x):this.renderFirstRun(l,c),P(this.appearance.availability,new Date)||this.renderAway(l);}renderFirstRun(e,t){let r=document.createElement("div");r.className="empty";let a=document.createElement("h3");a.textContent=this.appearance.greeting.trim()||this.strings.emptyTitle;let i=document.createElement("p");i.textContent=this.strings.emptyBody,r.append(a,i);for(let o of this.appearance.starterPrompts){let s=document.createElement("button");s.className="prompt",s.type="button",s.textContent=o,s.addEventListener("click",()=>{t.value=o,this.submit(t,e);}),r.append(s);}e.replaceChildren(r);}renderAway(e){let t=document.createElement("div");t.className="away",t.textContent=this.appearance.awayMessage.trim()||this.strings.awayBody,e.prepend(t);}close(){this.panel&&(this.panel.remove(),this.panel=null,this.lastFocused instanceof HTMLElement?this.lastFocused.focus():this.launcher.focus());}onIncomingTurn(e){if(this.panel){let t=this.panel.querySelector(".log");t instanceof HTMLElement&&this.appendTurn(t,e);return}e.authorKind!=="end_user"&&(this.unread+=1,this.renderBadge());}async submit(e,t){var i;let r=e.value.trim();if(!r)return;e.value="",(i=t.querySelector(".empty"))==null||i.remove();let a=await this.client.send(r,qe());a&&this.appendTurn(t,a);}renderThread(e,t){e.replaceChildren();for(let r of t.turns)this.appendTurn(e,r);}appendTurn(e,t){var d;(d=e.querySelector(".empty"))==null||d.remove();let r=Ge.includes(t.authorKind)?t.authorKind:"agent",a=this.settings,i=document.createElement("div");if(i.className=`turn ${r}`,r!=="end_user"&&a.nameAvatar){let c=document.createElement("span");if(c.className=r==="ai"?"av bot":"av",c.setAttribute("aria-hidden","true"),r==="agent"&&t.authorAvatarUrl){let u=document.createElement("img");u.alt="",u.src=this.client.avatarUrl(t.authorAvatarUrl),c.append(u);}else c.textContent=r==="ai"?this.strings.aiLabel:G(this.agentName(t));i.append(c);}let s=document.createElement("div");s.className="body";let p=r!=="end_user"&&a.namePlacement!=="hidden",l=document.createElement("div");if(l.textContent=t.body,p||r==="ai"&&a.namePlacement==="hidden"){let c=document.createElement("div");c.className=r==="ai"?"author ai":"author",c.textContent=r==="ai"?this.strings.aiLabel:this.agentName(t),a.stampPlacement==="beside_name"&&c.append(this.stamp(t)),a.namePlacement==="inline"?(c.classList.add("below"),s.append(l,c)):s.append(c,l);}else s.append(l);a.stampPlacement==="under_turn"&&s.append(this.stamp(t)),i.append(s),e.append(i),e.scrollTop=e.scrollHeight;}agentName(e){return e.authorName||this.strings.agentLabel}stamp(e){let t=document.createElement("span");return t.className="stamp",t.textContent=this.strings.timeLabel(e.createdAt),t}onKeydown(e,t,r){if(e.key==="Escape"){e.preventDefault(),this.close();return}if(e.key!=="Tab")return;let a=t.querySelectorAll('button, input, [tabindex]:not([tabindex="-1"])');if(a.length===0)return;let i=a[0],o=a[a.length-1],s=this.root.activeElement;e.shiftKey&&s===i?(e.preventDefault(),o.focus()):!e.shiftKey&&s===o?(e.preventDefault(),i.focus()):s===null&&(e.preventDefault(),r.focus());}renderBadge(){this.unread>0?(this.badge.hidden=false,this.badge.textContent=String(this.unread),this.launcher.setAttribute("aria-label",`${this.strings.launcherLabel}, ${this.strings.unreadLabel(this.unread)}`)):(this.badge.hidden=true,this.badge.textContent="",this.launcher.setAttribute("aria-label",this.strings.launcherLabel));}};function j(n){return `40${JSON.stringify(n)}`}function J(){return "3"}function X(n){let e=n.charAt(0),t=n.slice(1);if(e==="2")return {kind:"ping"};if(e==="1")return {kind:"disconnect"};if(e==="0"){let o=$(t);return {kind:"open",pingInterval:typeof(o==null?void 0:o.pingInterval)=="number"?o.pingInterval:25e3,pingTimeout:typeof(o==null?void 0:o.pingTimeout)=="number"?o.pingTimeout:2e4}}if(e!=="4")return {kind:"other"};let r=t.charAt(0),a=t.slice(1);if(r==="0")return {kind:"connected"};if(r==="1")return {kind:"disconnect"};if(r==="4"){let o=$(a);return {kind:"connectError",message:typeof(o==null?void 0:o.message)=="string"?o.message:"refused"}}if(r!=="2")return {kind:"other"};let i=$(a);return !Array.isArray(i)||typeof i[0]!="string"?{kind:"other"}:{kind:"event",name:i[0],payload:i[1]}}function $(n){try{return JSON.parse(n)}catch(e){return null}}var We="/socket.io/?EIO=4&transport=websocket",F=class{constructor(e){this.options=e;h(this,"socket",null);h(this,"heartbeat",null);h(this,"ready",false);h(this,"closed",false);h(this,"heartbeatWindow",45e3);h(this,"factory");h(this,"setTimer");h(this,"clearTimer");var t,r,a;this.factory=(t=e.socketFactory)!=null?t:Ye,this.setTimer=(r=e.setTimer)!=null?r:((i,o)=>setTimeout(i,o)),this.clearTimer=(a=e.clearTimer)!=null?a:(i=>clearTimeout(i));}open(){if(this.socket||this.closed)return;let e=`${this.options.host.replace(/^http/,"ws").replace(/\/+$/,"")}${We}`,t;try{t=this.factory(e);}catch(r){this.options.onClosed(false);return}this.socket=t,t.onmessage=r=>this.receive(String(r.data)),t.onerror=()=>t.close(),t.onclose=()=>this.fell();}close(){this.closed=true,this.stopHeartbeat();let e=this.socket;this.socket=null,e==null||e.close();}receive(e){var r,a,i,o;let t=X(e);if(t.kind==="open"){this.armHeartbeat(t.pingInterval+t.pingTimeout),(r=this.socket)==null||r.send(j(this.options.auth));return}if(t.kind==="ping"){this.armHeartbeat(),(a=this.socket)==null||a.send(J());return}if(t.kind==="connectError"||t.kind==="disconnect"){this.stopHeartbeat(),(i=this.socket)==null||i.close();return}if(t.kind==="event"){if(t.name==="ready"){this.ready=true,this.options.onReady();return}if(t.name==="conversation.turn"){let s=(o=t.payload)==null?void 0:o.turn;s&&this.options.onTurn(s);}}}fell(){this.stopHeartbeat();let e=this.ready;this.socket=null,this.ready=false,this.closed||this.options.onClosed(e);}armHeartbeat(e){e!==void 0&&(this.heartbeatWindow=e),this.stopHeartbeat(),this.heartbeat=this.setTimer(()=>{var t;return (t=this.socket)==null?void 0:t.close()},this.heartbeatWindow);}stopHeartbeat(){this.heartbeat!==null&&this.clearTimer(this.heartbeat),this.heartbeat=null;}};function Ye(n){let e=globalThis.WebSocket;if(!e)throw new Error("no WebSocket");return new e(n)}var je=6e4;function V(n){var m,C,k,w;let e=globalThis.document;if(!e)throw new Error("prodantix chat requires a document; mount it in the browser");let t=(m=n.mountPoint)!=null?m:e.createElement("div");n.mountPoint||e.body.append(t);let r=new _(n),a=new I(t,r,n.strings,n.appearance),i=(k=(C=n.appearance)==null?void 0:C.availability)!=null?k:T.availability,o,s=()=>{a.setOpenNow(P(i,new Date)),o=setTimeout(s,je);};s();let p=new Set,l,d=null,c=(w=n.pollIntervalMs)!=null?w:15e3,u=f=>{p.has(f.id)||f.authorKind==="end_user"||(p.add(f.id),a.onIncomingTurn(f));},g=async()=>{if(!r.hasThread)return;let f=await r.load();if(f){for(let E of f.turns)u(E);p=new Set(f.turns.map(E=>E.id));}},x=()=>{l||c<=0||(l=setInterval(()=>void g(),c));},v=()=>{l&&clearInterval(l),l=void 0;},b=()=>{if(d||!n.socketHost)return;let f=r.socketAuth;f&&(d=new F({auth:f,host:n.socketHost,onClosed:E=>{d=null,x(),E&&b();},onReady:v,onTurn:u,socketFactory:n.socketFactory}),d.open());};return x(),b(),{close:()=>a.close(),destroy:()=>{v(),clearTimeout(o),d==null||d.close(),d=null,a.close(),t.remove();},identify:f=>r.identify(f),open:()=>{a.open().then(b);}}}var z="prodantix.messenger.config";function Q(n,e){let t=n==null?void 0:n.get(z);if(!t)return null;try{let r=JSON.parse(t);return (r==null?void 0:r.apiKey)===e?r.config:null}catch(r){return null}}async function Z(n){var a,i,o,s,p;let e=L(n.fetchImpl);if(!e)return (a=n.onError)==null||a.call(n,new Error("no fetch available for the prodantix messenger")),null;let t=N(n.host),r=n.locale?`?locale=${encodeURIComponent(n.locale)}`:"";try{let l=await e(`${t}/v1/messenger/config${r}`,{headers:{authorization:`Bearer ${n.apiKey}`},method:"GET"});if(!l.ok)return (i=n.onError)==null||i.call(n,new Error(`prodantix messenger config: ${l.status}`)),null;let d=JSON.parse(await l.text());return d.enabled?((s=n.storage)==null||s.set(z,JSON.stringify({apiKey:n.apiKey,config:d})),d):((o=n.storage)==null||o.remove(z),d)}catch(l){return (p=n.onError)==null||p.call(n,l),null}}var Je=["close","identify","open","shutdown","toggle"],A="[prodantix/messenger]";function Xe(n,e){for(let t of n){let[r,...a]=t!=null?t:[];typeof r!="string"||!Je.includes(r)||e(r,...a);}}function Ve(n){if(!n)return null;try{return new URL(n).origin}catch(e){return null}}async function te(n,e={}){var u,g,x,v,b;let t=(u=e.warn)!=null?u:(m=>console.warn(m)),r=n.prodantix,a=r==null?void 0:r.k;if(!a)return t(`${A} no project key on the install snippet; nothing will load.`),null;let i=Ve((g=e.scriptSrc)!=null?g:Qe(n));if(!i)return t(`${A} could not tell which host served this script; nothing will load.`),null;let o=Ze(n),s=Q(o,a),p=await Z({apiKey:a,host:i,locale:((v=(x=n.document)==null?void 0:x.documentElement)==null?void 0:v.lang)||void 0,onError:m=>t(`${A} settings could not be read: ${String(m)}`),storage:o}),l=p!=null?p:s;if(!l)return t(`${A} no settings available; the messenger will not render.`),null;if(!l.enabled)return null;let d=V({apiKey:a,appearance:l,distinctId:tt(n,o),host:i,socketHost:l.socketUrl||void 0}),c=(m,...C)=>{if((m==="open"||m==="toggle")&&d.open(),m==="close"&&d.close(),m==="shutdown"&&d.destroy(),m==="identify"){let k=et(C[0]);if(!k){console.error(`${A} identify needs { userId, userHash }: the hash is HMAC-SHA256 of the user id under the project signing secret, computed on your server. Without it the visitor stays anonymous.`);return}d.identify(k);}};return Xe((b=r==null?void 0:r.q)!=null?b:[],c),n.prodantix=Object.assign((m,...C)=>c(m,...C),{k:a,q:[]}),d}function Qe(n){var t;let e=(t=n.document)==null?void 0:t.currentScript;return e==null?void 0:e.src}function Ze(n){let e=n.localStorage;if(e)return {get:t=>e.getItem(t),remove:t=>e.removeItem(t),set:(t,r)=>e.setItem(t,r)}}function et(n){if(typeof n!="object"||n===null)return null;let{userHash:e,userId:t}=n;return typeof t!="string"||typeof e!="string"||t.trim()===""||e.trim()===""?null:{userHash:e,userId:t}}var ee="prodantix.messenger.anon";function tt(n,e){var a,i,o;let t=e==null?void 0:e.get(ee);if(t)return t;let r=`anon_${(o=(i=(a=n.crypto)==null?void 0:a.randomUUID)==null?void 0:i.call(a))!=null?o:Math.random().toString(36).slice(2)}`;return e==null||e.set(ee,r),r}te(globalThis);})();//# sourceMappingURL=messenger.iife.js.map
130
+ `}${Re[t.composerShape]}${Oe[t.skin]}${q(t.launcherShape,t.launcherFill,t.launcherContent,t.launcherSize)}${$e[t.bubbleShape]}${ze[t.bubbleFill]}${Ue[t.namePlacement]}${t.nameAvatar?Ke:""}${t.dayDividers?Be:""}${De[t.stampPlacement]}${t.stampContent==="time_and_latency"?Ge:""}`}var We=["end_user","agent","ai"];function je(){let n=globalThis.location;if(n)return {host:n.host,path:n.pathname,title:document.title}}var M=class{constructor(e,t,r={},a={},i={}){this.host=e;this.client=t;u(this,"root");u(this,"strings");u(this,"settings");u(this,"appearance");u(this,"launcher");u(this,"badge");u(this,"panel",null);u(this,"lastFocused",null);u(this,"unread",0);u(this,"openNow");u(this,"style");u(this,"scheme");var o;this.strings={...He,...r},this.appearance={...T,...a},this.settings=I({...T,...a}),this.root=e.attachShadow({mode:(o=i.shadowMode)!=null?o:"closed"}),this.openNow=_(this.appearance.availability,new Date),this.scheme=i.scheme,this.style=document.createElement("style"),this.style.textContent=J(this.appearance,this.scheme),this.root.append(this.style),this.launcher=document.createElement("button"),this.launcher.className="launcher",this.launcher.type="button",this.launcher.setAttribute("aria-haspopup","dialog"),this.launcher.addEventListener("click",()=>this.toggle()),this.badge=document.createElement("span"),this.badge.className="badge",this.badge.hidden=true,this.drawLauncher(),this.root.append(this.launcher);}drawLauncher(){if(this.launcher.setAttribute("aria-label",this.strings.launcherLabel),this.launcher.replaceChildren(),this.launcher.append(W(this.settings.launcherContent,this.strings,this.appearance.team,e=>this.client.avatarUrl(e))),this.settings.launcherShape==="pill"){let e=document.createElement("span");e.className="label",e.textContent=this.settings.launcherContent==="team_faces"?this.strings.agentLabel:this.strings.launcherLabel,this.launcher.append(e);}this.launcher.append(this.badge),this.launcher.classList.toggle("closed",!this.openNow);}update(e,t){this.appearance={...T,...e},this.settings=I(this.appearance),t!==void 0&&(this.scheme=t),this.style.textContent=J(this.appearance,this.scheme),this.drawLauncher(),this.panel&&(this.close(),this.open());}toggle(){this.panel?this.close():this.open();}setOpenNow(e){var t;this.openNow=e,this.launcher.classList.toggle("closed",!e),(t=this.panel)==null||t.classList.toggle("closed",!e);}async open(){var v;if(this.panel)return;this.lastFocused=this.host.ownerDocument.activeElement,this.unread=0,this.renderBadge();let e=document.createElement("section");e.className=this.openNow?"panel":"panel closed",e.setAttribute("role","dialog"),e.setAttribute("aria-modal","true"),e.setAttribute("aria-label",this.strings.title);let t=document.createElement("div");t.className="header";let r=(v=this.appearance.team)!=null?v:[];r.length>0&&t.append(R(r,this.strings,b=>this.client.avatarUrl(b)));let a=document.createElement("div");a.className="headmain";let i=document.createElement("h2");i.textContent=this.strings.title;let o=document.createElement("p");o.className="status";let s=document.createElement("span");s.className="live",s.setAttribute("aria-hidden","true"),o.append(s,this.strings.replyTime),a.append(i,o);let p=document.createElement("button");p.className="close",p.type="button",p.setAttribute("aria-label",this.strings.closeLabel),p.textContent="\xD7",p.addEventListener("click",()=>this.close()),t.append(a,p);let l=document.createElement("div");l.className="log",l.setAttribute("role","log"),l.setAttribute("aria-live","polite"),l.setAttribute("aria-label",this.strings.title);let d=document.createElement("form");d.className="composer";let c=document.createElement("input");c.type="text",c.setAttribute("aria-label",this.strings.inputPlaceholder),c.placeholder=this.strings.inputPlaceholder;let h=document.createElement("button");h.type="submit",h.setAttribute("aria-label",this.strings.sendLabel),h.innerHTML='<svg class="sendglyph" aria-hidden="true" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M4.5 12 20 4.5 15 20l-3.6-5.4L4.5 12Z"/></svg>';let g=document.createElement("span");g.className="sendtext",g.textContent=this.strings.sendLabel,h.append(g),d.append(c,h),d.addEventListener("submit",b=>{b.preventDefault(),this.submit(c,l);}),e.append(t,l,d),e.addEventListener("keydown",b=>this.onKeydown(b,e,p)),this.root.append(e),this.panel=e,c.focus();let x=await this.client.load();x&&x.turns.length>0?this.renderThread(l,x):this.renderFirstRun(l,c),this.openNow||this.renderAway(l);}renderFirstRun(e,t){let r=document.createElement("div");r.className="empty";let a=document.createElement("h3");a.textContent=this.appearance.greeting.trim()||this.strings.emptyTitle;let i=document.createElement("p");i.textContent=this.strings.emptyBody,r.append(a,i);for(let o of this.appearance.starterPrompts){let s=document.createElement("button");s.className="prompt",s.type="button",s.textContent=o,s.addEventListener("click",()=>{t.value=o,this.submit(t,e);}),r.append(s);}e.replaceChildren(r);}renderAway(e){let t=document.createElement("div");t.className="away",t.textContent=this.appearance.awayMessage.trim()||this.strings.awayBody,e.prepend(t);}close(){this.panel&&(this.panel.remove(),this.panel=null,this.lastFocused instanceof HTMLElement?this.lastFocused.focus():this.launcher.focus());}onIncomingTurn(e){if(this.panel){let t=this.panel.querySelector(".log");t instanceof HTMLElement&&this.appendTurn(t,e);return}e.authorKind!=="end_user"&&(this.unread+=1,this.renderBadge());}async submit(e,t){var i;let r=e.value.trim();if(!r)return;e.value="",(i=t.querySelector(".empty"))==null||i.remove();let a=await this.client.send(r,je());a&&this.appendTurn(t,a);}renderThread(e,t){e.replaceChildren();for(let r of t.turns)this.appendTurn(e,r);}appendTurn(e,t){var d;(d=e.querySelector(".empty"))==null||d.remove();let r=We.includes(t.authorKind)?t.authorKind:"agent",a=this.settings,i=document.createElement("div");if(i.className=`turn ${r}`,r!=="end_user"&&a.nameAvatar){let c=document.createElement("span");if(c.className=r==="ai"?"av bot":"av",c.setAttribute("aria-hidden","true"),r==="agent"&&t.authorAvatarUrl){let h=document.createElement("img");h.alt="",h.src=this.client.avatarUrl(t.authorAvatarUrl),c.append(h);}else c.textContent=r==="ai"?this.strings.aiLabel:G(this.agentName(t));i.append(c);}let s=document.createElement("div");s.className="body";let p=r!=="end_user"&&a.namePlacement!=="hidden",l=document.createElement("div");if(l.textContent=t.body,p||r==="ai"&&a.namePlacement==="hidden"){let c=document.createElement("div");c.className=r==="ai"?"author ai":"author",c.textContent=r==="ai"?this.strings.aiLabel:this.agentName(t),a.stampPlacement==="beside_name"&&c.append(this.stamp(t)),a.namePlacement==="inline"?(c.classList.add("below"),s.append(l,c)):s.append(c,l);}else s.append(l);a.stampPlacement==="under_turn"&&s.append(this.stamp(t)),i.append(s),e.append(i),e.scrollTop=e.scrollHeight;}agentName(e){return e.authorName||this.strings.agentLabel}stamp(e){let t=document.createElement("span");return t.className="stamp",t.textContent=this.strings.timeLabel(e.createdAt),t}onKeydown(e,t,r){if(e.key==="Escape"){e.preventDefault(),this.close();return}if(e.key!=="Tab")return;let a=t.querySelectorAll('button, input, [tabindex]:not([tabindex="-1"])');if(a.length===0)return;let i=a[0],o=a[a.length-1],s=this.root.activeElement;e.shiftKey&&s===i?(e.preventDefault(),o.focus()):!e.shiftKey&&s===o?(e.preventDefault(),i.focus()):s===null&&(e.preventDefault(),r.focus());}renderBadge(){this.unread>0?(this.badge.hidden=false,this.badge.textContent=String(this.unread),this.launcher.setAttribute("aria-label",`${this.strings.launcherLabel}, ${this.strings.unreadLabel(this.unread)}`)):(this.badge.hidden=true,this.badge.textContent="",this.launcher.setAttribute("aria-label",this.strings.launcherLabel));}};function X(n){return `40${JSON.stringify(n)}`}function V(){return "3"}function Q(n){let e=n.charAt(0),t=n.slice(1);if(e==="2")return {kind:"ping"};if(e==="1")return {kind:"disconnect"};if(e==="0"){let o=$(t);return {kind:"open",pingInterval:typeof(o==null?void 0:o.pingInterval)=="number"?o.pingInterval:25e3,pingTimeout:typeof(o==null?void 0:o.pingTimeout)=="number"?o.pingTimeout:2e4}}if(e!=="4")return {kind:"other"};let r=t.charAt(0),a=t.slice(1);if(r==="0")return {kind:"connected"};if(r==="1")return {kind:"disconnect"};if(r==="4"){let o=$(a);return {kind:"connectError",message:typeof(o==null?void 0:o.message)=="string"?o.message:"refused"}}if(r!=="2")return {kind:"other"};let i=$(a);return !Array.isArray(i)||typeof i[0]!="string"?{kind:"other"}:{kind:"event",name:i[0],payload:i[1]}}function $(n){try{return JSON.parse(n)}catch(e){return null}}var Ye="/socket.io/?EIO=4&transport=websocket",F=class{constructor(e){this.options=e;u(this,"socket",null);u(this,"heartbeat",null);u(this,"ready",false);u(this,"closed",false);u(this,"heartbeatWindow",45e3);u(this,"factory");u(this,"setTimer");u(this,"clearTimer");var t,r,a;this.factory=(t=e.socketFactory)!=null?t:Je,this.setTimer=(r=e.setTimer)!=null?r:((i,o)=>setTimeout(i,o)),this.clearTimer=(a=e.clearTimer)!=null?a:(i=>clearTimeout(i));}open(){if(this.socket||this.closed)return;let e=`${this.options.host.replace(/^http/,"ws").replace(/\/+$/,"")}${Ye}`,t;try{t=this.factory(e);}catch(r){this.options.onClosed(false);return}this.socket=t,t.onmessage=r=>this.receive(String(r.data)),t.onerror=()=>t.close(),t.onclose=()=>this.fell();}close(){this.closed=true,this.stopHeartbeat();let e=this.socket;this.socket=null,e==null||e.close();}receive(e){var r,a,i,o;let t=Q(e);if(t.kind==="open"){this.armHeartbeat(t.pingInterval+t.pingTimeout),(r=this.socket)==null||r.send(X(this.options.auth));return}if(t.kind==="ping"){this.armHeartbeat(),(a=this.socket)==null||a.send(V());return}if(t.kind==="connectError"||t.kind==="disconnect"){this.stopHeartbeat(),(i=this.socket)==null||i.close();return}if(t.kind==="event"){if(t.name==="ready"){this.ready=true,this.options.onReady();return}if(t.name==="conversation.turn"){let s=(o=t.payload)==null?void 0:o.turn;s&&this.options.onTurn(s);}}}fell(){this.stopHeartbeat();let e=this.ready;this.socket=null,this.ready=false,this.closed||this.options.onClosed(e);}armHeartbeat(e){e!==void 0&&(this.heartbeatWindow=e),this.stopHeartbeat(),this.heartbeat=this.setTimer(()=>{var t;return (t=this.socket)==null?void 0:t.close()},this.heartbeatWindow);}stopHeartbeat(){this.heartbeat!==null&&this.clearTimer(this.heartbeat),this.heartbeat=null;}};function Je(n){let e=globalThis.WebSocket;if(!e)throw new Error("no WebSocket");return new e(n)}var Xe=6e4;function Z(n){var m,C,k,w;let e=globalThis.document;if(!e)throw new Error("prodantix chat requires a document; mount it in the browser");let t=(m=n.mountPoint)!=null?m:e.createElement("div");n.mountPoint||e.body.append(t);let r=new P(n),a=new M(t,r,n.strings,n.appearance),i=(k=(C=n.appearance)==null?void 0:C.availability)!=null?k:T.availability,o,s=()=>{a.setOpenNow(_(i,new Date)),o=setTimeout(s,Xe);};s();let p=new Set,l,d=null,c=(w=n.pollIntervalMs)!=null?w:15e3,h=f=>{p.has(f.id)||f.authorKind==="end_user"||(p.add(f.id),a.onIncomingTurn(f));},g=async()=>{if(!r.hasThread)return;let f=await r.load();if(f){for(let E of f.turns)h(E);p=new Set(f.turns.map(E=>E.id));}},x=()=>{l||c<=0||(l=setInterval(()=>void g(),c));},v=()=>{l&&clearInterval(l),l=void 0;},b=()=>{if(d||!n.socketHost)return;let f=r.socketAuth;f&&(d=new F({auth:f,host:n.socketHost,onClosed:E=>{d=null,x(),E&&b();},onReady:v,onTurn:h,socketFactory:n.socketFactory}),d.open());};return x(),b(),{close:()=>a.close(),destroy:()=>{v(),clearTimeout(o),d==null||d.close(),d=null,a.close(),t.remove();},identify:f=>r.identify(f),open:()=>{a.open().then(b);}}}var z="prodantix.messenger.config";function ee(n,e){let t=n==null?void 0:n.get(z);if(!t)return null;try{let r=JSON.parse(t);return (r==null?void 0:r.apiKey)===e?r.config:null}catch(r){return null}}async function te(n){var a,i,o,s,p;let e=L(n.fetchImpl);if(!e)return (a=n.onError)==null||a.call(n,new Error("no fetch available for the prodantix messenger")),null;let t=N(n.host),r=n.locale?`?locale=${encodeURIComponent(n.locale)}`:"";try{let l=await e(`${t}/v1/messenger/config${r}`,{headers:{authorization:`Bearer ${n.apiKey}`},method:"GET"});if(!l.ok)return (i=n.onError)==null||i.call(n,new Error(`prodantix messenger config: ${l.status}`)),null;let d=JSON.parse(await l.text());return d.enabled?((s=n.storage)==null||s.set(z,JSON.stringify({apiKey:n.apiKey,config:d})),d):((o=n.storage)==null||o.remove(z),d)}catch(l){return (p=n.onError)==null||p.call(n,l),null}}var Ve=["close","identify","open","shutdown","toggle"],A="[prodantix/messenger]";function Qe(n,e){for(let t of n){let[r,...a]=t!=null?t:[];typeof r!="string"||!Ve.includes(r)||e(r,...a);}}function Ze(n){if(!n)return null;try{return new URL(n).origin}catch(e){return null}}async function re(n,e={}){var h,g,x,v,b;let t=(h=e.warn)!=null?h:(m=>console.warn(m)),r=n.prodantix,a=r==null?void 0:r.k;if(!a)return t(`${A} no project key on the install snippet; nothing will load.`),null;let i=Ze((g=e.scriptSrc)!=null?g:et(n));if(!i)return t(`${A} could not tell which host served this script; nothing will load.`),null;let o=tt(n),s=ee(o,a),p=await te({apiKey:a,host:i,locale:((v=(x=n.document)==null?void 0:x.documentElement)==null?void 0:v.lang)||void 0,onError:m=>t(`${A} settings could not be read: ${String(m)}`),storage:o}),l=p!=null?p:s;if(!l)return t(`${A} no settings available; the messenger will not render.`),null;if(!l.enabled)return null;let d=Z({apiKey:a,appearance:l,distinctId:rt(n,o),host:i,socketHost:l.socketUrl||void 0}),c=(m,...C)=>{if((m==="open"||m==="toggle")&&d.open(),m==="close"&&d.close(),m==="shutdown"&&d.destroy(),m==="identify"){let k=nt(C[0]);if(!k){console.error(`${A} identify needs { userId, userHash }: the hash is HMAC-SHA256 of the user id under the project signing secret, computed on your server. Without it the visitor stays anonymous.`);return}d.identify(k);}};return Qe((b=r==null?void 0:r.q)!=null?b:[],c),n.prodantix=Object.assign((m,...C)=>c(m,...C),{k:a,q:[]}),d}function et(n){var t;let e=(t=n.document)==null?void 0:t.currentScript;return e==null?void 0:e.src}function tt(n){let e=n.localStorage;if(e)return {get:t=>e.getItem(t),remove:t=>e.removeItem(t),set:(t,r)=>e.setItem(t,r)}}function nt(n){if(typeof n!="object"||n===null)return null;let{userHash:e,userId:t}=n;return typeof t!="string"||typeof e!="string"||t.trim()===""||e.trim()===""?null:{userHash:e,userId:t}}var ne="prodantix.messenger.anon";function rt(n,e){var a,i,o;let t=e==null?void 0:e.get(ne);if(t)return t;let r=`anon_${(o=(i=(a=n.crypto)==null?void 0:a.randomUUID)==null?void 0:i.call(a))!=null?o:Math.random().toString(36).slice(2)}`;return e==null||e.set(ne,r),r}re(globalThis);})();//# sourceMappingURL=messenger.iife.js.map
119
131
  //# sourceMappingURL=messenger.iife.js.map
package/package.json CHANGED
@@ -63,5 +63,5 @@
63
63
  "sideEffects": false,
64
64
  "type": "module",
65
65
  "types": "./dist/index.d.ts",
66
- "version": "0.2.0-beta.378"
66
+ "version": "0.3.0-beta.379"
67
67
  }