@paramms/chat-widget 1.7.0 → 1.9.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/index.js CHANGED
@@ -1,18 +1,18 @@
1
1
  var Be = Object.defineProperty;
2
- var $e = (t, e, d) => e in t ? Be(t, e, { enumerable: !0, configurable: !0, writable: !0, value: d }) : t[e] = d;
3
- var C = (t, e, d) => $e(t, typeof e != "symbol" ? e + "" : e, d);
4
- import { l as Re, b as ve, p as Me, r as Ae, c as qe, a as Ne, m as Oe } from "./chatlist2.js";
5
- import { h as ut } from "./chatlist2.js";
6
- import { P as De, C as He, b as _e } from "./outbox.js";
7
- import { e as ft } from "./outbox.js";
8
- import { E2ESession as Ue, extractX3DHInit as Fe } from "./e2e.js";
9
- const We = `
10
- .ocw { ${Re("ocw")}
2
+ var $e = (t, e, l) => e in t ? Be(t, e, { enumerable: !0, configurable: !0, writable: !0, value: l }) : t[e] = l;
3
+ var C = (t, e, l) => $e(t, typeof e != "symbol" ? e + "" : e, l);
4
+ import { l as Me, b as ke, p as Re, r as Ae, c as qe, f as Ne, a as Oe, m as De } from "./chatlist2.js";
5
+ import { h as ht } from "./chatlist2.js";
6
+ import { P as He, C as _e, b as Ue } from "./outbox.js";
7
+ import { e as wt } from "./outbox.js";
8
+ import { E2ESession as Fe, extractX3DHInit as We } from "./e2e.js";
9
+ const Ge = `
10
+ .ocw { ${Me("ocw")}
11
11
  position:relative;
12
12
  display:flex; flex-direction:column; height:100%; min-height:320px; background:var(--ocw-bg);
13
13
  font-family:var(--ocw-fb); color:var(--ocw-ink); overflow:hidden; }
14
- @media (prefers-color-scheme: dark) { .ocw[data-theme="auto"] { ${ve("ocw")} } }
15
- .ocw[data-theme="dark"] { ${ve("ocw")} }
14
+ @media (prefers-color-scheme: dark) { .ocw[data-theme="auto"] { ${ke("ocw")} } }
15
+ .ocw[data-theme="dark"] { ${ke("ocw")} }
16
16
  /* ── Responsive sizing ──────────────────────────────────────────────────────
17
17
  * Sizing is driven by the WIDGET'S OWN width (ResizeObserver toggles
18
18
  * .ocw-compact below 400px), not the viewport — so a widget embedded in a
@@ -192,52 +192,51 @@ const We = `
192
192
  .ocw-sendbtn:disabled { opacity:.5; cursor:default; }
193
193
  .ocw-sendbtn:focus-visible, .ocw-back:focus-visible, .ocw-chip:focus-visible { outline:2px solid var(--ocw-accent); outline-offset:2px; }
194
194
 
195
- .ocw-translate-btn { position:absolute; bottom:2px; right:-26px; background:var(--ocw-card); border:1px solid var(--ocw-line); border-radius:50%; width:22px; height:22px; font-size:11px; cursor:pointer; color:var(--ocw-mut); display:flex; align-items:center; justify-content:center; opacity:0; transition:opacity .15s; padding:0; }
196
- .ocw-row.theirs .ocw-translate-btn { right:auto; left:-26px; }
197
- .ocw-bubble-wrap:hover .ocw-translate-btn { opacity:1; }
195
+ .ocw-translate-btn { display:inline-flex; align-items:center; gap:4px; margin-top:3px; background:none; border:none; padding:2px 0; font-size:11px; line-height:1; cursor:pointer; color:var(--ocw-mut); opacity:.85; }
196
+ .ocw-translate-btn:hover { opacity:1; text-decoration:underline; }
198
197
  .ocw-translation { margin-top:6px; padding-top:6px; border-top:1px solid var(--ocw-line); font-size:13px; line-height:1.45; }
199
198
  .ocw-translation::before { content:'🌐 '; opacity:.75; }
200
- `, ke = "objectchat-widget-styles", Ge = ["👍", "❤️", "😂", "😮", "😢", "🙏"], Ke = 400, Ve = '<svg viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg" aria-hidden="true"><path d="M22 2 11 13M22 2l-7 20-4-9-9-4 20-7z" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/></svg>';
201
- function Ye() {
202
- if (typeof document > "u" || document.getElementById(ke)) return;
203
- const t = document.createElement("style");
204
- t.id = ke, t.textContent = We, document.head.appendChild(t);
205
- }
206
- const Ce = "ocw-webfont";
199
+ `, Ce = "objectchat-widget-styles", Ke = ["👍", "❤️", "😂", "😮", "😢", "🙏"], Ve = 400, Ye = '<svg viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg" aria-hidden="true"><path d="M22 2 11 13M22 2l-7 20-4-9-9-4 20-7z" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/></svg>';
207
200
  function Xe() {
208
201
  if (typeof document > "u" || document.getElementById(Ce)) return;
202
+ const t = document.createElement("style");
203
+ t.id = Ce, t.textContent = Ge, document.head.appendChild(t);
204
+ }
205
+ const Ie = "ocw-webfont";
206
+ function Qe() {
207
+ if (typeof document > "u" || document.getElementById(Ie)) return;
209
208
  const t = document.createElement("link");
210
- t.id = Ce, t.rel = "stylesheet", t.href = "https://fonts.googleapis.com/css2?family=Baloo+2:wght@500;600;700&family=Nunito:wght@400;500;600;700&display=swap", document.head.appendChild(t);
209
+ t.id = Ie, t.rel = "stylesheet", t.href = "https://fonts.googleapis.com/css2?family=Baloo+2:wght@500;600;700&family=Nunito:wght@400;500;600;700&display=swap", document.head.appendChild(t);
211
210
  }
212
- function n(t, e, d) {
213
- const s = document.createElement(t);
214
- return e && (s.className = e), d !== void 0 && (s.textContent = d), s;
211
+ function n(t, e, l) {
212
+ const c = document.createElement(t);
213
+ return e && (c.className = e), l !== void 0 && (c.textContent = l), c;
215
214
  }
216
- function Qe(t, e) {
217
- const d = /(https?:\/\/[^\s]+)/g;
218
- let s = 0, c = null, h;
219
- for (; (h = d.exec(e)) !== null; ) {
220
- if (h.index > s) {
221
- const a = document.createTextNode(e.slice(s, h.index));
222
- t.append(a), c ?? (c = a);
215
+ function Je(t, e) {
216
+ const l = /(https?:\/\/[^\s]+)/g;
217
+ let c = 0, i = null, f;
218
+ for (; (f = l.exec(e)) !== null; ) {
219
+ if (f.index > c) {
220
+ const d = document.createTextNode(e.slice(c, f.index));
221
+ t.append(d), i ?? (i = d);
223
222
  }
224
- let y = h[0], l = "";
225
- const u = /[).,!?;:]+$/.exec(y);
226
- u && (l = u[0], y = y.slice(0, -l.length));
227
- const x = document.createElement("a");
228
- x.href = y, x.target = "_blank", x.rel = "noopener noreferrer", x.textContent = y, x.style.cssText = "color:inherit;text-decoration:underline;word-break:break-all", t.append(x), l && t.append(document.createTextNode(l)), s = h.index + h[0].length;
223
+ let y = f[0], s = "";
224
+ const x = /[).,!?;:]+$/.exec(y);
225
+ x && (s = x[0], y = y.slice(0, -s.length));
226
+ const u = document.createElement("a");
227
+ u.href = y, u.target = "_blank", u.rel = "noopener noreferrer", u.textContent = y, u.style.cssText = "color:inherit;text-decoration:underline;word-break:break-all", t.append(u), s && t.append(document.createTextNode(s)), c = f.index + f[0].length;
229
228
  }
230
- const b = document.createTextNode(e.slice(s));
231
- return t.append(b), c ?? (c = b), c;
229
+ const b = document.createTextNode(e.slice(c));
230
+ return t.append(b), i ?? (i = b), i;
232
231
  }
233
- function Je(t) {
232
+ function Ze(t) {
234
233
  try {
235
234
  return new Date(t).toLocaleTimeString([], { hour: "2-digit", minute: "2-digit" });
236
235
  } catch {
237
236
  return "";
238
237
  }
239
238
  }
240
- function re(t) {
239
+ function se(t) {
241
240
  var e;
242
241
  switch (t.kind) {
243
242
  case "text":
@@ -254,9 +253,9 @@ function re(t) {
254
253
  return `📅 ${t.title} — ${new Date(t.startIso).toLocaleString()}`;
255
254
  }
256
255
  }
257
- class Ze {
256
+ class et {
258
257
  /** Last seq the guest has seen per conversationId — used to compute unread badges. */
