var chatbox=document.getElementById("chatbox"),botchat=document.getElementById("botchat"),chatheader=document.getElementById("chatheader"),expandButton=chatheader.querySelector(".expand"),chatHeaderName=document.getElementById("chatheader-name"),chatHeaderPhoto=document.getElementById("chatheader-photo"),currentAgentName=(chatHeaderName?.textContent||"").trim(),newChatButton=document.getElementById("newChatButton"),chatUploadButton=document.getElementById("chatUploadButton"),chatFileInput=document.getElementById("chatFileInput"),chatEmojiButton=document.getElementById("chatEmojiButton"),chatEmojiPicker=document.getElementById("chatEmojiPicker"),chatMessagesHydrated=!1,pendingNewChat=!1,currentChatSessionId="",agentImageRenderDelayMs=450,serverInputEnabled=!1,preserveChoicesOnSelect=new Set,chatDingAudio=new Audio("https://cdn.lennontree.net/dropbox/cdn/chat/chat-ding.wav"),pendingSentMessages=new Map,SEND_ACK_TIMEOUT_MS=8e3,chatEmojiList=["๐Ÿ˜Š","๐Ÿ˜„","๐Ÿ˜ƒ","๐Ÿ˜","๐Ÿ˜‚","๐Ÿคฃ","๐Ÿ™‚","๐Ÿ˜‰","๐Ÿ˜","๐Ÿคฉ","๐Ÿ˜Ž","๐Ÿค”","๐Ÿ˜ฎ","๐Ÿ˜ข","๐Ÿ™","๐Ÿ‘","๐Ÿ‘Ž","๐Ÿ‘","๐Ÿ‘‹","โค๏ธ","๐Ÿ’™","๐Ÿ’š","๐Ÿ’›","๐Ÿงก","๐Ÿ”ฅ","โœจ","โœ…","โŒ","โš ๏ธ","โ›บ","๐Ÿ•๏ธ","๐Ÿท๏ธ","๐Ÿ› ๏ธ","๐Ÿ”ง","๐Ÿงต","๐Ÿ“","๐ŸŽจ","๐Ÿ–จ๏ธ","๐ŸŽ‰","๐ŸŽˆ","๐ŸŽช","๐ŸŽŠ","๐Ÿป","๐Ÿฝ๏ธ","๐ŸŒง๏ธ","โ˜”","๐ŸŒฆ๏ธ","โ˜€๏ธ","๐ŸŒค๏ธ","๐Ÿ’จ","โ„๏ธ","๐Ÿ“ฆ","๐Ÿšš","๐Ÿ“","๐Ÿ—บ๏ธ","๐Ÿ“ธ","๐Ÿ’ฌ","๐Ÿ“ž","๐Ÿ“ง","๐Ÿงพ","๐Ÿ“…","โฑ๏ธ","๐Ÿ’ท","๐Ÿ’ณ"];function escapeHtml(e){return String(null==e?"":e).replace(/&/g,"&").replace(//g,">").replace(/"/g,""").replace(/'/g,"'")}function toSafeMessageHtml(e){let t=escapeHtml(String(null==e?"":e));return t=t.replace(/รฃโ‚ฌย\d+:\d+รขโ‚ฌย sourceรฃโ‚ฌโ€˜/g,""),t=t.replace(/(^|[\s(])(https?:\/\/[^\s)<>]+)/g,'$1$2'),t.replace(/\n/g,"
")}function getChatCookieValue(e){const t=`; ${document.cookie||""}`.split(`; ${e}=`);return 2===t.length?decodeURIComponent(t.pop().split(";").shift()||""):""}function setInputVisible(e){const t=document.querySelector("#chatbox #input");t&&(e?t.classList.remove("hide"):t.classList.add("hide"))}function resetMessages(){const e=document.getElementById("messages");e&&(e.innerHTML="")}function normaliseMessageContent(e){if("string"==typeof e)return e;if(null==e)return"";if("object"==typeof e&&"Buffer"===e.type&&Array.isArray(e.data))try{return(new TextDecoder).decode(new Uint8Array(e.data))}catch(e){return""}return String(e)}function getAgentDisplayName(e){const t=String(e||"").trim().replace(/\s+/g," ");if(!t)return"";const n=t.toLowerCase();if(/\b(agent|ai|service)\b/.test(n))return t;const s=t.split(" ");return s.length<=1?t:s[0]}function updateChatHeader(e,t){const n=getAgentDisplayName(e);chatHeaderName&&n&&(chatHeaderName.textContent=n,currentAgentName=n),chatHeaderPhoto&&t&&(chatHeaderPhoto.src=t)}function addUpdateMessage(e){const t=document.getElementById("messages");if(!t)return;const n=String(e||"").trim();if(!n)return;const s=document.createElement("div");s.classList.add("message-cont","update"),s.innerHTML=`${escapeHtml(n)}`,t.appendChild(s),s.scrollIntoView()}function closeAlertOverlay(){document.body.classList.remove("overlay"),parent.document?.body.classList.remove("overlay");const e=document.querySelector(".modalo");e&&(e.innerHTML="")}function openLiveChatModal(){const e=document.getElementById("request-a-webchat");e&&("function"!=typeof modalOpen?"function"==typeof window.$&&window.$(e).modal("show"):modalOpen(e))}function openRequestCallbackModal(){const e=document.getElementById("request-a-callback");e&&("function"!=typeof modalOpen?"function"==typeof window.$&&window.$(e).modal("show"):modalOpen(e))}function aichat_init(){chatMessagesHydrated||resetMessages(),preserveChoicesOnSelect.clear(),serverInputEnabled=!1,setInputVisible(!1),connectWebSocket(),sessionStorage.setItem("chatOpened","true"),setTimeout(markMessagesAsRead,1e3),document.getElementById("botchat").classList.add("hide"),document.getElementById("chatbox").classList.remove("hide")}async function aichat_open_from_bubble({fullscreen:e=!1}={}){if(!0===window.CHAT_LIVE_ONLY)try{const e=await fetch("/api/isOpen",{method:"GET",credentials:"same-origin"});if(e.ok){if(!0!==(await e.json()).Open)return void openRequestCallbackModal()}}catch(e){console.log("Opening-hours request failed:",e)}e&&document.body.classList.add("fullscreenchat");try{await fetch("/ws-aichat-v2",{method:"GET",credentials:"same-origin"})}catch(e){console.log("Chat preflight request failed:",e)}aichat_init()}function aichat_minimize(){document.body.classList.contains("fullscreenchat")&&document.body.classList.remove("fullscreenchat"),document.getElementById("chatbox").classList.add("hide"),document.getElementById("botchat").classList.remove("hide"),sessionStorage.removeItem("chatOpened")}function showAgentTyping(e){const t=document.getElementById("messages");if(!t)return;const n=document.getElementById("typingDiv");if(n){const t=n.querySelector(".typing-indicator");if(t){const n=getAgentDisplayName(e||(chatHeaderName?.textContent||"Agent").trim());t.textContent=`${n||"Agent"} is typing...`}return}const s=document.createElement("div");s.id="typingDiv",s.className="message-cont assistant";const a=getAgentDisplayName(e||(chatHeaderName?.textContent||"Agent").trim());s.innerHTML=`${a||"Agent"} is typing...`,t.appendChild(s),s.scrollIntoView()}function hideAgentTyping(){const e=document.getElementById("messages"),t=document.getElementById("typingDiv");e&&t&&e.removeChild(t)}function removeCustomerProfilePrompt(){const e=document.getElementById("messages");if(!e)return;e.querySelectorAll(".customer-profile-prompt").forEach((e=>e.remove()))}function renderCustomerProfilePrompt(e){const t=document.getElementById("messages");if(!t)return;removeCustomerProfilePrompt();const n=document.createElement("div");n.classList.add("customer-profile-prompt"),n.style.display="flex",n.style.justifyContent="center",n.style.width="100%",n.style.margin="10px 0 14px";const s=e.form||{},a=Array.isArray(s.fields)?s.fields:[],o=String(s.submitType||"customer-profile-submit"),r=String(s.submitLabel||"Start Chat"),i=document.createElement("div");i.classList.add("message-cont","assistant"),i.style.display="block",i.style.width="100%",i.style.maxWidth="360px",i.style.padding="14px 14px 12px",i.style.borderRadius="12px",i.style.background="#f7fbff",i.style.border="1px solid #d7e7f6",i.style.boxShadow="0 1px 3px rgba(0,0,0,0.08)";const c=document.createElement("div");c.style.marginBottom="10px",c.style.fontWeight="600",c.style.lineHeight="1.3",c.style.color="#1b3f66",c.style.textAlign="center",c.textContent=e.content||"Before we start, please complete this quick form:",i.appendChild(c);const d=document.createElement("form");d.className="gt-chat-profile-form",d.style.margin="0 auto",d.style.maxWidth="300px",a.forEach((e=>{const t=String(e.key||"").trim();if(!t)return;const n=document.createElement("div");n.className="form-group",n.style.marginBottom="10px";const s=document.createElement("label");s.textContent=e.label||t,s.style.fontSize="13px",s.style.fontWeight="600",s.style.marginBottom="5px",s.style.color="#244d78",n.appendChild(s);const a=document.createElement("input");a.className="form-control",a.name=t,a.type=e.inputType||"text",a.placeholder=e.placeholder||"",a.required=!1!==e.required,n.appendChild(a),d.appendChild(n)}));const l=document.createElement("button");l.type="submit",l.className="btn btn-primary",l.textContent=r,l.style.display="block",l.style.width="100%",l.style.marginTop="4px",l.style.borderRadius="22px",l.style.fontWeight="700",l.style.padding="8px 12px",d.appendChild(l),d.addEventListener("submit",(function(e){if(e.preventDefault(),!ws||ws.readyState!==WebSocket.OPEN)return void addUpdateMessage("Connection is not ready. Please try again in a moment.");const t={type:o};a.forEach((e=>{const n=String(e.key||"").trim();if(!n)return;const s=d.elements[n]?String(d.elements[n].value||"").trim():"";t[n]=s})),t.name&&t.email&&t.phone?(ws.send(JSON.stringify(t)),l.disabled=!0,l.textContent="Submitting..."):addUpdateMessage("Please complete name, email, and phone.")})),i.appendChild(d),n.appendChild(i),t.appendChild(n),n.scrollIntoView(),setInputVisible(!1)}function markBubbleFailed(e){e.classList.add("message-failed"),e.removeAttribute("data-pending");const t=e.querySelector(".message-ticks");t&&t.remove();if(e.querySelector(".message-retry"))return;const n=document.createElement("span");n.className="message-retry",n.textContent="Failed to send. Tap to retry.";const s=pendingSentMessages.get(e)?.content||"";n.addEventListener("click",(function(){retrySend(e,s)}));const a=e.querySelector(".message-footer");a&&a.appendChild(n)}function retrySend(e,t){if(!t)return;e.classList.remove("message-failed");const n=e.querySelector(".message-retry");n&&n.remove();const s=document.createElement("span");s.className="message-ticks sent";const a=e.querySelector(".message-footer");a&&a.appendChild(s),e.setAttribute("data-pending","true"),pendingSentMessages.set(e,{content:t,timer:setTimeout((function(){markBubbleFailed(e)}),SEND_ACK_TIMEOUT_MS)}),ws&&ws.readyState===WebSocket.OPEN?ws.send(t):markBubbleFailed(e)}function isChatOpen(){const e=document.getElementById("chatbox");return e&&!e.classList.contains("hide")}function markMessageRead(e){isChatOpen()&&ws&&ws.readyState===WebSocket.OPEN&&ws.send(JSON.stringify({type:"message-read",messageIds:[e]}))}function markMessagesAsRead(){if(!isChatOpen())return;if(!ws||ws.readyState!==WebSocket.OPEN)return;const e=[];document.querySelectorAll("#messages [data-message-id]").forEach((function(t){t.classList.contains("user")||t.hasAttribute("data-read")||(e.push(t.getAttribute("data-message-id")),t.setAttribute("data-read","true"))})),e.length>0&&ws.send(JSON.stringify({type:"message-read",messageIds:e}))}function sendMessage(){var e=document.getElementById("userInput").value;if(!serverInputEnabled)return;if(e.length<=0)return;const t={role:"user",content:e};addMessage(t.role,JSON.stringify(t)),document.getElementById("userInput").value="";const n=document.querySelector('#messages [data-pending="true"]');if(!ws||ws.readyState!==WebSocket.OPEN)return n&&markBubbleFailed(n),void closeChatEmojiPicker();if(ws.send(e),closeChatEmojiPicker(),n){const t=setTimeout((function(){markBubbleFailed(n)}),SEND_ACK_TIMEOUT_MS);pendingSentMessages.set(n,{content:e,timer:t})}}function insertTextAtCursor(e,t){if(!e)return;const n=e.selectionStart||0,s=e.selectionEnd||0,a=e.value||"";e.value=a.slice(0,n)+t+a.slice(s);const o=n+t.length;e.setSelectionRange(o,o),e.focus()}function closeChatEmojiPicker(){chatEmojiPicker&&chatEmojiPicker.classList.remove("open")}function toggleChatEmojiPicker(){chatEmojiPicker&&chatEmojiPicker.classList.toggle("open")}function initChatEmojiPicker(){chatEmojiPicker&&(chatEmojiPicker.innerHTML="",chatEmojiList.forEach((function(e){const t=document.createElement("button");t.type="button",t.className="chat-emoji-option",t.textContent=e,t.addEventListener("click",(function(){insertTextAtCursor(document.getElementById("userInput"),e),closeChatEmojiPicker()})),chatEmojiPicker.appendChild(t)})))}async function uploadChatFile(e){if(!e)return null;const t=new FormData;t.append("chatFile",e);const n=(currentChatSessionId||"").trim()||getChatCookieValue("connect.tid");n&&(t.append("sessionId",n),t.append("chatSessionId",n));const s=await fetch("/chat-v2/upload-file",{method:"POST",credentials:"same-origin",headers:n?{"x-chat-session-id":n}:void 0,body:t});if(!s.ok)throw new Error("Upload failed");const a=await s.json();if(!a?.ok||!a?.file?.url||!a?.file?.name)throw new Error("Invalid upload response");return a.file}function renderFileMessage(e,t){const n=t?.file||{},s=String(n.url||"").trim(),a=escapeHtml(n.name||"File"),o=String(n.mimeType||"").toLowerCase(),r=String(t?.role||"").toLowerCase(),i=r&&"user"!==r;if(!s)return!1;const c=o.startsWith("image/");let d=`${a}`;if(c){const t=`${a}
${a}`;if(i)return e.innerHTML=`${a}
Loading image...`,setTimeout((()=>{e.isConnected&&(e.innerHTML=t)}),agentImageRenderDelayMs),!0;d=t}return e.innerHTML=d,!0}function addMessage(e,t){const n=JSON.parse(t);if("heartbeat"===n?.type||"heartbeat-ack"===n?.type)return;if("chat-reset"===n.type)return resetMessages(),chatMessagesHydrated=!1,document.getElementById("userInput").value="",preserveChoicesOnSelect.clear(),serverInputEnabled=!1,void setInputVisible(!1);if("chat-input-state"===n.type)return void setInputVisible(serverInputEnabled=!0===n.enabled);if("session-id"===n.type)return void(currentChatSessionId=String(n.sessionId||"").trim());if("session-id-required"===n.type)return n.error&&console.log(n.error),void setInputVisible(!1);if("customer-profile-request"===n.type)return renderCustomerProfilePrompt(n),void(chatMessagesHydrated=!0);if("customer-profile-ok"===n.type)return void removeCustomerProfilePrompt();if("initial-choice-ok"===n.type)return;if("open-live-chat-modal"===n.type)return void openLiveChatModal();if("customer-profile-error"===n.type||"customer-profile-required"===n.type)return setInputVisible(!1),void(n.error&&addUpdateMessage(n.error));if("customer-profile"===n.type)return;if("agent-typing"===n.type)return void showAgentTyping(n.agentName);if("agent-stop-typing"===n.type)return void hideAgentTyping();if("ai-typing"===n.type)return void showAgentTyping(n.agentName);if("ai-stop-typing"===n.type)return void hideAgentTyping();if("agent-meta"===n.type){getAgentDisplayName(n.agentName);return void updateChatHeader(n.agentName,n.agentPhoto)}if("system"===n.type)return void addUpdateMessage(n.content);if("chat-ended"===n.type)return serverInputEnabled=!1,void setInputVisible(!1);if("message-sent-ack"===n.type){const e=document.querySelector('#messages [data-pending="true"]');if(e){const t=pendingSentMessages.get(e);t&&(clearTimeout(t.timer),pendingSentMessages.delete(e)),n.messageId&&e.setAttribute("data-message-id",n.messageId),e.removeAttribute("data-pending");const s=e.querySelector(".message-ticks");s&&(s.className="message-ticks "+(n.status||"sent"))}return}if("message-status-update"===n.type)return void(n.updates||[]).forEach((function(e){const t=document.querySelector('[data-message-id="'+e.messageId+'"]');if(!t)return;const n=t.querySelector(".message-ticks");n&&(n.className="message-ticks "+e.status)}));if("agent-status"===n.type){if(String(n.content||"").trim().toLowerCase().includes("has taken over the chat"))return}const{role:s,buttons:a,choices:o}=n;if(!s)return;const r=normaliseMessageContent(n.content);let i=r;const c=document.getElementById("messages"),d=chatMessagesHydrated;chatMessagesHydrated=!0,hideAgentTyping(),s&&"user"!==s.toLowerCase()&&d&&(chatDingAudio.currentTime=0,chatDingAudio.play().catch((()=>{}))),i=i.replace(/\n/g,"
"),i=i.replace(/\[([^\]]+)\]\((https?:\/\/[^\s]+)\)/g,'$1'),i=i.replace(/ใ€\d+:\d+โ€ sourceใ€‘/g,""),i=i.replace(/(^|[\s(])(https?:\/\/[^\s)<>]+)/g,'$1$2');const l=document.createElement("div");if(""!==i||"file-message"===n.type||"live-agent-file-message"===n.type){const e="user"===s.toLowerCase(),t=document.createElement("span");t.className="message-bubble";if(!renderFileMessage(t,n)){const e=document.createElement("span");e.className="message-text",e.innerHTML=toSafeMessageHtml(r),t.appendChild(e)}const a=document.createElement("span");a.className="message-footer";const o=document.createElement("span");o.className="message-time";const i=n.timestamp?new Date(n.timestamp):new Date,d=isNaN(i.getTime())?new Date:i,u=String(d.getDate()).padStart(2,"0"),m=String(d.getMonth()+1).padStart(2,"0"),p=d.getFullYear(),g=String(d.getHours()).padStart(2,"0"),h=String(d.getMinutes()).padStart(2,"0");if(o.textContent=`${u}/${m}/${p} ${g}:${h}`,a.appendChild(o),e){const e=document.createElement("span");e.className="message-ticks "+(n.status||"sent"),a.appendChild(e)}t.appendChild(a),l.classList.add(s.toLowerCase()),l.classList.add("message-cont"),n.messageId?l.setAttribute("data-message-id",n.messageId):e&&l.setAttribute("data-pending","true"),l.appendChild(t),c.appendChild(l),!e&&n.messageId&&markMessageRead(n.messageId)}if(a&&a.length>0){const e=document.createElement("div");e.style.display="flex",e.style.gap="10px",e.style.alignItems="center",e.innerHTML=a.map((e=>`
${e}
`)).join(""),c.appendChild(e)}if(o&&o.length>0){preserveChoicesOnSelect.clear();(Array.isArray(n.preserveChoicesOnSelect)?n.preserveChoicesOnSelect:[]).forEach((e=>preserveChoicesOnSelect.add(String(e||"").trim().toLowerCase())));const e=document.createElement("div");e.classList.add("multiple-choice"),o.forEach((t=>{const n=document.createElement("div");n.classList.add("choice"),n.textContent=t;const s=preserveChoicesOnSelect.has(String(t||"").trim().toLowerCase());n.addEventListener("click",(()=>choiceClick(t,s))),e.appendChild(n)})),c.appendChild(e)}l.scrollIntoView()}function choiceClick(e,t=!1){const n=String(e||"").trim().toLowerCase().replace(/[โ€™โ€˜]/g,"'");if(!0===window.CHAT_LIVE_ONLY&&"i've already ordered"===n)return void openRequestCallbackModal();if(!t){const e=document.getElementById("messages").getElementsByClassName("multiple-choice");for(;e.length>0;)e[0].remove()}const s={role:"user",content:e};addMessage(s.role,JSON.stringify(s)),ws.send(e)}function confirmNewChat(){showAlert("fa-question-circle","Are you sure?",' ',"#FFFFFF",!1)}function startNewChat(){if(closeAlertOverlay(),!ws||ws.readyState!==WebSocket.OPEN)return pendingNewChat=!0,void connectWebSocket();pendingNewChat=!1,ws.send(JSON.stringify({type:"new-chat"}))}let ws;document.getElementById("userInput").addEventListener("keypress",(function(e){13===(e.which||e.keyCode)&&(e.preventDefault(),sendMessage())})),chatUploadButton?.addEventListener("click",(function(){chatFileInput&&(chatFileInput.value="",chatFileInput.click())})),chatEmojiButton?.addEventListener("click",(function(e){e.preventDefault(),e.stopPropagation(),toggleChatEmojiPicker()})),document.addEventListener("click",(function(e){chatEmojiPicker&&chatEmojiButton&&(chatEmojiPicker.contains(e.target)||chatEmojiButton.contains(e.target)||closeChatEmojiPicker())})),chatFileInput?.addEventListener("change",(async function(){const e=chatFileInput.files&&chatFileInput.files[0];if(!e)return;if(!serverInputEnabled)return addUpdateMessage("Please complete the required chat steps first."),void(chatFileInput.value="");if(!ws||ws.readyState!==WebSocket.OPEN)return void addUpdateMessage("Connection is not ready. Please try again in a moment.");const t=chatUploadButton?chatUploadButton.textContent:"";chatUploadButton&&(chatUploadButton.disabled=!0,chatUploadButton.textContent="...");try{const t=await uploadChatFile(e);ws.send(JSON.stringify({type:"customer-file-message",file:t}))}catch(e){addUpdateMessage("File upload failed. Please try again.")}finally{chatUploadButton&&(chatUploadButton.disabled=!1,chatUploadButton.textContent=t||"+"),chatFileInput.value=""}})),expandButton.addEventListener("click",(function(){document.body.classList.contains("fullscreenchat")?document.body.classList.remove("fullscreenchat"):document.body.classList.add("fullscreenchat")})),newChatButton?.addEventListener("click",(function(){confirmNewChat()})),"true"===sessionStorage.getItem("chatOpened")&&aichat_init(),initChatEmojiPicker();let chatHeartbeatTimer=null;const HEARTBEAT_INTERVAL_MS=2e4;let reconnectAttempts=0,reconnectTimer=null;const RECONNECT_BASE_DELAY_MS=1e3,RECONNECT_MAX_DELAY_MS=15e3;function getCookieValue(e){const t=`; ${document.cookie||""}`.split(`; ${e}=`);return 2===t.length?decodeURIComponent(t.pop().split(";").shift()||""):""}async function ensureSessionId(){const e=getCookieValue("connect.tid");if(e)return e;try{const e=await fetch("/session/id",{credentials:"include"});if(e.ok){const t=await e.json();if(t&&t.sessionId)return t.sessionId}}catch(e){console.warn("Failed to fetch session id",e)}return getCookieValue("connect.tid")}function resolveChatWsHost(){const e=String(window.CHAT_WS_HOST||"").trim();if(e)return e.replace(/^wss?:\/\//i,"").replace(/\/+$/,"");return"dev.galatent.co.uk"===String(window.location.hostname||"").trim().toLowerCase()?"localhost:8484":"chat.ws.galatent.co.uk"}function resolveChatWsProtocol(e){const t=String(e||"").toLowerCase();return t.startsWith("localhost")||t.startsWith("127.0.0.1")?"ws":"wss"}function buildSessionIdPayload(e){return{type:"session-id",sessionId:e,website:String(window.location.hostname||"").trim().toLowerCase()}}function connectWebSocket(){if(ws&&(ws.readyState===WebSocket.OPEN||ws.readyState===WebSocket.CONNECTING))return;const e=resolveChatWsHost(),t=`${resolveChatWsProtocol(e)}://${e}/ws-aichat-v2`;ws=new WebSocket(t),window.ws=ws,window.chatSocket=ws,ws.onopen=async function(){console.log("Connected to WebSocket!"),reconnectAttempts=0,setTimeout((function(){"function"==typeof markMessagesAsRead&&markMessagesAsRead()}),1500),reconnectTimer&&(clearTimeout(reconnectTimer),reconnectTimer=null),chatHeartbeatTimer&&(clearInterval(chatHeartbeatTimer),chatHeartbeatTimer=null),chatHeartbeatTimer=setInterval((()=>{ws&&ws.readyState===WebSocket.OPEN&&ws.send(JSON.stringify({type:"heartbeat",ts:Date.now()}))}),HEARTBEAT_INTERVAL_MS),chatMessagesHydrated=!1,resetMessages();const e=await ensureSessionId();if(e){ws.send(JSON.stringify(buildSessionIdPayload(e)));const t=setInterval((()=>{chatMessagesHydrated?clearInterval(t):ws.send(JSON.stringify(buildSessionIdPayload(e)))}),1e3)}if(void 0!==pendingNewChat&&pendingNewChat)return pendingNewChat=!1,void ws.send(JSON.stringify({type:"new-chat"}))},ws.onmessage=function(e){let t=null;try{t=JSON.parse(e.data)}catch(e){t=null}"heartbeat-ack"!==t?.type&&addMessage("Agent",e.data)},ws.onerror=function(e){console.log("WebSocket error:",{message:e?.message||"Unknown websocket error",readyState:ws?ws.readyState:null,url:t})},ws.onclose=function(e){console.log("WebSocket closed:",{code:e.code,reason:e.reason||"",wasClean:e.wasClean,url:t}),chatHeartbeatTimer&&(clearInterval(chatHeartbeatTimer),chatHeartbeatTimer=null),ws=null,window.ws&&window.ws.readyState===WebSocket.CLOSED&&(window.ws=null),window.chatSocket&&window.chatSocket.readyState===WebSocket.CLOSED&&(window.chatSocket=null);const n=Math.min(RECONNECT_MAX_DELAY_MS,RECONNECT_BASE_DELAY_MS*Math.pow(2,reconnectAttempts)),s=Math.floor(500*Math.random());reconnectAttempts+=1,reconnectTimer=setTimeout(connectWebSocket,n+s)}}