@skywu/virtual-chat-sdk 2.3.5 → 2.4.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/chat-sdk.esm.js +1 -1
- package/dist/chat-sdk.umd.js +1 -1
- package/dist/types/simulation/chat-simulator.d.ts.map +1 -1
- package/dist/types/types.d.ts +4 -2
- package/dist/types/types.d.ts.map +1 -1
- package/dist/types/ui/chat-widget.d.ts +5 -0
- package/dist/types/ui/chat-widget.d.ts.map +1 -1
- package/package.json +1 -1
package/dist/chat-sdk.esm.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
class e extends Error{constructor(e,t,s){super(e),this.code=t,this.details=s,this.name="ChatSDKError"}}class t{constructor(){this.events=new Map}on(e,t){this.events.has(e)||this.events.set(e,[]),this.events.get(e).push(t)}off(e,t){if(!this.events.has(e))return;if(!t)return void this.events.delete(e);const s=this.events.get(e),n=s.indexOf(t);n>-1&&s.splice(n,1),0===s.length&&this.events.delete(e)}emit(e,t){if(!this.events.has(e))return;this.events.get(e).forEach(s=>{try{s(t)}catch(t){console.error(`Error in event callback for "${e}":`,t)}})}getEventNames(){return Array.from(this.events.keys())}listenerCount(e){var t;return(null===(t=this.events.get(e))||void 0===t?void 0:t.length)||0}removeAllListeners(){this.events.clear()}}function s(e,t,s){const n=document.createElement(e);return t&&(n.className=t),n}function n(e){const t=document.createElement("div");return t.textContent=e,t.innerHTML}function a(e,t=!0){e.scrollTop=e.scrollHeight,e.scrollTo&&e.scrollTo({top:e.scrollHeight,behavior:t?"smooth":"auto"})}const i={USD:1,EUR:.92,GBP:.79,JPY:149.5,CNY:7.24,INR:83.12,BRL:4.97,RUB:92.5,KRW:1320,MXN:17.15,CAD:1.38,AUD:1.53,CHF:.88,SEK:10.85,NZD:1.67,SGD:1.34,HKD:7.82,NOK:10.95,TRY:28.5,ZAR:18.65,PLN:4.05,THB:35.2,IDR:15650,MYR:4.68,PHP:56.2,DKK:6.88,CZK:22.85,HUF:355,ILS:3.72,CLP:920,ARS:350,COP:4050,PEN:3.75,EGP:30.9,SAR:3.75,AED:3.67,VND:24500,PKR:278,BDT:110,NGN:775,UAH:36.5,RON:4.58,TWD:31.5,QAR:3.64,KWD:.31,OMR:.38,BHD:.38},o={USD:"$",EUR:"€",GBP:"£",JPY:"¥",CNY:"¥",INR:"₹",BRL:"R$",RUB:"₽",KRW:"₩",MXN:"$",CAD:"C$",AUD:"A$",CHF:"CHF",SEK:"kr",NZD:"NZ$",SGD:"S$",HKD:"HK$",NOK:"kr",TRY:"₺",ZAR:"R",PLN:"zł",THB:"฿",IDR:"Rp",MYR:"RM",PHP:"₱",DKK:"kr",CZK:"Kč",HUF:"Ft",ILS:"₪",CLP:"$",ARS:"$",COP:"$",PEN:"S/",EGP:"E£",SAR:"﷼",AED:"د.إ",VND:"₫",PKR:"₨",BDT:"৳",NGN:"₦",UAH:"₴",RON:"lei",TWD:"NT$",QAR:"﷼",KWD:"د.ك",OMR:"﷼",BHD:"د.ب"},r={USD:",",EUR:".",GBP:",",JPY:",",CNY:",",INR:",",BRL:".",RUB:" ",KRW:",",MXN:",",CAD:",",AUD:",",CHF:"'",SEK:" ",PLN:" ",THB:",",IDR:".",MYR:",",PHP:",",DKK:".",CZK:" ",HUF:" "},d={USD:".",EUR:",",GBP:".",JPY:".",CNY:".",INR:".",BRL:",",RUB:",",KRW:".",MXN:".",CAD:".",AUD:".",CHF:".",SEK:",",PLN:",",THB:".",IDR:",",MYR:".",PHP:".",DKK:",",CZK:",",HUF:","},l={US:"USD",CA:"CAD",MX:"MXN",BR:"BRL",AR:"ARS",CL:"CLP",CO:"COP",PE:"PEN",GB:"GBP",DE:"EUR",FR:"EUR",IT:"EUR",ES:"EUR",NL:"EUR",BE:"EUR",AT:"EUR",PT:"EUR",IE:"EUR",GR:"EUR",FI:"EUR",CH:"CHF",NO:"NOK",SE:"SEK",DK:"DKK",PL:"PLN",CZ:"CZK",HU:"HUF",RO:"RON",RU:"RUB",UA:"UAH",TR:"TRY",IL:"ILS",SA:"SAR",AE:"AED",EG:"EGP",CN:"CNY",JP:"JPY",KR:"KRW",IN:"INR",ID:"IDR",TH:"THB",VN:"VND",MY:"MYR",SG:"SGD",PH:"PHP",PK:"PKR",BD:"BDT",HK:"HKD",TW:"TWD",AU:"AUD",NZ:"NZD",ZA:"ZAR",NG:"NGN",KE:"KES",QA:"QAR",KW:"KWD",OM:"OMR",BH:"BHD"},h=new Set(["JPY","KRW","IDR","VND","CLP","PYG","UGX"]);function c(e,t){if(!e||!t)return e;const s=function(e){return l[e.toUpperCase()]||"USD"}(t);return e.replace(/\{\{AMOUNT:(\d+(?:\.\d+)?)\}\}/g,(e,t)=>{const n=parseFloat(t);return isNaN(n)?e:function(e,t){var s,n,a,l;const c=null!==(s=i[t])&&void 0!==s?s:1,m=null!==(n=o[t])&&void 0!==n?n:t+" ",g=null!==(a=r[t])&&void 0!==a?a:",",u=null!==(l=d[t])&&void 0!==l?l:".",p=h.has(t),y=e*c,b=p?Math.round(y):Math.round(100*y)/100,f=Math.floor(b).toString().replace(/\B(?=(\d{3})+(?!\d))/g,g);return p?`${m}${f}`:`${m}${f}${u}${(b%1).toFixed(2).slice(2)}`}(n,s)})}class m extends t{constructor(e,t){super(),this.simulationData=null,this.displayedMessages=[],this.currentMessageIndex=0,this.isRunning=!1,this.isPaused=!1,this.intervalId=null,this.pollingId=null,this.burstPhase=!0,this.totalToShow=1/0,this.virtualLastTimestamp=null,this.realLastTimestamp=null,this.lastTimestamp=null,this.lastDelayMs=0,this.userId="",this.config=e,this.apiClient=t,this.pollingIntervalMs="number"==typeof e.pollingInterval&&e.pollingInterval>0?e.pollingInterval:6e3}async initialize(){try{const e=this.config.language||"en",t=(this.config.country||"US").toUpperCase(),s=this.getPersistedUserId(),n=s||this.config.userId||this.generateUserId();this.userId=n,s||this.persistUserId(n);const a=await this.apiClient.getSimulationData(this.config.projectId,n,e,t);if(!a.success||!a.data)throw new Error("Failed to load simulation data");this.simulationData=a.data;const i=this.simulationData.project.initialBurstCount+this.simulationData.project.continuousCount;this.totalToShow=Math.min(i,this.simulationData.messages.length);const o=this.loadProgress();o&&"number"==typeof o.index?(this.currentMessageIndex=o.index,o.lastTimestamp&&(this.virtualLastTimestamp=new Date(o.lastTimestamp),this.lastTimestamp=new Date(o.lastTimestamp))):(this.currentMessageIndex=0,this.virtualLastTimestamp=null,this.lastTimestamp=null),this.realLastTimestamp=null,await this.loadExistingMessages(),await this.reconstructVirtualHistoryForDisplay(),this.emit("initialized",this.simulationData),this.startPolling(),!1!==this.config.autoStart&&this.start()}catch(e){throw this.emit("error",e),e}}start(){this.simulationData&&!this.isRunning&&(this.isRunning=!0,this.isPaused=!1,this.burstPhase=!0,this.emit("simulationStart"),this.performInitialBurst(),this.currentMessageIndex<this.totalToShow?(this.burstPhase=!1,this.scheduleNextMessage()):(this.isRunning=!1,this.emit("simulationEnd")))}performInitialBurst(){if(!this.simulationData)return;const{project:e,messages:t}=this.simulationData,s=e.initialBurstCount,n=Math.min(s,this.totalToShow,t.length);if(this.currentMessageIndex>=n)return;if(this.displayedMessages.some(e=>e.id.startsWith("sim-"))&&this.currentMessageIndex>0)return;const a=new Date,i=new Array(n);let o=new Date(a);for(let e=n-1;e>=0;e--)if(i[e]=new Date(o),e>0){const e=10+Math.floor(11*Math.random());o=new Date(o.getTime()-60*e*1e3)}const r=[],d=(this.config.country||"US").toUpperCase();let l=!1;for(let e=this.currentMessageIndex;e<n;e++){const s=t[e],n=c(s.content,d);if(s.hasScreenshot&&s.screenshotUrl){const t={id:`sim-${e}-text-${Date.now()}`,content:n,messageType:"text",timestamp:i[e],isOwnMessage:!1,virtualUser:s.virtualUser};this.displayedMessages.push(t),r.push(t);const a=new Date(i[e].getTime()+2e3),o={id:`sim-${e}-image-${Date.now()}`,content:this.resolveImageUrl(s.screenshotUrl),messageType:"image",timestamp:a,isOwnMessage:!1,virtualUser:s.virtualUser};this.displayedMessages.push(o),r.push(o)}else{const t={id:`sim-${e}-${Date.now()}`,content:n,messageType:s.messageType,timestamp:i[e],isOwnMessage:!1,virtualUser:s.virtualUser};this.displayedMessages.push(t),r.push(t)}this.currentMessageIndex=e+1,l=!0}l&&(this.lastTimestamp=i[n-1],this.virtualLastTimestamp=this.lastTimestamp,this.displayedMessages.sort((e,t)=>e.timestamp.getTime()-t.timestamp.getTime()),this.emit("messages-batch",r)),this.saveProgress()}pause(){this.isRunning&&(this.isPaused=!0,this.intervalId&&(clearTimeout(this.intervalId),this.intervalId=null),this.emit("simulationPause"))}resume(){this.isRunning&&this.isPaused&&(this.isPaused=!1,this.scheduleNextMessage(),this.emit("simulationResume"))}stop(){this.isRunning=!1,this.isPaused=!1,this.intervalId&&(clearTimeout(this.intervalId),this.intervalId=null),this.emit("simulationStop")}destroy(){this.stop(),this.stopPolling(),this.removeAllListeners()}scheduleNextMessage(){if(!this.simulationData||!this.isRunning||this.isPaused)return;const{project:e,messages:t}=this.simulationData;if(this.currentMessageIndex>=this.totalToShow)return this.isRunning=!1,void this.emit("simulationEnd");let s;if(this.burstPhase){const n=Math.min(e.initialBurstCount,t.length);this.currentMessageIndex<n?s=500+1e3*Math.random():(this.burstPhase=!1,s=this.getRandomInterval(e.messageIntervalMin,e.messageIntervalMax))}else{const n=Math.min(e.initialBurstCount,t.length);s=this.currentMessageIndex-n<5?1e3*(e.initialMessageInterval||10):this.getRandomInterval(e.messageIntervalMin,e.messageIntervalMax)}this.lastDelayMs=s,this.intervalId=setTimeout(()=>{this.displayNextMessage(),this.scheduleNextMessage()},s)}displayNextMessage(){if(!this.simulationData||this.currentMessageIndex>=this.simulationData.messages.length)return;const e=this.simulationData.messages[this.currentMessageIndex],t=(this.config.country||"US").toUpperCase(),s=c(e.content,t),n=this.lastTimestamp||new Date,a=new Date(n.getTime()+(this.lastDelayMs||0));if(this.lastTimestamp=a,e.hasScreenshot&&e.screenshotUrl){const t={id:`sim-${this.currentMessageIndex}-text-${Date.now()}`,content:s,messageType:"text",timestamp:a,isOwnMessage:!1,virtualUser:e.virtualUser};this.displayedMessages.push(t),this.emit("message",t);const n=new Date(a.getTime()+2e3),i={id:`sim-${this.currentMessageIndex}-image-${Date.now()}`,content:this.resolveImageUrl(e.screenshotUrl),messageType:"image",timestamp:n,isOwnMessage:!1,virtualUser:e.virtualUser};this.displayedMessages.push(i),this.lastTimestamp=n,setTimeout(()=>{this.emit("message",i)},2e3)}else{const t={id:`sim-${this.currentMessageIndex}-${Date.now()}`,content:s,messageType:e.messageType,timestamp:a,isOwnMessage:!1,virtualUser:e.virtualUser};this.displayedMessages.push(t),this.emit("message",t)}this.currentMessageIndex++,this.saveProgress()}async loadExistingMessages(){if(this.simulationData)try{const e=this.userId||this.config.userId||this.generateUserId(),t=await this.apiClient.getSimulationMessages(this.config.projectId,e,void 0,100);if(t.success&&t.messages&&t.messages.length>0){const s=t.messages.sort((e,t)=>new Date(e.createdAt||e.timestamp).getTime()-new Date(t.createdAt||t.timestamp).getTime()),n=new Set(this.displayedMessages.map(e=>e.id));for(const t of s){if(n.has(t.id))continue;const s=(this.config.country||"US").toUpperCase(),a={id:t.id,content:c(t.content||"",s),messageType:t.messageType,timestamp:new Date(t.createdAt||t.timestamp),isOwnMessage:t.userId===e,virtualUser:t.virtualUser,user:t.userId===e?{id:e,username:this.config.username||"You"}:void 0};this.displayedMessages.push(a)}if(s.length>0){const e=s[s.length-1];this.realLastTimestamp=new Date(e.createdAt||e.timestamp)}this.displayedMessages.length>0&&this.emit("messages-batch",[...this.displayedMessages])}}catch(e){console.warn("Failed to load existing messages:",e)}}startPolling(){this.pollingId&&(clearInterval(this.pollingId),this.pollingId=null),this.pollingId=setInterval(async()=>{await this.pollForNewMessages()},this.pollingIntervalMs)}stopPolling(){this.pollingId&&(clearInterval(this.pollingId),this.pollingId=null)}setPollingInterval(e){!e||e<=0||(this.pollingIntervalMs=e,this.pollingId&&this.startPolling())}get isPolling(){return!!this.pollingId}async pollForNewMessages(){if(this.simulationData)try{const e=this.userId||this.config.userId||this.generateUserId(),t=this.getLastMessageTimestamp(),s=await this.apiClient.getSimulationMessages(this.config.projectId,e,t);if(s.success&&s.messages&&s.messages.length>0){const t=new Set(this.displayedMessages.map(e=>e.id));let n=null;for(const a of s.messages){if(t.has(a.id))continue;const s=new Date(a.createdAt),i=(this.config.country||"US").toUpperCase(),o={id:a.id,content:c(a.content||"",i),messageType:a.messageType,timestamp:s,isOwnMessage:a.userId===e,virtualUser:a.virtualUser,user:a.userId===e?{id:e,username:this.config.username||"You"}:void 0};(!n||s>n)&&(n=s),this.displayedMessages.push(o),this.emit("message",o)}n&&(this.realLastTimestamp=n)}}catch(e){console.warn("Polling error:",e)}}async reconstructVirtualHistoryForDisplay(){if(!this.simulationData)return;const e=Math.min(this.currentMessageIndex,this.totalToShow,this.simulationData.messages.length);if(e<=0)return;const t=this.loadProgress(),s=(null==t?void 0:t.virtualMessages)||[];if(s.length>0){const e=[],t=new Set(this.displayedMessages.map(e=>e.id)),n=(this.config.country||"US").toUpperCase();for(const a of s)if(!t.has(a.id)){if("image"===a.messageType){const e=a.content||"";if(!e.startsWith("http")&&!e.startsWith("/uploads")&&!e.startsWith("/api"))continue}const t={id:a.id,content:"image"===a.messageType?this.resolveImageUrl(c(a.content||"",n)):c(a.content||"",n),messageType:a.messageType,timestamp:new Date(a.timestamp),isOwnMessage:!1,virtualUser:a.virtualUser};e.push(t)}if(e.length>0){this.displayedMessages.push(...e),this.displayedMessages.sort((e,t)=>e.timestamp.getTime()-t.timestamp.getTime());const t=e[e.length-1];this.virtualLastTimestamp=t.timestamp,this.lastTimestamp=t.timestamp,this.emit("messages-batch",e)}return}const n=new Date,a=new Array(e);let i=new Date(n);for(let t=e-1;t>=0;t--)if(a[t]=new Date(i),t>0){const e=10+Math.floor(11*Math.random());i=new Date(i.getTime()-60*e*1e3)}const o=[],{messages:r}=this.simulationData,d=(this.config.country||"US").toUpperCase();for(let t=0;t<e;t++){const e=r[t],s=a[t],n=c(e.content,d);if(e.hasScreenshot&&e.screenshotUrl){const a={id:`sim-${t}-text`,content:n,messageType:"text",timestamp:s,isOwnMessage:!1,virtualUser:e.virtualUser},i={id:`sim-${t}-image`,content:this.resolveImageUrl(e.screenshotUrl),messageType:"image",timestamp:new Date(s.getTime()+2e3),isOwnMessage:!1,virtualUser:e.virtualUser};o.push(a,i)}else{const a={id:`sim-${t}`,content:n,messageType:e.messageType,timestamp:s,isOwnMessage:!1,virtualUser:e.virtualUser};o.push(a)}}const l=new Set(this.displayedMessages.map(e=>e.id)),h=o.filter(e=>!l.has(e.id));if(0===h.length)return;this.displayedMessages.push(...h),this.displayedMessages.sort((e,t)=>e.timestamp.getTime()-t.timestamp.getTime());const m=h[h.length-1];this.virtualLastTimestamp=m.timestamp,this.lastTimestamp=m.timestamp,this.emit("messages-batch",h)}getLastMessageTimestamp(){if(this.realLastTimestamp)return this.realLastTimestamp.toISOString()}getUserKey(){return`vcs:user:${this.config.projectId}`}getProgressKey(){const e=this.userId||this.config.userId||"anon";return`vcs:progress:${this.config.projectId}:${e}`}getPersistedUserId(){try{return"undefined"==typeof window?null:window.localStorage.getItem(this.getUserKey())}catch(e){return null}}persistUserId(e){try{if("undefined"==typeof window)return;window.localStorage.setItem(this.getUserKey(),e)}catch(e){}}loadProgress(){try{if("undefined"==typeof window)return null;const e=window.localStorage.getItem(this.getProgressKey());return e?JSON.parse(e):null}catch(e){return null}}saveProgress(){try{if("undefined"==typeof window)return;const e=this.displayedMessages.filter(e=>e.id.startsWith("sim-")).map(e=>({id:e.id,content:e.content,messageType:e.messageType,timestamp:e.timestamp.toISOString(),virtualUser:e.virtualUser})),t={index:this.currentMessageIndex,lastTimestamp:this.lastTimestamp?this.lastTimestamp.toISOString():void 0,virtualMessages:e};window.localStorage.setItem(this.getProgressKey(),JSON.stringify(t))}catch(e){}}clearProgress(){try{if("undefined"==typeof window)return;window.localStorage.removeItem(this.getProgressKey())}catch(e){}}clearCachedProgress(){this.clearProgress()}resolveImageUrl(e){if(!e)return"";if(e.startsWith("http://")||e.startsWith("https://"))return e;const t=(this.config.apiBaseUrl||"").replace(/\/$/,"");return t?`${t}${e}`:e}getRandomInterval(e,t){return 1e3*(e+Math.random()*(t-e))}generateUserId(){return`user-${Date.now()}-${Math.random().toString(36).substring(2,11)}`}get messages(){return[...this.displayedMessages]}get isSimulationRunning(){return this.isRunning}get isSimulationPaused(){return this.isPaused}get data(){return this.simulationData}async sendMessage(e,t="text"){if(!this.simulationData)throw new Error("Simulation not initialized");const s=this.userId||this.config.userId||this.generateUserId(),n=this.config.username||"User";try{if("image"===t||"string"==typeof e&&e.startsWith("data:image/"))return;await Promise.all([this.apiClient.sendUserMessage(this.config.projectId,s,n,e,t),this.apiClient.triggerAIReply(this.config.projectId,s,n,e,t)])}catch(e){throw this.emit("error",e),e}}}class g{constructor(e){this.baseUrl=e.apiBaseUrl||window.location.origin,this.token=e.token}async request(t,s={}){const n=`${this.baseUrl}${t}`,a={"Content-Type":"application/json",...s.headers};this.token&&(a.Authorization=`Bearer ${this.token}`);try{const t=await fetch(n,{...s,headers:a,credentials:"include"});if(!t.ok)throw new e(`API request failed: ${t.status} ${t.statusText}`,"API_ERROR",{status:t.status,statusText:t.statusText});const i=await t.json();if(!i.success&&i.error)throw new e(i.error,"API_ERROR",i);return i}catch(t){if(t instanceof e)throw t;throw new e(`Network error: ${t.message}`,"NETWORK_ERROR",t)}}async getProject(e){return this.request(`/api/projects/${e}`)}async getTemplate(e,t,s){const n=new URLSearchParams;t&&n.set("lang",t),s&&n.set("country",s);const a=n.toString()?`?${n.toString()}`:"";return this.request(`/api/templates/${e}${a}`)}async getProjectTemplates(e){return this.request(`/api/projects/${e}/templates`)}async sendMessage(e,t,s,n="text"){return this.request("/api/chat/message",{method:"POST",body:JSON.stringify({projectId:e,userId:t,content:s,messageType:n})})}async joinProject(e,t,s){return this.request("/api/chat/join",{method:"POST",body:JSON.stringify({projectId:e,userId:t,username:s})})}async leaveProject(e,t){return this.request("/api/chat/leave",{method:"POST",body:JSON.stringify({projectId:e,userId:t})})}async getSimulationData(e,t,s,n){const a=new URLSearchParams({userId:t});return s&&a.append("lang",s),n&&a.append("country",n),this.request(`/api/chat/simulation/${e}?${a.toString()}`)}async getSimulationMessages(e,t,s,n){const a=new URLSearchParams({userId:t});return s&&a.append("since",s),n&&a.append("limit",n.toString()),this.request(`/api/chat/simulation/${e}/messages?${a.toString()}`)}async sendUserMessage(e,t,s,n,a="text"){return this.request("/api/chat/send",{method:"POST",body:JSON.stringify({projectId:e,userId:t,username:s,content:n,messageType:a})})}async triggerAIReply(e,t,s,n,a="text"){return this.request("/api/chat/ai-reply",{method:"POST",body:JSON.stringify({projectId:e,userId:t,username:s,content:n,messageType:a})})}setToken(e){this.token=e}setBaseUrl(e){this.baseUrl=e}}const u={en:{joinChat:"Join Chat",chatGroup:"{name} Group",online:"{count} online",inputPlaceholder:"Type a message...",send:"Send",messages:"messages",today:"Today",yesterday:"Yesterday",networkError:"Network error",sendFailed:"Failed to send"},zh:{joinChat:"加入群聊",chatGroup:"{name}交流群",online:"{count} 人在线",inputPlaceholder:"输入消息...",send:"发送",messages:"条消息",today:"今天",yesterday:"昨天",networkError:"网络错误",sendFailed:"发送失败"},"zh-TW":{joinChat:"加入群聊",chatGroup:"{name}交流群",online:"{count} 人在線",inputPlaceholder:"輸入訊息...",send:"發送",messages:"條訊息",today:"今天",yesterday:"昨天",networkError:"網路錯誤",sendFailed:"發送失敗"},es:{joinChat:"Unirse al Chat",chatGroup:"Grupo {name}",online:"{count} en línea",inputPlaceholder:"Escribe un mensaje...",send:"Enviar",messages:"mensajes",today:"Hoy",yesterday:"Ayer",networkError:"Error de red",sendFailed:"Error al enviar"},hi:{joinChat:"चैट में शामिल हों",chatGroup:"{name} समूह",online:"{count} ऑनलाइन",inputPlaceholder:"संदेश लिखें...",send:"भेजें",messages:"संदेश",today:"आज",yesterday:"कल",networkError:"नेटवर्क त्रुटि",sendFailed:"भेजने में विफल"},ar:{joinChat:"انضم للدردشة",chatGroup:"مجموعة {name}",online:"{count} متصل",inputPlaceholder:"اكتب رسالة...",send:"إرسال",messages:"رسائل",today:"اليوم",yesterday:"أمس",networkError:"خطأ في الشبكة",sendFailed:"فشل الإرسال"},pt:{joinChat:"Entrar no Chat",chatGroup:"Grupo {name}",online:"{count} online",inputPlaceholder:"Digite uma mensagem...",send:"Enviar",messages:"mensagens",today:"Hoje",yesterday:"Ontem",networkError:"Erro de rede",sendFailed:"Falha ao enviar"},bn:{joinChat:"চ্যাটে যোগ দিন",chatGroup:"{name} গ্রুপ",online:"{count} অনলাইন",inputPlaceholder:"একটি বার্তা লিখুন...",send:"পাঠান",messages:"বার্তা",today:"আজ",yesterday:"গতকাল",networkError:"নেটওয়ার্ক ত্রুটি",sendFailed:"পাঠাতে ব্যর্থ"},ru:{joinChat:"Присоединиться",chatGroup:"Группа {name}",online:"{count} онлайн",inputPlaceholder:"Введите сообщение...",send:"Отправить",messages:"сообщений",today:"Сегодня",yesterday:"Вчера",networkError:"Ошибка сети",sendFailed:"Не удалось отправить"},ja:{joinChat:"チャットに参加",chatGroup:"{name}グループ",online:"{count} オンライン",inputPlaceholder:"メッセージを入力...",send:"送信",messages:"メッセージ",today:"今日",yesterday:"昨日",networkError:"ネットワークエラー",sendFailed:"送信失敗"},de:{joinChat:"Chat beitreten",chatGroup:"{name} Gruppe",online:"{count} online",inputPlaceholder:"Nachricht eingeben...",send:"Senden",messages:"Nachrichten",today:"Heute",yesterday:"Gestern",networkError:"Netzwerkfehler",sendFailed:"Senden fehlgeschlagen"},fr:{joinChat:"Rejoindre le Chat",chatGroup:"Groupe {name}",online:"{count} en ligne",inputPlaceholder:"Tapez un message...",send:"Envoyer",messages:"messages",today:"Aujourd'hui",yesterday:"Hier",networkError:"Erreur réseau",sendFailed:"Échec de l'envoi"},ko:{joinChat:"채팅 참여",chatGroup:"{name} 그룹",online:"{count} 온라인",inputPlaceholder:"메시지 입력...",send:"전송",messages:"메시지",today:"오늘",yesterday:"어제",networkError:"네트워크 오류",sendFailed:"전송 실패"},it:{joinChat:"Unisciti alla Chat",chatGroup:"Gruppo {name}",online:"{count} online",inputPlaceholder:"Scrivi un messaggio...",send:"Invia",messages:"messaggi",today:"Oggi",yesterday:"Ieri",networkError:"Errore di rete",sendFailed:"Invio fallito"},tr:{joinChat:"Sohbete Katıl",chatGroup:"{name} Grubu",online:"{count} çevrimiçi",inputPlaceholder:"Bir mesaj yazın...",send:"Gönder",messages:"mesaj",today:"Bugün",yesterday:"Dün",networkError:"Ağ hatası",sendFailed:"Gönderilemedi"},vi:{joinChat:"Tham gia Chat",chatGroup:"Nhóm {name}",online:"{count} trực tuyến",inputPlaceholder:"Nhập tin nhắn...",send:"Gửi",messages:"tin nhắn",today:"Hôm nay",yesterday:"Hôm qua",networkError:"Lỗi mạng",sendFailed:"Gửi thất bại"},pl:{joinChat:"Dołącz do Czatu",chatGroup:"Grupa {name}",online:"{count} online",inputPlaceholder:"Wpisz wiadomość...",send:"Wyślij",messages:"wiadomości",today:"Dziś",yesterday:"Wczoraj",networkError:"Błąd sieci",sendFailed:"Nie udało się wysłać"},th:{joinChat:"เข้าร่วมแชท",chatGroup:"กลุ่ม {name}",online:"{count} ออนไลน์",inputPlaceholder:"พิมพ์ข้อความ...",send:"ส่ง",messages:"ข้อความ",today:"วันนี้",yesterday:"เมื่อวาน",networkError:"ข้อผิดพลาดเครือข่าย",sendFailed:"ส่งไม่สำเร็จ"},nl:{joinChat:"Deelnemen aan Chat",chatGroup:"{name} Groep",online:"{count} online",inputPlaceholder:"Typ een bericht...",send:"Verzenden",messages:"berichten",today:"Vandaag",yesterday:"Gisteren",networkError:"Netwerkfout",sendFailed:"Verzenden mislukt"},id:{joinChat:"Gabung Chat",chatGroup:"Grup {name}",online:"{count} online",inputPlaceholder:"Ketik pesan...",send:"Kirim",messages:"pesan",today:"Hari ini",yesterday:"Kemarin",networkError:"Kesalahan jaringan",sendFailed:"Gagal mengirim"},ms:{joinChat:"Sertai Chat",chatGroup:"Kumpulan {name}",online:"{count} dalam talian",inputPlaceholder:"Taip mesej...",send:"Hantar",messages:"mesej",today:"Hari ini",yesterday:"Semalam",networkError:"Ralat rangkaian",sendFailed:"Gagal menghantar"},ur:{joinChat:"چیٹ میں شامل ہوں",chatGroup:"{name} گروپ",online:"{count} آن لائن",inputPlaceholder:"پیغام ٹائپ کریں...",send:"بھیجیں",messages:"پیغامات",today:"آج",yesterday:"کل",networkError:"نیٹ ورک کی خرابی",sendFailed:"بھیجنے میں ناکام"},te:{joinChat:"చాట్లో చేరండి",chatGroup:"{name} సమూహం",online:"{count} ఆన్లైన్",inputPlaceholder:"సందేశాన్ని టైప్ చేయండి...",send:"పంపండి",messages:"సందేశాలు",today:"నేడు",yesterday:"నిన్న",networkError:"నెట్వర్క్ లోపం",sendFailed:"పంపడం విఫలమైంది"},mr:{joinChat:"चॅटमध्ये सामील व्हा",chatGroup:"{name} गट",online:"{count} ऑनलाइन",inputPlaceholder:"संदेश टाइप करा...",send:"पाठवा",messages:"संदेश",today:"आज",yesterday:"काल",networkError:"नेटवर्क त्रुटी",sendFailed:"पाठविण्यात अयशस्वी"},ta:{joinChat:"அரட்டையில் சேரவும்",chatGroup:"{name} குழு",online:"{count} ஆன்லைன்",inputPlaceholder:"ஒரு செய்தியை தட்டச்சு செய்யவும்...",send:"அனுப்பு",messages:"செய்திகள்",today:"இன்று",yesterday:"நேற்று",networkError:"நெட்வொர்க் பிழை",sendFailed:"அனுப்ப முடியவில்லை"},fa:{joinChat:"پیوستن به چت",chatGroup:"گروه {name}",online:"{count} آنلاین",inputPlaceholder:"پیامی تایپ کنید...",send:"ارسال",messages:"پیامها",today:"امروز",yesterday:"دیروز",networkError:"خطای شبکه",sendFailed:"ارسال نشد"},uk:{joinChat:"Приєднатися до чату",chatGroup:"Група {name}",online:"{count} онлайн",inputPlaceholder:"Введіть повідомлення...",send:"Надіслати",messages:"повідомлень",today:"Сьогодні",yesterday:"Вчора",networkError:"Помилка мережі",sendFailed:"Не вдалося надіслати"},gu:{joinChat:"ચેટમાં જોડાઓ",chatGroup:"{name} જૂથ",online:"{count} ઓનલાઇન",inputPlaceholder:"સંદેશ લખો...",send:"મોકલો",messages:"સંદેશાઓ",today:"આજે",yesterday:"ગઈકાલે",networkError:"નેટવર્ક ભૂલ",sendFailed:"મોકલવામાં નિષ્ફળ"},ro:{joinChat:"Alătură-te chatului",chatGroup:"Grupul {name}",online:"{count} online",inputPlaceholder:"Scrie un mesaj...",send:"Trimite",messages:"mesaje",today:"Astăzi",yesterday:"Ieri",networkError:"Eroare de rețea",sendFailed:"Trimitere eșuată"},sv:{joinChat:"Gå med i chatt",chatGroup:"{name} grupp",online:"{count} online",inputPlaceholder:"Skriv ett meddelande...",send:"Skicka",messages:"meddelanden",today:"Idag",yesterday:"Igår",networkError:"Nätverksfel",sendFailed:"Det gick inte att skicka"},hu:{joinChat:"Csatlakozás a chathez",chatGroup:"{name} Csoport",online:"{count} online",inputPlaceholder:"Írjon egy üzenetet...",send:"Küldés",messages:"üzenet",today:"Ma",yesterday:"Tegnap",networkError:"Hálózati hiba",sendFailed:"Küldés sikertelen"},cs:{joinChat:"Připojit se k chatu",chatGroup:"Skupina {name}",online:"{count} online",inputPlaceholder:"Napište zprávu...",send:"Odeslat",messages:"zpráv",today:"Dnes",yesterday:"Včera",networkError:"Chyba sítě",sendFailed:"Odeslání selhalo"},el:{joinChat:"Εγγραφή στο Chat",chatGroup:"Ομάδα {name}",online:"{count} online",inputPlaceholder:"Πληκτρολογήστε ένα μήνυμα...",send:"Αποστολή",messages:"μηνύματα",today:"Σήμερα",yesterday:"Χθες",networkError:"Σφάλμα δικτύου",sendFailed:"Αποτυχία αποστολής"},da:{joinChat:"Deltag i chat",chatGroup:"{name} Gruppe",online:"{count} online",inputPlaceholder:"Skriv en besked...",send:"Send",messages:"beskeder",today:"I dag",yesterday:"I går",networkError:"Netværksfejl",sendFailed:"Kunne ikke sende"},fi:{joinChat:"Liity chattiin",chatGroup:"{name} Ryhmä",online:"{count} paikalla",inputPlaceholder:"Kirjoita viesti...",send:"Lähetä",messages:"viestiä",today:"Tänään",yesterday:"Eilen",networkError:"Verkkovirhe",sendFailed:"Lähetys epäonnistui"},no:{joinChat:"Bli med i chat",chatGroup:"{name} Gruppe",online:"{count} pålogget",inputPlaceholder:"Skriv en melding...",send:"Send",messages:"meldinger",today:"I dag",yesterday:"I går",networkError:"Nettverksfeil",sendFailed:"Sending mislyktes"},he:{joinChat:"הצטרף לצ'אט",chatGroup:"קבוצת {name}",online:"{count} מחוברים",inputPlaceholder:"הקלד הודעה...",send:"שלח",messages:"הודעות",today:"היום",yesterday:"אתמול",networkError:"שגיאת רשת",sendFailed:"השליחה נכשלה"},tl:{joinChat:"Sumali sa Chat",chatGroup:"Grupong {name}",online:"{count} online",inputPlaceholder:"Mag-type ng mensahe...",send:"Ipadala",messages:"mga mensahe",today:"Ngayon",yesterday:"Kahapon",networkError:"Error sa network",sendFailed:"Nabigong ipadala"},sw:{joinChat:"Jiunge na Gumzo",chatGroup:"Kundi la {name}",online:"{count} mtandaoni",inputPlaceholder:"Andika ujumbe...",send:"Tuma",messages:"jumbe",today:"Leo",yesterday:"Jana",networkError:"Tatizo la mtandao",sendFailed:"Imeshindwa kutuma"},"pt-BR":{joinChat:"Entrar no Chat",chatGroup:"Grupo {name}",online:"{count} online",inputPlaceholder:"Escreva uma mensagem...",send:"Enviar",messages:"mensagens",today:"Hoje",yesterday:"Ontem",networkError:"Erro de rede",sendFailed:"Falha ao enviar"}};function p(e){if(u[e])return u[e];const t=e.split("-")[0];return u[t]?u[t]:u.en}function y(e,t){return e.replace(/\{(\w+)\}/g,(e,s)=>void 0!==t[s]?String(t[s]):e)}class b extends t{constructor(e){var t,s;super(),this.emojiPanelOpen=!1,this.onlineCount=0,this.currentTheme="whatsapp",this.isDarkMode=!1,this.customColors={},this.visibleStartIndex=0,this.hasInitializedData=!1,this.pollingStopTimer=null,this.config={...e,mode:e.mode||"floating"},this.t=p(e.language||"en"),this.currentTheme="telegram"===e.uiTemplate?"telegram":"whatsapp",this.isDarkMode="dark"===e.theme,this.customColors={primary:e.primaryColor,background:e.backgroundColor},this.onlineCount=500+Math.floor(301*Math.random()),this.initialRenderCount=null!==(t=this.config.initialRenderCount)&&void 0!==t?t:Number.MAX_SAFE_INTEGER,this.lazyLoadBatchSize=null!==(s=this.config.lazyLoadBatchSize)&&void 0!==s?s:20,this.state={isInitialized:!1,isOpen:!1,isJoined:!1,isConnected:!1,isSimulationRunning:!1,isSimulationPaused:!1,messages:[],virtualUsers:[],realUsers:[],typingUsers:[],simulationEnded:!1,displayedMessageCount:0,unreadCount:0,lastReadMessageId:null},this.apiClient=new g(e),this.simulator=new m(e,this.apiClient),this.setupSimulatorEvents(),this.init()}init(){try{this.setupContainer(),this.createWidget(),"floating"===this.config.mode&&(this.widgetElement.style.display="none",this.createFloatingButton()),this.setupEventListeners(),this.setupImageViewer(),this.state.isInitialized=!0,this.emit("ready")}catch(t){this.emit("error",new e("Failed to initialize chat widget","WIDGET_INIT_ERROR",t))}}setupSimulatorEvents(){this.simulator.on("initialized",e=>{var t;this.state.currentProject=e.project,this.state.currentTemplate=e.template,null!=this.config.initialRenderCount?this.initialRenderCount=this.config.initialRenderCount:this.initialRenderCount=Number.MAX_SAFE_INTEGER,this.setTitle((null===(t=e.project)||void 0===t?void 0:t.name)||"Chat",`0 ${this.t.messages}`),this.setLoading(!1),this.emit("simulationInitialized",e)}),this.simulator.on("message",e=>{var t;this.setLoading(!1),this.addMessage(e),this.state.displayedMessageCount++;const s=(null===(t=this.state.currentProject)||void 0===t?void 0:t.name)||"Chat";this.setTitle(s,`${this.state.displayedMessageCount} ${this.t.messages}`)}),this.simulator.on("messages-batch",e=>{var t;this.setLoading(!1),this.addMessagesBulk(e),this.state.displayedMessageCount+=e.length;const s=(null===(t=this.state.currentProject)||void 0===t?void 0:t.name)||"Chat";this.setTitle(s,`${this.state.displayedMessageCount} ${this.t.messages}`),setTimeout(()=>{this.scrollToBottom(!0)},100)}),this.simulator.on("simulationStart",()=>{var e,t;this.state.isSimulationRunning=!0,this.state.isSimulationPaused=!1,null===(t=(e=this.config).onSimulationStart)||void 0===t||t.call(e)}),this.simulator.on("simulationEnd",()=>{var e,t;this.state.isSimulationRunning=!1,this.state.simulationEnded=!0,null===(t=(e=this.config).onSimulationEnd)||void 0===t||t.call(e)}),this.simulator.on("simulationPause",()=>{this.state.isSimulationPaused=!0}),this.simulator.on("simulationResume",()=>{this.state.isSimulationPaused=!1}),this.simulator.on("error",e=>{this.emit("error",e)})}async initializeSimulation(){try{await this.simulator.initialize()}catch(t){this.emit("error",new e("Failed to initialize simulation","SIMULATION_INIT_ERROR",t))}}setupContainer(){var t;const s=function(e){if("string"==typeof e)return document.querySelector(e)||document.body;return e||document.body}(this.config.container);if(!s)throw new e("Container element not found","CONTAINER_NOT_FOUND");const n=null===(t=s.tagName)||void 0===t?void 0:t.toUpperCase();if("BODY"===n||"HTML"===n){const e=document.createElement("div");e.className="chat-sdk-host",e.style.position="static",e.style.width="0",e.style.height="0",document.body.appendChild(e),this.container=e}else this.container=s;this.shadowRoot=this.container.attachShadow({mode:"closed"});const a=this.getDefaultStyles();!function(e,t){const s=document.createElement("style");s.textContent=t,e.appendChild(s)}(this.shadowRoot,a)}createWidget(){var e;if(this.widgetElement&&this.messagesContainer)return;this.widgetElement=s("div","chat-sdk-container");const t="telegram"===this.config.uiTemplate?"telegram":"whatsapp";this.currentTheme=t,this.widgetElement.classList.add(`${t}-theme`),"telegram"===t&&"dark"===this.config.theme&&(this.widgetElement.classList.add("dark"),this.isDarkMode=!0),this.widgetElement.style.position="fixed",this.widgetElement.style.top="0",this.widgetElement.style.left="0",this.widgetElement.style.width="100vw",this.widgetElement.style.height="100vh",this.widgetElement.style.zIndex=String(null!==(e=this.config.zIndex)&&void 0!==e?e:2147483e3),this.widgetElement.innerHTML=`\n <div class="chat-sdk-header">\n <div class="chat-sdk-header-left">\n <div class="chat-sdk-title" id="chat-title"></div>\n <div class="chat-sdk-subtitle" id="chat-subtitle"></div>\n </div>\n <button class="chat-sdk-close-btn" type="button">\n <svg width="20" height="20" viewBox="0 0 16 16" fill="currentColor">\n <path d="M8 7.293l2.146-2.147a.5.5 0 01.708.708L8.707 8l2.147 2.146a.5.5 0 01-.708.708L8 8.707l-2.146 2.147a.5.5 0 01-.708-.708L7.293 8 5.146 5.854a.5.5 0 01.708-.708L8 7.293z"/>\n </svg>\n </button>\n </div>\n\n <div class="chat-sdk-messages" id="messages-container">\n <div class="chat-sdk-loading">\n <div class="chat-sdk-spinner"></div>\n Loading chat...\n </div>\n </div>\n\n <div class="chat-sdk-input-area">\n <button class="chat-sdk-icon-btn chat-sdk-emoji-btn" type="button" id="emoji-button" aria-label="Emoji">\n <span>😊</span>\n </button>\n <button class="chat-sdk-icon-btn chat-sdk-image-btn" type="button" id="image-button" aria-label="Image">\n <svg width="16" height="16" viewBox="0 0 24 24" fill="currentColor"><path d="M21 19V5a2 2 0 0 0-2-2H5a2 2 0 0 0-2 2v14h18zM5 5h14v8l-3-3-4 5-3-4-4 4V5z"/></svg>\n </button>\n <textarea\n class="chat-sdk-input"\n placeholder="${this.t.inputPlaceholder}"\n rows="1"\n id="message-input"\n ></textarea>\n <input type="file" accept="image/*" id="image-input" style="display:none" />\n <button class="chat-sdk-send-btn" type="button" id="send-button" disabled>\n <svg width="16" height="16" viewBox="0 0 16 16" fill="currentColor">\n <path d="M15.854.146a.5.5 0 01.11.54l-5.819 14.547a.75.75 0 01-1.329.124l-3.178-4.995L.643 7.184a.75.75 0 01.124-1.33L15.314.037a.5.5 0 01.54.11z"/>\n </svg>\n </button>\n </div>\n <div class="chat-sdk-emoji-picker" id="emoji-picker" style="display:none">\n <div class="chat-sdk-emoji-grid">\n <button type="button" class="chat-sdk-emoji-item" data-emoji="😀">😀</button>\n <button type="button" class="chat-sdk-emoji-item" data-emoji="😁">😁</button>\n <button type="button" class="chat-sdk-emoji-item" data-emoji="😂">😂</button>\n <button type="button" class="chat-sdk-emoji-item" data-emoji="🤣">🤣</button>\n <button type="button" class="chat-sdk-emoji-item" data-emoji="😊">😊</button>\n <button type="button" class="chat-sdk-emoji-item" data-emoji="😍">😍</button>\n <button type="button" class="chat-sdk-emoji-item" data-emoji="😎">😎</button>\n <button type="button" class="chat-sdk-emoji-item" data-emoji="🤔">🤔</button>\n <button type="button" class="chat-sdk-emoji-item" data-emoji="👍">👍</button>\n <button type="button" class="chat-sdk-emoji-item" data-emoji="🙏">🙏</button>\n </div>\n </div>\n `,this.messagesContainer=this.widgetElement.querySelector("#messages-container"),this.inputElement=this.widgetElement.querySelector("#message-input"),this.sendButton=this.widgetElement.querySelector("#send-button"),this.emojiButton=this.widgetElement.querySelector("#emoji-button"),this.imageButton=this.widgetElement.querySelector("#image-button"),this.fileInput=this.widgetElement.querySelector("#image-input"),this.emojiPicker=this.widgetElement.querySelector("#emoji-picker"),this.shadowRoot.appendChild(this.widgetElement)}setupEventListeners(){var e,t,s,n;const a=this.widgetElement.querySelector(".chat-sdk-close-btn");null==a||a.addEventListener("click",()=>this.close()),this.messagesContainer.addEventListener("scroll",this.handleScrollLazyLoad.bind(this)),this.inputElement.addEventListener("input",this.handleInputChange.bind(this)),this.inputElement.addEventListener("keydown",this.handleKeyDown.bind(this)),this.sendButton.addEventListener("click",this.handleSendMessage.bind(this)),this.inputElement.addEventListener("input",this.autoResizeTextarea.bind(this)),null===(e=this.emojiButton)||void 0===e||e.addEventListener("click",e=>{e.preventDefault(),e.stopPropagation(),this.toggleEmojiPicker(!this.emojiPanelOpen)}),null===(t=this.emojiPicker)||void 0===t||t.addEventListener("click",e=>{const t=e.target.closest(".chat-sdk-emoji-item");if(t&&t.hasAttribute("data-emoji")){const e=t.getAttribute("data-emoji")||"";this.insertEmojiAtCursor(e),this.toggleEmojiPicker(!1)}}),this.shadowRoot.addEventListener("click",e=>{const t=e.target,s=t.closest("#emoji-picker"),n=t.closest("#emoji-button");s||n||this.toggleEmojiPicker(!1)}),null===(s=this.imageButton)||void 0===s||s.addEventListener("click",e=>{var t;e.preventDefault(),e.stopPropagation(),null===(t=this.fileInput)||void 0===t||t.click()}),null===(n=this.fileInput)||void 0===n||n.addEventListener("change",this.handleImageSelected.bind(this)),document.addEventListener("keydown",e=>{if("Escape"===e.key){const e=document.querySelector(".chat-sdk-viewer-overlay");if(e)return e.style.opacity="0",void setTimeout(()=>e.remove(),200);this.state.isOpen&&this.close()}})}openImageZoom(e){const t=document.querySelector(".chat-sdk-global-zoom-overlay");t&&t.remove();const s=document.createElement("div");s.className="chat-sdk-global-zoom-overlay",Object.assign(s.style,{position:"fixed",top:"0",left:"0",width:"100vw",height:"100vh",backgroundColor:"rgba(0, 0, 0, 0.85)",zIndex:"2147483647",display:"flex",justifyContent:"center",alignItems:"center",cursor:"zoom-out",backdropFilter:"blur(4px)",opacity:"0",transition:"opacity 0.2s ease-in-out"});const n=document.createElement("img");n.src=e,Object.assign(n.style,{maxWidth:"80%",maxHeight:"90%",width:"80%",objectFit:"contain",borderRadius:"8px",boxShadow:"0 4px 20px rgba(0,0,0,0.5)",transform:"scale(0.9)",transition:"transform 0.2s cubic-bezier(0.1, 0.9, 0.2, 1)"}),s.addEventListener("click",()=>{s.style.opacity="0",n.style.transform="scale(0.9)",setTimeout(()=>s.remove(),200)}),s.appendChild(n),document.body.appendChild(s),requestAnimationFrame(()=>{s.style.opacity="1",n.style.transform="scale(1)"})}createFloatingButton(){var e,t,s,n,a,i,o,r,d,l,h;if(!this.shadowRoot)return;const c=this.config.floatingButton||{},m=c.position||"bottom-right",g=String(null!==(t=null!==(e=c.zIndex)&&void 0!==e?e:this.config.zIndex)&&void 0!==t?t:2147483e3),u={top:null===(s=c.offset)||void 0===s?void 0:s.top,right:null===(n=c.offset)||void 0===n?void 0:n.right,bottom:null!==(i=null===(a=c.offset)||void 0===a?void 0:a.bottom)&&void 0!==i?i:20,left:null===(o=c.offset)||void 0===o?void 0:o.left},p=document.createElement("button");p.className="chat-sdk-floating-btn",p.setAttribute("aria-label","Open chat");const y=this.t.joinChat;p.innerHTML=`\n <div style="\n position: relative;\n width: 100%;\n height: 100%;\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n padding: 6px;\n ">\n \x3c!-- Group chat icon (users) --\x3e\n <svg width="28" height="28" viewBox="0 0 24 24" fill="currentColor" style="margin-bottom: 2px;">\n <path d="M16 11c1.66 0 2.99-1.34 2.99-3S17.66 5 16 5c-1.66 0-3 1.34-3 3s1.34 3 3 3zm-8 0c1.66 0 2.99-1.34 2.99-3S9.66 5 8 5C6.34 5 5 6.34 5 8s1.34 3 3 3zm0 2c-2.33 0-7 1.17-7 3.5V19h14v-2.5c0-2.33-4.67-3.5-7-3.5zm8 0c-.29 0-.62.02-.97.05 1.16.84 1.97 1.97 1.97 3.45V19h6v-2.5c0-2.33-4.67-3.5-7-3.5z"/>\n </svg>\n\n \x3c!-- Text overlay at bottom --\x3e\n <div style="\n font-size: 10px;\n font-weight: 600;\n color: rgba(255, 255, 255, 0.95);\n text-align: center;\n line-height: 1.2;\n letter-spacing: 0.3px;\n text-shadow: 0 1px 2px rgba(0,0,0,0.2);\n ">${y}</div>\n\n \x3c!-- Unread badge --\x3e\n <span class="chat-sdk-unread-badge" style="\n position: absolute;\n top: -6px;\n right: -6px;\n background: #ff4444;\n color: white;\n border-radius: 10px;\n min-width: 18px;\n height: 18px;\n display: none;\n align-items: center;\n justify-content: center;\n font-size: 10px;\n font-weight: 700;\n line-height: 1;\n border: 2px solid white;\n box-shadow: 0 2px 4px rgba(0,0,0,0.3);\n padding: 0 5px;\n "></span>\n </div>\n `,p.style.position="fixed",p.style.zIndex=g,p.style.width="60px",p.style.height="60px",p.style.borderRadius="50%",p.style.border="none",p.style.cursor="pointer",p.style.display="flex",p.style.alignItems="center",p.style.justifyContent="center",p.style.color="#fff",p.style.boxShadow="0 10px 24px rgba(0,0,0,0.25), inset 0 2px 4px rgba(255,255,255,0.15)",p.style.background="linear-gradient(145deg, #25D366 0%, #128C7E 100%)",p.style.transition="transform .15s ease, box-shadow .15s ease",p.style.overflow="visible",m.includes("bottom")?(p.style.bottom=(null!==(r=u.bottom)&&void 0!==r?r:20)+"px",p.style.top=""):(p.style.top=(null!==(d=u.top)&&void 0!==d?d:20)+"px",p.style.bottom=""),m.includes("right")?(p.style.right=(null!==(l=u.right)&&void 0!==l?l:20)+"px",p.style.left=""):(p.style.left=(null!==(h=u.left)&&void 0!==h?h:20)+"px",p.style.right=""),p.addEventListener("mouseenter",()=>{p.style.transform="scale(1.06)",p.style.boxShadow="0 14px 28px rgba(0,0,0,0.30), inset 0 2px 4px rgba(255,255,255,0.2)"}),p.addEventListener("mouseleave",()=>{p.style.transform="scale(1)",p.style.boxShadow="0 10px 24px rgba(0,0,0,0.25), inset 0 2px 4px rgba(255,255,255,0.15)"}),p.addEventListener("mousedown",()=>{p.style.transform="scale(0.95)"}),p.addEventListener("mouseup",()=>{p.style.transform="scale(1.05)",setTimeout(()=>p.style.transform="scale(1)",100)}),p.addEventListener("click",e=>{e.preventDefault(),this.open()}),this.shadowRoot.appendChild(p),this.floatingButtonEl=p}updateUnreadBadge(){if(!this.floatingButtonEl)return;const e=this.floatingButtonEl.querySelector(".chat-sdk-unread-badge");if(!e)return;const t=this.state.unreadCount;t>0?(e.textContent=t>99?"99+":t.toString(),e.style.display="flex"):e.style.display="none"}markAllAsRead(){if(this.state.messages.length>0){const e=this.state.messages[this.state.messages.length-1];this.state.lastReadMessageId=e.id}this.state.unreadCount=0,this.updateUnreadBadge()}incrementUnreadCount(){this.state.isOpen||(this.state.unreadCount++,this.updateUnreadBadge())}toggleEmojiPicker(e){const t=this.emojiPicker;if(!t)return;const s="boolean"==typeof e?e:"none"===t.style.display;t.style.display=s?"block":"none",this.emojiPanelOpen=s}insertEmojiAtCursor(e){const t=this.inputElement,s=t.selectionStart||0,n=t.selectionEnd||0,a=t.value.substring(0,s),i=t.value.substring(n);t.value=a+e+i;const o=s+e.length;t.setSelectionRange(o,o),t.focus(),this.handleInputChange(),this.autoResizeTextarea()}isEmojiOnly(e){const t=e.trim();if(!t)return!1;if(t.length>6)return!1;let s=!1;for(let e=0;e<t.length;){const n=t.codePointAt(e)||0;if(e+=n>65535?2:1,!(n>=126976))return!1;s=!0}return s}async handleImageSelected(){const t=this.fileInput;if(!t||!t.files||0===t.files.length)return;const s=t.files[0];try{const e=await this.resizeImageFile(s,1280,.85),n={id:`local-img-failed-${Date.now()}-${Math.random().toString(36).slice(2,8)}`,content:e,messageType:"image",timestamp:new Date,isOwnMessage:!0,user:{id:this.config.userId||"me",username:this.config.username||"You"},failed:!0};this.state.messages.push(n),this.renderMessage(n),this.scrollToBottom(!0),t.value=""}catch(t){console.error("Image processing failed",t),this.emit("error",new e("Image processing failed","IMAGE_PROCESS_ERROR",t))}}resizeImageFile(e,t=1280,s=.85){return new Promise((n,a)=>{const i=URL.createObjectURL(e),o=new Image;o.onload=()=>{let{width:e,height:r}=o;const d=Math.min(1,t/Math.max(e,r)),l=document.createElement("canvas");d<1&&(e=Math.round(e*d),r=Math.round(r*d)),l.width=e,l.height=r;const h=l.getContext("2d");if(!h)return URL.revokeObjectURL(i),void a(new Error("Canvas not supported"));h.drawImage(o,0,0,e,r);const c=l.toDataURL("image/jpeg",s);URL.revokeObjectURL(i),n(c)},o.onerror=e=>{URL.revokeObjectURL(i),a(e)},o.src=i})}handleInputChange(){const e=this.inputElement.value.trim().length>0,t=!1!==this.config.enableUserInput&&!1!==this.config.allowInput;this.sendButton.disabled=!e||!t,e&&t&&this.emit("typing")}handleKeyDown(e){"Enter"!==e.key||e.shiftKey||(e.preventDefault(),this.handleSendMessage())}async handleSendMessage(){const t=this.inputElement.value.trim();if(!t)return;if(!1===this.config.enableUserInput||!1===this.config.allowInput)return;const s=this.isEmojiOnly(t)?"emoji":"text",n={id:`local-${Date.now()}-${Math.random().toString(36).slice(2,8)}`,content:t,messageType:s,timestamp:new Date,isOwnMessage:!0,user:{id:this.config.userId||"me",username:this.config.username||"You"}};this.state.messages.push(n),this.renderMessage(n),this.scrollToBottom(!0),this.inputElement.value="",this.sendButton.disabled=!0,this.autoResizeTextarea(),this.simulator.sendMessage(t,s).catch(t=>{console.error("Failed to send message:",t),this.emit("error",new e("Failed to send message","SEND_MESSAGE_ERROR",t))})}autoResizeTextarea(){this.inputElement.style.height="auto",this.inputElement.style.height=Math.min(this.inputElement.scrollHeight,100)+"px"}open(){var e;if(this.state.isOpen)return;if(this.hasInitializedData)try{this.simulator.startPolling()}catch(e){}else this.hasInitializedData=!0,this.setLoading(!0),this.initializeSimulation().catch(e=>{console.error("Failed to initialize simulation on open:",e),this.setLoading(!1)});this.pollingStopTimer&&(clearTimeout(this.pollingStopTimer),this.pollingStopTimer=null),this.floatingButtonEl&&(this.floatingButtonEl.style.display="none"),this.widgetElement.style.opacity="0",this.widgetElement.style.display="flex",requestAnimationFrame(()=>{this.widgetElement.style.transition="opacity .2s ease",this.widgetElement.style.opacity="1"}),this.state.isOpen=!0,this.markAllAsRead(),this.emit("open");const t=(null===(e=this.state.currentProject)||void 0===e?void 0:e.name)||"Chat";this.setTitle(t,`${this.state.displayedMessageCount} ${this.t.messages}`),this.scrollToBottom(!0),requestAnimationFrame(()=>this.scrollToBottom(!0)),setTimeout(()=>this.scrollToBottom(!0),0)}close(){this.state.isOpen&&(this.widgetElement.style.transition="opacity .2s ease",this.widgetElement.style.opacity="0",setTimeout(()=>{this.widgetElement.style.display="none",this.floatingButtonEl&&(this.floatingButtonEl.style.display="flex")},200),this.state.isOpen=!1,this.pollingStopTimer&&clearTimeout(this.pollingStopTimer),this.pollingStopTimer=setTimeout(()=>{try{this.simulator.stopPolling()}catch(e){}this.pollingStopTimer=null},1e4),this.emit("close"))}setTitle(e,t){var s,n;const a=null===(s=this.widgetElement)||void 0===s?void 0:s.querySelector("#chat-title"),i=null===(n=this.widgetElement)||void 0===n?void 0:n.querySelector("#chat-subtitle"),o=y(this.t.chatGroup,{name:e||"Chat"});this.currentTheme,a&&(a.textContent=o),i&&(i.textContent=y(this.t.online,{count:this.onlineCount}),i.style.display="block")}buildMessageElement(e,t){const n=s("div","chat-sdk-message");e.isOwnMessage&&n.classList.add("own");const a=!!t&&this.shouldGroupWithPrev(t,e);a&&n.classList.add("grouped");let i=null;e.isOwnMessage||(i=this.createAvatar(e),a&&i&&(i.style.visibility="hidden"));const o=!e.isOwnMessage&&!a,r="whatsapp"===this.currentTheme,d="telegram"===this.currentTheme&&e.isOwnMessage,l=this.createMessageContent(e,o,r,d);return i&&n.appendChild(i),n.appendChild(l),n}shouldGroupWithPrev(e,t){var s,n,a,i,o,r,d;if(!1===this.config.groupMessages)return!1;const l=null!==(s=this.config.groupTimeThresholdSec)&&void 0!==s?s:120,h=e.isOwnMessage===t.isOwnMessage,c=(null===(n=e.virtualUser)||void 0===n?void 0:n.id)&&(null===(a=e.virtualUser)||void 0===a?void 0:a.id)===(null===(i=t.virtualUser)||void 0===i?void 0:i.id),m=(null===(o=e.user)||void 0===o?void 0:o.id)&&(null===(r=e.user)||void 0===r?void 0:r.id)===(null===(d=t.user)||void 0===d?void 0:d.id),g=h&&(c||m||e.isOwnMessage&&t.isOwnMessage),u=Math.abs(t.timestamp.getTime()-e.timestamp.getTime())/1e3;return!!g&&u<=l}handleScrollLazyLoad(){if(this.messagesContainer.scrollTop<=20&&this.visibleStartIndex>0){const e=this.messagesContainer.scrollHeight,t=this.lazyLoadBatchSize,s=Math.max(0,this.visibleStartIndex-t),n=this.state.messages.slice(s,this.visibleStartIndex),a=document.createDocumentFragment();for(const e of n){const t=this.buildMessageElement(e);a.appendChild(t)}this.messagesContainer.insertBefore(a,this.messagesContainer.firstChild),this.visibleStartIndex=s;const i=this.messagesContainer.scrollHeight;this.messagesContainer.scrollTop+=i-e}}setLoading(e){if(e){if(!this.messagesContainer.querySelector(".chat-sdk-loading")){const e=document.createElement("div");e.className="chat-sdk-loading",e.innerHTML='\n <div class="chat-sdk-spinner"></div>\n Loading chat...\n ',this.messagesContainer.appendChild(e)}}else{const e=this.messagesContainer.querySelector(".chat-sdk-loading");null==e||e.remove()}}showJoinOverlay(){const e=s("div","chat-sdk-overlay");e.innerHTML='\n <div class="chat-sdk-join-card">\n <h3 class="chat-sdk-join-title">Join the conversation</h3>\n <p class="chat-sdk-join-description">\n Click below to join this group chat and start interacting with other members.\n </p>\n <button class="chat-sdk-join-btn" type="button">Join Chat</button>\n </div>\n ';const t=e.querySelector(".chat-sdk-join-btn");null==t||t.addEventListener("click",()=>{this.hideJoinOverlay(),this.emit("join-requested")}),this.widgetElement.appendChild(e)}hideJoinOverlay(){const e=this.widgetElement.querySelector(".chat-sdk-overlay");e&&e.remove()}addMessage(e){if(e.isOwnMessage)for(let t=this.state.messages.length-1;t>=0;t--){const s=this.state.messages[t];if(s.isOwnMessage&&s.content===e.content){if(Math.abs(e.timestamp.getTime()-s.timestamp.getTime())<=1e4)return;break}}this.state.messages.find(t=>t.id===e.id)?console.warn("Duplicate message detected and ignored:",e.id):(this.state.messages.push(e),this.renderMessage(e),e.isOwnMessage||this.incrementUnreadCount(),this.scrollToBottom(!0))}addMessagesBulk(e){if(!e||0===e.length)return;if(0===this.messagesContainer.querySelectorAll(".chat-sdk-message").length){this.state.messages=[...e].sort((e,t)=>e.timestamp.getTime()-t.timestamp.getTime());const t=this.state.messages.length,s=this.initialRenderCount;this.visibleStartIndex=Math.max(0,t-s);const n=this.state.messages.slice(this.visibleStartIndex),a=document.createDocumentFragment();let i;for(const e of n){const t=this.buildMessageElement(e,i);a.appendChild(t),i=e}this.messagesContainer.appendChild(a),setTimeout(()=>{this.scrollToBottom(!0)},0)}else{const t=new Set(this.state.messages.map(e=>e.id)),s=e.filter(e=>!t.has(e.id));if(s.length>0){this.state.messages.push(...s),this.state.messages.sort((e,t)=>e.timestamp.getTime()-t.timestamp.getTime()),this.messagesContainer.innerHTML="";const e=this.state.messages.length,t=this.initialRenderCount;this.visibleStartIndex=Math.max(0,e-t);const n=this.state.messages.slice(this.visibleStartIndex),a=document.createDocumentFragment();let i;for(const e of n){const t=this.buildMessageElement(e,i);a.appendChild(t),i=e}this.messagesContainer.appendChild(a),this.scrollToBottom()}}}reRenderAllMessages(){this.messagesContainer.innerHTML="";const e=this.state.messages.length,t=Math.max(0,e-this.initialRenderCount);this.state.messages.slice(t).forEach(e=>{this.renderMessage(e)}),this.scrollToBottom()}renderMessage(e){const t=this.state.messages.length-1,s=t>0?this.state.messages[t-1]:void 0,n=this.buildMessageElement(e,s);this.messagesContainer.appendChild(n)}createAvatar(e){var t,n,a,i;const o=s("div","chat-sdk-message-avatar");if(null===(t=e.virtualUser)||void 0===t?void 0:t.avatar)o.style.backgroundImage=`url(${e.virtualUser.avatar})`,o.style.backgroundSize="cover",o.style.backgroundPosition="center";else if(null===(n=e.user)||void 0===n?void 0:n.avatar)o.style.backgroundImage=`url(${e.user.avatar})`,o.style.backgroundSize="cover",o.style.backgroundPosition="center";else{const t=(null===(a=e.virtualUser)||void 0===a?void 0:a.username)||(null===(i=e.user)||void 0===i?void 0:i.username)||"U";o.textContent=t.charAt(0).toUpperCase()}return o}createMessageContent(e,t=!0,a=!1,i=!1){var o,r,d;const l=s("div","chat-sdk-message-content"),h=(null===(o=e.virtualUser)||void 0===o?void 0:o.displayName)||(null===(r=e.virtualUser)||void 0===r?void 0:r.username)||(null===(d=e.user)||void 0===d?void 0:d.username)||"Unknown";let c="";if("image"===e.messageType){c=`\n <div class="chat-sdk-message-image${e.failed?" failed":""}">\n <img src="${n(e.content)}" alt="Image"\n style="max-width: 200px; max-height: 280px; width: 100%; height: auto; cursor: pointer; display: block; border-radius: 8px; object-fit: cover;"\n data-image-url="${n(e.content)}"\n class="chat-sdk-image-preview" />\n </div>\n `}else c="emoji"===e.messageType?`<div class="chat-sdk-message-emoji" style="font-size: 2em; line-height: 1;">${n(e.content)}</div>`:`<p class="chat-sdk-message-text">${n(e.content)}</p>`;const m=`${function(e,t){const s=new Date,n=Math.floor((s.getTime()-e.getTime())/1e3),a=(t||("undefined"!=typeof navigator?navigator.language:"en")).toLowerCase().startsWith("zh");if(n<60)return a?"刚刚":"just now";if(n<3600){const e=Math.floor(n/60);return a?`${e} 分钟前`:`${e}m ago`}if(n<86400){const e=Math.floor(n/3600);return a?`${e} 小时前`:`${e}h ago`}const i=new Date(s.getFullYear(),s.getMonth(),s.getDate());if(e>=new Date(i.getTime()-864e5)&&e<i){const t=e.toLocaleTimeString(a?"zh-CN":void 0,{hour:"2-digit",minute:"2-digit",hour12:!1});return a?`昨天 ${t}`:`yesterday ${t}`}return s.getTime()-e.getTime()<6048e5?e.toLocaleString(a?"zh-CN":void 0,{month:"short",day:"numeric",hour:"2-digit",minute:"2-digit",hour12:!1}):e.toLocaleString(a?"zh-CN":void 0,{year:"numeric",month:"2-digit",day:"2-digit",hour:"2-digit",minute:"2-digit",hour12:!1})}(e.timestamp,this.config.language)}`,g=i?'<span class="chat-sdk-read-status">✓✓</span>':"",u=e.failed&&e.isOwnMessage?'<div class="chat-sdk-message-failed-indicator">\n <svg width="16" height="16" viewBox="0 0 16 16" fill="currentColor">\n <circle cx="8" cy="8" r="8" fill="#ff4444"/>\n <path d="M8 4v4M8 10h.01" stroke="white" stroke-width="1.5" stroke-linecap="round"/>\n </svg>\n </div>':"";return l.innerHTML=a?`\n <div class="chat-sdk-message-bubble">\n ${t&&!e.isOwnMessage?`<div class="chat-sdk-message-username">${n(h)}</div>`:""}\n ${c}\n <div class="chat-sdk-message-time-inside">${m}${g?" "+g:""}</div>\n </div>\n ${u}\n `:`\n ${t&&!e.isOwnMessage?`<div class="chat-sdk-message-username">${n(h)}</div>`:""}\n <div class="chat-sdk-message-bubble">\n ${c}\n </div>\n <div class="chat-sdk-message-time">${m}${g?" "+g:""}</div>\n ${u}\n `,l}scrollToBottom(e=!1){const t=this.messagesContainer;if(e)return void a(t);t.scrollTop+t.clientHeight>=t.scrollHeight-40&&a(t)}setupImageViewer(){this.messagesContainer.addEventListener("click",e=>{const t=e.target;if(t.classList.contains("chat-sdk-image-preview")){const e=t.getAttribute("data-image-url");e&&this.openImageViewer(e)}})}openImageViewer(e){const t=document.querySelector(".chat-sdk-viewer-overlay");t&&t.remove();const s=document.createElement("div");s.className="chat-sdk-viewer-overlay",Object.assign(s.style,{position:"fixed",inset:"0",width:"100vw",height:"100vh",background:"rgba(0,0,0,0.88)",zIndex:"2147483647",display:"flex",alignItems:"center",justifyContent:"center",opacity:"0",transition:"opacity 0.2s ease",cursor:"zoom-out"});const n=document.createElement("button");Object.assign(n.style,{position:"absolute",top:"16px",right:"20px",background:"none",border:"none",color:"#fff",fontSize:"32px",cursor:"pointer",lineHeight:"1",padding:"4px",zIndex:"1"}),n.innerHTML="×",n.setAttribute("aria-label","Close");const a=document.createElement("img");a.src=e,a.alt="Full size image",Object.assign(a.style,{maxWidth:"90vw",maxHeight:"90vh",objectFit:"contain",borderRadius:"8px",boxShadow:"0 8px 32px rgba(0,0,0,0.6)",transform:"scale(0.92)",transition:"transform 0.2s cubic-bezier(0.1, 0.9, 0.2, 1)",cursor:"default",display:"block"});s.addEventListener("click",e=>{e.target!==s&&e.target!==n||(s.style.opacity="0",a.style.transform="scale(0.92)",setTimeout(()=>{s.parentNode&&s.remove()},200))}),a.addEventListener("click",e=>e.stopPropagation()),s.appendChild(n),s.appendChild(a),document.body.appendChild(s),requestAnimationFrame(()=>{s.style.opacity="1",a.style.transform="scale(1)"})}showImagePreview(e){const t=s("div","chat-sdk-image-modal");t.innerHTML=`\n <div class="chat-sdk-image-modal-overlay">\n <div class="chat-sdk-image-modal-content">\n <button class="chat-sdk-image-modal-close">×</button>\n <img src="${n(e)}" alt="Image Preview" class="chat-sdk-image-modal-img" />\n </div>\n </div>\n `,this.widgetElement.appendChild(t);const a=t.querySelector(".chat-sdk-image-modal-close"),i=t.querySelector(".chat-sdk-image-modal-overlay"),o=()=>{t.remove()};null==a||a.addEventListener("click",o),null==i||i.addEventListener("click",e=>{e.target===i&&o()});const r=e=>{"Escape"===e.key&&(o(),document.removeEventListener("keydown",r))};document.addEventListener("keydown",r)}setJoined(e){this.state.isJoined=e,this.handleInputChange()}setUITemplate(e){this.currentTheme=e,this.config.uiTemplate=e,this.widgetElement.classList.remove("whatsapp-theme","telegram-theme","dark"),this.widgetElement.classList.add(`${e}-theme`),"telegram"===e&&this.isDarkMode&&this.widgetElement.classList.add("dark"),this.updateThemeStyles(),this.reRenderAllMessages()}setTheme(e){this.isDarkMode="dark"===e,this.config.theme=e,"telegram"===this.currentTheme&&(this.isDarkMode?this.widgetElement.classList.add("dark"):this.widgetElement.classList.remove("dark"),this.updateThemeStyles())}setCustomColors(e){this.customColors={...this.customColors,...e},this.config.primaryColor=e.primary,this.config.backgroundColor=e.background,this.updateThemeStyles()}updateThemeStyles(){const e=this.currentTheme,t=this.isDarkMode&&"telegram"===e,s=this.shadowRoot||document.documentElement;"whatsapp"===e?(this.setCSSProperty(s,"--chat-primary-color",this.customColors.primary||"#25D366"),this.setCSSProperty(s,"--chat-background-color",this.customColors.background||"#ECE5DD"),this.setCSSProperty(s,"--chat-message-own-bg","#DCF8C6"),this.setCSSProperty(s,"--chat-message-other-bg","#FFFFFF"),this.setCSSProperty(s,"--chat-header-bg","linear-gradient(135deg, #075e54 0%, #128c7e 100%)")):"telegram"===e&&(t?(this.setCSSProperty(s,"--chat-primary-color",this.customColors.primary||"#4FC3F7"),this.setCSSProperty(s,"--chat-background-color",this.customColors.background||"#212121"),this.setCSSProperty(s,"--chat-message-own-bg","linear-gradient(135deg, #4fc3f7 0%, #29b6f6 100%)"),this.setCSSProperty(s,"--chat-message-other-bg","#2F2F2F"),this.setCSSProperty(s,"--chat-header-bg","linear-gradient(135deg, #1976d2 0%, #1565c0 100%)"),this.setCSSProperty(s,"--chat-text-color","#FFFFFF")):(this.setCSSProperty(s,"--chat-primary-color",this.customColors.primary||"#2481CC"),this.setCSSProperty(s,"--chat-background-color",this.customColors.background||"#FFFFFF"),this.setCSSProperty(s,"--chat-message-own-bg","linear-gradient(135deg, #4fc3f7 0%, #29b6f6 100%)"),this.setCSSProperty(s,"--chat-message-other-bg","#F1F1F1"),this.setCSSProperty(s,"--chat-header-bg","linear-gradient(135deg, #2481cc 0%, #1c7cd6 100%)"),this.setCSSProperty(s,"--chat-text-color","#000000")))}setCSSProperty(e,t,s){if(e instanceof ShadowRoot){const n=e.querySelector("style");if(n){const e=n.textContent||"",a=new RegExp(`${t}\\s*:\\s*[^;]+;`,"g"),i=`${t}: ${s};`;if(a.test(e))n.textContent=e.replace(a,i);else{const t=/:host\s*\{([^}]*)\}/;t.test(e)?n.textContent=e.replace(t,(e,t)=>`:host { ${t} ${i} }`):n.textContent=`:host { ${i} }\n${e}`}}}else e.style.setProperty(t,s)}getState(){return{...this.state}}getDefaultStyles(){return"\n :host {\n --chat-primary-color: #25D366;\n --chat-background-color: #ECE5DD;\n --chat-message-own-bg: #DCF8C6;\n --chat-message-other-bg: #FFFFFF;\n --chat-header-bg: linear-gradient(135deg, #075e54 0%, #128c7e 100%);\n --chat-text-color: #333333;\n --chat-border-radius-message: 18px;\n --chat-border-radius-input: 25px;\n }\n\n .chat-sdk-container {\n font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif;\n font-size: 14px;\n line-height: 1.5;\n color: var(--chat-text-color);\n background: var(--chat-background-color);\n border-radius: 12px;\n box-shadow: 0 4px 20px rgba(0, 0, 0, 0.15);\n overflow: hidden;\n display: flex;\n flex-direction: column;\n position: relative;\n max-width: 100%;\n max-height: 100%;\n }\n\n .chat-sdk-container * {\n box-sizing: border-box;\n }\n\n /* WhatsApp Theme */\n .chat-sdk-container.whatsapp-theme .chat-sdk-header {\n background: linear-gradient(135deg, #075e54 0%, #128c7e 100%);\n color: white;\n padding: 12px 16px;\n display: flex;\n align-items: center;\n justify-content: flex-end;\n min-height: 60px;\n box-shadow: 0 1px 3px rgba(0,0,0,0.12);\n }\n .chat-sdk-container.whatsapp-theme .chat-sdk-header-left { display: none; }\n\n .chat-sdk-container.whatsapp-theme .chat-sdk-messages {\n background-color: #ece5dd;\n background-image: url(\"data:image/svg+xml,%3Csvg width='60' height='60' viewBox='0 0 60 60' xmlns='http://www.w3.org/2000/svg'%3E%3Cg fill='none' fill-rule='evenodd'%3E%3Cg fill='%23e5ddd5' fill-opacity='0.08'%3E%3Cpath d='M36 34v-4h-2v4h-4v2h4v4h2v-4h4v-2h-4zm0-30V0h-2v4h-4v2h4v4h2V6h4V4h-4zM6 34v-4H4v4H0v2h4v4h2v-4h4v-2H6zM6 4V0H4v4H0v2h4v4h2V6h4V4H6z'/%3E%3C/g%3E%3C/g%3E%3C/svg%3E\");\n padding: 8px 6px;\n }\n\n .chat-sdk-container.whatsapp-theme {\n --chat-primary-color: #25D366;\n --chat-background-color: #ECE5DD;\n --chat-message-own-bg: #DCF8C6;\n --chat-message-other-bg: #FFFFFF;\n --chat-header-bg: linear-gradient(135deg, #075e54 0%, #128c7e 100%);\n --chat-text-color: #303030;\n --chat-border-radius-message: 7.5px;\n --chat-border-radius-input: 25px;\n display: flex;\n flex-direction: column;\n height: 100%;\n }\n\n /* ── WhatsApp: Message Row Layout ── */\n .chat-sdk-container.whatsapp-theme .chat-sdk-message {\n display: flex;\n flex-direction: row;\n align-items: flex-end;\n margin-bottom: 4px;\n padding: 1px 10px;\n gap: 6px;\n }\n\n /* Own message: green bubble, right side, no avatar */\n .chat-sdk-container.whatsapp-theme .chat-sdk-message.own {\n flex-direction: row-reverse;\n justify-content: flex-start;\n }\n .chat-sdk-container.whatsapp-theme .chat-sdk-message.own .chat-sdk-message-avatar {\n display: none;\n }\n\n /* ── WhatsApp: Avatar ── */\n .chat-sdk-container.whatsapp-theme .chat-sdk-message-avatar {\n width: 32px;\n height: 32px;\n flex-shrink: 0;\n border-radius: 50%;\n align-self: flex-end;\n margin-bottom: 0;\n font-size: 13px;\n font-weight: 700;\n color: #fff;\n background: #aaa;\n }\n\n /* ── WhatsApp: Message Content Wrapper ── */\n .chat-sdk-container.whatsapp-theme .chat-sdk-message-content {\n max-width: 72%;\n min-width: 60px;\n position: relative;\n display: flex;\n flex-direction: column;\n }\n\n /* ── WhatsApp: Bubble ── */\n .chat-sdk-container.whatsapp-theme .chat-sdk-message-bubble {\n background: #fff;\n color: #303030;\n border-radius: 7.5px;\n padding: 6px 10px 20px 10px;\n box-shadow: 0 1px 0.5px rgba(0,0,0,0.13);\n position: relative;\n word-wrap: break-word;\n word-break: break-word;\n display: block;\n max-width: 100%;\n }\n\n /* Tail for other-person bubble (left bottom corner) */\n .chat-sdk-container.whatsapp-theme .chat-sdk-message:not(.own):not(.grouped) .chat-sdk-message-bubble::before {\n content: '';\n position: absolute;\n bottom: 0;\n left: -8px;\n width: 0;\n height: 0;\n border-style: solid;\n border-width: 0 0 8px 8px;\n border-color: transparent transparent #fff transparent;\n filter: drop-shadow(-1px 1px 0.5px rgba(0,0,0,0.10));\n }\n\n /* Own bubble: green */\n .chat-sdk-container.whatsapp-theme .chat-sdk-message.own .chat-sdk-message-bubble {\n background: #DCF8C6;\n color: #303030;\n border-radius: 7.5px;\n }\n\n /* Tail for own bubble (right bottom corner) */\n .chat-sdk-container.whatsapp-theme .chat-sdk-message.own:not(.grouped) .chat-sdk-message-bubble::before {\n content: '';\n position: absolute;\n bottom: 0;\n right: -8px;\n left: auto;\n width: 0;\n height: 0;\n border-style: solid;\n border-width: 8px 0 0 8px;\n border-color: transparent transparent transparent #DCF8C6;\n filter: drop-shadow(1px 1px 0.5px rgba(0,0,0,0.10));\n }\n\n /* ── WhatsApp: Username inside bubble (colored) ── */\n .chat-sdk-container.whatsapp-theme .chat-sdk-message-username {\n font-size: 12.5px;\n font-weight: 600;\n margin-bottom: 2px;\n line-height: 1.2;\n display: block;\n }\n\n /* Cycle username colors like real WhatsApp */\n .chat-sdk-container.whatsapp-theme .chat-sdk-message:nth-child(7n+1) .chat-sdk-message-username { color: #e91e8c; }\n .chat-sdk-container.whatsapp-theme .chat-sdk-message:nth-child(7n+2) .chat-sdk-message-username { color: #e67e22; }\n .chat-sdk-container.whatsapp-theme .chat-sdk-message:nth-child(7n+3) .chat-sdk-message-username { color: #1abc9c; }\n .chat-sdk-container.whatsapp-theme .chat-sdk-message:nth-child(7n+4) .chat-sdk-message-username { color: #9b59b6; }\n .chat-sdk-container.whatsapp-theme .chat-sdk-message:nth-child(7n+5) .chat-sdk-message-username { color: #e74c3c; }\n .chat-sdk-container.whatsapp-theme .chat-sdk-message:nth-child(7n+6) .chat-sdk-message-username { color: #3498db; }\n .chat-sdk-container.whatsapp-theme .chat-sdk-message:nth-child(7n+0) .chat-sdk-message-username { color: #2ecc71; }\n\n /* ── WhatsApp: Input area ── */\n .chat-sdk-container.whatsapp-theme .chat-sdk-input-area {\n background: #f0f2f5;\n border-top: none;\n padding: 8px 10px;\n }\n .chat-sdk-container.whatsapp-theme .chat-sdk-input {\n background: #fff;\n border: none;\n border-radius: 22px;\n padding: 9px 14px;\n font-size: 15px;\n box-shadow: none;\n }\n .chat-sdk-container.whatsapp-theme .chat-sdk-send-btn {\n background: #00a884;\n width: 42px;\n height: 42px;\n box-shadow: none;\n }\n\n\n /* Telegram Theme */\n .chat-sdk-container.telegram-theme {\n --chat-primary-color: #2481CC;\n --chat-background-color: #FFFFFF;\n --chat-message-own-bg: linear-gradient(135deg, #4fc3f7 0%, #29b6f6 100%);\n --chat-message-other-bg: #F1F1F1;\n --chat-header-bg: linear-gradient(135deg, #2481cc 0%, #1c7cd6 100%);\n --chat-text-color: #000000;\n --chat-border-radius-message: 12px;\n --chat-border-radius-input: 12px;\n\n /* Telegram input + details */\n .chat-sdk-container.telegram-theme .chat-sdk-message {\n align-items: flex-start; /* avatar aligns with username at top, not bottom */\n }\n .chat-sdk-container.telegram-theme .chat-sdk-message-content {\n max-width: 75%;\n }\n .chat-sdk-container.telegram-theme .chat-sdk-message-bubble {\n box-shadow: 0 1px 1px rgba(0,0,0,0.06);\n }\n .chat-sdk-container.telegram-theme .chat-sdk-input-area {\n background: #ffffff;\n border-top: 1px solid #e6e6e6;\n }\n .chat-sdk-container.telegram-theme .chat-sdk-input {\n background: #fff;\n border: 1px solid #cfd6dd;\n border-radius: 12px;\n padding: 9px 14px;\n }\n .chat-sdk-container.telegram-theme .chat-sdk-send-btn {\n background: #2481CC;\n border-radius: 10px;\n width: 38px;\n height: 36px;\n box-shadow: none;\n }\n /* Telegram dark */\n .chat-sdk-container.telegram-theme.dark .chat-sdk-input-area {\n background: #1f1f1f;\n border-top: 1px solid #2a2a2a;\n }\n .chat-sdk-container.telegram-theme.dark .chat-sdk-input {\n background: #2b2b2b;\n color: #e0e0e0;\n border-color: #444;\n }\n .chat-sdk-container.telegram-theme.dark .chat-sdk-send-btn {\n background: #1976d2;\n }\n\n\n .chat-sdk-container.telegram-theme .chat-sdk-header {\n background: var(--chat-header-bg);\n color: white;\n padding: 12px 16px;\n display: flex;\n align-items: center;\n justify-content: space-between;\n min-height: 60px;\n box-shadow: 0 1px 3px rgba(0,0,0,0.12);\n }\n\n .chat-sdk-container.telegram-theme .chat-sdk-messages {\n background-color: var(--chat-background-color);\n }\n\n .chat-sdk-container.telegram-theme .chat-sdk-message.own .chat-sdk-message-bubble {\n background: var(--chat-message-own-bg);\n color: white;\n border-radius: var(--chat-border-radius-message) var(--chat-border-radius-message) 4px var(--chat-border-radius-message);\n }\n\n .chat-sdk-container.telegram-theme .chat-sdk-message:not(.own) .chat-sdk-message-bubble {\n background: var(--chat-message-other-bg);\n color: var(--chat-text-color);\n border-radius: var(--chat-border-radius-message) var(--chat-border-radius-message) var(--chat-border-radius-message) 4px;\n }\n\n /* Telegram Dark Theme */\n .chat-sdk-container.telegram-theme.dark {\n --chat-background-color: #212121;\n --chat-message-other-bg: #2F2F2F;\n --chat-header-bg: linear-gradient(135deg, #1976d2 0%, #1565c0 100%);\n --chat-text-color: #FFFFFF;\n }\n\n /* Default header (fallback) */\n .chat-sdk-header {\n background: var(--chat-header-bg);\n color: white;\n padding: 12px 16px;\n display: flex;\n align-items: center;\n justify-content: space-between;\n min-height: 60px;\n }\n\n .chat-sdk-header-left { display: flex; flex-direction: column; gap: 2px; }\n .chat-sdk-title { font-size: 15px; font-weight: 600; }\n .chat-sdk-subtitle { font-size: 12px; opacity: 0.9; }\n\n .chat-sdk-close-btn {\n background: none;\n border: none;\n color: white;\n cursor: pointer;\n padding: 8px;\n border-radius: 50%;\n opacity: 0.8;\n transition: all 0.2s;\n display: flex;\n align-items: center;\n justify-content: center;\n width: 36px;\n height: 36px;\n }\n\n .chat-sdk-close-btn:hover {\n opacity: 1;\n background: rgba(255, 255, 255, 0.1);\n }\n\n .chat-sdk-messages {\n flex: 1;\n overflow-y: auto;\n padding: 16px;\n background: var(--chat-background-color);\n min-height: 0; /* allow flex to use full height */\n }\n\n .chat-sdk-message {\n margin-bottom: 12px;\n display: flex;\n align-items: flex-end;\n gap: 8px;\n }\n\n .chat-sdk-message.own {\n flex-direction: row-reverse;\n }\n\n .chat-sdk-message-avatar {\n width: 32px;\n height: 32px;\n border-radius: 50%;\n background: #ddd;\n display: flex;\n align-items: center;\n justify-content: center;\n font-size: 12px;\n font-weight: 600;\n color: #666;\n flex-shrink: 0;\n }\n\n .chat-sdk-message-content {\n max-width: 70%;\n position: relative;\n }\n\n .chat-sdk-message-bubble {\n background: var(--chat-message-other-bg);\n color: var(--chat-text-color);\n padding: 8px 12px;\n border-radius: var(--chat-border-radius-message);\n position: relative;\n word-wrap: break-word;\n box-shadow: 0 1px 2px rgba(0, 0, 0, 0.1);\n }\n\n .chat-sdk-message.own .chat-sdk-message-bubble {\n background: var(--chat-message-own-bg);\n color: white;\n }\n\n .chat-sdk-message-username {\n font-size: 11px;\n color: #666;\n margin-bottom: 2px;\n font-weight: 600;\n }\n\n .chat-sdk-message-text {\n margin: 0;\n line-height: 1.4;\n }\n\n .chat-sdk-message-time {\n font-size: 10px;\n color: #999;\n margin-top: 4px;\n text-align: right;\n }\n\n /* Message grouping */\n .chat-sdk-message.grouped {\n margin-top: 4px;\n }\n .chat-sdk-message.grouped .chat-sdk-message-username { display: none; }\n .chat-sdk-message.grouped .chat-sdk-message-avatar { visibility: hidden; }\n\n /* WhatsApp: time inside bubble */\n .chat-sdk-container.whatsapp-theme .chat-sdk-message-time-inside {\n position: absolute;\n right: 6px;\n bottom: 4px;\n font-size: 11px;\n color: rgba(0,0,0,0.45);\n display: flex;\n align-items: center;\n gap: 3px;\n line-height: 1;\n }\n .chat-sdk-container.whatsapp-theme .chat-sdk-message.own .chat-sdk-message-time-inside {\n color: rgba(0, 0, 0, 0.45);\n }\n /* hide external time for whatsapp (time is inside bubble) */\n .chat-sdk-container.whatsapp-theme .chat-sdk-message-time {\n display: none;\n }\n\n /* Telegram: read status */\n .chat-sdk-container.telegram-theme .chat-sdk-message-time {\n display: flex;\n align-items: center;\n justify-content: flex-end;\n gap: 6px;\n }\n .chat-sdk-container.telegram-theme .chat-sdk-message.own .chat-sdk-read-status {\n font-size: 12px;\n color: var(--chat-primary-color);\n line-height: 1;\n }\n\n /* Theme-specific image radii */\n .chat-sdk-container.whatsapp-theme .chat-sdk-message-image img { border-radius: 8px; max-width: 200px; max-height: 280px; }\n .chat-sdk-container.telegram-theme .chat-sdk-message-image img { border-radius: 6px; max-width: 200px; max-height: 280px; }\n\n\n .chat-sdk-input-area {\n padding: 12px 16px;\n background: white;\n border-top: 1px solid #e0e0e0;\n display: flex;\n align-items: center;\n gap: 8px;\n }\n\n\n .chat-sdk-icon-btn {\n background: transparent;\n border: none;\n width: 32px;\n height: 32px;\n border-radius: 6px;\n cursor: pointer;\n display: flex;\n align-items: center;\n justify-content: center;\n color: #666;\n }\n .chat-sdk-icon-btn:hover { background: rgba(0,0,0,0.06); }\n\n .chat-sdk-emoji-picker {\n position: absolute;\n left: 12px;\n bottom: 64px;\n background: #fff;\n border: 1px solid #e0e0e0;\n border-radius: 8px;\n box-shadow: 0 6px 16px rgba(0,0,0,0.12);\n padding: 6px;\n z-index: 5;\n }\n .chat-sdk-emoji-grid {\n display: grid;\n grid-template-columns: repeat(5, 28px);\n gap: 6px;\n }\n\n /* Failed message styles - Telegram style */\n .chat-sdk-message-failed-indicator {\n display: inline-flex;\n align-items: center;\n margin-left: 6px;\n color: #ff4444;\n cursor: pointer;\n }\n .chat-sdk-message-failed-indicator svg {\n width: 16px;\n height: 16px;\n }\n .chat-sdk-message.own .chat-sdk-message-content {\n display: flex;\n align-items: flex-end;\n gap: 6px;\n }\n .chat-sdk-message.own .chat-sdk-message-bubble {\n flex: 1;\n }\n .chat-sdk-emoji-item {\n background: none;\n border: none;\n font-size: 20px;\n line-height: 1;\n cursor: pointer;\n width: 28px;\n height: 28px;\n border-radius: 4px;\n }\n .chat-sdk-emoji-item:hover { background: #f3f4f6; }\n\n\n .chat-sdk-input {\n flex: 1;\n border: 1px solid #ddd;\n border-radius: var(--chat-border-radius-input);\n padding: 8px 16px;\n font-size: 14px;\n outline: none;\n resize: none;\n min-height: 36px;\n max-height: 100px;\n }\n\n .chat-sdk-input:focus {\n border-color: var(--chat-primary-color);\n }\n\n .chat-sdk-send-btn {\n background: var(--chat-primary-color);\n color: white;\n border: none;\n border-radius: 50%;\n width: 36px;\n height: 36px;\n cursor: pointer;\n display: flex;\n align-items: center;\n justify-content: center;\n transition: background-color 0.2s;\n }\n\n .chat-sdk-send-btn:hover {\n background: #064e45;\n }\n\n .chat-sdk-send-btn:disabled {\n background: #ccc;\n cursor: not-allowed;\n }\n\n .chat-sdk-overlay {\n position: absolute;\n top: 0;\n left: 0;\n right: 0;\n bottom: 0;\n background: rgba(0, 0, 0, 0.5);\n display: flex;\n align-items: center;\n justify-content: center;\n z-index: 10;\n }\n\n .chat-sdk-join-card {\n background: white;\n border-radius: 12px;\n padding: 24px;\n max-width: 300px;\n margin: 16px;\n text-align: center;\n }\n\n .chat-sdk-join-title {\n font-size: 18px;\n font-weight: 600;\n margin: 0 0 8px 0;\n color: #333;\n }\n\n .chat-sdk-join-description {\n font-size: 14px;\n color: #666;\n margin: 0 0 20px 0;\n line-height: 1.4;\n }\n\n .chat-sdk-join-btn {\n background: #075e54;\n color: white;\n border: none;\n border-radius: 8px;\n padding: 12px 24px;\n font-size: 14px;\n font-weight: 600;\n cursor: pointer;\n transition: background-color 0.2s;\n width: 100%;\n }\n\n .chat-sdk-join-btn:hover {\n background: #064e45;\n }\n\n .chat-sdk-loading {\n display: flex;\n align-items: center;\n justify-content: center;\n padding: 40px;\n color: #666;\n }\n\n .chat-sdk-spinner {\n width: 20px;\n height: 20px;\n border: 2px solid #e0e0e0;\n border-top: 2px solid #075e54;\n border-radius: 50%;\n animation: chat-sdk-spin 1s linear infinite;\n margin-right: 8px;\n }\n\n @keyframes chat-sdk-spin {\n 0% { transform: rotate(0deg); }\n 100% { transform: rotate(360deg); }\n }\n\n .chat-sdk-container.dark {\n background: #1f1f1f;\n color: #e0e0e0;\n }\n\n .chat-sdk-container.dark .chat-sdk-header {\n background: #2d2d2d;\n }\n\n .chat-sdk-container.dark .chat-sdk-messages {\n background: #0d1117;\n }\n\n .chat-sdk-container.dark .chat-sdk-message-bubble {\n background: #2d2d2d;\n color: #e0e0e0;\n }\n\n .chat-sdk-container.dark .chat-sdk-message.own .chat-sdk-message-bubble {\n background: #0969da;\n color: white;\n }\n\n /* Image Modal Viewer */\n .chat-sdk-image-modal {\n position: fixed;\n top: 0; left: 0; right: 0; bottom: 0;\n z-index: 9999;\n opacity: 0;\n visibility: hidden;\n transition: opacity 0.2s ease, visibility 0.2s ease;\n }\n\n .chat-sdk-image-modal-open {\n opacity: 1;\n visibility: visible;\n }\n\n .chat-sdk-image-backdrop {\n position: absolute;\n top: 0; left: 0; right: 0; bottom: 0;\n background: rgba(0, 0, 0, 0.9);\n display: flex;\n align-items: center;\n justify-content: center;\n padding: 20px;\n }\n\n .chat-sdk-image-container {\n position: relative;\n max-width: 90vw;\n max-height: 90vh;\n display: flex;\n align-items: center;\n justify-content: center;\n }\n\n .chat-sdk-image-close {\n position: absolute;\n top: -50px;\n right: 0;\n background: rgba(255, 255, 255, 0.1);\n border: none;\n border-radius: 50%;\n width: 40px;\n height: 40px;\n color: white;\n cursor: pointer;\n display: flex;\n align-items: center;\n justify-content: center;\n transition: background-color 0.2s;\n z-index: 1;\n }\n\n .chat-sdk-image-close:hover {\n background: rgba(255, 255, 255, 0.2);\n }\n\n .chat-sdk-image-full {\n max-width: 100%;\n max-height: 100%;\n object-fit: contain;\n border-radius: 8px;\n box-shadow: 0 10px 30px rgba(0, 0, 0, 0.5);\n }\n\n /* Responsive Design */\n @media (max-width: 640px) {\n .chat-sdk-container {\n border-radius: 0;\n height: 100vh;\n max-height: 100vh;\n }\n\n .chat-sdk-message-content {\n max-width: 85%;\n }\n\n .chat-sdk-message-bubble {\n font-size: 14px;\n padding: 8px 12px;\n }\n\n .chat-sdk-input {\n font-size: 16px; /* Prevent zoom on iOS */\n padding: 10px 14px;\n }\n\n .chat-sdk-header {\n padding: 8px 12px;\n min-height: 50px;\n }\n\n .chat-sdk-message-avatar {\n width: 28px;\n height: 28px;\n font-size: 11px;\n }\n }\n\n @media (min-width: 1024px) {\n .chat-sdk-message-content {\n max-width: 60%;\n }\n\n .chat-sdk-send-btn:hover:not(:disabled) {\n transform: scale(1.05);\n transition: all 0.2s ease;\n }\n }\n\n /* Image Zoom Overlay */\n .chat-sdk-image-zoom-overlay {\n position: absolute;\n top: 0; left: 0; right: 0; bottom: 0;\n background: rgba(0, 0, 0, 0.85);\n z-index: 999999;\n display: flex;\n justify-content: center;\n align-items: center;\n cursor: zoom-out;\n backdrop-filter: blur(2px);\n }\n .chat-sdk-image-zoom-img {\n max-width: 95%;\n max-height: 95%;\n object-fit: contain;\n border-radius: 4px;\n box-shadow: 0 4px 12px rgba(0,0,0,0.3);\n transform: scale(0.95);\n animation: chat-sdk-zoom-in 0.2s cubic-bezier(0.1, 0.9, 0.2, 1) forwards;\n }\n @keyframes chat-sdk-zoom-in {\n to { transform: scale(1); }\n }\n\n "}startSimulation(){this.simulator.start()}stopSimulation(){this.simulator.stop()}pauseSimulation(){this.simulator.pause()}resumeSimulation(){this.simulator.resume()}async sendMessage(e,t="text"){await this.simulator.sendMessage(e,t)}get isSimulationRunning(){return this.state.isSimulationRunning}get isSimulationPaused(){return this.state.isSimulationPaused}get simulationEnded(){return this.state.simulationEnded}get messageCount(){return this.state.displayedMessageCount}get messages(){return[...this.state.messages]}async reinitializeLanguage(e){this.config.language=e,this.setLoading(!0),this.messagesContainer.innerHTML="",this.state.messages=[],this.state.displayedMessageCount=0,this.state.unreadCount=0,this.updateUnreadBadge();try{this.simulator.clearCachedProgress()}catch(e){}try{this.simulator.destroy()}catch(e){}this.simulator=new m(this.config,this.apiClient),this.setupSimulatorEvents(),await this.initializeSimulation()}destroy(){this.pollingStopTimer&&(clearTimeout(this.pollingStopTimer),this.pollingStopTimer=null);try{this.simulator.destroy()}catch(e){}if(this.shadowRoot)try{for(;this.shadowRoot.firstChild;)this.shadowRoot.removeChild(this.shadowRoot.firstChild)}catch(e){}this.state.isOpen=!1,this.removeAllListeners()}clearMessages(){this.state.messages=[],this.state.displayedMessageCount=0,this.state.unreadCount=0,this.messagesContainer.innerHTML="",this.updateUnreadBadge()}rerender(){this.reRenderAllMessages()}getMessageCount(){return this.state.displayedMessageCount}isOpen(){return this.state.isOpen}updateLanguageElements(e){var t,s,n;this.t=p(e);const a=null===(t=this.widgetElement)||void 0===t?void 0:t.querySelector("#message-input");a&&(a.placeholder=this.t.inputPlaceholder);const i=null===(s=this.widgetElement)||void 0===s?void 0:s.querySelector(".send-button");i&&i.textContent&&(i.textContent=this.t.send);const o=this.getMessageCount(),r=(null===(n=this.state.currentProject)||void 0===n?void 0:n.name)||"Chat";this.setTitle(r,`${o} ${this.t.messages}`)}}const f=b;function v(e){return new b(e)}var k={init:v,ChatSDK:f,ChatSDKError:e};"undefined"!=typeof window&&(window.ChatSDK={init:v,ChatSDK:f,ChatSDKError:e});export{f as ChatSDK,e as ChatSDKError,k as default,v as init};
|
|
1
|
+
class e extends Error{constructor(e,t,s){super(e),this.code=t,this.details=s,this.name="ChatSDKError"}}class t{constructor(){this.events=new Map}on(e,t){this.events.has(e)||this.events.set(e,[]),this.events.get(e).push(t)}off(e,t){if(!this.events.has(e))return;if(!t)return void this.events.delete(e);const s=this.events.get(e),n=s.indexOf(t);n>-1&&s.splice(n,1),0===s.length&&this.events.delete(e)}emit(e,t){if(!this.events.has(e))return;this.events.get(e).forEach(s=>{try{s(t)}catch(t){console.error(`Error in event callback for "${e}":`,t)}})}getEventNames(){return Array.from(this.events.keys())}listenerCount(e){var t;return(null===(t=this.events.get(e))||void 0===t?void 0:t.length)||0}removeAllListeners(){this.events.clear()}}function s(e,t,s){const n=document.createElement(e);return t&&(n.className=t),n}function n(e){const t=document.createElement("div");return t.textContent=e,t.innerHTML}function i(e,t=!0){e.scrollTop=e.scrollHeight,e.scrollTo&&e.scrollTo({top:e.scrollHeight,behavior:t?"smooth":"auto"})}const a={USD:1,EUR:.92,GBP:.79,JPY:149.5,CNY:7.24,INR:83.12,BRL:4.97,RUB:92.5,KRW:1320,MXN:17.15,CAD:1.38,AUD:1.53,CHF:.88,SEK:10.85,NZD:1.67,SGD:1.34,HKD:7.82,NOK:10.95,TRY:28.5,ZAR:18.65,PLN:4.05,THB:35.2,IDR:15650,MYR:4.68,PHP:56.2,DKK:6.88,CZK:22.85,HUF:355,ILS:3.72,CLP:920,ARS:350,COP:4050,PEN:3.75,EGP:30.9,SAR:3.75,AED:3.67,VND:24500,PKR:278,BDT:110,NGN:775,UAH:36.5,RON:4.58,TWD:31.5,QAR:3.64,KWD:.31,OMR:.38,BHD:.38},o={USD:"$",EUR:"€",GBP:"£",JPY:"¥",CNY:"¥",INR:"₹",BRL:"R$",RUB:"₽",KRW:"₩",MXN:"$",CAD:"C$",AUD:"A$",CHF:"CHF",SEK:"kr",NZD:"NZ$",SGD:"S$",HKD:"HK$",NOK:"kr",TRY:"₺",ZAR:"R",PLN:"zł",THB:"฿",IDR:"Rp",MYR:"RM",PHP:"₱",DKK:"kr",CZK:"Kč",HUF:"Ft",ILS:"₪",CLP:"$",ARS:"$",COP:"$",PEN:"S/",EGP:"E£",SAR:"﷼",AED:"د.إ",VND:"₫",PKR:"₨",BDT:"৳",NGN:"₦",UAH:"₴",RON:"lei",TWD:"NT$",QAR:"﷼",KWD:"د.ك",OMR:"﷼",BHD:"د.ب"},r={USD:",",EUR:".",GBP:",",JPY:",",CNY:",",INR:",",BRL:".",RUB:" ",KRW:",",MXN:",",CAD:",",AUD:",",CHF:"'",SEK:" ",PLN:" ",THB:",",IDR:".",MYR:",",PHP:",",DKK:".",CZK:" ",HUF:" "},d={USD:".",EUR:",",GBP:".",JPY:".",CNY:".",INR:".",BRL:",",RUB:",",KRW:".",MXN:".",CAD:".",AUD:".",CHF:".",SEK:",",PLN:",",THB:".",IDR:",",MYR:".",PHP:".",DKK:",",CZK:",",HUF:","},l={US:"USD",CA:"CAD",MX:"MXN",BR:"BRL",AR:"ARS",CL:"CLP",CO:"COP",PE:"PEN",GB:"GBP",DE:"EUR",FR:"EUR",IT:"EUR",ES:"EUR",NL:"EUR",BE:"EUR",AT:"EUR",PT:"EUR",IE:"EUR",GR:"EUR",FI:"EUR",CH:"CHF",NO:"NOK",SE:"SEK",DK:"DKK",PL:"PLN",CZ:"CZK",HU:"HUF",RO:"RON",RU:"RUB",UA:"UAH",TR:"TRY",IL:"ILS",SA:"SAR",AE:"AED",EG:"EGP",CN:"CNY",JP:"JPY",KR:"KRW",IN:"INR",ID:"IDR",TH:"THB",VN:"VND",MY:"MYR",SG:"SGD",PH:"PHP",PK:"PKR",BD:"BDT",HK:"HKD",TW:"TWD",AU:"AUD",NZ:"NZD",ZA:"ZAR",NG:"NGN",KE:"KES",QA:"QAR",KW:"KWD",OM:"OMR",BH:"BHD"},h=new Set(["JPY","KRW","IDR","VND","CLP","PYG","UGX"]);function c(e,t){if(!e||!t)return e;const s=function(e){return l[e.toUpperCase()]||"USD"}(t);return e.replace(/\{\{AMOUNT:(\d+(?:\.\d+)?)\}\}/g,(e,t)=>{const n=parseFloat(t);return isNaN(n)?e:function(e,t){var s,n,i,l;const c=null!==(s=a[t])&&void 0!==s?s:1,m=null!==(n=o[t])&&void 0!==n?n:t+" ",u=null!==(i=r[t])&&void 0!==i?i:",",g=null!==(l=d[t])&&void 0!==l?l:".",p=h.has(t),y=e*c,b=p?Math.round(y):Math.round(100*y)/100,v=Math.floor(b).toString().replace(/\B(?=(\d{3})+(?!\d))/g,u);return p?`${m}${v}`:`${m}${v}${g}${(b%1).toFixed(2).slice(2)}`}(n,s)})}class m extends t{constructor(e,t){super(),this.simulationData=null,this.displayedMessages=[],this.currentMessageIndex=0,this.isRunning=!1,this.isPaused=!1,this.intervalId=null,this.pollingId=null,this.burstPhase=!0,this.totalToShow=1/0,this.virtualLastTimestamp=null,this.realLastTimestamp=null,this.lastTimestamp=null,this.lastDelayMs=0,this.userId="",this.config=e,this.apiClient=t,this.pollingIntervalMs="number"==typeof e.pollingInterval&&e.pollingInterval>0?e.pollingInterval:6e3}async initialize(){try{const e=this.config.language||"en",t=(this.config.country||"US").toUpperCase(),s=this.getPersistedUserId(),n=s||this.config.userId||this.generateUserId();this.userId=n,s||this.persistUserId(n);const i=await this.apiClient.getSimulationData(this.config.projectId,n,e,t);if(!i.success||!i.data)throw new Error("Failed to load simulation data");this.simulationData=i.data;const a=this.simulationData.project.initialBurstCount+this.simulationData.project.continuousCount;this.totalToShow=Math.min(a,this.simulationData.messages.length);const o=this.loadProgress();o&&"number"==typeof o.index?(this.currentMessageIndex=o.index,o.lastTimestamp&&(this.virtualLastTimestamp=new Date(o.lastTimestamp),this.lastTimestamp=new Date(o.lastTimestamp))):(this.currentMessageIndex=0,this.virtualLastTimestamp=null,this.lastTimestamp=null),this.realLastTimestamp=null,await this.loadExistingMessages(),await this.reconstructVirtualHistoryForDisplay(),this.emit("initialized",this.simulationData),this.startPolling(),!1!==this.config.autoStart&&this.start()}catch(e){throw this.emit("error",e),e}}start(){this.simulationData&&!this.isRunning&&(this.isRunning=!0,this.isPaused=!1,this.burstPhase=!0,this.emit("simulationStart"),this.performInitialBurst(),this.currentMessageIndex<this.totalToShow?(this.burstPhase=!1,this.scheduleNextMessage()):(this.isRunning=!1,this.emit("simulationEnd")))}performInitialBurst(){if(!this.simulationData)return;const{project:e,messages:t}=this.simulationData,s=e.initialBurstCount,n=Math.min(s,this.totalToShow,t.length);if(this.currentMessageIndex>=n)return;if(this.displayedMessages.some(e=>e.id.startsWith("sim-"))&&this.currentMessageIndex>0)return;const i=new Date,a=new Array(n);let o=new Date(i);for(let e=n-1;e>=0;e--)if(a[e]=new Date(o),e>0){const e=10+Math.floor(11*Math.random());o=new Date(o.getTime()-60*e*1e3)}const r=[],d=(this.config.country||"US").toUpperCase();let l=!1;for(let e=this.currentMessageIndex;e<n;e++){const s=t[e],n=c(s.content,d);if(s.hasScreenshot&&s.screenshotUrl){const t={id:`sim-${e}-text-${Date.now()}`,content:n,messageType:"text",timestamp:a[e],isOwnMessage:!1,virtualUser:s.virtualUser};this.displayedMessages.push(t),r.push(t);const i=new Date(a[e].getTime()+2e3),o={id:`sim-${e}-image-${Date.now()}`,content:this.resolveImageUrl(s.screenshotUrl),messageType:"image",timestamp:i,isOwnMessage:!1,virtualUser:s.virtualUser};this.displayedMessages.push(o),r.push(o)}else if("audio"===s.messageType){const t={id:`sim-${e}-audio-${Date.now()}`,content:"",messageType:"audio",audioUrl:this.resolveImageUrl(s.audioUrl||""),timestamp:a[e],isOwnMessage:!1,virtualUser:s.virtualUser};this.displayedMessages.push(t),r.push(t)}else{const t={id:`sim-${e}-${Date.now()}`,content:n,messageType:s.messageType,timestamp:a[e],isOwnMessage:!1,virtualUser:s.virtualUser};this.displayedMessages.push(t),r.push(t)}this.currentMessageIndex=e+1,l=!0}l&&(this.lastTimestamp=a[n-1],this.virtualLastTimestamp=this.lastTimestamp,this.displayedMessages.sort((e,t)=>e.timestamp.getTime()-t.timestamp.getTime()),this.emit("messages-batch",r)),this.saveProgress()}pause(){this.isRunning&&(this.isPaused=!0,this.intervalId&&(clearTimeout(this.intervalId),this.intervalId=null),this.emit("simulationPause"))}resume(){this.isRunning&&this.isPaused&&(this.isPaused=!1,this.scheduleNextMessage(),this.emit("simulationResume"))}stop(){this.isRunning=!1,this.isPaused=!1,this.intervalId&&(clearTimeout(this.intervalId),this.intervalId=null),this.emit("simulationStop")}destroy(){this.stop(),this.stopPolling(),this.removeAllListeners()}scheduleNextMessage(){if(!this.simulationData||!this.isRunning||this.isPaused)return;const{project:e,messages:t}=this.simulationData;if(this.currentMessageIndex>=this.totalToShow)return this.isRunning=!1,void this.emit("simulationEnd");let s;if(this.burstPhase){const n=Math.min(e.initialBurstCount,t.length);this.currentMessageIndex<n?s=500+1e3*Math.random():(this.burstPhase=!1,s=this.getRandomInterval(e.messageIntervalMin,e.messageIntervalMax))}else{const n=Math.min(e.initialBurstCount,t.length);s=this.currentMessageIndex-n<5?1e3*(e.initialMessageInterval||10):this.getRandomInterval(e.messageIntervalMin,e.messageIntervalMax)}this.lastDelayMs=s,this.intervalId=setTimeout(()=>{this.displayNextMessage(),this.scheduleNextMessage()},s)}displayNextMessage(){if(!this.simulationData||this.currentMessageIndex>=this.simulationData.messages.length)return;const e=this.simulationData.messages[this.currentMessageIndex],t=(this.config.country||"US").toUpperCase(),s=c(e.content,t),n=this.lastTimestamp||new Date,i=new Date(n.getTime()+(this.lastDelayMs||0));if(this.lastTimestamp=i,e.hasScreenshot&&e.screenshotUrl){const t={id:`sim-${this.currentMessageIndex}-text-${Date.now()}`,content:s,messageType:"text",timestamp:i,isOwnMessage:!1,virtualUser:e.virtualUser};this.displayedMessages.push(t),this.emit("message",t);const n=new Date(i.getTime()+2e3),a={id:`sim-${this.currentMessageIndex}-image-${Date.now()}`,content:this.resolveImageUrl(e.screenshotUrl),messageType:"image",timestamp:n,isOwnMessage:!1,virtualUser:e.virtualUser};this.displayedMessages.push(a),this.lastTimestamp=n,setTimeout(()=>{this.emit("message",a)},2e3)}else if("audio"===e.messageType){const t={id:`sim-${this.currentMessageIndex}-audio-${Date.now()}`,content:"",messageType:"audio",audioUrl:this.resolveImageUrl(e.audioUrl||""),timestamp:i,isOwnMessage:!1,virtualUser:e.virtualUser};this.displayedMessages.push(t),this.emit("message",t)}else{const t={id:`sim-${this.currentMessageIndex}-${Date.now()}`,content:s,messageType:e.messageType,timestamp:i,isOwnMessage:!1,virtualUser:e.virtualUser};this.displayedMessages.push(t),this.emit("message",t)}this.currentMessageIndex++,this.saveProgress()}async loadExistingMessages(){if(this.simulationData)try{const e=this.userId||this.config.userId||this.generateUserId(),t=await this.apiClient.getSimulationMessages(this.config.projectId,e,void 0,100);if(t.success&&t.messages&&t.messages.length>0){const s=t.messages.sort((e,t)=>new Date(e.createdAt||e.timestamp).getTime()-new Date(t.createdAt||t.timestamp).getTime()),n=new Set(this.displayedMessages.map(e=>e.id));for(const t of s){if(n.has(t.id))continue;const s=(this.config.country||"US").toUpperCase(),i={id:t.id,content:c(t.content||"",s),messageType:t.messageType,timestamp:new Date(t.createdAt||t.timestamp),isOwnMessage:t.userId===e,virtualUser:t.virtualUser,user:t.userId===e?{id:e,username:this.config.username||"You"}:void 0};this.displayedMessages.push(i)}if(s.length>0){const e=s[s.length-1];this.realLastTimestamp=new Date(e.createdAt||e.timestamp)}this.displayedMessages.length>0&&this.emit("messages-batch",[...this.displayedMessages])}}catch(e){console.warn("Failed to load existing messages:",e)}}startPolling(){this.pollingId&&(clearInterval(this.pollingId),this.pollingId=null),this.pollingId=setInterval(async()=>{await this.pollForNewMessages()},this.pollingIntervalMs)}stopPolling(){this.pollingId&&(clearInterval(this.pollingId),this.pollingId=null)}setPollingInterval(e){!e||e<=0||(this.pollingIntervalMs=e,this.pollingId&&this.startPolling())}get isPolling(){return!!this.pollingId}async pollForNewMessages(){if(this.simulationData)try{const e=this.userId||this.config.userId||this.generateUserId(),t=this.getLastMessageTimestamp(),s=await this.apiClient.getSimulationMessages(this.config.projectId,e,t);if(s.success&&s.messages&&s.messages.length>0){const t=new Set(this.displayedMessages.map(e=>e.id));let n=null;for(const i of s.messages){if(t.has(i.id))continue;const s=new Date(i.createdAt),a=(this.config.country||"US").toUpperCase(),o={id:i.id,content:c(i.content||"",a),messageType:i.messageType,timestamp:s,isOwnMessage:i.userId===e,virtualUser:i.virtualUser,user:i.userId===e?{id:e,username:this.config.username||"You"}:void 0};(!n||s>n)&&(n=s),this.displayedMessages.push(o),this.emit("message",o)}n&&(this.realLastTimestamp=n)}}catch(e){console.warn("Polling error:",e)}}async reconstructVirtualHistoryForDisplay(){if(!this.simulationData)return;const e=Math.min(this.currentMessageIndex,this.totalToShow,this.simulationData.messages.length);if(e<=0)return;const t=this.loadProgress(),s=(null==t?void 0:t.virtualMessages)||[];if(s.length>0){const e=[],t=new Set(this.displayedMessages.map(e=>e.id)),n=(this.config.country||"US").toUpperCase();for(const i of s)if(!t.has(i.id)){if("image"===i.messageType){const e=i.content||"";if(!e.startsWith("http")&&!e.startsWith("/uploads")&&!e.startsWith("/api"))continue}const t={id:i.id,content:"image"===i.messageType?this.resolveImageUrl(c(i.content||"",n)):"audio"===i.messageType?"":c(i.content||"",n),messageType:i.messageType,audioUrl:"audio"===i.messageType?this.resolveImageUrl(i.audioUrl||i.content||""):void 0,timestamp:new Date(i.timestamp),isOwnMessage:!1,virtualUser:i.virtualUser};e.push(t)}if(e.length>0){this.displayedMessages.push(...e),this.displayedMessages.sort((e,t)=>e.timestamp.getTime()-t.timestamp.getTime());const t=e[e.length-1];this.virtualLastTimestamp=t.timestamp,this.lastTimestamp=t.timestamp,this.emit("messages-batch",e)}return}const n=new Date,i=new Array(e);let a=new Date(n);for(let t=e-1;t>=0;t--)if(i[t]=new Date(a),t>0){const e=10+Math.floor(11*Math.random());a=new Date(a.getTime()-60*e*1e3)}const o=[],{messages:r}=this.simulationData,d=(this.config.country||"US").toUpperCase();for(let t=0;t<e;t++){const e=r[t],s=i[t],n=c(e.content,d);if(e.hasScreenshot&&e.screenshotUrl){const i={id:`sim-${t}-text`,content:n,messageType:"text",timestamp:s,isOwnMessage:!1,virtualUser:e.virtualUser},a={id:`sim-${t}-image`,content:this.resolveImageUrl(e.screenshotUrl),messageType:"image",timestamp:new Date(s.getTime()+2e3),isOwnMessage:!1,virtualUser:e.virtualUser};o.push(i,a)}else{const i={id:`sim-${t}`,content:n,messageType:e.messageType,timestamp:s,isOwnMessage:!1,virtualUser:e.virtualUser};o.push(i)}}const l=new Set(this.displayedMessages.map(e=>e.id)),h=o.filter(e=>!l.has(e.id));if(0===h.length)return;this.displayedMessages.push(...h),this.displayedMessages.sort((e,t)=>e.timestamp.getTime()-t.timestamp.getTime());const m=h[h.length-1];this.virtualLastTimestamp=m.timestamp,this.lastTimestamp=m.timestamp,this.emit("messages-batch",h)}getLastMessageTimestamp(){if(this.realLastTimestamp)return this.realLastTimestamp.toISOString()}getUserKey(){return`vcs:user:${this.config.projectId}`}getProgressKey(){const e=this.userId||this.config.userId||"anon";return`vcs:progress:${this.config.projectId}:${e}`}getPersistedUserId(){try{return"undefined"==typeof window?null:window.localStorage.getItem(this.getUserKey())}catch(e){return null}}persistUserId(e){try{if("undefined"==typeof window)return;window.localStorage.setItem(this.getUserKey(),e)}catch(e){}}loadProgress(){try{if("undefined"==typeof window)return null;const e=window.localStorage.getItem(this.getProgressKey());return e?JSON.parse(e):null}catch(e){return null}}saveProgress(){try{if("undefined"==typeof window)return;const e=this.displayedMessages.filter(e=>e.id.startsWith("sim-")).map(e=>({id:e.id,content:e.content,messageType:e.messageType,timestamp:e.timestamp.toISOString(),virtualUser:e.virtualUser})),t={index:this.currentMessageIndex,lastTimestamp:this.lastTimestamp?this.lastTimestamp.toISOString():void 0,virtualMessages:e};window.localStorage.setItem(this.getProgressKey(),JSON.stringify(t))}catch(e){}}clearProgress(){try{if("undefined"==typeof window)return;window.localStorage.removeItem(this.getProgressKey())}catch(e){}}clearCachedProgress(){this.clearProgress()}resolveImageUrl(e){if(!e)return"";if(e.startsWith("http://")||e.startsWith("https://"))return e;const t=(this.config.apiBaseUrl||"").replace(/\/$/,"");return t?`${t}${e}`:e}getRandomInterval(e,t){return 1e3*(e+Math.random()*(t-e))}generateUserId(){return`user-${Date.now()}-${Math.random().toString(36).substring(2,11)}`}get messages(){return[...this.displayedMessages]}get isSimulationRunning(){return this.isRunning}get isSimulationPaused(){return this.isPaused}get data(){return this.simulationData}async sendMessage(e,t="text"){if(!this.simulationData)throw new Error("Simulation not initialized");const s=this.userId||this.config.userId||this.generateUserId(),n=this.config.username||"User";try{if("image"===t||"string"==typeof e&&e.startsWith("data:image/"))return;await Promise.all([this.apiClient.sendUserMessage(this.config.projectId,s,n,e,t),this.apiClient.triggerAIReply(this.config.projectId,s,n,e,t)])}catch(e){throw this.emit("error",e),e}}}class u{constructor(e){this.baseUrl=e.apiBaseUrl||window.location.origin,this.token=e.token}async request(t,s={}){const n=`${this.baseUrl}${t}`,i={"Content-Type":"application/json",...s.headers};this.token&&(i.Authorization=`Bearer ${this.token}`);try{const t=await fetch(n,{...s,headers:i,credentials:"include"});if(!t.ok)throw new e(`API request failed: ${t.status} ${t.statusText}`,"API_ERROR",{status:t.status,statusText:t.statusText});const a=await t.json();if(!a.success&&a.error)throw new e(a.error,"API_ERROR",a);return a}catch(t){if(t instanceof e)throw t;throw new e(`Network error: ${t.message}`,"NETWORK_ERROR",t)}}async getProject(e){return this.request(`/api/projects/${e}`)}async getTemplate(e,t,s){const n=new URLSearchParams;t&&n.set("lang",t),s&&n.set("country",s);const i=n.toString()?`?${n.toString()}`:"";return this.request(`/api/templates/${e}${i}`)}async getProjectTemplates(e){return this.request(`/api/projects/${e}/templates`)}async sendMessage(e,t,s,n="text"){return this.request("/api/chat/message",{method:"POST",body:JSON.stringify({projectId:e,userId:t,content:s,messageType:n})})}async joinProject(e,t,s){return this.request("/api/chat/join",{method:"POST",body:JSON.stringify({projectId:e,userId:t,username:s})})}async leaveProject(e,t){return this.request("/api/chat/leave",{method:"POST",body:JSON.stringify({projectId:e,userId:t})})}async getSimulationData(e,t,s,n){const i=new URLSearchParams({userId:t});return s&&i.append("lang",s),n&&i.append("country",n),this.request(`/api/chat/simulation/${e}?${i.toString()}`)}async getSimulationMessages(e,t,s,n){const i=new URLSearchParams({userId:t});return s&&i.append("since",s),n&&i.append("limit",n.toString()),this.request(`/api/chat/simulation/${e}/messages?${i.toString()}`)}async sendUserMessage(e,t,s,n,i="text"){return this.request("/api/chat/send",{method:"POST",body:JSON.stringify({projectId:e,userId:t,username:s,content:n,messageType:i})})}async triggerAIReply(e,t,s,n,i="text"){return this.request("/api/chat/ai-reply",{method:"POST",body:JSON.stringify({projectId:e,userId:t,username:s,content:n,messageType:i})})}setToken(e){this.token=e}setBaseUrl(e){this.baseUrl=e}}const g={en:{joinChat:"Join Chat",chatGroup:"{name} Group",online:"{count} online",inputPlaceholder:"Type a message...",send:"Send",messages:"messages",today:"Today",yesterday:"Yesterday",networkError:"Network error",sendFailed:"Failed to send"},zh:{joinChat:"加入群聊",chatGroup:"{name}交流群",online:"{count} 人在线",inputPlaceholder:"输入消息...",send:"发送",messages:"条消息",today:"今天",yesterday:"昨天",networkError:"网络错误",sendFailed:"发送失败"},"zh-TW":{joinChat:"加入群聊",chatGroup:"{name}交流群",online:"{count} 人在線",inputPlaceholder:"輸入訊息...",send:"發送",messages:"條訊息",today:"今天",yesterday:"昨天",networkError:"網路錯誤",sendFailed:"發送失敗"},es:{joinChat:"Unirse al Chat",chatGroup:"Grupo {name}",online:"{count} en línea",inputPlaceholder:"Escribe un mensaje...",send:"Enviar",messages:"mensajes",today:"Hoy",yesterday:"Ayer",networkError:"Error de red",sendFailed:"Error al enviar"},hi:{joinChat:"चैट में शामिल हों",chatGroup:"{name} समूह",online:"{count} ऑनलाइन",inputPlaceholder:"संदेश लिखें...",send:"भेजें",messages:"संदेश",today:"आज",yesterday:"कल",networkError:"नेटवर्क त्रुटि",sendFailed:"भेजने में विफल"},ar:{joinChat:"انضم للدردشة",chatGroup:"مجموعة {name}",online:"{count} متصل",inputPlaceholder:"اكتب رسالة...",send:"إرسال",messages:"رسائل",today:"اليوم",yesterday:"أمس",networkError:"خطأ في الشبكة",sendFailed:"فشل الإرسال"},pt:{joinChat:"Entrar no Chat",chatGroup:"Grupo {name}",online:"{count} online",inputPlaceholder:"Digite uma mensagem...",send:"Enviar",messages:"mensagens",today:"Hoje",yesterday:"Ontem",networkError:"Erro de rede",sendFailed:"Falha ao enviar"},bn:{joinChat:"চ্যাটে যোগ দিন",chatGroup:"{name} গ্রুপ",online:"{count} অনলাইন",inputPlaceholder:"একটি বার্তা লিখুন...",send:"পাঠান",messages:"বার্তা",today:"আজ",yesterday:"গতকাল",networkError:"নেটওয়ার্ক ত্রুটি",sendFailed:"পাঠাতে ব্যর্থ"},ru:{joinChat:"Присоединиться",chatGroup:"Группа {name}",online:"{count} онлайн",inputPlaceholder:"Введите сообщение...",send:"Отправить",messages:"сообщений",today:"Сегодня",yesterday:"Вчера",networkError:"Ошибка сети",sendFailed:"Не удалось отправить"},ja:{joinChat:"チャットに参加",chatGroup:"{name}グループ",online:"{count} オンライン",inputPlaceholder:"メッセージを入力...",send:"送信",messages:"メッセージ",today:"今日",yesterday:"昨日",networkError:"ネットワークエラー",sendFailed:"送信失敗"},de:{joinChat:"Chat beitreten",chatGroup:"{name} Gruppe",online:"{count} online",inputPlaceholder:"Nachricht eingeben...",send:"Senden",messages:"Nachrichten",today:"Heute",yesterday:"Gestern",networkError:"Netzwerkfehler",sendFailed:"Senden fehlgeschlagen"},fr:{joinChat:"Rejoindre le Chat",chatGroup:"Groupe {name}",online:"{count} en ligne",inputPlaceholder:"Tapez un message...",send:"Envoyer",messages:"messages",today:"Aujourd'hui",yesterday:"Hier",networkError:"Erreur réseau",sendFailed:"Échec de l'envoi"},ko:{joinChat:"채팅 참여",chatGroup:"{name} 그룹",online:"{count} 온라인",inputPlaceholder:"메시지 입력...",send:"전송",messages:"메시지",today:"오늘",yesterday:"어제",networkError:"네트워크 오류",sendFailed:"전송 실패"},it:{joinChat:"Unisciti alla Chat",chatGroup:"Gruppo {name}",online:"{count} online",inputPlaceholder:"Scrivi un messaggio...",send:"Invia",messages:"messaggi",today:"Oggi",yesterday:"Ieri",networkError:"Errore di rete",sendFailed:"Invio fallito"},tr:{joinChat:"Sohbete Katıl",chatGroup:"{name} Grubu",online:"{count} çevrimiçi",inputPlaceholder:"Bir mesaj yazın...",send:"Gönder",messages:"mesaj",today:"Bugün",yesterday:"Dün",networkError:"Ağ hatası",sendFailed:"Gönderilemedi"},vi:{joinChat:"Tham gia Chat",chatGroup:"Nhóm {name}",online:"{count} trực tuyến",inputPlaceholder:"Nhập tin nhắn...",send:"Gửi",messages:"tin nhắn",today:"Hôm nay",yesterday:"Hôm qua",networkError:"Lỗi mạng",sendFailed:"Gửi thất bại"},pl:{joinChat:"Dołącz do Czatu",chatGroup:"Grupa {name}",online:"{count} online",inputPlaceholder:"Wpisz wiadomość...",send:"Wyślij",messages:"wiadomości",today:"Dziś",yesterday:"Wczoraj",networkError:"Błąd sieci",sendFailed:"Nie udało się wysłać"},th:{joinChat:"เข้าร่วมแชท",chatGroup:"กลุ่ม {name}",online:"{count} ออนไลน์",inputPlaceholder:"พิมพ์ข้อความ...",send:"ส่ง",messages:"ข้อความ",today:"วันนี้",yesterday:"เมื่อวาน",networkError:"ข้อผิดพลาดเครือข่าย",sendFailed:"ส่งไม่สำเร็จ"},nl:{joinChat:"Deelnemen aan Chat",chatGroup:"{name} Groep",online:"{count} online",inputPlaceholder:"Typ een bericht...",send:"Verzenden",messages:"berichten",today:"Vandaag",yesterday:"Gisteren",networkError:"Netwerkfout",sendFailed:"Verzenden mislukt"},id:{joinChat:"Gabung Chat",chatGroup:"Grup {name}",online:"{count} online",inputPlaceholder:"Ketik pesan...",send:"Kirim",messages:"pesan",today:"Hari ini",yesterday:"Kemarin",networkError:"Kesalahan jaringan",sendFailed:"Gagal mengirim"},ms:{joinChat:"Sertai Chat",chatGroup:"Kumpulan {name}",online:"{count} dalam talian",inputPlaceholder:"Taip mesej...",send:"Hantar",messages:"mesej",today:"Hari ini",yesterday:"Semalam",networkError:"Ralat rangkaian",sendFailed:"Gagal menghantar"},ur:{joinChat:"چیٹ میں شامل ہوں",chatGroup:"{name} گروپ",online:"{count} آن لائن",inputPlaceholder:"پیغام ٹائپ کریں...",send:"بھیجیں",messages:"پیغامات",today:"آج",yesterday:"کل",networkError:"نیٹ ورک کی خرابی",sendFailed:"بھیجنے میں ناکام"},te:{joinChat:"చాట్లో చేరండి",chatGroup:"{name} సమూహం",online:"{count} ఆన్లైన్",inputPlaceholder:"సందేశాన్ని టైప్ చేయండి...",send:"పంపండి",messages:"సందేశాలు",today:"నేడు",yesterday:"నిన్న",networkError:"నెట్వర్క్ లోపం",sendFailed:"పంపడం విఫలమైంది"},mr:{joinChat:"चॅटमध्ये सामील व्हा",chatGroup:"{name} गट",online:"{count} ऑनलाइन",inputPlaceholder:"संदेश टाइप करा...",send:"पाठवा",messages:"संदेश",today:"आज",yesterday:"काल",networkError:"नेटवर्क त्रुटी",sendFailed:"पाठविण्यात अयशस्वी"},ta:{joinChat:"அரட்டையில் சேரவும்",chatGroup:"{name} குழு",online:"{count} ஆன்லைன்",inputPlaceholder:"ஒரு செய்தியை தட்டச்சு செய்யவும்...",send:"அனுப்பு",messages:"செய்திகள்",today:"இன்று",yesterday:"நேற்று",networkError:"நெட்வொர்க் பிழை",sendFailed:"அனுப்ப முடியவில்லை"},fa:{joinChat:"پیوستن به چت",chatGroup:"گروه {name}",online:"{count} آنلاین",inputPlaceholder:"پیامی تایپ کنید...",send:"ارسال",messages:"پیامها",today:"امروز",yesterday:"دیروز",networkError:"خطای شبکه",sendFailed:"ارسال نشد"},uk:{joinChat:"Приєднатися до чату",chatGroup:"Група {name}",online:"{count} онлайн",inputPlaceholder:"Введіть повідомлення...",send:"Надіслати",messages:"повідомлень",today:"Сьогодні",yesterday:"Вчора",networkError:"Помилка мережі",sendFailed:"Не вдалося надіслати"},gu:{joinChat:"ચેટમાં જોડાઓ",chatGroup:"{name} જૂથ",online:"{count} ઓનલાઇન",inputPlaceholder:"સંદેશ લખો...",send:"મોકલો",messages:"સંદેશાઓ",today:"આજે",yesterday:"ગઈકાલે",networkError:"નેટવર્ક ભૂલ",sendFailed:"મોકલવામાં નિષ્ફળ"},ro:{joinChat:"Alătură-te chatului",chatGroup:"Grupul {name}",online:"{count} online",inputPlaceholder:"Scrie un mesaj...",send:"Trimite",messages:"mesaje",today:"Astăzi",yesterday:"Ieri",networkError:"Eroare de rețea",sendFailed:"Trimitere eșuată"},sv:{joinChat:"Gå med i chatt",chatGroup:"{name} grupp",online:"{count} online",inputPlaceholder:"Skriv ett meddelande...",send:"Skicka",messages:"meddelanden",today:"Idag",yesterday:"Igår",networkError:"Nätverksfel",sendFailed:"Det gick inte att skicka"},hu:{joinChat:"Csatlakozás a chathez",chatGroup:"{name} Csoport",online:"{count} online",inputPlaceholder:"Írjon egy üzenetet...",send:"Küldés",messages:"üzenet",today:"Ma",yesterday:"Tegnap",networkError:"Hálózati hiba",sendFailed:"Küldés sikertelen"},cs:{joinChat:"Připojit se k chatu",chatGroup:"Skupina {name}",online:"{count} online",inputPlaceholder:"Napište zprávu...",send:"Odeslat",messages:"zpráv",today:"Dnes",yesterday:"Včera",networkError:"Chyba sítě",sendFailed:"Odeslání selhalo"},el:{joinChat:"Εγγραφή στο Chat",chatGroup:"Ομάδα {name}",online:"{count} online",inputPlaceholder:"Πληκτρολογήστε ένα μήνυμα...",send:"Αποστολή",messages:"μηνύματα",today:"Σήμερα",yesterday:"Χθες",networkError:"Σφάλμα δικτύου",sendFailed:"Αποτυχία αποστολής"},da:{joinChat:"Deltag i chat",chatGroup:"{name} Gruppe",online:"{count} online",inputPlaceholder:"Skriv en besked...",send:"Send",messages:"beskeder",today:"I dag",yesterday:"I går",networkError:"Netværksfejl",sendFailed:"Kunne ikke sende"},fi:{joinChat:"Liity chattiin",chatGroup:"{name} Ryhmä",online:"{count} paikalla",inputPlaceholder:"Kirjoita viesti...",send:"Lähetä",messages:"viestiä",today:"Tänään",yesterday:"Eilen",networkError:"Verkkovirhe",sendFailed:"Lähetys epäonnistui"},no:{joinChat:"Bli med i chat",chatGroup:"{name} Gruppe",online:"{count} pålogget",inputPlaceholder:"Skriv en melding...",send:"Send",messages:"meldinger",today:"I dag",yesterday:"I går",networkError:"Nettverksfeil",sendFailed:"Sending mislyktes"},he:{joinChat:"הצטרף לצ'אט",chatGroup:"קבוצת {name}",online:"{count} מחוברים",inputPlaceholder:"הקלד הודעה...",send:"שלח",messages:"הודעות",today:"היום",yesterday:"אתמול",networkError:"שגיאת רשת",sendFailed:"השליחה נכשלה"},tl:{joinChat:"Sumali sa Chat",chatGroup:"Grupong {name}",online:"{count} online",inputPlaceholder:"Mag-type ng mensahe...",send:"Ipadala",messages:"mga mensahe",today:"Ngayon",yesterday:"Kahapon",networkError:"Error sa network",sendFailed:"Nabigong ipadala"},sw:{joinChat:"Jiunge na Gumzo",chatGroup:"Kundi la {name}",online:"{count} mtandaoni",inputPlaceholder:"Andika ujumbe...",send:"Tuma",messages:"jumbe",today:"Leo",yesterday:"Jana",networkError:"Tatizo la mtandao",sendFailed:"Imeshindwa kutuma"},"pt-BR":{joinChat:"Entrar no Chat",chatGroup:"Grupo {name}",online:"{count} online",inputPlaceholder:"Escreva uma mensagem...",send:"Enviar",messages:"mensagens",today:"Hoje",yesterday:"Ontem",networkError:"Erro de rede",sendFailed:"Falha ao enviar"}};function p(e){if(g[e])return g[e];const t=e.split("-")[0];return g[t]?g[t]:g.en}function y(e,t){return e.replace(/\{(\w+)\}/g,(e,s)=>void 0!==t[s]?String(t[s]):e)}class b extends t{constructor(e){var t,s;super(),this.emojiPanelOpen=!1,this.onlineCount=0,this.currentTheme="whatsapp",this.isDarkMode=!1,this.customColors={},this.visibleStartIndex=0,this.hasInitializedData=!1,this.pollingStopTimer=null,this.currentAudio=null,this.currentVoiceContainer=null,this.config={...e,mode:e.mode||"floating"},this.t=p(e.language||"en"),this.currentTheme="telegram"===e.uiTemplate?"telegram":"whatsapp",this.isDarkMode="dark"===e.theme,this.customColors={primary:e.primaryColor,background:e.backgroundColor},this.onlineCount=500+Math.floor(301*Math.random()),this.initialRenderCount=null!==(t=this.config.initialRenderCount)&&void 0!==t?t:Number.MAX_SAFE_INTEGER,this.lazyLoadBatchSize=null!==(s=this.config.lazyLoadBatchSize)&&void 0!==s?s:20,this.state={isInitialized:!1,isOpen:!1,isJoined:!1,isConnected:!1,isSimulationRunning:!1,isSimulationPaused:!1,messages:[],virtualUsers:[],realUsers:[],typingUsers:[],simulationEnded:!1,displayedMessageCount:0,unreadCount:0,lastReadMessageId:null},this.apiClient=new u(e),this.simulator=new m(e,this.apiClient),this.setupSimulatorEvents(),this.init()}init(){try{this.setupContainer(),this.createWidget(),"floating"===this.config.mode&&(this.widgetElement.style.display="none",this.createFloatingButton()),this.setupEventListeners(),this.setupImageViewer(),this.state.isInitialized=!0,this.emit("ready")}catch(t){this.emit("error",new e("Failed to initialize chat widget","WIDGET_INIT_ERROR",t))}}setupSimulatorEvents(){this.simulator.on("initialized",e=>{var t;this.state.currentProject=e.project,this.state.currentTemplate=e.template,null!=this.config.initialRenderCount?this.initialRenderCount=this.config.initialRenderCount:this.initialRenderCount=Number.MAX_SAFE_INTEGER,this.setTitle((null===(t=e.project)||void 0===t?void 0:t.name)||"Chat",`0 ${this.t.messages}`),this.setLoading(!1),this.emit("simulationInitialized",e)}),this.simulator.on("message",e=>{var t;this.setLoading(!1),this.addMessage(e),this.state.displayedMessageCount++;const s=(null===(t=this.state.currentProject)||void 0===t?void 0:t.name)||"Chat";this.setTitle(s,`${this.state.displayedMessageCount} ${this.t.messages}`)}),this.simulator.on("messages-batch",e=>{var t;this.setLoading(!1),this.addMessagesBulk(e),this.state.displayedMessageCount+=e.length;const s=(null===(t=this.state.currentProject)||void 0===t?void 0:t.name)||"Chat";this.setTitle(s,`${this.state.displayedMessageCount} ${this.t.messages}`),setTimeout(()=>{this.scrollToBottom(!0)},100)}),this.simulator.on("simulationStart",()=>{var e,t;this.state.isSimulationRunning=!0,this.state.isSimulationPaused=!1,null===(t=(e=this.config).onSimulationStart)||void 0===t||t.call(e)}),this.simulator.on("simulationEnd",()=>{var e,t;this.state.isSimulationRunning=!1,this.state.simulationEnded=!0,null===(t=(e=this.config).onSimulationEnd)||void 0===t||t.call(e)}),this.simulator.on("simulationPause",()=>{this.state.isSimulationPaused=!0}),this.simulator.on("simulationResume",()=>{this.state.isSimulationPaused=!1}),this.simulator.on("error",e=>{this.emit("error",e)})}async initializeSimulation(){try{await this.simulator.initialize()}catch(t){this.emit("error",new e("Failed to initialize simulation","SIMULATION_INIT_ERROR",t))}}setupContainer(){var t;const s=function(e){if("string"==typeof e)return document.querySelector(e)||document.body;return e||document.body}(this.config.container);if(!s)throw new e("Container element not found","CONTAINER_NOT_FOUND");const n=null===(t=s.tagName)||void 0===t?void 0:t.toUpperCase();if("BODY"===n||"HTML"===n){const e=document.createElement("div");e.className="chat-sdk-host",e.style.position="static",e.style.width="0",e.style.height="0",document.body.appendChild(e),this.container=e}else this.container=s;this.shadowRoot=this.container.attachShadow({mode:"closed"});const i=this.getDefaultStyles();!function(e,t){const s=document.createElement("style");s.textContent=t,e.appendChild(s)}(this.shadowRoot,i)}createWidget(){var e;if(this.widgetElement&&this.messagesContainer)return;this.widgetElement=s("div","chat-sdk-container");const t="telegram"===this.config.uiTemplate?"telegram":"whatsapp";this.currentTheme=t,this.widgetElement.classList.add(`${t}-theme`),"telegram"===t&&"dark"===this.config.theme&&(this.widgetElement.classList.add("dark"),this.isDarkMode=!0),this.widgetElement.style.position="fixed",this.widgetElement.style.top="0",this.widgetElement.style.left="0",this.widgetElement.style.width="100vw",this.widgetElement.style.height="100vh",this.widgetElement.style.zIndex=String(null!==(e=this.config.zIndex)&&void 0!==e?e:2147483e3),this.widgetElement.innerHTML=`\n <div class="chat-sdk-header">\n <div class="chat-sdk-header-left">\n <div class="chat-sdk-title" id="chat-title"></div>\n <div class="chat-sdk-subtitle" id="chat-subtitle"></div>\n </div>\n <button class="chat-sdk-close-btn" type="button">\n <svg width="20" height="20" viewBox="0 0 16 16" fill="currentColor">\n <path d="M8 7.293l2.146-2.147a.5.5 0 01.708.708L8.707 8l2.147 2.146a.5.5 0 01-.708.708L8 8.707l-2.146 2.147a.5.5 0 01-.708-.708L7.293 8 5.146 5.854a.5.5 0 01.708-.708L8 7.293z"/>\n </svg>\n </button>\n </div>\n\n <div class="chat-sdk-messages" id="messages-container">\n <div class="chat-sdk-loading">\n <div class="chat-sdk-spinner"></div>\n Loading chat...\n </div>\n </div>\n\n <div class="chat-sdk-input-area">\n <button class="chat-sdk-icon-btn chat-sdk-emoji-btn" type="button" id="emoji-button" aria-label="Emoji">\n <span>😊</span>\n </button>\n <button class="chat-sdk-icon-btn chat-sdk-image-btn" type="button" id="image-button" aria-label="Image">\n <svg width="16" height="16" viewBox="0 0 24 24" fill="currentColor"><path d="M21 19V5a2 2 0 0 0-2-2H5a2 2 0 0 0-2 2v14h18zM5 5h14v8l-3-3-4 5-3-4-4 4V5z"/></svg>\n </button>\n <textarea\n class="chat-sdk-input"\n placeholder="${this.t.inputPlaceholder}"\n rows="1"\n id="message-input"\n ></textarea>\n <input type="file" accept="image/*" id="image-input" style="display:none" />\n <button class="chat-sdk-send-btn" type="button" id="send-button" disabled>\n <svg width="16" height="16" viewBox="0 0 16 16" fill="currentColor">\n <path d="M15.854.146a.5.5 0 01.11.54l-5.819 14.547a.75.75 0 01-1.329.124l-3.178-4.995L.643 7.184a.75.75 0 01.124-1.33L15.314.037a.5.5 0 01.54.11z"/>\n </svg>\n </button>\n </div>\n <div class="chat-sdk-emoji-picker" id="emoji-picker" style="display:none">\n <div class="chat-sdk-emoji-grid">\n <button type="button" class="chat-sdk-emoji-item" data-emoji="😀">😀</button>\n <button type="button" class="chat-sdk-emoji-item" data-emoji="😁">😁</button>\n <button type="button" class="chat-sdk-emoji-item" data-emoji="😂">😂</button>\n <button type="button" class="chat-sdk-emoji-item" data-emoji="🤣">🤣</button>\n <button type="button" class="chat-sdk-emoji-item" data-emoji="😊">😊</button>\n <button type="button" class="chat-sdk-emoji-item" data-emoji="😍">😍</button>\n <button type="button" class="chat-sdk-emoji-item" data-emoji="😎">😎</button>\n <button type="button" class="chat-sdk-emoji-item" data-emoji="🤔">🤔</button>\n <button type="button" class="chat-sdk-emoji-item" data-emoji="👍">👍</button>\n <button type="button" class="chat-sdk-emoji-item" data-emoji="🙏">🙏</button>\n </div>\n </div>\n `,this.messagesContainer=this.widgetElement.querySelector("#messages-container"),this.inputElement=this.widgetElement.querySelector("#message-input"),this.sendButton=this.widgetElement.querySelector("#send-button"),this.emojiButton=this.widgetElement.querySelector("#emoji-button"),this.imageButton=this.widgetElement.querySelector("#image-button"),this.fileInput=this.widgetElement.querySelector("#image-input"),this.emojiPicker=this.widgetElement.querySelector("#emoji-picker"),this.shadowRoot.appendChild(this.widgetElement)}setupEventListeners(){var e,t,s,n;const i=this.widgetElement.querySelector(".chat-sdk-close-btn");null==i||i.addEventListener("click",()=>this.close()),this.messagesContainer.addEventListener("scroll",this.handleScrollLazyLoad.bind(this)),this.inputElement.addEventListener("input",this.handleInputChange.bind(this)),this.inputElement.addEventListener("keydown",this.handleKeyDown.bind(this)),this.sendButton.addEventListener("click",this.handleSendMessage.bind(this)),this.inputElement.addEventListener("input",this.autoResizeTextarea.bind(this)),null===(e=this.emojiButton)||void 0===e||e.addEventListener("click",e=>{e.preventDefault(),e.stopPropagation(),this.toggleEmojiPicker(!this.emojiPanelOpen)}),null===(t=this.emojiPicker)||void 0===t||t.addEventListener("click",e=>{const t=e.target.closest(".chat-sdk-emoji-item");if(t&&t.hasAttribute("data-emoji")){const e=t.getAttribute("data-emoji")||"";this.insertEmojiAtCursor(e),this.toggleEmojiPicker(!1)}}),this.shadowRoot.addEventListener("click",e=>{const t=e.target,s=t.closest("#emoji-picker"),n=t.closest("#emoji-button");s||n||this.toggleEmojiPicker(!1)}),null===(s=this.imageButton)||void 0===s||s.addEventListener("click",e=>{var t;e.preventDefault(),e.stopPropagation(),null===(t=this.fileInput)||void 0===t||t.click()}),null===(n=this.fileInput)||void 0===n||n.addEventListener("change",this.handleImageSelected.bind(this)),document.addEventListener("keydown",e=>{if("Escape"===e.key){const e=document.querySelector(".chat-sdk-viewer-overlay");if(e)return e.style.opacity="0",void setTimeout(()=>e.remove(),200);this.state.isOpen&&this.close()}})}openImageZoom(e){const t=document.querySelector(".chat-sdk-global-zoom-overlay");t&&t.remove();const s=document.createElement("div");s.className="chat-sdk-global-zoom-overlay",Object.assign(s.style,{position:"fixed",top:"0",left:"0",width:"100vw",height:"100vh",backgroundColor:"rgba(0, 0, 0, 0.85)",zIndex:"2147483647",display:"flex",justifyContent:"center",alignItems:"center",cursor:"zoom-out",backdropFilter:"blur(4px)",opacity:"0",transition:"opacity 0.2s ease-in-out"});const n=document.createElement("img");n.src=e,Object.assign(n.style,{maxWidth:"80%",maxHeight:"90%",width:"80%",objectFit:"contain",borderRadius:"8px",boxShadow:"0 4px 20px rgba(0,0,0,0.5)",transform:"scale(0.9)",transition:"transform 0.2s cubic-bezier(0.1, 0.9, 0.2, 1)"}),s.addEventListener("click",()=>{s.style.opacity="0",n.style.transform="scale(0.9)",setTimeout(()=>s.remove(),200)}),s.appendChild(n),document.body.appendChild(s),requestAnimationFrame(()=>{s.style.opacity="1",n.style.transform="scale(1)"})}createFloatingButton(){var e,t,s,n,i,a,o,r,d,l,h;if(!this.shadowRoot)return;const c=this.config.floatingButton||{},m=c.position||"bottom-right",u=String(null!==(t=null!==(e=c.zIndex)&&void 0!==e?e:this.config.zIndex)&&void 0!==t?t:2147483e3),g={top:null===(s=c.offset)||void 0===s?void 0:s.top,right:null===(n=c.offset)||void 0===n?void 0:n.right,bottom:null!==(a=null===(i=c.offset)||void 0===i?void 0:i.bottom)&&void 0!==a?a:20,left:null===(o=c.offset)||void 0===o?void 0:o.left},p=document.createElement("button");p.className="chat-sdk-floating-btn",p.setAttribute("aria-label","Open chat");const y=this.t.joinChat;p.innerHTML=`\n <div style="\n position: relative;\n width: 100%;\n height: 100%;\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n padding: 6px;\n ">\n \x3c!-- Group chat icon (users) --\x3e\n <svg width="28" height="28" viewBox="0 0 24 24" fill="currentColor" style="margin-bottom: 2px;">\n <path d="M16 11c1.66 0 2.99-1.34 2.99-3S17.66 5 16 5c-1.66 0-3 1.34-3 3s1.34 3 3 3zm-8 0c1.66 0 2.99-1.34 2.99-3S9.66 5 8 5C6.34 5 5 6.34 5 8s1.34 3 3 3zm0 2c-2.33 0-7 1.17-7 3.5V19h14v-2.5c0-2.33-4.67-3.5-7-3.5zm8 0c-.29 0-.62.02-.97.05 1.16.84 1.97 1.97 1.97 3.45V19h6v-2.5c0-2.33-4.67-3.5-7-3.5z"/>\n </svg>\n\n \x3c!-- Text overlay at bottom --\x3e\n <div style="\n font-size: 10px;\n font-weight: 600;\n color: rgba(255, 255, 255, 0.95);\n text-align: center;\n line-height: 1.2;\n letter-spacing: 0.3px;\n text-shadow: 0 1px 2px rgba(0,0,0,0.2);\n ">${y}</div>\n\n \x3c!-- Unread badge --\x3e\n <span class="chat-sdk-unread-badge" style="\n position: absolute;\n top: -6px;\n right: -6px;\n background: #ff4444;\n color: white;\n border-radius: 10px;\n min-width: 18px;\n height: 18px;\n display: none;\n align-items: center;\n justify-content: center;\n font-size: 10px;\n font-weight: 700;\n line-height: 1;\n border: 2px solid white;\n box-shadow: 0 2px 4px rgba(0,0,0,0.3);\n padding: 0 5px;\n "></span>\n </div>\n `,p.style.position="fixed",p.style.zIndex=u,p.style.width="60px",p.style.height="60px",p.style.borderRadius="50%",p.style.border="none",p.style.cursor="pointer",p.style.display="flex",p.style.alignItems="center",p.style.justifyContent="center",p.style.color="#fff",p.style.boxShadow="0 10px 24px rgba(0,0,0,0.25), inset 0 2px 4px rgba(255,255,255,0.15)",p.style.background="linear-gradient(145deg, #25D366 0%, #128C7E 100%)",p.style.transition="transform .15s ease, box-shadow .15s ease",p.style.overflow="visible",m.includes("bottom")?(p.style.bottom=(null!==(r=g.bottom)&&void 0!==r?r:20)+"px",p.style.top=""):(p.style.top=(null!==(d=g.top)&&void 0!==d?d:20)+"px",p.style.bottom=""),m.includes("right")?(p.style.right=(null!==(l=g.right)&&void 0!==l?l:20)+"px",p.style.left=""):(p.style.left=(null!==(h=g.left)&&void 0!==h?h:20)+"px",p.style.right=""),p.addEventListener("mouseenter",()=>{p.style.transform="scale(1.06)",p.style.boxShadow="0 14px 28px rgba(0,0,0,0.30), inset 0 2px 4px rgba(255,255,255,0.2)"}),p.addEventListener("mouseleave",()=>{p.style.transform="scale(1)",p.style.boxShadow="0 10px 24px rgba(0,0,0,0.25), inset 0 2px 4px rgba(255,255,255,0.15)"}),p.addEventListener("mousedown",()=>{p.style.transform="scale(0.95)"}),p.addEventListener("mouseup",()=>{p.style.transform="scale(1.05)",setTimeout(()=>p.style.transform="scale(1)",100)}),p.addEventListener("click",e=>{e.preventDefault(),this.open()}),this.shadowRoot.appendChild(p),this.floatingButtonEl=p}updateUnreadBadge(){if(!this.floatingButtonEl)return;const e=this.floatingButtonEl.querySelector(".chat-sdk-unread-badge");if(!e)return;const t=this.state.unreadCount;t>0?(e.textContent=t>99?"99+":t.toString(),e.style.display="flex"):e.style.display="none"}markAllAsRead(){if(this.state.messages.length>0){const e=this.state.messages[this.state.messages.length-1];this.state.lastReadMessageId=e.id}this.state.unreadCount=0,this.updateUnreadBadge()}incrementUnreadCount(){this.state.isOpen||(this.state.unreadCount++,this.updateUnreadBadge())}toggleEmojiPicker(e){const t=this.emojiPicker;if(!t)return;const s="boolean"==typeof e?e:"none"===t.style.display;t.style.display=s?"block":"none",this.emojiPanelOpen=s}insertEmojiAtCursor(e){const t=this.inputElement,s=t.selectionStart||0,n=t.selectionEnd||0,i=t.value.substring(0,s),a=t.value.substring(n);t.value=i+e+a;const o=s+e.length;t.setSelectionRange(o,o),t.focus(),this.handleInputChange(),this.autoResizeTextarea()}isEmojiOnly(e){const t=e.trim();if(!t)return!1;if(t.length>6)return!1;let s=!1;for(let e=0;e<t.length;){const n=t.codePointAt(e)||0;if(e+=n>65535?2:1,!(n>=126976))return!1;s=!0}return s}async handleImageSelected(){const t=this.fileInput;if(!t||!t.files||0===t.files.length)return;const s=t.files[0];try{const e=await this.resizeImageFile(s,1280,.85),n={id:`local-img-failed-${Date.now()}-${Math.random().toString(36).slice(2,8)}`,content:e,messageType:"image",timestamp:new Date,isOwnMessage:!0,user:{id:this.config.userId||"me",username:this.config.username||"You"},failed:!0};this.state.messages.push(n),this.renderMessage(n),this.scrollToBottom(!0),t.value=""}catch(t){console.error("Image processing failed",t),this.emit("error",new e("Image processing failed","IMAGE_PROCESS_ERROR",t))}}resizeImageFile(e,t=1280,s=.85){return new Promise((n,i)=>{const a=URL.createObjectURL(e),o=new Image;o.onload=()=>{let{width:e,height:r}=o;const d=Math.min(1,t/Math.max(e,r)),l=document.createElement("canvas");d<1&&(e=Math.round(e*d),r=Math.round(r*d)),l.width=e,l.height=r;const h=l.getContext("2d");if(!h)return URL.revokeObjectURL(a),void i(new Error("Canvas not supported"));h.drawImage(o,0,0,e,r);const c=l.toDataURL("image/jpeg",s);URL.revokeObjectURL(a),n(c)},o.onerror=e=>{URL.revokeObjectURL(a),i(e)},o.src=a})}handleInputChange(){const e=this.inputElement.value.trim().length>0,t=!1!==this.config.enableUserInput&&!1!==this.config.allowInput;this.sendButton.disabled=!e||!t,e&&t&&this.emit("typing")}handleKeyDown(e){"Enter"!==e.key||e.shiftKey||(e.preventDefault(),this.handleSendMessage())}async handleSendMessage(){const t=this.inputElement.value.trim();if(!t)return;if(!1===this.config.enableUserInput||!1===this.config.allowInput)return;const s=this.isEmojiOnly(t)?"emoji":"text",n={id:`local-${Date.now()}-${Math.random().toString(36).slice(2,8)}`,content:t,messageType:s,timestamp:new Date,isOwnMessage:!0,user:{id:this.config.userId||"me",username:this.config.username||"You"}};this.state.messages.push(n),this.renderMessage(n),this.scrollToBottom(!0),this.inputElement.value="",this.sendButton.disabled=!0,this.autoResizeTextarea(),this.simulator.sendMessage(t,s).catch(t=>{console.error("Failed to send message:",t),this.emit("error",new e("Failed to send message","SEND_MESSAGE_ERROR",t))})}autoResizeTextarea(){this.inputElement.style.height="auto",this.inputElement.style.height=Math.min(this.inputElement.scrollHeight,100)+"px"}open(){var e;if(this.state.isOpen)return;if(this.hasInitializedData)try{this.simulator.startPolling()}catch(e){}else this.hasInitializedData=!0,this.setLoading(!0),this.initializeSimulation().catch(e=>{console.error("Failed to initialize simulation on open:",e),this.setLoading(!1)});this.pollingStopTimer&&(clearTimeout(this.pollingStopTimer),this.pollingStopTimer=null),this.floatingButtonEl&&(this.floatingButtonEl.style.display="none"),this.widgetElement.style.opacity="0",this.widgetElement.style.display="flex",requestAnimationFrame(()=>{this.widgetElement.style.transition="opacity .2s ease",this.widgetElement.style.opacity="1"}),this.state.isOpen=!0,this.markAllAsRead(),this.emit("open");const t=(null===(e=this.state.currentProject)||void 0===e?void 0:e.name)||"Chat";this.setTitle(t,`${this.state.displayedMessageCount} ${this.t.messages}`),this.scrollToBottom(!0),requestAnimationFrame(()=>this.scrollToBottom(!0)),setTimeout(()=>this.scrollToBottom(!0),0)}close(){this.state.isOpen&&(this.widgetElement.style.transition="opacity .2s ease",this.widgetElement.style.opacity="0",setTimeout(()=>{this.widgetElement.style.display="none",this.floatingButtonEl&&(this.floatingButtonEl.style.display="flex")},200),this.state.isOpen=!1,this.pollingStopTimer&&clearTimeout(this.pollingStopTimer),this.pollingStopTimer=setTimeout(()=>{try{this.simulator.stopPolling()}catch(e){}this.pollingStopTimer=null},1e4),this.emit("close"))}setTitle(e,t){var s,n;const i=null===(s=this.widgetElement)||void 0===s?void 0:s.querySelector("#chat-title"),a=null===(n=this.widgetElement)||void 0===n?void 0:n.querySelector("#chat-subtitle"),o=y(this.t.chatGroup,{name:e||"Chat"});this.currentTheme,i&&(i.textContent=o),a&&(a.textContent=y(this.t.online,{count:this.onlineCount}),a.style.display="block")}buildMessageElement(e,t){const n=s("div","chat-sdk-message");e.isOwnMessage&&n.classList.add("own");const i=!!t&&this.shouldGroupWithPrev(t,e);i&&n.classList.add("grouped");let a=null;e.isOwnMessage||(a=this.createAvatar(e),i&&a&&(a.style.visibility="hidden"));const o=!e.isOwnMessage&&!i,r="whatsapp"===this.currentTheme,d="telegram"===this.currentTheme&&e.isOwnMessage,l=this.createMessageContent(e,o,r,d);return a&&n.appendChild(a),n.appendChild(l),n}shouldGroupWithPrev(e,t){var s,n,i,a,o,r,d;if(!1===this.config.groupMessages)return!1;const l=null!==(s=this.config.groupTimeThresholdSec)&&void 0!==s?s:120,h=e.isOwnMessage===t.isOwnMessage,c=(null===(n=e.virtualUser)||void 0===n?void 0:n.id)&&(null===(i=e.virtualUser)||void 0===i?void 0:i.id)===(null===(a=t.virtualUser)||void 0===a?void 0:a.id),m=(null===(o=e.user)||void 0===o?void 0:o.id)&&(null===(r=e.user)||void 0===r?void 0:r.id)===(null===(d=t.user)||void 0===d?void 0:d.id),u=h&&(c||m||e.isOwnMessage&&t.isOwnMessage),g=Math.abs(t.timestamp.getTime()-e.timestamp.getTime())/1e3;return!!u&&g<=l}handleScrollLazyLoad(){if(this.messagesContainer.scrollTop<=20&&this.visibleStartIndex>0){const e=this.messagesContainer.scrollHeight,t=this.lazyLoadBatchSize,s=Math.max(0,this.visibleStartIndex-t),n=this.state.messages.slice(s,this.visibleStartIndex),i=document.createDocumentFragment();for(const e of n){const t=this.buildMessageElement(e);i.appendChild(t)}this.messagesContainer.insertBefore(i,this.messagesContainer.firstChild),this.visibleStartIndex=s;const a=this.messagesContainer.scrollHeight;this.messagesContainer.scrollTop+=a-e}}setLoading(e){if(e){if(!this.messagesContainer.querySelector(".chat-sdk-loading")){const e=document.createElement("div");e.className="chat-sdk-loading",e.innerHTML='\n <div class="chat-sdk-spinner"></div>\n Loading chat...\n ',this.messagesContainer.appendChild(e)}}else{const e=this.messagesContainer.querySelector(".chat-sdk-loading");null==e||e.remove()}}showJoinOverlay(){const e=s("div","chat-sdk-overlay");e.innerHTML='\n <div class="chat-sdk-join-card">\n <h3 class="chat-sdk-join-title">Join the conversation</h3>\n <p class="chat-sdk-join-description">\n Click below to join this group chat and start interacting with other members.\n </p>\n <button class="chat-sdk-join-btn" type="button">Join Chat</button>\n </div>\n ';const t=e.querySelector(".chat-sdk-join-btn");null==t||t.addEventListener("click",()=>{this.hideJoinOverlay(),this.emit("join-requested")}),this.widgetElement.appendChild(e)}hideJoinOverlay(){const e=this.widgetElement.querySelector(".chat-sdk-overlay");e&&e.remove()}addMessage(e){if(e.isOwnMessage)for(let t=this.state.messages.length-1;t>=0;t--){const s=this.state.messages[t];if(s.isOwnMessage&&s.content===e.content){if(Math.abs(e.timestamp.getTime()-s.timestamp.getTime())<=1e4)return;break}}this.state.messages.find(t=>t.id===e.id)?console.warn("Duplicate message detected and ignored:",e.id):(this.state.messages.push(e),this.renderMessage(e),e.isOwnMessage||this.incrementUnreadCount(),this.scrollToBottom(!0))}addMessagesBulk(e){if(!e||0===e.length)return;if(0===this.messagesContainer.querySelectorAll(".chat-sdk-message").length){this.state.messages=[...e].sort((e,t)=>e.timestamp.getTime()-t.timestamp.getTime());const t=this.state.messages.length,s=this.initialRenderCount;this.visibleStartIndex=Math.max(0,t-s);const n=this.state.messages.slice(this.visibleStartIndex),i=document.createDocumentFragment();let a;for(const e of n){const t=this.buildMessageElement(e,a);i.appendChild(t),a=e}this.messagesContainer.appendChild(i),setTimeout(()=>{this.scrollToBottom(!0)},0)}else{const t=new Set(this.state.messages.map(e=>e.id)),s=e.filter(e=>!t.has(e.id));if(s.length>0){this.state.messages.push(...s),this.state.messages.sort((e,t)=>e.timestamp.getTime()-t.timestamp.getTime()),this.messagesContainer.innerHTML="";const e=this.state.messages.length,t=this.initialRenderCount;this.visibleStartIndex=Math.max(0,e-t);const n=this.state.messages.slice(this.visibleStartIndex),i=document.createDocumentFragment();let a;for(const e of n){const t=this.buildMessageElement(e,a);i.appendChild(t),a=e}this.messagesContainer.appendChild(i),this.scrollToBottom()}}}reRenderAllMessages(){this.messagesContainer.innerHTML="";const e=this.state.messages.length,t=Math.max(0,e-this.initialRenderCount);this.state.messages.slice(t).forEach(e=>{this.renderMessage(e)}),this.scrollToBottom()}renderMessage(e){const t=this.state.messages.length-1,s=t>0?this.state.messages[t-1]:void 0,n=this.buildMessageElement(e,s);this.messagesContainer.appendChild(n)}createAvatar(e){var t,n,i,a;const o=s("div","chat-sdk-message-avatar");if(null===(t=e.virtualUser)||void 0===t?void 0:t.avatar)o.style.backgroundImage=`url(${e.virtualUser.avatar})`,o.style.backgroundSize="cover",o.style.backgroundPosition="center";else if(null===(n=e.user)||void 0===n?void 0:n.avatar)o.style.backgroundImage=`url(${e.user.avatar})`,o.style.backgroundSize="cover",o.style.backgroundPosition="center";else{const t=(null===(i=e.virtualUser)||void 0===i?void 0:i.username)||(null===(a=e.user)||void 0===a?void 0:a.username)||"U";o.textContent=t.charAt(0).toUpperCase()}return o}createMessageContent(e,t=!0,i=!1,a=!1){var o,r,d;const l=s("div","chat-sdk-message-content"),h=(null===(o=e.virtualUser)||void 0===o?void 0:o.displayName)||(null===(r=e.virtualUser)||void 0===r?void 0:r.username)||(null===(d=e.user)||void 0===d?void 0:d.username)||"Unknown";let c="";if("image"===e.messageType){c=`\n <div class="chat-sdk-message-image${e.failed?" failed":""}">\n <img src="${n(e.content)}" alt="Image"\n style="max-width: 200px; max-height: 280px; width: 100%; height: auto; cursor: pointer; display: block; border-radius: 8px; object-fit: cover;"\n data-image-url="${n(e.content)}"\n class="chat-sdk-image-preview" />\n </div>\n `}else if("audio"===e.messageType){c=`\n <div class="chat-sdk-voice-msg" data-audio-src="${n(e.audioUrl||e.content||"")}" style="display:flex;align-items:center;gap:8px;min-width:200px;max-width:260px;padding:4px 2px;">\n <button class="chat-sdk-voice-play-btn" style="width:36px;height:36px;border-radius:50%;border:none;background:rgba(255,255,255,0.22);color:#fff;font-size:16px;cursor:pointer;display:flex;align-items:center;justify-content:center;flex-shrink:0;transition:background 0.15s;">\n <svg width="16" height="18" viewBox="0 0 16 18" fill="currentColor"><path d="M2 1.5v15l12-7.5L2 1.5z"/></svg>\n </button>\n <div class="chat-sdk-voice-waveform" style="display:flex;align-items:center;flex:1;height:28px;overflow:hidden;">\n ${Array.from({length:28},()=>`<span class="chat-sdk-voice-bar" style="display:inline-block;width:3px;height:${4+Math.floor(18*Math.random())}px;border-radius:1.5px;background:rgba(255,255,255,0.45);margin:0 1px;transition:background 0.15s;vertical-align:middle;flex-shrink:0"></span>`).join("")}\n </div>\n <span class="chat-sdk-voice-duration" style="font-size:11px;color:rgba(255,255,255,0.75);min-width:32px;text-align:right;flex-shrink:0;font-variant-numeric:tabular-nums;">0:00</span>\n </div>`}else c="emoji"===e.messageType?`<div class="chat-sdk-message-emoji" style="font-size: 2em; line-height: 1;">${n(e.content)}</div>`:`<p class="chat-sdk-message-text">${n(e.content)}</p>`;const m=`${function(e,t){const s=new Date,n=Math.floor((s.getTime()-e.getTime())/1e3),i=(t||("undefined"!=typeof navigator?navigator.language:"en")).toLowerCase().startsWith("zh");if(n<60)return i?"刚刚":"just now";if(n<3600){const e=Math.floor(n/60);return i?`${e} 分钟前`:`${e}m ago`}if(n<86400){const e=Math.floor(n/3600);return i?`${e} 小时前`:`${e}h ago`}const a=new Date(s.getFullYear(),s.getMonth(),s.getDate());if(e>=new Date(a.getTime()-864e5)&&e<a){const t=e.toLocaleTimeString(i?"zh-CN":void 0,{hour:"2-digit",minute:"2-digit",hour12:!1});return i?`昨天 ${t}`:`yesterday ${t}`}return s.getTime()-e.getTime()<6048e5?e.toLocaleString(i?"zh-CN":void 0,{month:"short",day:"numeric",hour:"2-digit",minute:"2-digit",hour12:!1}):e.toLocaleString(i?"zh-CN":void 0,{year:"numeric",month:"2-digit",day:"2-digit",hour:"2-digit",minute:"2-digit",hour12:!1})}(e.timestamp,this.config.language)}`,u=a?'<span class="chat-sdk-read-status">✓✓</span>':"",g=e.failed&&e.isOwnMessage?'<div class="chat-sdk-message-failed-indicator">\n <svg width="16" height="16" viewBox="0 0 16 16" fill="currentColor">\n <circle cx="8" cy="8" r="8" fill="#ff4444"/>\n <path d="M8 4v4M8 10h.01" stroke="white" stroke-width="1.5" stroke-linecap="round"/>\n </svg>\n </div>':"";return l.innerHTML=i?`\n <div class="chat-sdk-message-bubble">\n ${t&&!e.isOwnMessage?`<div class="chat-sdk-message-username">${n(h)}</div>`:""}\n ${c}\n <div class="chat-sdk-message-time-inside">${m}${u?" "+u:""}</div>\n </div>\n ${g}\n `:`\n ${t&&!e.isOwnMessage?`<div class="chat-sdk-message-username">${n(h)}</div>`:""}\n <div class="chat-sdk-message-bubble">\n ${c}\n </div>\n <div class="chat-sdk-message-time">${m}${u?" "+u:""}</div>\n ${g}\n `,l}scrollToBottom(e=!1){const t=this.messagesContainer;if(e)return void i(t);t.scrollTop+t.clientHeight>=t.scrollHeight-40&&i(t)}setupImageViewer(){this.messagesContainer.addEventListener("click",e=>{const t=e.target;if(t.classList.contains("chat-sdk-image-preview")){const e=t.getAttribute("data-image-url");e&&this.openImageViewer(e)}}),this.messagesContainer.addEventListener("click",e=>{const t=e.target.closest(".chat-sdk-voice-play-btn");if(!t)return;const s=t.closest(".chat-sdk-voice-msg");if(!s)return;const n=s.getAttribute("data-audio-src");n&&this.handleVoicePlay(s,n,t)})}handleVoicePlay(e,t,s){const n=e.querySelector(".chat-sdk-voice-waveform"),i=e.querySelector(".chat-sdk-voice-duration"),a=null==n?void 0:n.querySelectorAll(".chat-sdk-voice-bar");if(!n||!i||!a.length)return;if(this.currentVoiceContainer===e&&this.currentAudio&&!this.currentAudio.paused)return this.currentAudio.pause(),void(s.innerHTML='<svg width="16" height="18" viewBox="0 0 16 18" fill="currentColor"><path d="M2 1.5v15l12-7.5L2 1.5z"/></svg>');this.currentAudio&&(this.currentAudio.pause(),this.currentAudio.currentTime=0,this.resetVoiceUI(this.currentVoiceContainer));const o=new Audio(t);this.currentAudio=o,this.currentVoiceContainer=e,s.innerHTML='<svg width="14" height="18" viewBox="0 0 14 18" fill="currentColor"><rect x="1" y="1" width="4" height="16" rx="1"/><rect x="9" y="1" width="4" height="16" rx="1"/></svg>',o.addEventListener("loadedmetadata",()=>{i.textContent=this.formatAudioDuration(o.duration)}),o.addEventListener("timeupdate",()=>{if(!o.duration)return;const e=o.currentTime/o.duration,t=Math.floor(e*a.length);a.forEach((e,s)=>{e.style.background=s<t?"rgba(255,255,255,0.95)":"rgba(255,255,255,0.45)"});const s=o.duration-o.currentTime;i.textContent=this.formatAudioDuration(s)}),o.addEventListener("ended",()=>{this.resetVoiceUI(e),this.currentAudio=null,this.currentVoiceContainer=null}),o.addEventListener("error",()=>{console.warn("[ChatSDK] Voice audio load error:",t),this.resetVoiceUI(e),this.currentAudio=null,this.currentVoiceContainer=null}),o.play().catch(t=>{console.warn("[ChatSDK] Voice play failed:",t),this.resetVoiceUI(e)})}resetVoiceUI(e){if(!e)return;const t=e.querySelector(".chat-sdk-voice-play-btn"),s=e.querySelectorAll(".chat-sdk-voice-bar"),n=e.querySelector(".chat-sdk-voice-duration");t&&(t.innerHTML='<svg width="16" height="18" viewBox="0 0 16 18" fill="currentColor"><path d="M2 1.5v15l12-7.5L2 1.5z"/></svg>'),s.forEach(e=>{e.style.background="rgba(255,255,255,0.45)"}),n&&(n.textContent="0:00")}formatAudioDuration(e){const t=Math.max(0,Math.floor(e));return`${Math.floor(t/60)}:${(t%60).toString().padStart(2,"0")}`}openImageViewer(e){const t=document.querySelector(".chat-sdk-viewer-overlay");t&&t.remove();const s=document.createElement("div");s.className="chat-sdk-viewer-overlay",Object.assign(s.style,{position:"fixed",inset:"0",width:"100vw",height:"100vh",background:"rgba(0,0,0,0.88)",zIndex:"2147483647",display:"flex",alignItems:"center",justifyContent:"center",opacity:"0",transition:"opacity 0.2s ease",cursor:"zoom-out"});const n=document.createElement("button");Object.assign(n.style,{position:"absolute",top:"16px",right:"20px",background:"none",border:"none",color:"#fff",fontSize:"32px",cursor:"pointer",lineHeight:"1",padding:"4px",zIndex:"1"}),n.innerHTML="×",n.setAttribute("aria-label","Close");const i=document.createElement("img");i.src=e,i.alt="Full size image",Object.assign(i.style,{maxWidth:"90vw",maxHeight:"90vh",objectFit:"contain",borderRadius:"8px",boxShadow:"0 8px 32px rgba(0,0,0,0.6)",transform:"scale(0.92)",transition:"transform 0.2s cubic-bezier(0.1, 0.9, 0.2, 1)",cursor:"default",display:"block"});s.addEventListener("click",e=>{e.target!==s&&e.target!==n||(s.style.opacity="0",i.style.transform="scale(0.92)",setTimeout(()=>{s.parentNode&&s.remove()},200))}),i.addEventListener("click",e=>e.stopPropagation()),s.appendChild(n),s.appendChild(i),document.body.appendChild(s),requestAnimationFrame(()=>{s.style.opacity="1",i.style.transform="scale(1)"})}showImagePreview(e){const t=s("div","chat-sdk-image-modal");t.innerHTML=`\n <div class="chat-sdk-image-modal-overlay">\n <div class="chat-sdk-image-modal-content">\n <button class="chat-sdk-image-modal-close">×</button>\n <img src="${n(e)}" alt="Image Preview" class="chat-sdk-image-modal-img" />\n </div>\n </div>\n `,this.widgetElement.appendChild(t);const i=t.querySelector(".chat-sdk-image-modal-close"),a=t.querySelector(".chat-sdk-image-modal-overlay"),o=()=>{t.remove()};null==i||i.addEventListener("click",o),null==a||a.addEventListener("click",e=>{e.target===a&&o()});const r=e=>{"Escape"===e.key&&(o(),document.removeEventListener("keydown",r))};document.addEventListener("keydown",r)}setJoined(e){this.state.isJoined=e,this.handleInputChange()}setUITemplate(e){this.currentTheme=e,this.config.uiTemplate=e,this.widgetElement.classList.remove("whatsapp-theme","telegram-theme","dark"),this.widgetElement.classList.add(`${e}-theme`),"telegram"===e&&this.isDarkMode&&this.widgetElement.classList.add("dark"),this.updateThemeStyles(),this.reRenderAllMessages()}setTheme(e){this.isDarkMode="dark"===e,this.config.theme=e,"telegram"===this.currentTheme&&(this.isDarkMode?this.widgetElement.classList.add("dark"):this.widgetElement.classList.remove("dark"),this.updateThemeStyles())}setCustomColors(e){this.customColors={...this.customColors,...e},this.config.primaryColor=e.primary,this.config.backgroundColor=e.background,this.updateThemeStyles()}updateThemeStyles(){const e=this.currentTheme,t=this.isDarkMode&&"telegram"===e,s=this.shadowRoot||document.documentElement;"whatsapp"===e?(this.setCSSProperty(s,"--chat-primary-color",this.customColors.primary||"#25D366"),this.setCSSProperty(s,"--chat-background-color",this.customColors.background||"#ECE5DD"),this.setCSSProperty(s,"--chat-message-own-bg","#DCF8C6"),this.setCSSProperty(s,"--chat-message-other-bg","#FFFFFF"),this.setCSSProperty(s,"--chat-header-bg","linear-gradient(135deg, #075e54 0%, #128c7e 100%)")):"telegram"===e&&(t?(this.setCSSProperty(s,"--chat-primary-color",this.customColors.primary||"#4FC3F7"),this.setCSSProperty(s,"--chat-background-color",this.customColors.background||"#212121"),this.setCSSProperty(s,"--chat-message-own-bg","linear-gradient(135deg, #4fc3f7 0%, #29b6f6 100%)"),this.setCSSProperty(s,"--chat-message-other-bg","#2F2F2F"),this.setCSSProperty(s,"--chat-header-bg","linear-gradient(135deg, #1976d2 0%, #1565c0 100%)"),this.setCSSProperty(s,"--chat-text-color","#FFFFFF")):(this.setCSSProperty(s,"--chat-primary-color",this.customColors.primary||"#2481CC"),this.setCSSProperty(s,"--chat-background-color",this.customColors.background||"#FFFFFF"),this.setCSSProperty(s,"--chat-message-own-bg","linear-gradient(135deg, #4fc3f7 0%, #29b6f6 100%)"),this.setCSSProperty(s,"--chat-message-other-bg","#F1F1F1"),this.setCSSProperty(s,"--chat-header-bg","linear-gradient(135deg, #2481cc 0%, #1c7cd6 100%)"),this.setCSSProperty(s,"--chat-text-color","#000000")))}setCSSProperty(e,t,s){if(e instanceof ShadowRoot){const n=e.querySelector("style");if(n){const e=n.textContent||"",i=new RegExp(`${t}\\s*:\\s*[^;]+;`,"g"),a=`${t}: ${s};`;if(i.test(e))n.textContent=e.replace(i,a);else{const t=/:host\s*\{([^}]*)\}/;t.test(e)?n.textContent=e.replace(t,(e,t)=>`:host { ${t} ${a} }`):n.textContent=`:host { ${a} }\n${e}`}}}else e.style.setProperty(t,s)}getState(){return{...this.state}}getDefaultStyles(){return"\n :host {\n --chat-primary-color: #25D366;\n --chat-background-color: #ECE5DD;\n --chat-message-own-bg: #DCF8C6;\n --chat-message-other-bg: #FFFFFF;\n --chat-header-bg: linear-gradient(135deg, #075e54 0%, #128c7e 100%);\n --chat-text-color: #333333;\n --chat-border-radius-message: 18px;\n --chat-border-radius-input: 25px;\n }\n\n .chat-sdk-container {\n font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif;\n font-size: 14px;\n line-height: 1.5;\n color: var(--chat-text-color);\n background: var(--chat-background-color);\n border-radius: 12px;\n box-shadow: 0 4px 20px rgba(0, 0, 0, 0.15);\n overflow: hidden;\n display: flex;\n flex-direction: column;\n position: relative;\n max-width: 100%;\n max-height: 100%;\n }\n\n .chat-sdk-container * {\n box-sizing: border-box;\n }\n\n /* WhatsApp Theme */\n .chat-sdk-container.whatsapp-theme .chat-sdk-header {\n background: linear-gradient(135deg, #075e54 0%, #128c7e 100%);\n color: white;\n padding: 12px 16px;\n display: flex;\n align-items: center;\n justify-content: flex-end;\n min-height: 60px;\n box-shadow: 0 1px 3px rgba(0,0,0,0.12);\n }\n .chat-sdk-container.whatsapp-theme .chat-sdk-header-left { display: none; }\n\n .chat-sdk-container.whatsapp-theme .chat-sdk-messages {\n background-color: #ece5dd;\n background-image: url(\"data:image/svg+xml,%3Csvg width='60' height='60' viewBox='0 0 60 60' xmlns='http://www.w3.org/2000/svg'%3E%3Cg fill='none' fill-rule='evenodd'%3E%3Cg fill='%23e5ddd5' fill-opacity='0.08'%3E%3Cpath d='M36 34v-4h-2v4h-4v2h4v4h2v-4h4v-2h-4zm0-30V0h-2v4h-4v2h4v4h2V6h4V4h-4zM6 34v-4H4v4H0v2h4v4h2v-4h4v-2H6zM6 4V0H4v4H0v2h4v4h2V6h4V4H6z'/%3E%3C/g%3E%3C/g%3E%3C/svg%3E\");\n padding: 8px 6px;\n }\n\n .chat-sdk-container.whatsapp-theme {\n --chat-primary-color: #25D366;\n --chat-background-color: #ECE5DD;\n --chat-message-own-bg: #DCF8C6;\n --chat-message-other-bg: #FFFFFF;\n --chat-header-bg: linear-gradient(135deg, #075e54 0%, #128c7e 100%);\n --chat-text-color: #303030;\n --chat-border-radius-message: 7.5px;\n --chat-border-radius-input: 25px;\n display: flex;\n flex-direction: column;\n height: 100%;\n }\n\n /* ── WhatsApp: Message Row Layout ── */\n .chat-sdk-container.whatsapp-theme .chat-sdk-message {\n display: flex;\n flex-direction: row;\n align-items: flex-end;\n margin-bottom: 4px;\n padding: 1px 10px;\n gap: 6px;\n }\n\n /* Own message: green bubble, right side, no avatar */\n .chat-sdk-container.whatsapp-theme .chat-sdk-message.own {\n flex-direction: row-reverse;\n justify-content: flex-start;\n }\n .chat-sdk-container.whatsapp-theme .chat-sdk-message.own .chat-sdk-message-avatar {\n display: none;\n }\n\n /* ── WhatsApp: Avatar ── */\n .chat-sdk-container.whatsapp-theme .chat-sdk-message-avatar {\n width: 32px;\n height: 32px;\n flex-shrink: 0;\n border-radius: 50%;\n align-self: flex-end;\n margin-bottom: 0;\n font-size: 13px;\n font-weight: 700;\n color: #fff;\n background: #aaa;\n }\n\n /* ── WhatsApp: Message Content Wrapper ── */\n .chat-sdk-container.whatsapp-theme .chat-sdk-message-content {\n max-width: 72%;\n min-width: 60px;\n position: relative;\n display: flex;\n flex-direction: column;\n }\n\n /* ── WhatsApp: Bubble ── */\n .chat-sdk-container.whatsapp-theme .chat-sdk-message-bubble {\n background: #fff;\n color: #303030;\n border-radius: 7.5px;\n padding: 6px 10px 20px 10px;\n box-shadow: 0 1px 0.5px rgba(0,0,0,0.13);\n position: relative;\n word-wrap: break-word;\n word-break: break-word;\n display: block;\n max-width: 100%;\n }\n\n /* Tail for other-person bubble (left bottom corner) */\n .chat-sdk-container.whatsapp-theme .chat-sdk-message:not(.own):not(.grouped) .chat-sdk-message-bubble::before {\n content: '';\n position: absolute;\n bottom: 0;\n left: -8px;\n width: 0;\n height: 0;\n border-style: solid;\n border-width: 0 0 8px 8px;\n border-color: transparent transparent #fff transparent;\n filter: drop-shadow(-1px 1px 0.5px rgba(0,0,0,0.10));\n }\n\n /* Own bubble: green */\n .chat-sdk-container.whatsapp-theme .chat-sdk-message.own .chat-sdk-message-bubble {\n background: #DCF8C6;\n color: #303030;\n border-radius: 7.5px;\n }\n\n /* Tail for own bubble (right bottom corner) */\n .chat-sdk-container.whatsapp-theme .chat-sdk-message.own:not(.grouped) .chat-sdk-message-bubble::before {\n content: '';\n position: absolute;\n bottom: 0;\n right: -8px;\n left: auto;\n width: 0;\n height: 0;\n border-style: solid;\n border-width: 8px 0 0 8px;\n border-color: transparent transparent transparent #DCF8C6;\n filter: drop-shadow(1px 1px 0.5px rgba(0,0,0,0.10));\n }\n\n /* ── WhatsApp: Username inside bubble (colored) ── */\n .chat-sdk-container.whatsapp-theme .chat-sdk-message-username {\n font-size: 12.5px;\n font-weight: 600;\n margin-bottom: 2px;\n line-height: 1.2;\n display: block;\n }\n\n /* Cycle username colors like real WhatsApp */\n .chat-sdk-container.whatsapp-theme .chat-sdk-message:nth-child(7n+1) .chat-sdk-message-username { color: #e91e8c; }\n .chat-sdk-container.whatsapp-theme .chat-sdk-message:nth-child(7n+2) .chat-sdk-message-username { color: #e67e22; }\n .chat-sdk-container.whatsapp-theme .chat-sdk-message:nth-child(7n+3) .chat-sdk-message-username { color: #1abc9c; }\n .chat-sdk-container.whatsapp-theme .chat-sdk-message:nth-child(7n+4) .chat-sdk-message-username { color: #9b59b6; }\n .chat-sdk-container.whatsapp-theme .chat-sdk-message:nth-child(7n+5) .chat-sdk-message-username { color: #e74c3c; }\n .chat-sdk-container.whatsapp-theme .chat-sdk-message:nth-child(7n+6) .chat-sdk-message-username { color: #3498db; }\n .chat-sdk-container.whatsapp-theme .chat-sdk-message:nth-child(7n+0) .chat-sdk-message-username { color: #2ecc71; }\n\n /* ── WhatsApp: Input area ── */\n .chat-sdk-container.whatsapp-theme .chat-sdk-input-area {\n background: #f0f2f5;\n border-top: none;\n padding: 8px 10px;\n }\n .chat-sdk-container.whatsapp-theme .chat-sdk-input {\n background: #fff;\n border: none;\n border-radius: 22px;\n padding: 9px 14px;\n font-size: 15px;\n box-shadow: none;\n }\n .chat-sdk-container.whatsapp-theme .chat-sdk-send-btn {\n background: #00a884;\n width: 42px;\n height: 42px;\n box-shadow: none;\n }\n\n\n /* Telegram Theme */\n .chat-sdk-container.telegram-theme {\n --chat-primary-color: #2481CC;\n --chat-background-color: #FFFFFF;\n --chat-message-own-bg: linear-gradient(135deg, #4fc3f7 0%, #29b6f6 100%);\n --chat-message-other-bg: #F1F1F1;\n --chat-header-bg: linear-gradient(135deg, #2481cc 0%, #1c7cd6 100%);\n --chat-text-color: #000000;\n --chat-border-radius-message: 12px;\n --chat-border-radius-input: 12px;\n\n /* Telegram input + details */\n .chat-sdk-container.telegram-theme .chat-sdk-message {\n align-items: flex-start; /* avatar aligns with username at top, not bottom */\n }\n .chat-sdk-container.telegram-theme .chat-sdk-message-content {\n max-width: 75%;\n }\n .chat-sdk-container.telegram-theme .chat-sdk-message-bubble {\n box-shadow: 0 1px 1px rgba(0,0,0,0.06);\n }\n .chat-sdk-container.telegram-theme .chat-sdk-input-area {\n background: #ffffff;\n border-top: 1px solid #e6e6e6;\n }\n .chat-sdk-container.telegram-theme .chat-sdk-input {\n background: #fff;\n border: 1px solid #cfd6dd;\n border-radius: 12px;\n padding: 9px 14px;\n }\n .chat-sdk-container.telegram-theme .chat-sdk-send-btn {\n background: #2481CC;\n border-radius: 10px;\n width: 38px;\n height: 36px;\n box-shadow: none;\n }\n /* Telegram dark */\n .chat-sdk-container.telegram-theme.dark .chat-sdk-input-area {\n background: #1f1f1f;\n border-top: 1px solid #2a2a2a;\n }\n .chat-sdk-container.telegram-theme.dark .chat-sdk-input {\n background: #2b2b2b;\n color: #e0e0e0;\n border-color: #444;\n }\n .chat-sdk-container.telegram-theme.dark .chat-sdk-send-btn {\n background: #1976d2;\n }\n\n\n .chat-sdk-container.telegram-theme .chat-sdk-header {\n background: var(--chat-header-bg);\n color: white;\n padding: 12px 16px;\n display: flex;\n align-items: center;\n justify-content: space-between;\n min-height: 60px;\n box-shadow: 0 1px 3px rgba(0,0,0,0.12);\n }\n\n .chat-sdk-container.telegram-theme .chat-sdk-messages {\n background-color: var(--chat-background-color);\n }\n\n .chat-sdk-container.telegram-theme .chat-sdk-message.own .chat-sdk-message-bubble {\n background: var(--chat-message-own-bg);\n color: white;\n border-radius: var(--chat-border-radius-message) var(--chat-border-radius-message) 4px var(--chat-border-radius-message);\n }\n\n .chat-sdk-container.telegram-theme .chat-sdk-message:not(.own) .chat-sdk-message-bubble {\n background: var(--chat-message-other-bg);\n color: var(--chat-text-color);\n border-radius: var(--chat-border-radius-message) var(--chat-border-radius-message) var(--chat-border-radius-message) 4px;\n }\n\n /* Telegram Dark Theme */\n .chat-sdk-container.telegram-theme.dark {\n --chat-background-color: #212121;\n --chat-message-other-bg: #2F2F2F;\n --chat-header-bg: linear-gradient(135deg, #1976d2 0%, #1565c0 100%);\n --chat-text-color: #FFFFFF;\n }\n\n /* Default header (fallback) */\n .chat-sdk-header {\n background: var(--chat-header-bg);\n color: white;\n padding: 12px 16px;\n display: flex;\n align-items: center;\n justify-content: space-between;\n min-height: 60px;\n }\n\n .chat-sdk-header-left { display: flex; flex-direction: column; gap: 2px; }\n .chat-sdk-title { font-size: 15px; font-weight: 600; }\n .chat-sdk-subtitle { font-size: 12px; opacity: 0.9; }\n\n .chat-sdk-close-btn {\n background: none;\n border: none;\n color: white;\n cursor: pointer;\n padding: 8px;\n border-radius: 50%;\n opacity: 0.8;\n transition: all 0.2s;\n display: flex;\n align-items: center;\n justify-content: center;\n width: 36px;\n height: 36px;\n }\n\n .chat-sdk-close-btn:hover {\n opacity: 1;\n background: rgba(255, 255, 255, 0.1);\n }\n\n .chat-sdk-messages {\n flex: 1;\n overflow-y: auto;\n padding: 16px;\n background: var(--chat-background-color);\n min-height: 0; /* allow flex to use full height */\n }\n\n .chat-sdk-message {\n margin-bottom: 12px;\n display: flex;\n align-items: flex-end;\n gap: 8px;\n }\n\n .chat-sdk-message.own {\n flex-direction: row-reverse;\n }\n\n .chat-sdk-message-avatar {\n width: 32px;\n height: 32px;\n border-radius: 50%;\n background: #ddd;\n display: flex;\n align-items: center;\n justify-content: center;\n font-size: 12px;\n font-weight: 600;\n color: #666;\n flex-shrink: 0;\n }\n\n .chat-sdk-message-content {\n max-width: 70%;\n position: relative;\n }\n\n .chat-sdk-message-bubble {\n background: var(--chat-message-other-bg);\n color: var(--chat-text-color);\n padding: 8px 12px;\n border-radius: var(--chat-border-radius-message);\n position: relative;\n word-wrap: break-word;\n box-shadow: 0 1px 2px rgba(0, 0, 0, 0.1);\n }\n\n .chat-sdk-message.own .chat-sdk-message-bubble {\n background: var(--chat-message-own-bg);\n color: white;\n }\n\n .chat-sdk-message-username {\n font-size: 11px;\n color: #666;\n margin-bottom: 2px;\n font-weight: 600;\n }\n\n .chat-sdk-message-text {\n margin: 0;\n line-height: 1.4;\n }\n\n .chat-sdk-message-time {\n font-size: 10px;\n color: #999;\n margin-top: 4px;\n text-align: right;\n }\n\n /* Message grouping */\n .chat-sdk-message.grouped {\n margin-top: 4px;\n }\n .chat-sdk-message.grouped .chat-sdk-message-username { display: none; }\n .chat-sdk-message.grouped .chat-sdk-message-avatar { visibility: hidden; }\n\n /* WhatsApp: time inside bubble */\n .chat-sdk-container.whatsapp-theme .chat-sdk-message-time-inside {\n position: absolute;\n right: 6px;\n bottom: 4px;\n font-size: 11px;\n color: rgba(0,0,0,0.45);\n display: flex;\n align-items: center;\n gap: 3px;\n line-height: 1;\n }\n .chat-sdk-container.whatsapp-theme .chat-sdk-message.own .chat-sdk-message-time-inside {\n color: rgba(0, 0, 0, 0.45);\n }\n /* hide external time for whatsapp (time is inside bubble) */\n .chat-sdk-container.whatsapp-theme .chat-sdk-message-time {\n display: none;\n }\n\n /* Telegram: read status */\n .chat-sdk-container.telegram-theme .chat-sdk-message-time {\n display: flex;\n align-items: center;\n justify-content: flex-end;\n gap: 6px;\n }\n .chat-sdk-container.telegram-theme .chat-sdk-message.own .chat-sdk-read-status {\n font-size: 12px;\n color: var(--chat-primary-color);\n line-height: 1;\n }\n\n /* Theme-specific image radii */\n .chat-sdk-container.whatsapp-theme .chat-sdk-message-image img { border-radius: 8px; max-width: 200px; max-height: 280px; }\n .chat-sdk-container.telegram-theme .chat-sdk-message-image img { border-radius: 6px; max-width: 200px; max-height: 280px; }\n\n\n .chat-sdk-input-area {\n padding: 12px 16px;\n background: white;\n border-top: 1px solid #e0e0e0;\n display: flex;\n align-items: center;\n gap: 8px;\n }\n\n\n .chat-sdk-icon-btn {\n background: transparent;\n border: none;\n width: 32px;\n height: 32px;\n border-radius: 6px;\n cursor: pointer;\n display: flex;\n align-items: center;\n justify-content: center;\n color: #666;\n }\n .chat-sdk-icon-btn:hover { background: rgba(0,0,0,0.06); }\n\n .chat-sdk-emoji-picker {\n position: absolute;\n left: 12px;\n bottom: 64px;\n background: #fff;\n border: 1px solid #e0e0e0;\n border-radius: 8px;\n box-shadow: 0 6px 16px rgba(0,0,0,0.12);\n padding: 6px;\n z-index: 5;\n }\n .chat-sdk-emoji-grid {\n display: grid;\n grid-template-columns: repeat(5, 28px);\n gap: 6px;\n }\n\n /* Failed message styles - Telegram style */\n .chat-sdk-message-failed-indicator {\n display: inline-flex;\n align-items: center;\n margin-left: 6px;\n color: #ff4444;\n cursor: pointer;\n }\n .chat-sdk-message-failed-indicator svg {\n width: 16px;\n height: 16px;\n }\n .chat-sdk-message.own .chat-sdk-message-content {\n display: flex;\n align-items: flex-end;\n gap: 6px;\n }\n .chat-sdk-message.own .chat-sdk-message-bubble {\n flex: 1;\n }\n .chat-sdk-emoji-item {\n background: none;\n border: none;\n font-size: 20px;\n line-height: 1;\n cursor: pointer;\n width: 28px;\n height: 28px;\n border-radius: 4px;\n }\n .chat-sdk-emoji-item:hover { background: #f3f4f6; }\n\n\n .chat-sdk-input {\n flex: 1;\n border: 1px solid #ddd;\n border-radius: var(--chat-border-radius-input);\n padding: 8px 16px;\n font-size: 14px;\n outline: none;\n resize: none;\n min-height: 36px;\n max-height: 100px;\n }\n\n .chat-sdk-input:focus {\n border-color: var(--chat-primary-color);\n }\n\n .chat-sdk-send-btn {\n background: var(--chat-primary-color);\n color: white;\n border: none;\n border-radius: 50%;\n width: 36px;\n height: 36px;\n cursor: pointer;\n display: flex;\n align-items: center;\n justify-content: center;\n transition: background-color 0.2s;\n }\n\n .chat-sdk-send-btn:hover {\n background: #064e45;\n }\n\n .chat-sdk-send-btn:disabled {\n background: #ccc;\n cursor: not-allowed;\n }\n\n .chat-sdk-overlay {\n position: absolute;\n top: 0;\n left: 0;\n right: 0;\n bottom: 0;\n background: rgba(0, 0, 0, 0.5);\n display: flex;\n align-items: center;\n justify-content: center;\n z-index: 10;\n }\n\n .chat-sdk-join-card {\n background: white;\n border-radius: 12px;\n padding: 24px;\n max-width: 300px;\n margin: 16px;\n text-align: center;\n }\n\n .chat-sdk-join-title {\n font-size: 18px;\n font-weight: 600;\n margin: 0 0 8px 0;\n color: #333;\n }\n\n .chat-sdk-join-description {\n font-size: 14px;\n color: #666;\n margin: 0 0 20px 0;\n line-height: 1.4;\n }\n\n .chat-sdk-join-btn {\n background: #075e54;\n color: white;\n border: none;\n border-radius: 8px;\n padding: 12px 24px;\n font-size: 14px;\n font-weight: 600;\n cursor: pointer;\n transition: background-color 0.2s;\n width: 100%;\n }\n\n .chat-sdk-join-btn:hover {\n background: #064e45;\n }\n\n .chat-sdk-loading {\n display: flex;\n align-items: center;\n justify-content: center;\n padding: 40px;\n color: #666;\n }\n\n .chat-sdk-spinner {\n width: 20px;\n height: 20px;\n border: 2px solid #e0e0e0;\n border-top: 2px solid #075e54;\n border-radius: 50%;\n animation: chat-sdk-spin 1s linear infinite;\n margin-right: 8px;\n }\n\n @keyframes chat-sdk-spin {\n 0% { transform: rotate(0deg); }\n 100% { transform: rotate(360deg); }\n }\n\n .chat-sdk-container.dark {\n background: #1f1f1f;\n color: #e0e0e0;\n }\n\n .chat-sdk-container.dark .chat-sdk-header {\n background: #2d2d2d;\n }\n\n .chat-sdk-container.dark .chat-sdk-messages {\n background: #0d1117;\n }\n\n .chat-sdk-container.dark .chat-sdk-message-bubble {\n background: #2d2d2d;\n color: #e0e0e0;\n }\n\n .chat-sdk-container.dark .chat-sdk-message.own .chat-sdk-message-bubble {\n background: #0969da;\n color: white;\n }\n\n /* Image Modal Viewer */\n .chat-sdk-image-modal {\n position: fixed;\n top: 0; left: 0; right: 0; bottom: 0;\n z-index: 9999;\n opacity: 0;\n visibility: hidden;\n transition: opacity 0.2s ease, visibility 0.2s ease;\n }\n\n .chat-sdk-image-modal-open {\n opacity: 1;\n visibility: visible;\n }\n\n .chat-sdk-image-backdrop {\n position: absolute;\n top: 0; left: 0; right: 0; bottom: 0;\n background: rgba(0, 0, 0, 0.9);\n display: flex;\n align-items: center;\n justify-content: center;\n padding: 20px;\n }\n\n .chat-sdk-image-container {\n position: relative;\n max-width: 90vw;\n max-height: 90vh;\n display: flex;\n align-items: center;\n justify-content: center;\n }\n\n .chat-sdk-image-close {\n position: absolute;\n top: -50px;\n right: 0;\n background: rgba(255, 255, 255, 0.1);\n border: none;\n border-radius: 50%;\n width: 40px;\n height: 40px;\n color: white;\n cursor: pointer;\n display: flex;\n align-items: center;\n justify-content: center;\n transition: background-color 0.2s;\n z-index: 1;\n }\n\n .chat-sdk-image-close:hover {\n background: rgba(255, 255, 255, 0.2);\n }\n\n .chat-sdk-image-full {\n max-width: 100%;\n max-height: 100%;\n object-fit: contain;\n border-radius: 8px;\n box-shadow: 0 10px 30px rgba(0, 0, 0, 0.5);\n }\n\n /* Responsive Design */\n @media (max-width: 640px) {\n .chat-sdk-container {\n border-radius: 0;\n height: 100vh;\n max-height: 100vh;\n }\n\n .chat-sdk-message-content {\n max-width: 85%;\n }\n\n .chat-sdk-message-bubble {\n font-size: 14px;\n padding: 8px 12px;\n }\n\n .chat-sdk-input {\n font-size: 16px; /* Prevent zoom on iOS */\n padding: 10px 14px;\n }\n\n .chat-sdk-header {\n padding: 8px 12px;\n min-height: 50px;\n }\n\n .chat-sdk-message-avatar {\n width: 28px;\n height: 28px;\n font-size: 11px;\n }\n }\n\n @media (min-width: 1024px) {\n .chat-sdk-message-content {\n max-width: 60%;\n }\n\n .chat-sdk-send-btn:hover:not(:disabled) {\n transform: scale(1.05);\n transition: all 0.2s ease;\n }\n }\n\n /* Image Zoom Overlay */\n .chat-sdk-image-zoom-overlay {\n position: absolute;\n top: 0; left: 0; right: 0; bottom: 0;\n background: rgba(0, 0, 0, 0.85);\n z-index: 999999;\n display: flex;\n justify-content: center;\n align-items: center;\n cursor: zoom-out;\n backdrop-filter: blur(2px);\n }\n .chat-sdk-image-zoom-img {\n max-width: 95%;\n max-height: 95%;\n object-fit: contain;\n border-radius: 4px;\n box-shadow: 0 4px 12px rgba(0,0,0,0.3);\n transform: scale(0.95);\n animation: chat-sdk-zoom-in 0.2s cubic-bezier(0.1, 0.9, 0.2, 1) forwards;\n }\n @keyframes chat-sdk-zoom-in {\n to { transform: scale(1); }\n }\n\n "}startSimulation(){this.simulator.start()}stopSimulation(){this.simulator.stop()}pauseSimulation(){this.simulator.pause()}resumeSimulation(){this.simulator.resume()}async sendMessage(e,t="text"){await this.simulator.sendMessage(e,t)}get isSimulationRunning(){return this.state.isSimulationRunning}get isSimulationPaused(){return this.state.isSimulationPaused}get simulationEnded(){return this.state.simulationEnded}get messageCount(){return this.state.displayedMessageCount}get messages(){return[...this.state.messages]}async reinitializeLanguage(e){this.config.language=e,this.setLoading(!0),this.messagesContainer.innerHTML="",this.state.messages=[],this.state.displayedMessageCount=0,this.state.unreadCount=0,this.updateUnreadBadge();try{this.simulator.clearCachedProgress()}catch(e){}try{this.simulator.destroy()}catch(e){}this.simulator=new m(this.config,this.apiClient),this.setupSimulatorEvents(),await this.initializeSimulation()}destroy(){this.pollingStopTimer&&(clearTimeout(this.pollingStopTimer),this.pollingStopTimer=null);try{this.simulator.destroy()}catch(e){}if(this.shadowRoot)try{for(;this.shadowRoot.firstChild;)this.shadowRoot.removeChild(this.shadowRoot.firstChild)}catch(e){}this.state.isOpen=!1,this.removeAllListeners()}clearMessages(){this.state.messages=[],this.state.displayedMessageCount=0,this.state.unreadCount=0,this.messagesContainer.innerHTML="",this.updateUnreadBadge()}rerender(){this.reRenderAllMessages()}getMessageCount(){return this.state.displayedMessageCount}isOpen(){return this.state.isOpen}updateLanguageElements(e){var t,s,n;this.t=p(e);const i=null===(t=this.widgetElement)||void 0===t?void 0:t.querySelector("#message-input");i&&(i.placeholder=this.t.inputPlaceholder);const a=null===(s=this.widgetElement)||void 0===s?void 0:s.querySelector(".send-button");a&&a.textContent&&(a.textContent=this.t.send);const o=this.getMessageCount(),r=(null===(n=this.state.currentProject)||void 0===n?void 0:n.name)||"Chat";this.setTitle(r,`${o} ${this.t.messages}`)}}const v=b;function f(e){return new b(e)}var k={init:f,ChatSDK:v,ChatSDKError:e};"undefined"!=typeof window&&(window.ChatSDK={init:f,ChatSDK:v,ChatSDKError:e});export{v as ChatSDK,e as ChatSDKError,k as default,f as init};
|
package/dist/chat-sdk.umd.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
!function(e,t){"object"==typeof exports&&"undefined"!=typeof module?t(exports):"function"==typeof define&&define.amd?define(["exports"],t):t((e="undefined"!=typeof globalThis?globalThis:e||self).ChatSDK={})}(this,function(e){"use strict";class t extends Error{constructor(e,t,s){super(e),this.code=t,this.details=s,this.name="ChatSDKError"}}class s{constructor(){this.events=new Map}on(e,t){this.events.has(e)||this.events.set(e,[]),this.events.get(e).push(t)}off(e,t){if(!this.events.has(e))return;if(!t)return void this.events.delete(e);const s=this.events.get(e),n=s.indexOf(t);n>-1&&s.splice(n,1),0===s.length&&this.events.delete(e)}emit(e,t){if(!this.events.has(e))return;this.events.get(e).forEach(s=>{try{s(t)}catch(t){console.error(`Error in event callback for "${e}":`,t)}})}getEventNames(){return Array.from(this.events.keys())}listenerCount(e){var t;return(null===(t=this.events.get(e))||void 0===t?void 0:t.length)||0}removeAllListeners(){this.events.clear()}}function n(e,t,s){const n=document.createElement(e);return t&&(n.className=t),n}function a(e){const t=document.createElement("div");return t.textContent=e,t.innerHTML}function i(e,t=!0){e.scrollTop=e.scrollHeight,e.scrollTo&&e.scrollTo({top:e.scrollHeight,behavior:t?"smooth":"auto"})}const o={USD:1,EUR:.92,GBP:.79,JPY:149.5,CNY:7.24,INR:83.12,BRL:4.97,RUB:92.5,KRW:1320,MXN:17.15,CAD:1.38,AUD:1.53,CHF:.88,SEK:10.85,NZD:1.67,SGD:1.34,HKD:7.82,NOK:10.95,TRY:28.5,ZAR:18.65,PLN:4.05,THB:35.2,IDR:15650,MYR:4.68,PHP:56.2,DKK:6.88,CZK:22.85,HUF:355,ILS:3.72,CLP:920,ARS:350,COP:4050,PEN:3.75,EGP:30.9,SAR:3.75,AED:3.67,VND:24500,PKR:278,BDT:110,NGN:775,UAH:36.5,RON:4.58,TWD:31.5,QAR:3.64,KWD:.31,OMR:.38,BHD:.38},r={USD:"$",EUR:"€",GBP:"£",JPY:"¥",CNY:"¥",INR:"₹",BRL:"R$",RUB:"₽",KRW:"₩",MXN:"$",CAD:"C$",AUD:"A$",CHF:"CHF",SEK:"kr",NZD:"NZ$",SGD:"S$",HKD:"HK$",NOK:"kr",TRY:"₺",ZAR:"R",PLN:"zł",THB:"฿",IDR:"Rp",MYR:"RM",PHP:"₱",DKK:"kr",CZK:"Kč",HUF:"Ft",ILS:"₪",CLP:"$",ARS:"$",COP:"$",PEN:"S/",EGP:"E£",SAR:"﷼",AED:"د.إ",VND:"₫",PKR:"₨",BDT:"৳",NGN:"₦",UAH:"₴",RON:"lei",TWD:"NT$",QAR:"﷼",KWD:"د.ك",OMR:"﷼",BHD:"د.ب"},d={USD:",",EUR:".",GBP:",",JPY:",",CNY:",",INR:",",BRL:".",RUB:" ",KRW:",",MXN:",",CAD:",",AUD:",",CHF:"'",SEK:" ",PLN:" ",THB:",",IDR:".",MYR:",",PHP:",",DKK:".",CZK:" ",HUF:" "},l={USD:".",EUR:",",GBP:".",JPY:".",CNY:".",INR:".",BRL:",",RUB:",",KRW:".",MXN:".",CAD:".",AUD:".",CHF:".",SEK:",",PLN:",",THB:".",IDR:",",MYR:".",PHP:".",DKK:",",CZK:",",HUF:","},h={US:"USD",CA:"CAD",MX:"MXN",BR:"BRL",AR:"ARS",CL:"CLP",CO:"COP",PE:"PEN",GB:"GBP",DE:"EUR",FR:"EUR",IT:"EUR",ES:"EUR",NL:"EUR",BE:"EUR",AT:"EUR",PT:"EUR",IE:"EUR",GR:"EUR",FI:"EUR",CH:"CHF",NO:"NOK",SE:"SEK",DK:"DKK",PL:"PLN",CZ:"CZK",HU:"HUF",RO:"RON",RU:"RUB",UA:"UAH",TR:"TRY",IL:"ILS",SA:"SAR",AE:"AED",EG:"EGP",CN:"CNY",JP:"JPY",KR:"KRW",IN:"INR",ID:"IDR",TH:"THB",VN:"VND",MY:"MYR",SG:"SGD",PH:"PHP",PK:"PKR",BD:"BDT",HK:"HKD",TW:"TWD",AU:"AUD",NZ:"NZD",ZA:"ZAR",NG:"NGN",KE:"KES",QA:"QAR",KW:"KWD",OM:"OMR",BH:"BHD"},c=new Set(["JPY","KRW","IDR","VND","CLP","PYG","UGX"]);function m(e,t){if(!e||!t)return e;const s=function(e){return h[e.toUpperCase()]||"USD"}(t);return e.replace(/\{\{AMOUNT:(\d+(?:\.\d+)?)\}\}/g,(e,t)=>{const n=parseFloat(t);return isNaN(n)?e:function(e,t){var s,n,a,i;const h=null!==(s=o[t])&&void 0!==s?s:1,m=null!==(n=r[t])&&void 0!==n?n:t+" ",g=null!==(a=d[t])&&void 0!==a?a:",",u=null!==(i=l[t])&&void 0!==i?i:".",p=c.has(t),y=e*h,b=p?Math.round(y):Math.round(100*y)/100,f=Math.floor(b).toString().replace(/\B(?=(\d{3})+(?!\d))/g,g);return p?`${m}${f}`:`${m}${f}${u}${(b%1).toFixed(2).slice(2)}`}(n,s)})}class g extends s{constructor(e,t){super(),this.simulationData=null,this.displayedMessages=[],this.currentMessageIndex=0,this.isRunning=!1,this.isPaused=!1,this.intervalId=null,this.pollingId=null,this.burstPhase=!0,this.totalToShow=1/0,this.virtualLastTimestamp=null,this.realLastTimestamp=null,this.lastTimestamp=null,this.lastDelayMs=0,this.userId="",this.config=e,this.apiClient=t,this.pollingIntervalMs="number"==typeof e.pollingInterval&&e.pollingInterval>0?e.pollingInterval:6e3}async initialize(){try{const e=this.config.language||"en",t=(this.config.country||"US").toUpperCase(),s=this.getPersistedUserId(),n=s||this.config.userId||this.generateUserId();this.userId=n,s||this.persistUserId(n);const a=await this.apiClient.getSimulationData(this.config.projectId,n,e,t);if(!a.success||!a.data)throw new Error("Failed to load simulation data");this.simulationData=a.data;const i=this.simulationData.project.initialBurstCount+this.simulationData.project.continuousCount;this.totalToShow=Math.min(i,this.simulationData.messages.length);const o=this.loadProgress();o&&"number"==typeof o.index?(this.currentMessageIndex=o.index,o.lastTimestamp&&(this.virtualLastTimestamp=new Date(o.lastTimestamp),this.lastTimestamp=new Date(o.lastTimestamp))):(this.currentMessageIndex=0,this.virtualLastTimestamp=null,this.lastTimestamp=null),this.realLastTimestamp=null,await this.loadExistingMessages(),await this.reconstructVirtualHistoryForDisplay(),this.emit("initialized",this.simulationData),this.startPolling(),!1!==this.config.autoStart&&this.start()}catch(e){throw this.emit("error",e),e}}start(){this.simulationData&&!this.isRunning&&(this.isRunning=!0,this.isPaused=!1,this.burstPhase=!0,this.emit("simulationStart"),this.performInitialBurst(),this.currentMessageIndex<this.totalToShow?(this.burstPhase=!1,this.scheduleNextMessage()):(this.isRunning=!1,this.emit("simulationEnd")))}performInitialBurst(){if(!this.simulationData)return;const{project:e,messages:t}=this.simulationData,s=e.initialBurstCount,n=Math.min(s,this.totalToShow,t.length);if(this.currentMessageIndex>=n)return;if(this.displayedMessages.some(e=>e.id.startsWith("sim-"))&&this.currentMessageIndex>0)return;const a=new Date,i=new Array(n);let o=new Date(a);for(let e=n-1;e>=0;e--)if(i[e]=new Date(o),e>0){const e=10+Math.floor(11*Math.random());o=new Date(o.getTime()-60*e*1e3)}const r=[],d=(this.config.country||"US").toUpperCase();let l=!1;for(let e=this.currentMessageIndex;e<n;e++){const s=t[e],n=m(s.content,d);if(s.hasScreenshot&&s.screenshotUrl){const t={id:`sim-${e}-text-${Date.now()}`,content:n,messageType:"text",timestamp:i[e],isOwnMessage:!1,virtualUser:s.virtualUser};this.displayedMessages.push(t),r.push(t);const a=new Date(i[e].getTime()+2e3),o={id:`sim-${e}-image-${Date.now()}`,content:this.resolveImageUrl(s.screenshotUrl),messageType:"image",timestamp:a,isOwnMessage:!1,virtualUser:s.virtualUser};this.displayedMessages.push(o),r.push(o)}else{const t={id:`sim-${e}-${Date.now()}`,content:n,messageType:s.messageType,timestamp:i[e],isOwnMessage:!1,virtualUser:s.virtualUser};this.displayedMessages.push(t),r.push(t)}this.currentMessageIndex=e+1,l=!0}l&&(this.lastTimestamp=i[n-1],this.virtualLastTimestamp=this.lastTimestamp,this.displayedMessages.sort((e,t)=>e.timestamp.getTime()-t.timestamp.getTime()),this.emit("messages-batch",r)),this.saveProgress()}pause(){this.isRunning&&(this.isPaused=!0,this.intervalId&&(clearTimeout(this.intervalId),this.intervalId=null),this.emit("simulationPause"))}resume(){this.isRunning&&this.isPaused&&(this.isPaused=!1,this.scheduleNextMessage(),this.emit("simulationResume"))}stop(){this.isRunning=!1,this.isPaused=!1,this.intervalId&&(clearTimeout(this.intervalId),this.intervalId=null),this.emit("simulationStop")}destroy(){this.stop(),this.stopPolling(),this.removeAllListeners()}scheduleNextMessage(){if(!this.simulationData||!this.isRunning||this.isPaused)return;const{project:e,messages:t}=this.simulationData;if(this.currentMessageIndex>=this.totalToShow)return this.isRunning=!1,void this.emit("simulationEnd");let s;if(this.burstPhase){const n=Math.min(e.initialBurstCount,t.length);this.currentMessageIndex<n?s=500+1e3*Math.random():(this.burstPhase=!1,s=this.getRandomInterval(e.messageIntervalMin,e.messageIntervalMax))}else{const n=Math.min(e.initialBurstCount,t.length);s=this.currentMessageIndex-n<5?1e3*(e.initialMessageInterval||10):this.getRandomInterval(e.messageIntervalMin,e.messageIntervalMax)}this.lastDelayMs=s,this.intervalId=setTimeout(()=>{this.displayNextMessage(),this.scheduleNextMessage()},s)}displayNextMessage(){if(!this.simulationData||this.currentMessageIndex>=this.simulationData.messages.length)return;const e=this.simulationData.messages[this.currentMessageIndex],t=(this.config.country||"US").toUpperCase(),s=m(e.content,t),n=this.lastTimestamp||new Date,a=new Date(n.getTime()+(this.lastDelayMs||0));if(this.lastTimestamp=a,e.hasScreenshot&&e.screenshotUrl){const t={id:`sim-${this.currentMessageIndex}-text-${Date.now()}`,content:s,messageType:"text",timestamp:a,isOwnMessage:!1,virtualUser:e.virtualUser};this.displayedMessages.push(t),this.emit("message",t);const n=new Date(a.getTime()+2e3),i={id:`sim-${this.currentMessageIndex}-image-${Date.now()}`,content:this.resolveImageUrl(e.screenshotUrl),messageType:"image",timestamp:n,isOwnMessage:!1,virtualUser:e.virtualUser};this.displayedMessages.push(i),this.lastTimestamp=n,setTimeout(()=>{this.emit("message",i)},2e3)}else{const t={id:`sim-${this.currentMessageIndex}-${Date.now()}`,content:s,messageType:e.messageType,timestamp:a,isOwnMessage:!1,virtualUser:e.virtualUser};this.displayedMessages.push(t),this.emit("message",t)}this.currentMessageIndex++,this.saveProgress()}async loadExistingMessages(){if(this.simulationData)try{const e=this.userId||this.config.userId||this.generateUserId(),t=await this.apiClient.getSimulationMessages(this.config.projectId,e,void 0,100);if(t.success&&t.messages&&t.messages.length>0){const s=t.messages.sort((e,t)=>new Date(e.createdAt||e.timestamp).getTime()-new Date(t.createdAt||t.timestamp).getTime()),n=new Set(this.displayedMessages.map(e=>e.id));for(const t of s){if(n.has(t.id))continue;const s=(this.config.country||"US").toUpperCase(),a={id:t.id,content:m(t.content||"",s),messageType:t.messageType,timestamp:new Date(t.createdAt||t.timestamp),isOwnMessage:t.userId===e,virtualUser:t.virtualUser,user:t.userId===e?{id:e,username:this.config.username||"You"}:void 0};this.displayedMessages.push(a)}if(s.length>0){const e=s[s.length-1];this.realLastTimestamp=new Date(e.createdAt||e.timestamp)}this.displayedMessages.length>0&&this.emit("messages-batch",[...this.displayedMessages])}}catch(e){console.warn("Failed to load existing messages:",e)}}startPolling(){this.pollingId&&(clearInterval(this.pollingId),this.pollingId=null),this.pollingId=setInterval(async()=>{await this.pollForNewMessages()},this.pollingIntervalMs)}stopPolling(){this.pollingId&&(clearInterval(this.pollingId),this.pollingId=null)}setPollingInterval(e){!e||e<=0||(this.pollingIntervalMs=e,this.pollingId&&this.startPolling())}get isPolling(){return!!this.pollingId}async pollForNewMessages(){if(this.simulationData)try{const e=this.userId||this.config.userId||this.generateUserId(),t=this.getLastMessageTimestamp(),s=await this.apiClient.getSimulationMessages(this.config.projectId,e,t);if(s.success&&s.messages&&s.messages.length>0){const t=new Set(this.displayedMessages.map(e=>e.id));let n=null;for(const a of s.messages){if(t.has(a.id))continue;const s=new Date(a.createdAt),i=(this.config.country||"US").toUpperCase(),o={id:a.id,content:m(a.content||"",i),messageType:a.messageType,timestamp:s,isOwnMessage:a.userId===e,virtualUser:a.virtualUser,user:a.userId===e?{id:e,username:this.config.username||"You"}:void 0};(!n||s>n)&&(n=s),this.displayedMessages.push(o),this.emit("message",o)}n&&(this.realLastTimestamp=n)}}catch(e){console.warn("Polling error:",e)}}async reconstructVirtualHistoryForDisplay(){if(!this.simulationData)return;const e=Math.min(this.currentMessageIndex,this.totalToShow,this.simulationData.messages.length);if(e<=0)return;const t=this.loadProgress(),s=(null==t?void 0:t.virtualMessages)||[];if(s.length>0){const e=[],t=new Set(this.displayedMessages.map(e=>e.id)),n=(this.config.country||"US").toUpperCase();for(const a of s)if(!t.has(a.id)){if("image"===a.messageType){const e=a.content||"";if(!e.startsWith("http")&&!e.startsWith("/uploads")&&!e.startsWith("/api"))continue}const t={id:a.id,content:"image"===a.messageType?this.resolveImageUrl(m(a.content||"",n)):m(a.content||"",n),messageType:a.messageType,timestamp:new Date(a.timestamp),isOwnMessage:!1,virtualUser:a.virtualUser};e.push(t)}if(e.length>0){this.displayedMessages.push(...e),this.displayedMessages.sort((e,t)=>e.timestamp.getTime()-t.timestamp.getTime());const t=e[e.length-1];this.virtualLastTimestamp=t.timestamp,this.lastTimestamp=t.timestamp,this.emit("messages-batch",e)}return}const n=new Date,a=new Array(e);let i=new Date(n);for(let t=e-1;t>=0;t--)if(a[t]=new Date(i),t>0){const e=10+Math.floor(11*Math.random());i=new Date(i.getTime()-60*e*1e3)}const o=[],{messages:r}=this.simulationData,d=(this.config.country||"US").toUpperCase();for(let t=0;t<e;t++){const e=r[t],s=a[t],n=m(e.content,d);if(e.hasScreenshot&&e.screenshotUrl){const a={id:`sim-${t}-text`,content:n,messageType:"text",timestamp:s,isOwnMessage:!1,virtualUser:e.virtualUser},i={id:`sim-${t}-image`,content:this.resolveImageUrl(e.screenshotUrl),messageType:"image",timestamp:new Date(s.getTime()+2e3),isOwnMessage:!1,virtualUser:e.virtualUser};o.push(a,i)}else{const a={id:`sim-${t}`,content:n,messageType:e.messageType,timestamp:s,isOwnMessage:!1,virtualUser:e.virtualUser};o.push(a)}}const l=new Set(this.displayedMessages.map(e=>e.id)),h=o.filter(e=>!l.has(e.id));if(0===h.length)return;this.displayedMessages.push(...h),this.displayedMessages.sort((e,t)=>e.timestamp.getTime()-t.timestamp.getTime());const c=h[h.length-1];this.virtualLastTimestamp=c.timestamp,this.lastTimestamp=c.timestamp,this.emit("messages-batch",h)}getLastMessageTimestamp(){if(this.realLastTimestamp)return this.realLastTimestamp.toISOString()}getUserKey(){return`vcs:user:${this.config.projectId}`}getProgressKey(){const e=this.userId||this.config.userId||"anon";return`vcs:progress:${this.config.projectId}:${e}`}getPersistedUserId(){try{return"undefined"==typeof window?null:window.localStorage.getItem(this.getUserKey())}catch(e){return null}}persistUserId(e){try{if("undefined"==typeof window)return;window.localStorage.setItem(this.getUserKey(),e)}catch(e){}}loadProgress(){try{if("undefined"==typeof window)return null;const e=window.localStorage.getItem(this.getProgressKey());return e?JSON.parse(e):null}catch(e){return null}}saveProgress(){try{if("undefined"==typeof window)return;const e=this.displayedMessages.filter(e=>e.id.startsWith("sim-")).map(e=>({id:e.id,content:e.content,messageType:e.messageType,timestamp:e.timestamp.toISOString(),virtualUser:e.virtualUser})),t={index:this.currentMessageIndex,lastTimestamp:this.lastTimestamp?this.lastTimestamp.toISOString():void 0,virtualMessages:e};window.localStorage.setItem(this.getProgressKey(),JSON.stringify(t))}catch(e){}}clearProgress(){try{if("undefined"==typeof window)return;window.localStorage.removeItem(this.getProgressKey())}catch(e){}}clearCachedProgress(){this.clearProgress()}resolveImageUrl(e){if(!e)return"";if(e.startsWith("http://")||e.startsWith("https://"))return e;const t=(this.config.apiBaseUrl||"").replace(/\/$/,"");return t?`${t}${e}`:e}getRandomInterval(e,t){return 1e3*(e+Math.random()*(t-e))}generateUserId(){return`user-${Date.now()}-${Math.random().toString(36).substring(2,11)}`}get messages(){return[...this.displayedMessages]}get isSimulationRunning(){return this.isRunning}get isSimulationPaused(){return this.isPaused}get data(){return this.simulationData}async sendMessage(e,t="text"){if(!this.simulationData)throw new Error("Simulation not initialized");const s=this.userId||this.config.userId||this.generateUserId(),n=this.config.username||"User";try{if("image"===t||"string"==typeof e&&e.startsWith("data:image/"))return;await Promise.all([this.apiClient.sendUserMessage(this.config.projectId,s,n,e,t),this.apiClient.triggerAIReply(this.config.projectId,s,n,e,t)])}catch(e){throw this.emit("error",e),e}}}class u{constructor(e){this.baseUrl=e.apiBaseUrl||window.location.origin,this.token=e.token}async request(e,s={}){const n=`${this.baseUrl}${e}`,a={"Content-Type":"application/json",...s.headers};this.token&&(a.Authorization=`Bearer ${this.token}`);try{const e=await fetch(n,{...s,headers:a,credentials:"include"});if(!e.ok)throw new t(`API request failed: ${e.status} ${e.statusText}`,"API_ERROR",{status:e.status,statusText:e.statusText});const i=await e.json();if(!i.success&&i.error)throw new t(i.error,"API_ERROR",i);return i}catch(e){if(e instanceof t)throw e;throw new t(`Network error: ${e.message}`,"NETWORK_ERROR",e)}}async getProject(e){return this.request(`/api/projects/${e}`)}async getTemplate(e,t,s){const n=new URLSearchParams;t&&n.set("lang",t),s&&n.set("country",s);const a=n.toString()?`?${n.toString()}`:"";return this.request(`/api/templates/${e}${a}`)}async getProjectTemplates(e){return this.request(`/api/projects/${e}/templates`)}async sendMessage(e,t,s,n="text"){return this.request("/api/chat/message",{method:"POST",body:JSON.stringify({projectId:e,userId:t,content:s,messageType:n})})}async joinProject(e,t,s){return this.request("/api/chat/join",{method:"POST",body:JSON.stringify({projectId:e,userId:t,username:s})})}async leaveProject(e,t){return this.request("/api/chat/leave",{method:"POST",body:JSON.stringify({projectId:e,userId:t})})}async getSimulationData(e,t,s,n){const a=new URLSearchParams({userId:t});return s&&a.append("lang",s),n&&a.append("country",n),this.request(`/api/chat/simulation/${e}?${a.toString()}`)}async getSimulationMessages(e,t,s,n){const a=new URLSearchParams({userId:t});return s&&a.append("since",s),n&&a.append("limit",n.toString()),this.request(`/api/chat/simulation/${e}/messages?${a.toString()}`)}async sendUserMessage(e,t,s,n,a="text"){return this.request("/api/chat/send",{method:"POST",body:JSON.stringify({projectId:e,userId:t,username:s,content:n,messageType:a})})}async triggerAIReply(e,t,s,n,a="text"){return this.request("/api/chat/ai-reply",{method:"POST",body:JSON.stringify({projectId:e,userId:t,username:s,content:n,messageType:a})})}setToken(e){this.token=e}setBaseUrl(e){this.baseUrl=e}}const p={en:{joinChat:"Join Chat",chatGroup:"{name} Group",online:"{count} online",inputPlaceholder:"Type a message...",send:"Send",messages:"messages",today:"Today",yesterday:"Yesterday",networkError:"Network error",sendFailed:"Failed to send"},zh:{joinChat:"加入群聊",chatGroup:"{name}交流群",online:"{count} 人在线",inputPlaceholder:"输入消息...",send:"发送",messages:"条消息",today:"今天",yesterday:"昨天",networkError:"网络错误",sendFailed:"发送失败"},"zh-TW":{joinChat:"加入群聊",chatGroup:"{name}交流群",online:"{count} 人在線",inputPlaceholder:"輸入訊息...",send:"發送",messages:"條訊息",today:"今天",yesterday:"昨天",networkError:"網路錯誤",sendFailed:"發送失敗"},es:{joinChat:"Unirse al Chat",chatGroup:"Grupo {name}",online:"{count} en línea",inputPlaceholder:"Escribe un mensaje...",send:"Enviar",messages:"mensajes",today:"Hoy",yesterday:"Ayer",networkError:"Error de red",sendFailed:"Error al enviar"},hi:{joinChat:"चैट में शामिल हों",chatGroup:"{name} समूह",online:"{count} ऑनलाइन",inputPlaceholder:"संदेश लिखें...",send:"भेजें",messages:"संदेश",today:"आज",yesterday:"कल",networkError:"नेटवर्क त्रुटि",sendFailed:"भेजने में विफल"},ar:{joinChat:"انضم للدردشة",chatGroup:"مجموعة {name}",online:"{count} متصل",inputPlaceholder:"اكتب رسالة...",send:"إرسال",messages:"رسائل",today:"اليوم",yesterday:"أمس",networkError:"خطأ في الشبكة",sendFailed:"فشل الإرسال"},pt:{joinChat:"Entrar no Chat",chatGroup:"Grupo {name}",online:"{count} online",inputPlaceholder:"Digite uma mensagem...",send:"Enviar",messages:"mensagens",today:"Hoje",yesterday:"Ontem",networkError:"Erro de rede",sendFailed:"Falha ao enviar"},bn:{joinChat:"চ্যাটে যোগ দিন",chatGroup:"{name} গ্রুপ",online:"{count} অনলাইন",inputPlaceholder:"একটি বার্তা লিখুন...",send:"পাঠান",messages:"বার্তা",today:"আজ",yesterday:"গতকাল",networkError:"নেটওয়ার্ক ত্রুটি",sendFailed:"পাঠাতে ব্যর্থ"},ru:{joinChat:"Присоединиться",chatGroup:"Группа {name}",online:"{count} онлайн",inputPlaceholder:"Введите сообщение...",send:"Отправить",messages:"сообщений",today:"Сегодня",yesterday:"Вчера",networkError:"Ошибка сети",sendFailed:"Не удалось отправить"},ja:{joinChat:"チャットに参加",chatGroup:"{name}グループ",online:"{count} オンライン",inputPlaceholder:"メッセージを入力...",send:"送信",messages:"メッセージ",today:"今日",yesterday:"昨日",networkError:"ネットワークエラー",sendFailed:"送信失敗"},de:{joinChat:"Chat beitreten",chatGroup:"{name} Gruppe",online:"{count} online",inputPlaceholder:"Nachricht eingeben...",send:"Senden",messages:"Nachrichten",today:"Heute",yesterday:"Gestern",networkError:"Netzwerkfehler",sendFailed:"Senden fehlgeschlagen"},fr:{joinChat:"Rejoindre le Chat",chatGroup:"Groupe {name}",online:"{count} en ligne",inputPlaceholder:"Tapez un message...",send:"Envoyer",messages:"messages",today:"Aujourd'hui",yesterday:"Hier",networkError:"Erreur réseau",sendFailed:"Échec de l'envoi"},ko:{joinChat:"채팅 참여",chatGroup:"{name} 그룹",online:"{count} 온라인",inputPlaceholder:"메시지 입력...",send:"전송",messages:"메시지",today:"오늘",yesterday:"어제",networkError:"네트워크 오류",sendFailed:"전송 실패"},it:{joinChat:"Unisciti alla Chat",chatGroup:"Gruppo {name}",online:"{count} online",inputPlaceholder:"Scrivi un messaggio...",send:"Invia",messages:"messaggi",today:"Oggi",yesterday:"Ieri",networkError:"Errore di rete",sendFailed:"Invio fallito"},tr:{joinChat:"Sohbete Katıl",chatGroup:"{name} Grubu",online:"{count} çevrimiçi",inputPlaceholder:"Bir mesaj yazın...",send:"Gönder",messages:"mesaj",today:"Bugün",yesterday:"Dün",networkError:"Ağ hatası",sendFailed:"Gönderilemedi"},vi:{joinChat:"Tham gia Chat",chatGroup:"Nhóm {name}",online:"{count} trực tuyến",inputPlaceholder:"Nhập tin nhắn...",send:"Gửi",messages:"tin nhắn",today:"Hôm nay",yesterday:"Hôm qua",networkError:"Lỗi mạng",sendFailed:"Gửi thất bại"},pl:{joinChat:"Dołącz do Czatu",chatGroup:"Grupa {name}",online:"{count} online",inputPlaceholder:"Wpisz wiadomość...",send:"Wyślij",messages:"wiadomości",today:"Dziś",yesterday:"Wczoraj",networkError:"Błąd sieci",sendFailed:"Nie udało się wysłać"},th:{joinChat:"เข้าร่วมแชท",chatGroup:"กลุ่ม {name}",online:"{count} ออนไลน์",inputPlaceholder:"พิมพ์ข้อความ...",send:"ส่ง",messages:"ข้อความ",today:"วันนี้",yesterday:"เมื่อวาน",networkError:"ข้อผิดพลาดเครือข่าย",sendFailed:"ส่งไม่สำเร็จ"},nl:{joinChat:"Deelnemen aan Chat",chatGroup:"{name} Groep",online:"{count} online",inputPlaceholder:"Typ een bericht...",send:"Verzenden",messages:"berichten",today:"Vandaag",yesterday:"Gisteren",networkError:"Netwerkfout",sendFailed:"Verzenden mislukt"},id:{joinChat:"Gabung Chat",chatGroup:"Grup {name}",online:"{count} online",inputPlaceholder:"Ketik pesan...",send:"Kirim",messages:"pesan",today:"Hari ini",yesterday:"Kemarin",networkError:"Kesalahan jaringan",sendFailed:"Gagal mengirim"},ms:{joinChat:"Sertai Chat",chatGroup:"Kumpulan {name}",online:"{count} dalam talian",inputPlaceholder:"Taip mesej...",send:"Hantar",messages:"mesej",today:"Hari ini",yesterday:"Semalam",networkError:"Ralat rangkaian",sendFailed:"Gagal menghantar"},ur:{joinChat:"چیٹ میں شامل ہوں",chatGroup:"{name} گروپ",online:"{count} آن لائن",inputPlaceholder:"پیغام ٹائپ کریں...",send:"بھیجیں",messages:"پیغامات",today:"آج",yesterday:"کل",networkError:"نیٹ ورک کی خرابی",sendFailed:"بھیجنے میں ناکام"},te:{joinChat:"చాట్లో చేరండి",chatGroup:"{name} సమూహం",online:"{count} ఆన్లైన్",inputPlaceholder:"సందేశాన్ని టైప్ చేయండి...",send:"పంపండి",messages:"సందేశాలు",today:"నేడు",yesterday:"నిన్న",networkError:"నెట్వర్క్ లోపం",sendFailed:"పంపడం విఫలమైంది"},mr:{joinChat:"चॅटमध्ये सामील व्हा",chatGroup:"{name} गट",online:"{count} ऑनलाइन",inputPlaceholder:"संदेश टाइप करा...",send:"पाठवा",messages:"संदेश",today:"आज",yesterday:"काल",networkError:"नेटवर्क त्रुटी",sendFailed:"पाठविण्यात अयशस्वी"},ta:{joinChat:"அரட்டையில் சேரவும்",chatGroup:"{name} குழு",online:"{count} ஆன்லைன்",inputPlaceholder:"ஒரு செய்தியை தட்டச்சு செய்யவும்...",send:"அனுப்பு",messages:"செய்திகள்",today:"இன்று",yesterday:"நேற்று",networkError:"நெட்வொர்க் பிழை",sendFailed:"அனுப்ப முடியவில்லை"},fa:{joinChat:"پیوستن به چت",chatGroup:"گروه {name}",online:"{count} آنلاین",inputPlaceholder:"پیامی تایپ کنید...",send:"ارسال",messages:"پیامها",today:"امروز",yesterday:"دیروز",networkError:"خطای شبکه",sendFailed:"ارسال نشد"},uk:{joinChat:"Приєднатися до чату",chatGroup:"Група {name}",online:"{count} онлайн",inputPlaceholder:"Введіть повідомлення...",send:"Надіслати",messages:"повідомлень",today:"Сьогодні",yesterday:"Вчора",networkError:"Помилка мережі",sendFailed:"Не вдалося надіслати"},gu:{joinChat:"ચેટમાં જોડાઓ",chatGroup:"{name} જૂથ",online:"{count} ઓનલાઇન",inputPlaceholder:"સંદેશ લખો...",send:"મોકલો",messages:"સંદેશાઓ",today:"આજે",yesterday:"ગઈકાલે",networkError:"નેટવર્ક ભૂલ",sendFailed:"મોકલવામાં નિષ્ફળ"},ro:{joinChat:"Alătură-te chatului",chatGroup:"Grupul {name}",online:"{count} online",inputPlaceholder:"Scrie un mesaj...",send:"Trimite",messages:"mesaje",today:"Astăzi",yesterday:"Ieri",networkError:"Eroare de rețea",sendFailed:"Trimitere eșuată"},sv:{joinChat:"Gå med i chatt",chatGroup:"{name} grupp",online:"{count} online",inputPlaceholder:"Skriv ett meddelande...",send:"Skicka",messages:"meddelanden",today:"Idag",yesterday:"Igår",networkError:"Nätverksfel",sendFailed:"Det gick inte att skicka"},hu:{joinChat:"Csatlakozás a chathez",chatGroup:"{name} Csoport",online:"{count} online",inputPlaceholder:"Írjon egy üzenetet...",send:"Küldés",messages:"üzenet",today:"Ma",yesterday:"Tegnap",networkError:"Hálózati hiba",sendFailed:"Küldés sikertelen"},cs:{joinChat:"Připojit se k chatu",chatGroup:"Skupina {name}",online:"{count} online",inputPlaceholder:"Napište zprávu...",send:"Odeslat",messages:"zpráv",today:"Dnes",yesterday:"Včera",networkError:"Chyba sítě",sendFailed:"Odeslání selhalo"},el:{joinChat:"Εγγραφή στο Chat",chatGroup:"Ομάδα {name}",online:"{count} online",inputPlaceholder:"Πληκτρολογήστε ένα μήνυμα...",send:"Αποστολή",messages:"μηνύματα",today:"Σήμερα",yesterday:"Χθες",networkError:"Σφάλμα δικτύου",sendFailed:"Αποτυχία αποστολής"},da:{joinChat:"Deltag i chat",chatGroup:"{name} Gruppe",online:"{count} online",inputPlaceholder:"Skriv en besked...",send:"Send",messages:"beskeder",today:"I dag",yesterday:"I går",networkError:"Netværksfejl",sendFailed:"Kunne ikke sende"},fi:{joinChat:"Liity chattiin",chatGroup:"{name} Ryhmä",online:"{count} paikalla",inputPlaceholder:"Kirjoita viesti...",send:"Lähetä",messages:"viestiä",today:"Tänään",yesterday:"Eilen",networkError:"Verkkovirhe",sendFailed:"Lähetys epäonnistui"},no:{joinChat:"Bli med i chat",chatGroup:"{name} Gruppe",online:"{count} pålogget",inputPlaceholder:"Skriv en melding...",send:"Send",messages:"meldinger",today:"I dag",yesterday:"I går",networkError:"Nettverksfeil",sendFailed:"Sending mislyktes"},he:{joinChat:"הצטרף לצ'אט",chatGroup:"קבוצת {name}",online:"{count} מחוברים",inputPlaceholder:"הקלד הודעה...",send:"שלח",messages:"הודעות",today:"היום",yesterday:"אתמול",networkError:"שגיאת רשת",sendFailed:"השליחה נכשלה"},tl:{joinChat:"Sumali sa Chat",chatGroup:"Grupong {name}",online:"{count} online",inputPlaceholder:"Mag-type ng mensahe...",send:"Ipadala",messages:"mga mensahe",today:"Ngayon",yesterday:"Kahapon",networkError:"Error sa network",sendFailed:"Nabigong ipadala"},sw:{joinChat:"Jiunge na Gumzo",chatGroup:"Kundi la {name}",online:"{count} mtandaoni",inputPlaceholder:"Andika ujumbe...",send:"Tuma",messages:"jumbe",today:"Leo",yesterday:"Jana",networkError:"Tatizo la mtandao",sendFailed:"Imeshindwa kutuma"},"pt-BR":{joinChat:"Entrar no Chat",chatGroup:"Grupo {name}",online:"{count} online",inputPlaceholder:"Escreva uma mensagem...",send:"Enviar",messages:"mensagens",today:"Hoje",yesterday:"Ontem",networkError:"Erro de rede",sendFailed:"Falha ao enviar"}};function y(e){if(p[e])return p[e];const t=e.split("-")[0];return p[t]?p[t]:p.en}function b(e,t){return e.replace(/\{(\w+)\}/g,(e,s)=>void 0!==t[s]?String(t[s]):e)}class f extends s{constructor(e){var t,s;super(),this.emojiPanelOpen=!1,this.onlineCount=0,this.currentTheme="whatsapp",this.isDarkMode=!1,this.customColors={},this.visibleStartIndex=0,this.hasInitializedData=!1,this.pollingStopTimer=null,this.config={...e,mode:e.mode||"floating"},this.t=y(e.language||"en"),this.currentTheme="telegram"===e.uiTemplate?"telegram":"whatsapp",this.isDarkMode="dark"===e.theme,this.customColors={primary:e.primaryColor,background:e.backgroundColor},this.onlineCount=500+Math.floor(301*Math.random()),this.initialRenderCount=null!==(t=this.config.initialRenderCount)&&void 0!==t?t:Number.MAX_SAFE_INTEGER,this.lazyLoadBatchSize=null!==(s=this.config.lazyLoadBatchSize)&&void 0!==s?s:20,this.state={isInitialized:!1,isOpen:!1,isJoined:!1,isConnected:!1,isSimulationRunning:!1,isSimulationPaused:!1,messages:[],virtualUsers:[],realUsers:[],typingUsers:[],simulationEnded:!1,displayedMessageCount:0,unreadCount:0,lastReadMessageId:null},this.apiClient=new u(e),this.simulator=new g(e,this.apiClient),this.setupSimulatorEvents(),this.init()}init(){try{this.setupContainer(),this.createWidget(),"floating"===this.config.mode&&(this.widgetElement.style.display="none",this.createFloatingButton()),this.setupEventListeners(),this.setupImageViewer(),this.state.isInitialized=!0,this.emit("ready")}catch(e){this.emit("error",new t("Failed to initialize chat widget","WIDGET_INIT_ERROR",e))}}setupSimulatorEvents(){this.simulator.on("initialized",e=>{var t;this.state.currentProject=e.project,this.state.currentTemplate=e.template,null!=this.config.initialRenderCount?this.initialRenderCount=this.config.initialRenderCount:this.initialRenderCount=Number.MAX_SAFE_INTEGER,this.setTitle((null===(t=e.project)||void 0===t?void 0:t.name)||"Chat",`0 ${this.t.messages}`),this.setLoading(!1),this.emit("simulationInitialized",e)}),this.simulator.on("message",e=>{var t;this.setLoading(!1),this.addMessage(e),this.state.displayedMessageCount++;const s=(null===(t=this.state.currentProject)||void 0===t?void 0:t.name)||"Chat";this.setTitle(s,`${this.state.displayedMessageCount} ${this.t.messages}`)}),this.simulator.on("messages-batch",e=>{var t;this.setLoading(!1),this.addMessagesBulk(e),this.state.displayedMessageCount+=e.length;const s=(null===(t=this.state.currentProject)||void 0===t?void 0:t.name)||"Chat";this.setTitle(s,`${this.state.displayedMessageCount} ${this.t.messages}`),setTimeout(()=>{this.scrollToBottom(!0)},100)}),this.simulator.on("simulationStart",()=>{var e,t;this.state.isSimulationRunning=!0,this.state.isSimulationPaused=!1,null===(t=(e=this.config).onSimulationStart)||void 0===t||t.call(e)}),this.simulator.on("simulationEnd",()=>{var e,t;this.state.isSimulationRunning=!1,this.state.simulationEnded=!0,null===(t=(e=this.config).onSimulationEnd)||void 0===t||t.call(e)}),this.simulator.on("simulationPause",()=>{this.state.isSimulationPaused=!0}),this.simulator.on("simulationResume",()=>{this.state.isSimulationPaused=!1}),this.simulator.on("error",e=>{this.emit("error",e)})}async initializeSimulation(){try{await this.simulator.initialize()}catch(e){this.emit("error",new t("Failed to initialize simulation","SIMULATION_INIT_ERROR",e))}}setupContainer(){var e;const s=function(e){if("string"==typeof e)return document.querySelector(e)||document.body;return e||document.body}(this.config.container);if(!s)throw new t("Container element not found","CONTAINER_NOT_FOUND");const n=null===(e=s.tagName)||void 0===e?void 0:e.toUpperCase();if("BODY"===n||"HTML"===n){const e=document.createElement("div");e.className="chat-sdk-host",e.style.position="static",e.style.width="0",e.style.height="0",document.body.appendChild(e),this.container=e}else this.container=s;this.shadowRoot=this.container.attachShadow({mode:"closed"});const a=this.getDefaultStyles();!function(e,t){const s=document.createElement("style");s.textContent=t,e.appendChild(s)}(this.shadowRoot,a)}createWidget(){var e;if(this.widgetElement&&this.messagesContainer)return;this.widgetElement=n("div","chat-sdk-container");const t="telegram"===this.config.uiTemplate?"telegram":"whatsapp";this.currentTheme=t,this.widgetElement.classList.add(`${t}-theme`),"telegram"===t&&"dark"===this.config.theme&&(this.widgetElement.classList.add("dark"),this.isDarkMode=!0),this.widgetElement.style.position="fixed",this.widgetElement.style.top="0",this.widgetElement.style.left="0",this.widgetElement.style.width="100vw",this.widgetElement.style.height="100vh",this.widgetElement.style.zIndex=String(null!==(e=this.config.zIndex)&&void 0!==e?e:2147483e3),this.widgetElement.innerHTML=`\n <div class="chat-sdk-header">\n <div class="chat-sdk-header-left">\n <div class="chat-sdk-title" id="chat-title"></div>\n <div class="chat-sdk-subtitle" id="chat-subtitle"></div>\n </div>\n <button class="chat-sdk-close-btn" type="button">\n <svg width="20" height="20" viewBox="0 0 16 16" fill="currentColor">\n <path d="M8 7.293l2.146-2.147a.5.5 0 01.708.708L8.707 8l2.147 2.146a.5.5 0 01-.708.708L8 8.707l-2.146 2.147a.5.5 0 01-.708-.708L7.293 8 5.146 5.854a.5.5 0 01.708-.708L8 7.293z"/>\n </svg>\n </button>\n </div>\n\n <div class="chat-sdk-messages" id="messages-container">\n <div class="chat-sdk-loading">\n <div class="chat-sdk-spinner"></div>\n Loading chat...\n </div>\n </div>\n\n <div class="chat-sdk-input-area">\n <button class="chat-sdk-icon-btn chat-sdk-emoji-btn" type="button" id="emoji-button" aria-label="Emoji">\n <span>😊</span>\n </button>\n <button class="chat-sdk-icon-btn chat-sdk-image-btn" type="button" id="image-button" aria-label="Image">\n <svg width="16" height="16" viewBox="0 0 24 24" fill="currentColor"><path d="M21 19V5a2 2 0 0 0-2-2H5a2 2 0 0 0-2 2v14h18zM5 5h14v8l-3-3-4 5-3-4-4 4V5z"/></svg>\n </button>\n <textarea\n class="chat-sdk-input"\n placeholder="${this.t.inputPlaceholder}"\n rows="1"\n id="message-input"\n ></textarea>\n <input type="file" accept="image/*" id="image-input" style="display:none" />\n <button class="chat-sdk-send-btn" type="button" id="send-button" disabled>\n <svg width="16" height="16" viewBox="0 0 16 16" fill="currentColor">\n <path d="M15.854.146a.5.5 0 01.11.54l-5.819 14.547a.75.75 0 01-1.329.124l-3.178-4.995L.643 7.184a.75.75 0 01.124-1.33L15.314.037a.5.5 0 01.54.11z"/>\n </svg>\n </button>\n </div>\n <div class="chat-sdk-emoji-picker" id="emoji-picker" style="display:none">\n <div class="chat-sdk-emoji-grid">\n <button type="button" class="chat-sdk-emoji-item" data-emoji="😀">😀</button>\n <button type="button" class="chat-sdk-emoji-item" data-emoji="😁">😁</button>\n <button type="button" class="chat-sdk-emoji-item" data-emoji="😂">😂</button>\n <button type="button" class="chat-sdk-emoji-item" data-emoji="🤣">🤣</button>\n <button type="button" class="chat-sdk-emoji-item" data-emoji="😊">😊</button>\n <button type="button" class="chat-sdk-emoji-item" data-emoji="😍">😍</button>\n <button type="button" class="chat-sdk-emoji-item" data-emoji="😎">😎</button>\n <button type="button" class="chat-sdk-emoji-item" data-emoji="🤔">🤔</button>\n <button type="button" class="chat-sdk-emoji-item" data-emoji="👍">👍</button>\n <button type="button" class="chat-sdk-emoji-item" data-emoji="🙏">🙏</button>\n </div>\n </div>\n `,this.messagesContainer=this.widgetElement.querySelector("#messages-container"),this.inputElement=this.widgetElement.querySelector("#message-input"),this.sendButton=this.widgetElement.querySelector("#send-button"),this.emojiButton=this.widgetElement.querySelector("#emoji-button"),this.imageButton=this.widgetElement.querySelector("#image-button"),this.fileInput=this.widgetElement.querySelector("#image-input"),this.emojiPicker=this.widgetElement.querySelector("#emoji-picker"),this.shadowRoot.appendChild(this.widgetElement)}setupEventListeners(){var e,t,s,n;const a=this.widgetElement.querySelector(".chat-sdk-close-btn");null==a||a.addEventListener("click",()=>this.close()),this.messagesContainer.addEventListener("scroll",this.handleScrollLazyLoad.bind(this)),this.inputElement.addEventListener("input",this.handleInputChange.bind(this)),this.inputElement.addEventListener("keydown",this.handleKeyDown.bind(this)),this.sendButton.addEventListener("click",this.handleSendMessage.bind(this)),this.inputElement.addEventListener("input",this.autoResizeTextarea.bind(this)),null===(e=this.emojiButton)||void 0===e||e.addEventListener("click",e=>{e.preventDefault(),e.stopPropagation(),this.toggleEmojiPicker(!this.emojiPanelOpen)}),null===(t=this.emojiPicker)||void 0===t||t.addEventListener("click",e=>{const t=e.target.closest(".chat-sdk-emoji-item");if(t&&t.hasAttribute("data-emoji")){const e=t.getAttribute("data-emoji")||"";this.insertEmojiAtCursor(e),this.toggleEmojiPicker(!1)}}),this.shadowRoot.addEventListener("click",e=>{const t=e.target,s=t.closest("#emoji-picker"),n=t.closest("#emoji-button");s||n||this.toggleEmojiPicker(!1)}),null===(s=this.imageButton)||void 0===s||s.addEventListener("click",e=>{var t;e.preventDefault(),e.stopPropagation(),null===(t=this.fileInput)||void 0===t||t.click()}),null===(n=this.fileInput)||void 0===n||n.addEventListener("change",this.handleImageSelected.bind(this)),document.addEventListener("keydown",e=>{if("Escape"===e.key){const e=document.querySelector(".chat-sdk-viewer-overlay");if(e)return e.style.opacity="0",void setTimeout(()=>e.remove(),200);this.state.isOpen&&this.close()}})}openImageZoom(e){const t=document.querySelector(".chat-sdk-global-zoom-overlay");t&&t.remove();const s=document.createElement("div");s.className="chat-sdk-global-zoom-overlay",Object.assign(s.style,{position:"fixed",top:"0",left:"0",width:"100vw",height:"100vh",backgroundColor:"rgba(0, 0, 0, 0.85)",zIndex:"2147483647",display:"flex",justifyContent:"center",alignItems:"center",cursor:"zoom-out",backdropFilter:"blur(4px)",opacity:"0",transition:"opacity 0.2s ease-in-out"});const n=document.createElement("img");n.src=e,Object.assign(n.style,{maxWidth:"80%",maxHeight:"90%",width:"80%",objectFit:"contain",borderRadius:"8px",boxShadow:"0 4px 20px rgba(0,0,0,0.5)",transform:"scale(0.9)",transition:"transform 0.2s cubic-bezier(0.1, 0.9, 0.2, 1)"}),s.addEventListener("click",()=>{s.style.opacity="0",n.style.transform="scale(0.9)",setTimeout(()=>s.remove(),200)}),s.appendChild(n),document.body.appendChild(s),requestAnimationFrame(()=>{s.style.opacity="1",n.style.transform="scale(1)"})}createFloatingButton(){var e,t,s,n,a,i,o,r,d,l,h;if(!this.shadowRoot)return;const c=this.config.floatingButton||{},m=c.position||"bottom-right",g=String(null!==(t=null!==(e=c.zIndex)&&void 0!==e?e:this.config.zIndex)&&void 0!==t?t:2147483e3),u={top:null===(s=c.offset)||void 0===s?void 0:s.top,right:null===(n=c.offset)||void 0===n?void 0:n.right,bottom:null!==(i=null===(a=c.offset)||void 0===a?void 0:a.bottom)&&void 0!==i?i:20,left:null===(o=c.offset)||void 0===o?void 0:o.left},p=document.createElement("button");p.className="chat-sdk-floating-btn",p.setAttribute("aria-label","Open chat");const y=this.t.joinChat;p.innerHTML=`\n <div style="\n position: relative;\n width: 100%;\n height: 100%;\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n padding: 6px;\n ">\n \x3c!-- Group chat icon (users) --\x3e\n <svg width="28" height="28" viewBox="0 0 24 24" fill="currentColor" style="margin-bottom: 2px;">\n <path d="M16 11c1.66 0 2.99-1.34 2.99-3S17.66 5 16 5c-1.66 0-3 1.34-3 3s1.34 3 3 3zm-8 0c1.66 0 2.99-1.34 2.99-3S9.66 5 8 5C6.34 5 5 6.34 5 8s1.34 3 3 3zm0 2c-2.33 0-7 1.17-7 3.5V19h14v-2.5c0-2.33-4.67-3.5-7-3.5zm8 0c-.29 0-.62.02-.97.05 1.16.84 1.97 1.97 1.97 3.45V19h6v-2.5c0-2.33-4.67-3.5-7-3.5z"/>\n </svg>\n\n \x3c!-- Text overlay at bottom --\x3e\n <div style="\n font-size: 10px;\n font-weight: 600;\n color: rgba(255, 255, 255, 0.95);\n text-align: center;\n line-height: 1.2;\n letter-spacing: 0.3px;\n text-shadow: 0 1px 2px rgba(0,0,0,0.2);\n ">${y}</div>\n\n \x3c!-- Unread badge --\x3e\n <span class="chat-sdk-unread-badge" style="\n position: absolute;\n top: -6px;\n right: -6px;\n background: #ff4444;\n color: white;\n border-radius: 10px;\n min-width: 18px;\n height: 18px;\n display: none;\n align-items: center;\n justify-content: center;\n font-size: 10px;\n font-weight: 700;\n line-height: 1;\n border: 2px solid white;\n box-shadow: 0 2px 4px rgba(0,0,0,0.3);\n padding: 0 5px;\n "></span>\n </div>\n `,p.style.position="fixed",p.style.zIndex=g,p.style.width="60px",p.style.height="60px",p.style.borderRadius="50%",p.style.border="none",p.style.cursor="pointer",p.style.display="flex",p.style.alignItems="center",p.style.justifyContent="center",p.style.color="#fff",p.style.boxShadow="0 10px 24px rgba(0,0,0,0.25), inset 0 2px 4px rgba(255,255,255,0.15)",p.style.background="linear-gradient(145deg, #25D366 0%, #128C7E 100%)",p.style.transition="transform .15s ease, box-shadow .15s ease",p.style.overflow="visible",m.includes("bottom")?(p.style.bottom=(null!==(r=u.bottom)&&void 0!==r?r:20)+"px",p.style.top=""):(p.style.top=(null!==(d=u.top)&&void 0!==d?d:20)+"px",p.style.bottom=""),m.includes("right")?(p.style.right=(null!==(l=u.right)&&void 0!==l?l:20)+"px",p.style.left=""):(p.style.left=(null!==(h=u.left)&&void 0!==h?h:20)+"px",p.style.right=""),p.addEventListener("mouseenter",()=>{p.style.transform="scale(1.06)",p.style.boxShadow="0 14px 28px rgba(0,0,0,0.30), inset 0 2px 4px rgba(255,255,255,0.2)"}),p.addEventListener("mouseleave",()=>{p.style.transform="scale(1)",p.style.boxShadow="0 10px 24px rgba(0,0,0,0.25), inset 0 2px 4px rgba(255,255,255,0.15)"}),p.addEventListener("mousedown",()=>{p.style.transform="scale(0.95)"}),p.addEventListener("mouseup",()=>{p.style.transform="scale(1.05)",setTimeout(()=>p.style.transform="scale(1)",100)}),p.addEventListener("click",e=>{e.preventDefault(),this.open()}),this.shadowRoot.appendChild(p),this.floatingButtonEl=p}updateUnreadBadge(){if(!this.floatingButtonEl)return;const e=this.floatingButtonEl.querySelector(".chat-sdk-unread-badge");if(!e)return;const t=this.state.unreadCount;t>0?(e.textContent=t>99?"99+":t.toString(),e.style.display="flex"):e.style.display="none"}markAllAsRead(){if(this.state.messages.length>0){const e=this.state.messages[this.state.messages.length-1];this.state.lastReadMessageId=e.id}this.state.unreadCount=0,this.updateUnreadBadge()}incrementUnreadCount(){this.state.isOpen||(this.state.unreadCount++,this.updateUnreadBadge())}toggleEmojiPicker(e){const t=this.emojiPicker;if(!t)return;const s="boolean"==typeof e?e:"none"===t.style.display;t.style.display=s?"block":"none",this.emojiPanelOpen=s}insertEmojiAtCursor(e){const t=this.inputElement,s=t.selectionStart||0,n=t.selectionEnd||0,a=t.value.substring(0,s),i=t.value.substring(n);t.value=a+e+i;const o=s+e.length;t.setSelectionRange(o,o),t.focus(),this.handleInputChange(),this.autoResizeTextarea()}isEmojiOnly(e){const t=e.trim();if(!t)return!1;if(t.length>6)return!1;let s=!1;for(let e=0;e<t.length;){const n=t.codePointAt(e)||0;if(e+=n>65535?2:1,!(n>=126976))return!1;s=!0}return s}async handleImageSelected(){const e=this.fileInput;if(!e||!e.files||0===e.files.length)return;const s=e.files[0];try{const t=await this.resizeImageFile(s,1280,.85),n={id:`local-img-failed-${Date.now()}-${Math.random().toString(36).slice(2,8)}`,content:t,messageType:"image",timestamp:new Date,isOwnMessage:!0,user:{id:this.config.userId||"me",username:this.config.username||"You"},failed:!0};this.state.messages.push(n),this.renderMessage(n),this.scrollToBottom(!0),e.value=""}catch(e){console.error("Image processing failed",e),this.emit("error",new t("Image processing failed","IMAGE_PROCESS_ERROR",e))}}resizeImageFile(e,t=1280,s=.85){return new Promise((n,a)=>{const i=URL.createObjectURL(e),o=new Image;o.onload=()=>{let{width:e,height:r}=o;const d=Math.min(1,t/Math.max(e,r)),l=document.createElement("canvas");d<1&&(e=Math.round(e*d),r=Math.round(r*d)),l.width=e,l.height=r;const h=l.getContext("2d");if(!h)return URL.revokeObjectURL(i),void a(new Error("Canvas not supported"));h.drawImage(o,0,0,e,r);const c=l.toDataURL("image/jpeg",s);URL.revokeObjectURL(i),n(c)},o.onerror=e=>{URL.revokeObjectURL(i),a(e)},o.src=i})}handleInputChange(){const e=this.inputElement.value.trim().length>0,t=!1!==this.config.enableUserInput&&!1!==this.config.allowInput;this.sendButton.disabled=!e||!t,e&&t&&this.emit("typing")}handleKeyDown(e){"Enter"!==e.key||e.shiftKey||(e.preventDefault(),this.handleSendMessage())}async handleSendMessage(){const e=this.inputElement.value.trim();if(!e)return;if(!1===this.config.enableUserInput||!1===this.config.allowInput)return;const s=this.isEmojiOnly(e)?"emoji":"text",n={id:`local-${Date.now()}-${Math.random().toString(36).slice(2,8)}`,content:e,messageType:s,timestamp:new Date,isOwnMessage:!0,user:{id:this.config.userId||"me",username:this.config.username||"You"}};this.state.messages.push(n),this.renderMessage(n),this.scrollToBottom(!0),this.inputElement.value="",this.sendButton.disabled=!0,this.autoResizeTextarea(),this.simulator.sendMessage(e,s).catch(e=>{console.error("Failed to send message:",e),this.emit("error",new t("Failed to send message","SEND_MESSAGE_ERROR",e))})}autoResizeTextarea(){this.inputElement.style.height="auto",this.inputElement.style.height=Math.min(this.inputElement.scrollHeight,100)+"px"}open(){var e;if(this.state.isOpen)return;if(this.hasInitializedData)try{this.simulator.startPolling()}catch(e){}else this.hasInitializedData=!0,this.setLoading(!0),this.initializeSimulation().catch(e=>{console.error("Failed to initialize simulation on open:",e),this.setLoading(!1)});this.pollingStopTimer&&(clearTimeout(this.pollingStopTimer),this.pollingStopTimer=null),this.floatingButtonEl&&(this.floatingButtonEl.style.display="none"),this.widgetElement.style.opacity="0",this.widgetElement.style.display="flex",requestAnimationFrame(()=>{this.widgetElement.style.transition="opacity .2s ease",this.widgetElement.style.opacity="1"}),this.state.isOpen=!0,this.markAllAsRead(),this.emit("open");const t=(null===(e=this.state.currentProject)||void 0===e?void 0:e.name)||"Chat";this.setTitle(t,`${this.state.displayedMessageCount} ${this.t.messages}`),this.scrollToBottom(!0),requestAnimationFrame(()=>this.scrollToBottom(!0)),setTimeout(()=>this.scrollToBottom(!0),0)}close(){this.state.isOpen&&(this.widgetElement.style.transition="opacity .2s ease",this.widgetElement.style.opacity="0",setTimeout(()=>{this.widgetElement.style.display="none",this.floatingButtonEl&&(this.floatingButtonEl.style.display="flex")},200),this.state.isOpen=!1,this.pollingStopTimer&&clearTimeout(this.pollingStopTimer),this.pollingStopTimer=setTimeout(()=>{try{this.simulator.stopPolling()}catch(e){}this.pollingStopTimer=null},1e4),this.emit("close"))}setTitle(e,t){var s,n;const a=null===(s=this.widgetElement)||void 0===s?void 0:s.querySelector("#chat-title"),i=null===(n=this.widgetElement)||void 0===n?void 0:n.querySelector("#chat-subtitle"),o=b(this.t.chatGroup,{name:e||"Chat"});this.currentTheme,a&&(a.textContent=o),i&&(i.textContent=b(this.t.online,{count:this.onlineCount}),i.style.display="block")}buildMessageElement(e,t){const s=n("div","chat-sdk-message");e.isOwnMessage&&s.classList.add("own");const a=!!t&&this.shouldGroupWithPrev(t,e);a&&s.classList.add("grouped");let i=null;e.isOwnMessage||(i=this.createAvatar(e),a&&i&&(i.style.visibility="hidden"));const o=!e.isOwnMessage&&!a,r="whatsapp"===this.currentTheme,d="telegram"===this.currentTheme&&e.isOwnMessage,l=this.createMessageContent(e,o,r,d);return i&&s.appendChild(i),s.appendChild(l),s}shouldGroupWithPrev(e,t){var s,n,a,i,o,r,d;if(!1===this.config.groupMessages)return!1;const l=null!==(s=this.config.groupTimeThresholdSec)&&void 0!==s?s:120,h=e.isOwnMessage===t.isOwnMessage,c=(null===(n=e.virtualUser)||void 0===n?void 0:n.id)&&(null===(a=e.virtualUser)||void 0===a?void 0:a.id)===(null===(i=t.virtualUser)||void 0===i?void 0:i.id),m=(null===(o=e.user)||void 0===o?void 0:o.id)&&(null===(r=e.user)||void 0===r?void 0:r.id)===(null===(d=t.user)||void 0===d?void 0:d.id),g=h&&(c||m||e.isOwnMessage&&t.isOwnMessage),u=Math.abs(t.timestamp.getTime()-e.timestamp.getTime())/1e3;return!!g&&u<=l}handleScrollLazyLoad(){if(this.messagesContainer.scrollTop<=20&&this.visibleStartIndex>0){const e=this.messagesContainer.scrollHeight,t=this.lazyLoadBatchSize,s=Math.max(0,this.visibleStartIndex-t),n=this.state.messages.slice(s,this.visibleStartIndex),a=document.createDocumentFragment();for(const e of n){const t=this.buildMessageElement(e);a.appendChild(t)}this.messagesContainer.insertBefore(a,this.messagesContainer.firstChild),this.visibleStartIndex=s;const i=this.messagesContainer.scrollHeight;this.messagesContainer.scrollTop+=i-e}}setLoading(e){if(e){if(!this.messagesContainer.querySelector(".chat-sdk-loading")){const e=document.createElement("div");e.className="chat-sdk-loading",e.innerHTML='\n <div class="chat-sdk-spinner"></div>\n Loading chat...\n ',this.messagesContainer.appendChild(e)}}else{const e=this.messagesContainer.querySelector(".chat-sdk-loading");null==e||e.remove()}}showJoinOverlay(){const e=n("div","chat-sdk-overlay");e.innerHTML='\n <div class="chat-sdk-join-card">\n <h3 class="chat-sdk-join-title">Join the conversation</h3>\n <p class="chat-sdk-join-description">\n Click below to join this group chat and start interacting with other members.\n </p>\n <button class="chat-sdk-join-btn" type="button">Join Chat</button>\n </div>\n ';const t=e.querySelector(".chat-sdk-join-btn");null==t||t.addEventListener("click",()=>{this.hideJoinOverlay(),this.emit("join-requested")}),this.widgetElement.appendChild(e)}hideJoinOverlay(){const e=this.widgetElement.querySelector(".chat-sdk-overlay");e&&e.remove()}addMessage(e){if(e.isOwnMessage)for(let t=this.state.messages.length-1;t>=0;t--){const s=this.state.messages[t];if(s.isOwnMessage&&s.content===e.content){if(Math.abs(e.timestamp.getTime()-s.timestamp.getTime())<=1e4)return;break}}this.state.messages.find(t=>t.id===e.id)?console.warn("Duplicate message detected and ignored:",e.id):(this.state.messages.push(e),this.renderMessage(e),e.isOwnMessage||this.incrementUnreadCount(),this.scrollToBottom(!0))}addMessagesBulk(e){if(!e||0===e.length)return;if(0===this.messagesContainer.querySelectorAll(".chat-sdk-message").length){this.state.messages=[...e].sort((e,t)=>e.timestamp.getTime()-t.timestamp.getTime());const t=this.state.messages.length,s=this.initialRenderCount;this.visibleStartIndex=Math.max(0,t-s);const n=this.state.messages.slice(this.visibleStartIndex),a=document.createDocumentFragment();let i;for(const e of n){const t=this.buildMessageElement(e,i);a.appendChild(t),i=e}this.messagesContainer.appendChild(a),setTimeout(()=>{this.scrollToBottom(!0)},0)}else{const t=new Set(this.state.messages.map(e=>e.id)),s=e.filter(e=>!t.has(e.id));if(s.length>0){this.state.messages.push(...s),this.state.messages.sort((e,t)=>e.timestamp.getTime()-t.timestamp.getTime()),this.messagesContainer.innerHTML="";const e=this.state.messages.length,t=this.initialRenderCount;this.visibleStartIndex=Math.max(0,e-t);const n=this.state.messages.slice(this.visibleStartIndex),a=document.createDocumentFragment();let i;for(const e of n){const t=this.buildMessageElement(e,i);a.appendChild(t),i=e}this.messagesContainer.appendChild(a),this.scrollToBottom()}}}reRenderAllMessages(){this.messagesContainer.innerHTML="";const e=this.state.messages.length,t=Math.max(0,e-this.initialRenderCount);this.state.messages.slice(t).forEach(e=>{this.renderMessage(e)}),this.scrollToBottom()}renderMessage(e){const t=this.state.messages.length-1,s=t>0?this.state.messages[t-1]:void 0,n=this.buildMessageElement(e,s);this.messagesContainer.appendChild(n)}createAvatar(e){var t,s,a,i;const o=n("div","chat-sdk-message-avatar");if(null===(t=e.virtualUser)||void 0===t?void 0:t.avatar)o.style.backgroundImage=`url(${e.virtualUser.avatar})`,o.style.backgroundSize="cover",o.style.backgroundPosition="center";else if(null===(s=e.user)||void 0===s?void 0:s.avatar)o.style.backgroundImage=`url(${e.user.avatar})`,o.style.backgroundSize="cover",o.style.backgroundPosition="center";else{const t=(null===(a=e.virtualUser)||void 0===a?void 0:a.username)||(null===(i=e.user)||void 0===i?void 0:i.username)||"U";o.textContent=t.charAt(0).toUpperCase()}return o}createMessageContent(e,t=!0,s=!1,i=!1){var o,r,d;const l=n("div","chat-sdk-message-content"),h=(null===(o=e.virtualUser)||void 0===o?void 0:o.displayName)||(null===(r=e.virtualUser)||void 0===r?void 0:r.username)||(null===(d=e.user)||void 0===d?void 0:d.username)||"Unknown";let c="";if("image"===e.messageType){c=`\n <div class="chat-sdk-message-image${e.failed?" failed":""}">\n <img src="${a(e.content)}" alt="Image"\n style="max-width: 200px; max-height: 280px; width: 100%; height: auto; cursor: pointer; display: block; border-radius: 8px; object-fit: cover;"\n data-image-url="${a(e.content)}"\n class="chat-sdk-image-preview" />\n </div>\n `}else c="emoji"===e.messageType?`<div class="chat-sdk-message-emoji" style="font-size: 2em; line-height: 1;">${a(e.content)}</div>`:`<p class="chat-sdk-message-text">${a(e.content)}</p>`;const m=`${function(e,t){const s=new Date,n=Math.floor((s.getTime()-e.getTime())/1e3),a=(t||("undefined"!=typeof navigator?navigator.language:"en")).toLowerCase().startsWith("zh");if(n<60)return a?"刚刚":"just now";if(n<3600){const e=Math.floor(n/60);return a?`${e} 分钟前`:`${e}m ago`}if(n<86400){const e=Math.floor(n/3600);return a?`${e} 小时前`:`${e}h ago`}const i=new Date(s.getFullYear(),s.getMonth(),s.getDate());if(e>=new Date(i.getTime()-864e5)&&e<i){const t=e.toLocaleTimeString(a?"zh-CN":void 0,{hour:"2-digit",minute:"2-digit",hour12:!1});return a?`昨天 ${t}`:`yesterday ${t}`}return s.getTime()-e.getTime()<6048e5?e.toLocaleString(a?"zh-CN":void 0,{month:"short",day:"numeric",hour:"2-digit",minute:"2-digit",hour12:!1}):e.toLocaleString(a?"zh-CN":void 0,{year:"numeric",month:"2-digit",day:"2-digit",hour:"2-digit",minute:"2-digit",hour12:!1})}(e.timestamp,this.config.language)}`,g=i?'<span class="chat-sdk-read-status">✓✓</span>':"",u=e.failed&&e.isOwnMessage?'<div class="chat-sdk-message-failed-indicator">\n <svg width="16" height="16" viewBox="0 0 16 16" fill="currentColor">\n <circle cx="8" cy="8" r="8" fill="#ff4444"/>\n <path d="M8 4v4M8 10h.01" stroke="white" stroke-width="1.5" stroke-linecap="round"/>\n </svg>\n </div>':"";return l.innerHTML=s?`\n <div class="chat-sdk-message-bubble">\n ${t&&!e.isOwnMessage?`<div class="chat-sdk-message-username">${a(h)}</div>`:""}\n ${c}\n <div class="chat-sdk-message-time-inside">${m}${g?" "+g:""}</div>\n </div>\n ${u}\n `:`\n ${t&&!e.isOwnMessage?`<div class="chat-sdk-message-username">${a(h)}</div>`:""}\n <div class="chat-sdk-message-bubble">\n ${c}\n </div>\n <div class="chat-sdk-message-time">${m}${g?" "+g:""}</div>\n ${u}\n `,l}scrollToBottom(e=!1){const t=this.messagesContainer;if(e)return void i(t);t.scrollTop+t.clientHeight>=t.scrollHeight-40&&i(t)}setupImageViewer(){this.messagesContainer.addEventListener("click",e=>{const t=e.target;if(t.classList.contains("chat-sdk-image-preview")){const e=t.getAttribute("data-image-url");e&&this.openImageViewer(e)}})}openImageViewer(e){const t=document.querySelector(".chat-sdk-viewer-overlay");t&&t.remove();const s=document.createElement("div");s.className="chat-sdk-viewer-overlay",Object.assign(s.style,{position:"fixed",inset:"0",width:"100vw",height:"100vh",background:"rgba(0,0,0,0.88)",zIndex:"2147483647",display:"flex",alignItems:"center",justifyContent:"center",opacity:"0",transition:"opacity 0.2s ease",cursor:"zoom-out"});const n=document.createElement("button");Object.assign(n.style,{position:"absolute",top:"16px",right:"20px",background:"none",border:"none",color:"#fff",fontSize:"32px",cursor:"pointer",lineHeight:"1",padding:"4px",zIndex:"1"}),n.innerHTML="×",n.setAttribute("aria-label","Close");const a=document.createElement("img");a.src=e,a.alt="Full size image",Object.assign(a.style,{maxWidth:"90vw",maxHeight:"90vh",objectFit:"contain",borderRadius:"8px",boxShadow:"0 8px 32px rgba(0,0,0,0.6)",transform:"scale(0.92)",transition:"transform 0.2s cubic-bezier(0.1, 0.9, 0.2, 1)",cursor:"default",display:"block"});s.addEventListener("click",e=>{e.target!==s&&e.target!==n||(s.style.opacity="0",a.style.transform="scale(0.92)",setTimeout(()=>{s.parentNode&&s.remove()},200))}),a.addEventListener("click",e=>e.stopPropagation()),s.appendChild(n),s.appendChild(a),document.body.appendChild(s),requestAnimationFrame(()=>{s.style.opacity="1",a.style.transform="scale(1)"})}showImagePreview(e){const t=n("div","chat-sdk-image-modal");t.innerHTML=`\n <div class="chat-sdk-image-modal-overlay">\n <div class="chat-sdk-image-modal-content">\n <button class="chat-sdk-image-modal-close">×</button>\n <img src="${a(e)}" alt="Image Preview" class="chat-sdk-image-modal-img" />\n </div>\n </div>\n `,this.widgetElement.appendChild(t);const s=t.querySelector(".chat-sdk-image-modal-close"),i=t.querySelector(".chat-sdk-image-modal-overlay"),o=()=>{t.remove()};null==s||s.addEventListener("click",o),null==i||i.addEventListener("click",e=>{e.target===i&&o()});const r=e=>{"Escape"===e.key&&(o(),document.removeEventListener("keydown",r))};document.addEventListener("keydown",r)}setJoined(e){this.state.isJoined=e,this.handleInputChange()}setUITemplate(e){this.currentTheme=e,this.config.uiTemplate=e,this.widgetElement.classList.remove("whatsapp-theme","telegram-theme","dark"),this.widgetElement.classList.add(`${e}-theme`),"telegram"===e&&this.isDarkMode&&this.widgetElement.classList.add("dark"),this.updateThemeStyles(),this.reRenderAllMessages()}setTheme(e){this.isDarkMode="dark"===e,this.config.theme=e,"telegram"===this.currentTheme&&(this.isDarkMode?this.widgetElement.classList.add("dark"):this.widgetElement.classList.remove("dark"),this.updateThemeStyles())}setCustomColors(e){this.customColors={...this.customColors,...e},this.config.primaryColor=e.primary,this.config.backgroundColor=e.background,this.updateThemeStyles()}updateThemeStyles(){const e=this.currentTheme,t=this.isDarkMode&&"telegram"===e,s=this.shadowRoot||document.documentElement;"whatsapp"===e?(this.setCSSProperty(s,"--chat-primary-color",this.customColors.primary||"#25D366"),this.setCSSProperty(s,"--chat-background-color",this.customColors.background||"#ECE5DD"),this.setCSSProperty(s,"--chat-message-own-bg","#DCF8C6"),this.setCSSProperty(s,"--chat-message-other-bg","#FFFFFF"),this.setCSSProperty(s,"--chat-header-bg","linear-gradient(135deg, #075e54 0%, #128c7e 100%)")):"telegram"===e&&(t?(this.setCSSProperty(s,"--chat-primary-color",this.customColors.primary||"#4FC3F7"),this.setCSSProperty(s,"--chat-background-color",this.customColors.background||"#212121"),this.setCSSProperty(s,"--chat-message-own-bg","linear-gradient(135deg, #4fc3f7 0%, #29b6f6 100%)"),this.setCSSProperty(s,"--chat-message-other-bg","#2F2F2F"),this.setCSSProperty(s,"--chat-header-bg","linear-gradient(135deg, #1976d2 0%, #1565c0 100%)"),this.setCSSProperty(s,"--chat-text-color","#FFFFFF")):(this.setCSSProperty(s,"--chat-primary-color",this.customColors.primary||"#2481CC"),this.setCSSProperty(s,"--chat-background-color",this.customColors.background||"#FFFFFF"),this.setCSSProperty(s,"--chat-message-own-bg","linear-gradient(135deg, #4fc3f7 0%, #29b6f6 100%)"),this.setCSSProperty(s,"--chat-message-other-bg","#F1F1F1"),this.setCSSProperty(s,"--chat-header-bg","linear-gradient(135deg, #2481cc 0%, #1c7cd6 100%)"),this.setCSSProperty(s,"--chat-text-color","#000000")))}setCSSProperty(e,t,s){if(e instanceof ShadowRoot){const n=e.querySelector("style");if(n){const e=n.textContent||"",a=new RegExp(`${t}\\s*:\\s*[^;]+;`,"g"),i=`${t}: ${s};`;if(a.test(e))n.textContent=e.replace(a,i);else{const t=/:host\s*\{([^}]*)\}/;t.test(e)?n.textContent=e.replace(t,(e,t)=>`:host { ${t} ${i} }`):n.textContent=`:host { ${i} }\n${e}`}}}else e.style.setProperty(t,s)}getState(){return{...this.state}}getDefaultStyles(){return"\n :host {\n --chat-primary-color: #25D366;\n --chat-background-color: #ECE5DD;\n --chat-message-own-bg: #DCF8C6;\n --chat-message-other-bg: #FFFFFF;\n --chat-header-bg: linear-gradient(135deg, #075e54 0%, #128c7e 100%);\n --chat-text-color: #333333;\n --chat-border-radius-message: 18px;\n --chat-border-radius-input: 25px;\n }\n\n .chat-sdk-container {\n font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif;\n font-size: 14px;\n line-height: 1.5;\n color: var(--chat-text-color);\n background: var(--chat-background-color);\n border-radius: 12px;\n box-shadow: 0 4px 20px rgba(0, 0, 0, 0.15);\n overflow: hidden;\n display: flex;\n flex-direction: column;\n position: relative;\n max-width: 100%;\n max-height: 100%;\n }\n\n .chat-sdk-container * {\n box-sizing: border-box;\n }\n\n /* WhatsApp Theme */\n .chat-sdk-container.whatsapp-theme .chat-sdk-header {\n background: linear-gradient(135deg, #075e54 0%, #128c7e 100%);\n color: white;\n padding: 12px 16px;\n display: flex;\n align-items: center;\n justify-content: flex-end;\n min-height: 60px;\n box-shadow: 0 1px 3px rgba(0,0,0,0.12);\n }\n .chat-sdk-container.whatsapp-theme .chat-sdk-header-left { display: none; }\n\n .chat-sdk-container.whatsapp-theme .chat-sdk-messages {\n background-color: #ece5dd;\n background-image: url(\"data:image/svg+xml,%3Csvg width='60' height='60' viewBox='0 0 60 60' xmlns='http://www.w3.org/2000/svg'%3E%3Cg fill='none' fill-rule='evenodd'%3E%3Cg fill='%23e5ddd5' fill-opacity='0.08'%3E%3Cpath d='M36 34v-4h-2v4h-4v2h4v4h2v-4h4v-2h-4zm0-30V0h-2v4h-4v2h4v4h2V6h4V4h-4zM6 34v-4H4v4H0v2h4v4h2v-4h4v-2H6zM6 4V0H4v4H0v2h4v4h2V6h4V4H6z'/%3E%3C/g%3E%3C/g%3E%3C/svg%3E\");\n padding: 8px 6px;\n }\n\n .chat-sdk-container.whatsapp-theme {\n --chat-primary-color: #25D366;\n --chat-background-color: #ECE5DD;\n --chat-message-own-bg: #DCF8C6;\n --chat-message-other-bg: #FFFFFF;\n --chat-header-bg: linear-gradient(135deg, #075e54 0%, #128c7e 100%);\n --chat-text-color: #303030;\n --chat-border-radius-message: 7.5px;\n --chat-border-radius-input: 25px;\n display: flex;\n flex-direction: column;\n height: 100%;\n }\n\n /* ── WhatsApp: Message Row Layout ── */\n .chat-sdk-container.whatsapp-theme .chat-sdk-message {\n display: flex;\n flex-direction: row;\n align-items: flex-end;\n margin-bottom: 4px;\n padding: 1px 10px;\n gap: 6px;\n }\n\n /* Own message: green bubble, right side, no avatar */\n .chat-sdk-container.whatsapp-theme .chat-sdk-message.own {\n flex-direction: row-reverse;\n justify-content: flex-start;\n }\n .chat-sdk-container.whatsapp-theme .chat-sdk-message.own .chat-sdk-message-avatar {\n display: none;\n }\n\n /* ── WhatsApp: Avatar ── */\n .chat-sdk-container.whatsapp-theme .chat-sdk-message-avatar {\n width: 32px;\n height: 32px;\n flex-shrink: 0;\n border-radius: 50%;\n align-self: flex-end;\n margin-bottom: 0;\n font-size: 13px;\n font-weight: 700;\n color: #fff;\n background: #aaa;\n }\n\n /* ── WhatsApp: Message Content Wrapper ── */\n .chat-sdk-container.whatsapp-theme .chat-sdk-message-content {\n max-width: 72%;\n min-width: 60px;\n position: relative;\n display: flex;\n flex-direction: column;\n }\n\n /* ── WhatsApp: Bubble ── */\n .chat-sdk-container.whatsapp-theme .chat-sdk-message-bubble {\n background: #fff;\n color: #303030;\n border-radius: 7.5px;\n padding: 6px 10px 20px 10px;\n box-shadow: 0 1px 0.5px rgba(0,0,0,0.13);\n position: relative;\n word-wrap: break-word;\n word-break: break-word;\n display: block;\n max-width: 100%;\n }\n\n /* Tail for other-person bubble (left bottom corner) */\n .chat-sdk-container.whatsapp-theme .chat-sdk-message:not(.own):not(.grouped) .chat-sdk-message-bubble::before {\n content: '';\n position: absolute;\n bottom: 0;\n left: -8px;\n width: 0;\n height: 0;\n border-style: solid;\n border-width: 0 0 8px 8px;\n border-color: transparent transparent #fff transparent;\n filter: drop-shadow(-1px 1px 0.5px rgba(0,0,0,0.10));\n }\n\n /* Own bubble: green */\n .chat-sdk-container.whatsapp-theme .chat-sdk-message.own .chat-sdk-message-bubble {\n background: #DCF8C6;\n color: #303030;\n border-radius: 7.5px;\n }\n\n /* Tail for own bubble (right bottom corner) */\n .chat-sdk-container.whatsapp-theme .chat-sdk-message.own:not(.grouped) .chat-sdk-message-bubble::before {\n content: '';\n position: absolute;\n bottom: 0;\n right: -8px;\n left: auto;\n width: 0;\n height: 0;\n border-style: solid;\n border-width: 8px 0 0 8px;\n border-color: transparent transparent transparent #DCF8C6;\n filter: drop-shadow(1px 1px 0.5px rgba(0,0,0,0.10));\n }\n\n /* ── WhatsApp: Username inside bubble (colored) ── */\n .chat-sdk-container.whatsapp-theme .chat-sdk-message-username {\n font-size: 12.5px;\n font-weight: 600;\n margin-bottom: 2px;\n line-height: 1.2;\n display: block;\n }\n\n /* Cycle username colors like real WhatsApp */\n .chat-sdk-container.whatsapp-theme .chat-sdk-message:nth-child(7n+1) .chat-sdk-message-username { color: #e91e8c; }\n .chat-sdk-container.whatsapp-theme .chat-sdk-message:nth-child(7n+2) .chat-sdk-message-username { color: #e67e22; }\n .chat-sdk-container.whatsapp-theme .chat-sdk-message:nth-child(7n+3) .chat-sdk-message-username { color: #1abc9c; }\n .chat-sdk-container.whatsapp-theme .chat-sdk-message:nth-child(7n+4) .chat-sdk-message-username { color: #9b59b6; }\n .chat-sdk-container.whatsapp-theme .chat-sdk-message:nth-child(7n+5) .chat-sdk-message-username { color: #e74c3c; }\n .chat-sdk-container.whatsapp-theme .chat-sdk-message:nth-child(7n+6) .chat-sdk-message-username { color: #3498db; }\n .chat-sdk-container.whatsapp-theme .chat-sdk-message:nth-child(7n+0) .chat-sdk-message-username { color: #2ecc71; }\n\n /* ── WhatsApp: Input area ── */\n .chat-sdk-container.whatsapp-theme .chat-sdk-input-area {\n background: #f0f2f5;\n border-top: none;\n padding: 8px 10px;\n }\n .chat-sdk-container.whatsapp-theme .chat-sdk-input {\n background: #fff;\n border: none;\n border-radius: 22px;\n padding: 9px 14px;\n font-size: 15px;\n box-shadow: none;\n }\n .chat-sdk-container.whatsapp-theme .chat-sdk-send-btn {\n background: #00a884;\n width: 42px;\n height: 42px;\n box-shadow: none;\n }\n\n\n /* Telegram Theme */\n .chat-sdk-container.telegram-theme {\n --chat-primary-color: #2481CC;\n --chat-background-color: #FFFFFF;\n --chat-message-own-bg: linear-gradient(135deg, #4fc3f7 0%, #29b6f6 100%);\n --chat-message-other-bg: #F1F1F1;\n --chat-header-bg: linear-gradient(135deg, #2481cc 0%, #1c7cd6 100%);\n --chat-text-color: #000000;\n --chat-border-radius-message: 12px;\n --chat-border-radius-input: 12px;\n\n /* Telegram input + details */\n .chat-sdk-container.telegram-theme .chat-sdk-message {\n align-items: flex-start; /* avatar aligns with username at top, not bottom */\n }\n .chat-sdk-container.telegram-theme .chat-sdk-message-content {\n max-width: 75%;\n }\n .chat-sdk-container.telegram-theme .chat-sdk-message-bubble {\n box-shadow: 0 1px 1px rgba(0,0,0,0.06);\n }\n .chat-sdk-container.telegram-theme .chat-sdk-input-area {\n background: #ffffff;\n border-top: 1px solid #e6e6e6;\n }\n .chat-sdk-container.telegram-theme .chat-sdk-input {\n background: #fff;\n border: 1px solid #cfd6dd;\n border-radius: 12px;\n padding: 9px 14px;\n }\n .chat-sdk-container.telegram-theme .chat-sdk-send-btn {\n background: #2481CC;\n border-radius: 10px;\n width: 38px;\n height: 36px;\n box-shadow: none;\n }\n /* Telegram dark */\n .chat-sdk-container.telegram-theme.dark .chat-sdk-input-area {\n background: #1f1f1f;\n border-top: 1px solid #2a2a2a;\n }\n .chat-sdk-container.telegram-theme.dark .chat-sdk-input {\n background: #2b2b2b;\n color: #e0e0e0;\n border-color: #444;\n }\n .chat-sdk-container.telegram-theme.dark .chat-sdk-send-btn {\n background: #1976d2;\n }\n\n\n .chat-sdk-container.telegram-theme .chat-sdk-header {\n background: var(--chat-header-bg);\n color: white;\n padding: 12px 16px;\n display: flex;\n align-items: center;\n justify-content: space-between;\n min-height: 60px;\n box-shadow: 0 1px 3px rgba(0,0,0,0.12);\n }\n\n .chat-sdk-container.telegram-theme .chat-sdk-messages {\n background-color: var(--chat-background-color);\n }\n\n .chat-sdk-container.telegram-theme .chat-sdk-message.own .chat-sdk-message-bubble {\n background: var(--chat-message-own-bg);\n color: white;\n border-radius: var(--chat-border-radius-message) var(--chat-border-radius-message) 4px var(--chat-border-radius-message);\n }\n\n .chat-sdk-container.telegram-theme .chat-sdk-message:not(.own) .chat-sdk-message-bubble {\n background: var(--chat-message-other-bg);\n color: var(--chat-text-color);\n border-radius: var(--chat-border-radius-message) var(--chat-border-radius-message) var(--chat-border-radius-message) 4px;\n }\n\n /* Telegram Dark Theme */\n .chat-sdk-container.telegram-theme.dark {\n --chat-background-color: #212121;\n --chat-message-other-bg: #2F2F2F;\n --chat-header-bg: linear-gradient(135deg, #1976d2 0%, #1565c0 100%);\n --chat-text-color: #FFFFFF;\n }\n\n /* Default header (fallback) */\n .chat-sdk-header {\n background: var(--chat-header-bg);\n color: white;\n padding: 12px 16px;\n display: flex;\n align-items: center;\n justify-content: space-between;\n min-height: 60px;\n }\n\n .chat-sdk-header-left { display: flex; flex-direction: column; gap: 2px; }\n .chat-sdk-title { font-size: 15px; font-weight: 600; }\n .chat-sdk-subtitle { font-size: 12px; opacity: 0.9; }\n\n .chat-sdk-close-btn {\n background: none;\n border: none;\n color: white;\n cursor: pointer;\n padding: 8px;\n border-radius: 50%;\n opacity: 0.8;\n transition: all 0.2s;\n display: flex;\n align-items: center;\n justify-content: center;\n width: 36px;\n height: 36px;\n }\n\n .chat-sdk-close-btn:hover {\n opacity: 1;\n background: rgba(255, 255, 255, 0.1);\n }\n\n .chat-sdk-messages {\n flex: 1;\n overflow-y: auto;\n padding: 16px;\n background: var(--chat-background-color);\n min-height: 0; /* allow flex to use full height */\n }\n\n .chat-sdk-message {\n margin-bottom: 12px;\n display: flex;\n align-items: flex-end;\n gap: 8px;\n }\n\n .chat-sdk-message.own {\n flex-direction: row-reverse;\n }\n\n .chat-sdk-message-avatar {\n width: 32px;\n height: 32px;\n border-radius: 50%;\n background: #ddd;\n display: flex;\n align-items: center;\n justify-content: center;\n font-size: 12px;\n font-weight: 600;\n color: #666;\n flex-shrink: 0;\n }\n\n .chat-sdk-message-content {\n max-width: 70%;\n position: relative;\n }\n\n .chat-sdk-message-bubble {\n background: var(--chat-message-other-bg);\n color: var(--chat-text-color);\n padding: 8px 12px;\n border-radius: var(--chat-border-radius-message);\n position: relative;\n word-wrap: break-word;\n box-shadow: 0 1px 2px rgba(0, 0, 0, 0.1);\n }\n\n .chat-sdk-message.own .chat-sdk-message-bubble {\n background: var(--chat-message-own-bg);\n color: white;\n }\n\n .chat-sdk-message-username {\n font-size: 11px;\n color: #666;\n margin-bottom: 2px;\n font-weight: 600;\n }\n\n .chat-sdk-message-text {\n margin: 0;\n line-height: 1.4;\n }\n\n .chat-sdk-message-time {\n font-size: 10px;\n color: #999;\n margin-top: 4px;\n text-align: right;\n }\n\n /* Message grouping */\n .chat-sdk-message.grouped {\n margin-top: 4px;\n }\n .chat-sdk-message.grouped .chat-sdk-message-username { display: none; }\n .chat-sdk-message.grouped .chat-sdk-message-avatar { visibility: hidden; }\n\n /* WhatsApp: time inside bubble */\n .chat-sdk-container.whatsapp-theme .chat-sdk-message-time-inside {\n position: absolute;\n right: 6px;\n bottom: 4px;\n font-size: 11px;\n color: rgba(0,0,0,0.45);\n display: flex;\n align-items: center;\n gap: 3px;\n line-height: 1;\n }\n .chat-sdk-container.whatsapp-theme .chat-sdk-message.own .chat-sdk-message-time-inside {\n color: rgba(0, 0, 0, 0.45);\n }\n /* hide external time for whatsapp (time is inside bubble) */\n .chat-sdk-container.whatsapp-theme .chat-sdk-message-time {\n display: none;\n }\n\n /* Telegram: read status */\n .chat-sdk-container.telegram-theme .chat-sdk-message-time {\n display: flex;\n align-items: center;\n justify-content: flex-end;\n gap: 6px;\n }\n .chat-sdk-container.telegram-theme .chat-sdk-message.own .chat-sdk-read-status {\n font-size: 12px;\n color: var(--chat-primary-color);\n line-height: 1;\n }\n\n /* Theme-specific image radii */\n .chat-sdk-container.whatsapp-theme .chat-sdk-message-image img { border-radius: 8px; max-width: 200px; max-height: 280px; }\n .chat-sdk-container.telegram-theme .chat-sdk-message-image img { border-radius: 6px; max-width: 200px; max-height: 280px; }\n\n\n .chat-sdk-input-area {\n padding: 12px 16px;\n background: white;\n border-top: 1px solid #e0e0e0;\n display: flex;\n align-items: center;\n gap: 8px;\n }\n\n\n .chat-sdk-icon-btn {\n background: transparent;\n border: none;\n width: 32px;\n height: 32px;\n border-radius: 6px;\n cursor: pointer;\n display: flex;\n align-items: center;\n justify-content: center;\n color: #666;\n }\n .chat-sdk-icon-btn:hover { background: rgba(0,0,0,0.06); }\n\n .chat-sdk-emoji-picker {\n position: absolute;\n left: 12px;\n bottom: 64px;\n background: #fff;\n border: 1px solid #e0e0e0;\n border-radius: 8px;\n box-shadow: 0 6px 16px rgba(0,0,0,0.12);\n padding: 6px;\n z-index: 5;\n }\n .chat-sdk-emoji-grid {\n display: grid;\n grid-template-columns: repeat(5, 28px);\n gap: 6px;\n }\n\n /* Failed message styles - Telegram style */\n .chat-sdk-message-failed-indicator {\n display: inline-flex;\n align-items: center;\n margin-left: 6px;\n color: #ff4444;\n cursor: pointer;\n }\n .chat-sdk-message-failed-indicator svg {\n width: 16px;\n height: 16px;\n }\n .chat-sdk-message.own .chat-sdk-message-content {\n display: flex;\n align-items: flex-end;\n gap: 6px;\n }\n .chat-sdk-message.own .chat-sdk-message-bubble {\n flex: 1;\n }\n .chat-sdk-emoji-item {\n background: none;\n border: none;\n font-size: 20px;\n line-height: 1;\n cursor: pointer;\n width: 28px;\n height: 28px;\n border-radius: 4px;\n }\n .chat-sdk-emoji-item:hover { background: #f3f4f6; }\n\n\n .chat-sdk-input {\n flex: 1;\n border: 1px solid #ddd;\n border-radius: var(--chat-border-radius-input);\n padding: 8px 16px;\n font-size: 14px;\n outline: none;\n resize: none;\n min-height: 36px;\n max-height: 100px;\n }\n\n .chat-sdk-input:focus {\n border-color: var(--chat-primary-color);\n }\n\n .chat-sdk-send-btn {\n background: var(--chat-primary-color);\n color: white;\n border: none;\n border-radius: 50%;\n width: 36px;\n height: 36px;\n cursor: pointer;\n display: flex;\n align-items: center;\n justify-content: center;\n transition: background-color 0.2s;\n }\n\n .chat-sdk-send-btn:hover {\n background: #064e45;\n }\n\n .chat-sdk-send-btn:disabled {\n background: #ccc;\n cursor: not-allowed;\n }\n\n .chat-sdk-overlay {\n position: absolute;\n top: 0;\n left: 0;\n right: 0;\n bottom: 0;\n background: rgba(0, 0, 0, 0.5);\n display: flex;\n align-items: center;\n justify-content: center;\n z-index: 10;\n }\n\n .chat-sdk-join-card {\n background: white;\n border-radius: 12px;\n padding: 24px;\n max-width: 300px;\n margin: 16px;\n text-align: center;\n }\n\n .chat-sdk-join-title {\n font-size: 18px;\n font-weight: 600;\n margin: 0 0 8px 0;\n color: #333;\n }\n\n .chat-sdk-join-description {\n font-size: 14px;\n color: #666;\n margin: 0 0 20px 0;\n line-height: 1.4;\n }\n\n .chat-sdk-join-btn {\n background: #075e54;\n color: white;\n border: none;\n border-radius: 8px;\n padding: 12px 24px;\n font-size: 14px;\n font-weight: 600;\n cursor: pointer;\n transition: background-color 0.2s;\n width: 100%;\n }\n\n .chat-sdk-join-btn:hover {\n background: #064e45;\n }\n\n .chat-sdk-loading {\n display: flex;\n align-items: center;\n justify-content: center;\n padding: 40px;\n color: #666;\n }\n\n .chat-sdk-spinner {\n width: 20px;\n height: 20px;\n border: 2px solid #e0e0e0;\n border-top: 2px solid #075e54;\n border-radius: 50%;\n animation: chat-sdk-spin 1s linear infinite;\n margin-right: 8px;\n }\n\n @keyframes chat-sdk-spin {\n 0% { transform: rotate(0deg); }\n 100% { transform: rotate(360deg); }\n }\n\n .chat-sdk-container.dark {\n background: #1f1f1f;\n color: #e0e0e0;\n }\n\n .chat-sdk-container.dark .chat-sdk-header {\n background: #2d2d2d;\n }\n\n .chat-sdk-container.dark .chat-sdk-messages {\n background: #0d1117;\n }\n\n .chat-sdk-container.dark .chat-sdk-message-bubble {\n background: #2d2d2d;\n color: #e0e0e0;\n }\n\n .chat-sdk-container.dark .chat-sdk-message.own .chat-sdk-message-bubble {\n background: #0969da;\n color: white;\n }\n\n /* Image Modal Viewer */\n .chat-sdk-image-modal {\n position: fixed;\n top: 0; left: 0; right: 0; bottom: 0;\n z-index: 9999;\n opacity: 0;\n visibility: hidden;\n transition: opacity 0.2s ease, visibility 0.2s ease;\n }\n\n .chat-sdk-image-modal-open {\n opacity: 1;\n visibility: visible;\n }\n\n .chat-sdk-image-backdrop {\n position: absolute;\n top: 0; left: 0; right: 0; bottom: 0;\n background: rgba(0, 0, 0, 0.9);\n display: flex;\n align-items: center;\n justify-content: center;\n padding: 20px;\n }\n\n .chat-sdk-image-container {\n position: relative;\n max-width: 90vw;\n max-height: 90vh;\n display: flex;\n align-items: center;\n justify-content: center;\n }\n\n .chat-sdk-image-close {\n position: absolute;\n top: -50px;\n right: 0;\n background: rgba(255, 255, 255, 0.1);\n border: none;\n border-radius: 50%;\n width: 40px;\n height: 40px;\n color: white;\n cursor: pointer;\n display: flex;\n align-items: center;\n justify-content: center;\n transition: background-color 0.2s;\n z-index: 1;\n }\n\n .chat-sdk-image-close:hover {\n background: rgba(255, 255, 255, 0.2);\n }\n\n .chat-sdk-image-full {\n max-width: 100%;\n max-height: 100%;\n object-fit: contain;\n border-radius: 8px;\n box-shadow: 0 10px 30px rgba(0, 0, 0, 0.5);\n }\n\n /* Responsive Design */\n @media (max-width: 640px) {\n .chat-sdk-container {\n border-radius: 0;\n height: 100vh;\n max-height: 100vh;\n }\n\n .chat-sdk-message-content {\n max-width: 85%;\n }\n\n .chat-sdk-message-bubble {\n font-size: 14px;\n padding: 8px 12px;\n }\n\n .chat-sdk-input {\n font-size: 16px; /* Prevent zoom on iOS */\n padding: 10px 14px;\n }\n\n .chat-sdk-header {\n padding: 8px 12px;\n min-height: 50px;\n }\n\n .chat-sdk-message-avatar {\n width: 28px;\n height: 28px;\n font-size: 11px;\n }\n }\n\n @media (min-width: 1024px) {\n .chat-sdk-message-content {\n max-width: 60%;\n }\n\n .chat-sdk-send-btn:hover:not(:disabled) {\n transform: scale(1.05);\n transition: all 0.2s ease;\n }\n }\n\n /* Image Zoom Overlay */\n .chat-sdk-image-zoom-overlay {\n position: absolute;\n top: 0; left: 0; right: 0; bottom: 0;\n background: rgba(0, 0, 0, 0.85);\n z-index: 999999;\n display: flex;\n justify-content: center;\n align-items: center;\n cursor: zoom-out;\n backdrop-filter: blur(2px);\n }\n .chat-sdk-image-zoom-img {\n max-width: 95%;\n max-height: 95%;\n object-fit: contain;\n border-radius: 4px;\n box-shadow: 0 4px 12px rgba(0,0,0,0.3);\n transform: scale(0.95);\n animation: chat-sdk-zoom-in 0.2s cubic-bezier(0.1, 0.9, 0.2, 1) forwards;\n }\n @keyframes chat-sdk-zoom-in {\n to { transform: scale(1); }\n }\n\n "}startSimulation(){this.simulator.start()}stopSimulation(){this.simulator.stop()}pauseSimulation(){this.simulator.pause()}resumeSimulation(){this.simulator.resume()}async sendMessage(e,t="text"){await this.simulator.sendMessage(e,t)}get isSimulationRunning(){return this.state.isSimulationRunning}get isSimulationPaused(){return this.state.isSimulationPaused}get simulationEnded(){return this.state.simulationEnded}get messageCount(){return this.state.displayedMessageCount}get messages(){return[...this.state.messages]}async reinitializeLanguage(e){this.config.language=e,this.setLoading(!0),this.messagesContainer.innerHTML="",this.state.messages=[],this.state.displayedMessageCount=0,this.state.unreadCount=0,this.updateUnreadBadge();try{this.simulator.clearCachedProgress()}catch(e){}try{this.simulator.destroy()}catch(e){}this.simulator=new g(this.config,this.apiClient),this.setupSimulatorEvents(),await this.initializeSimulation()}destroy(){this.pollingStopTimer&&(clearTimeout(this.pollingStopTimer),this.pollingStopTimer=null);try{this.simulator.destroy()}catch(e){}if(this.shadowRoot)try{for(;this.shadowRoot.firstChild;)this.shadowRoot.removeChild(this.shadowRoot.firstChild)}catch(e){}this.state.isOpen=!1,this.removeAllListeners()}clearMessages(){this.state.messages=[],this.state.displayedMessageCount=0,this.state.unreadCount=0,this.messagesContainer.innerHTML="",this.updateUnreadBadge()}rerender(){this.reRenderAllMessages()}getMessageCount(){return this.state.displayedMessageCount}isOpen(){return this.state.isOpen}updateLanguageElements(e){var t,s,n;this.t=y(e);const a=null===(t=this.widgetElement)||void 0===t?void 0:t.querySelector("#message-input");a&&(a.placeholder=this.t.inputPlaceholder);const i=null===(s=this.widgetElement)||void 0===s?void 0:s.querySelector(".send-button");i&&i.textContent&&(i.textContent=this.t.send);const o=this.getMessageCount(),r=(null===(n=this.state.currentProject)||void 0===n?void 0:n.name)||"Chat";this.setTitle(r,`${o} ${this.t.messages}`)}}const v=f;function k(e){return new f(e)}var w={init:k,ChatSDK:v,ChatSDKError:t};"undefined"!=typeof window&&(window.ChatSDK={init:k,ChatSDK:v,ChatSDKError:t}),e.ChatSDK=v,e.ChatSDKError=t,e.default=w,e.init=k,Object.defineProperty(e,"__esModule",{value:!0})});
|
|
1
|
+
!function(e,t){"object"==typeof exports&&"undefined"!=typeof module?t(exports):"function"==typeof define&&define.amd?define(["exports"],t):t((e="undefined"!=typeof globalThis?globalThis:e||self).ChatSDK={})}(this,function(e){"use strict";class t extends Error{constructor(e,t,s){super(e),this.code=t,this.details=s,this.name="ChatSDKError"}}class s{constructor(){this.events=new Map}on(e,t){this.events.has(e)||this.events.set(e,[]),this.events.get(e).push(t)}off(e,t){if(!this.events.has(e))return;if(!t)return void this.events.delete(e);const s=this.events.get(e),n=s.indexOf(t);n>-1&&s.splice(n,1),0===s.length&&this.events.delete(e)}emit(e,t){if(!this.events.has(e))return;this.events.get(e).forEach(s=>{try{s(t)}catch(t){console.error(`Error in event callback for "${e}":`,t)}})}getEventNames(){return Array.from(this.events.keys())}listenerCount(e){var t;return(null===(t=this.events.get(e))||void 0===t?void 0:t.length)||0}removeAllListeners(){this.events.clear()}}function n(e,t,s){const n=document.createElement(e);return t&&(n.className=t),n}function i(e){const t=document.createElement("div");return t.textContent=e,t.innerHTML}function a(e,t=!0){e.scrollTop=e.scrollHeight,e.scrollTo&&e.scrollTo({top:e.scrollHeight,behavior:t?"smooth":"auto"})}const o={USD:1,EUR:.92,GBP:.79,JPY:149.5,CNY:7.24,INR:83.12,BRL:4.97,RUB:92.5,KRW:1320,MXN:17.15,CAD:1.38,AUD:1.53,CHF:.88,SEK:10.85,NZD:1.67,SGD:1.34,HKD:7.82,NOK:10.95,TRY:28.5,ZAR:18.65,PLN:4.05,THB:35.2,IDR:15650,MYR:4.68,PHP:56.2,DKK:6.88,CZK:22.85,HUF:355,ILS:3.72,CLP:920,ARS:350,COP:4050,PEN:3.75,EGP:30.9,SAR:3.75,AED:3.67,VND:24500,PKR:278,BDT:110,NGN:775,UAH:36.5,RON:4.58,TWD:31.5,QAR:3.64,KWD:.31,OMR:.38,BHD:.38},r={USD:"$",EUR:"€",GBP:"£",JPY:"¥",CNY:"¥",INR:"₹",BRL:"R$",RUB:"₽",KRW:"₩",MXN:"$",CAD:"C$",AUD:"A$",CHF:"CHF",SEK:"kr",NZD:"NZ$",SGD:"S$",HKD:"HK$",NOK:"kr",TRY:"₺",ZAR:"R",PLN:"zł",THB:"฿",IDR:"Rp",MYR:"RM",PHP:"₱",DKK:"kr",CZK:"Kč",HUF:"Ft",ILS:"₪",CLP:"$",ARS:"$",COP:"$",PEN:"S/",EGP:"E£",SAR:"﷼",AED:"د.إ",VND:"₫",PKR:"₨",BDT:"৳",NGN:"₦",UAH:"₴",RON:"lei",TWD:"NT$",QAR:"﷼",KWD:"د.ك",OMR:"﷼",BHD:"د.ب"},d={USD:",",EUR:".",GBP:",",JPY:",",CNY:",",INR:",",BRL:".",RUB:" ",KRW:",",MXN:",",CAD:",",AUD:",",CHF:"'",SEK:" ",PLN:" ",THB:",",IDR:".",MYR:",",PHP:",",DKK:".",CZK:" ",HUF:" "},l={USD:".",EUR:",",GBP:".",JPY:".",CNY:".",INR:".",BRL:",",RUB:",",KRW:".",MXN:".",CAD:".",AUD:".",CHF:".",SEK:",",PLN:",",THB:".",IDR:",",MYR:".",PHP:".",DKK:",",CZK:",",HUF:","},h={US:"USD",CA:"CAD",MX:"MXN",BR:"BRL",AR:"ARS",CL:"CLP",CO:"COP",PE:"PEN",GB:"GBP",DE:"EUR",FR:"EUR",IT:"EUR",ES:"EUR",NL:"EUR",BE:"EUR",AT:"EUR",PT:"EUR",IE:"EUR",GR:"EUR",FI:"EUR",CH:"CHF",NO:"NOK",SE:"SEK",DK:"DKK",PL:"PLN",CZ:"CZK",HU:"HUF",RO:"RON",RU:"RUB",UA:"UAH",TR:"TRY",IL:"ILS",SA:"SAR",AE:"AED",EG:"EGP",CN:"CNY",JP:"JPY",KR:"KRW",IN:"INR",ID:"IDR",TH:"THB",VN:"VND",MY:"MYR",SG:"SGD",PH:"PHP",PK:"PKR",BD:"BDT",HK:"HKD",TW:"TWD",AU:"AUD",NZ:"NZD",ZA:"ZAR",NG:"NGN",KE:"KES",QA:"QAR",KW:"KWD",OM:"OMR",BH:"BHD"},c=new Set(["JPY","KRW","IDR","VND","CLP","PYG","UGX"]);function m(e,t){if(!e||!t)return e;const s=function(e){return h[e.toUpperCase()]||"USD"}(t);return e.replace(/\{\{AMOUNT:(\d+(?:\.\d+)?)\}\}/g,(e,t)=>{const n=parseFloat(t);return isNaN(n)?e:function(e,t){var s,n,i,a;const h=null!==(s=o[t])&&void 0!==s?s:1,m=null!==(n=r[t])&&void 0!==n?n:t+" ",u=null!==(i=d[t])&&void 0!==i?i:",",g=null!==(a=l[t])&&void 0!==a?a:".",p=c.has(t),y=e*h,b=p?Math.round(y):Math.round(100*y)/100,f=Math.floor(b).toString().replace(/\B(?=(\d{3})+(?!\d))/g,u);return p?`${m}${f}`:`${m}${f}${g}${(b%1).toFixed(2).slice(2)}`}(n,s)})}class u extends s{constructor(e,t){super(),this.simulationData=null,this.displayedMessages=[],this.currentMessageIndex=0,this.isRunning=!1,this.isPaused=!1,this.intervalId=null,this.pollingId=null,this.burstPhase=!0,this.totalToShow=1/0,this.virtualLastTimestamp=null,this.realLastTimestamp=null,this.lastTimestamp=null,this.lastDelayMs=0,this.userId="",this.config=e,this.apiClient=t,this.pollingIntervalMs="number"==typeof e.pollingInterval&&e.pollingInterval>0?e.pollingInterval:6e3}async initialize(){try{const e=this.config.language||"en",t=(this.config.country||"US").toUpperCase(),s=this.getPersistedUserId(),n=s||this.config.userId||this.generateUserId();this.userId=n,s||this.persistUserId(n);const i=await this.apiClient.getSimulationData(this.config.projectId,n,e,t);if(!i.success||!i.data)throw new Error("Failed to load simulation data");this.simulationData=i.data;const a=this.simulationData.project.initialBurstCount+this.simulationData.project.continuousCount;this.totalToShow=Math.min(a,this.simulationData.messages.length);const o=this.loadProgress();o&&"number"==typeof o.index?(this.currentMessageIndex=o.index,o.lastTimestamp&&(this.virtualLastTimestamp=new Date(o.lastTimestamp),this.lastTimestamp=new Date(o.lastTimestamp))):(this.currentMessageIndex=0,this.virtualLastTimestamp=null,this.lastTimestamp=null),this.realLastTimestamp=null,await this.loadExistingMessages(),await this.reconstructVirtualHistoryForDisplay(),this.emit("initialized",this.simulationData),this.startPolling(),!1!==this.config.autoStart&&this.start()}catch(e){throw this.emit("error",e),e}}start(){this.simulationData&&!this.isRunning&&(this.isRunning=!0,this.isPaused=!1,this.burstPhase=!0,this.emit("simulationStart"),this.performInitialBurst(),this.currentMessageIndex<this.totalToShow?(this.burstPhase=!1,this.scheduleNextMessage()):(this.isRunning=!1,this.emit("simulationEnd")))}performInitialBurst(){if(!this.simulationData)return;const{project:e,messages:t}=this.simulationData,s=e.initialBurstCount,n=Math.min(s,this.totalToShow,t.length);if(this.currentMessageIndex>=n)return;if(this.displayedMessages.some(e=>e.id.startsWith("sim-"))&&this.currentMessageIndex>0)return;const i=new Date,a=new Array(n);let o=new Date(i);for(let e=n-1;e>=0;e--)if(a[e]=new Date(o),e>0){const e=10+Math.floor(11*Math.random());o=new Date(o.getTime()-60*e*1e3)}const r=[],d=(this.config.country||"US").toUpperCase();let l=!1;for(let e=this.currentMessageIndex;e<n;e++){const s=t[e],n=m(s.content,d);if(s.hasScreenshot&&s.screenshotUrl){const t={id:`sim-${e}-text-${Date.now()}`,content:n,messageType:"text",timestamp:a[e],isOwnMessage:!1,virtualUser:s.virtualUser};this.displayedMessages.push(t),r.push(t);const i=new Date(a[e].getTime()+2e3),o={id:`sim-${e}-image-${Date.now()}`,content:this.resolveImageUrl(s.screenshotUrl),messageType:"image",timestamp:i,isOwnMessage:!1,virtualUser:s.virtualUser};this.displayedMessages.push(o),r.push(o)}else if("audio"===s.messageType){const t={id:`sim-${e}-audio-${Date.now()}`,content:"",messageType:"audio",audioUrl:this.resolveImageUrl(s.audioUrl||""),timestamp:a[e],isOwnMessage:!1,virtualUser:s.virtualUser};this.displayedMessages.push(t),r.push(t)}else{const t={id:`sim-${e}-${Date.now()}`,content:n,messageType:s.messageType,timestamp:a[e],isOwnMessage:!1,virtualUser:s.virtualUser};this.displayedMessages.push(t),r.push(t)}this.currentMessageIndex=e+1,l=!0}l&&(this.lastTimestamp=a[n-1],this.virtualLastTimestamp=this.lastTimestamp,this.displayedMessages.sort((e,t)=>e.timestamp.getTime()-t.timestamp.getTime()),this.emit("messages-batch",r)),this.saveProgress()}pause(){this.isRunning&&(this.isPaused=!0,this.intervalId&&(clearTimeout(this.intervalId),this.intervalId=null),this.emit("simulationPause"))}resume(){this.isRunning&&this.isPaused&&(this.isPaused=!1,this.scheduleNextMessage(),this.emit("simulationResume"))}stop(){this.isRunning=!1,this.isPaused=!1,this.intervalId&&(clearTimeout(this.intervalId),this.intervalId=null),this.emit("simulationStop")}destroy(){this.stop(),this.stopPolling(),this.removeAllListeners()}scheduleNextMessage(){if(!this.simulationData||!this.isRunning||this.isPaused)return;const{project:e,messages:t}=this.simulationData;if(this.currentMessageIndex>=this.totalToShow)return this.isRunning=!1,void this.emit("simulationEnd");let s;if(this.burstPhase){const n=Math.min(e.initialBurstCount,t.length);this.currentMessageIndex<n?s=500+1e3*Math.random():(this.burstPhase=!1,s=this.getRandomInterval(e.messageIntervalMin,e.messageIntervalMax))}else{const n=Math.min(e.initialBurstCount,t.length);s=this.currentMessageIndex-n<5?1e3*(e.initialMessageInterval||10):this.getRandomInterval(e.messageIntervalMin,e.messageIntervalMax)}this.lastDelayMs=s,this.intervalId=setTimeout(()=>{this.displayNextMessage(),this.scheduleNextMessage()},s)}displayNextMessage(){if(!this.simulationData||this.currentMessageIndex>=this.simulationData.messages.length)return;const e=this.simulationData.messages[this.currentMessageIndex],t=(this.config.country||"US").toUpperCase(),s=m(e.content,t),n=this.lastTimestamp||new Date,i=new Date(n.getTime()+(this.lastDelayMs||0));if(this.lastTimestamp=i,e.hasScreenshot&&e.screenshotUrl){const t={id:`sim-${this.currentMessageIndex}-text-${Date.now()}`,content:s,messageType:"text",timestamp:i,isOwnMessage:!1,virtualUser:e.virtualUser};this.displayedMessages.push(t),this.emit("message",t);const n=new Date(i.getTime()+2e3),a={id:`sim-${this.currentMessageIndex}-image-${Date.now()}`,content:this.resolveImageUrl(e.screenshotUrl),messageType:"image",timestamp:n,isOwnMessage:!1,virtualUser:e.virtualUser};this.displayedMessages.push(a),this.lastTimestamp=n,setTimeout(()=>{this.emit("message",a)},2e3)}else if("audio"===e.messageType){const t={id:`sim-${this.currentMessageIndex}-audio-${Date.now()}`,content:"",messageType:"audio",audioUrl:this.resolveImageUrl(e.audioUrl||""),timestamp:i,isOwnMessage:!1,virtualUser:e.virtualUser};this.displayedMessages.push(t),this.emit("message",t)}else{const t={id:`sim-${this.currentMessageIndex}-${Date.now()}`,content:s,messageType:e.messageType,timestamp:i,isOwnMessage:!1,virtualUser:e.virtualUser};this.displayedMessages.push(t),this.emit("message",t)}this.currentMessageIndex++,this.saveProgress()}async loadExistingMessages(){if(this.simulationData)try{const e=this.userId||this.config.userId||this.generateUserId(),t=await this.apiClient.getSimulationMessages(this.config.projectId,e,void 0,100);if(t.success&&t.messages&&t.messages.length>0){const s=t.messages.sort((e,t)=>new Date(e.createdAt||e.timestamp).getTime()-new Date(t.createdAt||t.timestamp).getTime()),n=new Set(this.displayedMessages.map(e=>e.id));for(const t of s){if(n.has(t.id))continue;const s=(this.config.country||"US").toUpperCase(),i={id:t.id,content:m(t.content||"",s),messageType:t.messageType,timestamp:new Date(t.createdAt||t.timestamp),isOwnMessage:t.userId===e,virtualUser:t.virtualUser,user:t.userId===e?{id:e,username:this.config.username||"You"}:void 0};this.displayedMessages.push(i)}if(s.length>0){const e=s[s.length-1];this.realLastTimestamp=new Date(e.createdAt||e.timestamp)}this.displayedMessages.length>0&&this.emit("messages-batch",[...this.displayedMessages])}}catch(e){console.warn("Failed to load existing messages:",e)}}startPolling(){this.pollingId&&(clearInterval(this.pollingId),this.pollingId=null),this.pollingId=setInterval(async()=>{await this.pollForNewMessages()},this.pollingIntervalMs)}stopPolling(){this.pollingId&&(clearInterval(this.pollingId),this.pollingId=null)}setPollingInterval(e){!e||e<=0||(this.pollingIntervalMs=e,this.pollingId&&this.startPolling())}get isPolling(){return!!this.pollingId}async pollForNewMessages(){if(this.simulationData)try{const e=this.userId||this.config.userId||this.generateUserId(),t=this.getLastMessageTimestamp(),s=await this.apiClient.getSimulationMessages(this.config.projectId,e,t);if(s.success&&s.messages&&s.messages.length>0){const t=new Set(this.displayedMessages.map(e=>e.id));let n=null;for(const i of s.messages){if(t.has(i.id))continue;const s=new Date(i.createdAt),a=(this.config.country||"US").toUpperCase(),o={id:i.id,content:m(i.content||"",a),messageType:i.messageType,timestamp:s,isOwnMessage:i.userId===e,virtualUser:i.virtualUser,user:i.userId===e?{id:e,username:this.config.username||"You"}:void 0};(!n||s>n)&&(n=s),this.displayedMessages.push(o),this.emit("message",o)}n&&(this.realLastTimestamp=n)}}catch(e){console.warn("Polling error:",e)}}async reconstructVirtualHistoryForDisplay(){if(!this.simulationData)return;const e=Math.min(this.currentMessageIndex,this.totalToShow,this.simulationData.messages.length);if(e<=0)return;const t=this.loadProgress(),s=(null==t?void 0:t.virtualMessages)||[];if(s.length>0){const e=[],t=new Set(this.displayedMessages.map(e=>e.id)),n=(this.config.country||"US").toUpperCase();for(const i of s)if(!t.has(i.id)){if("image"===i.messageType){const e=i.content||"";if(!e.startsWith("http")&&!e.startsWith("/uploads")&&!e.startsWith("/api"))continue}const t={id:i.id,content:"image"===i.messageType?this.resolveImageUrl(m(i.content||"",n)):"audio"===i.messageType?"":m(i.content||"",n),messageType:i.messageType,audioUrl:"audio"===i.messageType?this.resolveImageUrl(i.audioUrl||i.content||""):void 0,timestamp:new Date(i.timestamp),isOwnMessage:!1,virtualUser:i.virtualUser};e.push(t)}if(e.length>0){this.displayedMessages.push(...e),this.displayedMessages.sort((e,t)=>e.timestamp.getTime()-t.timestamp.getTime());const t=e[e.length-1];this.virtualLastTimestamp=t.timestamp,this.lastTimestamp=t.timestamp,this.emit("messages-batch",e)}return}const n=new Date,i=new Array(e);let a=new Date(n);for(let t=e-1;t>=0;t--)if(i[t]=new Date(a),t>0){const e=10+Math.floor(11*Math.random());a=new Date(a.getTime()-60*e*1e3)}const o=[],{messages:r}=this.simulationData,d=(this.config.country||"US").toUpperCase();for(let t=0;t<e;t++){const e=r[t],s=i[t],n=m(e.content,d);if(e.hasScreenshot&&e.screenshotUrl){const i={id:`sim-${t}-text`,content:n,messageType:"text",timestamp:s,isOwnMessage:!1,virtualUser:e.virtualUser},a={id:`sim-${t}-image`,content:this.resolveImageUrl(e.screenshotUrl),messageType:"image",timestamp:new Date(s.getTime()+2e3),isOwnMessage:!1,virtualUser:e.virtualUser};o.push(i,a)}else{const i={id:`sim-${t}`,content:n,messageType:e.messageType,timestamp:s,isOwnMessage:!1,virtualUser:e.virtualUser};o.push(i)}}const l=new Set(this.displayedMessages.map(e=>e.id)),h=o.filter(e=>!l.has(e.id));if(0===h.length)return;this.displayedMessages.push(...h),this.displayedMessages.sort((e,t)=>e.timestamp.getTime()-t.timestamp.getTime());const c=h[h.length-1];this.virtualLastTimestamp=c.timestamp,this.lastTimestamp=c.timestamp,this.emit("messages-batch",h)}getLastMessageTimestamp(){if(this.realLastTimestamp)return this.realLastTimestamp.toISOString()}getUserKey(){return`vcs:user:${this.config.projectId}`}getProgressKey(){const e=this.userId||this.config.userId||"anon";return`vcs:progress:${this.config.projectId}:${e}`}getPersistedUserId(){try{return"undefined"==typeof window?null:window.localStorage.getItem(this.getUserKey())}catch(e){return null}}persistUserId(e){try{if("undefined"==typeof window)return;window.localStorage.setItem(this.getUserKey(),e)}catch(e){}}loadProgress(){try{if("undefined"==typeof window)return null;const e=window.localStorage.getItem(this.getProgressKey());return e?JSON.parse(e):null}catch(e){return null}}saveProgress(){try{if("undefined"==typeof window)return;const e=this.displayedMessages.filter(e=>e.id.startsWith("sim-")).map(e=>({id:e.id,content:e.content,messageType:e.messageType,timestamp:e.timestamp.toISOString(),virtualUser:e.virtualUser})),t={index:this.currentMessageIndex,lastTimestamp:this.lastTimestamp?this.lastTimestamp.toISOString():void 0,virtualMessages:e};window.localStorage.setItem(this.getProgressKey(),JSON.stringify(t))}catch(e){}}clearProgress(){try{if("undefined"==typeof window)return;window.localStorage.removeItem(this.getProgressKey())}catch(e){}}clearCachedProgress(){this.clearProgress()}resolveImageUrl(e){if(!e)return"";if(e.startsWith("http://")||e.startsWith("https://"))return e;const t=(this.config.apiBaseUrl||"").replace(/\/$/,"");return t?`${t}${e}`:e}getRandomInterval(e,t){return 1e3*(e+Math.random()*(t-e))}generateUserId(){return`user-${Date.now()}-${Math.random().toString(36).substring(2,11)}`}get messages(){return[...this.displayedMessages]}get isSimulationRunning(){return this.isRunning}get isSimulationPaused(){return this.isPaused}get data(){return this.simulationData}async sendMessage(e,t="text"){if(!this.simulationData)throw new Error("Simulation not initialized");const s=this.userId||this.config.userId||this.generateUserId(),n=this.config.username||"User";try{if("image"===t||"string"==typeof e&&e.startsWith("data:image/"))return;await Promise.all([this.apiClient.sendUserMessage(this.config.projectId,s,n,e,t),this.apiClient.triggerAIReply(this.config.projectId,s,n,e,t)])}catch(e){throw this.emit("error",e),e}}}class g{constructor(e){this.baseUrl=e.apiBaseUrl||window.location.origin,this.token=e.token}async request(e,s={}){const n=`${this.baseUrl}${e}`,i={"Content-Type":"application/json",...s.headers};this.token&&(i.Authorization=`Bearer ${this.token}`);try{const e=await fetch(n,{...s,headers:i,credentials:"include"});if(!e.ok)throw new t(`API request failed: ${e.status} ${e.statusText}`,"API_ERROR",{status:e.status,statusText:e.statusText});const a=await e.json();if(!a.success&&a.error)throw new t(a.error,"API_ERROR",a);return a}catch(e){if(e instanceof t)throw e;throw new t(`Network error: ${e.message}`,"NETWORK_ERROR",e)}}async getProject(e){return this.request(`/api/projects/${e}`)}async getTemplate(e,t,s){const n=new URLSearchParams;t&&n.set("lang",t),s&&n.set("country",s);const i=n.toString()?`?${n.toString()}`:"";return this.request(`/api/templates/${e}${i}`)}async getProjectTemplates(e){return this.request(`/api/projects/${e}/templates`)}async sendMessage(e,t,s,n="text"){return this.request("/api/chat/message",{method:"POST",body:JSON.stringify({projectId:e,userId:t,content:s,messageType:n})})}async joinProject(e,t,s){return this.request("/api/chat/join",{method:"POST",body:JSON.stringify({projectId:e,userId:t,username:s})})}async leaveProject(e,t){return this.request("/api/chat/leave",{method:"POST",body:JSON.stringify({projectId:e,userId:t})})}async getSimulationData(e,t,s,n){const i=new URLSearchParams({userId:t});return s&&i.append("lang",s),n&&i.append("country",n),this.request(`/api/chat/simulation/${e}?${i.toString()}`)}async getSimulationMessages(e,t,s,n){const i=new URLSearchParams({userId:t});return s&&i.append("since",s),n&&i.append("limit",n.toString()),this.request(`/api/chat/simulation/${e}/messages?${i.toString()}`)}async sendUserMessage(e,t,s,n,i="text"){return this.request("/api/chat/send",{method:"POST",body:JSON.stringify({projectId:e,userId:t,username:s,content:n,messageType:i})})}async triggerAIReply(e,t,s,n,i="text"){return this.request("/api/chat/ai-reply",{method:"POST",body:JSON.stringify({projectId:e,userId:t,username:s,content:n,messageType:i})})}setToken(e){this.token=e}setBaseUrl(e){this.baseUrl=e}}const p={en:{joinChat:"Join Chat",chatGroup:"{name} Group",online:"{count} online",inputPlaceholder:"Type a message...",send:"Send",messages:"messages",today:"Today",yesterday:"Yesterday",networkError:"Network error",sendFailed:"Failed to send"},zh:{joinChat:"加入群聊",chatGroup:"{name}交流群",online:"{count} 人在线",inputPlaceholder:"输入消息...",send:"发送",messages:"条消息",today:"今天",yesterday:"昨天",networkError:"网络错误",sendFailed:"发送失败"},"zh-TW":{joinChat:"加入群聊",chatGroup:"{name}交流群",online:"{count} 人在線",inputPlaceholder:"輸入訊息...",send:"發送",messages:"條訊息",today:"今天",yesterday:"昨天",networkError:"網路錯誤",sendFailed:"發送失敗"},es:{joinChat:"Unirse al Chat",chatGroup:"Grupo {name}",online:"{count} en línea",inputPlaceholder:"Escribe un mensaje...",send:"Enviar",messages:"mensajes",today:"Hoy",yesterday:"Ayer",networkError:"Error de red",sendFailed:"Error al enviar"},hi:{joinChat:"चैट में शामिल हों",chatGroup:"{name} समूह",online:"{count} ऑनलाइन",inputPlaceholder:"संदेश लिखें...",send:"भेजें",messages:"संदेश",today:"आज",yesterday:"कल",networkError:"नेटवर्क त्रुटि",sendFailed:"भेजने में विफल"},ar:{joinChat:"انضم للدردشة",chatGroup:"مجموعة {name}",online:"{count} متصل",inputPlaceholder:"اكتب رسالة...",send:"إرسال",messages:"رسائل",today:"اليوم",yesterday:"أمس",networkError:"خطأ في الشبكة",sendFailed:"فشل الإرسال"},pt:{joinChat:"Entrar no Chat",chatGroup:"Grupo {name}",online:"{count} online",inputPlaceholder:"Digite uma mensagem...",send:"Enviar",messages:"mensagens",today:"Hoje",yesterday:"Ontem",networkError:"Erro de rede",sendFailed:"Falha ao enviar"},bn:{joinChat:"চ্যাটে যোগ দিন",chatGroup:"{name} গ্রুপ",online:"{count} অনলাইন",inputPlaceholder:"একটি বার্তা লিখুন...",send:"পাঠান",messages:"বার্তা",today:"আজ",yesterday:"গতকাল",networkError:"নেটওয়ার্ক ত্রুটি",sendFailed:"পাঠাতে ব্যর্থ"},ru:{joinChat:"Присоединиться",chatGroup:"Группа {name}",online:"{count} онлайн",inputPlaceholder:"Введите сообщение...",send:"Отправить",messages:"сообщений",today:"Сегодня",yesterday:"Вчера",networkError:"Ошибка сети",sendFailed:"Не удалось отправить"},ja:{joinChat:"チャットに参加",chatGroup:"{name}グループ",online:"{count} オンライン",inputPlaceholder:"メッセージを入力...",send:"送信",messages:"メッセージ",today:"今日",yesterday:"昨日",networkError:"ネットワークエラー",sendFailed:"送信失敗"},de:{joinChat:"Chat beitreten",chatGroup:"{name} Gruppe",online:"{count} online",inputPlaceholder:"Nachricht eingeben...",send:"Senden",messages:"Nachrichten",today:"Heute",yesterday:"Gestern",networkError:"Netzwerkfehler",sendFailed:"Senden fehlgeschlagen"},fr:{joinChat:"Rejoindre le Chat",chatGroup:"Groupe {name}",online:"{count} en ligne",inputPlaceholder:"Tapez un message...",send:"Envoyer",messages:"messages",today:"Aujourd'hui",yesterday:"Hier",networkError:"Erreur réseau",sendFailed:"Échec de l'envoi"},ko:{joinChat:"채팅 참여",chatGroup:"{name} 그룹",online:"{count} 온라인",inputPlaceholder:"메시지 입력...",send:"전송",messages:"메시지",today:"오늘",yesterday:"어제",networkError:"네트워크 오류",sendFailed:"전송 실패"},it:{joinChat:"Unisciti alla Chat",chatGroup:"Gruppo {name}",online:"{count} online",inputPlaceholder:"Scrivi un messaggio...",send:"Invia",messages:"messaggi",today:"Oggi",yesterday:"Ieri",networkError:"Errore di rete",sendFailed:"Invio fallito"},tr:{joinChat:"Sohbete Katıl",chatGroup:"{name} Grubu",online:"{count} çevrimiçi",inputPlaceholder:"Bir mesaj yazın...",send:"Gönder",messages:"mesaj",today:"Bugün",yesterday:"Dün",networkError:"Ağ hatası",sendFailed:"Gönderilemedi"},vi:{joinChat:"Tham gia Chat",chatGroup:"Nhóm {name}",online:"{count} trực tuyến",inputPlaceholder:"Nhập tin nhắn...",send:"Gửi",messages:"tin nhắn",today:"Hôm nay",yesterday:"Hôm qua",networkError:"Lỗi mạng",sendFailed:"Gửi thất bại"},pl:{joinChat:"Dołącz do Czatu",chatGroup:"Grupa {name}",online:"{count} online",inputPlaceholder:"Wpisz wiadomość...",send:"Wyślij",messages:"wiadomości",today:"Dziś",yesterday:"Wczoraj",networkError:"Błąd sieci",sendFailed:"Nie udało się wysłać"},th:{joinChat:"เข้าร่วมแชท",chatGroup:"กลุ่ม {name}",online:"{count} ออนไลน์",inputPlaceholder:"พิมพ์ข้อความ...",send:"ส่ง",messages:"ข้อความ",today:"วันนี้",yesterday:"เมื่อวาน",networkError:"ข้อผิดพลาดเครือข่าย",sendFailed:"ส่งไม่สำเร็จ"},nl:{joinChat:"Deelnemen aan Chat",chatGroup:"{name} Groep",online:"{count} online",inputPlaceholder:"Typ een bericht...",send:"Verzenden",messages:"berichten",today:"Vandaag",yesterday:"Gisteren",networkError:"Netwerkfout",sendFailed:"Verzenden mislukt"},id:{joinChat:"Gabung Chat",chatGroup:"Grup {name}",online:"{count} online",inputPlaceholder:"Ketik pesan...",send:"Kirim",messages:"pesan",today:"Hari ini",yesterday:"Kemarin",networkError:"Kesalahan jaringan",sendFailed:"Gagal mengirim"},ms:{joinChat:"Sertai Chat",chatGroup:"Kumpulan {name}",online:"{count} dalam talian",inputPlaceholder:"Taip mesej...",send:"Hantar",messages:"mesej",today:"Hari ini",yesterday:"Semalam",networkError:"Ralat rangkaian",sendFailed:"Gagal menghantar"},ur:{joinChat:"چیٹ میں شامل ہوں",chatGroup:"{name} گروپ",online:"{count} آن لائن",inputPlaceholder:"پیغام ٹائپ کریں...",send:"بھیجیں",messages:"پیغامات",today:"آج",yesterday:"کل",networkError:"نیٹ ورک کی خرابی",sendFailed:"بھیجنے میں ناکام"},te:{joinChat:"చాట్లో చేరండి",chatGroup:"{name} సమూహం",online:"{count} ఆన్లైన్",inputPlaceholder:"సందేశాన్ని టైప్ చేయండి...",send:"పంపండి",messages:"సందేశాలు",today:"నేడు",yesterday:"నిన్న",networkError:"నెట్వర్క్ లోపం",sendFailed:"పంపడం విఫలమైంది"},mr:{joinChat:"चॅटमध्ये सामील व्हा",chatGroup:"{name} गट",online:"{count} ऑनलाइन",inputPlaceholder:"संदेश टाइप करा...",send:"पाठवा",messages:"संदेश",today:"आज",yesterday:"काल",networkError:"नेटवर्क त्रुटी",sendFailed:"पाठविण्यात अयशस्वी"},ta:{joinChat:"அரட்டையில் சேரவும்",chatGroup:"{name} குழு",online:"{count} ஆன்லைன்",inputPlaceholder:"ஒரு செய்தியை தட்டச்சு செய்யவும்...",send:"அனுப்பு",messages:"செய்திகள்",today:"இன்று",yesterday:"நேற்று",networkError:"நெட்வொர்க் பிழை",sendFailed:"அனுப்ப முடியவில்லை"},fa:{joinChat:"پیوستن به چت",chatGroup:"گروه {name}",online:"{count} آنلاین",inputPlaceholder:"پیامی تایپ کنید...",send:"ارسال",messages:"پیامها",today:"امروز",yesterday:"دیروز",networkError:"خطای شبکه",sendFailed:"ارسال نشد"},uk:{joinChat:"Приєднатися до чату",chatGroup:"Група {name}",online:"{count} онлайн",inputPlaceholder:"Введіть повідомлення...",send:"Надіслати",messages:"повідомлень",today:"Сьогодні",yesterday:"Вчора",networkError:"Помилка мережі",sendFailed:"Не вдалося надіслати"},gu:{joinChat:"ચેટમાં જોડાઓ",chatGroup:"{name} જૂથ",online:"{count} ઓનલાઇન",inputPlaceholder:"સંદેશ લખો...",send:"મોકલો",messages:"સંદેશાઓ",today:"આજે",yesterday:"ગઈકાલે",networkError:"નેટવર્ક ભૂલ",sendFailed:"મોકલવામાં નિષ્ફળ"},ro:{joinChat:"Alătură-te chatului",chatGroup:"Grupul {name}",online:"{count} online",inputPlaceholder:"Scrie un mesaj...",send:"Trimite",messages:"mesaje",today:"Astăzi",yesterday:"Ieri",networkError:"Eroare de rețea",sendFailed:"Trimitere eșuată"},sv:{joinChat:"Gå med i chatt",chatGroup:"{name} grupp",online:"{count} online",inputPlaceholder:"Skriv ett meddelande...",send:"Skicka",messages:"meddelanden",today:"Idag",yesterday:"Igår",networkError:"Nätverksfel",sendFailed:"Det gick inte att skicka"},hu:{joinChat:"Csatlakozás a chathez",chatGroup:"{name} Csoport",online:"{count} online",inputPlaceholder:"Írjon egy üzenetet...",send:"Küldés",messages:"üzenet",today:"Ma",yesterday:"Tegnap",networkError:"Hálózati hiba",sendFailed:"Küldés sikertelen"},cs:{joinChat:"Připojit se k chatu",chatGroup:"Skupina {name}",online:"{count} online",inputPlaceholder:"Napište zprávu...",send:"Odeslat",messages:"zpráv",today:"Dnes",yesterday:"Včera",networkError:"Chyba sítě",sendFailed:"Odeslání selhalo"},el:{joinChat:"Εγγραφή στο Chat",chatGroup:"Ομάδα {name}",online:"{count} online",inputPlaceholder:"Πληκτρολογήστε ένα μήνυμα...",send:"Αποστολή",messages:"μηνύματα",today:"Σήμερα",yesterday:"Χθες",networkError:"Σφάλμα δικτύου",sendFailed:"Αποτυχία αποστολής"},da:{joinChat:"Deltag i chat",chatGroup:"{name} Gruppe",online:"{count} online",inputPlaceholder:"Skriv en besked...",send:"Send",messages:"beskeder",today:"I dag",yesterday:"I går",networkError:"Netværksfejl",sendFailed:"Kunne ikke sende"},fi:{joinChat:"Liity chattiin",chatGroup:"{name} Ryhmä",online:"{count} paikalla",inputPlaceholder:"Kirjoita viesti...",send:"Lähetä",messages:"viestiä",today:"Tänään",yesterday:"Eilen",networkError:"Verkkovirhe",sendFailed:"Lähetys epäonnistui"},no:{joinChat:"Bli med i chat",chatGroup:"{name} Gruppe",online:"{count} pålogget",inputPlaceholder:"Skriv en melding...",send:"Send",messages:"meldinger",today:"I dag",yesterday:"I går",networkError:"Nettverksfeil",sendFailed:"Sending mislyktes"},he:{joinChat:"הצטרף לצ'אט",chatGroup:"קבוצת {name}",online:"{count} מחוברים",inputPlaceholder:"הקלד הודעה...",send:"שלח",messages:"הודעות",today:"היום",yesterday:"אתמול",networkError:"שגיאת רשת",sendFailed:"השליחה נכשלה"},tl:{joinChat:"Sumali sa Chat",chatGroup:"Grupong {name}",online:"{count} online",inputPlaceholder:"Mag-type ng mensahe...",send:"Ipadala",messages:"mga mensahe",today:"Ngayon",yesterday:"Kahapon",networkError:"Error sa network",sendFailed:"Nabigong ipadala"},sw:{joinChat:"Jiunge na Gumzo",chatGroup:"Kundi la {name}",online:"{count} mtandaoni",inputPlaceholder:"Andika ujumbe...",send:"Tuma",messages:"jumbe",today:"Leo",yesterday:"Jana",networkError:"Tatizo la mtandao",sendFailed:"Imeshindwa kutuma"},"pt-BR":{joinChat:"Entrar no Chat",chatGroup:"Grupo {name}",online:"{count} online",inputPlaceholder:"Escreva uma mensagem...",send:"Enviar",messages:"mensagens",today:"Hoje",yesterday:"Ontem",networkError:"Erro de rede",sendFailed:"Falha ao enviar"}};function y(e){if(p[e])return p[e];const t=e.split("-")[0];return p[t]?p[t]:p.en}function b(e,t){return e.replace(/\{(\w+)\}/g,(e,s)=>void 0!==t[s]?String(t[s]):e)}class f extends s{constructor(e){var t,s;super(),this.emojiPanelOpen=!1,this.onlineCount=0,this.currentTheme="whatsapp",this.isDarkMode=!1,this.customColors={},this.visibleStartIndex=0,this.hasInitializedData=!1,this.pollingStopTimer=null,this.currentAudio=null,this.currentVoiceContainer=null,this.config={...e,mode:e.mode||"floating"},this.t=y(e.language||"en"),this.currentTheme="telegram"===e.uiTemplate?"telegram":"whatsapp",this.isDarkMode="dark"===e.theme,this.customColors={primary:e.primaryColor,background:e.backgroundColor},this.onlineCount=500+Math.floor(301*Math.random()),this.initialRenderCount=null!==(t=this.config.initialRenderCount)&&void 0!==t?t:Number.MAX_SAFE_INTEGER,this.lazyLoadBatchSize=null!==(s=this.config.lazyLoadBatchSize)&&void 0!==s?s:20,this.state={isInitialized:!1,isOpen:!1,isJoined:!1,isConnected:!1,isSimulationRunning:!1,isSimulationPaused:!1,messages:[],virtualUsers:[],realUsers:[],typingUsers:[],simulationEnded:!1,displayedMessageCount:0,unreadCount:0,lastReadMessageId:null},this.apiClient=new g(e),this.simulator=new u(e,this.apiClient),this.setupSimulatorEvents(),this.init()}init(){try{this.setupContainer(),this.createWidget(),"floating"===this.config.mode&&(this.widgetElement.style.display="none",this.createFloatingButton()),this.setupEventListeners(),this.setupImageViewer(),this.state.isInitialized=!0,this.emit("ready")}catch(e){this.emit("error",new t("Failed to initialize chat widget","WIDGET_INIT_ERROR",e))}}setupSimulatorEvents(){this.simulator.on("initialized",e=>{var t;this.state.currentProject=e.project,this.state.currentTemplate=e.template,null!=this.config.initialRenderCount?this.initialRenderCount=this.config.initialRenderCount:this.initialRenderCount=Number.MAX_SAFE_INTEGER,this.setTitle((null===(t=e.project)||void 0===t?void 0:t.name)||"Chat",`0 ${this.t.messages}`),this.setLoading(!1),this.emit("simulationInitialized",e)}),this.simulator.on("message",e=>{var t;this.setLoading(!1),this.addMessage(e),this.state.displayedMessageCount++;const s=(null===(t=this.state.currentProject)||void 0===t?void 0:t.name)||"Chat";this.setTitle(s,`${this.state.displayedMessageCount} ${this.t.messages}`)}),this.simulator.on("messages-batch",e=>{var t;this.setLoading(!1),this.addMessagesBulk(e),this.state.displayedMessageCount+=e.length;const s=(null===(t=this.state.currentProject)||void 0===t?void 0:t.name)||"Chat";this.setTitle(s,`${this.state.displayedMessageCount} ${this.t.messages}`),setTimeout(()=>{this.scrollToBottom(!0)},100)}),this.simulator.on("simulationStart",()=>{var e,t;this.state.isSimulationRunning=!0,this.state.isSimulationPaused=!1,null===(t=(e=this.config).onSimulationStart)||void 0===t||t.call(e)}),this.simulator.on("simulationEnd",()=>{var e,t;this.state.isSimulationRunning=!1,this.state.simulationEnded=!0,null===(t=(e=this.config).onSimulationEnd)||void 0===t||t.call(e)}),this.simulator.on("simulationPause",()=>{this.state.isSimulationPaused=!0}),this.simulator.on("simulationResume",()=>{this.state.isSimulationPaused=!1}),this.simulator.on("error",e=>{this.emit("error",e)})}async initializeSimulation(){try{await this.simulator.initialize()}catch(e){this.emit("error",new t("Failed to initialize simulation","SIMULATION_INIT_ERROR",e))}}setupContainer(){var e;const s=function(e){if("string"==typeof e)return document.querySelector(e)||document.body;return e||document.body}(this.config.container);if(!s)throw new t("Container element not found","CONTAINER_NOT_FOUND");const n=null===(e=s.tagName)||void 0===e?void 0:e.toUpperCase();if("BODY"===n||"HTML"===n){const e=document.createElement("div");e.className="chat-sdk-host",e.style.position="static",e.style.width="0",e.style.height="0",document.body.appendChild(e),this.container=e}else this.container=s;this.shadowRoot=this.container.attachShadow({mode:"closed"});const i=this.getDefaultStyles();!function(e,t){const s=document.createElement("style");s.textContent=t,e.appendChild(s)}(this.shadowRoot,i)}createWidget(){var e;if(this.widgetElement&&this.messagesContainer)return;this.widgetElement=n("div","chat-sdk-container");const t="telegram"===this.config.uiTemplate?"telegram":"whatsapp";this.currentTheme=t,this.widgetElement.classList.add(`${t}-theme`),"telegram"===t&&"dark"===this.config.theme&&(this.widgetElement.classList.add("dark"),this.isDarkMode=!0),this.widgetElement.style.position="fixed",this.widgetElement.style.top="0",this.widgetElement.style.left="0",this.widgetElement.style.width="100vw",this.widgetElement.style.height="100vh",this.widgetElement.style.zIndex=String(null!==(e=this.config.zIndex)&&void 0!==e?e:2147483e3),this.widgetElement.innerHTML=`\n <div class="chat-sdk-header">\n <div class="chat-sdk-header-left">\n <div class="chat-sdk-title" id="chat-title"></div>\n <div class="chat-sdk-subtitle" id="chat-subtitle"></div>\n </div>\n <button class="chat-sdk-close-btn" type="button">\n <svg width="20" height="20" viewBox="0 0 16 16" fill="currentColor">\n <path d="M8 7.293l2.146-2.147a.5.5 0 01.708.708L8.707 8l2.147 2.146a.5.5 0 01-.708.708L8 8.707l-2.146 2.147a.5.5 0 01-.708-.708L7.293 8 5.146 5.854a.5.5 0 01.708-.708L8 7.293z"/>\n </svg>\n </button>\n </div>\n\n <div class="chat-sdk-messages" id="messages-container">\n <div class="chat-sdk-loading">\n <div class="chat-sdk-spinner"></div>\n Loading chat...\n </div>\n </div>\n\n <div class="chat-sdk-input-area">\n <button class="chat-sdk-icon-btn chat-sdk-emoji-btn" type="button" id="emoji-button" aria-label="Emoji">\n <span>😊</span>\n </button>\n <button class="chat-sdk-icon-btn chat-sdk-image-btn" type="button" id="image-button" aria-label="Image">\n <svg width="16" height="16" viewBox="0 0 24 24" fill="currentColor"><path d="M21 19V5a2 2 0 0 0-2-2H5a2 2 0 0 0-2 2v14h18zM5 5h14v8l-3-3-4 5-3-4-4 4V5z"/></svg>\n </button>\n <textarea\n class="chat-sdk-input"\n placeholder="${this.t.inputPlaceholder}"\n rows="1"\n id="message-input"\n ></textarea>\n <input type="file" accept="image/*" id="image-input" style="display:none" />\n <button class="chat-sdk-send-btn" type="button" id="send-button" disabled>\n <svg width="16" height="16" viewBox="0 0 16 16" fill="currentColor">\n <path d="M15.854.146a.5.5 0 01.11.54l-5.819 14.547a.75.75 0 01-1.329.124l-3.178-4.995L.643 7.184a.75.75 0 01.124-1.33L15.314.037a.5.5 0 01.54.11z"/>\n </svg>\n </button>\n </div>\n <div class="chat-sdk-emoji-picker" id="emoji-picker" style="display:none">\n <div class="chat-sdk-emoji-grid">\n <button type="button" class="chat-sdk-emoji-item" data-emoji="😀">😀</button>\n <button type="button" class="chat-sdk-emoji-item" data-emoji="😁">😁</button>\n <button type="button" class="chat-sdk-emoji-item" data-emoji="😂">😂</button>\n <button type="button" class="chat-sdk-emoji-item" data-emoji="🤣">🤣</button>\n <button type="button" class="chat-sdk-emoji-item" data-emoji="😊">😊</button>\n <button type="button" class="chat-sdk-emoji-item" data-emoji="😍">😍</button>\n <button type="button" class="chat-sdk-emoji-item" data-emoji="😎">😎</button>\n <button type="button" class="chat-sdk-emoji-item" data-emoji="🤔">🤔</button>\n <button type="button" class="chat-sdk-emoji-item" data-emoji="👍">👍</button>\n <button type="button" class="chat-sdk-emoji-item" data-emoji="🙏">🙏</button>\n </div>\n </div>\n `,this.messagesContainer=this.widgetElement.querySelector("#messages-container"),this.inputElement=this.widgetElement.querySelector("#message-input"),this.sendButton=this.widgetElement.querySelector("#send-button"),this.emojiButton=this.widgetElement.querySelector("#emoji-button"),this.imageButton=this.widgetElement.querySelector("#image-button"),this.fileInput=this.widgetElement.querySelector("#image-input"),this.emojiPicker=this.widgetElement.querySelector("#emoji-picker"),this.shadowRoot.appendChild(this.widgetElement)}setupEventListeners(){var e,t,s,n;const i=this.widgetElement.querySelector(".chat-sdk-close-btn");null==i||i.addEventListener("click",()=>this.close()),this.messagesContainer.addEventListener("scroll",this.handleScrollLazyLoad.bind(this)),this.inputElement.addEventListener("input",this.handleInputChange.bind(this)),this.inputElement.addEventListener("keydown",this.handleKeyDown.bind(this)),this.sendButton.addEventListener("click",this.handleSendMessage.bind(this)),this.inputElement.addEventListener("input",this.autoResizeTextarea.bind(this)),null===(e=this.emojiButton)||void 0===e||e.addEventListener("click",e=>{e.preventDefault(),e.stopPropagation(),this.toggleEmojiPicker(!this.emojiPanelOpen)}),null===(t=this.emojiPicker)||void 0===t||t.addEventListener("click",e=>{const t=e.target.closest(".chat-sdk-emoji-item");if(t&&t.hasAttribute("data-emoji")){const e=t.getAttribute("data-emoji")||"";this.insertEmojiAtCursor(e),this.toggleEmojiPicker(!1)}}),this.shadowRoot.addEventListener("click",e=>{const t=e.target,s=t.closest("#emoji-picker"),n=t.closest("#emoji-button");s||n||this.toggleEmojiPicker(!1)}),null===(s=this.imageButton)||void 0===s||s.addEventListener("click",e=>{var t;e.preventDefault(),e.stopPropagation(),null===(t=this.fileInput)||void 0===t||t.click()}),null===(n=this.fileInput)||void 0===n||n.addEventListener("change",this.handleImageSelected.bind(this)),document.addEventListener("keydown",e=>{if("Escape"===e.key){const e=document.querySelector(".chat-sdk-viewer-overlay");if(e)return e.style.opacity="0",void setTimeout(()=>e.remove(),200);this.state.isOpen&&this.close()}})}openImageZoom(e){const t=document.querySelector(".chat-sdk-global-zoom-overlay");t&&t.remove();const s=document.createElement("div");s.className="chat-sdk-global-zoom-overlay",Object.assign(s.style,{position:"fixed",top:"0",left:"0",width:"100vw",height:"100vh",backgroundColor:"rgba(0, 0, 0, 0.85)",zIndex:"2147483647",display:"flex",justifyContent:"center",alignItems:"center",cursor:"zoom-out",backdropFilter:"blur(4px)",opacity:"0",transition:"opacity 0.2s ease-in-out"});const n=document.createElement("img");n.src=e,Object.assign(n.style,{maxWidth:"80%",maxHeight:"90%",width:"80%",objectFit:"contain",borderRadius:"8px",boxShadow:"0 4px 20px rgba(0,0,0,0.5)",transform:"scale(0.9)",transition:"transform 0.2s cubic-bezier(0.1, 0.9, 0.2, 1)"}),s.addEventListener("click",()=>{s.style.opacity="0",n.style.transform="scale(0.9)",setTimeout(()=>s.remove(),200)}),s.appendChild(n),document.body.appendChild(s),requestAnimationFrame(()=>{s.style.opacity="1",n.style.transform="scale(1)"})}createFloatingButton(){var e,t,s,n,i,a,o,r,d,l,h;if(!this.shadowRoot)return;const c=this.config.floatingButton||{},m=c.position||"bottom-right",u=String(null!==(t=null!==(e=c.zIndex)&&void 0!==e?e:this.config.zIndex)&&void 0!==t?t:2147483e3),g={top:null===(s=c.offset)||void 0===s?void 0:s.top,right:null===(n=c.offset)||void 0===n?void 0:n.right,bottom:null!==(a=null===(i=c.offset)||void 0===i?void 0:i.bottom)&&void 0!==a?a:20,left:null===(o=c.offset)||void 0===o?void 0:o.left},p=document.createElement("button");p.className="chat-sdk-floating-btn",p.setAttribute("aria-label","Open chat");const y=this.t.joinChat;p.innerHTML=`\n <div style="\n position: relative;\n width: 100%;\n height: 100%;\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n padding: 6px;\n ">\n \x3c!-- Group chat icon (users) --\x3e\n <svg width="28" height="28" viewBox="0 0 24 24" fill="currentColor" style="margin-bottom: 2px;">\n <path d="M16 11c1.66 0 2.99-1.34 2.99-3S17.66 5 16 5c-1.66 0-3 1.34-3 3s1.34 3 3 3zm-8 0c1.66 0 2.99-1.34 2.99-3S9.66 5 8 5C6.34 5 5 6.34 5 8s1.34 3 3 3zm0 2c-2.33 0-7 1.17-7 3.5V19h14v-2.5c0-2.33-4.67-3.5-7-3.5zm8 0c-.29 0-.62.02-.97.05 1.16.84 1.97 1.97 1.97 3.45V19h6v-2.5c0-2.33-4.67-3.5-7-3.5z"/>\n </svg>\n\n \x3c!-- Text overlay at bottom --\x3e\n <div style="\n font-size: 10px;\n font-weight: 600;\n color: rgba(255, 255, 255, 0.95);\n text-align: center;\n line-height: 1.2;\n letter-spacing: 0.3px;\n text-shadow: 0 1px 2px rgba(0,0,0,0.2);\n ">${y}</div>\n\n \x3c!-- Unread badge --\x3e\n <span class="chat-sdk-unread-badge" style="\n position: absolute;\n top: -6px;\n right: -6px;\n background: #ff4444;\n color: white;\n border-radius: 10px;\n min-width: 18px;\n height: 18px;\n display: none;\n align-items: center;\n justify-content: center;\n font-size: 10px;\n font-weight: 700;\n line-height: 1;\n border: 2px solid white;\n box-shadow: 0 2px 4px rgba(0,0,0,0.3);\n padding: 0 5px;\n "></span>\n </div>\n `,p.style.position="fixed",p.style.zIndex=u,p.style.width="60px",p.style.height="60px",p.style.borderRadius="50%",p.style.border="none",p.style.cursor="pointer",p.style.display="flex",p.style.alignItems="center",p.style.justifyContent="center",p.style.color="#fff",p.style.boxShadow="0 10px 24px rgba(0,0,0,0.25), inset 0 2px 4px rgba(255,255,255,0.15)",p.style.background="linear-gradient(145deg, #25D366 0%, #128C7E 100%)",p.style.transition="transform .15s ease, box-shadow .15s ease",p.style.overflow="visible",m.includes("bottom")?(p.style.bottom=(null!==(r=g.bottom)&&void 0!==r?r:20)+"px",p.style.top=""):(p.style.top=(null!==(d=g.top)&&void 0!==d?d:20)+"px",p.style.bottom=""),m.includes("right")?(p.style.right=(null!==(l=g.right)&&void 0!==l?l:20)+"px",p.style.left=""):(p.style.left=(null!==(h=g.left)&&void 0!==h?h:20)+"px",p.style.right=""),p.addEventListener("mouseenter",()=>{p.style.transform="scale(1.06)",p.style.boxShadow="0 14px 28px rgba(0,0,0,0.30), inset 0 2px 4px rgba(255,255,255,0.2)"}),p.addEventListener("mouseleave",()=>{p.style.transform="scale(1)",p.style.boxShadow="0 10px 24px rgba(0,0,0,0.25), inset 0 2px 4px rgba(255,255,255,0.15)"}),p.addEventListener("mousedown",()=>{p.style.transform="scale(0.95)"}),p.addEventListener("mouseup",()=>{p.style.transform="scale(1.05)",setTimeout(()=>p.style.transform="scale(1)",100)}),p.addEventListener("click",e=>{e.preventDefault(),this.open()}),this.shadowRoot.appendChild(p),this.floatingButtonEl=p}updateUnreadBadge(){if(!this.floatingButtonEl)return;const e=this.floatingButtonEl.querySelector(".chat-sdk-unread-badge");if(!e)return;const t=this.state.unreadCount;t>0?(e.textContent=t>99?"99+":t.toString(),e.style.display="flex"):e.style.display="none"}markAllAsRead(){if(this.state.messages.length>0){const e=this.state.messages[this.state.messages.length-1];this.state.lastReadMessageId=e.id}this.state.unreadCount=0,this.updateUnreadBadge()}incrementUnreadCount(){this.state.isOpen||(this.state.unreadCount++,this.updateUnreadBadge())}toggleEmojiPicker(e){const t=this.emojiPicker;if(!t)return;const s="boolean"==typeof e?e:"none"===t.style.display;t.style.display=s?"block":"none",this.emojiPanelOpen=s}insertEmojiAtCursor(e){const t=this.inputElement,s=t.selectionStart||0,n=t.selectionEnd||0,i=t.value.substring(0,s),a=t.value.substring(n);t.value=i+e+a;const o=s+e.length;t.setSelectionRange(o,o),t.focus(),this.handleInputChange(),this.autoResizeTextarea()}isEmojiOnly(e){const t=e.trim();if(!t)return!1;if(t.length>6)return!1;let s=!1;for(let e=0;e<t.length;){const n=t.codePointAt(e)||0;if(e+=n>65535?2:1,!(n>=126976))return!1;s=!0}return s}async handleImageSelected(){const e=this.fileInput;if(!e||!e.files||0===e.files.length)return;const s=e.files[0];try{const t=await this.resizeImageFile(s,1280,.85),n={id:`local-img-failed-${Date.now()}-${Math.random().toString(36).slice(2,8)}`,content:t,messageType:"image",timestamp:new Date,isOwnMessage:!0,user:{id:this.config.userId||"me",username:this.config.username||"You"},failed:!0};this.state.messages.push(n),this.renderMessage(n),this.scrollToBottom(!0),e.value=""}catch(e){console.error("Image processing failed",e),this.emit("error",new t("Image processing failed","IMAGE_PROCESS_ERROR",e))}}resizeImageFile(e,t=1280,s=.85){return new Promise((n,i)=>{const a=URL.createObjectURL(e),o=new Image;o.onload=()=>{let{width:e,height:r}=o;const d=Math.min(1,t/Math.max(e,r)),l=document.createElement("canvas");d<1&&(e=Math.round(e*d),r=Math.round(r*d)),l.width=e,l.height=r;const h=l.getContext("2d");if(!h)return URL.revokeObjectURL(a),void i(new Error("Canvas not supported"));h.drawImage(o,0,0,e,r);const c=l.toDataURL("image/jpeg",s);URL.revokeObjectURL(a),n(c)},o.onerror=e=>{URL.revokeObjectURL(a),i(e)},o.src=a})}handleInputChange(){const e=this.inputElement.value.trim().length>0,t=!1!==this.config.enableUserInput&&!1!==this.config.allowInput;this.sendButton.disabled=!e||!t,e&&t&&this.emit("typing")}handleKeyDown(e){"Enter"!==e.key||e.shiftKey||(e.preventDefault(),this.handleSendMessage())}async handleSendMessage(){const e=this.inputElement.value.trim();if(!e)return;if(!1===this.config.enableUserInput||!1===this.config.allowInput)return;const s=this.isEmojiOnly(e)?"emoji":"text",n={id:`local-${Date.now()}-${Math.random().toString(36).slice(2,8)}`,content:e,messageType:s,timestamp:new Date,isOwnMessage:!0,user:{id:this.config.userId||"me",username:this.config.username||"You"}};this.state.messages.push(n),this.renderMessage(n),this.scrollToBottom(!0),this.inputElement.value="",this.sendButton.disabled=!0,this.autoResizeTextarea(),this.simulator.sendMessage(e,s).catch(e=>{console.error("Failed to send message:",e),this.emit("error",new t("Failed to send message","SEND_MESSAGE_ERROR",e))})}autoResizeTextarea(){this.inputElement.style.height="auto",this.inputElement.style.height=Math.min(this.inputElement.scrollHeight,100)+"px"}open(){var e;if(this.state.isOpen)return;if(this.hasInitializedData)try{this.simulator.startPolling()}catch(e){}else this.hasInitializedData=!0,this.setLoading(!0),this.initializeSimulation().catch(e=>{console.error("Failed to initialize simulation on open:",e),this.setLoading(!1)});this.pollingStopTimer&&(clearTimeout(this.pollingStopTimer),this.pollingStopTimer=null),this.floatingButtonEl&&(this.floatingButtonEl.style.display="none"),this.widgetElement.style.opacity="0",this.widgetElement.style.display="flex",requestAnimationFrame(()=>{this.widgetElement.style.transition="opacity .2s ease",this.widgetElement.style.opacity="1"}),this.state.isOpen=!0,this.markAllAsRead(),this.emit("open");const t=(null===(e=this.state.currentProject)||void 0===e?void 0:e.name)||"Chat";this.setTitle(t,`${this.state.displayedMessageCount} ${this.t.messages}`),this.scrollToBottom(!0),requestAnimationFrame(()=>this.scrollToBottom(!0)),setTimeout(()=>this.scrollToBottom(!0),0)}close(){this.state.isOpen&&(this.widgetElement.style.transition="opacity .2s ease",this.widgetElement.style.opacity="0",setTimeout(()=>{this.widgetElement.style.display="none",this.floatingButtonEl&&(this.floatingButtonEl.style.display="flex")},200),this.state.isOpen=!1,this.pollingStopTimer&&clearTimeout(this.pollingStopTimer),this.pollingStopTimer=setTimeout(()=>{try{this.simulator.stopPolling()}catch(e){}this.pollingStopTimer=null},1e4),this.emit("close"))}setTitle(e,t){var s,n;const i=null===(s=this.widgetElement)||void 0===s?void 0:s.querySelector("#chat-title"),a=null===(n=this.widgetElement)||void 0===n?void 0:n.querySelector("#chat-subtitle"),o=b(this.t.chatGroup,{name:e||"Chat"});this.currentTheme,i&&(i.textContent=o),a&&(a.textContent=b(this.t.online,{count:this.onlineCount}),a.style.display="block")}buildMessageElement(e,t){const s=n("div","chat-sdk-message");e.isOwnMessage&&s.classList.add("own");const i=!!t&&this.shouldGroupWithPrev(t,e);i&&s.classList.add("grouped");let a=null;e.isOwnMessage||(a=this.createAvatar(e),i&&a&&(a.style.visibility="hidden"));const o=!e.isOwnMessage&&!i,r="whatsapp"===this.currentTheme,d="telegram"===this.currentTheme&&e.isOwnMessage,l=this.createMessageContent(e,o,r,d);return a&&s.appendChild(a),s.appendChild(l),s}shouldGroupWithPrev(e,t){var s,n,i,a,o,r,d;if(!1===this.config.groupMessages)return!1;const l=null!==(s=this.config.groupTimeThresholdSec)&&void 0!==s?s:120,h=e.isOwnMessage===t.isOwnMessage,c=(null===(n=e.virtualUser)||void 0===n?void 0:n.id)&&(null===(i=e.virtualUser)||void 0===i?void 0:i.id)===(null===(a=t.virtualUser)||void 0===a?void 0:a.id),m=(null===(o=e.user)||void 0===o?void 0:o.id)&&(null===(r=e.user)||void 0===r?void 0:r.id)===(null===(d=t.user)||void 0===d?void 0:d.id),u=h&&(c||m||e.isOwnMessage&&t.isOwnMessage),g=Math.abs(t.timestamp.getTime()-e.timestamp.getTime())/1e3;return!!u&&g<=l}handleScrollLazyLoad(){if(this.messagesContainer.scrollTop<=20&&this.visibleStartIndex>0){const e=this.messagesContainer.scrollHeight,t=this.lazyLoadBatchSize,s=Math.max(0,this.visibleStartIndex-t),n=this.state.messages.slice(s,this.visibleStartIndex),i=document.createDocumentFragment();for(const e of n){const t=this.buildMessageElement(e);i.appendChild(t)}this.messagesContainer.insertBefore(i,this.messagesContainer.firstChild),this.visibleStartIndex=s;const a=this.messagesContainer.scrollHeight;this.messagesContainer.scrollTop+=a-e}}setLoading(e){if(e){if(!this.messagesContainer.querySelector(".chat-sdk-loading")){const e=document.createElement("div");e.className="chat-sdk-loading",e.innerHTML='\n <div class="chat-sdk-spinner"></div>\n Loading chat...\n ',this.messagesContainer.appendChild(e)}}else{const e=this.messagesContainer.querySelector(".chat-sdk-loading");null==e||e.remove()}}showJoinOverlay(){const e=n("div","chat-sdk-overlay");e.innerHTML='\n <div class="chat-sdk-join-card">\n <h3 class="chat-sdk-join-title">Join the conversation</h3>\n <p class="chat-sdk-join-description">\n Click below to join this group chat and start interacting with other members.\n </p>\n <button class="chat-sdk-join-btn" type="button">Join Chat</button>\n </div>\n ';const t=e.querySelector(".chat-sdk-join-btn");null==t||t.addEventListener("click",()=>{this.hideJoinOverlay(),this.emit("join-requested")}),this.widgetElement.appendChild(e)}hideJoinOverlay(){const e=this.widgetElement.querySelector(".chat-sdk-overlay");e&&e.remove()}addMessage(e){if(e.isOwnMessage)for(let t=this.state.messages.length-1;t>=0;t--){const s=this.state.messages[t];if(s.isOwnMessage&&s.content===e.content){if(Math.abs(e.timestamp.getTime()-s.timestamp.getTime())<=1e4)return;break}}this.state.messages.find(t=>t.id===e.id)?console.warn("Duplicate message detected and ignored:",e.id):(this.state.messages.push(e),this.renderMessage(e),e.isOwnMessage||this.incrementUnreadCount(),this.scrollToBottom(!0))}addMessagesBulk(e){if(!e||0===e.length)return;if(0===this.messagesContainer.querySelectorAll(".chat-sdk-message").length){this.state.messages=[...e].sort((e,t)=>e.timestamp.getTime()-t.timestamp.getTime());const t=this.state.messages.length,s=this.initialRenderCount;this.visibleStartIndex=Math.max(0,t-s);const n=this.state.messages.slice(this.visibleStartIndex),i=document.createDocumentFragment();let a;for(const e of n){const t=this.buildMessageElement(e,a);i.appendChild(t),a=e}this.messagesContainer.appendChild(i),setTimeout(()=>{this.scrollToBottom(!0)},0)}else{const t=new Set(this.state.messages.map(e=>e.id)),s=e.filter(e=>!t.has(e.id));if(s.length>0){this.state.messages.push(...s),this.state.messages.sort((e,t)=>e.timestamp.getTime()-t.timestamp.getTime()),this.messagesContainer.innerHTML="";const e=this.state.messages.length,t=this.initialRenderCount;this.visibleStartIndex=Math.max(0,e-t);const n=this.state.messages.slice(this.visibleStartIndex),i=document.createDocumentFragment();let a;for(const e of n){const t=this.buildMessageElement(e,a);i.appendChild(t),a=e}this.messagesContainer.appendChild(i),this.scrollToBottom()}}}reRenderAllMessages(){this.messagesContainer.innerHTML="";const e=this.state.messages.length,t=Math.max(0,e-this.initialRenderCount);this.state.messages.slice(t).forEach(e=>{this.renderMessage(e)}),this.scrollToBottom()}renderMessage(e){const t=this.state.messages.length-1,s=t>0?this.state.messages[t-1]:void 0,n=this.buildMessageElement(e,s);this.messagesContainer.appendChild(n)}createAvatar(e){var t,s,i,a;const o=n("div","chat-sdk-message-avatar");if(null===(t=e.virtualUser)||void 0===t?void 0:t.avatar)o.style.backgroundImage=`url(${e.virtualUser.avatar})`,o.style.backgroundSize="cover",o.style.backgroundPosition="center";else if(null===(s=e.user)||void 0===s?void 0:s.avatar)o.style.backgroundImage=`url(${e.user.avatar})`,o.style.backgroundSize="cover",o.style.backgroundPosition="center";else{const t=(null===(i=e.virtualUser)||void 0===i?void 0:i.username)||(null===(a=e.user)||void 0===a?void 0:a.username)||"U";o.textContent=t.charAt(0).toUpperCase()}return o}createMessageContent(e,t=!0,s=!1,a=!1){var o,r,d;const l=n("div","chat-sdk-message-content"),h=(null===(o=e.virtualUser)||void 0===o?void 0:o.displayName)||(null===(r=e.virtualUser)||void 0===r?void 0:r.username)||(null===(d=e.user)||void 0===d?void 0:d.username)||"Unknown";let c="";if("image"===e.messageType){c=`\n <div class="chat-sdk-message-image${e.failed?" failed":""}">\n <img src="${i(e.content)}" alt="Image"\n style="max-width: 200px; max-height: 280px; width: 100%; height: auto; cursor: pointer; display: block; border-radius: 8px; object-fit: cover;"\n data-image-url="${i(e.content)}"\n class="chat-sdk-image-preview" />\n </div>\n `}else if("audio"===e.messageType){c=`\n <div class="chat-sdk-voice-msg" data-audio-src="${i(e.audioUrl||e.content||"")}" style="display:flex;align-items:center;gap:8px;min-width:200px;max-width:260px;padding:4px 2px;">\n <button class="chat-sdk-voice-play-btn" style="width:36px;height:36px;border-radius:50%;border:none;background:rgba(255,255,255,0.22);color:#fff;font-size:16px;cursor:pointer;display:flex;align-items:center;justify-content:center;flex-shrink:0;transition:background 0.15s;">\n <svg width="16" height="18" viewBox="0 0 16 18" fill="currentColor"><path d="M2 1.5v15l12-7.5L2 1.5z"/></svg>\n </button>\n <div class="chat-sdk-voice-waveform" style="display:flex;align-items:center;flex:1;height:28px;overflow:hidden;">\n ${Array.from({length:28},()=>`<span class="chat-sdk-voice-bar" style="display:inline-block;width:3px;height:${4+Math.floor(18*Math.random())}px;border-radius:1.5px;background:rgba(255,255,255,0.45);margin:0 1px;transition:background 0.15s;vertical-align:middle;flex-shrink:0"></span>`).join("")}\n </div>\n <span class="chat-sdk-voice-duration" style="font-size:11px;color:rgba(255,255,255,0.75);min-width:32px;text-align:right;flex-shrink:0;font-variant-numeric:tabular-nums;">0:00</span>\n </div>`}else c="emoji"===e.messageType?`<div class="chat-sdk-message-emoji" style="font-size: 2em; line-height: 1;">${i(e.content)}</div>`:`<p class="chat-sdk-message-text">${i(e.content)}</p>`;const m=`${function(e,t){const s=new Date,n=Math.floor((s.getTime()-e.getTime())/1e3),i=(t||("undefined"!=typeof navigator?navigator.language:"en")).toLowerCase().startsWith("zh");if(n<60)return i?"刚刚":"just now";if(n<3600){const e=Math.floor(n/60);return i?`${e} 分钟前`:`${e}m ago`}if(n<86400){const e=Math.floor(n/3600);return i?`${e} 小时前`:`${e}h ago`}const a=new Date(s.getFullYear(),s.getMonth(),s.getDate());if(e>=new Date(a.getTime()-864e5)&&e<a){const t=e.toLocaleTimeString(i?"zh-CN":void 0,{hour:"2-digit",minute:"2-digit",hour12:!1});return i?`昨天 ${t}`:`yesterday ${t}`}return s.getTime()-e.getTime()<6048e5?e.toLocaleString(i?"zh-CN":void 0,{month:"short",day:"numeric",hour:"2-digit",minute:"2-digit",hour12:!1}):e.toLocaleString(i?"zh-CN":void 0,{year:"numeric",month:"2-digit",day:"2-digit",hour:"2-digit",minute:"2-digit",hour12:!1})}(e.timestamp,this.config.language)}`,u=a?'<span class="chat-sdk-read-status">✓✓</span>':"",g=e.failed&&e.isOwnMessage?'<div class="chat-sdk-message-failed-indicator">\n <svg width="16" height="16" viewBox="0 0 16 16" fill="currentColor">\n <circle cx="8" cy="8" r="8" fill="#ff4444"/>\n <path d="M8 4v4M8 10h.01" stroke="white" stroke-width="1.5" stroke-linecap="round"/>\n </svg>\n </div>':"";return l.innerHTML=s?`\n <div class="chat-sdk-message-bubble">\n ${t&&!e.isOwnMessage?`<div class="chat-sdk-message-username">${i(h)}</div>`:""}\n ${c}\n <div class="chat-sdk-message-time-inside">${m}${u?" "+u:""}</div>\n </div>\n ${g}\n `:`\n ${t&&!e.isOwnMessage?`<div class="chat-sdk-message-username">${i(h)}</div>`:""}\n <div class="chat-sdk-message-bubble">\n ${c}\n </div>\n <div class="chat-sdk-message-time">${m}${u?" "+u:""}</div>\n ${g}\n `,l}scrollToBottom(e=!1){const t=this.messagesContainer;if(e)return void a(t);t.scrollTop+t.clientHeight>=t.scrollHeight-40&&a(t)}setupImageViewer(){this.messagesContainer.addEventListener("click",e=>{const t=e.target;if(t.classList.contains("chat-sdk-image-preview")){const e=t.getAttribute("data-image-url");e&&this.openImageViewer(e)}}),this.messagesContainer.addEventListener("click",e=>{const t=e.target.closest(".chat-sdk-voice-play-btn");if(!t)return;const s=t.closest(".chat-sdk-voice-msg");if(!s)return;const n=s.getAttribute("data-audio-src");n&&this.handleVoicePlay(s,n,t)})}handleVoicePlay(e,t,s){const n=e.querySelector(".chat-sdk-voice-waveform"),i=e.querySelector(".chat-sdk-voice-duration"),a=null==n?void 0:n.querySelectorAll(".chat-sdk-voice-bar");if(!n||!i||!a.length)return;if(this.currentVoiceContainer===e&&this.currentAudio&&!this.currentAudio.paused)return this.currentAudio.pause(),void(s.innerHTML='<svg width="16" height="18" viewBox="0 0 16 18" fill="currentColor"><path d="M2 1.5v15l12-7.5L2 1.5z"/></svg>');this.currentAudio&&(this.currentAudio.pause(),this.currentAudio.currentTime=0,this.resetVoiceUI(this.currentVoiceContainer));const o=new Audio(t);this.currentAudio=o,this.currentVoiceContainer=e,s.innerHTML='<svg width="14" height="18" viewBox="0 0 14 18" fill="currentColor"><rect x="1" y="1" width="4" height="16" rx="1"/><rect x="9" y="1" width="4" height="16" rx="1"/></svg>',o.addEventListener("loadedmetadata",()=>{i.textContent=this.formatAudioDuration(o.duration)}),o.addEventListener("timeupdate",()=>{if(!o.duration)return;const e=o.currentTime/o.duration,t=Math.floor(e*a.length);a.forEach((e,s)=>{e.style.background=s<t?"rgba(255,255,255,0.95)":"rgba(255,255,255,0.45)"});const s=o.duration-o.currentTime;i.textContent=this.formatAudioDuration(s)}),o.addEventListener("ended",()=>{this.resetVoiceUI(e),this.currentAudio=null,this.currentVoiceContainer=null}),o.addEventListener("error",()=>{console.warn("[ChatSDK] Voice audio load error:",t),this.resetVoiceUI(e),this.currentAudio=null,this.currentVoiceContainer=null}),o.play().catch(t=>{console.warn("[ChatSDK] Voice play failed:",t),this.resetVoiceUI(e)})}resetVoiceUI(e){if(!e)return;const t=e.querySelector(".chat-sdk-voice-play-btn"),s=e.querySelectorAll(".chat-sdk-voice-bar"),n=e.querySelector(".chat-sdk-voice-duration");t&&(t.innerHTML='<svg width="16" height="18" viewBox="0 0 16 18" fill="currentColor"><path d="M2 1.5v15l12-7.5L2 1.5z"/></svg>'),s.forEach(e=>{e.style.background="rgba(255,255,255,0.45)"}),n&&(n.textContent="0:00")}formatAudioDuration(e){const t=Math.max(0,Math.floor(e));return`${Math.floor(t/60)}:${(t%60).toString().padStart(2,"0")}`}openImageViewer(e){const t=document.querySelector(".chat-sdk-viewer-overlay");t&&t.remove();const s=document.createElement("div");s.className="chat-sdk-viewer-overlay",Object.assign(s.style,{position:"fixed",inset:"0",width:"100vw",height:"100vh",background:"rgba(0,0,0,0.88)",zIndex:"2147483647",display:"flex",alignItems:"center",justifyContent:"center",opacity:"0",transition:"opacity 0.2s ease",cursor:"zoom-out"});const n=document.createElement("button");Object.assign(n.style,{position:"absolute",top:"16px",right:"20px",background:"none",border:"none",color:"#fff",fontSize:"32px",cursor:"pointer",lineHeight:"1",padding:"4px",zIndex:"1"}),n.innerHTML="×",n.setAttribute("aria-label","Close");const i=document.createElement("img");i.src=e,i.alt="Full size image",Object.assign(i.style,{maxWidth:"90vw",maxHeight:"90vh",objectFit:"contain",borderRadius:"8px",boxShadow:"0 8px 32px rgba(0,0,0,0.6)",transform:"scale(0.92)",transition:"transform 0.2s cubic-bezier(0.1, 0.9, 0.2, 1)",cursor:"default",display:"block"});s.addEventListener("click",e=>{e.target!==s&&e.target!==n||(s.style.opacity="0",i.style.transform="scale(0.92)",setTimeout(()=>{s.parentNode&&s.remove()},200))}),i.addEventListener("click",e=>e.stopPropagation()),s.appendChild(n),s.appendChild(i),document.body.appendChild(s),requestAnimationFrame(()=>{s.style.opacity="1",i.style.transform="scale(1)"})}showImagePreview(e){const t=n("div","chat-sdk-image-modal");t.innerHTML=`\n <div class="chat-sdk-image-modal-overlay">\n <div class="chat-sdk-image-modal-content">\n <button class="chat-sdk-image-modal-close">×</button>\n <img src="${i(e)}" alt="Image Preview" class="chat-sdk-image-modal-img" />\n </div>\n </div>\n `,this.widgetElement.appendChild(t);const s=t.querySelector(".chat-sdk-image-modal-close"),a=t.querySelector(".chat-sdk-image-modal-overlay"),o=()=>{t.remove()};null==s||s.addEventListener("click",o),null==a||a.addEventListener("click",e=>{e.target===a&&o()});const r=e=>{"Escape"===e.key&&(o(),document.removeEventListener("keydown",r))};document.addEventListener("keydown",r)}setJoined(e){this.state.isJoined=e,this.handleInputChange()}setUITemplate(e){this.currentTheme=e,this.config.uiTemplate=e,this.widgetElement.classList.remove("whatsapp-theme","telegram-theme","dark"),this.widgetElement.classList.add(`${e}-theme`),"telegram"===e&&this.isDarkMode&&this.widgetElement.classList.add("dark"),this.updateThemeStyles(),this.reRenderAllMessages()}setTheme(e){this.isDarkMode="dark"===e,this.config.theme=e,"telegram"===this.currentTheme&&(this.isDarkMode?this.widgetElement.classList.add("dark"):this.widgetElement.classList.remove("dark"),this.updateThemeStyles())}setCustomColors(e){this.customColors={...this.customColors,...e},this.config.primaryColor=e.primary,this.config.backgroundColor=e.background,this.updateThemeStyles()}updateThemeStyles(){const e=this.currentTheme,t=this.isDarkMode&&"telegram"===e,s=this.shadowRoot||document.documentElement;"whatsapp"===e?(this.setCSSProperty(s,"--chat-primary-color",this.customColors.primary||"#25D366"),this.setCSSProperty(s,"--chat-background-color",this.customColors.background||"#ECE5DD"),this.setCSSProperty(s,"--chat-message-own-bg","#DCF8C6"),this.setCSSProperty(s,"--chat-message-other-bg","#FFFFFF"),this.setCSSProperty(s,"--chat-header-bg","linear-gradient(135deg, #075e54 0%, #128c7e 100%)")):"telegram"===e&&(t?(this.setCSSProperty(s,"--chat-primary-color",this.customColors.primary||"#4FC3F7"),this.setCSSProperty(s,"--chat-background-color",this.customColors.background||"#212121"),this.setCSSProperty(s,"--chat-message-own-bg","linear-gradient(135deg, #4fc3f7 0%, #29b6f6 100%)"),this.setCSSProperty(s,"--chat-message-other-bg","#2F2F2F"),this.setCSSProperty(s,"--chat-header-bg","linear-gradient(135deg, #1976d2 0%, #1565c0 100%)"),this.setCSSProperty(s,"--chat-text-color","#FFFFFF")):(this.setCSSProperty(s,"--chat-primary-color",this.customColors.primary||"#2481CC"),this.setCSSProperty(s,"--chat-background-color",this.customColors.background||"#FFFFFF"),this.setCSSProperty(s,"--chat-message-own-bg","linear-gradient(135deg, #4fc3f7 0%, #29b6f6 100%)"),this.setCSSProperty(s,"--chat-message-other-bg","#F1F1F1"),this.setCSSProperty(s,"--chat-header-bg","linear-gradient(135deg, #2481cc 0%, #1c7cd6 100%)"),this.setCSSProperty(s,"--chat-text-color","#000000")))}setCSSProperty(e,t,s){if(e instanceof ShadowRoot){const n=e.querySelector("style");if(n){const e=n.textContent||"",i=new RegExp(`${t}\\s*:\\s*[^;]+;`,"g"),a=`${t}: ${s};`;if(i.test(e))n.textContent=e.replace(i,a);else{const t=/:host\s*\{([^}]*)\}/;t.test(e)?n.textContent=e.replace(t,(e,t)=>`:host { ${t} ${a} }`):n.textContent=`:host { ${a} }\n${e}`}}}else e.style.setProperty(t,s)}getState(){return{...this.state}}getDefaultStyles(){return"\n :host {\n --chat-primary-color: #25D366;\n --chat-background-color: #ECE5DD;\n --chat-message-own-bg: #DCF8C6;\n --chat-message-other-bg: #FFFFFF;\n --chat-header-bg: linear-gradient(135deg, #075e54 0%, #128c7e 100%);\n --chat-text-color: #333333;\n --chat-border-radius-message: 18px;\n --chat-border-radius-input: 25px;\n }\n\n .chat-sdk-container {\n font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif;\n font-size: 14px;\n line-height: 1.5;\n color: var(--chat-text-color);\n background: var(--chat-background-color);\n border-radius: 12px;\n box-shadow: 0 4px 20px rgba(0, 0, 0, 0.15);\n overflow: hidden;\n display: flex;\n flex-direction: column;\n position: relative;\n max-width: 100%;\n max-height: 100%;\n }\n\n .chat-sdk-container * {\n box-sizing: border-box;\n }\n\n /* WhatsApp Theme */\n .chat-sdk-container.whatsapp-theme .chat-sdk-header {\n background: linear-gradient(135deg, #075e54 0%, #128c7e 100%);\n color: white;\n padding: 12px 16px;\n display: flex;\n align-items: center;\n justify-content: flex-end;\n min-height: 60px;\n box-shadow: 0 1px 3px rgba(0,0,0,0.12);\n }\n .chat-sdk-container.whatsapp-theme .chat-sdk-header-left { display: none; }\n\n .chat-sdk-container.whatsapp-theme .chat-sdk-messages {\n background-color: #ece5dd;\n background-image: url(\"data:image/svg+xml,%3Csvg width='60' height='60' viewBox='0 0 60 60' xmlns='http://www.w3.org/2000/svg'%3E%3Cg fill='none' fill-rule='evenodd'%3E%3Cg fill='%23e5ddd5' fill-opacity='0.08'%3E%3Cpath d='M36 34v-4h-2v4h-4v2h4v4h2v-4h4v-2h-4zm0-30V0h-2v4h-4v2h4v4h2V6h4V4h-4zM6 34v-4H4v4H0v2h4v4h2v-4h4v-2H6zM6 4V0H4v4H0v2h4v4h2V6h4V4H6z'/%3E%3C/g%3E%3C/g%3E%3C/svg%3E\");\n padding: 8px 6px;\n }\n\n .chat-sdk-container.whatsapp-theme {\n --chat-primary-color: #25D366;\n --chat-background-color: #ECE5DD;\n --chat-message-own-bg: #DCF8C6;\n --chat-message-other-bg: #FFFFFF;\n --chat-header-bg: linear-gradient(135deg, #075e54 0%, #128c7e 100%);\n --chat-text-color: #303030;\n --chat-border-radius-message: 7.5px;\n --chat-border-radius-input: 25px;\n display: flex;\n flex-direction: column;\n height: 100%;\n }\n\n /* ── WhatsApp: Message Row Layout ── */\n .chat-sdk-container.whatsapp-theme .chat-sdk-message {\n display: flex;\n flex-direction: row;\n align-items: flex-end;\n margin-bottom: 4px;\n padding: 1px 10px;\n gap: 6px;\n }\n\n /* Own message: green bubble, right side, no avatar */\n .chat-sdk-container.whatsapp-theme .chat-sdk-message.own {\n flex-direction: row-reverse;\n justify-content: flex-start;\n }\n .chat-sdk-container.whatsapp-theme .chat-sdk-message.own .chat-sdk-message-avatar {\n display: none;\n }\n\n /* ── WhatsApp: Avatar ── */\n .chat-sdk-container.whatsapp-theme .chat-sdk-message-avatar {\n width: 32px;\n height: 32px;\n flex-shrink: 0;\n border-radius: 50%;\n align-self: flex-end;\n margin-bottom: 0;\n font-size: 13px;\n font-weight: 700;\n color: #fff;\n background: #aaa;\n }\n\n /* ── WhatsApp: Message Content Wrapper ── */\n .chat-sdk-container.whatsapp-theme .chat-sdk-message-content {\n max-width: 72%;\n min-width: 60px;\n position: relative;\n display: flex;\n flex-direction: column;\n }\n\n /* ── WhatsApp: Bubble ── */\n .chat-sdk-container.whatsapp-theme .chat-sdk-message-bubble {\n background: #fff;\n color: #303030;\n border-radius: 7.5px;\n padding: 6px 10px 20px 10px;\n box-shadow: 0 1px 0.5px rgba(0,0,0,0.13);\n position: relative;\n word-wrap: break-word;\n word-break: break-word;\n display: block;\n max-width: 100%;\n }\n\n /* Tail for other-person bubble (left bottom corner) */\n .chat-sdk-container.whatsapp-theme .chat-sdk-message:not(.own):not(.grouped) .chat-sdk-message-bubble::before {\n content: '';\n position: absolute;\n bottom: 0;\n left: -8px;\n width: 0;\n height: 0;\n border-style: solid;\n border-width: 0 0 8px 8px;\n border-color: transparent transparent #fff transparent;\n filter: drop-shadow(-1px 1px 0.5px rgba(0,0,0,0.10));\n }\n\n /* Own bubble: green */\n .chat-sdk-container.whatsapp-theme .chat-sdk-message.own .chat-sdk-message-bubble {\n background: #DCF8C6;\n color: #303030;\n border-radius: 7.5px;\n }\n\n /* Tail for own bubble (right bottom corner) */\n .chat-sdk-container.whatsapp-theme .chat-sdk-message.own:not(.grouped) .chat-sdk-message-bubble::before {\n content: '';\n position: absolute;\n bottom: 0;\n right: -8px;\n left: auto;\n width: 0;\n height: 0;\n border-style: solid;\n border-width: 8px 0 0 8px;\n border-color: transparent transparent transparent #DCF8C6;\n filter: drop-shadow(1px 1px 0.5px rgba(0,0,0,0.10));\n }\n\n /* ── WhatsApp: Username inside bubble (colored) ── */\n .chat-sdk-container.whatsapp-theme .chat-sdk-message-username {\n font-size: 12.5px;\n font-weight: 600;\n margin-bottom: 2px;\n line-height: 1.2;\n display: block;\n }\n\n /* Cycle username colors like real WhatsApp */\n .chat-sdk-container.whatsapp-theme .chat-sdk-message:nth-child(7n+1) .chat-sdk-message-username { color: #e91e8c; }\n .chat-sdk-container.whatsapp-theme .chat-sdk-message:nth-child(7n+2) .chat-sdk-message-username { color: #e67e22; }\n .chat-sdk-container.whatsapp-theme .chat-sdk-message:nth-child(7n+3) .chat-sdk-message-username { color: #1abc9c; }\n .chat-sdk-container.whatsapp-theme .chat-sdk-message:nth-child(7n+4) .chat-sdk-message-username { color: #9b59b6; }\n .chat-sdk-container.whatsapp-theme .chat-sdk-message:nth-child(7n+5) .chat-sdk-message-username { color: #e74c3c; }\n .chat-sdk-container.whatsapp-theme .chat-sdk-message:nth-child(7n+6) .chat-sdk-message-username { color: #3498db; }\n .chat-sdk-container.whatsapp-theme .chat-sdk-message:nth-child(7n+0) .chat-sdk-message-username { color: #2ecc71; }\n\n /* ── WhatsApp: Input area ── */\n .chat-sdk-container.whatsapp-theme .chat-sdk-input-area {\n background: #f0f2f5;\n border-top: none;\n padding: 8px 10px;\n }\n .chat-sdk-container.whatsapp-theme .chat-sdk-input {\n background: #fff;\n border: none;\n border-radius: 22px;\n padding: 9px 14px;\n font-size: 15px;\n box-shadow: none;\n }\n .chat-sdk-container.whatsapp-theme .chat-sdk-send-btn {\n background: #00a884;\n width: 42px;\n height: 42px;\n box-shadow: none;\n }\n\n\n /* Telegram Theme */\n .chat-sdk-container.telegram-theme {\n --chat-primary-color: #2481CC;\n --chat-background-color: #FFFFFF;\n --chat-message-own-bg: linear-gradient(135deg, #4fc3f7 0%, #29b6f6 100%);\n --chat-message-other-bg: #F1F1F1;\n --chat-header-bg: linear-gradient(135deg, #2481cc 0%, #1c7cd6 100%);\n --chat-text-color: #000000;\n --chat-border-radius-message: 12px;\n --chat-border-radius-input: 12px;\n\n /* Telegram input + details */\n .chat-sdk-container.telegram-theme .chat-sdk-message {\n align-items: flex-start; /* avatar aligns with username at top, not bottom */\n }\n .chat-sdk-container.telegram-theme .chat-sdk-message-content {\n max-width: 75%;\n }\n .chat-sdk-container.telegram-theme .chat-sdk-message-bubble {\n box-shadow: 0 1px 1px rgba(0,0,0,0.06);\n }\n .chat-sdk-container.telegram-theme .chat-sdk-input-area {\n background: #ffffff;\n border-top: 1px solid #e6e6e6;\n }\n .chat-sdk-container.telegram-theme .chat-sdk-input {\n background: #fff;\n border: 1px solid #cfd6dd;\n border-radius: 12px;\n padding: 9px 14px;\n }\n .chat-sdk-container.telegram-theme .chat-sdk-send-btn {\n background: #2481CC;\n border-radius: 10px;\n width: 38px;\n height: 36px;\n box-shadow: none;\n }\n /* Telegram dark */\n .chat-sdk-container.telegram-theme.dark .chat-sdk-input-area {\n background: #1f1f1f;\n border-top: 1px solid #2a2a2a;\n }\n .chat-sdk-container.telegram-theme.dark .chat-sdk-input {\n background: #2b2b2b;\n color: #e0e0e0;\n border-color: #444;\n }\n .chat-sdk-container.telegram-theme.dark .chat-sdk-send-btn {\n background: #1976d2;\n }\n\n\n .chat-sdk-container.telegram-theme .chat-sdk-header {\n background: var(--chat-header-bg);\n color: white;\n padding: 12px 16px;\n display: flex;\n align-items: center;\n justify-content: space-between;\n min-height: 60px;\n box-shadow: 0 1px 3px rgba(0,0,0,0.12);\n }\n\n .chat-sdk-container.telegram-theme .chat-sdk-messages {\n background-color: var(--chat-background-color);\n }\n\n .chat-sdk-container.telegram-theme .chat-sdk-message.own .chat-sdk-message-bubble {\n background: var(--chat-message-own-bg);\n color: white;\n border-radius: var(--chat-border-radius-message) var(--chat-border-radius-message) 4px var(--chat-border-radius-message);\n }\n\n .chat-sdk-container.telegram-theme .chat-sdk-message:not(.own) .chat-sdk-message-bubble {\n background: var(--chat-message-other-bg);\n color: var(--chat-text-color);\n border-radius: var(--chat-border-radius-message) var(--chat-border-radius-message) var(--chat-border-radius-message) 4px;\n }\n\n /* Telegram Dark Theme */\n .chat-sdk-container.telegram-theme.dark {\n --chat-background-color: #212121;\n --chat-message-other-bg: #2F2F2F;\n --chat-header-bg: linear-gradient(135deg, #1976d2 0%, #1565c0 100%);\n --chat-text-color: #FFFFFF;\n }\n\n /* Default header (fallback) */\n .chat-sdk-header {\n background: var(--chat-header-bg);\n color: white;\n padding: 12px 16px;\n display: flex;\n align-items: center;\n justify-content: space-between;\n min-height: 60px;\n }\n\n .chat-sdk-header-left { display: flex; flex-direction: column; gap: 2px; }\n .chat-sdk-title { font-size: 15px; font-weight: 600; }\n .chat-sdk-subtitle { font-size: 12px; opacity: 0.9; }\n\n .chat-sdk-close-btn {\n background: none;\n border: none;\n color: white;\n cursor: pointer;\n padding: 8px;\n border-radius: 50%;\n opacity: 0.8;\n transition: all 0.2s;\n display: flex;\n align-items: center;\n justify-content: center;\n width: 36px;\n height: 36px;\n }\n\n .chat-sdk-close-btn:hover {\n opacity: 1;\n background: rgba(255, 255, 255, 0.1);\n }\n\n .chat-sdk-messages {\n flex: 1;\n overflow-y: auto;\n padding: 16px;\n background: var(--chat-background-color);\n min-height: 0; /* allow flex to use full height */\n }\n\n .chat-sdk-message {\n margin-bottom: 12px;\n display: flex;\n align-items: flex-end;\n gap: 8px;\n }\n\n .chat-sdk-message.own {\n flex-direction: row-reverse;\n }\n\n .chat-sdk-message-avatar {\n width: 32px;\n height: 32px;\n border-radius: 50%;\n background: #ddd;\n display: flex;\n align-items: center;\n justify-content: center;\n font-size: 12px;\n font-weight: 600;\n color: #666;\n flex-shrink: 0;\n }\n\n .chat-sdk-message-content {\n max-width: 70%;\n position: relative;\n }\n\n .chat-sdk-message-bubble {\n background: var(--chat-message-other-bg);\n color: var(--chat-text-color);\n padding: 8px 12px;\n border-radius: var(--chat-border-radius-message);\n position: relative;\n word-wrap: break-word;\n box-shadow: 0 1px 2px rgba(0, 0, 0, 0.1);\n }\n\n .chat-sdk-message.own .chat-sdk-message-bubble {\n background: var(--chat-message-own-bg);\n color: white;\n }\n\n .chat-sdk-message-username {\n font-size: 11px;\n color: #666;\n margin-bottom: 2px;\n font-weight: 600;\n }\n\n .chat-sdk-message-text {\n margin: 0;\n line-height: 1.4;\n }\n\n .chat-sdk-message-time {\n font-size: 10px;\n color: #999;\n margin-top: 4px;\n text-align: right;\n }\n\n /* Message grouping */\n .chat-sdk-message.grouped {\n margin-top: 4px;\n }\n .chat-sdk-message.grouped .chat-sdk-message-username { display: none; }\n .chat-sdk-message.grouped .chat-sdk-message-avatar { visibility: hidden; }\n\n /* WhatsApp: time inside bubble */\n .chat-sdk-container.whatsapp-theme .chat-sdk-message-time-inside {\n position: absolute;\n right: 6px;\n bottom: 4px;\n font-size: 11px;\n color: rgba(0,0,0,0.45);\n display: flex;\n align-items: center;\n gap: 3px;\n line-height: 1;\n }\n .chat-sdk-container.whatsapp-theme .chat-sdk-message.own .chat-sdk-message-time-inside {\n color: rgba(0, 0, 0, 0.45);\n }\n /* hide external time for whatsapp (time is inside bubble) */\n .chat-sdk-container.whatsapp-theme .chat-sdk-message-time {\n display: none;\n }\n\n /* Telegram: read status */\n .chat-sdk-container.telegram-theme .chat-sdk-message-time {\n display: flex;\n align-items: center;\n justify-content: flex-end;\n gap: 6px;\n }\n .chat-sdk-container.telegram-theme .chat-sdk-message.own .chat-sdk-read-status {\n font-size: 12px;\n color: var(--chat-primary-color);\n line-height: 1;\n }\n\n /* Theme-specific image radii */\n .chat-sdk-container.whatsapp-theme .chat-sdk-message-image img { border-radius: 8px; max-width: 200px; max-height: 280px; }\n .chat-sdk-container.telegram-theme .chat-sdk-message-image img { border-radius: 6px; max-width: 200px; max-height: 280px; }\n\n\n .chat-sdk-input-area {\n padding: 12px 16px;\n background: white;\n border-top: 1px solid #e0e0e0;\n display: flex;\n align-items: center;\n gap: 8px;\n }\n\n\n .chat-sdk-icon-btn {\n background: transparent;\n border: none;\n width: 32px;\n height: 32px;\n border-radius: 6px;\n cursor: pointer;\n display: flex;\n align-items: center;\n justify-content: center;\n color: #666;\n }\n .chat-sdk-icon-btn:hover { background: rgba(0,0,0,0.06); }\n\n .chat-sdk-emoji-picker {\n position: absolute;\n left: 12px;\n bottom: 64px;\n background: #fff;\n border: 1px solid #e0e0e0;\n border-radius: 8px;\n box-shadow: 0 6px 16px rgba(0,0,0,0.12);\n padding: 6px;\n z-index: 5;\n }\n .chat-sdk-emoji-grid {\n display: grid;\n grid-template-columns: repeat(5, 28px);\n gap: 6px;\n }\n\n /* Failed message styles - Telegram style */\n .chat-sdk-message-failed-indicator {\n display: inline-flex;\n align-items: center;\n margin-left: 6px;\n color: #ff4444;\n cursor: pointer;\n }\n .chat-sdk-message-failed-indicator svg {\n width: 16px;\n height: 16px;\n }\n .chat-sdk-message.own .chat-sdk-message-content {\n display: flex;\n align-items: flex-end;\n gap: 6px;\n }\n .chat-sdk-message.own .chat-sdk-message-bubble {\n flex: 1;\n }\n .chat-sdk-emoji-item {\n background: none;\n border: none;\n font-size: 20px;\n line-height: 1;\n cursor: pointer;\n width: 28px;\n height: 28px;\n border-radius: 4px;\n }\n .chat-sdk-emoji-item:hover { background: #f3f4f6; }\n\n\n .chat-sdk-input {\n flex: 1;\n border: 1px solid #ddd;\n border-radius: var(--chat-border-radius-input);\n padding: 8px 16px;\n font-size: 14px;\n outline: none;\n resize: none;\n min-height: 36px;\n max-height: 100px;\n }\n\n .chat-sdk-input:focus {\n border-color: var(--chat-primary-color);\n }\n\n .chat-sdk-send-btn {\n background: var(--chat-primary-color);\n color: white;\n border: none;\n border-radius: 50%;\n width: 36px;\n height: 36px;\n cursor: pointer;\n display: flex;\n align-items: center;\n justify-content: center;\n transition: background-color 0.2s;\n }\n\n .chat-sdk-send-btn:hover {\n background: #064e45;\n }\n\n .chat-sdk-send-btn:disabled {\n background: #ccc;\n cursor: not-allowed;\n }\n\n .chat-sdk-overlay {\n position: absolute;\n top: 0;\n left: 0;\n right: 0;\n bottom: 0;\n background: rgba(0, 0, 0, 0.5);\n display: flex;\n align-items: center;\n justify-content: center;\n z-index: 10;\n }\n\n .chat-sdk-join-card {\n background: white;\n border-radius: 12px;\n padding: 24px;\n max-width: 300px;\n margin: 16px;\n text-align: center;\n }\n\n .chat-sdk-join-title {\n font-size: 18px;\n font-weight: 600;\n margin: 0 0 8px 0;\n color: #333;\n }\n\n .chat-sdk-join-description {\n font-size: 14px;\n color: #666;\n margin: 0 0 20px 0;\n line-height: 1.4;\n }\n\n .chat-sdk-join-btn {\n background: #075e54;\n color: white;\n border: none;\n border-radius: 8px;\n padding: 12px 24px;\n font-size: 14px;\n font-weight: 600;\n cursor: pointer;\n transition: background-color 0.2s;\n width: 100%;\n }\n\n .chat-sdk-join-btn:hover {\n background: #064e45;\n }\n\n .chat-sdk-loading {\n display: flex;\n align-items: center;\n justify-content: center;\n padding: 40px;\n color: #666;\n }\n\n .chat-sdk-spinner {\n width: 20px;\n height: 20px;\n border: 2px solid #e0e0e0;\n border-top: 2px solid #075e54;\n border-radius: 50%;\n animation: chat-sdk-spin 1s linear infinite;\n margin-right: 8px;\n }\n\n @keyframes chat-sdk-spin {\n 0% { transform: rotate(0deg); }\n 100% { transform: rotate(360deg); }\n }\n\n .chat-sdk-container.dark {\n background: #1f1f1f;\n color: #e0e0e0;\n }\n\n .chat-sdk-container.dark .chat-sdk-header {\n background: #2d2d2d;\n }\n\n .chat-sdk-container.dark .chat-sdk-messages {\n background: #0d1117;\n }\n\n .chat-sdk-container.dark .chat-sdk-message-bubble {\n background: #2d2d2d;\n color: #e0e0e0;\n }\n\n .chat-sdk-container.dark .chat-sdk-message.own .chat-sdk-message-bubble {\n background: #0969da;\n color: white;\n }\n\n /* Image Modal Viewer */\n .chat-sdk-image-modal {\n position: fixed;\n top: 0; left: 0; right: 0; bottom: 0;\n z-index: 9999;\n opacity: 0;\n visibility: hidden;\n transition: opacity 0.2s ease, visibility 0.2s ease;\n }\n\n .chat-sdk-image-modal-open {\n opacity: 1;\n visibility: visible;\n }\n\n .chat-sdk-image-backdrop {\n position: absolute;\n top: 0; left: 0; right: 0; bottom: 0;\n background: rgba(0, 0, 0, 0.9);\n display: flex;\n align-items: center;\n justify-content: center;\n padding: 20px;\n }\n\n .chat-sdk-image-container {\n position: relative;\n max-width: 90vw;\n max-height: 90vh;\n display: flex;\n align-items: center;\n justify-content: center;\n }\n\n .chat-sdk-image-close {\n position: absolute;\n top: -50px;\n right: 0;\n background: rgba(255, 255, 255, 0.1);\n border: none;\n border-radius: 50%;\n width: 40px;\n height: 40px;\n color: white;\n cursor: pointer;\n display: flex;\n align-items: center;\n justify-content: center;\n transition: background-color 0.2s;\n z-index: 1;\n }\n\n .chat-sdk-image-close:hover {\n background: rgba(255, 255, 255, 0.2);\n }\n\n .chat-sdk-image-full {\n max-width: 100%;\n max-height: 100%;\n object-fit: contain;\n border-radius: 8px;\n box-shadow: 0 10px 30px rgba(0, 0, 0, 0.5);\n }\n\n /* Responsive Design */\n @media (max-width: 640px) {\n .chat-sdk-container {\n border-radius: 0;\n height: 100vh;\n max-height: 100vh;\n }\n\n .chat-sdk-message-content {\n max-width: 85%;\n }\n\n .chat-sdk-message-bubble {\n font-size: 14px;\n padding: 8px 12px;\n }\n\n .chat-sdk-input {\n font-size: 16px; /* Prevent zoom on iOS */\n padding: 10px 14px;\n }\n\n .chat-sdk-header {\n padding: 8px 12px;\n min-height: 50px;\n }\n\n .chat-sdk-message-avatar {\n width: 28px;\n height: 28px;\n font-size: 11px;\n }\n }\n\n @media (min-width: 1024px) {\n .chat-sdk-message-content {\n max-width: 60%;\n }\n\n .chat-sdk-send-btn:hover:not(:disabled) {\n transform: scale(1.05);\n transition: all 0.2s ease;\n }\n }\n\n /* Image Zoom Overlay */\n .chat-sdk-image-zoom-overlay {\n position: absolute;\n top: 0; left: 0; right: 0; bottom: 0;\n background: rgba(0, 0, 0, 0.85);\n z-index: 999999;\n display: flex;\n justify-content: center;\n align-items: center;\n cursor: zoom-out;\n backdrop-filter: blur(2px);\n }\n .chat-sdk-image-zoom-img {\n max-width: 95%;\n max-height: 95%;\n object-fit: contain;\n border-radius: 4px;\n box-shadow: 0 4px 12px rgba(0,0,0,0.3);\n transform: scale(0.95);\n animation: chat-sdk-zoom-in 0.2s cubic-bezier(0.1, 0.9, 0.2, 1) forwards;\n }\n @keyframes chat-sdk-zoom-in {\n to { transform: scale(1); }\n }\n\n "}startSimulation(){this.simulator.start()}stopSimulation(){this.simulator.stop()}pauseSimulation(){this.simulator.pause()}resumeSimulation(){this.simulator.resume()}async sendMessage(e,t="text"){await this.simulator.sendMessage(e,t)}get isSimulationRunning(){return this.state.isSimulationRunning}get isSimulationPaused(){return this.state.isSimulationPaused}get simulationEnded(){return this.state.simulationEnded}get messageCount(){return this.state.displayedMessageCount}get messages(){return[...this.state.messages]}async reinitializeLanguage(e){this.config.language=e,this.setLoading(!0),this.messagesContainer.innerHTML="",this.state.messages=[],this.state.displayedMessageCount=0,this.state.unreadCount=0,this.updateUnreadBadge();try{this.simulator.clearCachedProgress()}catch(e){}try{this.simulator.destroy()}catch(e){}this.simulator=new u(this.config,this.apiClient),this.setupSimulatorEvents(),await this.initializeSimulation()}destroy(){this.pollingStopTimer&&(clearTimeout(this.pollingStopTimer),this.pollingStopTimer=null);try{this.simulator.destroy()}catch(e){}if(this.shadowRoot)try{for(;this.shadowRoot.firstChild;)this.shadowRoot.removeChild(this.shadowRoot.firstChild)}catch(e){}this.state.isOpen=!1,this.removeAllListeners()}clearMessages(){this.state.messages=[],this.state.displayedMessageCount=0,this.state.unreadCount=0,this.messagesContainer.innerHTML="",this.updateUnreadBadge()}rerender(){this.reRenderAllMessages()}getMessageCount(){return this.state.displayedMessageCount}isOpen(){return this.state.isOpen}updateLanguageElements(e){var t,s,n;this.t=y(e);const i=null===(t=this.widgetElement)||void 0===t?void 0:t.querySelector("#message-input");i&&(i.placeholder=this.t.inputPlaceholder);const a=null===(s=this.widgetElement)||void 0===s?void 0:s.querySelector(".send-button");a&&a.textContent&&(a.textContent=this.t.send);const o=this.getMessageCount(),r=(null===(n=this.state.currentProject)||void 0===n?void 0:n.name)||"Chat";this.setTitle(r,`${o} ${this.t.messages}`)}}const v=f;function k(e){return new f(e)}var x={init:k,ChatSDK:v,ChatSDKError:t};"undefined"!=typeof window&&(window.ChatSDK={init:k,ChatSDK:v,ChatSDKError:t}),e.ChatSDK=v,e.ChatSDKError=t,e.default=x,e.init=k,Object.defineProperty(e,"__esModule",{value:!0})});
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"chat-simulator.d.ts","sourceRoot":"","sources":["../../../src/simulation/chat-simulator.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,WAAW,EAAE,eAAe,EAAe,MAAM,UAAU,CAAA;AACnF,OAAO,EAAE,kBAAkB,EAAE,MAAM,wBAAwB,CAAA;AAC3D,OAAO,EAAE,SAAS,EAAE,MAAM,eAAe,CAAA;AAGzC,MAAM,WAAW,cAAc;IAC7B,OAAO,EAAE;QACP,EAAE,EAAE,MAAM,CAAA;QACV,IAAI,EAAE,MAAM,CAAA;QACZ,UAAU,EAAE,MAAM,CAAA;QAClB,iBAAiB,EAAE,MAAM,CAAA;QACzB,eAAe,EAAE,MAAM,CAAA;QACvB,kBAAkB,EAAE,MAAM,CAAA;QAC1B,kBAAkB,EAAE,MAAM,CAAA;QAC1B,sBAAsB,EAAE,MAAM,CAAA;QAC9B,YAAY,CAAC,EAAE,MAAM,CAAA;QACrB,eAAe,CAAC,EAAE,MAAM,CAAA;KACzB,CAAA;IACD,QAAQ,EAAE;QACR,EAAE,EAAE,MAAM,CAAA;QACV,IAAI,EAAE,MAAM,CAAA;QACZ,QAAQ,EAAE,MAAM,CAAA;KACjB,CAAA;IACD,QAAQ,EAAE,eAAe,EAAE,CAAA;IAC3B,OAAO,EAAE;QACP,EAAE,EAAE,MAAM,CAAA;QACV,SAAS,EAAE,MAAM,CAAA;KAClB,CAAA;CACF;AAED,qBAAa,aAAc,SAAQ,kBAAkB;IACnD,OAAO,CAAC,MAAM,CAAe;IAC7B,OAAO,CAAC,SAAS,CAAW;IAC5B,OAAO,CAAC,cAAc,CAA8B;IACpD,OAAO,CAAC,iBAAiB,CAAoB;IAC7C,OAAO,CAAC,mBAAmB,CAAI;IAC/B,OAAO,CAAC,SAAS,CAAQ;IACzB,OAAO,CAAC,QAAQ,CAAQ;IACxB,OAAO,CAAC,UAAU,CAA8B;IAChD,OAAO,CAAC,SAAS,CAA8B;IAC/C,OAAO,CAAC,iBAAiB,CAAQ;IACjC,OAAO,CAAC,UAAU,CAAO;IACzB,OAAO,CAAC,WAAW,CAAW;IAE9B,OAAO,CAAC,oBAAoB,CAAoB;IAChD,OAAO,CAAC,iBAAiB,CAAoB;IAC7C,OAAO,CAAC,aAAa,CAAoB;IACzC,OAAO,CAAC,WAAW,CAAY;IAE/B,OAAO,CAAC,MAAM,CAAa;gBAEf,MAAM,EAAE,aAAa,EAAE,SAAS,EAAE,SAAS;IAUjD,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC;IAiEjC,KAAK,IAAI,IAAI;IAqBb,OAAO,CAAC,mBAAmB;
|
|
1
|
+
{"version":3,"file":"chat-simulator.d.ts","sourceRoot":"","sources":["../../../src/simulation/chat-simulator.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,WAAW,EAAE,eAAe,EAAe,MAAM,UAAU,CAAA;AACnF,OAAO,EAAE,kBAAkB,EAAE,MAAM,wBAAwB,CAAA;AAC3D,OAAO,EAAE,SAAS,EAAE,MAAM,eAAe,CAAA;AAGzC,MAAM,WAAW,cAAc;IAC7B,OAAO,EAAE;QACP,EAAE,EAAE,MAAM,CAAA;QACV,IAAI,EAAE,MAAM,CAAA;QACZ,UAAU,EAAE,MAAM,CAAA;QAClB,iBAAiB,EAAE,MAAM,CAAA;QACzB,eAAe,EAAE,MAAM,CAAA;QACvB,kBAAkB,EAAE,MAAM,CAAA;QAC1B,kBAAkB,EAAE,MAAM,CAAA;QAC1B,sBAAsB,EAAE,MAAM,CAAA;QAC9B,YAAY,CAAC,EAAE,MAAM,CAAA;QACrB,eAAe,CAAC,EAAE,MAAM,CAAA;KACzB,CAAA;IACD,QAAQ,EAAE;QACR,EAAE,EAAE,MAAM,CAAA;QACV,IAAI,EAAE,MAAM,CAAA;QACZ,QAAQ,EAAE,MAAM,CAAA;KACjB,CAAA;IACD,QAAQ,EAAE,eAAe,EAAE,CAAA;IAC3B,OAAO,EAAE;QACP,EAAE,EAAE,MAAM,CAAA;QACV,SAAS,EAAE,MAAM,CAAA;KAClB,CAAA;CACF;AAED,qBAAa,aAAc,SAAQ,kBAAkB;IACnD,OAAO,CAAC,MAAM,CAAe;IAC7B,OAAO,CAAC,SAAS,CAAW;IAC5B,OAAO,CAAC,cAAc,CAA8B;IACpD,OAAO,CAAC,iBAAiB,CAAoB;IAC7C,OAAO,CAAC,mBAAmB,CAAI;IAC/B,OAAO,CAAC,SAAS,CAAQ;IACzB,OAAO,CAAC,QAAQ,CAAQ;IACxB,OAAO,CAAC,UAAU,CAA8B;IAChD,OAAO,CAAC,SAAS,CAA8B;IAC/C,OAAO,CAAC,iBAAiB,CAAQ;IACjC,OAAO,CAAC,UAAU,CAAO;IACzB,OAAO,CAAC,WAAW,CAAW;IAE9B,OAAO,CAAC,oBAAoB,CAAoB;IAChD,OAAO,CAAC,iBAAiB,CAAoB;IAC7C,OAAO,CAAC,aAAa,CAAoB;IACzC,OAAO,CAAC,WAAW,CAAY;IAE/B,OAAO,CAAC,MAAM,CAAa;gBAEf,MAAM,EAAE,aAAa,EAAE,SAAS,EAAE,SAAS;IAUjD,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC;IAiEjC,KAAK,IAAI,IAAI;IAqBb,OAAO,CAAC,mBAAmB;IAqH3B,KAAK,IAAI,IAAI;IAWb,MAAM,IAAI,IAAI;IAQd,IAAI,IAAI,IAAI;IAYZ,OAAO,IAAI,IAAI;IAMf,OAAO,CAAC,mBAAmB;IA+C3B,OAAO,CAAC,kBAAkB;YA4EZ,oBAAoB;IAgE3B,YAAY,IAAI,IAAI;IAWpB,WAAW,IAAI,IAAI;IAOnB,kBAAkB,CAAC,EAAE,EAAE,MAAM,GAAG,IAAI;IAS3C,IAAW,SAAS,IAAI,OAAO,CAE9B;YAEa,kBAAkB;YAwDlB,mCAAmC;IAyIjD,OAAO,CAAC,uBAAuB;IAO/B,OAAO,CAAC,UAAU;IAGlB,OAAO,CAAC,cAAc;IAItB,OAAO,CAAC,kBAAkB;IAM1B,OAAO,CAAC,aAAa;IAMrB,OAAO,CAAC,YAAY;IAQpB,OAAO,CAAC,YAAY;IAuBpB,OAAO,CAAC,aAAa;IAQrB,mBAAmB,IAAI,IAAI;IAK3B;;;OAGG;IACH,OAAO,CAAC,eAAe;IAOvB,OAAO,CAAC,iBAAiB;IAIzB,OAAO,CAAC,cAAc;IAKtB,IAAI,QAAQ,IAAI,WAAW,EAAE,CAE5B;IAED,IAAI,mBAAmB,IAAI,OAAO,CAEjC;IAED,IAAI,kBAAkB,IAAI,OAAO,CAEhC;IAED,IAAI,IAAI,IAAI,cAAc,GAAG,IAAI,CAEhC;IAGK,WAAW,CAAC,OAAO,EAAE,MAAM,EAAE,WAAW,GAAE,MAAe,GAAG,OAAO,CAAC,IAAI,CAAC;CAwChF"}
|
package/dist/types/types.d.ts
CHANGED
|
@@ -74,13 +74,14 @@ export interface ChatSDKConfig {
|
|
|
74
74
|
export interface ChatMessage {
|
|
75
75
|
id: string;
|
|
76
76
|
content: string;
|
|
77
|
-
messageType: 'text' | 'image' | 'emoji' | 'file';
|
|
77
|
+
messageType: 'text' | 'image' | 'emoji' | 'file' | 'audio';
|
|
78
78
|
timestamp: Date;
|
|
79
79
|
isOwnMessage: boolean;
|
|
80
80
|
virtualUser?: VirtualUser;
|
|
81
81
|
user?: RealUser;
|
|
82
82
|
hasScreenshot?: boolean;
|
|
83
83
|
screenshotUrl?: string;
|
|
84
|
+
audioUrl?: string;
|
|
84
85
|
failed?: boolean;
|
|
85
86
|
}
|
|
86
87
|
export interface VirtualUser {
|
|
@@ -113,11 +114,12 @@ export interface Template {
|
|
|
113
114
|
export interface TemplateMessage {
|
|
114
115
|
id: string;
|
|
115
116
|
content: string;
|
|
116
|
-
messageType: 'text' | 'image' | 'file';
|
|
117
|
+
messageType: 'text' | 'image' | 'file' | 'audio';
|
|
117
118
|
order: number;
|
|
118
119
|
delay?: number;
|
|
119
120
|
hasScreenshot: boolean;
|
|
120
121
|
screenshotUrl?: string;
|
|
122
|
+
audioUrl?: string;
|
|
121
123
|
virtualUser?: VirtualUser;
|
|
122
124
|
translations?: Record<string, string>;
|
|
123
125
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/types.ts"],"names":[],"mappings":"AACA,MAAM,WAAW,oBAAoB;IACnC,GAAG,CAAC,EAAE,MAAM,CAAA;IACZ,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,IAAI,CAAC,EAAE,MAAM,CAAA;CACd;AAED,MAAM,MAAM,sBAAsB,GAAG,cAAc,GAAG,aAAa,GAAG,WAAW,GAAG,UAAU,CAAA;AAE9F,MAAM,WAAW,oBAAoB;IACnC,QAAQ,CAAC,EAAE,sBAAsB,CAAA;IACjC,MAAM,CAAC,EAAE,oBAAoB,CAAA;IAC7B,IAAI,CAAC,EAAE,MAAM,GAAG,MAAM,CAAA;IACtB,MAAM,CAAC,EAAE,MAAM,CAAA;CAChB;AAED,MAAM,WAAW,aAAa;IAE5B,SAAS,EAAE,MAAM,GAAG,WAAW,CAAA;IAC/B,SAAS,EAAE,MAAM,CAAA;IAGjB,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,KAAK,CAAC,EAAE,OAAO,GAAG,MAAM,GAAG,MAAM,CAAA;IACjC,UAAU,CAAC,EAAE,UAAU,GAAG,UAAU,CAAA;IAGpC,YAAY,CAAC,EAAE,MAAM,CAAA;IACrB,eAAe,CAAC,EAAE,MAAM,CAAA;IACxB,WAAW,CAAC,EAAE;QACZ,MAAM,CAAC,EAAE;YACP,OAAO,CAAC,EAAE,MAAM,CAAA;YAChB,UAAU,CAAC,EAAE,MAAM,CAAA;YACnB,UAAU,CAAC,EAAE,MAAM,CAAA;YACnB,YAAY,CAAC,EAAE,MAAM,CAAA;YACrB,MAAM,CAAC,EAAE,MAAM,CAAA;SAChB,CAAA;QACD,YAAY,CAAC,EAAE;YACb,OAAO,CAAC,EAAE,MAAM,CAAA;YAChB,KAAK,CAAC,EAAE,MAAM,CAAA;SACf,CAAA;KACF,CAAA;IAGD,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,KAAK,CAAC,EAAE,MAAM,CAAA;IAGd,KAAK,CAAC,EAAE,MAAM,GAAG,MAAM,CAAA;IACvB,MAAM,CAAC,EAAE,MAAM,GAAG,MAAM,CAAA;IACxB,QAAQ,CAAC,EAAE,OAAO,GAAG,UAAU,GAAG,UAAU,CAAA;IAC5C,MAAM,CAAC,EAAE,MAAM,CAAA;IAGf,IAAI,CAAC,EAAE,YAAY,GAAG,UAAU,CAAA;IAChC,cAAc,CAAC,EAAE,oBAAoB,CAAA;IAGrC,QAAQ,CAAC,EAAE,OAAO,CAAA;IAClB,SAAS,CAAC,EAAE,OAAO,CAAA;IACnB,WAAW,CAAC,EAAE,OAAO,CAAA;IACrB,aAAa,CAAC,EAAE,OAAO,CAAA;IACvB,UAAU,CAAC,EAAE,OAAO,CAAA;IACpB,eAAe,CAAC,EAAE,OAAO,CAAA;IACzB,eAAe,CAAC,EAAE,MAAM,CAAA;IAIxB,kBAAkB,CAAC,EAAE,MAAM,CAAA;IAC3B,iBAAiB,CAAC,EAAE,MAAM,CAAA;IAG1B,aAAa,CAAC,EAAE,OAAO,CAAA;IACvB,qBAAqB,CAAC,EAAE,MAAM,CAAA;IAG9B,OAAO,CAAC,EAAE,MAAM,IAAI,CAAA;IACpB,MAAM,CAAC,EAAE,MAAM,IAAI,CAAA;IACnB,OAAO,CAAC,EAAE,MAAM,IAAI,CAAA;IACpB,MAAM,CAAC,EAAE,CAAC,IAAI,EAAE;QAAE,MAAM,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,MAAM,CAAA;KAAE,KAAK,IAAI,CAAA;IAC7D,SAAS,CAAC,EAAE,CAAC,OAAO,EAAE,WAAW,KAAK,IAAI,CAAA;IAC1C,aAAa,CAAC,EAAE,CAAC,OAAO,EAAE,WAAW,KAAK,IAAI,CAAA;IAC9C,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,KAAK,KAAK,IAAI,CAAA;IAChC,gBAAgB,CAAC,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,IAAI,CAAA;IAC7C,aAAa,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAA;IACvC,iBAAiB,CAAC,EAAE,MAAM,IAAI,CAAA;IAC9B,eAAe,CAAC,EAAE,MAAM,IAAI,CAAA;CAC7B;AAGD,MAAM,WAAW,WAAW;IAC1B,EAAE,EAAE,MAAM,CAAA;IACV,OAAO,EAAE,MAAM,CAAA;IACf,WAAW,EAAE,MAAM,GAAG,OAAO,GAAG,OAAO,GAAG,MAAM,CAAA;
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/types.ts"],"names":[],"mappings":"AACA,MAAM,WAAW,oBAAoB;IACnC,GAAG,CAAC,EAAE,MAAM,CAAA;IACZ,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,IAAI,CAAC,EAAE,MAAM,CAAA;CACd;AAED,MAAM,MAAM,sBAAsB,GAAG,cAAc,GAAG,aAAa,GAAG,WAAW,GAAG,UAAU,CAAA;AAE9F,MAAM,WAAW,oBAAoB;IACnC,QAAQ,CAAC,EAAE,sBAAsB,CAAA;IACjC,MAAM,CAAC,EAAE,oBAAoB,CAAA;IAC7B,IAAI,CAAC,EAAE,MAAM,GAAG,MAAM,CAAA;IACtB,MAAM,CAAC,EAAE,MAAM,CAAA;CAChB;AAED,MAAM,WAAW,aAAa;IAE5B,SAAS,EAAE,MAAM,GAAG,WAAW,CAAA;IAC/B,SAAS,EAAE,MAAM,CAAA;IAGjB,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,KAAK,CAAC,EAAE,OAAO,GAAG,MAAM,GAAG,MAAM,CAAA;IACjC,UAAU,CAAC,EAAE,UAAU,GAAG,UAAU,CAAA;IAGpC,YAAY,CAAC,EAAE,MAAM,CAAA;IACrB,eAAe,CAAC,EAAE,MAAM,CAAA;IACxB,WAAW,CAAC,EAAE;QACZ,MAAM,CAAC,EAAE;YACP,OAAO,CAAC,EAAE,MAAM,CAAA;YAChB,UAAU,CAAC,EAAE,MAAM,CAAA;YACnB,UAAU,CAAC,EAAE,MAAM,CAAA;YACnB,YAAY,CAAC,EAAE,MAAM,CAAA;YACrB,MAAM,CAAC,EAAE,MAAM,CAAA;SAChB,CAAA;QACD,YAAY,CAAC,EAAE;YACb,OAAO,CAAC,EAAE,MAAM,CAAA;YAChB,KAAK,CAAC,EAAE,MAAM,CAAA;SACf,CAAA;KACF,CAAA;IAGD,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,KAAK,CAAC,EAAE,MAAM,CAAA;IAGd,KAAK,CAAC,EAAE,MAAM,GAAG,MAAM,CAAA;IACvB,MAAM,CAAC,EAAE,MAAM,GAAG,MAAM,CAAA;IACxB,QAAQ,CAAC,EAAE,OAAO,GAAG,UAAU,GAAG,UAAU,CAAA;IAC5C,MAAM,CAAC,EAAE,MAAM,CAAA;IAGf,IAAI,CAAC,EAAE,YAAY,GAAG,UAAU,CAAA;IAChC,cAAc,CAAC,EAAE,oBAAoB,CAAA;IAGrC,QAAQ,CAAC,EAAE,OAAO,CAAA;IAClB,SAAS,CAAC,EAAE,OAAO,CAAA;IACnB,WAAW,CAAC,EAAE,OAAO,CAAA;IACrB,aAAa,CAAC,EAAE,OAAO,CAAA;IACvB,UAAU,CAAC,EAAE,OAAO,CAAA;IACpB,eAAe,CAAC,EAAE,OAAO,CAAA;IACzB,eAAe,CAAC,EAAE,MAAM,CAAA;IAIxB,kBAAkB,CAAC,EAAE,MAAM,CAAA;IAC3B,iBAAiB,CAAC,EAAE,MAAM,CAAA;IAG1B,aAAa,CAAC,EAAE,OAAO,CAAA;IACvB,qBAAqB,CAAC,EAAE,MAAM,CAAA;IAG9B,OAAO,CAAC,EAAE,MAAM,IAAI,CAAA;IACpB,MAAM,CAAC,EAAE,MAAM,IAAI,CAAA;IACnB,OAAO,CAAC,EAAE,MAAM,IAAI,CAAA;IACpB,MAAM,CAAC,EAAE,CAAC,IAAI,EAAE;QAAE,MAAM,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,MAAM,CAAA;KAAE,KAAK,IAAI,CAAA;IAC7D,SAAS,CAAC,EAAE,CAAC,OAAO,EAAE,WAAW,KAAK,IAAI,CAAA;IAC1C,aAAa,CAAC,EAAE,CAAC,OAAO,EAAE,WAAW,KAAK,IAAI,CAAA;IAC9C,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,KAAK,KAAK,IAAI,CAAA;IAChC,gBAAgB,CAAC,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,IAAI,CAAA;IAC7C,aAAa,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAA;IACvC,iBAAiB,CAAC,EAAE,MAAM,IAAI,CAAA;IAC9B,eAAe,CAAC,EAAE,MAAM,IAAI,CAAA;CAC7B;AAGD,MAAM,WAAW,WAAW;IAC1B,EAAE,EAAE,MAAM,CAAA;IACV,OAAO,EAAE,MAAM,CAAA;IACf,WAAW,EAAE,MAAM,GAAG,OAAO,GAAG,OAAO,GAAG,MAAM,GAAG,OAAO,CAAA;IAC1D,SAAS,EAAE,IAAI,CAAA;IACf,YAAY,EAAE,OAAO,CAAA;IACrB,WAAW,CAAC,EAAE,WAAW,CAAA;IACzB,IAAI,CAAC,EAAE,QAAQ,CAAA;IACf,aAAa,CAAC,EAAE,OAAO,CAAA;IACvB,aAAa,CAAC,EAAE,MAAM,CAAA;IACtB,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,MAAM,CAAC,EAAE,OAAO,CAAA;CACjB;AAED,MAAM,WAAW,WAAW;IAC1B,EAAE,EAAE,MAAM,CAAA;IACV,QAAQ,EAAE,MAAM,CAAA;IAChB,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,MAAM,CAAC,EAAE,MAAM,CAAA;CAChB;AAED,MAAM,WAAW,QAAQ;IACvB,EAAE,EAAE,MAAM,CAAA;IACV,QAAQ,EAAE,MAAM,CAAA;IAChB,MAAM,CAAC,EAAE,MAAM,CAAA;CAChB;AAGD,MAAM,WAAW,OAAO;IACtB,EAAE,EAAE,MAAM,CAAA;IACV,IAAI,EAAE,MAAM,CAAA;IACZ,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,UAAU,EAAE,MAAM,CAAA;IAClB,QAAQ,EAAE,MAAM,CAAA;IAChB,QAAQ,EAAE,OAAO,CAAA;IACjB,SAAS,CAAC,EAAE,QAAQ,EAAE,CAAA;CACvB;AAED,MAAM,WAAW,QAAQ;IACvB,EAAE,EAAE,MAAM,CAAA;IACV,IAAI,EAAE,MAAM,CAAA;IACZ,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,QAAQ,EAAE,MAAM,CAAA;IAChB,QAAQ,EAAE,eAAe,EAAE,CAAA;CAC5B;AAED,MAAM,WAAW,eAAe;IAC9B,EAAE,EAAE,MAAM,CAAA;IACV,OAAO,EAAE,MAAM,CAAA;IACf,WAAW,EAAE,MAAM,GAAG,OAAO,GAAG,MAAM,GAAG,OAAO,CAAA;IAChD,KAAK,EAAE,MAAM,CAAA;IACb,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,aAAa,EAAE,OAAO,CAAA;IACtB,aAAa,CAAC,EAAE,MAAM,CAAA;IACtB,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,WAAW,CAAC,EAAE,WAAW,CAAA;IACzB,YAAY,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;CACtC;AAGD,MAAM,WAAW,eAAe;IAE9B,IAAI,IAAI,IAAI,CAAA;IACZ,KAAK,IAAI,IAAI,CAAA;IACb,OAAO,IAAI,IAAI,CAAA;IAGf,WAAW,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAA;IAC5C,QAAQ,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,GAAG,MAAM,GAAG,IAAI,CAAA;IAChD,WAAW,CAAC,UAAU,EAAE,MAAM,GAAG,IAAI,CAAA;IACrC,aAAa,CAAC,QAAQ,EAAE,UAAU,GAAG,UAAU,GAAG,IAAI,CAAA;IACtD,eAAe,CAAC,MAAM,EAAE;QAAE,OAAO,CAAC,EAAE,MAAM,CAAC;QAAC,UAAU,CAAC,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI,CAAA;IAGxE,QAAQ,IAAI,IAAI,CAAA;IAChB,SAAS,IAAI,IAAI,CAAA;IACjB,WAAW,CAAC,OAAO,EAAE,MAAM,EAAE,WAAW,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IAGxD,eAAe,IAAI,IAAI,CAAA;IACvB,cAAc,IAAI,IAAI,CAAA;IACtB,eAAe,IAAI,IAAI,CAAA;IACvB,gBAAgB,IAAI,IAAI,CAAA;IACxB,WAAW,CAAC,OAAO,EAAE,MAAM,EAAE,WAAW,CAAC,EAAE,MAAM,GAAG,OAAO,GAAG,OAAO,GAAG,MAAM,GAAG,IAAI,CAAA;IAGrF,MAAM,IAAI,OAAO,CAAA;IACjB,QAAQ,IAAI,OAAO,CAAA;IACnB,SAAS,IAAI,aAAa,CAAA;IAC1B,WAAW,IAAI,WAAW,EAAE,CAAA;IAG5B,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,QAAQ,GAAG,IAAI,CAAA;IAC3C,GAAG,CAAC,KAAK,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,QAAQ,GAAG,IAAI,CAAA;IAC7C,IAAI,CAAC,KAAK,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,GAAG,GAAG,IAAI,CAAA;CACtC;AAGD,MAAM,WAAW,SAAS;IACxB,aAAa,EAAE,OAAO,CAAA;IACtB,MAAM,EAAE,OAAO,CAAA;IACf,QAAQ,EAAE,OAAO,CAAA;IACjB,WAAW,EAAE,OAAO,CAAA;IACpB,mBAAmB,EAAE,OAAO,CAAA;IAC5B,kBAAkB,EAAE,OAAO,CAAA;IAC3B,cAAc,CAAC,EAAE,OAAO,CAAA;IACxB,eAAe,CAAC,EAAE,QAAQ,CAAA;IAC1B,QAAQ,EAAE,WAAW,EAAE,CAAA;IACvB,YAAY,EAAE,WAAW,EAAE,CAAA;IAC3B,SAAS,EAAE,QAAQ,EAAE,CAAA;IACrB,WAAW,EAAE,MAAM,EAAE,CAAA;IACrB,eAAe,EAAE,OAAO,CAAA;IACxB,oBAAoB,CAAC,EAAE,MAAM,CAAA;IAC7B,qBAAqB,EAAE,MAAM,CAAA;IAC7B,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,WAAW,EAAE,MAAM,CAAA;IACnB,iBAAiB,EAAE,MAAM,GAAG,IAAI,CAAA;CACjC;AAGD,MAAM,WAAW,WAAW,CAAC,CAAC,GAAG,GAAG;IAClC,OAAO,EAAE,OAAO,CAAA;IAChB,IAAI,CAAC,EAAE,CAAC,CAAA;IACR,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,KAAK,CAAC,EAAE,MAAM,CAAA;CACf;AAED,MAAM,WAAW,eAAgB,SAAQ,WAAW;IAClD,OAAO,EAAE,OAAO,CAAA;CACjB;AAED,MAAM,WAAW,gBAAiB,SAAQ,WAAW;IACnD,QAAQ,EAAE,QAAQ,CAAA;IAClB,kBAAkB,CAAC,EAAE,MAAM,EAAE,CAAA;IAC7B,gBAAgB,CAAC,EAAE,MAAM,CAAA;CAC1B;AAGD,MAAM,WAAW,YAAY;IAC3B,aAAa,EAAE,CAAC,IAAI,EAAE;QAAE,MAAM,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,MAAM,CAAC;QAAC,SAAS,EAAE,MAAM,CAAA;KAAE,KAAK,IAAI,CAAA;IACtF,WAAW,EAAE,CAAC,IAAI,EAAE;QAAE,MAAM,EAAE,MAAM,CAAC;QAAC,SAAS,EAAE,MAAM,CAAA;KAAE,KAAK,IAAI,CAAA;IAClE,aAAa,EAAE,CAAC,OAAO,EAAE,WAAW,KAAK,IAAI,CAAA;IAC7C,aAAa,EAAE,CAAC,IAAI,EAAE;QAAE,MAAM,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,MAAM,CAAC;QAAC,SAAS,EAAE,MAAM,CAAA;KAAE,KAAK,IAAI,CAAA;IACtF,qBAAqB,EAAE,CAAC,IAAI,EAAE;QAAE,MAAM,EAAE,MAAM,CAAC;QAAC,SAAS,EAAE,MAAM,CAAA;KAAE,KAAK,IAAI,CAAA;IAC5E,kBAAkB,EAAE,CAAC,IAAI,EAAE;QAAE,SAAS,EAAE,MAAM,CAAA;KAAE,KAAK,IAAI,CAAA;CAC1D;AAGD,qBAAa,YAAa,SAAQ,KAAK;IAG5B,IAAI,CAAC,EAAE,MAAM;IACb,OAAO,CAAC,EAAE,GAAG;gBAFpB,OAAO,EAAE,MAAM,EACR,IAAI,CAAC,EAAE,MAAM,YAAA,EACb,OAAO,CAAC,EAAE,GAAG,YAAA;CAKvB;AAGD,MAAM,WAAW,YAAY;IAC3B,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,QAAQ,GAAG,IAAI,CAAA;IAC3C,GAAG,CAAC,KAAK,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,QAAQ,GAAG,IAAI,CAAA;IAC7C,IAAI,CAAC,KAAK,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,GAAG,GAAG,IAAI,CAAA;CACtC"}
|
|
@@ -65,6 +65,11 @@ export declare class ChatWidget extends SimpleEventEmitter {
|
|
|
65
65
|
private createMessageContent;
|
|
66
66
|
private scrollToBottom;
|
|
67
67
|
private setupImageViewer;
|
|
68
|
+
private currentAudio;
|
|
69
|
+
private currentVoiceContainer;
|
|
70
|
+
private handleVoicePlay;
|
|
71
|
+
private resetVoiceUI;
|
|
72
|
+
private formatAudioDuration;
|
|
68
73
|
private openImageViewer;
|
|
69
74
|
private showImagePreview;
|
|
70
75
|
setJoined(joined: boolean): void;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"chat-widget.d.ts","sourceRoot":"","sources":["../../../src/ui/chat-widget.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,aAAa,EACb,WAAW,EACX,SAAS,EAIV,MAAM,UAAU,CAAA;AACjB,OAAO,EAAE,kBAAkB,EAAE,MAAM,wBAAwB,CAAA;AAiB3D,qBAAa,UAAW,SAAQ,kBAAkB;IAChD,OAAO,CAAC,MAAM,CAAe;IAC7B,OAAO,CAAC,SAAS,CAAc;IAC/B,OAAO,CAAC,UAAU,CAAa;IAC/B,OAAO,CAAC,aAAa,CAAc;IACnC,OAAO,CAAC,iBAAiB,CAAc;IACvC,OAAO,CAAC,YAAY,CAAsB;IAC1C,OAAO,CAAC,UAAU,CAAoB;IACtC,OAAO,CAAC,WAAW,CAAoB;IACvC,OAAO,CAAC,WAAW,CAAoB;IACvC,OAAO,CAAC,SAAS,CAAmB;IACpC,OAAO,CAAC,WAAW,CAAc;IACjC,OAAO,CAAC,cAAc,CAAiB;IACvC,OAAO,CAAC,KAAK,CAAW;IACxB,OAAO,CAAC,SAAS,CAAe;IAChC,OAAO,CAAC,SAAS,CAAW;IAC5B,OAAO,CAAC,WAAW,CAAY;IAG/B,OAAO,CAAC,gBAAgB,CAAC,CAAmB;IAG5C,OAAO,CAAC,YAAY,CAAsC;IAC1D,OAAO,CAAC,UAAU,CAAiB;IACnC,OAAO,CAAC,YAAY,CAAgD;IAGpE,OAAO,CAAC,iBAAiB,CAAY;IACrC,OAAO,CAAC,kBAAkB,CAAQ;IAClC,OAAO,CAAC,iBAAiB,CAAQ;IAGjC,OAAO,CAAC,kBAAkB,CAAiB;IAG3C,OAAO,CAAC,gBAAgB,CAA8B;IAGtD,OAAO,CAAC,CAAC,CAAa;gBAEV,MAAM,EAAE,aAAa;IA8CjC,OAAO,CAAC,IAAI;IA4BZ,OAAO,CAAC,oBAAoB;YAgEd,oBAAoB;IAYlC,OAAO,CAAC,cAAc;IAmCtB,OAAO,CAAC,YAAY;IA+FpB,OAAO,CAAC,mBAAmB;IAsE3B,OAAO,CAAC,aAAa;IAsDrB,OAAO,CAAC,oBAAoB;IAkI5B,OAAO,CAAC,iBAAiB;IAgBzB,OAAO,CAAC,aAAa;IAUrB,OAAO,CAAC,oBAAoB;IAS5B,OAAO,CAAC,iBAAiB;IASzB,OAAO,CAAC,mBAAmB;IAe3B,OAAO,CAAC,WAAW;YAuBL,mBAAmB;IAiCjC,OAAO,CAAC,eAAe;IAkCvB,OAAO,CAAC,iBAAiB;IAWzB,OAAO,CAAC,aAAa;YAOP,iBAAiB;IA2C/B,OAAO,CAAC,kBAAkB;IAM1B,IAAI,IAAI,IAAI;IAuDZ,KAAK,IAAI,IAAI;IA4Bb,QAAQ,CAAC,KAAK,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,MAAM,GAAG,IAAI;IAwBhD,OAAO,CAAC,mBAAmB;IAkC3B,OAAO,CAAC,mBAAmB;IAgB3B,OAAO,CAAC,oBAAoB;IAwB5B,UAAU,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI;IAoBlC,eAAe,IAAI,IAAI;IAqBvB,eAAe,IAAI,IAAI;IAOvB,UAAU,CAAC,OAAO,EAAE,WAAW,GAAG,IAAI;IAmCtC,eAAe,CAAC,QAAQ,EAAE,WAAW,EAAE,GAAG,IAAI;IAyD9C,OAAO,CAAC,mBAAmB;IAgB3B,OAAO,CAAC,aAAa;IAOrB,OAAO,CAAC,YAAY;IAmBpB,OAAO,CAAC,oBAAoB;
|
|
1
|
+
{"version":3,"file":"chat-widget.d.ts","sourceRoot":"","sources":["../../../src/ui/chat-widget.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,aAAa,EACb,WAAW,EACX,SAAS,EAIV,MAAM,UAAU,CAAA;AACjB,OAAO,EAAE,kBAAkB,EAAE,MAAM,wBAAwB,CAAA;AAiB3D,qBAAa,UAAW,SAAQ,kBAAkB;IAChD,OAAO,CAAC,MAAM,CAAe;IAC7B,OAAO,CAAC,SAAS,CAAc;IAC/B,OAAO,CAAC,UAAU,CAAa;IAC/B,OAAO,CAAC,aAAa,CAAc;IACnC,OAAO,CAAC,iBAAiB,CAAc;IACvC,OAAO,CAAC,YAAY,CAAsB;IAC1C,OAAO,CAAC,UAAU,CAAoB;IACtC,OAAO,CAAC,WAAW,CAAoB;IACvC,OAAO,CAAC,WAAW,CAAoB;IACvC,OAAO,CAAC,SAAS,CAAmB;IACpC,OAAO,CAAC,WAAW,CAAc;IACjC,OAAO,CAAC,cAAc,CAAiB;IACvC,OAAO,CAAC,KAAK,CAAW;IACxB,OAAO,CAAC,SAAS,CAAe;IAChC,OAAO,CAAC,SAAS,CAAW;IAC5B,OAAO,CAAC,WAAW,CAAY;IAG/B,OAAO,CAAC,gBAAgB,CAAC,CAAmB;IAG5C,OAAO,CAAC,YAAY,CAAsC;IAC1D,OAAO,CAAC,UAAU,CAAiB;IACnC,OAAO,CAAC,YAAY,CAAgD;IAGpE,OAAO,CAAC,iBAAiB,CAAY;IACrC,OAAO,CAAC,kBAAkB,CAAQ;IAClC,OAAO,CAAC,iBAAiB,CAAQ;IAGjC,OAAO,CAAC,kBAAkB,CAAiB;IAG3C,OAAO,CAAC,gBAAgB,CAA8B;IAGtD,OAAO,CAAC,CAAC,CAAa;gBAEV,MAAM,EAAE,aAAa;IA8CjC,OAAO,CAAC,IAAI;IA4BZ,OAAO,CAAC,oBAAoB;YAgEd,oBAAoB;IAYlC,OAAO,CAAC,cAAc;IAmCtB,OAAO,CAAC,YAAY;IA+FpB,OAAO,CAAC,mBAAmB;IAsE3B,OAAO,CAAC,aAAa;IAsDrB,OAAO,CAAC,oBAAoB;IAkI5B,OAAO,CAAC,iBAAiB;IAgBzB,OAAO,CAAC,aAAa;IAUrB,OAAO,CAAC,oBAAoB;IAS5B,OAAO,CAAC,iBAAiB;IASzB,OAAO,CAAC,mBAAmB;IAe3B,OAAO,CAAC,WAAW;YAuBL,mBAAmB;IAiCjC,OAAO,CAAC,eAAe;IAkCvB,OAAO,CAAC,iBAAiB;IAWzB,OAAO,CAAC,aAAa;YAOP,iBAAiB;IA2C/B,OAAO,CAAC,kBAAkB;IAM1B,IAAI,IAAI,IAAI;IAuDZ,KAAK,IAAI,IAAI;IA4Bb,QAAQ,CAAC,KAAK,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,MAAM,GAAG,IAAI;IAwBhD,OAAO,CAAC,mBAAmB;IAkC3B,OAAO,CAAC,mBAAmB;IAgB3B,OAAO,CAAC,oBAAoB;IAwB5B,UAAU,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI;IAoBlC,eAAe,IAAI,IAAI;IAqBvB,eAAe,IAAI,IAAI;IAOvB,UAAU,CAAC,OAAO,EAAE,WAAW,GAAG,IAAI;IAmCtC,eAAe,CAAC,QAAQ,EAAE,WAAW,EAAE,GAAG,IAAI;IAyD9C,OAAO,CAAC,mBAAmB;IAgB3B,OAAO,CAAC,aAAa;IAOrB,OAAO,CAAC,YAAY;IAmBpB,OAAO,CAAC,oBAAoB;IA2F5B,OAAO,CAAC,cAAc;IAYtB,OAAO,CAAC,gBAAgB;IA8BxB,OAAO,CAAC,YAAY,CAAgC;IACpD,OAAO,CAAC,qBAAqB,CAA2B;IAExD,OAAO,CAAC,eAAe;IA8DvB,OAAO,CAAC,YAAY;IAiBpB,OAAO,CAAC,mBAAmB;IAO3B,OAAO,CAAC,eAAe;IAgFvB,OAAO,CAAC,gBAAgB;IAwCxB,SAAS,CAAC,MAAM,EAAE,OAAO,GAAG,IAAI;IAMhC,aAAa,CAAC,QAAQ,EAAE,UAAU,GAAG,UAAU,GAAG,IAAI;IAsBtD,QAAQ,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,GAAG,IAAI;IAevC,eAAe,CAAC,MAAM,EAAE;QAAE,OAAO,CAAC,EAAE,MAAM,CAAC;QAAC,UAAU,CAAC,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI;IAOxE,OAAO,CAAC,iBAAiB;IAgCzB,OAAO,CAAC,cAAc;IA8BtB,QAAQ,IAAI,SAAS;IAIrB,OAAO,CAAC,gBAAgB;IAqxBxB,eAAe,IAAI,IAAI;IAIvB,cAAc,IAAI,IAAI;IAItB,eAAe,IAAI,IAAI;IAIvB,gBAAgB,IAAI,IAAI;IAIlB,WAAW,CAAC,OAAO,EAAE,MAAM,EAAE,WAAW,GAAE,MAAe,GAAG,OAAO,CAAC,IAAI,CAAC;IAK/E,IAAI,mBAAmB,IAAI,OAAO,CAEjC;IAED,IAAI,kBAAkB,IAAI,OAAO,CAEhC;IAED,IAAI,eAAe,IAAI,OAAO,CAE7B;IAED,IAAI,YAAY,IAAI,MAAM,CAEzB;IAED,IAAI,QAAQ,IAAI,WAAW,EAAE,CAE5B;IAEK,oBAAoB,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAqC3D,OAAO,IAAI,IAAI;IAwBf,aAAa,IAAI,IAAI;IAQrB,QAAQ,IAAI,IAAI;IAIhB,eAAe,IAAI,MAAM;IAIzB,MAAM,IAAI,OAAO;IAIjB,sBAAsB,CAAC,QAAQ,EAAE,MAAM,GAAG,IAAI;CAqB/C"}
|
package/package.json
CHANGED