259
- constructor(e, d, s, c = {}) {
258
+ constructor(e, l, c, i = {}) {
260
259
  C(this, "scroll");
261
260
  C(this, "chips");
262
261
  C(this, "typing");
@@ -291,59 +290,59 @@ class Ze {
291
290
  /** Whether the subject card (server Subject entity, mount config fallback)
292
291
  * has been built — built once when data first arrives. */
293
292
  C(this, "subjectBuilt", !1);
294
- var z, O, T, _, r, i, v, f, m, k, S;
295
- this.root = e, this.me = d, this.h = s, this.cfg = c, Ye(), c.webfont !== !1 && Xe(), e.replaceChildren(), e.classList.add("ocw"), c.accent && e.style.setProperty("--ocw-accent", c.accent);
296
- const h = c.accent2 ?? c.accent;
297
- h && e.style.setProperty("--ocw-accent2", h), this.cfgAccent2 = c.accent2, e.dataset.theme = c.theme ?? "light";
293
+ var P, O, j, _, E, r, a, h, m, v, k;
294
+ this.root = e, this.me = l, this.h = c, this.cfg = i, Xe(), i.webfont !== !1 && Qe(), e.replaceChildren(), e.classList.add("ocw"), i.accent && e.style.setProperty("--ocw-accent", i.accent);
295
+ const f = i.accent2 ?? i.accent;
296
+ f && e.style.setProperty("--ocw-accent2", f), this.cfgAccent2 = i.accent2, e.dataset.theme = i.theme ?? "light";
298
297
  const b = n("div", "ocw-head");
299
298
  if (this.h.onBack) {
300
299
  const w = n("button", "ocw-back", "‹");
301
300
  w.type = "button", w.setAttribute("aria-label", "Back"), w.addEventListener("click", () => this.h.onBack()), b.append(w);
302
301
  }
303
- const y = ((z = c.subject) == null ? void 0 : z.ownerLabel) ?? ((O = c.subject) == null ? void 0 : O.title) ?? "", l = n("div", "ocw-avatar");
304
- y.trim() && (l.textContent = y.trim()[0].toUpperCase(), b.append(l));
305
- const u = n("div", "ocw-head-main");
306
- this.headerName = n("div", "ocw-head-name", ((T = c.subject) == null ? void 0 : T.ownerLabel) ?? ((_ = c.subject) == null ? void 0 : _.title) ?? ""), u.append(this.headerName), this.headStatus = n("div", "ocw-head-status"), this.headStatus.style.display = "none", u.append(this.headStatus), (r = c.subject) != null && r.subtitle && u.append(n("div", "ocw-head-meta", c.subject.subtitle)), b.append(u), this.statusBadge = n("span", "ocw-badge", ((i = c.subject) == null ? void 0 : i.status) ?? ""), (v = c.subject) != null && v.status || (this.statusBadge.style.display = "none"), b.append(this.statusBadge), this.e2eBadge = n("span", "ocw-e2e", "🔒 E2E"), this.e2eBadge.style.display = "none", b.append(this.e2eBadge), this.connStatus = n("span", "ocw-conn-status"), this.connStatus.style.display = "none", b.append(this.connStatus), b.append(n("button", "ocw-menu", "⋯")), this.chips = n("div", "ocw-chiprow"), this.scroll = n("div", "ocw-scroll"), this.subjectCard = n("div", "ocw-subject"), this.typing = n("div", "ocw-typing");
307
- const x = n("div", "ocw-typing-bubble");
308
- x.append(n("div", "ocw-typing-dot"), n("div", "ocw-typing-dot"), n("div", "ocw-typing-dot")), this.typing.append(x), this.quick = n("div", "ocw-quick");
309
- for (const w of c.quickReplies ?? []) {
310
- const I = n("button", void 0, w);
311
- I.addEventListener("click", () => {
302
+ const y = ((P = i.subject) == null ? void 0 : P.ownerLabel) ?? ((O = i.subject) == null ? void 0 : O.title) ?? "", s = n("div", "ocw-avatar");
303
+ y.trim() && (s.textContent = y.trim()[0].toUpperCase(), b.append(s));
304
+ const x = n("div", "ocw-head-main");
305
+ this.headerName = n("div", "ocw-head-name", ((j = i.subject) == null ? void 0 : j.ownerLabel) ?? ((_ = i.subject) == null ? void 0 : _.title) ?? ""), x.append(this.headerName), this.headStatus = n("div", "ocw-head-status"), this.headStatus.style.display = "none", x.append(this.headStatus), (E = i.subject) != null && E.subtitle && x.append(n("div", "ocw-head-meta", i.subject.subtitle)), b.append(x), this.statusBadge = n("span", "ocw-badge", ((r = i.subject) == null ? void 0 : r.status) ?? ""), (a = i.subject) != null && a.status || (this.statusBadge.style.display = "none"), b.append(this.statusBadge), this.e2eBadge = n("span", "ocw-e2e", "🔒 E2E"), this.e2eBadge.style.display = "none", b.append(this.e2eBadge), this.connStatus = n("span", "ocw-conn-status"), this.connStatus.style.display = "none", b.append(this.connStatus), b.append(n("button", "ocw-menu", "⋯")), this.chips = n("div", "ocw-chiprow"), this.scroll = n("div", "ocw-scroll"), this.subjectCard = n("div", "ocw-subject"), this.typing = n("div", "ocw-typing");
306
+ const u = n("div", "ocw-typing-bubble");
307
+ u.append(n("div", "ocw-typing-dot"), n("div", "ocw-typing-dot"), n("div", "ocw-typing-dot")), this.typing.append(u), this.quick = n("div", "ocw-quick");
308
+ for (const w of i.quickReplies ?? []) {
309
+ const S = n("button", void 0, w);
310
+ S.addEventListener("click", () => {
312
311
  this.h.onSend(w), this.quick.style.display = "none";
313
- }), this.quick.append(I);
312
+ }), this.quick.append(S);
314
313
  }
315
- this.formHost = n("div", "ocw-form-host"), this.csatPanel = n("div", "ocw-csat"), this.csatPanel.style.display = "none", this.awayNotice = n("div", "ocw-away"), this.awayNotice.style.display = "none", this.preChatPanel = n("div", "ocw-prechat"), this.preChatPanel.style.display = "none", this.deflectPanel = n("div", "ocw-deflect"), this.deflectPanel.style.display = "none", this.input = n("textarea", void 0), this.input.rows = 1, this.input.placeholder = ((f = c.i18n) == null ? void 0 : f.placeholder) ?? "Message…";
316
- const a = n("button", "ocw-sendbtn");
317
- a.type = "button";
318
- const j = (m = c.i18n) == null ? void 0 : m.send;
319
- j ? (a.textContent = j, a.classList.add("ocw-sendbtn-label"), a.setAttribute("aria-label", j)) : (a.innerHTML = Ve, a.setAttribute("aria-label", "Send message")), a.disabled = !0, this.sendBtn = a, a.addEventListener("click", () => this.flushSend()), this.input.addEventListener("input", () => {
320
- var w, I;
321
- this.sendBtn.disabled = this.input.value.trim().length === 0, this.autoGrowInput(), this.storeRef && !this.storeRef.messages().some((N) => N.senderRole === "guest") ? (I = (w = this.h).onDeflectQuery) == null || I.call(w, this.input.value) : this.hideDeflection();
314
+ this.formHost = n("div", "ocw-form-host"), this.csatPanel = n("div", "ocw-csat"), this.csatPanel.style.display = "none", this.awayNotice = n("div", "ocw-away"), this.awayNotice.style.display = "none", this.preChatPanel = n("div", "ocw-prechat"), this.preChatPanel.style.display = "none", this.deflectPanel = n("div", "ocw-deflect"), this.deflectPanel.style.display = "none", this.input = n("textarea", void 0), this.input.rows = 1, this.input.placeholder = ((h = i.i18n) == null ? void 0 : h.placeholder) ?? "Message…";
315
+ const d = n("button", "ocw-sendbtn");
316
+ d.type = "button";
317
+ const I = (m = i.i18n) == null ? void 0 : m.send;
318
+ I ? (d.textContent = I, d.classList.add("ocw-sendbtn-label"), d.setAttribute("aria-label", I)) : (d.innerHTML = Ye, d.setAttribute("aria-label", "Send message")), d.disabled = !0, this.sendBtn = d, d.addEventListener("click", () => this.flushSend()), this.input.addEventListener("input", () => {
319
+ var w, S;
320
+ this.sendBtn.disabled = this.input.value.trim().length === 0, this.autoGrowInput(), this.storeRef && !this.storeRef.messages().some((z) => z.senderRole === "guest") ? (S = (w = this.h).onDeflectQuery) == null || S.call(w, this.input.value) : this.hideDeflection();
322
321
  }), this.input.addEventListener("keydown", (w) => {
323
322
  w.isComposing || w.keyCode === 229 || (w.key === "Enter" && !w.shiftKey ? (w.preventDefault(), this.flushSend()) : this.signalTyping());
324
323
  });
325
- const R = n("button", "ocw-attach", "📎");
326
- R.title = "Attach image or file";
327
- const E = document.createElement("input");
328
- E.type = "file", E.accept = "image/*,.pdf,.txt,.doc,.docx", E.style.display = "none", R.addEventListener("click", () => E.click()), E.addEventListener("change", () => {
324
+ const T = n("button", "ocw-attach", "📎");
325
+ T.title = "Attach image or file";
326
+ const L = document.createElement("input");
327
+ L.type = "file", L.accept = "image/*,.pdf,.txt,.doc,.docx", L.style.display = "none", T.addEventListener("click", () => L.click()), L.addEventListener("change", () => {
329
328
  var w;
330
- (w = E.files) != null && w[0] && this.h.onAttach && this.h.onAttach(E.files[0]), E.value = "";
329
+ (w = L.files) != null && w[0] && this.h.onAttach && this.h.onAttach(L.files[0]), L.value = "";
331
330
  });
332
- const A = n("div", "ocw-input");
333
- A.append(R, E, this.input, a);
334
- const P = n("div", "ocw-footer");
335
- ((k = c.i18n) == null ? void 0 : k.poweredBy) !== void 0 ? P.textContent = c.i18n.poweredBy : P.innerHTML = 'Powered by <a href="https://relay.paramms.com" target="_blank" rel="noopener">Relay</a>', this.footer = P, this.reopenBtn = n("button", "ocw-reopen", ((S = this.cfg.i18n) == null ? void 0 : S.reopen) ?? "Reopen conversation"), this.reopenBtn.type = "button", this.reopenBtn.addEventListener("click", () => {
331
+ const B = n("div", "ocw-input");
332
+ B.append(T, L, this.input, d);
333
+ const R = n("div", "ocw-footer");
334
+ ((v = i.i18n) == null ? void 0 : v.poweredBy) !== void 0 ? R.textContent = i.i18n.poweredBy : R.innerHTML = 'Powered by <a href="https://relay.paramms.com" target="_blank" rel="noopener">Relay</a>', this.footer = R, this.reopenBtn = n("button", "ocw-reopen", ((k = this.cfg.i18n) == null ? void 0 : k.reopen) ?? "Reopen conversation"), this.reopenBtn.type = "button", this.reopenBtn.addEventListener("click", () => {
336
335
  this.reopenBtn.style.display = "none";
337
336
  const w = this.root.querySelector(".ocw-input textarea");
338
337
  w == null || w.focus();
339
- }), e.append(b, this.chips, this.scroll, this.typing, this.quick, this.formHost, this.csatPanel, this.preChatPanel, this.deflectPanel, this.awayNotice, A, this.reopenBtn, this.footer);
340
- const B = (w) => {
341
- e.classList.toggle("ocw-compact", w > 0 && w < Ke);
338
+ }), e.append(b, this.chips, this.scroll, this.typing, this.quick, this.formHost, this.csatPanel, this.preChatPanel, this.deflectPanel, this.awayNotice, B, this.reopenBtn, this.footer);
339
+ const A = (w) => {
340
+ e.classList.toggle("ocw-compact", w > 0 && w < Ve);
342
341
  };
343
- B(e.clientWidth), typeof ResizeObserver < "u" && (this.compactObserver = new ResizeObserver((w) => {
344
- var N;
345
- const I = ((N = w[0]) == null ? void 0 : N.contentRect.width) ?? e.clientWidth;
346
- B(I);
342
+ A(e.clientWidth), typeof ResizeObserver < "u" && (this.compactObserver = new ResizeObserver((w) => {
343
+ var z;
344
+ const S = ((z = w[0]) == null ? void 0 : z.contentRect.width) ?? e.clientWidth;
345
+ A(S);
347
346
  }), this.compactObserver.observe(e));
348
347
  }
349
348
  /** Returns the scroll container so history.ts can attach scroll listeners. */
@@ -352,13 +351,13 @@ class Ze {
352
351
  }
353
352
  /** Registers a cleanup fn removed on destroy() to prevent listener leaks. */
354
353
  setScrollCleanup(e) {
355
- var d;
356
- (d = this.scrollCleanup) == null || d.call(this), this.scrollCleanup = e;
354
+ var l;
355
+ (l = this.scrollCleanup) == null || l.call(this), this.scrollCleanup = e;
357
356
  }
358
357
  /** Call when the widget is unmounted. Disconnects scroll listeners and clears timers. */
359
358
  destroy() {
360
- var e, d;
361
- (e = this.scrollCleanup) == null || e.call(this), this.scrollCleanup = null, this.typingTimer && (clearTimeout(this.typingTimer), this.typingTimer = null), (d = this.compactObserver) == null || d.disconnect(), this.compactObserver = null;
359
+ var e, l;
360
+ (e = this.scrollCleanup) == null || e.call(this), this.scrollCleanup = null, this.typingTimer && (clearTimeout(this.typingTimer), this.typingTimer = null), (l = this.compactObserver) == null || l.disconnect(), this.compactObserver = null;
362
361
  }
363
362
  flushSend() {
364
363
  this.hideDeflection();
@@ -382,110 +381,110 @@ class Ze {
382
381
  this.cfg.i18n = { ...this.cfg.i18n ?? {}, aiAssistant: e };
383
382
  }
384
383
  render(e) {
385
- var E, A, P, B, z, O, T, _;
384
+ var L, B, R, A, P, O, j, _;
386
385
  if (this.storeRef = e, e.accent && (this.root.style.setProperty("--ocw-accent", e.accent), this.root.style.setProperty("--ocw-accent2", this.cfgAccent2 ?? e.accent)), this.e2eBadge.style.display = e.e2e ? "inline-flex" : "none", this.buildSubjectCard(e), e.subject) {
387
- const r = (E = this.cfg.subject) == null ? void 0 : E.ownerLabel;
388
- r && (this.headerName.textContent = r);
386
+ const E = (L = this.cfg.subject) == null ? void 0 : L.ownerLabel;
387
+ E && (this.headerName.textContent = E);
389
388
  }
390
389
  this.quick.style.display = e.messages().length === 0 ? "flex" : "none", this.chips.replaceChildren();
391
- const d = e.visibleActions();
392
- this.chips.style.display = d.length ? "flex" : "none";
393
- for (const r of d) this.chips.append(this.chipEl(r));
394
- const s = this.scroll.scrollHeight, c = this.scroll.scrollTop;
390
+ const l = e.visibleActions();
391
+ this.chips.style.display = l.length ? "flex" : "none";
392
+ for (const E of l) this.chips.append(this.chipEl(E));
393
+ const c = this.scroll.scrollHeight, i = this.scroll.scrollTop;
395
394
  if (this.scroll.replaceChildren(), this.subjectCard.childNodes.length && this.scroll.append(this.subjectCard), e.hasMoreHistory) {
396
- const r = n("div", "ocw-load-more");
397
- r.textContent = "↑ Loading earlier messages…", r.style.pointerEvents = "none", this.scroll.append(r);
395
+ const E = n("div", "ocw-load-more");
396
+ E.textContent = "↑ Loading earlier messages…", E.style.pointerEvents = "none", this.scroll.append(E);
398
397
  }
399
- let h = 0, b = null;
398
+ let f = 0, b = null;
400
399
  const y = [...e.messages()];
401
- for (let r = 0; r < y.length; r++) {
402
- const i = y[r], v = i.senderRole !== "system" && i.senderId !== this.me && !i.internal && i.senderId !== b;
403
- this.scroll.append(this.messageEl(i, e, v, r === y.length - 1)), i.senderRole !== "system" && (b = i.senderId), i.senderId !== this.me && i.seq > h && (h = i.seq);
400
+ for (let E = 0; E < y.length; E++) {
401
+ const r = y[E], a = r.senderRole !== "system" && r.senderId !== this.me && !r.internal && r.senderId !== b;
402
+ this.scroll.append(this.messageEl(r, e, a, E === y.length - 1)), r.senderRole !== "system" && (b = r.senderId), r.senderId !== this.me && r.seq > f && (f = r.seq);
404
403
  }
405
- c > 20 ? this.scroll.scrollTop = this.scroll.scrollHeight - s + c : this.scroll.scrollTop = this.scroll.scrollHeight, h > 0 && this.h.onReadUpTo(h);
406
- const l = [...e.typing];
407
- this.typing.classList.toggle("active", l.length > 0);
408
- const u = this.typing.querySelector(".ocw-typing-bubble");
409
- u && u.setAttribute("aria-label", l.length ? "typing" : ""), this.footer.style.display = e.whiteLabel ? "none" : "block";
410
- const x = e.messages().some((r) => r.senderRole === "guest");
411
- if (!!((A = e.preChat) != null && A.enabled) && !this.preChatDone && !x && (e.preChat.showWhen !== "offline" || e.offline))
412
- this.preChatBuilt || this.buildPreChatPanel(e.preChat), this.preChatPanel.style.display = "block", this.awayNotice.style.display = "none", (P = this.root.querySelector(".ocw-input")) == null || P.style.setProperty("display", "none");
404
+ i > 20 ? this.scroll.scrollTop = this.scroll.scrollHeight - c + i : this.scroll.scrollTop = this.scroll.scrollHeight, f > 0 && this.h.onReadUpTo(f);
405
+ const s = [...e.typing];
406
+ this.typing.classList.toggle("active", s.length > 0);
407
+ const x = this.typing.querySelector(".ocw-typing-bubble");
408
+ x && x.setAttribute("aria-label", s.length ? "typing" : ""), this.footer.style.display = e.whiteLabel ? "none" : "block";
409
+ const u = e.messages().some((E) => E.senderRole === "guest");
410
+ if (!!((B = e.preChat) != null && B.enabled) && !this.preChatDone && !u && (e.preChat.showWhen !== "offline" || e.offline))
411
+ this.preChatBuilt || this.buildPreChatPanel(e.preChat), this.preChatPanel.style.display = "block", this.awayNotice.style.display = "none", (R = this.root.querySelector(".ocw-input")) == null || R.style.setProperty("display", "none");
413
412
  else {
414
413
  if (this.preChatPanel.style.display = "none", e.offline) {
415
414
  this.awayNotice.firstChild || this.awayNotice.append(n("span", "ocw-away-icon", "🌙"), n("span", "", ""));
416
- const r = this.awayNotice.lastChild;
417
- r.textContent = e.offlineMessage || ((B = this.cfg.i18n) == null ? void 0 : B.offline) || "We're away right now — send your message and we'll reply as soon as we're back.", this.awayNotice.style.display = "flex";
415
+ const E = this.awayNotice.lastChild;
416
+ E.textContent = e.offlineMessage || ((A = this.cfg.i18n) == null ? void 0 : A.offline) || "We're away right now — send your message and we'll reply as soon as we're back.", this.awayNotice.style.display = "flex";
418
417
  } else
419
418
  this.awayNotice.style.display = "none";
420
- (z = this.root.querySelector(".ocw-input")) == null || z.style.removeProperty("display");
419
+ (P = this.root.querySelector(".ocw-input")) == null || P.style.removeProperty("display");
421
420
  }
422
- const j = ["resolved", "closed", "sold", "issued", "checked_out"];
423
- this.h.onCsat && !this.csatSubmitted && j.includes(e.state) && e.messages().length > 0 && (this.csatPanel.style.display === "none" && this.buildCsatPanel(), this.csatPanel.style.display = "block");
424
- const R = j.includes(e.state);
425
- if (e.offline ? (this.headStatus.textContent = `● ${e.offlineMessage || ((O = this.cfg.i18n) == null ? void 0 : O.away) || "Away"}`, this.headStatus.className = "ocw-head-status away", this.headStatus.style.display = "") : e.conversationId ? (this.headStatus.textContent = `● ${((T = this.cfg.i18n) == null ? void 0 : T.online) ?? "Online"}`, this.headStatus.className = "ocw-head-status online", this.headStatus.style.display = "") : this.headStatus.style.display = "none", R && e.messages().length > 0) {
426
- const r = n("div", "ocw-resolved-note", `— ${((_ = this.cfg.i18n) == null ? void 0 : _.resolved) ?? "Marked as resolved"} —`);
427
- this.scroll.append(r), this.reopenBtn.style.display = "block";
421
+ const I = ["resolved", "closed", "sold", "issued", "checked_out"];
422
+ this.h.onCsat && !this.csatSubmitted && I.includes(e.state) && e.messages().length > 0 && (this.csatPanel.style.display === "none" && this.buildCsatPanel(), this.csatPanel.style.display = "block");
423
+ const T = I.includes(e.state);
424
+ if (e.offline ? (this.headStatus.textContent = `● ${e.offlineMessage || ((O = this.cfg.i18n) == null ? void 0 : O.away) || "Away"}`, this.headStatus.className = "ocw-head-status away", this.headStatus.style.display = "") : e.conversationId ? (this.headStatus.textContent = `● ${((j = this.cfg.i18n) == null ? void 0 : j.online) ?? "Online"}`, this.headStatus.className = "ocw-head-status online", this.headStatus.style.display = "") : this.headStatus.style.display = "none", T && e.messages().length > 0) {
425
+ const E = n("div", "ocw-resolved-note", `— ${((_ = this.cfg.i18n) == null ? void 0 : _.resolved) ?? "Marked as resolved"} —`);
426
+ this.scroll.append(E), this.reopenBtn.style.display = "block";
428
427
  } else
429
428
  this.reopenBtn.style.display = "none";
430
429
  }
431
- setConnStatus(e, d) {
430
+ setConnStatus(e, l) {
432
431
  if (e === "open") {
433
432
  this.connStatus.style.display = "none";
434
433
  return;
435
434
  }
436
435
  this.connStatus.style.display = "";
437
- const s = e === "error";
438
- this.connStatus.className = `ocw-conn-status${s ? " err" : e === "reconnecting" ? " warn" : ""}`, this.connStatus.textContent = s ? `⚠ ${d ?? "Chat unavailable"}` : e === "reconnecting" ? d ?? "↻ reconnecting…" : "● connecting…";
436
+ const c = e === "error";
437
+ this.connStatus.className = `ocw-conn-status${c ? " err" : e === "reconnecting" ? " warn" : ""}`, this.connStatus.textContent = c ? `⚠ ${l ?? "Chat unavailable"}` : e === "reconnecting" ? l ?? "↻ reconnecting…" : "● connecting…";
439
438
  }
440
439
  buildPreChatPanel(e) {
441
- var l;
440
+ var s;
442
441
  this.preChatBuilt = !0, this.preChatPanel.replaceChildren(), this.preChatPanel.append(n("div", "ocw-prechat-title", e.title ?? "Before we start…"));
443
- const d = n("div", "ocw-offline-form"), s = {};
444
- for (const u of e.fields ?? ["name", "email"]) {
445
- const x = n("input", "ocw-offline-input");
446
- x.type = u === "email" ? "email" : u === "phone" ? "tel" : "text", x.placeholder = u === "name" ? "Your name" : u === "email" ? "Your email" : "Your phone number", s[u] = x, d.append(x);
442
+ const l = n("div", "ocw-offline-form"), c = {};
443
+ for (const x of e.fields ?? ["name", "email"]) {
444
+ const u = n("input", "ocw-offline-input");
445
+ u.type = x === "email" ? "email" : x === "phone" ? "tel" : "text", u.placeholder = x === "name" ? "Your name" : x === "email" ? "Your email" : "Your phone number", c[x] = u, l.append(u);
447
446
  }
448
- let c = null;
449
- if ((l = e.topics) != null && l.length) {
450
- c = n("select", void 0);
451
- const u = document.createElement("option");
452
- u.value = "", u.textContent = "What is this about?", c.append(u);
453
- for (const x of e.topics) {
454
- const a = document.createElement("option");
455
- a.value = x, a.textContent = x, c.append(a);
447
+ let i = null;
448
+ if ((s = e.topics) != null && s.length) {
449
+ i = n("select", void 0);
450
+ const x = document.createElement("option");
451
+ x.value = "", x.textContent = "What is this about?", i.append(x);
452
+ for (const u of e.topics) {
453
+ const d = document.createElement("option");
454
+ d.value = u, d.textContent = u, i.append(d);
456
455
  }
457
- d.append(c);
456
+ l.append(i);
458
457
  }
459
- let h = null, b = null;
458
+ let f = null, b = null;
460
459
  if (e.callbackOption) {
461
- const u = n("label", "ocw-prechat-cb");
462
- h = document.createElement("input"), h.type = "checkbox", u.append(h, document.createTextNode("📞 Request a call back")), d.append(u), s.phone || (b = n("input", "ocw-offline-input"), b.type = "tel", b.placeholder = "Phone number for the call", b.style.display = "none", h.addEventListener("change", () => b.style.setProperty("display", h.checked ? "block" : "none")), d.append(b));
460
+ const x = n("label", "ocw-prechat-cb");
461
+ f = document.createElement("input"), f.type = "checkbox", x.append(f, document.createTextNode("📞 Request a call back")), l.append(x), c.phone || (b = n("input", "ocw-offline-input"), b.type = "tel", b.placeholder = "Phone number for the call", b.style.display = "none", f.addEventListener("change", () => b.style.setProperty("display", f.checked ? "block" : "none")), l.append(b));
463
462
  }
464
463
  const y = n("button", "ocw-offline-submit", "Start chat");
465
464
  y.type = "button", y.addEventListener("click", () => {
466
- var j, R, E, A, P, B, z;
467
- const u = (j = s.email) == null ? void 0 : j.value.trim();
468
- if (s.email && (!u || !/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(u))) {
469
- s.email.focus();
465
+ var I, T, L, B, R, A, P;
466
+ const x = (I = c.email) == null ? void 0 : I.value.trim();
467
+ if (c.email && (!x || !/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(x))) {
468
+ c.email.focus();
470
469
  return;
471
470
  }
472
- const x = !!(h != null && h.checked), a = (((R = s.phone) == null ? void 0 : R.value) ?? (b == null ? void 0 : b.value) ?? "").trim();
473
- if (x && !a) {
474
- (E = s.phone ?? b) == null || E.focus();
471
+ const u = !!(f != null && f.checked), d = (((T = c.phone) == null ? void 0 : T.value) ?? (b == null ? void 0 : b.value) ?? "").trim();
472
+ if (u && !d) {
473
+ (L = c.phone ?? b) == null || L.focus();
475
474
  return;
476
475
  }
477
- if (c && ((A = e.topics) != null && A.length) && !c.value) {
478
- c.focus();
476
+ if (i && ((B = e.topics) != null && B.length) && !i.value) {
477
+ i.focus();
479
478
  return;
480
479
  }
481
- y.disabled = !0, this.completePreChat(), (z = (B = this.h).onPreChat) == null || z.call(B, {
482
- ...(P = s.name) != null && P.value.trim() ? { name: s.name.value.trim() } : {},
483
- ...u ? { email: u } : {},
484
- ...a ? { phone: a } : {},
485
- ...c != null && c.value ? { topic: c.value } : {},
486
- ...x ? { callback: !0 } : {}
480
+ y.disabled = !0, this.completePreChat(), (P = (A = this.h).onPreChat) == null || P.call(A, {
481
+ ...(R = c.name) != null && R.value.trim() ? { name: c.name.value.trim() } : {},
482
+ ...x ? { email: x } : {},
483
+ ...d ? { phone: d } : {},
484
+ ...i != null && i.value ? { topic: i.value } : {},
485
+ ...u ? { callback: !0 } : {}
487
486
  });
488
- }), d.append(y), this.preChatPanel.append(d);
487
+ }), l.append(y), this.preChatPanel.append(l);
489
488
  }
490
489
  /** Mark pre-chat complete (submitted now or in a previous session). */
491
490
  completePreChat() {
@@ -495,9 +494,9 @@ class Ze {
495
494
  showDeflection(e) {
496
495
  if (!e.length) return this.hideDeflection();
497
496
  this.deflectPanel.replaceChildren(), this.deflectPanel.append(n("div", "ocw-deflect-hint", "Instant answers — tap to expand"));
498
- for (const d of e.slice(0, 3)) {
499
- const s = n("button", "ocw-deflect-card");
500
- s.append(n("div", "ocw-deflect-q", d.title), n("div", "ocw-deflect-a", d.answer)), s.addEventListener("click", () => s.classList.toggle("open")), this.deflectPanel.append(s);
497
+ for (const l of e.slice(0, 3)) {
498
+ const c = n("button", "ocw-deflect-card");
499
+ c.append(n("div", "ocw-deflect-q", l.title), n("div", "ocw-deflect-a", l.answer)), c.addEventListener("click", () => c.classList.toggle("open")), this.deflectPanel.append(c);
501
500
  }
502
501
  this.deflectPanel.style.display = "flex";
503
502
  }
@@ -506,266 +505,275 @@ class Ze {
506
505
  }
507
506
  buildCsatPanel() {
508
507
  this.csatPanel.replaceChildren(), this.csatPanel.append(n("div", "ocw-csat-title", "How did we do?"));
509
- const e = n("div", "ocw-csat-stars"), d = [];
510
- for (let s = 1; s <= 5; s++) {
511
- const c = n("button", "ocw-csat-star", "★");
512
- c.dataset.score = String(s), c.addEventListener("mouseenter", () => d.forEach((h, b) => h.classList.toggle("lit", b < s))), c.addEventListener("mouseleave", () => d.forEach((h) => h.classList.remove("lit"))), c.addEventListener("click", () => {
513
- var h, b;
514
- this.csatSubmitted = !0, this.csatPanel.replaceChildren(n("div", "ocw-csat-done", `Thanks for your ${s}★ rating!`)), (b = (h = this.h).onCsat) == null || b.call(h, s);
515
- }), d.push(c), e.append(c);
508
+ const e = n("div", "ocw-csat-stars"), l = [];
509
+ for (let c = 1; c <= 5; c++) {
510
+ const i = n("button", "ocw-csat-star", "★");
511
+ i.dataset.score = String(c), i.addEventListener("mouseenter", () => l.forEach((f, b) => f.classList.toggle("lit", b < c))), i.addEventListener("mouseleave", () => l.forEach((f) => f.classList.remove("lit"))), i.addEventListener("click", () => {
512
+ var f, b;
513
+ this.csatSubmitted = !0, this.csatPanel.replaceChildren(n("div", "ocw-csat-done", `Thanks for your ${c}★ rating!`)), (b = (f = this.h).onCsat) == null || b.call(f, c);
514
+ }), l.push(i), e.append(i);
516
515
  }
517
516
  this.csatPanel.append(e);
518
517
  }
519
518
  buildSubjectCard(e) {
520
519
  if (this.subjectBuilt) return;
521
- const d = e.subject, s = this.cfg.subject, c = (d == null ? void 0 : d.title) ?? (s == null ? void 0 : s.title);
522
- if (!c) return;
523
- this.subjectBuilt = !0, this.subjectCard.replaceChildren(), this.subjectCard.append(n("div", "ocw-subject-title", c)), s != null && s.subtitle && this.subjectCard.append(n("div", "ocw-subject-sub", s.subtitle));
524
- const h = n("div", "ocw-tags");
525
- if (d) for (const [y, l] of Object.entries(d.fields)) h.append(n("span", "ocw-tag", `${y}: ${l}`));
526
- else for (const y of (s == null ? void 0 : s.tags) ?? []) h.append(n("span", "ocw-tag", y));
527
- h.childNodes.length && this.subjectCard.append(h);
528
- const b = (d == null ? void 0 : d.state) ?? (s == null ? void 0 : s.status);
520
+ const l = e.subject, c = this.cfg.subject, i = (l == null ? void 0 : l.title) ?? (c == null ? void 0 : c.title);
521
+ if (!i) return;
522
+ this.subjectBuilt = !0, this.subjectCard.replaceChildren(), this.subjectCard.append(n("div", "ocw-subject-title", i)), c != null && c.subtitle && this.subjectCard.append(n("div", "ocw-subject-sub", c.subtitle));
523
+ const f = n("div", "ocw-tags");
524
+ if (l) for (const [y, s] of Object.entries(l.fields)) f.append(n("span", "ocw-tag", `${y}: ${s}`));
525
+ else for (const y of (c == null ? void 0 : c.tags) ?? []) f.append(n("span", "ocw-tag", y));
526
+ f.childNodes.length && this.subjectCard.append(f);
527
+ const b = (l == null ? void 0 : l.state) ?? (c == null ? void 0 : c.status);
529
528
  b && (this.statusBadge.textContent = b, this.statusBadge.style.display = "inline-flex");
530
529
  }
531
530
  chipEl(e) {
532
- const d = n("button", "ocw-chip", e.icon ? `${e.icon} ${e.label}` : e.label);
533
- return d.dataset.actionId = e.id, d.addEventListener("click", async () => {
534
- var s;
535
- e.confirm && !await this.confirm(e.label) || ((s = e.input) != null && s.length ? this.openForm(e) : this.h.onInvoke(e.id));
536
- }), d;
531
+ const l = n("button", "ocw-chip", e.icon ? `${e.icon} ${e.label}` : e.label);
532
+ return l.dataset.actionId = e.id, l.addEventListener("click", async () => {
533
+ var c;
534
+ e.confirm && !await this.confirm(e.label) || ((c = e.input) != null && c.length ? this.openForm(e) : this.h.onInvoke(e.id));
535
+ }), l;
537
536
  }
538
537
  /** In-widget confirmation modal (replaces window.confirm). */
539
538
  confirm(e) {
540
- return new Promise((d) => {
541
- const s = n("div", "ocw-modal"), c = n("div", "ocw-modal-card");
542
- c.append(n("div", "ocw-modal-title", e)), c.append(n("div", "ocw-modal-body", `Confirm “${e}”?`));
543
- const h = n("div", "ocw-modal-actions"), b = n("button", "ocw-modal-cancel", "Cancel"), y = n("button", "ocw-modal-ok", "Confirm"), l = (u) => {
544
- s.remove(), d(u);
539
+ return new Promise((l) => {
540
+ const c = n("div", "ocw-modal"), i = n("div", "ocw-modal-card");
541
+ i.append(n("div", "ocw-modal-title", e)), i.append(n("div", "ocw-modal-body", `Confirm “${e}”?`));
542
+ const f = n("div", "ocw-modal-actions"), b = n("button", "ocw-modal-cancel", "Cancel"), y = n("button", "ocw-modal-ok", "Confirm"), s = (x) => {
543
+ c.remove(), l(x);
545
544
  };
546
- b.addEventListener("click", () => l(!1)), y.addEventListener("click", () => l(!0)), s.addEventListener("click", (u) => {
547
- u.target === s && l(!1);
548
- }), h.append(b, y), c.append(h), s.append(c), this.root.append(s), y.focus();
545
+ b.addEventListener("click", () => s(!1)), y.addEventListener("click", () => s(!0)), c.addEventListener("click", (x) => {
546
+ x.target === c && s(!1);
547
+ }), f.append(b, y), i.append(f), c.append(i), this.root.append(c), y.focus();
549
548
  });
550
549
  }
551
550
  /** Inline form for a form-effect action: typed inputs (date picker, number,
552
- * text) rendered above the composer — no browser prompts. */
553
- openForm(e) {
554
- var y, l;
551
+ * text) rendered above the composer — no browser prompts. `prefill` seeds
552
+ * field values (search pre-fill) — deterministic parse, correctable before
553
+ * submit. */
554
+ openForm(e, l) {
555
+ var s, x;
555
556
  this.formHost.replaceChildren();
556
- const d = n("div", "ocw-form");
557
- d.append(n("div", "ocw-form-title", e.icon ? `${e.icon} ${e.label}` : e.label));
558
- const s = /* @__PURE__ */ new Map();
557
+ const c = n("div", "ocw-form");
558
+ c.append(n("div", "ocw-form-title", e.icon ? `${e.icon} ${e.label}` : e.label));
559
+ const i = /* @__PURE__ */ new Map();
559
560
  for (const u of e.input ?? []) {
560
- const x = n("label", "ocw-form-row");
561
- if (x.append(n("span", "ocw-form-lbl", u.label)), u.type === "select" && ((y = u.options) != null && y.length)) {
562
- const a = n("select", "ocw-form-input");
563
- u.required || a.append(n("option", void 0, "— select —"));
564
- for (const j of u.options) {
565
- const R = n("option");
566
- R.value = j, R.textContent = j, a.append(R);
561
+ const d = l == null ? void 0 : l[u.name], I = n("label", "ocw-form-row");
562
+ if (I.append(n("span", "ocw-form-lbl", u.label)), u.type === "select" && ((s = u.options) != null && s.length)) {
563
+ const T = n("select", "ocw-form-input");
564
+ u.required || T.append(n("option", void 0, "— select —"));
565
+ for (const L of u.options) {
566
+ const B = n("option");
567
+ B.value = L, B.textContent = L, T.append(B);
567
568
  }
568
- u.required && (a.required = !0), x.append(a), s.set(u.name, a);
569
+ u.required && (T.required = !0), d != null && u.options.includes(d) && (T.value = d), I.append(T), i.set(u.name, T);
569
570
  } else {
570
- const a = n("input", "ocw-form-input");
571
- a.type = u.type === "number" ? "number" : u.type === "date" ? "datetime-local" : "text", u.required && (a.required = !0), x.append(a), s.set(u.name, a);
571
+ const T = n("input", "ocw-form-input");
572
+ T.type = u.type === "number" ? "number" : u.type === "date" ? "datetime-local" : "text", u.required && (T.required = !0), d != null && d !== "" && (T.value = d), I.append(T), i.set(u.name, T);
572
573
  }
573
- d.append(x);
574
+ c.append(I);
574
575
  }
575
- const c = n("div", "ocw-form-actions"), h = n("button", "ocw-form-cancel", "Cancel"), b = n("button", "ocw-form-submit", "Send");
576
- h.addEventListener("click", () => this.formHost.replaceChildren()), b.addEventListener("click", () => {
576
+ const f = n("div", "ocw-form-actions"), b = n("button", "ocw-form-cancel", "Cancel"), y = n("button", "ocw-form-submit", "Send");
577
+ b.addEventListener("click", () => this.formHost.replaceChildren()), y.addEventListener("click", () => {
577
578
  const u = {};
578
- for (const [x, a] of s) {
579
- if (a.required && !a.value) {
580
- a.style.borderColor = "#e5484d";
579
+ for (const [d, I] of i) {
580
+ if (I.required && !I.value) {
581
+ I.style.borderColor = "#e5484d";
581
582
  return;
582
583
  }
583
- u[x] = a.type === "number" ? Number(a.value) : a.value;
584
+ u[d] = I.type === "number" ? Number(I.value) : I.value;
584
585
  }
585
586
  this.formHost.replaceChildren(), this.h.onInvoke(e.id, u);
586
- }), c.append(h, b), d.append(c), this.formHost.append(d), (l = s.values().next().value) == null || l.focus();
587
+ }), f.append(b, y), c.append(f), this.formHost.append(c), (x = i.values().next().value) == null || x.focus();
587
588
  }
588
- messageEl(e, d, s = !1, c = !1) {
589
- var R, E, A, P, B, z, O, T, _;
589
+ messageEl(e, l, c = !1, i = !1) {
590
+ var T, L, B, R, A, P, O, j, _, E;
590
591
  if (e.senderRole === "system") {
591
592
  const r = n("div", "ocw-sys");
592
- return r.textContent = e.deletedAt ? "message deleted" : re(e.content), r;
593
+ return r.textContent = e.deletedAt ? "message deleted" : se(e.content), r;
593
594
  }
594
- const h = e.senderId === this.me, b = !!e.internal, y = n("div", `ocw-row ${b ? "ocw-note mine" : h ? "mine" : "theirs"} ${e.senderRole === "bot" ? "ocw-bot" : ""}`), l = n("div");
595
- if (s) {
596
- const r = e.senderRole === "bot" ? ((R = this.cfg.i18n) == null ? void 0 : R.aiAssistant) ?? "AI Assistant" : ((E = this.cfg.subject) == null ? void 0 : E.ownerLabel) ?? ((A = this.cfg.subject) == null ? void 0 : A.title) ?? "Support";
597
- l.append(n("div", "ocw-msg-sender", r));
595
+ const f = e.senderId === this.me, b = !!e.internal, y = n("div", `ocw-row ${b ? "ocw-note mine" : f ? "mine" : "theirs"} ${e.senderRole === "bot" ? "ocw-bot" : ""}`), s = n("div");
596
+ if (c) {
597
+ const r = e.senderRole === "bot" ? ((T = this.cfg.i18n) == null ? void 0 : T.aiAssistant) ?? "AI Assistant" : ((L = this.cfg.subject) == null ? void 0 : L.ownerLabel) ?? ((B = this.cfg.subject) == null ? void 0 : B.title) ?? "Support";
598
+ s.append(n("div", "ocw-msg-sender", r));
598
599
  }
599
- const u = n("div", "ocw-bubble-wrap");
600
+ const x = n("div", "ocw-bubble-wrap");
600
601
  if (e.replyToId) {
601
602
  const r = n("div", "ocw-reply-to", "↩ replying to a message");
602
- r.style.cssText = "font-size:11px;color:var(--ocw-mut);margin-bottom:2px;font-style:italic", l.append(r);
603
+ r.style.cssText = "font-size:11px;color:var(--ocw-mut);margin-bottom:2px;font-style:italic", s.append(r);
603
604
  }
604
- const x = n("div", "ocw-bubble");
605
- let a = null;
606
- if (e.deletedAt) x.append(n("span", "ocw-deleted", "message deleted"));
605
+ const u = n("div", "ocw-bubble");
606
+ let d = null;
607
+ if (e.deletedAt) u.append(n("span", "ocw-deleted", "message deleted"));
607
608
  else if (e.content.kind === "attachment") {
608
609
  const r = e.content;
609
- if ((P = r.mime) != null && P.startsWith("image/")) {
610
- const i = document.createElement("img");
611
- i.src = r.url, i.alt = r.name ?? "image", i.style.cssText = "max-width:220px;max-height:160px;border-radius:10px;display:block;cursor:pointer", i.addEventListener("click", () => window.open(r.url, "_blank")), x.append(i);
612
- } else if ((B = r.mime) != null && B.startsWith("video/")) {
613
- const i = document.createElement("video");
614
- i.src = r.url, i.controls = !0, i.style.cssText = "max-width:240px;max-height:180px;border-radius:10px;display:block", x.append(i);
610
+ if ((R = r.mime) != null && R.startsWith("image/")) {
611
+ const a = document.createElement("img");
612
+ a.src = r.url, a.alt = r.name ?? "image", a.style.cssText = "max-width:220px;max-height:160px;border-radius:10px;display:block;cursor:pointer", a.addEventListener("click", () => window.open(r.url, "_blank")), u.append(a);
613
+ } else if ((A = r.mime) != null && A.startsWith("video/")) {
614
+ const a = document.createElement("video");
615
+ a.src = r.url, a.controls = !0, a.style.cssText = "max-width:240px;max-height:180px;border-radius:10px;display:block", u.append(a);
615
616
  } else {
616
- const i = document.createElement("a");
617
- i.href = r.url, i.target = "_blank", i.rel = "noopener", i.style.cssText = "display:flex;align-items:center;gap:8px;color:inherit;text-decoration:none", i.append(n("span", void 0, "📄"), n("span", void 0, r.name ?? "file")), x.append(i);
617
+ const a = document.createElement("a");
618
+ a.href = r.url, a.target = "_blank", a.rel = "noopener", a.style.cssText = "display:flex;align-items:center;gap:8px;color:inherit;text-decoration:none", a.append(n("span", void 0, "📄"), n("span", void 0, r.name ?? "file")), u.append(a);
618
619
  }
619
620
  } else if (e.content.kind === "appointment") {
620
- const r = e.content, i = n("div", "ocw-appt");
621
- i.append(n("div", "ocw-appt-title", `📅 ${r.title}`)), i.append(n("div", "ocw-appt-time", new Date(r.startIso).toLocaleString() + " – " + new Date(r.endIso).toLocaleTimeString())), r.location && i.append(n("div", "ocw-appt-loc", `📍 ${r.location}`)), r.description && i.append(n("div", "ocw-appt-desc", r.description));
622
- const v = n("div", "ocw-appt-links"), f = document.createElement("a");
623
- f.href = r.googleUrl, f.target = "_blank", f.rel = "noopener", f.className = "ocw-appt-btn", f.textContent = "📅 Add to Google Calendar";
624
- const m = document.createElement("a");
625
- m.href = r.icalUrl, m.download = `${r.title}.ics`, m.className = "ocw-appt-btn ocw-appt-btn-sec", m.textContent = "🍎 Apple / iCal", v.append(f, m), i.append(v), x.append(i);
621
+ const r = e.content, a = n("div", "ocw-appt");
622
+ a.append(n("div", "ocw-appt-title", `📅 ${r.title}`)), a.append(n("div", "ocw-appt-time", new Date(r.startIso).toLocaleString() + " – " + new Date(r.endIso).toLocaleTimeString())), r.location && a.append(n("div", "ocw-appt-loc", `📍 ${r.location}`)), r.description && a.append(n("div", "ocw-appt-desc", r.description));
623
+ const h = n("div", "ocw-appt-links"), m = document.createElement("a");
624
+ m.href = r.googleUrl, m.target = "_blank", m.rel = "noopener", m.className = "ocw-appt-btn", m.textContent = "📅 Add to Google Calendar";
625
+ const v = document.createElement("a");
626
+ v.href = r.icalUrl, v.download = `${r.title}.ics`, v.className = "ocw-appt-btn ocw-appt-btn-sec", v.textContent = "🍎 Apple / iCal", h.append(m, v), a.append(h), u.append(a);
626
627
  } else
627
- a = Qe(x, re(e.content)), e.editedAt && x.append(n("span", "ocw-edited", "(edited)"));
628
- if (u.append(x), c && !e.deletedAt && e.content.kind === "text" && ((z = e.content.quickReplies) != null && z.length)) {
628
+ d = Je(u, se(e.content)), e.editedAt && u.append(n("span", "ocw-edited", "(edited)"));
629
+ if (x.append(u), i && !e.deletedAt && e.content.kind === "text" && ((P = e.content.quickReplies) != null && P.length)) {
629
630
  const r = n("div", "ocw-flow-choices");
630
631
  r.style.cssText = "display:flex;flex-wrap:wrap;gap:6px;margin-top:6px";
631
- for (const i of e.content.quickReplies) {
632
- const v = n("button", "ocw-flow-choice", i);
633
- v.type = "button", v.style.cssText = "border:1px solid var(--ocw-bd,rgba(0,0,0,.12));background:var(--ocw-bg,#fff);color:inherit;border-radius:14px;padding:5px 12px;font:inherit;font-size:13px;cursor:pointer", v.addEventListener("click", () => {
634
- r.querySelectorAll("button").forEach((f) => f.disabled = !0), r.style.opacity = "0.5", this.h.onSend(i);
635
- }), r.append(v);
632
+ for (const a of e.content.quickReplies) {
633
+ const h = n("button", "ocw-flow-choice", a);
634
+ h.type = "button", h.style.cssText = "border:1px solid var(--ocw-bd,rgba(0,0,0,.12));background:var(--ocw-bg,#fff);color:inherit;border-radius:14px;padding:5px 12px;font:inherit;font-size:13px;cursor:pointer", h.addEventListener("click", () => {
635
+ r.querySelectorAll("button").forEach((m) => m.disabled = !0), r.style.opacity = "0.5", this.h.onSend(a);
636
+ }), r.append(h);
637
+ }
638
+ x.append(r);
639
+ }
640
+ if (i && !e.deletedAt && e.content.kind === "form") {
641
+ const r = e.content, a = l.actionById(r.actionId);
642
+ if ((O = a == null ? void 0 : a.input) != null && O.length) {
643
+ const h = n("button", "ocw-chip", a.icon ? `${a.icon} ${a.label}` : a.label);
644
+ h.type = "button", h.style.cssText = "margin-top:6px", h.addEventListener("click", async () => {
645
+ a.confirm && !await this.confirm(a.label) || this.openForm(a, r.prefill);
646
+ }), x.append(h);
636
647
  }
637
- u.append(r);
638
648
  }
639
- if (!h && !b && this.h.onTranslate && e.content.kind === "text" && !e.deletedAt && e.seq > 0 && a) {
649
+ if (!f && !b && this.h.onTranslate && e.content.kind === "text" && !e.deletedAt && e.seq > 0 && d) {
640
650
  const r = e.content.text;
641
651
  if (r.trim()) {
642
- const i = n("button", "ocw-translate-btn", "🌐");
643
- i.type = "button", i.title = "Translate";
644
- const v = n("div", "ocw-translation");
645
- v.style.display = "none", x.append(v);
646
- const f = (S) => {
647
- v.textContent = S, v.style.display = "", this.showingTranslation.add(e.id), i.textContent = "", i.title = "Show original";
648
- }, m = () => {
649
- v.style.display = "none", this.showingTranslation.delete(e.id), i.textContent = "🌐", i.title = "Translate";
652
+ const a = n("button", "ocw-translate-btn");
653
+ a.type = "button", a.innerHTML = '<span aria-hidden="true">🌐</span> Translate', a.title = "Translate";
654
+ const h = n("div", "ocw-translation");
655
+ h.style.display = "none", u.append(h);
656
+ const m = (w) => {
657
+ h.textContent = w, h.style.display = "", this.showingTranslation.add(e.id), a.innerHTML = '<span aria-hidden="true">↩</span> Original', a.title = "Show original";
658
+ }, v = () => {
659
+ h.style.display = "none", this.showingTranslation.delete(e.id), a.innerHTML = '<span aria-hidden="true">🌐</span> Translate', a.title = "Translate";
650
660
  };
651
- i.addEventListener("click", (S) => {
652
- if (S.stopPropagation(), this.showingTranslation.has(e.id)) {
653
- m();
661
+ a.addEventListener("click", (w) => {
662
+ if (w.stopPropagation(), this.showingTranslation.has(e.id)) {
663
+ v();
654
664
  return;
655
665
  }
656
- const w = this.translationCache.get(e.id);
657
- if (w !== void 0) {
658
- f(w);
666
+ const S = this.translationCache.get(e.id);
667
+ if (S !== void 0) {
668
+ m(S);
659
669
  return;
660
670
  }
661
- i.textContent = "⏳", this.h.onTranslate(r).then((I) => {
662
- if (I === null) {
663
- i.textContent = "⚠️", i.title = "Translation unavailable", setTimeout(() => {
664
- i.textContent = "🌐", i.title = "Translate";
665
- }, 1500);
671
+ a.textContent = "⏳", this.h.onTranslate(r).then((z) => {
672
+ if (z === null) {
673
+ a.textContent = "⚠️ Unavailable", setTimeout(() => v(), 1500);
666
674
  return;
667
675
  }
668
- this.translationCache.set(e.id, I), f(I);
676
+ this.translationCache.set(e.id, z), m(z);
669
677
  });
670
- }), u.append(i);
678
+ }), x.append(a);
671
679
  const k = this.translationCache.get(e.id);
672
- this.showingTranslation.has(e.id) && k !== void 0 && f(k);
680
+ this.showingTranslation.has(e.id) && k !== void 0 && m(k);
673
681
  }
674
682
  }
675
- if (h && !e.deletedAt && e.seq > 0 && (this.h.onEdit ?? this.h.onDelete)) {
683
+ if (f && !e.deletedAt && e.seq > 0 && (this.h.onEdit ?? this.h.onDelete)) {
676
684
  const r = n("div", "ocw-msg-menu");
677
685
  if (this.h.onEdit) {
678
- const i = n("button", void 0, "✏️");
679
- i.title = "Edit", i.addEventListener("click", (v) => {
680
- v.stopPropagation();
681
- const f = re(e.content), m = document.createElement("textarea");
682
- m.value = f, m.rows = Math.min(4, Math.ceil(f.length / 40) + 1), m.style.cssText = "width:100%;resize:vertical;border:1px solid var(--ocw-accent);border-radius:8px;padding:6px 10px;font:inherit;font-size:14px;background:var(--ocw-card);color:#1c1b1a;box-sizing:border-box";
686
+ const a = n("button", void 0, "✏️");
687
+ a.title = "Edit", a.addEventListener("click", (h) => {
688
+ h.stopPropagation();
689
+ const m = se(e.content), v = document.createElement("textarea");
690
+ v.value = m, v.rows = Math.min(4, Math.ceil(m.length / 40) + 1), v.style.cssText = "width:100%;resize:vertical;border:1px solid var(--ocw-accent);border-radius:8px;padding:6px 10px;font:inherit;font-size:14px;background:var(--ocw-card);color:#1c1b1a;box-sizing:border-box";
683
691
  const k = n("button", "ocw-form-submit", "Save");
684
692
  k.style.cssText = "margin-top:6px;padding:5px 14px;font-size:13px";
685
- const S = n("button", "ocw-form-cancel", "Cancel");
686
- S.style.cssText = "margin-top:6px;padding:5px 10px;font-size:13px";
687
- const w = n("div");
688
- w.style.cssText = "display:flex;gap:6px;justify-content:flex-end", w.append(S, k);
689
- const I = n("div");
690
- I.append(m, w), x.replaceChildren(I), m.focus(), m.select();
691
- const N = () => x.replaceChildren(a ?? document.createTextNode(f));
692
- S.addEventListener("click", N), k.addEventListener("click", () => {
693
- const D = m.value.trim();
694
- D && D !== f && this.h.onEdit(e.id, D), N();
695
- }), m.addEventListener("keydown", (D) => {
696
- D.key === "Enter" && !D.shiftKey && (D.preventDefault(), k.click()), D.key === "Escape" && N();
693
+ const w = n("button", "ocw-form-cancel", "Cancel");
694
+ w.style.cssText = "margin-top:6px;padding:5px 10px;font-size:13px";
695
+ const S = n("div");
696
+ S.style.cssText = "display:flex;gap:6px;justify-content:flex-end", S.append(w, k);
697
+ const z = n("div");
698
+ z.append(v, S), u.replaceChildren(z), v.focus(), v.select();
699
+ const U = () => u.replaceChildren(d ?? document.createTextNode(m));
700
+ w.addEventListener("click", U), k.addEventListener("click", () => {
701
+ const D = v.value.trim();
702
+ D && D !== m && this.h.onEdit(e.id, D), U();
703
+ }), v.addEventListener("keydown", (D) => {
704
+ D.key === "Enter" && !D.shiftKey && (D.preventDefault(), k.click()), D.key === "Escape" && U();
697
705
  });
698
- }), r.append(i);
706
+ }), r.append(a);
699
707
  }
700
708
  if (this.h.onDelete) {
701
- const i = n("button", "del", "🗑");
702
- i.title = "Delete", i.addEventListener("click", (v) => {
703
- v.stopPropagation(), this.h.onDelete(e.id);
704
- }), r.append(i);
709
+ const a = n("button", "del", "🗑");
710
+ a.title = "Delete", a.addEventListener("click", (h) => {
711
+ h.stopPropagation(), this.h.onDelete(e.id);
712
+ }), r.append(a);
705
713
  }
706
- u.append(r);
714
+ x.append(r);
707
715
  }
708
- if (l.append(u), e.senderRole === "bot" && !e.deletedAt && e.seq > 0 && e.content.kind === "text") {
716
+ if (s.append(x), e.senderRole === "bot" && !e.deletedAt && e.seq > 0 && e.content.kind === "text") {
709
717
  const r = e.content.citations;
710
718
  if (r != null && r.length) {
711
- const i = n("div", "ocw-cites");
712
- i.style.cssText = "margin-top:4px;font-size:11px;color:var(--ocw-mut,#667)", i.textContent = `${((O = this.cfg.i18n) == null ? void 0 : O.sources) ?? "Sources"}: ${r.map((v) => v.source).join(", ")}`, l.append(i);
719
+ const a = n("div", "ocw-cites");
720
+ a.style.cssText = "margin-top:4px;font-size:11px;color:var(--ocw-mut,#667)", a.textContent = `${((j = this.cfg.i18n) == null ? void 0 : j.sources) ?? "Sources"}: ${r.map((h) => h.source).join(", ")}`, s.append(a);
713
721
  }
714
722
  if (this.h.onReact) {
715
- const i = n("div", "ocw-bot-feedback");
716
- i.style.cssText = "display:flex;gap:6px;margin-top:4px";
717
- const v = (f, m) => {
718
- const k = n("button", "ocw-fb-btn", f);
719
- k.type = "button", k.title = m, k.style.cssText = "border:1px solid var(--ocw-bd,rgba(0,0,0,.12));background:transparent;border-radius:12px;padding:1px 8px;font-size:12px;cursor:pointer;opacity:.7";
720
- const S = () => {
721
- var w, I;
722
- return !!((I = (w = e.reactions) == null ? void 0 : w[f]) != null && I.includes(this.me));
723
+ const a = n("div", "ocw-bot-feedback");
724
+ a.style.cssText = "display:flex;gap:6px;margin-top:4px";
725
+ const h = (m, v) => {
726
+ const k = n("button", "ocw-fb-btn", m);
727
+ k.type = "button", k.title = v, k.style.cssText = "border:1px solid var(--ocw-bd,rgba(0,0,0,.12));background:transparent;border-radius:12px;padding:1px 8px;font-size:12px;cursor:pointer;opacity:.7";
728
+ const w = () => {
729
+ var S, z;
730
+ return !!((z = (S = e.reactions) == null ? void 0 : S[m]) != null && z.includes(this.me));
723
731
  };
724
- return S() && (k.style.opacity = "1"), k.addEventListener("click", () => {
725
- var w, I;
726
- (I = (w = this.h).onReact) == null || I.call(w, e.id, f, S()), k.style.opacity = "1";
732
+ return w() && (k.style.opacity = "1"), k.addEventListener("click", () => {
733
+ var S, z;
734
+ (z = (S = this.h).onReact) == null || z.call(S, e.id, m, w()), k.style.opacity = "1";
727
735
  }), k;
728
736
  };
729
- i.append(v("👍", ((T = this.cfg.i18n) == null ? void 0 : T.helpful) ?? "Helpful"), v("👎", ((_ = this.cfg.i18n) == null ? void 0 : _.notHelpful) ?? "Not helpful")), l.append(i);
737
+ a.append(h("👍", ((_ = this.cfg.i18n) == null ? void 0 : _.helpful) ?? "Helpful"), h("👎", ((E = this.cfg.i18n) == null ? void 0 : E.notHelpful) ?? "Not helpful")), s.append(a);
730
738
  }
731
739
  }
732
740
  if (this.h.onReact && !e.deletedAt && e.seq > 0) {
733
- const r = n("div", "ocw-react-wrap"), i = n("div", "ocw-react");
741
+ const r = n("div", "ocw-react-wrap"), a = n("div", "ocw-react");
734
742
  if (e.reactions && Object.keys(e.reactions).length)
735
- for (const [m, k] of Object.entries(e.reactions)) {
736
- const S = n("button", `ocw-react-pill${k.includes(this.me) ? " mine" : ""}`, `${m} ${k.length}`);
737
- S.addEventListener("click", () => {
738
- var w, I;
739
- return (I = (w = this.h).onReact) == null ? void 0 : I.call(w, e.id, m, k.includes(this.me));
740
- }), i.append(S);
743
+ for (const [v, k] of Object.entries(e.reactions)) {
744
+ const w = n("button", `ocw-react-pill${k.includes(this.me) ? " mine" : ""}`, `${v} ${k.length}`);
745
+ w.addEventListener("click", () => {
746
+ var S, z;
747
+ return (z = (S = this.h).onReact) == null ? void 0 : z.call(S, e.id, v, k.includes(this.me));
748
+ }), a.append(w);
741
749
  }
742
- const v = n("button", "ocw-react-btn", "+"), f = n("div", "ocw-react-picker");
743
- for (const m of Ge) {
744
- const k = n("button", void 0, m);
745
- k.addEventListener("click", (S) => {
746
- var I, N, D, X;
747
- S.stopPropagation();
748
- const w = (N = (I = e.reactions) == null ? void 0 : I[m]) == null ? void 0 : N.includes(this.me);
749
- (X = (D = this.h).onReact) == null || X.call(D, e.id, m, !!w), f.style.display = "none";
750
- }), f.append(k);
750
+ const h = n("button", "ocw-react-btn", "+"), m = n("div", "ocw-react-picker");
751
+ for (const v of Ke) {
752
+ const k = n("button", void 0, v);
753
+ k.addEventListener("click", (w) => {
754
+ var z, U, D, Q;
755
+ w.stopPropagation();
756
+ const S = (U = (z = e.reactions) == null ? void 0 : z[v]) == null ? void 0 : U.includes(this.me);
757
+ (Q = (D = this.h).onReact) == null || Q.call(D, e.id, v, !!S), m.style.display = "none";
758
+ }), m.append(k);
751
759
  }
752
- f.style.display = "none", v.addEventListener("click", (m) => {
753
- m.stopPropagation();
754
- const k = f.style.display === "none";
755
- f.style.display = k ? "flex" : "none", k && document.addEventListener("click", () => {
756
- f.style.display = "none";
760
+ m.style.display = "none", h.addEventListener("click", (v) => {
761
+ v.stopPropagation();
762
+ const k = m.style.display === "none";
763
+ m.style.display = k ? "flex" : "none", k && document.addEventListener("click", () => {
764
+ m.style.display = "none";
757
765
  }, { once: !0 });
758
- }), i.append(v), r.append(i, f), l.append(r);
759
- } else e.reactions && Object.keys(e.reactions).length && l.append(n("div", "ocw-react", Object.entries(e.reactions).map(([r, i]) => `${r}${i.length}`).join(" ")));
760
- const j = n("div", "ocw-time ocw-meta", Je(e.ts));
761
- if (h && e.status) {
762
- const r = n("span", `ocw-tick${e.status === "read" ? " read" : e.status === "delivered" ? " delivered" : ""}`, et(e.status));
763
- j.append(r);
766
+ }), a.append(h), r.append(a, m), s.append(r);
767
+ } else e.reactions && Object.keys(e.reactions).length && s.append(n("div", "ocw-react", Object.entries(e.reactions).map(([r, a]) => `${r}${a.length}`).join(" ")));
768
+ const I = n("div", "ocw-time ocw-meta", Ze(e.ts));
769
+ if (f && e.status) {
770
+ const r = n("span", `ocw-tick${e.status === "read" ? " read" : e.status === "delivered" ? " delivered" : ""}`, tt(e.status));
771
+ I.append(r);
764
772
  }
765
- return h && e.seq > 0 && d.lastReadByOthers >= e.seq && j.append(n("span", "ocw-seen", " · Seen")), l.append(j), y.append(l), y;
773
+ return f && e.seq > 0 && l.lastReadByOthers >= e.seq && I.append(n("span", "ocw-seen", " · Seen")), s.append(I), y.append(s), y;
766
774
  }
767
775
  }
768
- function et(t) {
776
+ function tt(t) {
769
777
  switch (t) {
770
778
  case "read":
771
779
  return "✓✓";
@@ -777,31 +785,31 @@ function et(t) {
777
785
  return "🕓";
778
786
  }
779
787
  }
780
- const F = /* @__PURE__ */ new WeakMap(), ne = /* @__PURE__ */ new Map();
781
- function Ie(t) {
788
+ const G = /* @__PURE__ */ new WeakMap(), oe = /* @__PURE__ */ new Map();
789
+ function Te(t) {
782
790
  return `relay-launcher::${t.profileId}::${t.subjectId ?? ""}`;
783
791
  }
784
- let Y = null;
785
- function tt() {
786
- if (Y && Y.state !== "closed") return Y;
792
+ let X = null;
793
+ function nt() {
794
+ if (X && X.state !== "closed") return X;
787
795
  try {
788
- return Y = new AudioContext(), Y;
796
+ return X = new AudioContext(), X;
789
797
  } catch {
790
798
  return null;
791
799
  }
792
800
  }
793
- function lt(t) {
801
+ function dt(t) {
794
802
  var e;
795
- (e = F.get(t)) == null || e.close(), F.delete(t);
803
+ (e = G.get(t)) == null || e.close(), G.delete(t);
796
804
  }
797
- function nt(t) {
805
+ function ot(t) {
798
806
  const e = t.el;
799
- let d = null, s = null, c = !1;
800
- const h = () => {
801
- d == null || d.close(), d = null, s == null || s.close(), s = null, e.innerHTML = "";
807
+ let l = null, c = null, i = !1;
808
+ const f = () => {
809
+ l == null || l.close(), l = null, c == null || c.close(), c = null, e.innerHTML = "";
802
810
  };
803
811
  function b() {
804
- c || (h(), s = Oe({
812
+ i || (f(), c = De({
805
813
  el: e,
806
814
  url: t.url,
807
815
  ...t.apiUrl ? { apiUrl: t.apiUrl } : {},
@@ -814,46 +822,46 @@ function nt(t) {
814
822
  ...t.webfont === !1 ? { webfont: !1 } : {},
815
823
  ...t.locale ? { locale: t.locale } : {},
816
824
  ...t.i18n ? { i18n: t.i18n } : {},
817
- onSelect: (l) => y(l)
825
+ onSelect: (s) => y(s)
818
826
  }));
819
827
  }
820
- function y(l) {
821
- if (c) return;
822
- h();
823
- const { subjectId: u, kind: x, peerId: a, ...j } = t;
824
- d = ot({
825
- ...j,
828
+ function y(s) {
829
+ if (i) return;
830
+ f();
831
+ const { subjectId: x, kind: u, peerId: d, ...I } = t;
832
+ l = it({
833
+ ...I,
826
834
  inbox: !1,
827
835
  launcher: !1,
828
836
  el: e,
829
- ...l.profileId ? { profileId: l.profileId } : {},
830
- ...l.subjectId ? { subjectId: l.subjectId } : {},
831
- ...l.kind === "direct" && l.peerId ? { kind: "direct", peerId: l.peerId } : {},
837
+ ...s.profileId ? { profileId: s.profileId } : {},
838
+ ...s.subjectId ? { subjectId: s.subjectId } : {},
839
+ ...s.kind === "direct" && s.peerId ? { kind: "direct", peerId: s.peerId } : {},
832
840
  onBack: b
833
841
  });
834
842
  }
835
843
  return b(), { close() {
836
- c = !0, h();
844
+ i = !0, f();
837
845
  } };
838
846
  }
839
- function ot(t) {
840
- var de, pe, ue, he, fe, we, be, xe;
841
- if (t.inbox) return nt(t);
842
- F.has(t.el) && (F.get(t.el).close(), F.delete(t.el)), t.launcher && ((de = ne.get(Ie(t))) == null || de.close());
843
- const e = Me();
844
- let d, s = !1;
845
- const c = t.token ?? t.userId ?? e, h = c !== e ? e : void 0, { wsUrl: b, httpBase: y } = Ae(t.url, t.apiUrl);
846
- let l = new He(c);
847
- const u = t.subjectId ? `${c}::${t.subjectId}` : c, x = new De(u);
848
- let a, j = !1, R = null, E = null, A = null, P = null;
847
+ function it(t) {
848
+ var pe, ue, he, fe, we, be, xe, me;
849
+ if (t.inbox) return ot(t);
850
+ G.has(t.el) && (G.get(t.el).close(), G.delete(t.el)), t.launcher && ((pe = oe.get(Te(t))) == null || pe.close());
851
+ const e = Re();
852
+ let l, c = !1;
853
+ const i = t.token ?? t.userId ?? e, f = i !== e ? e : void 0, { wsUrl: b, httpBase: y } = Ae(t.url, t.apiUrl);
854
+ let s = new _e(i);
855
+ const x = t.subjectId ? `${i}::${t.subjectId}` : i, u = new He(x);
856
+ let d, I = !1, T = null, L = null, B = null, R = null;
849
857
  !t.launcher && !t.el.style.height && t.el.clientHeight === 0 && (t.el.style.width = t.el.style.width || "100%", t.el.style.height = "600px");
850
- for (const o of x.load()) l.addOptimistic(o.clientMsgId, o.content);
851
- let B = null, z = null, O = 0, T = !t.launcher;
858
+ for (const o of u.load()) s.addOptimistic(o.clientMsgId, o.content);
859
+ let A = null, P = null, O = 0, j = !t.launcher;
852
860
  if (t.launcher) {
853
861
  const p = (t.position ?? "bottom-right").includes("right");
854
- B = document.createElement("div"), B.style.cssText = `position:fixed;${p ? "right:20px" : "left:20px"};bottom:20px;z-index:9999;display:flex;flex-direction:column;align-items:${p ? "flex-end" : "flex-start"};gap:12px`;
855
- const g = document.createElement("div"), M = typeof window < "u" && typeof window.matchMedia == "function" ? window.matchMedia("(max-width: 479px)") : null, K = ($) => {
856
- t.el.classList.toggle("ocw-fs", $), g.style.cssText = $ ? [
862
+ A = document.createElement("div"), A.style.cssText = `position:fixed;${p ? "right:20px" : "left:20px"};bottom:20px;z-index:9999;display:flex;flex-direction:column;align-items:${p ? "flex-end" : "flex-start"};gap:12px`;
863
+ const g = document.createElement("div"), $ = typeof window < "u" && typeof window.matchMedia == "function" ? window.matchMedia("(max-width: 479px)") : null, W = (q) => {
864
+ t.el.classList.toggle("ocw-fs", q), g.style.cssText = q ? [
857
865
  "position:fixed",
858
866
  "inset:0",
859
867
  "width:100%",
@@ -882,10 +890,10 @@ function ot(t) {
882
890
  "transform:scale(.95)"
883
891
  ].join(";");
884
892
  };
885
- K((M == null ? void 0 : M.matches) ?? !1);
886
- const V = ($) => K($.matches);
887
- M == null || M.addEventListener("change", V), R = M, E = V, t.el.style.cssText = "width:100%;height:100%;overflow:hidden", g.append(t.el);
888
- const J = '<svg viewBox="0 0 24 24" width="26" height="26" fill="none" xmlns="http://www.w3.org/2000/svg" aria-hidden="true"><path d="M21 11.5a8.38 8.38 0 0 1-.9 3.8 8.5 8.5 0 0 1-7.6 4.7 8.38 8.38 0 0 1-3.8-.9L3 21l1.9-5.7a8.38 8.38 0 0 1-.9-3.8 8.5 8.5 0 0 1 4.7-7.6 8.38 8.38 0 0 1 3.8-.9h.5a8.48 8.48 0 0 1 8 8v.5z" fill="currentColor" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/></svg>', Z = '<svg viewBox="0 0 24 24" width="22" height="22" fill="none" xmlns="http://www.w3.org/2000/svg" aria-hidden="true"><path d="M18 6 6 18M6 6l12 12" stroke="currentColor" stroke-width="2.5" stroke-linecap="round"/></svg>', H = document.createElement("button");
893
+ W(($ == null ? void 0 : $.matches) ?? !1);
894
+ const Y = (q) => W(q.matches);
895
+ $ == null || $.addEventListener("change", Y), T = $, L = Y, t.el.style.cssText = "width:100%;height:100%;overflow:hidden", g.append(t.el);
896
+ const Z = '<svg viewBox="0 0 24 24" width="26" height="26" fill="none" xmlns="http://www.w3.org/2000/svg" aria-hidden="true"><path d="M21 11.5a8.38 8.38 0 0 1-.9 3.8 8.5 8.5 0 0 1-7.6 4.7 8.38 8.38 0 0 1-3.8-.9L3 21l1.9-5.7a8.38 8.38 0 0 1-.9-3.8 8.5 8.5 0 0 1 4.7-7.6 8.38 8.38 0 0 1 3.8-.9h.5a8.48 8.48 0 0 1 8 8v.5z" fill="currentColor" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/></svg>', ee = '<svg viewBox="0 0 24 24" width="22" height="22" fill="none" xmlns="http://www.w3.org/2000/svg" aria-hidden="true"><path d="M18 6 6 18M6 6l12 12" stroke="currentColor" stroke-width="2.5" stroke-linecap="round"/></svg>', H = document.createElement("button");
889
897
  H.type = "button", H.style.cssText = [
890
898
  "width:56px;height:56px;border-radius:50%",
891
899
  `background:${t.accent ?? "#6c5ce7"}`,
@@ -898,27 +906,27 @@ function ot(t) {
898
906
  H.style.transform = "scale(1.08)";
899
907
  }, H.onmouseleave = () => {
900
908
  H.style.transform = "scale(1)";
901
- }, z = document.createElement("span"), z.style.cssText = "position:absolute;top:-4px;right:-4px;background:#4c6fff;color:#fff;border-radius:50%;width:20px;height:20px;font-size:11px;font-weight:700;display:none;align-items:center;justify-content:center";
902
- const ee = () => {
903
- H.innerHTML = T ? Z : J, H.setAttribute("aria-label", T ? "Close chat" : "Open chat"), H.setAttribute("aria-expanded", String(T)), H.append(z);
909
+ }, P = document.createElement("span"), P.style.cssText = "position:absolute;top:-4px;right:-4px;background:#4c6fff;color:#fff;border-radius:50%;width:20px;height:20px;font-size:11px;font-weight:700;display:none;align-items:center;justify-content:center";
910
+ const te = () => {
911
+ H.innerHTML = j ? ee : Z, H.setAttribute("aria-label", j ? "Close chat" : "Open chat"), H.setAttribute("aria-expanded", String(j)), H.append(P);
904
912
  };
905
- ee(), B.append(g, H), document.body.append(B);
906
- const oe = `ocw-teaser-dismissed::${t.profileId}`, te = typeof t.launcherMessage == "string" ? { title: t.launcherMessage } : t.launcherMessage;
907
- let L = null;
908
- const Le = () => {
913
+ te(), A.append(g, H), document.body.append(A);
914
+ const ie = `ocw-teaser-dismissed::${t.profileId}`, ne = typeof t.launcherMessage == "string" ? { title: t.launcherMessage } : t.launcherMessage;
915
+ let M = null;
916
+ const je = () => {
909
917
  try {
910
- return sessionStorage.getItem(oe) === "1";
918
+ return sessionStorage.getItem(ie) === "1";
911
919
  } catch {
912
920
  return !1;
913
921
  }
914
- }, Pe = '<svg viewBox="0 0 24 24" width="15" height="15" fill="none" xmlns="http://www.w3.org/2000/svg" aria-hidden="true"><path d="M21 11.5a8.38 8.38 0 0 1-.9 3.8 8.5 8.5 0 0 1-7.6 4.7 8.38 8.38 0 0 1-3.8-.9L3 21l1.9-5.7a8.38 8.38 0 0 1-.9-3.8 8.5 8.5 0 0 1 4.7-7.6 8.38 8.38 0 0 1 3.8-.9h.5a8.48 8.48 0 0 1 8 8v.5z" fill="currentColor" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/></svg>', me = () => {
915
- const $ = te != null && te.title ? te : l.launcherMessage ?? void 0;
916
- if (!(!!($ != null && $.title) && !T && !Le())) {
917
- L && (L.remove(), L = null);
922
+ }, Pe = '<svg viewBox="0 0 24 24" width="15" height="15" fill="none" xmlns="http://www.w3.org/2000/svg" aria-hidden="true"><path d="M21 11.5a8.38 8.38 0 0 1-.9 3.8 8.5 8.5 0 0 1-7.6 4.7 8.38 8.38 0 0 1-3.8-.9L3 21l1.9-5.7a8.38 8.38 0 0 1-.9-3.8 8.5 8.5 0 0 1 4.7-7.6 8.38 8.38 0 0 1 3.8-.9h.5a8.48 8.48 0 0 1 8 8v.5z" fill="currentColor" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/></svg>', ge = () => {
923
+ const q = ne != null && ne.title ? ne : s.launcherMessage ?? void 0;
924
+ if (!(!!(q != null && q.title) && !j && !je())) {
925
+ M && (M.remove(), M = null);
918
926
  return;
919
927
  }
920
- if (L) return;
921
- L = document.createElement("div"), L.setAttribute("role", "button"), L.setAttribute("tabindex", "0"), L.setAttribute("aria-label", $.title), L.style.cssText = [
928
+ if (M) return;
929
+ M = document.createElement("div"), M.setAttribute("role", "button"), M.setAttribute("tabindex", "0"), M.setAttribute("aria-label", q.title), M.style.cssText = [
922
930
  "max-width:280px",
923
931
  "background:#fff",
924
932
  "border-radius:16px",
@@ -930,61 +938,61 @@ function ot(t) {
930
938
  `align-self:${p ? "flex-end" : "flex-start"}`,
931
939
  "animation:ocw-teaser-in .22s ease-out"
932
940
  ].join(";");
933
- const ae = document.createElement("div");
934
- if (ae.textContent = $.title, ae.style.cssText = "font-size:15px;font-weight:600;color:#111;line-height:1.35", L.append(ae), $.subtitle) {
935
- const U = document.createElement("div");
936
- U.style.cssText = "display:flex;align-items:center;gap:6px;margin-top:6px;font-size:13px;color:#6b7280";
937
- const ce = document.createElement("span");
938
- ce.innerHTML = Pe, ce.style.cssText = `color:${t.accent ?? "#6c5ce7"};display:inline-flex`;
939
- const ye = document.createElement("span");
940
- ye.textContent = $.subtitle, U.append(ce, ye), L.append(U);
941
+ const ce = document.createElement("div");
942
+ if (ce.textContent = q.title, ce.style.cssText = "font-size:15px;font-weight:600;color:#111;line-height:1.35", M.append(ce), q.subtitle) {
943
+ const F = document.createElement("div");
944
+ F.style.cssText = "display:flex;align-items:center;gap:6px;margin-top:6px;font-size:13px;color:#6b7280";
945
+ const re = document.createElement("span");
946
+ re.innerHTML = Pe, re.style.cssText = `color:${t.accent ?? "#6c5ce7"};display:inline-flex`;
947
+ const ve = document.createElement("span");
948
+ ve.textContent = q.subtitle, F.append(re, ve), M.append(F);
941
949
  }
942
- const W = document.createElement("button");
943
- W.type = "button", W.setAttribute("aria-label", "Dismiss"), W.innerHTML = '<svg viewBox="0 0 24 24" width="14" height="14" fill="none" xmlns="http://www.w3.org/2000/svg"><path d="M18 6 6 18M6 6l12 12" stroke="currentColor" stroke-width="2.5" stroke-linecap="round"/></svg>', W.style.cssText = "position:absolute;top:8px;right:8px;width:24px;height:24px;border:none;border-radius:50%;background:#f3f4f6;color:#6b7280;cursor:pointer;display:flex;align-items:center;justify-content:center;padding:0", W.addEventListener("click", (U) => {
944
- U.stopPropagation();
950
+ const K = document.createElement("button");
951
+ K.type = "button", K.setAttribute("aria-label", "Dismiss"), K.innerHTML = '<svg viewBox="0 0 24 24" width="14" height="14" fill="none" xmlns="http://www.w3.org/2000/svg"><path d="M18 6 6 18M6 6l12 12" stroke="currentColor" stroke-width="2.5" stroke-linecap="round"/></svg>', K.style.cssText = "position:absolute;top:8px;right:8px;width:24px;height:24px;border:none;border-radius:50%;background:#f3f4f6;color:#6b7280;cursor:pointer;display:flex;align-items:center;justify-content:center;padding:0", K.addEventListener("click", (F) => {
952
+ F.stopPropagation();
945
953
  try {
946
- sessionStorage.setItem(oe, "1");
954
+ sessionStorage.setItem(ie, "1");
947
955
  } catch {
948
956
  }
949
- L && (L.remove(), L = null);
950
- }), L.append(W);
951
- const ge = () => {
952
- T || (T = !0, ie(!0), ee(), O = 0, z && (z.style.display = "none"), L && (L.remove(), L = null));
957
+ M && (M.remove(), M = null);
958
+ }), M.append(K);
959
+ const ye = () => {
960
+ j || (j = !0, ae(!0), te(), O = 0, P && (P.style.display = "none"), M && (M.remove(), M = null));
953
961
  };
954
- L.addEventListener("click", ge), L.addEventListener("keydown", (U) => {
955
- (U.key === "Enter" || U.key === " ") && (U.preventDefault(), ge());
956
- }), B.insertBefore(L, H);
962
+ M.addEventListener("click", ye), M.addEventListener("keydown", (F) => {
963
+ (F.key === "Enter" || F.key === " ") && (F.preventDefault(), ye());
964
+ }), A.insertBefore(M, H);
957
965
  };
958
966
  if (!document.getElementById("ocw-teaser-style")) {
959
- const $ = document.createElement("style");
960
- $.id = "ocw-teaser-style", $.textContent = "@keyframes ocw-teaser-in{from{opacity:0;transform:translateY(8px)}to{opacity:1;transform:translateY(0)}}", document.head.append($);
967
+ const q = document.createElement("style");
968
+ q.id = "ocw-teaser-style", q.textContent = "@keyframes ocw-teaser-in{from{opacity:0;transform:translateY(8px)}to{opacity:1;transform:translateY(0)}}", document.head.append(q);
961
969
  }
962
- P = me, me();
963
- const ie = ($) => {
964
- $ ? (g.style.display = "flex", requestAnimationFrame(() => {
970
+ R = ge, ge();
971
+ const ae = (q) => {
972
+ q ? (g.style.display = "flex", requestAnimationFrame(() => {
965
973
  g.style.opacity = "1", g.style.transform = "scale(1)";
966
974
  })) : (g.style.opacity = "0", g.style.transform = "scale(.95)", setTimeout(() => {
967
- T || (g.style.display = "none");
975
+ j || (g.style.display = "none");
968
976
  }, 180));
969
977
  };
970
978
  H.addEventListener("click", () => {
971
- if (T = !T, ie(T), ee(), T) {
972
- O = 0, z && (z.style.display = "none");
979
+ if (j = !j, ae(j), te(), j) {
980
+ O = 0, P && (P.style.display = "none");
973
981
  try {
974
- sessionStorage.setItem(oe, "1");
982
+ sessionStorage.setItem(ie, "1");
975
983
  } catch {
976
984
  }
977
985
  }
978
- P == null || P();
979
- }), A = ($) => {
980
- $.key === "Escape" && T && (T = !1, ie(!1), ee());
981
- }, document.addEventListener("keydown", A);
986
+ R == null || R();
987
+ }), B = (q) => {
988
+ q.key === "Escape" && j && (j = !1, ae(!1), te());
989
+ }, document.addEventListener("keydown", B);
982
990
  }
983
991
  const _ = () => {
984
- T || (O++, z && (z.textContent = String(O), z.style.display = "flex"));
985
- }, r = () => {
992
+ j || (O++, P && (P.textContent = String(O), P.style.display = "flex"));
993
+ }, E = () => {
986
994
  try {
987
- const o = tt();
995
+ const o = nt();
988
996
  if (!o) return;
989
997
  o.state === "suspended" && o.resume().catch(() => {
990
998
  });
@@ -992,77 +1000,77 @@ function ot(t) {
992
1000
  p.connect(g), g.connect(o.destination), p.frequency.setValueAtTime(880, o.currentTime), p.frequency.exponentialRampToValueAtTime(440, o.currentTime + 0.15), g.gain.setValueAtTime(0.3, o.currentTime), g.gain.exponentialRampToValueAtTime(1e-3, o.currentTime + 0.3), p.start(), p.stop(o.currentTime + 0.3);
993
1001
  } catch {
994
1002
  }
995
- }, i = [], v = (o) => {
996
- for (; i.length; ) {
997
- const p = i.shift();
998
- x.add({ clientMsgId: p.clientMsgId, content: p.content, ts: Date.now() }), f.send({ type: "send", conversationId: o, clientMsgId: p.clientMsgId, content: p.content });
1003
+ }, r = [], a = (o) => {
1004
+ for (; r.length; ) {
1005
+ const p = r.shift();
1006
+ u.add({ clientMsgId: p.clientMsgId, content: p.content, ts: Date.now() }), h.send({ type: "send", conversationId: o, clientMsgId: p.clientMsgId, content: p.content });
999
1007
  }
1000
1008
  };
1001
- let f;
1002
- const m = new Ue(`ocw-e2e-${t.profileId}`);
1003
- let k = !1;
1004
- const S = [], w = [];
1005
- let I = !1;
1006
- const N = (o, p) => {
1009
+ let h;
1010
+ const m = new Fe(`ocw-e2e-${t.profileId}`);
1011
+ let v = !1;
1012
+ const k = [], w = [];
1013
+ let S = !1;
1014
+ const z = (o, p) => {
1007
1015
  m.sealText(p).then((g) => {
1008
- a && f.send({ type: "send", conversationId: a, clientMsgId: o, content: g });
1016
+ d && h.send({ type: "send", conversationId: d, clientMsgId: o, content: g });
1009
1017
  });
1010
- }, D = (o, p, g) => {
1011
- m.sealText(p, g).then((M) => {
1012
- a && f.send({ type: "send", conversationId: a, clientMsgId: o, content: M });
1018
+ }, U = (o, p, g) => {
1019
+ m.sealText(p, g).then(($) => {
1020
+ d && h.send({ type: "send", conversationId: d, clientMsgId: o, content: $ });
1013
1021
  });
1014
- }, X = () => {
1015
- for (; S.length; ) {
1016
- const o = S.shift();
1017
- N(o.clientMsgId, o.text);
1022
+ }, D = () => {
1023
+ for (; k.length; ) {
1024
+ const o = k.shift();
1025
+ z(o.clientMsgId, o.text);
1018
1026
  }
1019
1027
  for (; w.length; ) {
1020
1028
  const o = w.shift();
1021
- N(o.clientMsgId, o.text);
1029
+ z(o.clientMsgId, o.text);
1022
1030
  }
1023
- }, Te = (o) => {
1024
- f.send({ type: "fetchPrekey", targetUserId: o });
1031
+ }, Q = (o) => {
1032
+ h.send({ type: "fetchPrekey", targetUserId: o });
1025
1033
  }, Se = qe(t.locale, t.i18n), Ee = ["ar", "he", "fa", "ur"], ze = typeof navigator < "u" ? (navigator.language ?? "").slice(0, 2).toLowerCase() : "";
1026
1034
  Ee.includes(ze) && !t.el.dir && (t.el.dir = "rtl", t.el.style.fontFamily = t.el.style.fontFamily || "Tahoma,Arial,system-ui,sans-serif");
1027
- const se = `oc_prechat_${t.profileId}_${c.slice(-8)}`, q = new Ze(t.el, c, {
1035
+ const le = `oc_prechat_${t.profileId}_${i.slice(-8)}`, N = new et(t.el, i, {
1028
1036
  onSend(o) {
1029
1037
  const p = `cm_${Math.random().toString(36).slice(2)}`, g = { kind: "text", text: o };
1030
- l.addOptimistic(p, g), q.render(l), l.e2e ? m.ready ? N(p, o) : I ? w.push({ clientMsgId: p, text: o }) : (S.push({ clientMsgId: p, text: o }), l.assignedAgentId && Te(l.assignedAgentId)) : a ? (x.add({ clientMsgId: p, content: g, ts: Date.now() }), f.send({ type: "send", conversationId: a, clientMsgId: p, content: g })) : i.push({ clientMsgId: p, content: g });
1038
+ s.addOptimistic(p, g), N.render(s), s.e2e ? m.ready ? z(p, o) : S ? w.push({ clientMsgId: p, text: o }) : (k.push({ clientMsgId: p, text: o }), s.assignedAgentId && Q(s.assignedAgentId)) : d ? (u.add({ clientMsgId: p, content: g, ts: Date.now() }), h.send({ type: "send", conversationId: d, clientMsgId: p, content: g })) : r.push({ clientMsgId: p, content: g });
1031
1039
  },
1032
1040
  async onAttach(o) {
1033
- if (!a) return;
1041
+ if (!d) return;
1034
1042
  const p = `${y}/upload?name=${encodeURIComponent(o.name)}`, g = `cm_${Math.random().toString(36).slice(2)}`;
1035
- l.addOptimistic(g, { kind: "text", text: `📎 Uploading ${o.name}…` }), q.render(l);
1043
+ s.addOptimistic(g, { kind: "text", text: `📎 Uploading ${o.name}…` }), N.render(s);
1036
1044
  try {
1037
- const M = await fetch(p, {
1045
+ const $ = await fetch(p, {
1038
1046
  method: "POST",
1039
1047
  // Use the resolved connection token (a signed JWT, an explicit userId,
1040
1048
  // or the anonymous persistent uid) — NOT just opts.token. The server
1041
1049
  // requires an Authorization header, and the verifier accepts an
1042
1050
  // anonymous id as a guest; keying off opts.token alone meant anonymous
1043
1051
  // visitors (the common case) sent no auth and every upload 401'd.
1044
- headers: { "content-type": o.type, authorization: `Bearer ${c}` },
1052
+ headers: { "content-type": o.type, authorization: `Bearer ${i}` },
1045
1053
  body: o
1046
1054
  });
1047
- if (!M.ok) throw new Error(`Upload failed: ${M.status}`);
1048
- const { url: K, name: V, mime: J, size: Z } = await M.json();
1049
- l.addOptimistic(g, { kind: "attachment", url: K, name: V, mime: J, size: Z }), q.render(l), f.send({ type: "send", conversationId: a, clientMsgId: g, content: { kind: "attachment", url: K, name: V, mime: J, size: Z } });
1050
- } catch (M) {
1051
- l.addOptimistic(g, { kind: "text", text: `⚠️ Upload failed: ${M.message}` }), q.render(l);
1055
+ if (!$.ok) throw new Error(`Upload failed: ${$.status}`);
1056
+ const { url: W, name: Y, mime: Z, size: ee } = await $.json();
1057
+ s.addOptimistic(g, { kind: "attachment", url: W, name: Y, mime: Z, size: ee }), N.render(s), h.send({ type: "send", conversationId: d, clientMsgId: g, content: { kind: "attachment", url: W, name: Y, mime: Z, size: ee } });
1058
+ } catch ($) {
1059
+ s.addOptimistic(g, { kind: "text", text: `⚠️ Upload failed: ${$.message}` }), N.render(s);
1052
1060
  }
1053
1061
  },
1054
1062
  onInvoke(o, p) {
1055
- a && f.send({ type: "invoke", conversationId: a, actionId: o, clientInvokeId: `iv_${Math.random().toString(36).slice(2)}`, ...p ? { inputs: p } : {} });
1063
+ d && h.send({ type: "invoke", conversationId: d, actionId: o, clientInvokeId: `iv_${Math.random().toString(36).slice(2)}`, ...p ? { inputs: p } : {} });
1056
1064
  },
1057
1065
  onTyping(o, p) {
1058
- a && f.send({ type: "typing", conversationId: a, isTyping: o, ...p ? { preview: p } : {} });
1066
+ d && h.send({ type: "typing", conversationId: d, isTyping: o, ...p ? { preview: p } : {} });
1059
1067
  },
1060
1068
  onPreChat(o) {
1061
1069
  try {
1062
- localStorage.setItem(se, "1");
1070
+ localStorage.setItem(le, "1");
1063
1071
  } catch {
1064
1072
  }
1065
- f.send({
1073
+ h.send({
1066
1074
  type: "open",
1067
1075
  profileId: t.profileId,
1068
1076
  ...t.subjectId ? { subjectId: t.subjectId } : {},
@@ -1076,67 +1084,70 @@ function ot(t) {
1076
1084
  }
1077
1085
  });
1078
1086
  const p = o.callback ? `📞 Call-back requested${o.phone ? `: ${o.phone}` : ""}${o.topic ? ` — ${o.topic}` : ""}` : o.topic ? `Topic: ${o.topic}` : "";
1079
- p && a && !l.e2e && f.send({ type: "send", conversationId: a, clientMsgId: `pc_${Math.random().toString(36).slice(2, 12)}`, content: { kind: "text", text: p } });
1087
+ p && d && !s.e2e && h.send({ type: "send", conversationId: d, clientMsgId: `pc_${Math.random().toString(36).slice(2, 12)}`, content: { kind: "text", text: p } });
1080
1088
  },
1081
- ...((pe = t.features) == null ? void 0 : pe.deflection) !== !1 ? {
1089
+ ...((ue = t.features) == null ? void 0 : ue.deflection) !== !1 ? {
1082
1090
  onDeflectQuery(o) {
1083
- if (s) return;
1084
- clearTimeout(d);
1091
+ if (c) return;
1092
+ clearTimeout(l);
1085
1093
  const p = o.trim();
1086
1094
  if (p.length < 3) {
1087
- q.hideDeflection();
1095
+ N.hideDeflection();
1088
1096
  return;
1089
1097
  }
1090
- d = setTimeout(() => {
1091
- fetch(`${y}/kb/search?profileId=${encodeURIComponent(t.profileId)}&q=${encodeURIComponent(p.slice(0, 200))}`).then((g) => g.ok ? g.json() : { articles: [] }).then((g) => q.showDeflection(g.articles ?? [])).catch(() => q.hideDeflection());
1098
+ l = setTimeout(() => {
1099
+ fetch(`${y}/kb/search?profileId=${encodeURIComponent(t.profileId)}&q=${encodeURIComponent(p.slice(0, 200))}`).then((g) => g.ok ? g.json() : { articles: [] }).then((g) => N.showDeflection(g.articles ?? [])).catch(() => N.hideDeflection());
1092
1100
  }, 350);
1093
1101
  }
1094
1102
  } : {},
1095
1103
  onReadUpTo(o) {
1096
- a && f.send({ type: "read", conversationId: a, seq: o });
1104
+ d && h.send({ type: "read", conversationId: d, seq: o });
1097
1105
  },
1098
1106
  onLoadMore() {
1099
- if (!a || !l.e2e) return;
1100
- const o = l.messages()[0];
1101
- o && f.send({ type: "history", conversationId: a, beforeSeq: o.seq, limit: 20 });
1107
+ if (!d || !s.e2e) return;
1108
+ const o = s.messages()[0];
1109
+ o && h.send({ type: "history", conversationId: d, beforeSeq: o.seq, limit: 20 });
1102
1110
  },
1103
1111
  onEdit(o, p) {
1104
- a && f.send({ type: "edit", conversationId: a, messageId: o, content: { kind: "text", text: p } });
1112
+ d && h.send({ type: "edit", conversationId: d, messageId: o, content: { kind: "text", text: p } });
1105
1113
  },
1106
1114
  onDelete(o) {
1107
- a && f.send({ type: "delete", conversationId: a, messageId: o });
1115
+ d && h.send({ type: "delete", conversationId: d, messageId: o });
1108
1116
  },
1109
- ...((ue = t.features) == null ? void 0 : ue.reactions) !== !1 ? {
1117
+ ...((he = t.features) == null ? void 0 : he.reactions) !== !1 ? {
1110
1118
  onReact(o, p, g) {
1111
- a && f.send({ type: "react", conversationId: a, messageId: o, emoji: p, remove: g });
1119
+ d && h.send({ type: "react", conversationId: d, messageId: o, emoji: p, remove: g });
1112
1120
  }
1113
1121
  } : {},
1114
- ...((he = t.features) == null ? void 0 : he.csat) !== !1 ? {
1122
+ ...((fe = t.features) == null ? void 0 : fe.csat) !== !1 ? {
1115
1123
  onCsat(o) {
1116
- a && fetch(`${y}/conversations/${a}/csat`, {
1124
+ d && fetch(`${y}/conversations/${d}/csat`, {
1117
1125
  method: "POST",
1118
- headers: { "Content-Type": "application/json", Authorization: `Bearer ${c}` },
1126
+ headers: { "Content-Type": "application/json", Authorization: `Bearer ${i}` },
1119
1127
  body: JSON.stringify({ score: o })
1120
1128
  }).catch(() => {
1121
1129
  });
1122
1130
  }
1123
1131
  } : {},
1124
- ...t.translateLang ? {
1125
- async onTranslate(o) {
1126
- try {
1127
- const p = await fetch(`${y}/translate`, {
1128
- method: "POST",
1129
- headers: { "content-type": "application/json", authorization: `Bearer ${c}` },
1130
- body: JSON.stringify({ text: o, targetLang: t.translateLang })
1131
- });
1132
- if (!p.ok) return null;
1133
- const { translated: g } = await p.json();
1134
- return g;
1135
- } catch {
1136
- return null;
1132
+ ...(() => {
1133
+ const o = t.locale ?? (typeof navigator < "u" ? navigator.language : ""), p = t.translateLang !== void 0 ? t.translateLang : o ? o.split("-")[0] : Ne();
1134
+ return p ? {
1135
+ async onTranslate(g) {
1136
+ try {
1137
+ const $ = await fetch(`${y}/translate`, {
1138
+ method: "POST",
1139
+ headers: { "content-type": "application/json", authorization: `Bearer ${i}` },
1140
+ body: JSON.stringify({ text: g, targetLang: p })
1141
+ });
1142
+ if (!$.ok) return null;
1143
+ const { translated: W } = await $.json();
1144
+ return W;
1145
+ } catch {
1146
+ return null;
1147
+ }
1137
1148
  }
1138
- }
1139
- } : {},
1149
+ } : {};
1150
+ })(),
1140
1151
  ...t.onBack ? { onBack: t.onBack } : {}
1141
1152
  }, {
1142
1153
  ...t.subject ? { subject: t.subject } : {},
@@ -1145,107 +1156,107 @@ function ot(t) {
1145
1156
  ...t.accent2 ? { accent2: t.accent2 } : {},
1146
1157
  ...t.theme ? { theme: t.theme } : {},
1147
1158
  ...t.webfont === !1 ? { webfont: !1 } : {},
1148
- ...(fe = t.user) != null && fe.name || (we = t.user) != null && we.avatar ? { userInfo: { ...t.user.name ? { name: t.user.name } : {}, ...t.user.avatar ? { avatar: t.user.avatar } : {} } } : {},
1159
+ ...(we = t.user) != null && we.name || (be = t.user) != null && be.avatar ? { userInfo: { ...t.user.name ? { name: t.user.name } : {}, ...t.user.avatar ? { avatar: t.user.avatar } : {} } } : {},
1149
1160
  i18n: Se
1150
1161
  });
1151
1162
  try {
1152
- localStorage.getItem(se) && q.completePreChat();
1163
+ localStorage.getItem(le) && N.completePreChat();
1153
1164
  } catch {
1154
1165
  }
1155
- const le = t.user && (t.user.name || t.user.email || t.user.avatar || t.user.meta) ? {
1166
+ const de = t.user && (t.user.name || t.user.email || t.user.avatar || t.user.meta) ? {
1156
1167
  ...t.user.name ? { name: t.user.name } : {},
1157
1168
  ...t.user.email ? { email: t.user.email } : {},
1158
1169
  ...t.user.avatar ? { avatar: t.user.avatar } : {},
1159
1170
  ...t.user.meta ? { meta: t.user.meta } : {}
1160
- } : void 0, je = {
1171
+ } : void 0, Le = {
1161
1172
  type: "open",
1162
1173
  profileId: t.profileId,
1163
1174
  // Direct conversations use the kind/peerId pair; the dm:… subject key is
1164
1175
  // server-derived and owner-keyed, so passing it as subjectId from the
1165
1176
  // NON-owner side would find-or-create a junk duplicate thread.
1166
1177
  ...t.kind === "direct" && t.peerId ? { kind: "direct", peerId: t.peerId } : t.subjectId ? { subjectId: t.subjectId } : {},
1167
- ...h ? { linkFrom: h } : {},
1168
- ...le ? { userInfo: le } : {},
1178
+ ...f ? { linkFrom: f } : {},
1179
+ ...de ? { userInfo: de } : {},
1169
1180
  ...typeof location < "u" ? { pageUrl: location.href } : {},
1170
1181
  ...typeof document < "u" && document.title ? { pageTitle: document.title } : {},
1171
1182
  // Pass subject display info so the server can persist it to the Subject record.
1172
1183
  // This is how listingTitle and listingMeta get saved without a separate API call.
1173
- ...(be = t.subject) != null && be.title ? { subjectTitle: t.subject.title } : {},
1174
- ...(xe = t.subject) != null && xe.subtitle ? { subjectMeta: t.subject.subtitle } : {}
1184
+ ...(xe = t.subject) != null && xe.title ? { subjectTitle: t.subject.title } : {},
1185
+ ...(me = t.subject) != null && me.subtitle ? { subjectMeta: t.subject.subtitle } : {}
1175
1186
  };
1176
- f = new _e({
1187
+ h = new Ue({
1177
1188
  ...t.refreshToken ? { refreshToken: t.refreshToken } : {},
1178
1189
  url: b,
1179
- token: c,
1180
- open: je,
1181
- getCursor: () => l.highestSeq(),
1182
- onStatusChange: (o, p) => q.setConnStatus(o, p),
1190
+ token: i,
1191
+ open: Le,
1192
+ getCursor: () => s.highestSeq(),
1193
+ onStatusChange: (o, p) => N.setConnStatus(o, p),
1183
1194
  onFrame(o) {
1184
1195
  if (o.type === "opened") {
1185
- if (a = o.conversation.id, !j) {
1186
- j = !0;
1187
- for (const p of x.load())
1188
- f.send({ type: "send", conversationId: a, clientMsgId: p.clientMsgId, content: p.content });
1196
+ if (d = o.conversation.id, !I) {
1197
+ I = !0;
1198
+ for (const p of u.load())
1199
+ h.send({ type: "send", conversationId: d, clientMsgId: p.clientMsgId, content: p.content });
1189
1200
  }
1190
- Ne(b, c, a, l, q, y), i.length && v(a);
1201
+ Oe(b, i, d, s, N, y), r.length && a(d);
1191
1202
  }
1192
- if (o.type === "ack" && x.remove(o.clientMsgId), o.type === "prekeyBundle") {
1193
- o.bundle && (I = !0, m.x3dhSendTo(o.bundle).then((p) => {
1194
- const g = [...S.splice(0), ...w.splice(0)];
1195
- for (const M of g) D(M.clientMsgId, M.text, p);
1196
- q.render(l);
1203
+ if (o.type === "ack" && u.remove(o.clientMsgId), o.type === "prekeyBundle") {
1204
+ o.bundle && (S = !0, m.x3dhSendTo(o.bundle).then((p) => {
1205
+ const g = [...k.splice(0), ...w.splice(0)];
1206
+ for (const $ of g) U($.clientMsgId, $.text, p);
1207
+ N.render(s);
1197
1208
  }));
1198
1209
  return;
1199
1210
  }
1200
- if (o.type === "message" && l.e2e) {
1201
- const p = Fe(o.message.content);
1211
+ if (o.type === "message" && s.e2e) {
1212
+ const p = We(o.message.content);
1202
1213
  if (p && !m.ready) {
1203
1214
  m.x3dhReceiveFrom(p.x3dhIK, p.x3dhEK, p.x3dhSPK, p.x3dhOTP).then(async () => {
1204
- await m.openFrame(o), l.apply(o), q.render(l);
1215
+ await m.openFrame(o), s.apply(o), N.render(s);
1205
1216
  });
1206
1217
  return;
1207
1218
  }
1208
1219
  }
1209
1220
  if (o.type === "peerkey") {
1210
1221
  m.onPeerKey(o.key).then(() => {
1211
- X(), q.render(l);
1222
+ D(), N.render(s);
1212
1223
  });
1213
1224
  return;
1214
1225
  }
1215
1226
  (async () => {
1216
- if (l.e2e && await m.openFrame(o), l.apply(o), o.type === "manifest") {
1217
- P == null || P();
1227
+ if (s.e2e && await m.openFrame(o), s.apply(o), o.type === "manifest") {
1228
+ R == null || R();
1218
1229
  const p = o.botName;
1219
- p && q.setBotName(p);
1230
+ p && N.setBotName(p);
1220
1231
  }
1221
- if (o.type === "message" && o.message.senderId !== c && !o.message.internal && (_(), r()), l.e2e && a && !k) {
1222
- k = !0;
1232
+ if (o.type === "message" && o.message.senderId !== i && !o.message.internal && (_(), E()), s.e2e && d && !v) {
1233
+ v = !0;
1223
1234
  const p = await m.initX3DH();
1224
- f.send({ type: "uploadPrekeys", ...p });
1235
+ h.send({ type: "uploadPrekeys", ...p });
1225
1236
  const g = await m.begin();
1226
- f.send({ type: "pubkey", conversationId: a, key: g });
1237
+ h.send({ type: "pubkey", conversationId: d, key: g });
1227
1238
  }
1228
- q.render(l);
1239
+ N.render(s);
1229
1240
  })();
1230
1241
  }
1231
- }), f.connect(), q.render(l);
1232
- const G = t.launcher ? Ie(t) : null, Q = { close: () => {
1233
- s = !0, clearTimeout(d), f.close(), B == null || B.remove(), q.destroy(), R && E && R.removeEventListener("change", E), A && (document.removeEventListener("keydown", A), A = null), F.delete(t.el), G && ne.get(G) === Q && ne.delete(G);
1242
+ }), h.connect(), N.render(s);
1243
+ const V = t.launcher ? Te(t) : null, J = { close: () => {
1244
+ c = !0, clearTimeout(l), h.close(), A == null || A.remove(), N.destroy(), T && L && T.removeEventListener("change", L), B && (document.removeEventListener("keydown", B), B = null), G.delete(t.el), V && oe.get(V) === J && oe.delete(V);
1234
1245
  } };
1235
- return F.set(t.el, Q), G && ne.set(G, Q), Q;
1246
+ return G.set(t.el, J), V && oe.set(V, J), J;
1236
1247
  }
1237
1248
  export {
1238
- He as ChatStore,
1239
- _e as ConnectionManager,
1240
- Ue as E2ESession,
1241
- De as PersistentOutbox,
1242
- Ze as Renderer,
1243
- ft as asConversationId,
1244
- Fe as extractX3DHInit,
1245
- ut as httpBaseFromWsUrl,
1246
- ot as mount,
1249
+ _e as ChatStore,
1250
+ Ue as ConnectionManager,
1251
+ Fe as E2ESession,
1252
+ He as PersistentOutbox,
1253
+ et as Renderer,
1254
+ wt as asConversationId,
1255
+ We as extractX3DHInit,
1256
+ ht as httpBaseFromWsUrl,
1257
+ it as mount,
1247
1258
  Ae as resolveRelayUrls,
1248
- Ne as restoreHistory,
1249
- lt as unmount
1259
+ Oe as restoreHistory,
1260
+ dt as unmount
1250
1261
  };
1251
1262
  //# sourceMappingURL=index.js.map