@accurix/centrinfo-widget 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.cjs ADDED
@@ -0,0 +1,1153 @@
1
+ let e=require(`preact`),t=require(`preact/hooks`),n=require(`preact/jsx-runtime`);var r=class extends Error{constructor(e,t){super(t),this.status=e,this.name=`ApiError`}};const i=()=>({agentName:`Assistant`,greeting:`Hi! ๐Ÿ‘‹ How can I help you today?`,allowVoiceInput:!1,availableActions:[]});var a=class{constructor(e,t,n){this.baseUrl=e,this.token=t,this.gifApiKey=n}headers(e=!0){let t={Authorization:`Bearer ${this.token}`};return e&&(t[`Content-Type`]=`application/json`),t}async json(e){let t;try{t=await e.json()}catch{t=void 0}if(!e.ok){let n=s(t)??`request failed (${e.status})`;throw new r(e.status,n)}return t?.data??t}async bootstrap(){try{let e=await fetch(`${this.baseUrl}/public-chat/bootstrap`,{headers:this.headers(!1)});if(!e.ok)return i();let t=await this.json(e);return{...i(),...t}}catch{return i()}}async stream(e,t,n){let r=await fetch(`${this.baseUrl}/public-chat/stream`,{method:`POST`,headers:this.headers(),body:JSON.stringify({question:e,sessionId:t}),signal:n.signal});return!r.ok||!r.body?this.send(e,t,n):c(r.body,n)}async send(e,t,n){let r=await fetch(`${this.baseUrl}/public-chat`,{method:`POST`,headers:this.headers(),body:JSON.stringify({question:e,sessionId:t}),signal:n.signal}),i=await this.json(r);return n.onChunk(i.answer??``),{answer:i.answer??``,sources:i.sources??[],suggestedReplies:i.suggestedReplies??[],availableActions:i.availableActions??[],handoffOffered:i.handoffOffered??!1,requestedContactFields:u(i.requestedContactFields),conversationEnded:i.conversationEnded??!1}}async action(e,t){let n=await fetch(`${this.baseUrl}/public-chat/${e}`,{method:`POST`,headers:this.headers(),body:JSON.stringify(t)}),r=await this.json(n);return{ok:!0,note:r?.note,booking:r?.booking}}async identify(e,t){if(!(!e||!t))try{let n=await fetch(`${this.baseUrl}/public-chat/identify`,{method:`POST`,headers:this.headers(),body:JSON.stringify(o(e,t))});if(!n.ok)try{await n.text()}catch{}}catch{}}async transcribe(e,t){let n=await fetch(`${this.baseUrl}/public-chat/transcribe`,{method:`POST`,headers:this.headers(),body:JSON.stringify({audioBase64:e,mimeType:t})});return(await this.json(n)).text??``}async endConversation(e){try{let t=await fetch(`${this.baseUrl}/public-chat/end`,{method:`POST`,headers:this.headers(),body:JSON.stringify({sessionId:e})});if(!t.ok)try{await t.text()}catch{}}catch{}}async sendFeedback(e){try{let t=await fetch(`${this.baseUrl}/public-chat/feedback`,{method:`POST`,headers:this.headers(),body:JSON.stringify(e)});if(!t.ok)try{await t.text()}catch{}}catch{}}async extract(e,t,n){let r=await fetch(`${this.baseUrl}/public-chat/extract`,{method:`POST`,headers:this.headers(),body:JSON.stringify({fileBase64:e,mimeType:t,filename:n})});return(await this.json(r)).text??``}async demoSlots(e,t){try{let n=`from=${encodeURIComponent(e)}&to=${encodeURIComponent(t)}`,r=await fetch(`${this.baseUrl}/public-chat/demo-slots?${n}`,{headers:this.headers(!1)});if(!r.ok)return{taken:[],busy:[]};let i=await this.json(r);return{taken:i?.taken??[],busy:i?.busy??[]}}catch{return{taken:[],busy:[]}}}async searchGifs(e){if(!this.gifApiKey)return[];let t=`https://tenor.googleapis.com/v2/search?q=${encodeURIComponent(e.trim()||`trending`)}&key=${this.gifApiKey}&limit=24&media_filter=tinygif,gif&contentfilter=high`;try{let e=await fetch(t);return e.ok?((await e.json()).results??[]).map(e=>({id:e.id,url:e.media_formats?.gif?.url??e.media_formats?.tinygif?.url??``,preview:e.media_formats?.tinygif?.url??e.media_formats?.gif?.url??``,alt:e.content_description||`GIF`})).filter(e=>e.url):[]}catch{return[]}}};const o=(e,t)=>{let n={...t.customAttributes??{},...t.metadata??{}};t.createdAt!==void 0&&(n.createdAt=t.createdAt),t.avatarUrl&&(n.avatarUrl=t.avatarUrl),t.company&&(n.company=t.company);let r={sessionId:e},i=t.externalId??t.userId;return i&&(r.externalId=i),t.email&&(r.email=t.email),t.firstName&&(r.firstName=t.firstName),t.lastName&&(r.lastName=t.lastName),t.name&&(r.name=t.name),t.phone&&(r.phone=t.phone),Object.keys(n).length>0&&(r.metadata=n),r},s=e=>{let t=e?.message;if(Array.isArray(t))return t.join(`, `);if(typeof t==`string`)return t},c=async(e,t)=>{let n=e.getReader(),i=new TextDecoder,a={answer:``,sources:[],suggestedReplies:[],availableActions:[],handoffOffered:!1,requestedContactFields:[],conversationEnded:!1},o=``;for(;;){let{done:e,value:s}=await n.read();if(e)break;o+=i.decode(s,{stream:!0});let c;for(;(c=o.indexOf(`
2
+
3
+ `))!==-1;){let e=o.slice(0,c);o=o.slice(c+2);let n=l(e);if(n){if(n.event===`error`)throw new r(502,n.data?.message??`stream error`);if(n.event===`chunk`&&typeof n.data?.text==`string`)a.answer+=n.data.text,t.onChunk(n.data.text);else if(n.event===`final`&&n.data)a.sources=n.data.sources??[],a.suggestedReplies=n.data.suggestedReplies??[],a.availableActions=n.data.availableActions??[],a.handoffOffered=!!n.data.handoffOffered,a.requestedContactFields=u(n.data.requestedContactFields),a.conversationEnded=!!n.data.conversationEnded;else if(n.event===`done`)return a}}}return a},l=e=>{let t=`message`,n=[];for(let r of e.split(`
4
+ `))r.startsWith(`event:`)?t=r.slice(6).trim():r.startsWith(`data:`)&&n.push(r.slice(5).trim());if(n.length===0)return{event:t};try{return{event:t,data:JSON.parse(n.join(`
5
+ `))}}catch{return{event:t}}},u=e=>Array.isArray(e)?e.filter(e=>typeof e==`string`):[],d=e=>new Promise(t=>setTimeout(t,e)),f={agentName:`Sara`,agentAvatarUrl:``,greeting:`Hi! ๐Ÿ‘‹ I'm Sara, the Northwind assistant. Ask me anything about tracking, customs, or pricing โ€” or book a demo.`,allowVoiceInput:!0,availableActions:[`public_book_demo`,`public_capture_contact`,`public_submit_inquiry`],agentDescription:`I help with shipment tracking, customs, and pricing.`,welcomeSubtitle:`Ask me anything โ€” most answers are instant.`,disclaimerText:`Sara is an AI assistant; answers may be imperfect.`,starterQuestions:[`How do I track a shipment?`,`How does customs work?`,`What's your pricing?`]},p=[{match:/^\s*(hi+|hey+|hello|yo|sup|howdy|hola|thanks|thank you|thx|good (morning|afternoon|evening))\b/i,result:{answer:`Hello! ๐Ÿ‘‹ How can I help you today?`,sources:[],suggestedReplies:[`How do I track a shipment?`,`How does customs work?`],handoffOffered:!1}},{match:/track|shipment|where|status/i,result:{answer:`You can track any shipment in real time from the **Tracking** tab โ€” we merge GPS pings with carrier scan events, so the status is usually fresher than the carrier's own site. Each shipment also has a shareable link you can send to customers.`,sources:[{title:`Real-time tracking`,url:`https://northwind.example/docs/tracking`},{title:`Shareable tracking links`,url:`https://northwind.example/docs/share`}],suggestedReplies:[`How fresh is the data?`,`Can customers track too?`],handoffOffered:!1}},{match:/custom|clear|duty|tariff|import/i,result:{answer:`Customs is automated end-to-end: HS codes are auto-classified from your product catalog, duties are estimated up front, and most lanes are pre-cleared before the freight lands. If a shipment needs a human broker, we flag it early so it never sits at the border.`,sources:[{title:`Smart customs`,url:`https://northwind.example/docs/customs`}],suggestedReplies:[`Which countries are pre-cleared?`,`What does it cost?`],handoffOffered:!1}},{match:/price|cost|pricing|plan|quote/i,result:{answer:`Pricing is usage-based โ€” you pay per shipment, with volume tiers that kick in automatically. There's no platform fee and no per-seat charge. I can have someone put together a quote for your lanes if you'd like.`,sources:[{title:`Pricing`,url:`https://northwind.example/pricing`}],suggestedReplies:[`How do volume tiers work?`,`Is there a free trial?`],handoffOffered:!1}}],m={answer:`That's a great question โ€” I don't have a confident answer from Northwind's published docs yet. Want me to pass it to the team so a human can follow up? You can also book a quick demo.`,sources:[],suggestedReplies:[`What can you help with?`],handoffOffered:!0};var h=class{async bootstrap(){return await d(180),f}async stream(e,t,n){await d(550);let r=p.find(t=>t.match.test(e)),i=r?r.result:m,a=i.answer.split(/(\s+)/);for(let e of a){if(n.signal?.aborted)break;n.onChunk(e),await d(18+Math.min(40,e.length*6))}return{...i,availableActions:f.availableActions}}async action(e,t){return await d(450),{ok:!0,note:{"book-demo":`Demo requested โ€” we'll email you a few times that work. ๐Ÿ“…`,contact:`Got it โ€” saved your details. โœ…`,inquiry:`Thanks! We'll get back to you shortly. โœ‰๏ธ`,"request-callback":`We'll call you back soon. ๐Ÿ“ž`,"subscribe-newsletter":`You're subscribed. ๐ŸŽ‰`}[e]}}async transcribe(e,t){return await d(700),`How do I track a shipment?`}async extract(e,t,n){return await d(600),`[Attached file${n?`: ${n}`:``}] Invoice #4821 โ€” 3 pallets, Rotterdam โ†’ Lagos, ETA 12 days.`}async identify(e,t){await d(50)}async endConversation(e){await d(50)}async sendFeedback(){await d(50)}async demoSlots(e,t){return await d(150),{taken:[[11,0],[15,0]].map(([e,t])=>{let n=new Date;return n.setHours(e,t,0,0),n.toISOString()}),busy:[]}}async searchGifs(e){await d(280);let t=e.trim().toLowerCase(),n=t?y.filter(e=>e.alt.includes(t)||e.tags.some(e=>e.includes(t)||t.includes(e))):y;return(n.length>0?n:y).map(e=>({id:e.id,url:v(e.emoji,e.anim),preview:v(e.emoji,e.anim),alt:e.alt}))}};const g=`<animateTransform attributeName='transform' attributeType='XML' type='translate' values='0 0;0 -16;0 0' dur='0.7s' repeatCount='indefinite'/>`,_=`<animateTransform attributeName='transform' attributeType='XML' type='rotate' values='-14 64 110;14 64 110;-14 64 110' dur='0.9s' repeatCount='indefinite'/>`,v=(e,t)=>{let n=`<svg xmlns='http://www.w3.org/2000/svg' width='128' height='128'><rect width='128' height='128' rx='14' fill='#eef1f4'/><text x='64' y='88' font-size='64' text-anchor='middle'>${e}${t}</text></svg>`;return`data:image/svg+xml,${encodeURIComponent(n)}`},y=[{id:`g1`,emoji:`๐Ÿ‘`,alt:`thumbs up`,tags:[`thumbs`,`yes`,`ok`,`great`,`good`],anim:g},{id:`g2`,emoji:`๐ŸŽ‰`,alt:`celebrate`,tags:[`party`,`yay`,`congrats`,`celebrate`],anim:_},{id:`g3`,emoji:`๐Ÿ‘‹`,alt:`wave hello`,tags:[`hi`,`hello`,`hey`,`wave`,`bye`],anim:_},{id:`g4`,emoji:`โค๏ธ`,alt:`heart`,tags:[`love`,`thanks`,`heart`],anim:g},{id:`g5`,emoji:`๐Ÿค”`,alt:`thinking`,tags:[`hmm`,`think`,`thinking`],anim:_},{id:`g6`,emoji:`๐Ÿ˜‚`,alt:`laughing`,tags:[`lol`,`funny`,`haha`,`laugh`],anim:g},{id:`g7`,emoji:`๐Ÿ”ฅ`,alt:`fire`,tags:[`fire`,`hot`,`lit`,`awesome`],anim:g},{id:`g8`,emoji:`๐Ÿš€`,alt:`rocket`,tags:[`rocket`,`launch`,`fast`,`go`],anim:_}],b=e=>new Promise(t=>setTimeout(t,e));var x=class{constructor(e,t){this.real=e,this.strings=t}bootstrap(){return this.real.bootstrap()}async stream(e,t,n){await b(300);for(let e of this.strings.previewReply.split(/(\s+)/)){if(n.signal?.aborted)break;n.onChunk(e),await b(16)}return{answer:this.strings.previewReply,sources:[],suggestedReplies:[],availableActions:[],handoffOffered:!1}}async action(){return await b(250),{ok:!0,note:this.strings.previewActionNote}}async identify(){}async endConversation(){}async sendFeedback(){}async transcribe(){return``}async extract(){return``}async searchGifs(){return[]}async demoSlots(){return{taken:[],busy:[]}}};const S=[{name:`Smileys`,emojis:`๐Ÿ˜€.๐Ÿ˜ƒ.๐Ÿ˜„.๐Ÿ˜.๐Ÿ˜….๐Ÿ˜‚.๐Ÿคฃ.๐Ÿ˜Š.๐Ÿ˜‡.๐Ÿ™‚.๐Ÿ™ƒ.๐Ÿ˜‰.๐Ÿ˜Œ.๐Ÿ˜.๐Ÿฅฐ.๐Ÿ˜˜.๐Ÿ˜‹.๐Ÿ˜›.๐Ÿ˜œ.๐Ÿคช.๐Ÿค—.๐Ÿคญ.๐Ÿค”.๐Ÿค.๐Ÿ˜.๐Ÿ˜ถ.๐Ÿ˜.๐Ÿ™„.๐Ÿ˜ด.๐Ÿฅณ.๐Ÿ˜Ž.๐Ÿค“.๐Ÿฅบ.๐Ÿ˜ข.๐Ÿ˜ญ.๐Ÿ˜ค.๐Ÿ˜ .๐Ÿคฏ.๐Ÿ˜ฌ.๐Ÿ˜ฑ.๐Ÿคฉ.๐Ÿฅฑ`.split(`.`)},{name:`Gestures`,emojis:[`๐Ÿ‘`,`๐Ÿ‘Ž`,`๐Ÿ‘Œ`,`๐ŸคŒ`,`โœŒ๏ธ`,`๐Ÿคž`,`๐ŸคŸ`,`๐Ÿค˜`,`๐Ÿค™`,`๐Ÿ‘ˆ`,`๐Ÿ‘‰`,`๐Ÿ‘†`,`๐Ÿ‘‡`,`โœ‹`,`๐Ÿ–๏ธ`,`๐Ÿ‘‹`,`๐Ÿค`,`๐Ÿ™`,`๐Ÿ’ช`,`๐Ÿ‘`,`๐Ÿ™Œ`,`๐Ÿ‘`,`๐Ÿคฒ`,`๐Ÿซถ`]},{name:`Hearts & symbols`,emojis:`โค๏ธ.๐Ÿงก.๐Ÿ’›.๐Ÿ’š.๐Ÿ’™.๐Ÿ’œ.๐Ÿ–ค.๐Ÿค.๐Ÿ’”.โฃ๏ธ.๐Ÿ’•.๐Ÿ’–.๐Ÿ’˜.๐Ÿ’.โœจ.โญ.๐ŸŒŸ.๐Ÿ’ซ.๐Ÿ”ฅ.๐ŸŽ‰.๐ŸŽŠ.โœ….โŒ.โšก.๐Ÿ’ฏ.๐Ÿš€`.split(`.`)},{name:`Animals & nature`,emojis:[`๐Ÿถ`,`๐Ÿฑ`,`๐ŸฆŠ`,`๐Ÿป`,`๐Ÿผ`,`๐Ÿจ`,`๐Ÿฆ`,`๐Ÿฎ`,`๐Ÿธ`,`๐Ÿต`,`๐Ÿง`,`๐Ÿฆ„`,`๐Ÿ`,`๐Ÿฆ‹`,`๐Ÿข`,`๐Ÿฌ`,`๐ŸŒท`,`๐ŸŒธ`,`๐ŸŒน`,`๐ŸŒป`,`๐ŸŒณ`,`๐Ÿ€`]},{name:`Food & drink`,emojis:[`๐ŸŽ`,`๐ŸŒ`,`๐Ÿ‰`,`๐Ÿ“`,`๐Ÿ’`,`๐Ÿฅ‘`,`๐Ÿ”`,`๐ŸŸ`,`๐Ÿ•`,`๐ŸŒฎ`,`๐Ÿฟ`,`๐Ÿฉ`,`๐Ÿช`,`๐ŸŽ‚`,`โ˜•`,`๐Ÿต`,`๐Ÿบ`,`๐Ÿฅ‚`,`๐Ÿท`]},{name:`Objects & travel`,emojis:`๐Ÿš€.โœˆ๏ธ.๐Ÿš—.๐Ÿ .๐Ÿ“ฆ.๐Ÿ“ฑ.๐Ÿ’ป.โŒš.๐Ÿ“ท.๐Ÿ’ก.๐Ÿ”‘.๐ŸŽ.๐Ÿ“Œ.โœ๏ธ.๐Ÿ“.๐Ÿ“ž.๐Ÿ“ง.๐Ÿ’ฐ.๐Ÿ“ˆ.โฐ.๐Ÿ””.๐ŸŽฏ.๐Ÿ†.๐ŸŽฎ.๐ŸŽต.๐Ÿ’ฌ.๐Ÿ‘€`.split(`.`)}],C={inquiry:{title:`Leave a message`,submit:`Send message`,fields:[{key:`visitorName`,label:`Name`,kind:`text`,identity:`name`},{key:`visitorEmail`,label:`Email`,kind:`email`,required:!0,identity:`email`},{key:`message`,label:`Message`,kind:`textarea`,required:!0,placeholder:`How can we help?`}]},contact:{title:`Share your details`,submit:`Save`,fields:[{key:`name`,label:`Name`,kind:`text`,identity:`name`},{key:`email`,label:`Email`,kind:`email`,required:!0,identity:`email`},{key:`phone`,label:`Phone`,kind:`tel`,identity:`phone`}]},"book-demo":{title:`Book a demo`,submit:`Request demo`,fields:[{key:`visitorName`,label:`Name`,kind:`text`,identity:`name`},{key:`visitorEmail`,label:`Email`,kind:`email`,required:!0,identity:`email`},{key:`preferredAt`,label:`Preferred time`,kind:`text`,placeholder:`e.g. Thursday 3pm`},{key:`notes`,label:`Notes`,kind:`textarea`,placeholder:`Anything we should know?`}]},"request-callback":{title:`Request a callback`,submit:`Request callback`,fields:[{key:`visitorName`,label:`Name`,kind:`text`,identity:`name`},{key:`visitorPhone`,label:`Phone`,kind:`tel`,required:!0,identity:`phone`},{key:`bestTime`,label:`Best time to call`,kind:`text`,placeholder:`e.g. tomorrow afternoon`},{key:`topic`,label:`Topic`,kind:`text`,placeholder:`What should we call about?`}]},"subscribe-newsletter":{title:`Subscribe`,submit:`Subscribe`,fields:[{key:`visitorName`,label:`Name`,kind:`text`,identity:`name`},{key:`visitorEmail`,label:`Email`,kind:`email`,required:!0,identity:`email`}]}},w={openChat:`Open chat`,closeChat:`Close chat`,muteSounds:`Mute sounds`,unmuteSounds:`Unmute sounds`,statusOnline:`Online ยท replies instantly`,statusOffline:`Away ยท leave a message`,composerPlaceholder:`Type your messageโ€ฆ`,send:`Send message`,emoji:`Emoji`,gifs:`GIFs`,attachFile:`Attach a file`,recordVoice:`Record a voice message`,stopRecording:`Stop recording`,stop:`Stop`,copy:`Copy`,copied:`Copied`,retry:`Retry`,clearChat:`Clear conversation`,clearChatConfirm:`Clear this conversation?`,clearChatConfirmBody:`This clears the messages on this device and starts a fresh chat.`,clearConfirmCta:`Clear chat`,endChat:`End conversation`,endChatConfirm:`End this conversation?`,endChatConfirmBody:`You won't be able to send more messages in this chat, but you can start a new one anytime.`,endConfirmCta:`End conversation`,conversationEnded:`This conversation has ended.`,startNewChat:`Start a new conversation`,pastConversations:`Past conversations`,viewingPast:`Viewing a past conversation (read-only)`,backToChat:`Back to current chat`,historyEnded:`ended`,feedbackHelpful:`Helpful`,feedbackNotHelpful:`Not helpful`,feedbackThanks:`Thanks for the feedback`,csatPrompt:`How was this chat?`,feedbackCommentPlaceholder:`What went wrong? (optional)`,feedbackSend:`Send`,cancel:`Cancel`,newMessages:`New messages`,poweredBy:`Powered by`,searchGifs:`Search GIFsโ€ฆ`,searchingGifs:`Searchingโ€ฆ`,noGifs:`No GIFs found`,assistantTyping:`Assistant is typing`,emptyReply:`Sorry, I couldn't generate a reply.`,errorGeneric:`Something went wrong reaching the assistant. Please try again.`,errorRateLimit:`Youโ€™re sending messages a little fast โ€” give it a second and try again.`,attaching:`Reading fileโ€ฆ`,attachTooLarge:`That file is too large (max 8 MB).`,attachFailed:`Couldnโ€™t read that file โ€” try another.`,handoffTitle:`Want our team to follow up?`,handoffName:`Name (optional)`,handoffEmail:`Your email`,handoffNotify:`Notify the team`,sending:`Sendingโ€ฆ`,handoffShared:`Iโ€™ve shared this with our team โ€” theyโ€™ll get back to you at {email}.`,formThanks:`Thanks! Weโ€™ll be in touch.`,formError:`Something went wrong โ€” please try again.`,bookingPickTime:`What time works best?`,bookingDuration:`30-minute demo`,bookingRequested:`Requested for {when} โ€” weโ€™ll confirm by email.`,bookingConfirmed:`Youโ€™re booked for {when}! A calendar invite is on its way. ๐Ÿ“…`,bookingSlotTaken:`That time was just taken โ€” please pick another.`,bookingViaProvider:`Pick a time that works for you on {provider}.`,bookingOpenScheduler:`Open the scheduler`,bookingLinkOpened:`Opening the scheduler โ€” pick a time that suits you. ๐Ÿ“…`,bookingMeetingLink:`Meeting link`,previewReply:`๐Ÿ‘‹ This is a preview โ€” replies here are samples. Publish the widget on your site to chat with the live AI.`,previewActionNote:`Preview โ€” nothing was actually sent. This works for real once you publish.`,previewBanner:`Preview โ€” sample replies, no AI`},T=(e,t)=>e.replace(/\{(\w+)\}/g,(e,n)=>t[n]??``),E=e=>e?{...w,...e}:w,D=(0,e.createContext)(w),O=D.Provider,k=()=>(0,t.useContext)(D),A=(e,t)=>(0,n.jsx)(`svg`,{viewBox:`0 0 24 24`,fill:`none`,stroke:`currentColor`,"stroke-width":`2`,"stroke-linecap":`round`,"stroke-linejoin":`round`,"aria-hidden":`true`,...t,children:e}),ee=e=>(0,n.jsx)(`svg`,{viewBox:`0 0 24 24`,fill:`currentColor`,"aria-hidden":`true`,...e,children:(0,n.jsx)(`path`,{"fill-rule":`evenodd`,"clip-rule":`evenodd`,d:`M5 3.25h14A3.75 3.75 0 0 1 22.75 7v6A3.75 3.75 0 0 1 19 16.75h-7.19l-4.26 3.84A.75.75 0 0 1 6.25 20v-3.32A3.75 3.75 0 0 1 2.25 13V7A3.75 3.75 0 0 1 6 3.25Zm3 7.75a1.25 1.25 0 1 0 0-2.5 1.25 1.25 0 0 0 0 2.5Zm4 0a1.25 1.25 0 1 0 0-2.5 1.25 1.25 0 0 0 0 2.5Zm4 0a1.25 1.25 0 1 0 0-2.5 1.25 1.25 0 0 0 0 2.5Z`})}),te=e=>A((0,n.jsx)(`path`,{d:`m6 9 6 6 6-6`}),e),j=e=>A((0,n.jsxs)(n.Fragment,{children:[(0,n.jsx)(`path`,{d:`m22 2-7 20-4-9-9-4Z`}),(0,n.jsx)(`path`,{d:`M22 2 11 13`})]}),e),ne=e=>A((0,n.jsxs)(n.Fragment,{children:[(0,n.jsx)(`path`,{d:`M12 2a3 3 0 0 0-3 3v7a3 3 0 0 0 6 0V5a3 3 0 0 0-3-3Z`}),(0,n.jsx)(`path`,{d:`M19 10v2a7 7 0 0 1-14 0v-2`}),(0,n.jsx)(`line`,{x1:`12`,y1:`19`,x2:`12`,y2:`22`})]}),e),M=e=>A((0,n.jsxs)(n.Fragment,{children:[(0,n.jsx)(`path`,{d:`M15 3h6v6`}),(0,n.jsx)(`path`,{d:`M10 14 21 3`}),(0,n.jsx)(`path`,{d:`M18 13v6a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h6`})]}),e),N=e=>A((0,n.jsxs)(n.Fragment,{children:[(0,n.jsx)(`rect`,{x:`3`,y:`4`,width:`18`,height:`18`,rx:`2`}),(0,n.jsx)(`line`,{x1:`16`,y1:`2`,x2:`16`,y2:`6`}),(0,n.jsx)(`line`,{x1:`8`,y1:`2`,x2:`8`,y2:`6`}),(0,n.jsx)(`line`,{x1:`3`,y1:`10`,x2:`21`,y2:`10`})]}),e),P=e=>A((0,n.jsxs)(n.Fragment,{children:[(0,n.jsx)(`rect`,{x:`2`,y:`4`,width:`20`,height:`16`,rx:`2`}),(0,n.jsx)(`path`,{d:`m22 7-10 5L2 7`})]}),e),F=e=>A((0,n.jsx)(`path`,{d:`M22 16.92v3a2 2 0 0 1-2.18 2 19.79 19.79 0 0 1-8.63-3.07 19.5 19.5 0 0 1-6-6 19.79 19.79 0 0 1-3.07-8.67A2 2 0 0 1 4.11 2h3a2 2 0 0 1 2 1.72c.13.96.36 1.9.7 2.81a2 2 0 0 1-.45 2.11L8.09 9.91a16 16 0 0 0 6 6l1.27-1.27a2 2 0 0 1 2.11-.45c.91.34 1.85.57 2.81.7A2 2 0 0 1 22 16.92Z`}),e),re=e=>A((0,n.jsxs)(n.Fragment,{children:[(0,n.jsx)(`circle`,{cx:`12`,cy:`12`,r:`9`}),(0,n.jsx)(`path`,{d:`M8.5 14.5a4 4 0 0 0 7 0`}),(0,n.jsx)(`line`,{x1:`9`,y1:`9.5`,x2:`9.01`,y2:`9.5`}),(0,n.jsx)(`line`,{x1:`15`,y1:`9.5`,x2:`15.01`,y2:`9.5`})]}),e),I=e=>A((0,n.jsxs)(n.Fragment,{children:[(0,n.jsx)(`line`,{x1:`18`,y1:`6`,x2:`6`,y2:`18`}),(0,n.jsx)(`line`,{x1:`6`,y1:`6`,x2:`18`,y2:`18`})]}),e),L=e=>A((0,n.jsxs)(n.Fragment,{children:[(0,n.jsx)(`path`,{d:`M11 5 6 9H2v6h4l5 4z`}),(0,n.jsx)(`path`,{d:`M15.5 8.5a5 5 0 0 1 0 7`}),(0,n.jsx)(`path`,{d:`M19 5a9 9 0 0 1 0 14`})]}),e),ie=e=>A((0,n.jsxs)(n.Fragment,{children:[(0,n.jsx)(`path`,{d:`M11 5 6 9H2v6h4l5 4z`}),(0,n.jsx)(`line`,{x1:`22`,y1:`9`,x2:`16`,y2:`15`}),(0,n.jsx)(`line`,{x1:`16`,y1:`9`,x2:`22`,y2:`15`})]}),e),R=e=>A((0,n.jsx)(`path`,{d:`M20 6 9 17l-5-5`}),e),z=e=>A((0,n.jsxs)(n.Fragment,{children:[(0,n.jsx)(`rect`,{x:`9`,y:`9`,width:`13`,height:`13`,rx:`2`}),(0,n.jsx)(`path`,{d:`M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1`})]}),e),ae=e=>A((0,n.jsxs)(n.Fragment,{children:[(0,n.jsx)(`path`,{d:`M1 4v6h6`}),(0,n.jsx)(`path`,{d:`M3.51 15a9 9 0 1 0 2.13-9.36L1 10`})]}),e),oe=e=>A((0,n.jsx)(`rect`,{x:`6`,y:`6`,width:`12`,height:`12`,rx:`2`}),e),se=e=>A((0,n.jsx)(`path`,{d:`M21.44 11.05 12.25 20.24a6 6 0 0 1-8.49-8.49l9.19-9.19a4 4 0 0 1 5.66 5.66l-9.2 9.19a2 2 0 0 1-2.83-2.83l8.49-8.48`}),e),ce=e=>A((0,n.jsxs)(n.Fragment,{children:[(0,n.jsx)(`path`,{d:`M18.36 6.64a9 9 0 1 1-12.73 0`}),(0,n.jsx)(`line`,{x1:`12`,y1:`2`,x2:`12`,y2:`12`})]}),e),le=e=>A((0,n.jsxs)(n.Fragment,{children:[(0,n.jsx)(`circle`,{cx:`12`,cy:`12`,r:`9`}),(0,n.jsx)(`path`,{d:`M12 7v5l3 2`})]}),e),ue=e=>A((0,n.jsxs)(n.Fragment,{children:[(0,n.jsx)(`path`,{d:`M7 10v12`}),(0,n.jsx)(`path`,{d:`M15 5.88 14 10h5.83a2 2 0 0 1 1.92 2.56l-2.33 8A2 2 0 0 1 17.5 22H4a2 2 0 0 1-2-2v-8a2 2 0 0 1 2-2h2.76a2 2 0 0 0 1.79-1.11L12 2a3.13 3.13 0 0 1 3 3.88Z`})]}),e),de=e=>A((0,n.jsxs)(n.Fragment,{children:[(0,n.jsx)(`path`,{d:`M17 14V2`}),(0,n.jsx)(`path`,{d:`M9 18.12 10 14H4.17a2 2 0 0 1-1.92-2.56l2.33-8A2 2 0 0 1 6.5 2H20a2 2 0 0 1 2 2v8a2 2 0 0 1-2 2h-2.76a2 2 0 0 0-1.79 1.11L12 22a3.13 3.13 0 0 1-3-3.88Z`})]}),e),fe=e=>A((0,n.jsxs)(n.Fragment,{children:[(0,n.jsx)(`line`,{x1:`12`,y1:`5`,x2:`12`,y2:`19`}),(0,n.jsx)(`path`,{d:`m19 12-7 7-7-7`})]}),e),pe=/(`[^`]+`)|(\*\*[^*]+\*\*)|(\[[^\]]+\]\(https?:\/\/[^\s)]+\))|(https?:\/\/[^\s)]+)/g,B=e=>{let t=[],r=0,i=0,a;for(pe.lastIndex=0;(a=pe.exec(e))!==null;){a.index>r&&t.push(e.slice(r,a.index));let o=a[0];if(o.startsWith("`"))t.push((0,n.jsx)(`code`,{class:`cf-md-code`,children:o.slice(1,-1)},i++));else if(o.startsWith(`**`))t.push((0,n.jsx)(`strong`,{children:o.slice(2,-2)},i++));else if(o.startsWith(`[`)){let e=/^\[([^\]]+)\]\((https?:\/\/[^\s)]+)\)$/.exec(o),r=e?e[1]:o,a=e?e[2]:`#`;t.push((0,n.jsx)(`a`,{href:a,target:`_blank`,rel:`noopener noreferrer nofollow`,children:r},i++))}else t.push((0,n.jsx)(`a`,{href:o,target:`_blank`,rel:`noopener noreferrer nofollow`,children:o},i++));r=a.index+o.length}return r<e.length&&t.push(e.slice(r)),t},me=/^(```|#{1,6}\s|\s*[-*]\s|\s*\d+\.\s)/,he=e=>{let t=e.replace(/\r\n/g,`
6
+ `).split(`
7
+ `),r=[],i=0,a=0;for(;a<t.length;){let e=t[a];if(e.trim().startsWith("```")){let e=[];for(a++;a<t.length&&!t[a].trim().startsWith("```");)e.push(t[a]),a++;a++,r.push((0,n.jsx)(`pre`,{class:`cf-md-pre`,children:(0,n.jsx)(`code`,{children:e.join(`
8
+ `)})},i++));continue}if(e.trim()===``){a++;continue}let o=/^(#{1,6})\s+(.*)$/.exec(e);if(o){r.push((0,n.jsx)(`div`,{class:`cf-md-h`,children:B(o[2])},i++)),a++;continue}if(/^\s*[-*]\s+/.test(e)){let e=[];for(;a<t.length&&/^\s*[-*]\s+/.test(t[a]);)e.push((0,n.jsx)(`li`,{children:B(t[a].replace(/^\s*[-*]\s+/,``))},e.length)),a++;r.push((0,n.jsx)(`ul`,{class:`cf-md-list`,children:e},i++));continue}if(/^\s*\d+\.\s+/.test(e)){let e=[];for(;a<t.length&&/^\s*\d+\.\s+/.test(t[a]);)e.push((0,n.jsx)(`li`,{children:B(t[a].replace(/^\s*\d+\.\s+/,``))},e.length)),a++;r.push((0,n.jsx)(`ol`,{class:`cf-md-list`,children:e},i++));continue}let s=[e];for(a++;a<t.length&&t[a].trim()!==``&&!me.test(t[a]);)s.push(t[a]),a++;r.push((0,n.jsx)(`p`,{children:B(s.join(` `))},i++))}return r},ge=()=>{let e=(0,t.useRef)(null);return(0,t.useEffect)(()=>{let t=requestAnimationFrame(()=>e.current?.scrollIntoView({block:`end`}));return()=>cancelAnimationFrame(t)},[]),e},_e=e=>e.trim().split(/\s+/).slice(0,2).map(e=>e[0]?.toUpperCase()??``).join(``)||`๐Ÿค–`,ve=({persona:e,small:t})=>{let r=t?`cf-msg__avatar`:`cf-header__avatar`;return e?.agentAvatarUrl?(0,n.jsx)(`span`,{class:r,children:(0,n.jsx)(`img`,{src:e.agentAvatarUrl,alt:``})}):(0,n.jsx)(`span`,{class:r,children:e?_e(e.agentName):`ยท`})},ye=()=>{let e=k();return(0,n.jsxs)(`div`,{class:`cf-msg__bubble cf-typing`,"aria-label":e.assistantTyping,children:[(0,n.jsx)(`span`,{class:`cf-typing__dot`}),(0,n.jsx)(`span`,{class:`cf-typing__dot`}),(0,n.jsx)(`span`,{class:`cf-typing__dot`})]})},be=3,V=({msg:e})=>{if(!e.sources||e.sources.length===0)return null;let t=new Set,r=[];for(let n of e.sources){let e=(n.url||n.title||``).toLowerCase();!e||t.has(e)||(t.add(e),r.push(n))}if(r.length===0)return null;let i=r.slice(0,3),a=r.length-i.length;return(0,n.jsxs)(`div`,{class:`cf-sources`,children:[i.map((e,t)=>e.url?(0,n.jsxs)(`a`,{class:`cf-source`,href:e.url,target:`_blank`,rel:`noopener noreferrer nofollow`,title:e.title||e.url,children:[(0,n.jsx)(M,{}),(0,n.jsx)(`span`,{children:e.title||e.url})]},t):(0,n.jsxs)(`span`,{class:`cf-source`,title:e.title,children:[(0,n.jsx)(M,{}),(0,n.jsx)(`span`,{children:e.title})]},t)),a>0&&(0,n.jsxs)(`span`,{class:`cf-source cf-source--more`,children:[`+`,a,` more`]})]})},H=({replies:e,onPick:t})=>e&&e.length>0?(0,n.jsx)(`div`,{class:`cf-chips`,children:e.map((e,r)=>(0,n.jsx)(`button`,{type:`button`,class:`cf-chip`,onClick:()=>t(e),children:e},r))}):null,U={public_book_demo:{type:`book-demo`,label:`Book a demo`,Icon:N},public_submit_inquiry:{type:`inquiry`,label:`Leave a message`,Icon:P},public_request_callback:{type:`request-callback`,label:`Request a callback`,Icon:F},public_subscribe_newsletter:{type:`subscribe-newsletter`,label:`Subscribe`,Icon:P}},xe=({field:e,value:t,onInput:r})=>{let i=e.placeholder??e.label,a={class:`cf-form__input`,placeholder:e.required?`${i} *`:i,value:t,"aria-label":e.label,onInput:e=>r(e.target.value)};return e.kind===`textarea`?(0,n.jsx)(`textarea`,{rows:2,...a}):(0,n.jsx)(`input`,{type:e.kind,...a})},Se=({spec:e,visitor:r,onSubmit:i,onCancel:a})=>{let o=k(),s=ge(),[c,l]=(0,t.useState)(()=>{let t={};for(let n of e.fields)n.identity&&r[n.identity]&&(t[n.key]=r[n.identity]);return t}),[u,d]=(0,t.useState)(`idle`),[f,p]=(0,t.useState)(``),m=e=>!!(e.identity&&r[e.identity]?.trim()),h=e.fields.filter(e=>!m(e)),g=h.every(e=>!e.required||(c[e.key]?.trim()??``)!==``),_=r.email||r.name||``;return u===`done`?(0,n.jsxs)(`div`,{class:`cf-form cf-form--done`,children:[(0,n.jsx)(R,{}),(0,n.jsx)(`span`,{children:f})]}):(0,n.jsxs)(`div`,{class:`cf-form`,ref:s,children:[(0,n.jsx)(`div`,{class:`cf-form__title`,children:e.title}),h.length===0&&_&&(0,n.jsxs)(`div`,{class:`cf-form__as`,children:[`as `,_]}),h.map(e=>(0,n.jsx)(xe,{field:e,value:c[e.key]??``,onInput:t=>l(n=>({...n,[e.key]:t}))},e.key)),u===`error`&&(0,n.jsx)(`div`,{class:`cf-form__err`,children:o.formError}),(0,n.jsxs)(`div`,{class:`cf-form__actions`,children:[a&&(0,n.jsx)(`button`,{type:`button`,class:`cf-form__cancel`,onClick:a,children:`Cancel`}),(0,n.jsx)(`button`,{type:`button`,class:`cf-form__submit`,disabled:!g||u===`submitting`,onClick:async()=>{if(!g||u===`submitting`)return;d(`submitting`);let t={},n={};for(let r of e.fields){let e=c[r.key]?.trim();e&&(t[r.key]=e,r.identity&&(n[r.identity]=e))}try{p((await i(t,n)).note||o.formThanks),d(`done`)}catch{d(`error`)}},children:u===`submitting`?o.sending:e.submit})]})]})},W=e=>String(e).padStart(2,`0`),Ce=()=>{let e=[];for(let t=9;t<=17;t++)e.push(`${W(t)}:00`),e.push(`${W(t)}:30`);return e},we=e=>{let t=new Date;return t.setHours(0,0,0,0),Array.from({length:e},(e,n)=>{let r=new Date(t);return r.setDate(t.getDate()+n),r})},G=(e,t)=>{let[n,r]=t.split(`:`).map(Number),i=new Date(e.getFullYear(),e.getMonth(),e.getDate(),n??0,r??0);try{return new Intl.DateTimeFormat(void 0,{weekday:`short`,day:`numeric`,month:`short`,year:`numeric`,hour:`2-digit`,minute:`2-digit`,timeZoneName:`short`}).format(i)}catch{return`${e.toDateString()} ${t}`}},K=(e,t)=>{let[n,r]=t.split(`:`).map(Number);return new Date(e.getFullYear(),e.getMonth(),e.getDate(),n??0,r??0)},q=({visitor:e,onSubmit:r,onCancel:i,onDemoSlots:a,scheduler:o})=>{let s=k(),c=ge(),l=(0,t.useMemo)(()=>we(14),[]),u=(0,t.useMemo)(()=>Ce(),[]),[d,f]=(0,t.useState)((0,t.useMemo)(()=>{let e=Date.now();for(let t=0;t<l.length;t++)if(u.some(n=>K(l[t],n).getTime()>e))return t;return 0},[l,u])),[p,m]=(0,t.useState)(null),[h,g]=(0,t.useState)(e.name??``),[_,v]=(0,t.useState)(e.email??``),[y,b]=(0,t.useState)(`idle`),[x,S]=(0,t.useState)(``),[w,E]=(0,t.useState)(``),[D,O]=(0,t.useState)(``),A=o?.connected&&o.mode===`link`,ee=async()=>{if(y===`submitting`||!e.email?.trim()&&!_.trim())return;b(`submitting`),E(``);let t={};_.trim()&&(t.email=_.trim()),h.trim()&&(t.name=h.trim());try{let e=await r({..._.trim()?{visitorEmail:_.trim()}:{},...h.trim()?{visitorName:h.trim()}:{}},t),n=e.booking?.schedulingLink||o?.bookingLink||``;if(!n){b(`error`);return}try{window.open(n,`_blank`,`noopener,noreferrer`)}catch{}O(n),S(e.note||s.bookingLinkOpened),b(`done`)}catch{b(`error`)}},[te,j]=(0,t.useState)(new Set),[ne,N]=(0,t.useState)([]),[P,F]=(0,t.useState)(0),[re,I]=(0,t.useState)(!1);(0,t.useEffect)(()=>{if(!a)return;let e=!0,t=new Date,n=new Date;return n.setDate(n.getDate()+15),a(t.toISOString(),n.toISOString()).then(t=>{e&&(j(new Set(t.taken.map(e=>Date.parse(e)).filter(e=>!Number.isNaN(e)))),N(t.busy.map(e=>[Date.parse(e.start),Date.parse(e.end)]).filter(([e,t])=>!Number.isNaN(e)&&!Number.isNaN(t))))}).catch(()=>{}),()=>{e=!1}},[a,P]);let L=!!e.email?.trim(),ie=!!p&&(L||_.trim()!==``),z=e.email||e.name||``,ae=e=>te.has(K(l[d],e).getTime()),oe=e=>K(l[d],e).getTime()<=Date.now(),se=e=>{let t=K(l[d],e).getTime(),n=t+18e5;return ne.some(([e,r])=>t<r&&n>e)},ce=async()=>{if(!ie||y===`submitting`||!p)return;b(`submitting`),I(!1),E(``);let e=K(l[d],p),t=G(l[d],p),n={};_.trim()&&(n.email=_.trim()),h.trim()&&(n.name=h.trim());try{let i=await r({preferredAt:t,slotAt:e.toISOString(),..._.trim()?{visitorEmail:_.trim()}:{},...h.trim()?{visitorName:h.trim()}:{}},n);i.booking?.confirmed?(S(i.note||T(s.bookingConfirmed,{when:t})),O(i.booking.meetingUrl||i.booking.eventLink||``)):S(i.note||T(s.bookingRequested,{when:t})),b(`done`)}catch(t){if(t?.status===409)j(t=>new Set(t).add(e.getTime())),m(null),I(!0),F(e=>e+1),b(`idle`);else{let e=t?.message;E(e&&e.length<120?e:``),b(`error`)}}};return y===`done`?(0,n.jsxs)(`div`,{class:`cf-form cf-form--done`,children:[(0,n.jsx)(R,{}),(0,n.jsx)(`span`,{children:x}),D&&(0,n.jsxs)(`a`,{class:`cf-booking__link`,href:D,target:`_blank`,rel:`noopener noreferrer`,children:[A?s.bookingOpenScheduler:s.bookingMeetingLink,` `,(0,n.jsx)(M,{})]})]}):A?(0,n.jsxs)(`div`,{class:`cf-form cf-booking`,ref:c,children:[(0,n.jsx)(`div`,{class:`cf-form__title`,children:C[`book-demo`].title}),(0,n.jsx)(`div`,{class:`cf-booking__hint`,children:T(s.bookingViaProvider,{provider:o?.label??`the scheduler`})}),L?z?(0,n.jsxs)(`div`,{class:`cf-form__as`,children:[`as `,z]}):null:(0,n.jsxs)(n.Fragment,{children:[(0,n.jsx)(`input`,{class:`cf-form__input`,type:`text`,placeholder:s.handoffName,value:h,"aria-label":s.handoffName,onInput:e=>g(e.target.value)}),(0,n.jsx)(`input`,{class:`cf-form__input`,type:`email`,placeholder:`${s.handoffEmail} *`,value:_,"aria-label":s.handoffEmail,onInput:e=>v(e.target.value)})]}),y===`error`&&(0,n.jsx)(`div`,{class:`cf-form__err`,children:w||s.formError}),(0,n.jsxs)(`div`,{class:`cf-form__actions`,children:[i&&(0,n.jsx)(`button`,{type:`button`,class:`cf-form__cancel`,onClick:i,children:s.cancel}),(0,n.jsx)(`button`,{type:`button`,class:`cf-form__submit`,disabled:y===`submitting`||!L&&_.trim()===``,onClick:ee,children:y===`submitting`?s.sending:s.bookingOpenScheduler})]})]}):(0,n.jsxs)(`div`,{class:`cf-form cf-booking`,ref:c,children:[(0,n.jsx)(`div`,{class:`cf-form__title`,children:C[`book-demo`].title}),(0,n.jsxs)(`div`,{class:`cf-booking__hint`,children:[s.bookingPickTime,` ยท `,(0,n.jsx)(`span`,{class:`cf-booking__dur`,children:s.bookingDuration})]}),(0,n.jsx)(`div`,{class:`cf-booking__dates`,role:`tablist`,"aria-label":`Pick a day`,children:l.map((e,t)=>(0,n.jsxs)(`button`,{type:`button`,role:`tab`,"aria-selected":t===d,class:`cf-booking__date ${t===d?`is-selected`:``}`,onClick:()=>{f(t),m(null)},children:[(0,n.jsx)(`span`,{class:`cf-booking__dow`,children:e.toLocaleDateString(void 0,{weekday:`short`})}),(0,n.jsx)(`span`,{class:`cf-booking__dom`,children:e.getDate()})]},t))}),(0,n.jsx)(`div`,{class:`cf-booking__slots`,role:`listbox`,"aria-label":`Pick a time`,children:u.map(e=>{let t=oe(e),r=se(e),i=ae(e),a=i||t||r;return(0,n.jsx)(`button`,{type:`button`,role:`option`,"aria-selected":p===e,disabled:a,title:t?`Earlier today`:r?`Busy on the calendar`:i?`Already booked`:void 0,class:`cf-booking__slot ${p===e?`is-selected`:``} ${a?`is-taken`:``}`,onClick:()=>m(e),children:e},e)})}),re&&(0,n.jsx)(`div`,{class:`cf-form__err`,children:s.bookingSlotTaken}),L?z?(0,n.jsxs)(`div`,{class:`cf-form__as`,children:[`as `,z]}):null:(0,n.jsxs)(n.Fragment,{children:[(0,n.jsx)(`input`,{class:`cf-form__input`,type:`text`,placeholder:s.handoffName,value:h,"aria-label":s.handoffName,onInput:e=>g(e.target.value)}),(0,n.jsx)(`input`,{class:`cf-form__input`,type:`email`,placeholder:`${s.handoffEmail} *`,value:_,"aria-label":s.handoffEmail,onInput:e=>v(e.target.value)})]}),y===`error`&&(0,n.jsx)(`div`,{class:`cf-form__err`,children:w||s.formError}),(0,n.jsxs)(`div`,{class:`cf-form__actions`,children:[i&&(0,n.jsx)(`button`,{type:`button`,class:`cf-form__cancel`,onClick:i,children:s.cancel}),(0,n.jsx)(`button`,{type:`button`,class:`cf-form__submit`,disabled:!ie||y===`submitting`,onClick:ce,children:y===`submitting`?s.sending:C[`book-demo`].submit})]})]})},J=({actions:e,visitor:r,onSubmitForm:i,onDemoSlots:a,scheduler:o,exclude:s=[]})=>{let[c,l]=(0,t.useState)(null),u=(e??[]).map(e=>U[e]).filter(e=>!!e&&!s.includes(e.type));return u.length===0?null:c===`book-demo`?(0,n.jsx)(q,{visitor:r,onCancel:()=>l(null),onSubmit:(e,t)=>i(`book-demo`,e,t),onDemoSlots:a,scheduler:o}):c?(0,n.jsx)(Se,{spec:C[c],visitor:r,onCancel:()=>l(null),onSubmit:(e,t)=>i(c,e,t)}):(0,n.jsx)(`div`,{class:`cf-actions`,children:u.map(({type:e,label:t,Icon:r})=>(0,n.jsxs)(`button`,{type:`button`,class:`cf-action`,onClick:()=>l(e),children:[(0,n.jsx)(r,{}),t]},e))})},Y=({hasEmail:e,visitor:r,question:i,onSubmitForm:a})=>{let o=k(),[s,c]=(0,t.useState)(!1),[l,u]=(0,t.useState)(!1),[d,f]=(0,t.useState)(r.name??``),[p,m]=(0,t.useState)(r.email??``);if(e)return null;if(s){let e=r.email||p;return(0,n.jsxs)(`div`,{class:`cf-handoff cf-handoff--done`,children:[(0,n.jsx)(R,{}),(0,n.jsx)(`span`,{children:T(o.handoffShared,{email:e})})]})}let h=async()=>{if(!(!p.trim()||l)){u(!0);try{await a(`inquiry`,{visitorEmail:p.trim(),...d.trim()?{visitorName:d.trim()}:{},message:i||`I had a question the assistant couldnโ€™t answer.`,subject:`Help request from chat`},{email:p.trim(),name:d.trim()||void 0}),c(!0)}catch{u(!1)}}};return(0,n.jsxs)(`div`,{class:`cf-handoff`,children:[(0,n.jsx)(`div`,{class:`cf-handoff__title`,children:o.handoffTitle}),(0,n.jsx)(`input`,{class:`cf-form__input`,type:`text`,placeholder:o.handoffName,value:d,"aria-label":o.handoffName,onInput:e=>f(e.target.value)}),(0,n.jsx)(`input`,{class:`cf-form__input`,type:`email`,placeholder:`${o.handoffEmail} *`,value:p,"aria-label":o.handoffEmail,onInput:e=>m(e.target.value)}),(0,n.jsx)(`button`,{type:`button`,class:`cf-form__submit`,disabled:!p.trim()||l,onClick:h,children:l?o.sending:o.handoffNotify})]})},Te=({text:e})=>{let r=k(),[i,a]=(0,t.useState)(!1);return(0,n.jsxs)(`button`,{type:`button`,class:`cf-tool`,onClick:async()=>{try{await navigator.clipboard.writeText(e),a(!0),setTimeout(()=>a(!1),1500)}catch{}},"aria-label":r.copy,children:[i?(0,n.jsx)(R,{}):(0,n.jsx)(z,{}),i?r.copied:r.copy]})},Ee=({items:e,onPick:t})=>e.length===0?null:(0,n.jsx)(`div`,{class:`cf-starters`,children:e.map((e,r)=>(0,n.jsx)(`button`,{type:`button`,class:`cf-starter`,onClick:()=>t(e),children:e},r))}),De=({msg:e,onRate:r})=>{let i=k(),[a,o]=(0,t.useState)(!1),[s,c]=(0,t.useState)(``),l=e.feedback,u=()=>{r(e.id,`up`),o(!1)},d=()=>{r(e.id,`down`),o(!0)},f=()=>{r(e.id,`down`,s.trim()),o(!1)};return(0,n.jsxs)(`div`,{class:`cf-feedback`,children:[(0,n.jsxs)(`div`,{class:`cf-feedback__row`,children:[(0,n.jsx)(`button`,{type:`button`,class:`cf-feedback__btn ${l===`up`?`is-active`:``}`,"aria-label":i.feedbackHelpful,"aria-pressed":l===`up`,onClick:u,children:(0,n.jsx)(ue,{})}),(0,n.jsx)(`button`,{type:`button`,class:`cf-feedback__btn ${l===`down`?`is-active`:``}`,"aria-label":i.feedbackNotHelpful,"aria-pressed":l===`down`,onClick:d,children:(0,n.jsx)(de,{})}),l&&!a&&(0,n.jsx)(`span`,{class:`cf-feedback__thanks`,children:i.feedbackThanks})]}),a&&l===`down`&&(0,n.jsxs)(`div`,{class:`cf-feedback__comment`,children:[(0,n.jsx)(`textarea`,{class:`cf-feedback__input`,rows:2,placeholder:i.feedbackCommentPlaceholder,value:s,onInput:e=>c(e.target.value)}),(0,n.jsx)(`button`,{type:`button`,class:`cf-feedback__send`,onClick:f,children:i.feedbackSend})]})]})},Oe=({msg:e,persona:t,isLast:r,visitor:i,hasEmail:a,lastQuestion:o,showActions:s,onPickReply:c,onSubmitForm:l,onDemoSlots:u,onRetry:d,ratable:f,onRate:p})=>{let m=k(),h=e.role===`user`,g=e.requestedContactFields?.includes(`email`)===!0,_=r&&!h&&!!(e.handoffOffered||g),v=_&&!a?[`inquiry`]:[],y=!e.pending&&!e.streaming;return(0,n.jsxs)(`div`,{class:`cf-msg cf-msg--${h?`user`:`agent`}`,children:[!h&&(0,n.jsx)(ve,{persona:t,small:!0}),(0,n.jsxs)(`div`,{class:`cf-msg__col`,children:[e.pending&&e.content===``?(0,n.jsx)(ye,{}):e.imageUrl?(0,n.jsxs)(`div`,{class:`cf-msg__bubble cf-msg__bubble--media`,children:[(0,n.jsx)(`img`,{class:`cf-msg__media`,src:e.imageUrl,alt:`GIF`}),e.content&&(0,n.jsx)(`span`,{class:`cf-msg__caption`,children:e.content})]}):(0,n.jsxs)(`div`,{class:`cf-msg__bubble`,children:[h?e.content:he(e.content),e.streaming&&(0,n.jsx)(`span`,{class:`cf-caret`,"aria-hidden":`true`})]}),h&&e.attachmentName&&(0,n.jsxs)(`div`,{class:`cf-attach-chip`,title:e.attachmentName,children:[(0,n.jsx)(se,{}),(0,n.jsx)(`span`,{children:e.attachmentName})]}),!h&&(0,n.jsxs)(n.Fragment,{children:[y&&(e.error||e.content)&&(0,n.jsx)(`div`,{class:`cf-msg__tools`,children:e.error?(0,n.jsxs)(`button`,{type:`button`,class:`cf-tool`,onClick:()=>d(e.id,e.retryText??``),children:[(0,n.jsx)(ae,{}),m.retry]}):(0,n.jsx)(Te,{text:e.content})}),y&&f&&!e.error&&e.content&&(0,n.jsx)(De,{msg:e,onRate:p}),(0,n.jsx)(V,{msg:e}),r&&(0,n.jsx)(H,{replies:e.suggestedReplies,onPick:c}),_&&(0,n.jsx)(Y,{hasEmail:a,visitor:i,question:o,onSubmitForm:l}),s&&(0,n.jsx)(J,{actions:e.availableActions,visitor:i,onSubmitForm:l,onDemoSlots:u,scheduler:t?.scheduler,exclude:v})]})]})]})},ke=e=>new Promise((t,n)=>{let r=new FileReader;r.onload=()=>t(String(r.result).split(`,`)[1]??``),r.onerror=n,r.readAsDataURL(e)}),Ae=({onPick:e})=>(0,n.jsx)(`div`,{class:`cf-picker cf-emoji`,children:S.map(t=>(0,n.jsxs)(`div`,{class:`cf-emoji__group`,children:[(0,n.jsx)(`div`,{class:`cf-emoji__label`,children:t.name}),(0,n.jsx)(`div`,{class:`cf-emoji__grid`,children:t.emojis.map((t,r)=>(0,n.jsx)(`button`,{type:`button`,class:`cf-emoji__btn`,onClick:()=>e(t),"aria-label":t,children:t},r))})]},t.name))}),je=({onSearch:e,onPick:r})=>{let i=k(),[a,o]=(0,t.useState)(``),[s,c]=(0,t.useState)([]),[l,u]=(0,t.useState)(!0);return(0,t.useEffect)(()=>{let t=!0;u(!0);let n=setTimeout(()=>{e(a).then(e=>t&&(c(e),u(!1))).catch(()=>t&&(c([]),u(!1)))},300);return()=>{t=!1,clearTimeout(n)}},[a,e]),(0,n.jsxs)(`div`,{class:`cf-picker cf-gif`,children:[(0,n.jsx)(`input`,{class:`cf-gif__search`,placeholder:i.searchGifs,value:a,"aria-label":i.searchGifs,onInput:e=>o(e.target.value)}),(0,n.jsx)(`div`,{class:`cf-gif__grid`,children:l?(0,n.jsx)(`div`,{class:`cf-gif__hint`,children:i.searchingGifs}):s.length===0?(0,n.jsx)(`div`,{class:`cf-gif__hint`,children:i.noGifs}):s.map(e=>(0,n.jsx)(`button`,{type:`button`,class:`cf-gif__item`,onClick:()=>r(e.url),"aria-label":e.alt,children:(0,n.jsx)(`img`,{src:e.preview,alt:e.alt,loading:`lazy`})},e.id))}),(0,n.jsx)(`div`,{class:`cf-gif__powered`,children:`via Tenor`})]})},Me=8*1024*1024,Ne=`image/png,image/jpeg,image/webp,image/gif,application/pdf`,Pe=({onSend:e,onSendGif:r,disabled:i,allowVoice:a,onTranscribe:o,gifEnabled:s,onSearchGifs:c,allowAttach:l,onExtract:u})=>{let d=k(),[f,p]=(0,t.useState)(``),[m,h]=(0,t.useState)(!1),[g,_]=(0,t.useState)(`none`),[v,y]=(0,t.useState)(null),[b,x]=(0,t.useState)(!1),[S,C]=(0,t.useState)(``),w=(0,t.useRef)(null),T=(0,t.useRef)(null),E=(0,t.useRef)(null),D=(0,t.useRef)(null),O=(0,t.useRef)([]);(0,t.useEffect)(()=>{let e=w.current;e&&(e.style.height=`auto`,e.style.height=`${Math.min(e.scrollHeight,110)}px`)},[f]),(0,t.useEffect)(()=>{if(g===`none`)return;let e=e=>{T.current&&!e.composedPath().includes(T.current)&&_(`none`)};return document.addEventListener(`mousedown`,e),()=>document.removeEventListener(`mousedown`,e)},[g]);let A=e=>_(t=>t===e?`none`:e),ee=e=>{let t=w.current;if(!t){p(t=>t+e);return}let n=t.selectionStart??f.length,r=t.selectionEnd??f.length;p(f.slice(0,n)+e+f.slice(r)),requestAnimationFrame(()=>{t.focus();let r=n+e.length;t.setSelectionRange(r,r)})},te=e=>{_(`none`),r(e)},M=async e=>{let t=e.target,n=t.files?.[0];if(t.value=``,n){if(C(``),n.size>8388608){C(d.attachTooLarge);return}x(!0);try{let e=await u(await ke(n),n.type||`application/octet-stream`,n.name);if(!e){C(d.attachFailed);return}y({name:n.name,text:e})}catch{C(d.attachFailed)}finally{x(!1)}}},N=(!!f.trim()||!!v)&&!i&&!b,P=()=>{N&&(e(f,v?{attachmentName:v.name,attachmentText:v.text}:void 0),p(``),y(null),C(``))},F=e=>{e.key===`Enter`&&!e.shiftKey?(e.preventDefault(),P()):e.key===`Escape`&&g!==`none`&&(e.preventDefault(),e.stopPropagation(),_(`none`))},L=async()=>{if(m){D.current?.stop();return}try{let e=await navigator.mediaDevices.getUserMedia({audio:!0}),t=new MediaRecorder(e);O.current=[],t.ondataavailable=e=>e.data.size>0&&O.current.push(e.data),t.onstop=async()=>{e.getTracks().forEach(e=>e.stop()),h(!1);let n=new Blob(O.current,{type:t.mimeType||`audio/webm`});try{let e=await o(await ke(n),n.type);e&&p(t=>t?`${t} ${e}`:e)}catch{}},D.current=t,t.start(),h(!0)}catch{let e=await o(``,`audio/webm`).catch(()=>``);e&&p(t=>t?`${t} ${e}`:e)}};return(0,n.jsxs)(`div`,{class:`cf-composer`,ref:T,children:[g===`emoji`&&(0,n.jsx)(Ae,{onPick:ee}),g===`gif`&&(0,n.jsx)(je,{onSearch:c,onPick:te}),(v||b||S)&&(0,n.jsx)(`div`,{class:`cf-attach-row`,children:b?(0,n.jsx)(`span`,{class:`cf-attach-status`,children:d.attaching}):S?(0,n.jsx)(`span`,{class:`cf-attach-status cf-attach-status--err`,children:S}):v&&(0,n.jsxs)(`span`,{class:`cf-attach-chip`,title:v.name,children:[(0,n.jsx)(se,{}),(0,n.jsx)(`span`,{children:v.name}),(0,n.jsx)(`button`,{type:`button`,class:`cf-attach-x`,"aria-label":`Remove attachment`,onClick:()=>y(null),children:(0,n.jsx)(I,{})})]})}),(0,n.jsxs)(`div`,{class:`cf-composer__field`,children:[(0,n.jsx)(`button`,{type:`button`,class:`cf-iconbtn ${g===`emoji`?`is-active`:``}`,"aria-label":d.emoji,"aria-pressed":g===`emoji`,onClick:()=>A(`emoji`),children:g===`emoji`?(0,n.jsx)(I,{}):(0,n.jsx)(re,{})}),s&&(0,n.jsx)(`button`,{type:`button`,class:`cf-iconbtn cf-gifbtn ${g===`gif`?`is-active`:``}`,"aria-label":d.gifs,"aria-pressed":g===`gif`,onClick:()=>A(`gif`),children:(0,n.jsx)(`span`,{class:`cf-gif-label`,children:`GIF`})}),l&&(0,n.jsxs)(n.Fragment,{children:[(0,n.jsx)(`input`,{ref:E,type:`file`,class:`cf-file-input`,accept:`image/png,image/jpeg,image/webp,image/gif,application/pdf`,onChange:M,tabIndex:-1,"aria-hidden":`true`}),(0,n.jsx)(`button`,{type:`button`,class:`cf-iconbtn`,"aria-label":d.attachFile,disabled:b,onClick:()=>E.current?.click(),children:(0,n.jsx)(se,{})})]}),(0,n.jsx)(`textarea`,{ref:w,class:`cf-textarea`,rows:1,placeholder:d.composerPlaceholder,value:f,"aria-label":d.composerPlaceholder,disabled:i,onInput:e=>p(e.target.value),onKeyDown:F}),a&&(0,n.jsx)(`button`,{type:`button`,class:`cf-iconbtn cf-mic ${m?`is-recording`:``}`,"aria-label":m?d.stopRecording:d.recordVoice,"aria-pressed":m,onClick:L,children:(0,n.jsx)(ne,{})}),(0,n.jsx)(`button`,{type:`button`,class:`cf-send`,"aria-label":d.send,disabled:!N,onClick:P,children:(0,n.jsx)(j,{})})]})]})};let Fe=!0,X=null;const Ie=e=>{Fe=e},Le=()=>{let e=typeof window<`u`?window.AudioContext??window.webkitAudioContext:void 0;if(!e)return null;if(!X)try{X=new e}catch{return null}return X.state===`suspended`&&X.resume(),X},Z=(e,t,n,r,i,a)=>{let o=e.createOscillator(),s=e.createGain();o.type=i,o.frequency.setValueAtTime(t,n),o.connect(s),s.connect(e.destination),s.gain.setValueAtTime(1e-4,n),s.gain.exponentialRampToValueAtTime(a,n+.012),s.gain.exponentialRampToValueAtTime(1e-4,n+r),o.start(n),o.stop(n+r+.03)},Re=e=>{if(!Fe)return;let t=Le();if(!t)return;let n=t.currentTime;try{e===`open`?(Z(t,523,n,.12,`sine`,.05),Z(t,784,n+.08,.16,`sine`,.05)):e===`send`?Z(t,660,n,.08,`triangle`,.04):e===`receive`&&(Z(t,880,n,.1,`sine`,.045),Z(t,1175,n+.09,.14,`sine`,.045))}catch{}},Q=()=>typeof crypto<`u`&&crypto.randomUUID?crypto.randomUUID():`${Date.now()}-${Math.round(Math.random()*1e9)}`,ze=e=>{try{return e===`none`?null:e===`session`?sessionStorage:localStorage}catch{return null}},$=e=>`centrinfo:session:${e.slice(0,12)}`,Be=e=>`centrinfo:visitor:${e.slice(0,12)}`,Ve=(e,t)=>`centrinfo:chat:${e.slice(0,12)}:${t}`,He=e=>`centrinfo:history:${e.slice(0,12)}`,Ue=20,We=720*60*60*1e3,Ge=1440*60*1e3,Ke=(e,t)=>{try{return JSON.parse(e?.getItem(Be(t))||`{}`)}catch{return{}}},qe=(e,t)=>{if(!e)return Q();try{let n=$(t),r=e.getItem(n);if(r)return r;let i=Q();return e.setItem(n,i),i}catch{return Q()}},Je=(e,t,n)=>{if(!e)return{};try{let r=e.getItem(Ve(t,n));return r?JSON.parse(r):{}}catch{return{}}},Ye=(e,t,n)=>{let{ts:r,messages:i}=Je(e,t,n);return!Array.isArray(i)||typeof r==`number`&&Date.now()-r>We?[]:i},Xe=(e,t,n)=>{let{ts:r,messages:i,ended:a}=Je(e,t,n);return!Array.isArray(i)||i.length===0||typeof r==`number`&&Date.now()-r>We?!1:a===!0||typeof r==`number`&&Date.now()-r>864e5},Ze=(e,t,n,r,i)=>{if(e)try{let a=r.filter(e=>!e.pending).slice(-50);if(a.length===0)return;e.setItem(Ve(t,n),JSON.stringify({ts:Date.now(),messages:a,ended:i}))}catch{}},Qe=(e,t)=>{if(!e)return[];try{let n=e.getItem(He(t)),r=n?JSON.parse(n):[];return Array.isArray(r)?r:[]}catch{return[]}},$e=(e,t,n)=>{if(e)try{e.setItem(He(t),JSON.stringify(n.slice(0,20)))}catch{}},et=(e,t)=>{if(e)try{let n=`centrinfo:chat:${t.slice(0,12)}:`,r=new Set([$(t),Be(t),He(t)]),i=[];for(let t=0;t<e.length;t++){let a=e.key(t);a&&(r.has(a)||a.startsWith(n))&&i.push(a)}i.forEach(t=>e.removeItem(t))}catch{}},tt=e=>{let t=(e.find(e=>e.role===`user`&&e.content.trim())?.content||e.find(e=>e.content.trim())?.content||``).trim().replace(/\s+/g,` `);return t.length>60?t.slice(0,60)+`โ€ฆ`:t||`Conversation`},nt=(e,n)=>{let r=(0,t.useRef)(ze(n.persistence)).current,i=(0,t.useRef)(qe(r,n.token)),a=(0,t.useRef)(null),[o,s]=(0,t.useState)(null),[c,l]=(0,t.useState)(()=>Ye(r,n.token,i.current)),[u,d]=(0,t.useState)(!1),[f,p]=(0,t.useState)(()=>Xe(r,n.token,i.current)),[m,h]=(0,t.useState)(()=>Ke(r,n.token)),[g,_]=(0,t.useState)(()=>Qe(r,n.token)),[v,y]=(0,t.useState)(null),[b,x]=(0,t.useState)([]),S=(0,t.useRef)(m);(0,t.useEffect)(()=>{S.current=m},[m]);let C=(0,t.useCallback)(()=>{a.current?.abort(),et(r,n.token);let e=Q();i.current=e;try{r?.setItem($(n.token),e)}catch{}y(null),x([]),p(!1),_([]),h({}),l(o?[{id:Q(),role:`assistant`,content:o.greeting,availableActions:o.availableActions}]:[])},[r,n.token,o]),w=(0,t.useCallback)(e=>{try{r?.setItem(Be(n.token),JSON.stringify(e))}catch{}},[r,n.token]),T=(0,t.useCallback)(t=>{let n=(t.email??``).trim().toLowerCase(),r=(S.current.email??``).trim().toLowerCase();n&&r&&n!==r&&C();let a={};t.email?.trim()&&(a.email=t.email.trim()),t.phone?.trim()&&(a.phone=t.phone.trim());let o=[t.firstName,t.lastName].filter(e=>!!e?.trim()).join(` `).trim()||t.name?.trim()||``;o&&(a.name=o),Object.keys(a).length>0&&h(e=>{let t={...a,...e};return w(t),t}),e.identify(i.current,t).catch(()=>{})},[e,w,C]);(0,t.useEffect)(()=>{let t=!0;return e.bootstrap().then(e=>{t&&(s(e),l(t=>t.length>0?t:[{id:Q(),role:`assistant`,content:e.greeting,availableActions:e.availableActions}]))}),n.user&&T(n.user),()=>{t=!1}},[]),(0,t.useEffect)(()=>{Ze(r,n.token,i.current,c,f)},[c,f,r,n.token]),(0,t.useEffect)(()=>{c.some(e=>e.role===`user`)&&_(e=>{let t=i.current,a=[{sessionId:t,ts:Date.now(),title:tt(c),ended:f},...e.filter(e=>e.sessionId!==t)];return $e(r,n.token,a),a.slice(0,20)})},[c,f,r,n.token]);let E=(0,t.useCallback)((e,t)=>{l(n=>n.map(n=>n.id===e?{...n,...t}:n))},[]),D=(0,t.useCallback)((t,r)=>{d(!0);let o=new AbortController;a.current=o,e.stream(t,i.current,{signal:o.signal,onChunk:e=>l(t=>t.map(t=>t.id===r?{...t,content:t.content+e,pending:!1,streaming:!0}:t))}).then(e=>{l(t=>t.map(t=>t.id===r?{...t,content:e.answer||t.content||n.strings.emptyReply,pending:!1,streaming:!1,error:!1,retryText:void 0,sources:e.sources,suggestedReplies:e.suggestedReplies,availableActions:e.availableActions,handoffOffered:e.handoffOffered,requestedContactFields:e.requestedContactFields}:t)),Re(`receive`),n.onMessage?.({role:`assistant`,content:e.answer}),e.handoffOffered&&n.onHandoff?.(),e.conversationEnded&&p(!0)}).catch(e=>{if(o.signal.aborted){E(r,{pending:!1,streaming:!1});return}E(r,{content:e?.status===429?n.strings.errorRateLimit:n.strings.errorGeneric,pending:!1,streaming:!1,error:!0,retryText:t})}).finally(()=>{d(!1),a.current=null})},[e,n,E]),O=(0,t.useCallback)((e,t={})=>{let r=e.trim(),{imageUrl:i,attachmentName:a,attachmentText:o}=t;if(!r&&!i&&!o||u||f)return;let s=r;o?s=`${r}\n\n[Attached file${a?` "${a}"`:``}]:\n${o}`.trim():!s&&i&&(s=i);let c={id:Q(),role:`user`,content:r,imageUrl:i,attachmentName:a},d=Q();l(e=>[...e,c,{id:d,role:`assistant`,content:``,pending:!0}]),Re(`send`),n.onMessage?.({role:`user`,content:s}),D(s,d)},[u,f,n,D]),k=(0,t.useCallback)(()=>a.current?.abort(),[]),A=(0,t.useCallback)((e,t)=>{u||f||!t||(E(e,{content:``,pending:!0,streaming:!1,error:!1}),Re(`send`),D(t,e))},[u,f,E,D]),ee=(0,t.useCallback)((t,n,r)=>{E(t,{feedback:n});let a=c.findIndex(e=>e.id===t),o=a>=0?c[a]?.content:void 0,s;for(let e=a-1;e>=0;e--)if(c[e]?.role===`user`){s=c[e]?.content;break}e.sendFeedback({sessionId:i.current,messageId:t,rating:n,comment:r,question:s,answer:o}).catch(()=>{})},[e,E,c]),te=(0,t.useCallback)(async(t,r,a={})=>{n.onAction?.(t);let o=await e.action(t,{sessionId:i.current,...r}),s={};return a.name?.trim()&&(s.name=a.name.trim()),a.email?.trim()&&(s.email=a.email.trim()),a.phone?.trim()&&(s.phone=a.phone.trim()),Object.keys(s).length>0&&(h(e=>{let t={...e,...s};return w(t),t}),s.email&&t!==`contact`&&e.action(`contact`,{sessionId:i.current,...s}).catch(()=>{})),Re(`receive`),o},[e,n,w]),j=(0,t.useCallback)(e=>{let t=e.trim();t&&l(e=>e.some(e=>e.role===`assistant`&&e.content===t)?e:[...e,{id:Q(),role:`assistant`,content:t}])},[]),ne=(0,t.useCallback)((t,n)=>{e.sendFeedback({sessionId:i.current,messageId:`__csat__`,rating:t,comment:n}).catch(()=>{})},[e]),M=(0,t.useCallback)((t,n)=>e.transcribe(t,n),[e]),N=(0,t.useCallback)((t,n,r)=>e.extract(t,n,r),[e]),P=(0,t.useCallback)(t=>e.searchGifs(t),[e]),F=(0,t.useCallback)((t,n)=>e.demoSlots(t,n),[e]),re=(0,t.useCallback)(e=>O(``,{imageUrl:e}),[O]),I=n.demo||!!n.gifApiKey,L=(0,t.useCallback)(()=>{a.current?.abort(),p(!0),e.endConversation(i.current).catch(()=>{})},[e]),ie=(0,t.useCallback)(()=>{a.current?.abort();let e=Q();i.current=e;try{r?.setItem($(n.token),e)}catch{}y(null),x([]),p(!1),l(o?[{id:Q(),role:`assistant`,content:o.greeting,availableActions:o.availableActions}]:[])},[r,n.token,o]),R=(0,t.useCallback)(e=>{if(e===i.current){y(null);return}x(Ye(r,n.token,e)),y(e)},[r,n.token]),z=(0,t.useCallback)(()=>{y(null),x([])},[]);return{persona:o,messages:c,sending:u,visitor:m,starters:n.starters.length>0?n.starters:o?.starterQuestions??[],hasEmail:!!m.email,send:O,sendGif:re,stop:k,retry:A,rateMessage:ee,injectAssistant:j,submitCsat:ne,submitForm:te,transcribe:M,extract:N,searchGifs:P,demoSlots:F,gifEnabled:I,identify:T,ended:f,endConversation:L,startNew:ie,history:g,viewingSessionId:v,viewMessages:b,openConversation:R,closeHistoryView:z,shutdown:C}},rt=e=>{let[n,r]=(0,t.useState)(`light`);return(0,t.useEffect)(()=>{if(e!==`auto`||typeof matchMedia>`u`)return;let t=matchMedia(`(prefers-color-scheme: dark)`),n=()=>r(t.matches?`dark`:`light`);return n(),t.addEventListener(`change`,n),()=>t.removeEventListener(`change`,n)},[e]),e===`auto`?n:e},it=({transport:e,config:r,bindControls:i})=>{let a=r.strings,{persona:o,messages:s,sending:c,visitor:l,hasEmail:u,starters:d,send:f,sendGif:p,stop:m,retry:h,rateMessage:g,injectAssistant:_,submitCsat:v,submitForm:y,transcribe:b,extract:x,searchGifs:S,demoSlots:C,gifEnabled:w,identify:T,ended:E,endConversation:D,startNew:k,history:A,viewingSessionId:j,viewMessages:ne,openConversation:M,closeHistoryView:N,shutdown:P}=nt(e,r),[F,re]=(0,t.useState)(r.openByDefault),[I,R]=(0,t.useState)(0),[z,ae]=(0,t.useState)(()=>{try{return localStorage.getItem(`centrinfo:muted`)===`1`}catch{return!1}}),se=rt(r.theme);(0,t.useEffect)(()=>{Ie(r.sound&&!z)},[r.sound,z]);let pe=(0,t.useCallback)(()=>{ae(e=>{let t=!e;try{localStorage.setItem(`centrinfo:muted`,t?`1`:`0`)}catch{}return t})},[]),B=(0,t.useRef)(null),me=(0,t.useRef)(null),he=(0,t.useRef)(null),ge=(0,t.useRef)(0),[_e,ye]=(0,t.useState)(!0),[be,V]=(0,t.useState)(!1),[H,U]=(0,t.useState)(!1),xe=(0,t.useRef)(null),[Se,W]=(0,t.useState)(!1),[Ce,we]=(0,t.useState)(!1),G=!!j,K=G?ne:s,q=(0,t.useCallback)(()=>{re(!0),R(0),Re(`open`),r.onOpen?.(),r.onShow?.()},[r]),J=(0,t.useCallback)(()=>{re(!1),r.onClose?.(),r.onHide?.(),me.current?.focus()},[r]),Y=(0,t.useCallback)(()=>F?J():q(),[F,q,J]),Te=(0,t.useCallback)(()=>U(!0),[]),De=(0,t.useCallback)(()=>{D(),U(!1)},[D]),ke=(0,t.useCallback)(()=>{k(),V(!1),ye(!0)},[k]);(0,t.useEffect)(()=>{H&&xe.current?.focus()},[H]),(0,t.useEffect)(()=>{i({open:q,close:J,toggle:Y,identify:T,startNew:k,endConversation:D,shutdown:P})},[i,q,J,Y,T,k,D,P]),(0,t.useEffect)(()=>{let e=s.filter(e=>e.role===`assistant`&&!e.pending).length;if(F){ge.current=e;return}e>ge.current&&R(e-ge.current)},[s,F]),(0,t.useEffect)(()=>{r.onUnreadChange?.(I)},[I,r]),(0,t.useEffect)(()=>{let e=r.sessionDurationMinutes;if(!e||e<=0)return;let t=setTimeout(()=>P(),e*60*1e3);return()=>clearTimeout(t)},[r.sessionDurationMinutes,s,F,P]),(0,t.useEffect)(()=>{let e=r.customLauncherSelector;if(!e||typeof document>`u`)return;let t=[];try{t=Array.from(document.querySelectorAll(e))}catch{return}let n=e=>{e.preventDefault(),Y()};return t.forEach(e=>e.addEventListener(`click`,n)),()=>t.forEach(e=>e.removeEventListener(`click`,n))},[r.customLauncherSelector,Y]);let Ae=(0,t.useRef)(!1);(0,t.useEffect)(()=>{let e=r.proactiveMessage?.trim();if(!e||Ae.current)return;let t=r.proactiveOnPaths??[],n=typeof location<`u`?location.pathname:``;if(t.length>0&&!t.some(e=>n.includes(e)))return;let i=`centrinfo:proactive:${r.token.slice(0,12)}`;try{if(sessionStorage.getItem(i)===`1`)return}catch{}let a=setTimeout(()=>{if(!(F||E||s.some(e=>e.role===`user`))){Ae.current=!0;try{sessionStorage.setItem(i,`1`)}catch{}_(e),q()}},Math.max(0,r.proactiveDelaySeconds)*1e3);return()=>clearTimeout(a)},[r.proactiveMessage]),(0,t.useEffect)(()=>{let e=he.current;!F||!e||(s[s.length-1]?.role===`user`||_e?(e.scrollTop=e.scrollHeight,V(!1)):V(!0))},[s,F,c,_e]);let je=(0,t.useCallback)(()=>{let e=he.current;if(!e)return;let t=e.scrollHeight-e.scrollTop-e.clientHeight<80;ye(t),t&&V(!1)},[]),Me=(0,t.useCallback)(()=>{let e=he.current;e&&(e.scrollTop=e.scrollHeight),V(!1),ye(!0)},[]),[Ne,Fe]=(0,t.useState)(``),X=(0,t.useRef)(!1);(0,t.useEffect)(()=>{if(X.current&&!c){let e=[...s].reverse().find(e=>e.role===`assistant`&&!e.streaming&&!e.pending&&e.content);e&&Fe(e.content)}X.current=c},[c,s]),(0,t.useEffect)(()=>{if(!F)return;let e=B.current;H||e?.querySelector(`.cf-textarea`)?.focus();let t=t=>{if(t.key===`Escape`){if(t.preventDefault(),H){U(!1);return}J();return}if(t.key!==`Tab`||!e)return;let n=e.querySelectorAll(`button, [href], textarea, input, [tabindex]:not([tabindex="-1"])`),r=Array.from(n).filter(e=>!e.hasAttribute(`disabled`));if(r.length===0)return;let i=r[0],a=r[r.length-1],o=e.getRootNode()instanceof ShadowRoot?e.getRootNode().activeElement:document.activeElement;t.shiftKey&&o===i?(t.preventDefault(),a.focus()):!t.shiftKey&&o===a&&(t.preventDefault(),i.focus())};return e?.addEventListener(`keydown`,t),()=>e?.removeEventListener(`keydown`,t)},[F,J,H]),(0,t.useEffect)(()=>{let e=B.current;e&&(F?e.removeAttribute(`inert`):e.setAttribute(`inert`,``))},[F]);let Le=r.accentColor??o?.accentColor,Z={zIndex:r.zIndex,"--cf-h-pad":`${r.horizontalPadding}px`,"--cf-v-pad":`${r.verticalPadding}px`,...Le?{"--cf-accent":Le,"--cf-accent-2":`color-mix(in oklab, ${Le} 76%, #14141f)`}:{}},Q=e=>f(e),ze=[...s].reverse().find(e=>e.role===`user`&&e.content.trim())?.content??``,$=s.some(e=>e.role===`user`),Be=!$&&!!(o?.agentDescription||o?.welcomeSubtitle);return(0,n.jsx)(O,{value:a,children:(0,n.jsxs)(`div`,{class:`cf-root`,"data-theme":se,"data-align":r.alignment,style:Z,children:[(0,n.jsxs)(`div`,{ref:B,class:`cf-panel ${F?`is-open`:``}`,role:`dialog`,"aria-modal":`false`,"aria-label":`Chat with ${o?.agentName??`us`}`,"aria-hidden":!F,children:[(0,n.jsxs)(`div`,{class:`cf-header`,children:[(0,n.jsx)(ve,{persona:o}),(0,n.jsxs)(`div`,{class:`cf-header__meta`,children:[(0,n.jsx)(`div`,{class:`cf-header__name`,children:o?.agentName??`Chat`}),(0,n.jsx)(`div`,{class:`cf-header__status ${o?.offline?`cf-header__status--offline`:``}`,children:(0,n.jsx)(`span`,{class:`cf-header__status-text`,children:o?.offline?a.statusOffline:a.statusOnline})})]}),(0,n.jsxs)(`div`,{class:`cf-header__actions`,children:[A.length>0&&(0,n.jsx)(`button`,{type:`button`,class:`cf-header__btn`,"aria-label":a.pastConversations,title:a.pastConversations,"aria-pressed":Se,onClick:()=>W(e=>!e),children:(0,n.jsx)(le,{})}),$&&!E&&!G&&(0,n.jsx)(`button`,{type:`button`,class:`cf-header__btn`,"aria-label":a.endChat,title:a.endChat,onClick:Te,children:(0,n.jsx)(ce,{})}),r.sound&&(0,n.jsx)(`button`,{type:`button`,class:`cf-header__btn`,"aria-label":z?a.unmuteSounds:a.muteSounds,"aria-pressed":z,onClick:pe,children:z?(0,n.jsx)(ie,{}):(0,n.jsx)(L,{})}),(0,n.jsx)(`button`,{type:`button`,class:`cf-header__btn`,"aria-label":a.closeChat,onClick:J,children:(0,n.jsx)(te,{})})]})]}),r.preview&&(0,n.jsx)(`div`,{class:`cf-preview-banner`,children:a.previewBanner}),G&&(0,n.jsx)(`div`,{class:`cf-viewing-banner`,children:a.viewingPast}),(0,n.jsxs)(`div`,{class:`cf-body`,ref:he,role:`log`,onScroll:je,children:[Be&&!G&&(0,n.jsxs)(`div`,{class:`cf-welcome`,children:[o?.agentDescription&&(0,n.jsx)(`p`,{class:`cf-welcome__desc`,children:o.agentDescription}),o?.welcomeSubtitle&&(0,n.jsx)(`p`,{class:`cf-welcome__sub`,children:o.welcomeSubtitle})]}),K.map((e,t)=>(0,n.jsx)(Oe,{msg:e,persona:o,isLast:!G&&t===K.length-1,visitor:l,hasEmail:u,lastQuestion:ze,showActions:!G&&t===K.length-1&&(!$||!!e.handoffOffered),onPickReply:Q,onSubmitForm:y,onDemoSlots:C,onRetry:h,ratable:!G&&K.slice(0,t).some(e=>e.role===`user`),onRate:g},e.id)),!$&&!G&&(0,n.jsx)(Ee,{items:d,onPick:f}),be&&(0,n.jsxs)(`button`,{type:`button`,class:`cf-newmsg`,onClick:Me,children:[(0,n.jsx)(fe,{}),a.newMessages]})]}),(0,n.jsx)(`div`,{class:`cf-sr-live`,"aria-live":`polite`,"aria-atomic":`true`,children:Ne}),c&&!E&&!G&&(0,n.jsx)(`div`,{class:`cf-stopbar`,children:(0,n.jsxs)(`button`,{type:`button`,class:`cf-stop`,onClick:m,children:[(0,n.jsx)(oe,{}),a.stop]})}),G?(0,n.jsx)(`div`,{class:`cf-ended`,children:(0,n.jsx)(`button`,{type:`button`,class:`cf-ended__btn`,onClick:N,children:a.backToChat})}):E?(0,n.jsxs)(`div`,{class:`cf-ended`,children:[(0,n.jsx)(`p`,{class:`cf-ended__text`,children:a.conversationEnded}),r.csat&&$?Ce?(0,n.jsx)(`p`,{class:`cf-ended__text`,children:a.feedbackThanks}):(0,n.jsxs)(`div`,{class:`cf-csat`,children:[(0,n.jsx)(`span`,{class:`cf-csat__q`,children:a.csatPrompt}),(0,n.jsx)(`button`,{type:`button`,class:`cf-csat__btn`,"aria-label":a.feedbackHelpful,onClick:()=>{v(`up`),we(!0)},children:(0,n.jsx)(ue,{})}),(0,n.jsx)(`button`,{type:`button`,class:`cf-csat__btn`,"aria-label":a.feedbackNotHelpful,onClick:()=>{v(`down`),we(!0)},children:(0,n.jsx)(de,{})})]}):null,(0,n.jsx)(`button`,{type:`button`,class:`cf-ended__btn`,onClick:ke,children:a.startNewChat})]}):(0,n.jsx)(Pe,{onSend:f,onSendGif:p,disabled:c,allowVoice:!!o?.allowVoiceInput,onTranscribe:b,gifEnabled:w,onSearchGifs:S,allowAttach:r.attachments,onExtract:x}),!E&&o?.disclaimerText&&(0,n.jsx)(`div`,{class:`cf-disclaimer`,children:o.disclaimerText}),(0,n.jsxs)(`div`,{class:`cf-footer`,children:[a.poweredBy,` `,(0,n.jsx)(`a`,{href:`https://accurix.tech/centrinfo`,target:`_blank`,rel:`noopener noreferrer`,children:`Centrinfo`})]}),H&&(0,n.jsx)(`div`,{class:`cf-confirm`,onClick:()=>U(!1),children:(0,n.jsxs)(`div`,{class:`cf-confirm__card`,role:`alertdialog`,"aria-modal":`true`,"aria-label":a.endChatConfirm,onClick:e=>e.stopPropagation(),children:[(0,n.jsx)(`div`,{class:`cf-confirm__title`,children:a.endChatConfirm}),(0,n.jsx)(`div`,{class:`cf-confirm__body`,children:a.endChatConfirmBody}),(0,n.jsxs)(`div`,{class:`cf-confirm__actions`,children:[(0,n.jsx)(`button`,{ref:xe,type:`button`,class:`cf-confirm__btn cf-confirm__btn--cancel`,onClick:()=>U(!1),children:a.cancel}),(0,n.jsx)(`button`,{type:`button`,class:`cf-confirm__btn cf-confirm__btn--danger`,onClick:De,children:a.endConfirmCta})]})]})}),Se&&(0,n.jsx)(`div`,{class:`cf-confirm`,onClick:()=>W(!1),children:(0,n.jsxs)(`div`,{class:`cf-history`,role:`dialog`,"aria-modal":`true`,"aria-label":a.pastConversations,onClick:e=>e.stopPropagation(),children:[(0,n.jsxs)(`div`,{class:`cf-history__head`,children:[(0,n.jsx)(`span`,{children:a.pastConversations}),(0,n.jsx)(`button`,{type:`button`,class:`cf-header__btn`,"aria-label":a.closeChat,onClick:()=>W(!1),children:(0,n.jsx)(te,{})})]}),(0,n.jsx)(`div`,{class:`cf-history__list`,children:A.map(e=>(0,n.jsxs)(`button`,{type:`button`,class:`cf-history__item ${e.sessionId===j?`is-active`:``}`,onClick:()=>{M(e.sessionId),W(!1)},children:[(0,n.jsx)(`span`,{class:`cf-history__title`,children:e.title}),(0,n.jsxs)(`span`,{class:`cf-history__meta`,children:[new Date(e.ts).toLocaleDateString(void 0,{month:`short`,day:`numeric`}),e.ended?` ยท ${a.historyEnded}`:``]})]},e.sessionId))})]})})]}),!r.hideDefaultLauncher&&(0,n.jsxs)(`button`,{ref:me,type:`button`,class:`cf-launcher`,"aria-label":F?a.closeChat:a.openChat,"aria-expanded":F,onClick:Y,children:[r.launcherIcon?(0,n.jsx)(`img`,{class:`cf-launcher__img`,src:r.launcherIcon,alt:``}):(0,n.jsx)(ee,{}),!F&&I>0&&(0,n.jsx)(`span`,{class:`cf-launcher__badge`,children:I})]})]})})},at=`https://api.accurixtech.com`,ot=e=>{if(!e||typeof e.token!=`string`||e.token.length===0)throw Error("[centrinfo-widget] `token` is required โ€” pass your pub_* token to Centrinfo.init({ token }).");return{token:e.token,apiBaseUrl:(e.apiBaseUrl??`https://api.accurixtech.com`).replace(/\/$/,``),accentColor:e.accentColor,launcherIcon:e.launcherIcon,gifApiKey:e.gifApiKey,theme:e.theme??`auto`,openByDefault:e.openByDefault??!1,sound:e.sound??!0,starters:e.starters??[],strings:E(e.labels),persistence:e.persistence??`local`,attachments:e.attachments??!0,zIndex:e.zIndex??2147483e3,demo:e.demo??!1,preview:e.preview??!1,alignment:e.alignment===`left`?`left`:`right`,horizontalPadding:typeof e.horizontalPadding==`number`?e.horizontalPadding:20,verticalPadding:typeof e.verticalPadding==`number`?e.verticalPadding:20,hideDefaultLauncher:e.hideDefaultLauncher??!1,customLauncherSelector:e.customLauncherSelector,sessionDurationMinutes:typeof e.sessionDurationMinutes==`number`?e.sessionDurationMinutes:0,proactiveMessage:e.proactiveMessage,proactiveDelaySeconds:typeof e.proactiveDelaySeconds==`number`?e.proactiveDelaySeconds:5,proactiveOnPaths:e.proactiveOnPaths,csat:e.csat??!0,user:e.user,onOpen:e.onOpen,onClose:e.onClose,onShow:e.onShow,onHide:e.onHide,onUnreadChange:e.onUnreadChange,onMessage:e.onMessage,onAction:e.onAction,onHandoff:e.onHandoff}},st=`
9
+ :host {
10
+ all: initial;
11
+ }
12
+ .cf-root {
13
+ --cf-accent: #2f7f55;
14
+ --cf-accent-2: #2f7de8;
15
+ --cf-accent-ink: #ffffff;
16
+ --cf-bg: #ffffff;
17
+ --cf-surface: #f4f6f8;
18
+ --cf-surface-2: #eef1f4;
19
+ --cf-text: #0f1e2a;
20
+ --cf-muted: #5b7186;
21
+ --cf-border: #e4e9ee;
22
+ --cf-shadow: 0 12px 48px -12px rgba(15, 30, 42, 0.4), 0 4px 12px -4px rgba(15, 30, 42, 0.2);
23
+ --cf-radius: 18px;
24
+ --cf-font: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif;
25
+
26
+ position: fixed;
27
+ bottom: 0;
28
+ right: 0;
29
+ font-family: var(--cf-font);
30
+ font-size: 15px;
31
+ line-height: 1.5;
32
+ color: var(--cf-text);
33
+ -webkit-font-smoothing: antialiased;
34
+ }
35
+ .cf-root[data-theme='dark'] {
36
+ --cf-accent-ink: #ffffff;
37
+ --cf-bg: #0f1c27;
38
+ --cf-surface: #1a2a37;
39
+ --cf-surface-2: #213442;
40
+ --cf-text: #eef3f7;
41
+ --cf-muted: #93a7b6;
42
+ --cf-border: #2a3d4c;
43
+ --cf-shadow: 0 12px 48px -12px rgba(0, 0, 0, 0.6), 0 4px 12px -4px rgba(0, 0, 0, 0.4);
44
+ }
45
+ .cf-root *,
46
+ .cf-root *::before,
47
+ .cf-root *::after {
48
+ box-sizing: border-box;
49
+ }
50
+ /* :where() keeps this reset at ZERO added specificity, so component button
51
+ styles (.cf-launcher, .cf-send, .cf-chip, .cf-action) win over it. Without
52
+ it, ".cf-root button" (class+element) out-specifies ".cf-launcher" (class)
53
+ and silently wipes every button background โ€” the launcher rendered white. */
54
+ .cf-root :where(button) {
55
+ font-family: inherit;
56
+ cursor: pointer;
57
+ border: none;
58
+ background: none;
59
+ padding: 0;
60
+ color: inherit;
61
+ }
62
+
63
+ /* ---------- Launcher ---------- */
64
+ .cf-launcher {
65
+ position: fixed;
66
+ bottom: var(--cf-v-pad, 20px);
67
+ right: var(--cf-h-pad, 20px);
68
+ z-index: 1;
69
+ /* The host element is pointer-events: none so it can't swallow
70
+ clicks on host-page UI behind it (see mount.tsx). Re-enable here
71
+ on the only two visible surfaces (launcher + panel) so they DO
72
+ receive clicks where they're actually drawn. */
73
+ pointer-events: auto;
74
+ width: 60px;
75
+ height: 60px;
76
+ border-radius: 50%;
77
+ background: linear-gradient(135deg, var(--cf-accent, #2f7f55) 0%, var(--cf-accent-2, #2f7de8) 140%);
78
+ color: var(--cf-accent-ink);
79
+ display: grid;
80
+ place-items: center;
81
+ box-shadow: 0 8px 24px -6px rgba(15, 30, 42, 0.45);
82
+ transition: transform 0.22s cubic-bezier(0.34, 1.56, 0.64, 1), box-shadow 0.2s ease;
83
+ animation: cf-pop 0.4s cubic-bezier(0.34, 1.56, 0.64, 1) both;
84
+ }
85
+ .cf-launcher:hover {
86
+ transform: scale(1.06);
87
+ box-shadow: 0 12px 28px -6px rgba(15, 30, 42, 0.5);
88
+ }
89
+ .cf-launcher:active {
90
+ transform: scale(0.95);
91
+ }
92
+ .cf-launcher:focus-visible {
93
+ outline: 3px solid var(--cf-accent-2);
94
+ outline-offset: 3px;
95
+ }
96
+ .cf-launcher svg {
97
+ width: 30px;
98
+ height: 30px;
99
+ transition: transform 0.25s ease, opacity 0.2s ease;
100
+ }
101
+ /* Custom org logo in the launcher (config.launcherIcon). */
102
+ .cf-launcher__img {
103
+ width: 34px;
104
+ height: 34px;
105
+ border-radius: 50%;
106
+ object-fit: cover;
107
+ }
108
+ .cf-launcher__badge {
109
+ position: absolute;
110
+ top: -2px;
111
+ right: -2px;
112
+ min-width: 20px;
113
+ height: 20px;
114
+ padding: 0 5px;
115
+ border-radius: 10px;
116
+ background: #f25767;
117
+ color: #fff;
118
+ font-size: 11px;
119
+ font-weight: 700;
120
+ display: grid;
121
+ place-items: center;
122
+ box-shadow: 0 0 0 2px var(--cf-bg);
123
+ animation: cf-badge-pop 0.3s ease both;
124
+ }
125
+
126
+ /* ---------- Panel ---------- */
127
+ .cf-panel {
128
+ position: fixed;
129
+ /* Pair to .cf-launcher's pointer-events: auto โ€” the host element
130
+ itself is pointer-events: none, so each visible surface re-enables. */
131
+ pointer-events: auto;
132
+ bottom: var(--cf-v-pad, 20px);
133
+ right: var(--cf-h-pad, 20px);
134
+ /* Above the launcher so the open chat covers it (no second button showing). */
135
+ z-index: 2;
136
+ width: 384px;
137
+ max-width: calc(100vw - 32px);
138
+ height: 640px;
139
+ max-height: calc(100vh - 40px);
140
+ background: var(--cf-bg);
141
+ border-radius: var(--cf-radius);
142
+ box-shadow: var(--cf-shadow);
143
+ display: flex;
144
+ flex-direction: column;
145
+ overflow: hidden;
146
+ transform-origin: bottom right;
147
+ opacity: 0;
148
+ transform: translateY(16px) scale(0.96);
149
+ pointer-events: none;
150
+ transition: opacity 0.24s ease, transform 0.28s cubic-bezier(0.22, 1, 0.36, 1);
151
+ }
152
+ .cf-panel.is-open {
153
+ opacity: 1;
154
+ transform: translateY(0) scale(1);
155
+ pointer-events: auto;
156
+ }
157
+
158
+ /* Left-aligned messenger (alignment: 'left') โ€” dock to the left edge. */
159
+ .cf-root[data-align='left'] .cf-launcher { right: auto; left: var(--cf-h-pad, 20px); }
160
+ .cf-root[data-align='left'] .cf-panel { right: auto; left: var(--cf-h-pad, 20px); transform-origin: bottom left; }
161
+
162
+ /* ---------- Header ---------- */
163
+ .cf-header {
164
+ position: relative;
165
+ padding: 16px 14px 18px 18px;
166
+ background: linear-gradient(135deg, var(--cf-accent, #2f7f55) 0%, var(--cf-accent-2, #2f7de8) 150%);
167
+ color: var(--cf-accent-ink);
168
+ display: flex;
169
+ align-items: center;
170
+ gap: 10px;
171
+ flex-shrink: 0;
172
+ }
173
+ .cf-header__avatar {
174
+ width: 42px;
175
+ height: 42px;
176
+ border-radius: 50%;
177
+ background: rgba(255, 255, 255, 0.18);
178
+ display: grid;
179
+ place-items: center;
180
+ font-weight: 700;
181
+ font-size: 17px;
182
+ overflow: hidden;
183
+ flex-shrink: 0;
184
+ box-shadow: 0 0 0 2px rgba(255, 255, 255, 0.25);
185
+ }
186
+ .cf-header__avatar img {
187
+ width: 100%;
188
+ height: 100%;
189
+ object-fit: cover;
190
+ }
191
+ .cf-header__meta {
192
+ min-width: 0;
193
+ flex: 1 1 auto;
194
+ }
195
+ .cf-header__name {
196
+ font-weight: 700;
197
+ font-size: 16px;
198
+ letter-spacing: -0.2px;
199
+ white-space: nowrap;
200
+ overflow: hidden;
201
+ text-overflow: ellipsis;
202
+ }
203
+ .cf-header__status {
204
+ display: flex;
205
+ align-items: center;
206
+ gap: 6px;
207
+ font-size: 12.5px;
208
+ opacity: 0.9;
209
+ margin-top: 1px;
210
+ min-width: 0;
211
+ }
212
+ .cf-header__status::before {
213
+ content: '';
214
+ width: 7px;
215
+ height: 7px;
216
+ border-radius: 50%;
217
+ background: #7ee2a8;
218
+ box-shadow: 0 0 0 2px rgba(126, 226, 168, 0.3);
219
+ flex-shrink: 0;
220
+ }
221
+ /* Keep the status on one line โ€” the icons no longer squeeze it to wrap. */
222
+ .cf-header__status-text {
223
+ white-space: nowrap;
224
+ overflow: hidden;
225
+ text-overflow: ellipsis;
226
+ }
227
+ /* Action icons cluster tightly together, separated from the meta by the
228
+ header gap, and never shrink (so the meta yields space first). */
229
+ .cf-header__actions {
230
+ display: flex;
231
+ align-items: center;
232
+ gap: 2px;
233
+ flex-shrink: 0;
234
+ }
235
+ .cf-header__btn {
236
+ width: 30px;
237
+ height: 30px;
238
+ border-radius: 8px;
239
+ display: grid;
240
+ place-items: center;
241
+ color: var(--cf-accent-ink);
242
+ opacity: 0.85;
243
+ transition: background 0.15s ease, opacity 0.15s ease;
244
+ flex-shrink: 0;
245
+ }
246
+ .cf-header__btn:hover {
247
+ background: rgba(255, 255, 255, 0.16);
248
+ opacity: 1;
249
+ }
250
+ .cf-header__btn svg {
251
+ width: 17px;
252
+ height: 17px;
253
+ }
254
+ .cf-header__btn:focus-visible {
255
+ outline: 2px solid #fff;
256
+ outline-offset: 1px;
257
+ }
258
+
259
+ /* Preview-mode banner (data-preview) โ€” sample replies, no AI. */
260
+ .cf-preview-banner {
261
+ flex-shrink: 0;
262
+ padding: 5px 12px;
263
+ text-align: center;
264
+ font-size: 11.5px;
265
+ font-weight: 600;
266
+ letter-spacing: 0.2px;
267
+ color: #7a5b00;
268
+ background: #fff3cd;
269
+ border-bottom: 1px solid #ffe69c;
270
+ }
271
+ .cf-root[data-theme='dark'] .cf-preview-banner {
272
+ color: #ffe08a;
273
+ background: #3a3320;
274
+ border-bottom-color: #4d4427;
275
+ }
276
+
277
+ /* ---------- Body / messages ---------- */
278
+ .cf-body {
279
+ flex: 1;
280
+ overflow-y: auto;
281
+ /* Never scroll/shift horizontally โ€” a long source pill or code line is
282
+ clipped, not allowed to push the whole thread sideways. */
283
+ overflow-x: hidden;
284
+ padding: 18px 16px 8px;
285
+ display: flex;
286
+ flex-direction: column;
287
+ gap: 12px;
288
+ scroll-behavior: smooth;
289
+ background: var(--cf-bg);
290
+ }
291
+ .cf-body::-webkit-scrollbar {
292
+ width: 8px;
293
+ }
294
+ .cf-body::-webkit-scrollbar-thumb {
295
+ background: var(--cf-border);
296
+ border-radius: 4px;
297
+ }
298
+ .cf-msg {
299
+ display: flex;
300
+ gap: 8px;
301
+ max-width: 100%;
302
+ animation: cf-msg-in 0.32s cubic-bezier(0.22, 1, 0.36, 1) both;
303
+ }
304
+ .cf-msg--user {
305
+ justify-content: flex-end;
306
+ }
307
+ .cf-msg__avatar {
308
+ width: 26px;
309
+ height: 26px;
310
+ border-radius: 50%;
311
+ background: linear-gradient(135deg, var(--cf-accent, #2f7f55), var(--cf-accent-2, #2f7de8));
312
+ color: #fff;
313
+ display: grid;
314
+ place-items: center;
315
+ font-size: 11px;
316
+ font-weight: 700;
317
+ flex-shrink: 0;
318
+ overflow: hidden;
319
+ align-self: flex-end;
320
+ }
321
+ .cf-msg__avatar img { width: 100%; height: 100%; object-fit: cover; }
322
+ .cf-msg__bubble {
323
+ padding: 10px 13px;
324
+ border-radius: 16px;
325
+ max-width: 100%;
326
+ /* break-word (not anywhere) only breaks words too long to fit โ€” so short
327
+ words like "Hello" never split mid-word. */
328
+ overflow-wrap: break-word;
329
+ white-space: pre-wrap;
330
+ font-size: 14.5px;
331
+ }
332
+ .cf-msg--agent .cf-msg__bubble {
333
+ background: var(--cf-surface);
334
+ border-bottom-left-radius: 5px;
335
+ color: var(--cf-text);
336
+ }
337
+ .cf-msg--user .cf-msg__bubble {
338
+ background: linear-gradient(135deg, var(--cf-accent, #2f7f55) 0%, var(--cf-accent-2, #2f7de8) 160%);
339
+ color: var(--cf-accent-ink);
340
+ border-bottom-right-radius: 5px;
341
+ }
342
+ .cf-msg__bubble a {
343
+ color: inherit;
344
+ text-decoration: underline;
345
+ }
346
+ .cf-msg__bubble strong { font-weight: 700; }
347
+ .cf-msg__bubble p { margin: 0 0 8px; }
348
+ .cf-msg__bubble p:last-child { margin-bottom: 0; }
349
+ .cf-msg__col { min-width: 0; max-width: 85%; display: flex; flex-direction: column; gap: 8px; align-items: flex-start; }
350
+ .cf-msg--user .cf-msg__col { align-items: flex-end; }
351
+
352
+ /* ---------- Markdown in answers ---------- */
353
+ .cf-msg__bubble .cf-md-h { font-weight: 700; font-size: 14.5px; margin: 4px 0 2px; }
354
+ .cf-msg__bubble ul.cf-md-list, .cf-msg__bubble ol.cf-md-list { margin: 4px 0; padding-left: 20px; }
355
+ .cf-msg__bubble .cf-md-list li { margin: 2px 0; }
356
+ .cf-md-code {
357
+ font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
358
+ font-size: 0.86em;
359
+ background: var(--cf-surface-2);
360
+ padding: 1px 5px;
361
+ border-radius: 5px;
362
+ }
363
+ .cf-msg--user .cf-md-code { background: rgba(255, 255, 255, 0.22); }
364
+ .cf-md-pre {
365
+ margin: 6px 0;
366
+ padding: 10px 12px;
367
+ background: var(--cf-surface-2);
368
+ border: 1px solid var(--cf-border);
369
+ border-radius: 10px;
370
+ overflow-x: auto;
371
+ }
372
+ .cf-md-pre code { font-family: ui-monospace, SFMono-Regular, Menlo, monospace; font-size: 12.5px; white-space: pre; color: var(--cf-text); }
373
+ .cf-msg--user .cf-md-pre { background: rgba(0, 0, 0, 0.18); border-color: rgba(255, 255, 255, 0.18); }
374
+ .cf-msg--user .cf-md-pre code { color: var(--cf-accent-ink); }
375
+
376
+ /* streaming caret */
377
+ .cf-caret {
378
+ display: inline-block;
379
+ width: 7px;
380
+ height: 1em;
381
+ margin-left: 2px;
382
+ vertical-align: text-bottom;
383
+ background: var(--cf-accent);
384
+ border-radius: 1px;
385
+ animation: cf-blink 1s step-end infinite;
386
+ }
387
+ @keyframes cf-blink {
388
+ 0%, 100% { opacity: 1; }
389
+ 50% { opacity: 0; }
390
+ }
391
+
392
+ /* message tools (copy / retry) */
393
+ .cf-msg__tools { display: flex; gap: 6px; }
394
+ .cf-tool {
395
+ display: inline-flex;
396
+ align-items: center;
397
+ gap: 5px;
398
+ font-size: 12px;
399
+ color: var(--cf-muted);
400
+ padding: 3px 7px;
401
+ border-radius: 7px;
402
+ opacity: 0.6;
403
+ transition: opacity 0.15s ease, background 0.15s ease, color 0.15s ease;
404
+ }
405
+ .cf-msg:hover .cf-tool { opacity: 1; }
406
+ .cf-tool:hover { background: var(--cf-surface); color: var(--cf-text); }
407
+ .cf-tool svg { width: 13px; height: 13px; }
408
+
409
+ /* Per-message ๐Ÿ‘/๐Ÿ‘Ž feedback. */
410
+ .cf-feedback { margin-top: 4px; }
411
+ .cf-feedback__row { display: flex; align-items: center; gap: 4px; }
412
+ .cf-feedback__btn {
413
+ display: inline-flex;
414
+ align-items: center;
415
+ justify-content: center;
416
+ width: 26px;
417
+ height: 26px;
418
+ border-radius: 7px;
419
+ color: var(--cf-muted);
420
+ opacity: 0.6;
421
+ cursor: pointer;
422
+ transition: opacity 0.15s ease, background 0.15s ease, color 0.15s ease;
423
+ }
424
+ .cf-msg:hover .cf-feedback__btn { opacity: 1; }
425
+ .cf-feedback__btn:hover { background: var(--cf-surface); color: var(--cf-text); }
426
+ .cf-feedback__btn.is-active { opacity: 1; color: var(--cf-accent); background: var(--cf-surface); }
427
+ .cf-feedback__btn svg { width: 14px; height: 14px; }
428
+ .cf-feedback__thanks { margin-left: 4px; font-size: 11.5px; color: var(--cf-muted); }
429
+ .cf-feedback__comment { display: flex; flex-direction: column; gap: 6px; margin-top: 6px; max-width: 260px; }
430
+ .cf-feedback__input {
431
+ width: 100%;
432
+ resize: none;
433
+ font: inherit;
434
+ font-size: 12.5px;
435
+ line-height: 1.4;
436
+ color: var(--cf-text);
437
+ background: var(--cf-bg);
438
+ border: 1px solid var(--cf-border);
439
+ border-radius: 9px;
440
+ padding: 7px 9px;
441
+ box-sizing: border-box;
442
+ }
443
+ .cf-feedback__input:focus { outline: none; border-color: var(--cf-accent); }
444
+ .cf-feedback__send {
445
+ align-self: flex-end;
446
+ font-size: 12px;
447
+ font-weight: 600;
448
+ color: var(--cf-accent-ink);
449
+ background: var(--cf-accent);
450
+ border: none;
451
+ border-radius: 999px;
452
+ padding: 5px 14px;
453
+ cursor: pointer;
454
+ transition: opacity 0.15s ease;
455
+ }
456
+ .cf-feedback__send:hover { opacity: 0.9; }
457
+
458
+ /* conversation starters */
459
+ .cf-starters { display: flex; flex-direction: column; align-items: flex-start; gap: 8px; margin: 2px 0 4px 34px; }
460
+ .cf-starter {
461
+ padding: 9px 13px;
462
+ border-radius: 14px;
463
+ border: 1px solid var(--cf-border);
464
+ background: var(--cf-bg);
465
+ color: var(--cf-text);
466
+ font-size: 13.5px;
467
+ font-weight: 500;
468
+ text-align: left;
469
+ transition: border-color 0.15s ease, transform 0.1s ease;
470
+ }
471
+ .cf-starter:hover { border-color: var(--cf-accent); }
472
+ .cf-starter:active { transform: scale(0.98); }
473
+
474
+ /* stop generating */
475
+ .cf-stopbar { display: flex; justify-content: center; padding: 6px 0 2px; flex-shrink: 0; }
476
+ .cf-stop {
477
+ display: inline-flex;
478
+ align-items: center;
479
+ gap: 6px;
480
+ font-size: 12.5px;
481
+ font-weight: 600;
482
+ color: var(--cf-muted);
483
+ background: var(--cf-bg);
484
+ border: 1px solid var(--cf-border);
485
+ border-radius: 999px;
486
+ padding: 6px 14px;
487
+ box-shadow: var(--cf-shadow);
488
+ transition: border-color 0.15s ease, color 0.15s ease;
489
+ }
490
+ .cf-stop:hover { border-color: var(--cf-accent); color: var(--cf-text); }
491
+ .cf-stop svg { width: 13px; height: 13px; }
492
+
493
+ /* typing */
494
+ .cf-typing {
495
+ display: inline-flex;
496
+ gap: 4px;
497
+ padding: 13px 14px;
498
+ }
499
+ .cf-typing__dot {
500
+ width: 7px;
501
+ height: 7px;
502
+ border-radius: 50%;
503
+ background: var(--cf-muted);
504
+ animation: cf-typing 1.1s infinite ease-in-out;
505
+ }
506
+ .cf-typing__dot:nth-child(2) { animation-delay: 0.15s; }
507
+ .cf-typing__dot:nth-child(3) { animation-delay: 0.3s; }
508
+
509
+ /* sources */
510
+ .cf-sources {
511
+ display: flex;
512
+ flex-wrap: wrap;
513
+ gap: 6px;
514
+ /* Tie the row to the message column so a long title can't widen the thread. */
515
+ max-width: 100%;
516
+ min-width: 0;
517
+ }
518
+ .cf-source {
519
+ display: inline-flex;
520
+ align-items: center;
521
+ gap: 5px;
522
+ padding: 5px 10px;
523
+ border-radius: 999px;
524
+ background: var(--cf-surface-2);
525
+ border: 1px solid var(--cf-border);
526
+ color: var(--cf-muted);
527
+ font-size: 12px;
528
+ text-decoration: none;
529
+ max-width: 100%;
530
+ min-width: 0;
531
+ transition: border-color 0.15s ease, color 0.15s ease;
532
+ }
533
+ .cf-source:hover { color: var(--cf-text); border-color: var(--cf-accent); }
534
+ .cf-source--more { color: var(--cf-muted); cursor: default; }
535
+ .cf-source--more:hover { border-color: var(--cf-border); color: var(--cf-muted); }
536
+ .cf-source svg { width: 12px; height: 12px; flex-shrink: 0; }
537
+ .cf-source span { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
538
+
539
+ /* chips + actions */
540
+ .cf-chips, .cf-actions {
541
+ display: flex;
542
+ flex-wrap: wrap;
543
+ gap: 8px;
544
+ }
545
+ .cf-chip {
546
+ padding: 8px 13px;
547
+ border-radius: 999px;
548
+ background: var(--cf-bg);
549
+ border: 1.5px solid var(--cf-accent);
550
+ color: var(--cf-accent);
551
+ font-size: 13px;
552
+ font-weight: 600;
553
+ transition: background 0.15s ease, color 0.15s ease, transform 0.1s ease;
554
+ }
555
+ .cf-root[data-theme='dark'] .cf-chip { color: var(--cf-text); border-color: var(--cf-border); }
556
+ .cf-chip:hover { background: var(--cf-accent); color: var(--cf-accent-ink); }
557
+ .cf-chip:active { transform: scale(0.97); }
558
+ .cf-chip:focus-visible { outline: 2px solid var(--cf-accent-2); outline-offset: 2px; }
559
+ .cf-action {
560
+ display: inline-flex;
561
+ align-items: center;
562
+ gap: 7px;
563
+ padding: 9px 14px;
564
+ border-radius: 12px;
565
+ background: var(--cf-surface);
566
+ border: 1px solid var(--cf-border);
567
+ color: var(--cf-text);
568
+ font-size: 13.5px;
569
+ font-weight: 600;
570
+ transition: border-color 0.15s ease, transform 0.1s ease;
571
+ }
572
+ .cf-action:hover { border-color: var(--cf-accent); }
573
+ .cf-action:active { transform: scale(0.98); }
574
+ .cf-action svg { width: 15px; height: 15px; color: var(--cf-accent); }
575
+
576
+ /* ---------- Inline forms + handoff card ---------- */
577
+ .cf-form {
578
+ display: flex;
579
+ flex-direction: column;
580
+ gap: 8px;
581
+ width: 100%;
582
+ max-width: 300px;
583
+ padding: 12px;
584
+ border-radius: 14px;
585
+ border: 1px solid var(--cf-border);
586
+ background: var(--cf-surface);
587
+ animation: cf-msg-in 0.2s ease both;
588
+ }
589
+ .cf-form__title { font-size: 13.5px; font-weight: 700; color: var(--cf-fg, var(--cf-text)); }
590
+ .cf-form__as { font-size: 12.5px; color: var(--cf-muted); margin-top: -2px; }
591
+ .cf-form__input {
592
+ width: 100%;
593
+ padding: 9px 11px;
594
+ border: 1.5px solid var(--cf-border);
595
+ border-radius: 10px;
596
+ background: var(--cf-bg);
597
+ color: var(--cf-text);
598
+ font-family: inherit;
599
+ font-size: 14px;
600
+ outline: none;
601
+ resize: none;
602
+ }
603
+ .cf-form__input:focus { border-color: var(--cf-accent); }
604
+ .cf-form__input::placeholder { color: var(--cf-muted); }
605
+ .cf-form__actions { display: flex; justify-content: flex-end; gap: 8px; margin-top: 2px; }
606
+ .cf-form__submit {
607
+ padding: 8px 14px;
608
+ border-radius: 10px;
609
+ font-size: 13.5px;
610
+ font-weight: 600;
611
+ background: linear-gradient(135deg, var(--cf-accent, #2f7f55) 0%, var(--cf-accent-2, #2f7de8) 160%);
612
+ color: var(--cf-accent-ink);
613
+ transition: opacity 0.15s ease, transform 0.1s ease;
614
+ }
615
+ .cf-form__submit:disabled { opacity: 0.45; cursor: default; }
616
+ .cf-form__submit:not(:disabled):active { transform: scale(0.97); }
617
+ .cf-form__cancel { padding: 8px 12px; border-radius: 10px; font-size: 13.5px; font-weight: 600; color: var(--cf-muted); }
618
+ .cf-form__cancel:hover { color: var(--cf-text); }
619
+ .cf-form__err { font-size: 12.5px; color: #f25767; }
620
+ .cf-form--done {
621
+ flex-direction: row;
622
+ align-items: center;
623
+ gap: 8px;
624
+ font-size: 13.5px;
625
+ color: var(--cf-text);
626
+ }
627
+ .cf-form--done svg { width: 18px; height: 18px; color: var(--cf-accent); flex-shrink: 0; }
628
+ .cf-form--done { flex-wrap: wrap; }
629
+ .cf-booking__link {
630
+ display: inline-flex;
631
+ align-items: center;
632
+ gap: 4px;
633
+ font-size: 13px;
634
+ font-weight: 600;
635
+ color: var(--cf-accent);
636
+ text-decoration: none;
637
+ flex-basis: 100%;
638
+ }
639
+ .cf-booking__link svg { width: 13px; height: 13px; }
640
+ .cf-booking__link:hover { text-decoration: underline; }
641
+
642
+ .cf-handoff {
643
+ display: flex;
644
+ flex-direction: column;
645
+ gap: 8px;
646
+ width: 100%;
647
+ max-width: 300px;
648
+ padding: 12px;
649
+ border-radius: 14px;
650
+ border: 1.5px solid var(--cf-accent);
651
+ background: color-mix(in oklab, var(--cf-accent) 8%, var(--cf-bg));
652
+ animation: cf-msg-in 0.2s ease both;
653
+ }
654
+ .cf-handoff__title { font-size: 13.5px; font-weight: 700; color: var(--cf-text); }
655
+
656
+ /* ---------- Demo booking picker ---------- */
657
+ .cf-booking { max-width: 320px; }
658
+ .cf-booking__hint { font-size: 12.5px; color: var(--cf-muted); margin-top: -2px; }
659
+ .cf-booking__dur { font-weight: 600; color: var(--cf-text); }
660
+ .cf-booking__dates {
661
+ display: flex;
662
+ gap: 6px;
663
+ overflow-x: auto;
664
+ padding-bottom: 4px;
665
+ scrollbar-width: thin;
666
+ }
667
+ .cf-booking__dates::-webkit-scrollbar { height: 5px; }
668
+ .cf-booking__dates::-webkit-scrollbar-thumb { background: var(--cf-border); border-radius: 3px; }
669
+ .cf-booking__date {
670
+ flex-shrink: 0;
671
+ display: flex;
672
+ flex-direction: column;
673
+ align-items: center;
674
+ gap: 1px;
675
+ width: 46px;
676
+ padding: 7px 0;
677
+ border-radius: 10px;
678
+ border: 1px solid var(--cf-border);
679
+ background: var(--cf-bg);
680
+ color: var(--cf-text);
681
+ transition: border-color 0.15s ease, background 0.15s ease, transform 0.1s ease;
682
+ }
683
+ .cf-booking__date:hover { border-color: var(--cf-accent); }
684
+ .cf-booking__date:active { transform: scale(0.96); }
685
+ .cf-booking__date.is-selected {
686
+ border-color: var(--cf-accent);
687
+ background: color-mix(in oklab, var(--cf-accent) 14%, var(--cf-bg));
688
+ color: var(--cf-accent);
689
+ }
690
+ .cf-root[data-theme='dark'] .cf-booking__date.is-selected { color: var(--cf-text); }
691
+ .cf-booking__dow { font-size: 10px; text-transform: uppercase; letter-spacing: 0.4px; color: var(--cf-muted); }
692
+ .cf-booking__date.is-selected .cf-booking__dow { color: inherit; }
693
+ .cf-booking__dom { font-size: 15px; font-weight: 700; line-height: 1.1; }
694
+ .cf-booking__slots {
695
+ display: grid;
696
+ grid-template-columns: repeat(3, 1fr);
697
+ gap: 6px;
698
+ max-height: 156px;
699
+ overflow-y: auto;
700
+ padding: 2px;
701
+ }
702
+ .cf-booking__slots::-webkit-scrollbar { width: 6px; }
703
+ .cf-booking__slots::-webkit-scrollbar-thumb { background: var(--cf-border); border-radius: 3px; }
704
+ .cf-booking__slot {
705
+ padding: 8px 0;
706
+ border-radius: 9px;
707
+ border: 1px solid var(--cf-border);
708
+ background: var(--cf-bg);
709
+ color: var(--cf-accent);
710
+ font-size: 13px;
711
+ font-weight: 600;
712
+ transition: border-color 0.15s ease, background 0.15s ease, color 0.15s ease, transform 0.1s ease;
713
+ }
714
+ .cf-root[data-theme='dark'] .cf-booking__slot { color: var(--cf-text); }
715
+ .cf-booking__slot:hover { border-color: var(--cf-accent); }
716
+ .cf-booking__slot:active { transform: scale(0.96); }
717
+ .cf-booking__slot.is-selected {
718
+ background: linear-gradient(135deg, var(--cf-accent, #2f7f55) 0%, var(--cf-accent-2, #2f7de8) 160%);
719
+ color: var(--cf-accent-ink);
720
+ border-color: var(--cf-accent);
721
+ }
722
+ .cf-booking__slot.is-taken,
723
+ .cf-booking__slot:disabled {
724
+ color: var(--cf-muted);
725
+ background: var(--cf-surface);
726
+ border-color: var(--cf-border);
727
+ text-decoration: line-through;
728
+ cursor: not-allowed;
729
+ opacity: 0.55;
730
+ }
731
+ .cf-booking__slot.is-taken:hover { border-color: var(--cf-border); }
732
+ .cf-handoff--done {
733
+ flex-direction: row;
734
+ align-items: center;
735
+ border-color: var(--cf-border);
736
+ background: var(--cf-surface);
737
+ font-size: 13.5px;
738
+ }
739
+ .cf-handoff--done svg { width: 18px; height: 18px; color: var(--cf-accent); flex-shrink: 0; }
740
+
741
+ /* note (action confirmation) */
742
+ .cf-note {
743
+ align-self: center;
744
+ font-size: 12.5px;
745
+ color: var(--cf-muted);
746
+ background: var(--cf-surface);
747
+ padding: 7px 12px;
748
+ border-radius: 999px;
749
+ animation: cf-msg-in 0.3s ease both;
750
+ }
751
+
752
+ /* ---------- Composer ---------- */
753
+ .cf-composer {
754
+ flex-shrink: 0;
755
+ padding: 10px 12px;
756
+ border-top: 1px solid var(--cf-border);
757
+ background: var(--cf-bg);
758
+ }
759
+ .cf-composer__field {
760
+ display: flex;
761
+ align-items: flex-end;
762
+ gap: 6px;
763
+ background: var(--cf-surface);
764
+ border: 1.5px solid var(--cf-border);
765
+ border-radius: 14px;
766
+ padding: 6px 6px 6px 12px;
767
+ transition: border-color 0.15s ease;
768
+ }
769
+ .cf-composer__field:focus-within { border-color: var(--cf-accent); }
770
+ .cf-textarea {
771
+ flex: 1;
772
+ border: none;
773
+ background: none;
774
+ resize: none;
775
+ outline: none;
776
+ font-family: inherit;
777
+ font-size: 14.5px;
778
+ color: var(--cf-text);
779
+ max-height: 110px;
780
+ line-height: 1.45;
781
+ padding: 6px 0;
782
+ }
783
+ .cf-textarea::placeholder { color: var(--cf-muted); }
784
+ .cf-iconbtn {
785
+ width: 36px;
786
+ height: 36px;
787
+ border-radius: 10px;
788
+ display: grid;
789
+ place-items: center;
790
+ flex-shrink: 0;
791
+ color: var(--cf-muted);
792
+ transition: background 0.15s ease, color 0.15s ease;
793
+ }
794
+ .cf-iconbtn:hover { background: var(--cf-surface-2); color: var(--cf-text); }
795
+ .cf-iconbtn:focus-visible { outline: 2px solid var(--cf-accent-2); outline-offset: 1px; }
796
+ .cf-iconbtn svg { width: 19px; height: 19px; }
797
+ .cf-send {
798
+ width: 36px;
799
+ height: 36px;
800
+ border-radius: 10px;
801
+ display: grid;
802
+ place-items: center;
803
+ flex-shrink: 0;
804
+ background: linear-gradient(135deg, var(--cf-accent, #2f7f55) 0%, var(--cf-accent-2, #2f7de8) 160%);
805
+ color: var(--cf-accent-ink);
806
+ transition: opacity 0.15s ease, transform 0.1s ease;
807
+ }
808
+ .cf-send:disabled { opacity: 0.4; cursor: default; }
809
+ .cf-send:not(:disabled):hover { transform: scale(1.05); }
810
+ .cf-send:not(:disabled):active { transform: scale(0.94); }
811
+ .cf-send svg { width: 18px; height: 18px; }
812
+ .cf-mic.is-recording { color: #f25767; animation: cf-pulse 1s infinite; }
813
+
814
+ .cf-iconbtn.is-active { background: var(--cf-surface-2); color: var(--cf-accent); }
815
+ .cf-gif-label { font-size: 11px; font-weight: 800; letter-spacing: 0.5px; }
816
+
817
+ /* ---------- Emoji + GIF pickers ---------- */
818
+ .cf-composer { position: relative; }
819
+ .cf-picker {
820
+ position: absolute;
821
+ left: 8px;
822
+ right: 8px;
823
+ bottom: calc(100% - 4px);
824
+ background: var(--cf-bg);
825
+ border: 1px solid var(--cf-border);
826
+ border-radius: 14px;
827
+ box-shadow: var(--cf-shadow);
828
+ overflow: hidden;
829
+ animation: cf-msg-in 0.18s ease both;
830
+ z-index: 2;
831
+ }
832
+ .cf-emoji { max-height: 260px; overflow-y: auto; padding: 8px 10px 10px; }
833
+ .cf-emoji__label {
834
+ font-size: 11px;
835
+ font-weight: 700;
836
+ text-transform: uppercase;
837
+ letter-spacing: 0.5px;
838
+ color: var(--cf-muted);
839
+ margin: 8px 2px 4px;
840
+ }
841
+ .cf-emoji__grid { display: grid; grid-template-columns: repeat(8, 1fr); gap: 2px; }
842
+ .cf-emoji__btn {
843
+ font-size: 21px;
844
+ line-height: 1;
845
+ height: 34px;
846
+ border-radius: 8px;
847
+ transition: background 0.12s ease, transform 0.08s ease;
848
+ }
849
+ .cf-emoji__btn:hover { background: var(--cf-surface); }
850
+ .cf-emoji__btn:active { transform: scale(0.9); }
851
+
852
+ .cf-gif { display: flex; flex-direction: column; max-height: 320px; }
853
+ .cf-gif__search {
854
+ margin: 10px 10px 8px;
855
+ padding: 9px 12px;
856
+ border: 1.5px solid var(--cf-border);
857
+ border-radius: 10px;
858
+ background: var(--cf-surface);
859
+ color: var(--cf-text);
860
+ font-family: inherit;
861
+ font-size: 14px;
862
+ outline: none;
863
+ }
864
+ .cf-gif__search:focus { border-color: var(--cf-accent); }
865
+ .cf-gif__search::placeholder { color: var(--cf-muted); }
866
+ .cf-gif__grid {
867
+ flex: 1;
868
+ overflow-y: auto;
869
+ display: grid;
870
+ grid-template-columns: 1fr 1fr;
871
+ gap: 6px;
872
+ padding: 0 10px 8px;
873
+ align-content: start;
874
+ }
875
+ .cf-gif__item {
876
+ border-radius: 10px;
877
+ overflow: hidden;
878
+ background: var(--cf-surface);
879
+ aspect-ratio: 1 / 1;
880
+ transition: transform 0.1s ease, box-shadow 0.12s ease;
881
+ }
882
+ .cf-gif__item:hover { transform: scale(1.03); box-shadow: 0 0 0 2px var(--cf-accent); }
883
+ .cf-gif__item img { width: 100%; height: 100%; object-fit: cover; display: block; }
884
+ .cf-gif__hint { grid-column: 1 / -1; text-align: center; color: var(--cf-muted); font-size: 13px; padding: 24px 0; }
885
+ .cf-gif__powered { text-align: right; font-size: 10px; color: var(--cf-muted); padding: 0 12px 8px; }
886
+
887
+ /* Inline media (GIF) in a message bubble. */
888
+ .cf-msg__bubble--media { padding: 4px; background: var(--cf-surface); overflow: hidden; }
889
+ .cf-msg--user .cf-msg__bubble--media { background: var(--cf-surface-2); }
890
+ .cf-msg__media { display: block; max-width: 200px; width: 100%; border-radius: 12px; }
891
+ .cf-msg__caption { display: block; padding: 4px 6px 2px; font-size: 14px; }
892
+
893
+ .cf-footer {
894
+ text-align: center;
895
+ padding: 7px 0 9px;
896
+ font-size: 11px;
897
+ color: var(--cf-muted);
898
+ }
899
+ .cf-footer a { color: var(--cf-muted); text-decoration: none; font-weight: 600; }
900
+ .cf-footer a:hover { color: var(--cf-accent); }
901
+
902
+ /* ---------- Welcome intro (token branding) ---------- */
903
+ .cf-welcome { text-align: center; padding: 2px 14px 4px; }
904
+ .cf-welcome__desc { margin: 0 0 4px; font-size: 14px; font-weight: 600; color: var(--cf-text); }
905
+ .cf-welcome__sub { margin: 0; font-size: 12.5px; color: var(--cf-muted); }
906
+
907
+ /* Offline presence dot (amber instead of green). */
908
+ .cf-header__status--offline::before { background: #e2c07e; box-shadow: 0 0 0 2px rgba(226, 192, 126, 0.3); }
909
+
910
+ /* Disclaimer fine-print under the composer. */
911
+ .cf-disclaimer { padding: 0 16px 2px; font-size: 10.5px; line-height: 1.45; color: var(--cf-muted); text-align: center; }
912
+
913
+ /* Read-only banner shown while viewing a past conversation. */
914
+ .cf-viewing-banner {
915
+ padding: 7px 16px;
916
+ font-size: 12px;
917
+ font-weight: 600;
918
+ text-align: center;
919
+ color: var(--cf-muted);
920
+ background: var(--cf-surface);
921
+ border-bottom: 1px solid var(--cf-border);
922
+ flex-shrink: 0;
923
+ }
924
+
925
+ /* Past-conversations history panel (over the chat, like the confirm dialog). */
926
+ .cf-history {
927
+ width: min(340px, 90%);
928
+ max-height: 70%;
929
+ display: flex;
930
+ flex-direction: column;
931
+ background: var(--cf-bg);
932
+ border-radius: 14px;
933
+ box-shadow: var(--cf-shadow);
934
+ overflow: hidden;
935
+ }
936
+ .cf-history__head {
937
+ display: flex;
938
+ align-items: center;
939
+ justify-content: space-between;
940
+ padding: 12px 14px;
941
+ font-size: 14px;
942
+ font-weight: 700;
943
+ color: var(--cf-text);
944
+ border-bottom: 1px solid var(--cf-border);
945
+ }
946
+ .cf-history__list { overflow-y: auto; padding: 6px; }
947
+ .cf-history__item {
948
+ display: flex;
949
+ flex-direction: column;
950
+ gap: 2px;
951
+ width: 100%;
952
+ text-align: left;
953
+ padding: 9px 10px;
954
+ border-radius: 9px;
955
+ cursor: pointer;
956
+ transition: background 0.15s ease;
957
+ }
958
+ .cf-history__item:hover { background: var(--cf-surface); }
959
+ .cf-history__item.is-active { background: var(--cf-surface); }
960
+ .cf-history__title { font-size: 13px; color: var(--cf-text); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
961
+ .cf-history__meta { font-size: 11px; color: var(--cf-muted); }
962
+
963
+ /* Ended-conversation bar โ€” replaces the composer once the chat is closed. */
964
+ .cf-ended {
965
+ display: flex;
966
+ flex-direction: column;
967
+ align-items: center;
968
+ gap: 10px;
969
+ padding: 14px 16px 16px;
970
+ flex-shrink: 0;
971
+ text-align: center;
972
+ }
973
+ .cf-ended__text { margin: 0; font-size: 12.5px; line-height: 1.45; color: var(--cf-muted); }
974
+ .cf-csat { display: inline-flex; align-items: center; gap: 8px; }
975
+ .cf-csat__q { font-size: 12.5px; color: var(--cf-muted); }
976
+ .cf-csat__btn {
977
+ display: inline-flex;
978
+ align-items: center;
979
+ justify-content: center;
980
+ width: 30px;
981
+ height: 30px;
982
+ border-radius: 8px;
983
+ color: var(--cf-muted);
984
+ cursor: pointer;
985
+ transition: background 0.15s ease, color 0.15s ease;
986
+ }
987
+ .cf-csat__btn:hover { background: var(--cf-surface); color: var(--cf-accent); }
988
+ .cf-csat__btn svg { width: 16px; height: 16px; }
989
+ .cf-ended__btn {
990
+ font-size: 13px;
991
+ font-weight: 600;
992
+ color: var(--cf-accent-ink);
993
+ background: var(--cf-accent);
994
+ border: none;
995
+ border-radius: 999px;
996
+ padding: 9px 18px;
997
+ cursor: pointer;
998
+ transition: opacity 0.15s ease;
999
+ }
1000
+ .cf-ended__btn:hover { opacity: 0.9; }
1001
+ .cf-ended__btn:focus-visible { outline: 2px solid var(--cf-accent); outline-offset: 2px; }
1002
+
1003
+ /* "โ†“ New messages" pill โ€” shown when a reply streams in while scrolled up. */
1004
+ .cf-newmsg {
1005
+ /* Sticky inside the scroll body: pins to the bottom of the visible thread,
1006
+ just above the composer (never overlapping it). Horizontal centering via
1007
+ align-self so it doesn't fight the entrance animation's transform. */
1008
+ position: sticky;
1009
+ bottom: 10px;
1010
+ align-self: center;
1011
+ z-index: 3;
1012
+ pointer-events: auto;
1013
+ display: inline-flex;
1014
+ align-items: center;
1015
+ gap: 6px;
1016
+ font-size: 12.5px;
1017
+ font-weight: 600;
1018
+ color: var(--cf-accent-ink);
1019
+ background: linear-gradient(135deg, var(--cf-accent, #2f7f55) 0%, var(--cf-accent-2, #2f7de8) 160%);
1020
+ border-radius: 999px;
1021
+ padding: 7px 14px;
1022
+ box-shadow: var(--cf-shadow);
1023
+ animation: cf-msg-in 0.2s ease both;
1024
+ }
1025
+ .cf-newmsg svg { width: 14px; height: 14px; }
1026
+
1027
+ /* ---------- Clear-chat confirm dialog (in-widget, replaces window.confirm) ---------- */
1028
+ .cf-confirm {
1029
+ position: absolute;
1030
+ inset: 0;
1031
+ z-index: 6;
1032
+ pointer-events: auto;
1033
+ display: grid;
1034
+ place-items: center;
1035
+ padding: 22px;
1036
+ background: color-mix(in oklab, var(--cf-bg) 62%, transparent);
1037
+ backdrop-filter: blur(2px);
1038
+ animation: cf-fade-in 0.14s ease both;
1039
+ }
1040
+ .cf-confirm__card {
1041
+ width: 100%;
1042
+ max-width: 300px;
1043
+ background: var(--cf-bg);
1044
+ border: 1px solid var(--cf-border);
1045
+ border-radius: 16px;
1046
+ box-shadow: var(--cf-shadow);
1047
+ padding: 18px;
1048
+ text-align: center;
1049
+ animation: cf-msg-in 0.18s cubic-bezier(0.22, 1, 0.36, 1) both;
1050
+ }
1051
+ .cf-confirm__title { font-size: 15px; font-weight: 700; color: var(--cf-text); }
1052
+ .cf-confirm__body { margin-top: 6px; font-size: 13px; line-height: 1.45; color: var(--cf-muted); }
1053
+ .cf-confirm__actions { margin-top: 16px; display: flex; gap: 8px; justify-content: center; }
1054
+ .cf-confirm__btn {
1055
+ padding: 9px 16px;
1056
+ border-radius: 10px;
1057
+ font-size: 13.5px;
1058
+ font-weight: 600;
1059
+ transition: transform 0.1s ease, opacity 0.15s ease, border-color 0.15s ease, background 0.15s ease;
1060
+ }
1061
+ .cf-confirm__btn:active { transform: scale(0.97); }
1062
+ .cf-confirm__btn:focus-visible { outline: 2px solid var(--cf-accent-2); outline-offset: 2px; }
1063
+ .cf-confirm__btn--cancel { background: var(--cf-surface); color: var(--cf-text); border: 1px solid var(--cf-border); }
1064
+ .cf-confirm__btn--cancel:hover { border-color: var(--cf-accent); }
1065
+ .cf-confirm__btn--danger { background: #f25767; color: #fff; }
1066
+ .cf-confirm__btn--danger:hover { opacity: 0.9; }
1067
+
1068
+ /* Visually-hidden live region (announces the final answer only). */
1069
+ .cf-sr-live {
1070
+ position: absolute;
1071
+ width: 1px;
1072
+ height: 1px;
1073
+ padding: 0;
1074
+ margin: -1px;
1075
+ overflow: hidden;
1076
+ clip: rect(0 0 0 0);
1077
+ white-space: nowrap;
1078
+ border: 0;
1079
+ }
1080
+
1081
+ /* ---------- Attachments ---------- */
1082
+ .cf-file-input { display: none; }
1083
+ .cf-iconbtn:disabled { opacity: 0.4; cursor: default; }
1084
+ .cf-attach-row { padding: 0 4px 8px; }
1085
+ .cf-attach-status { font-size: 12px; color: var(--cf-muted); }
1086
+ .cf-attach-status--err { color: #f25767; }
1087
+ .cf-attach-chip {
1088
+ display: inline-flex;
1089
+ align-items: center;
1090
+ gap: 6px;
1091
+ max-width: 100%;
1092
+ padding: 5px 6px 5px 10px;
1093
+ border-radius: 999px;
1094
+ background: var(--cf-surface-2);
1095
+ border: 1px solid var(--cf-border);
1096
+ color: var(--cf-text);
1097
+ font-size: 12px;
1098
+ }
1099
+ .cf-attach-chip > span { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
1100
+ .cf-attach-chip svg { width: 13px; height: 13px; flex-shrink: 0; color: var(--cf-muted); }
1101
+ .cf-attach-x { display: grid; place-items: center; width: 18px; height: 18px; border-radius: 50%; color: var(--cf-muted); flex-shrink: 0; }
1102
+ .cf-attach-x:hover { background: var(--cf-surface); color: var(--cf-text); }
1103
+ .cf-attach-x svg { width: 11px; height: 11px; }
1104
+
1105
+ /* ---------- Mobile: full-screen panel ---------- */
1106
+ @media (max-width: 480px) {
1107
+ .cf-panel {
1108
+ bottom: 0;
1109
+ right: 0;
1110
+ width: 100vw;
1111
+ max-width: 100vw;
1112
+ height: 100dvh;
1113
+ max-height: 100dvh;
1114
+ border-radius: 0;
1115
+ }
1116
+ .cf-launcher { bottom: 16px; right: 16px; }
1117
+ }
1118
+
1119
+ /* ---------- Keyframes ---------- */
1120
+ @keyframes cf-pop {
1121
+ from { transform: scale(0); opacity: 0; }
1122
+ to { transform: scale(1); opacity: 1; }
1123
+ }
1124
+ @keyframes cf-badge-pop {
1125
+ from { transform: scale(0); }
1126
+ to { transform: scale(1); }
1127
+ }
1128
+ @keyframes cf-msg-in {
1129
+ from { opacity: 0; transform: translateY(8px); }
1130
+ to { opacity: 1; transform: none; }
1131
+ }
1132
+ @keyframes cf-fade-in {
1133
+ from { opacity: 0; }
1134
+ to { opacity: 1; }
1135
+ }
1136
+ @keyframes cf-typing {
1137
+ 0%, 80%, 100% { opacity: 0.35; transform: translateY(0); }
1138
+ 40% { opacity: 1; transform: translateY(-4px); }
1139
+ }
1140
+ @keyframes cf-pulse {
1141
+ 0%, 100% { opacity: 1; }
1142
+ 50% { opacity: 0.4; }
1143
+ }
1144
+
1145
+ @media (prefers-reduced-motion: reduce) {
1146
+ .cf-root *, .cf-root *::before, .cf-root *::after {
1147
+ animation-duration: 0.01ms !important;
1148
+ animation-iteration-count: 1 !important;
1149
+ transition-duration: 0.01ms !important;
1150
+ scroll-behavior: auto !important;
1151
+ }
1152
+ }
1153
+ `;function ct(e){"@babel/helpers - typeof";return ct=typeof Symbol==`function`&&typeof Symbol.iterator==`symbol`?function(e){return typeof e}:function(e){return e&&typeof Symbol==`function`&&e.constructor===Symbol&&e!==Symbol.prototype?`symbol`:typeof e},ct(e)}function lt(e,t){if(ct(e)!=`object`||!e)return e;var n=e[Symbol.toPrimitive];if(n!==void 0){var r=n.call(e,t||`default`);if(ct(r)!=`object`)return r;throw TypeError(`@@toPrimitive must return a primitive value.`)}return(t===`string`?String:Number)(e)}function ut(e){var t=lt(e,`string`);return ct(t)==`symbol`?t:t+``}function dt(e,t,n){return(t=ut(t))in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}const ft=`centrinfo-widget`;var pt=class extends HTMLElement{constructor(...e){super(...e),dt(this,`controls`,null)}mountWith(t){let r=ot(t),i=this.shadowRoot??this.attachShadow({mode:`open`});if(`adoptedStyleSheets`in Document.prototype&&typeof CSSStyleSheet<`u`){let e=new CSSStyleSheet;e.replaceSync(st),i.adoptedStyleSheets=[e]}else{let e=document.createElement(`style`);e.textContent=st,i.appendChild(e)}(0,e.render)((0,n.jsx)(it,{transport:r.demo?new h:r.preview?new x(new a(r.apiBaseUrl,r.token,r.gifApiKey),r.strings):new a(r.apiBaseUrl,r.token,r.gifApiKey),config:r,bindControls:e=>this.controls=e}),i)}open(){this.controls?.open()}close(){this.controls?.close()}toggle(){this.controls?.toggle()}identify(e){this.controls?.identify(e)}clear(){this.controls?.startNew()}shutdown(){this.controls?.shutdown()}unmount(){this.shadowRoot&&(0,e.render)(null,this.shadowRoot)}};typeof customElements<`u`&&!customElements.get(ft)&&customElements.define(ft,pt);const mt=e=>{if(typeof document>`u`)throw Error(`[centrinfo-widget] createWidget must run in a browser.`);let t=document.createElement(ft);return t.style.pointerEvents=`none`,t.style.position=`fixed`,t.style.inset=`0`,t.style.width=`0`,t.style.height=`0`,document.body.appendChild(t),t.mountWith(e),{open:()=>t.open(),close:()=>t.close(),toggle:()=>t.toggle(),show:()=>t.open(),hide:()=>t.close(),identify:e=>t.identify(e),update:e=>t.identify(e),clear:()=>t.clear(),shutdown:()=>t.shutdown(),logout:()=>t.shutdown(),destroy:()=>{t.unmount(),t.remove()}}};let ht=null;const gt=e=>(ht?.destroy(),ht=mt(e),ht),_t={init:gt,createWidget:mt};exports.Centrinfo=_t,exports.createWidget=mt,exports.init=gt;