@paramms/chat-widget 1.0.40 → 1.0.41

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,13 +1,13 @@
1
- var Pe = Object.defineProperty;
2
- var Le = (t, e, i) => e in t ? Pe(t, e, { enumerable: !0, configurable: !0, writable: !0, value: i }) : t[e] = i;
3
- var y = (t, e, i) => Le(t, typeof e != "symbol" ? e + "" : e, i);
4
- import { p as je, r as Ae, a as $e } from "./codec.js";
1
+ var Le = Object.defineProperty;
2
+ var je = (t, e, i) => e in t ? Le(t, e, { enumerable: !0, configurable: !0, writable: !0, value: i }) : t[e] = i;
3
+ var y = (t, e, i) => je(t, typeof e != "symbol" ? e + "" : e, i);
4
+ import { p as Pe, r as Ae, a as Be } from "./codec.js";
5
5
  import { h as st } from "./codec.js";
6
- import { P as Be, C as Me, b as Re } from "./outbox.js";
7
- import { e as at } from "./outbox.js";
8
- import { E2ESession as qe, extractX3DHInit as Oe } from "./e2e.js";
6
+ import { P as $e, C as Me, b as Re } from "./outbox.js";
7
+ import { e as rt } from "./outbox.js";
8
+ import { E2ESession as qe, extractX3DHInit as Ne } from "./e2e.js";
9
9
  const xe = "http://www.w3.org/2000/svg", De = 8e3;
10
- class He {
10
+ class Oe {
11
11
  constructor() {
12
12
  y(this, "svg", null);
13
13
  y(this, "timers", /* @__PURE__ */ new Set());
@@ -32,16 +32,16 @@ class He {
32
32
  draw(e) {
33
33
  var b;
34
34
  if (typeof document > "u" || !((b = e.points) != null && b.length)) return;
35
- const i = this.ensureSvg(), s = window.innerWidth, r = window.innerHeight, a = document.createElementNS(xe, "polyline");
36
- a.setAttribute("points", e.points.map((d) => `${(d.x * s).toFixed(1)},${(d.y * r).toFixed(1)}`).join(" ")), a.setAttribute("fill", "none"), a.setAttribute("stroke", e.color || "#ff3b30"), a.setAttribute("stroke-width", String(e.width || 3)), a.setAttribute("stroke-linecap", "round"), a.setAttribute("stroke-linejoin", "round"), a.setAttribute("data-stroke-id", e.id), i.append(a);
37
- const f = setTimeout(() => {
38
- a.style.transition = "opacity 600ms", a.style.opacity = "0";
35
+ const i = this.ensureSvg(), s = window.innerWidth, a = window.innerHeight, c = document.createElementNS(xe, "polyline");
36
+ c.setAttribute("points", e.points.map((d) => `${(d.x * s).toFixed(1)},${(d.y * a).toFixed(1)}`).join(" ")), c.setAttribute("fill", "none"), c.setAttribute("stroke", e.color || "#ff3b30"), c.setAttribute("stroke-width", String(e.width || 3)), c.setAttribute("stroke-linecap", "round"), c.setAttribute("stroke-linejoin", "round"), c.setAttribute("data-stroke-id", e.id), i.append(c);
37
+ const w = setTimeout(() => {
38
+ c.style.transition = "opacity 600ms", c.style.opacity = "0";
39
39
  const d = setTimeout(() => {
40
- a.remove(), this.timers.delete(d);
40
+ c.remove(), this.timers.delete(d);
41
41
  }, 650);
42
- this.timers.add(d), this.timers.delete(f);
42
+ this.timers.add(d), this.timers.delete(w);
43
43
  }, De);
44
- this.timers.add(f);
44
+ this.timers.add(w);
45
45
  }
46
46
  clear() {
47
47
  var e;
@@ -53,7 +53,7 @@ class He {
53
53
  this.timers.clear(), (e = this.svg) == null || e.remove(), this.svg = null;
54
54
  }
55
55
  }
56
- const me = "objectchat-widget-styles", Ne = ["👍", "❤️", "😂", "😮", "😢", "🙏"], _e = 400, Fe = '<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>', Ue = `
56
+ const ge = "objectchat-widget-styles", He = ["👍", "❤️", "😂", "😮", "😢", "🙏"], _e = 400, Fe = '<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>', Ue = `
57
57
  .ocw { --ocw-accent:#4F63F5; --ocw-bg:#f3efe9; --ocw-card:#fff; --ocw-line:#ececec; --ocw-ink:#1c1b1a; --ocw-mut:#9b9690;
58
58
  position:relative;
59
59
  display:flex; flex-direction:column; height:100%; min-height:320px; background:var(--ocw-bg);
@@ -152,15 +152,13 @@ const me = "objectchat-widget-styles", Ne = ["👍", "❤️", "😂", "😮", "
152
152
  .ocw-conn-status.err { color:#c0392b; font-weight:600; }
153
153
  .ocw-load-more { display:block; width:100%; background:none; border:1px solid #e3ded7; border-radius:10px; padding:6px 0; font-size:12px; color:var(--ocw-mut); cursor:pointer; margin-bottom:8px; }
154
154
  .ocw-load-more:hover { border-color:var(--ocw-accent); color:var(--ocw-accent); }
155
- .ocw-offline { margin:20px 14px; padding:20px; background:#fff; border:1px solid #e3ded7; border-radius:16px; text-align:center; }
156
- .ocw-offline-icon { font-size:32px; margin-bottom:8px; }
157
- .ocw-offline-title { font-weight:700; font-size:16px; margin-bottom:6px; }
158
- .ocw-offline-msg { font-size:13px; color:var(--ocw-mut); margin-bottom:16px; }
155
+ .ocw-away { margin:0 14px 8px; padding:9px 12px; background:#fff8e6; border:1px solid #f0e2bd; border-radius:10px; font-size:12px; color:#7a5c17; display:flex; gap:7px; align-items:flex-start; line-height:1.45; }
156
+ .ocw-away-icon { flex:none; }
157
+ /* Shared form styles (used by the pre-chat panel; named for the retired offline form). */
159
158
  .ocw-offline-form { display:flex; flex-direction:column; gap:8px; text-align:left; }
160
159
  .ocw-offline-input { border:1px solid #e3ded7; border-radius:10px; padding:10px 12px; font-size:13px; font-family:inherit; }
161
160
  .ocw-offline-input:focus { outline:none; border-color:var(--ocw-accent); }
162
161
  .ocw-offline-submit { background:var(--ocw-accent); color:#fff; border:none; border-radius:10px; padding:11px; font-size:14px; font-weight:600; cursor:pointer; }
163
- .ocw-offline-thanks { font-size:14px; color:#15803d; font-weight:600; }
164
162
  .ocw-prechat { margin:20px 14px; padding:20px; background:#fff; border:1px solid #e3ded7; border-radius:16px; }
165
163
  .ocw-prechat-title { font-weight:700; font-size:15px; margin-bottom:12px; }
166
164
  .ocw-prechat select { border:1px solid #e3ded7; border-radius:10px; padding:10px 12px; font:inherit; font-size:13px; background:#fff; }
@@ -245,9 +243,9 @@ const me = "objectchat-widget-styles", Ne = ["👍", "❤️", "😂", "😮", "
245
243
  .ocw-translated-tag { font-size:10px; color:var(--ocw-mut); margin-top:2px; }
246
244
  `;
247
245
  function We() {
248
- if (typeof document > "u" || document.getElementById(me)) return;
246
+ if (typeof document > "u" || document.getElementById(ge)) return;
249
247
  const t = document.createElement("style");
250
- t.id = me, t.textContent = Ue, document.head.appendChild(t);
248
+ t.id = ge, t.textContent = Ue, document.head.appendChild(t);
251
249
  }
252
250
  function o(t, e, i) {
253
251
  const s = document.createElement(t);
@@ -277,16 +275,16 @@ function ie(t) {
277
275
  return `📅 ${t.title} — ${new Date(t.startIso).toLocaleString()}`;
278
276
  }
279
277
  }
280
- class Ye {
278
+ class Ke {
281
279
  /** Last seq the guest has seen per conversationId — used to compute unread badges. */
282
- constructor(e, i, s, r = {}) {
280
+ constructor(e, i, s, a = {}) {
283
281
  y(this, "scroll");
284
282
  y(this, "chips");
285
283
  y(this, "typing");
286
284
  y(this, "quick");
287
285
  y(this, "formHost");
288
286
  y(this, "csatPanel");
289
- y(this, "offlinePanel");
287
+ y(this, "awayNotice");
290
288
  y(this, "preChatPanel");
291
289
  y(this, "deflectPanel");
292
290
  y(this, "preChatBuilt", !1);
@@ -319,73 +317,73 @@ class Ye {
319
317
  /** Whether the subject card (server Subject entity, mount config fallback)
320
318
  * has been built — built once when data first arrives. */
321
319
  y(this, "subjectBuilt", !1);
322
- var k, I, j, C, R, A, O, U, T, B;
323
- this.root = e, this.me = i, this.h = s, this.cfg = r, We(), e.replaceChildren(), e.classList.add("ocw"), r.accent && e.style.setProperty("--ocw-accent", r.accent);
324
- const a = o("div", "ocw-head");
320
+ var k, I, P, C, R, A, N, U, T, $;
321
+ this.root = e, this.me = i, this.h = s, this.cfg = a, We(), e.replaceChildren(), e.classList.add("ocw"), a.accent && e.style.setProperty("--ocw-accent", a.accent);
322
+ const c = o("div", "ocw-head");
325
323
  if (this.h.onBack) {
326
- const m = o("button", "ocw-back", "‹");
327
- m.type = "button", m.setAttribute("aria-label", "Back"), m.addEventListener("click", () => this.h.onBack()), a.append(m);
324
+ const g = o("button", "ocw-back", "‹");
325
+ g.type = "button", g.setAttribute("aria-label", "Back"), g.addEventListener("click", () => this.h.onBack()), c.append(g);
328
326
  }
329
- const f = o("div", "ocw-avatar");
330
- if ((k = r.userInfo) != null && k.avatar) {
331
- const m = document.createElement("img");
332
- m.src = r.userInfo.avatar, m.alt = r.userInfo.name ?? "You", m.style.cssText = "width:100%;height:100%;border-radius:50%;object-fit:cover", f.append(m);
327
+ const w = o("div", "ocw-avatar");
328
+ if ((k = a.userInfo) != null && k.avatar) {
329
+ const g = document.createElement("img");
330
+ g.src = a.userInfo.avatar, g.alt = a.userInfo.name ?? "You", g.style.cssText = "width:100%;height:100%;border-radius:50%;object-fit:cover", w.append(g);
333
331
  } else
334
- f.textContent = (I = r.userInfo) != null && I.name ? r.userInfo.name[0].toUpperCase() : "🧑";
335
- a.append(f);
332
+ w.textContent = (I = a.userInfo) != null && I.name ? a.userInfo.name[0].toUpperCase() : "🧑";
333
+ c.append(w);
336
334
  const b = o("div", "ocw-head-main");
337
- this.headerName = o("div", "ocw-head-name", ((j = r.subject) == null ? void 0 : j.ownerLabel) ?? ((C = r.subject) == null ? void 0 : C.title) ?? ""), b.append(this.headerName), (R = r.subject) != null && R.subtitle && b.append(o("div", "ocw-head-meta", r.subject.subtitle)), a.append(b), this.statusBadge = o("span", "ocw-badge", ((A = r.subject) == null ? void 0 : A.status) ?? ""), (O = r.subject) != null && O.status || (this.statusBadge.style.display = "none"), a.append(this.statusBadge), this.e2eBadge = o("span", "ocw-e2e", "🔒 E2E"), this.e2eBadge.style.display = "none", a.append(this.e2eBadge), this.connStatus = o("span", "ocw-conn-status"), this.connStatus.style.display = "none", a.append(this.connStatus), this.cobrowseBtn = o("button", "ocw-menu ocw-cobrowse-btn", "🖍"), this.cobrowseBtn.title = "Shared whiteboard — draw to point things out together", this.cobrowseBtn.addEventListener("click", () => {
335
+ this.headerName = o("div", "ocw-head-name", ((P = a.subject) == null ? void 0 : P.ownerLabel) ?? ((C = a.subject) == null ? void 0 : C.title) ?? ""), b.append(this.headerName), (R = a.subject) != null && R.subtitle && b.append(o("div", "ocw-head-meta", a.subject.subtitle)), c.append(b), this.statusBadge = o("span", "ocw-badge", ((A = a.subject) == null ? void 0 : A.status) ?? ""), (N = a.subject) != null && N.status || (this.statusBadge.style.display = "none"), c.append(this.statusBadge), this.e2eBadge = o("span", "ocw-e2e", "🔒 E2E"), this.e2eBadge.style.display = "none", c.append(this.e2eBadge), this.connStatus = o("span", "ocw-conn-status"), this.connStatus.style.display = "none", c.append(this.connStatus), this.cobrowseBtn = o("button", "ocw-menu ocw-cobrowse-btn", "🖍"), this.cobrowseBtn.title = "Shared whiteboard — draw to point things out together", this.cobrowseBtn.addEventListener("click", () => {
338
336
  this.cobrowseActive = !this.cobrowseActive, this.updateCobrowseUI();
339
- }), a.append(this.cobrowseBtn), a.append(o("button", "ocw-menu", "⋯")), this.chips = o("div", "ocw-chiprow"), this.scroll = o("div", "ocw-scroll"), this.subjectCard = o("div", "ocw-subject"), this.typing = o("div", "ocw-typing");
337
+ }), c.append(this.cobrowseBtn), c.append(o("button", "ocw-menu", "⋯")), this.chips = o("div", "ocw-chiprow"), this.scroll = o("div", "ocw-scroll"), this.subjectCard = o("div", "ocw-subject"), this.typing = o("div", "ocw-typing");
340
338
  const d = o("div", "ocw-typing-bubble");
341
339
  d.append(o("div", "ocw-typing-dot"), o("div", "ocw-typing-dot"), o("div", "ocw-typing-dot")), this.typing.append(o("div", "ocw-dot", "🧑"), d), this.quick = o("div", "ocw-quick");
342
- for (const m of r.quickReplies ?? []) {
343
- const S = o("button", void 0, m);
340
+ for (const g of a.quickReplies ?? []) {
341
+ const S = o("button", void 0, g);
344
342
  S.addEventListener("click", () => {
345
- this.h.onSend(m), this.quick.style.display = "none";
343
+ this.h.onSend(g), this.quick.style.display = "none";
346
344
  }), this.quick.append(S);
347
345
  }
348
- this.formHost = o("div", "ocw-form-host"), this.csatPanel = o("div", "ocw-csat"), this.csatPanel.style.display = "none", this.offlinePanel = o("div", "ocw-offline"), this.offlinePanel.style.display = "none", this.preChatPanel = o("div", "ocw-prechat"), this.preChatPanel.style.display = "none", this.deflectPanel = o("div", "ocw-deflect"), this.deflectPanel.style.display = "none", this.input = o("textarea", void 0), this.input.rows = 1, this.input.placeholder = ((U = r.i18n) == null ? void 0 : U.placeholder) ?? "Message…";
346
+ this.formHost = o("div", "ocw-form-host"), this.csatPanel = o("div", "ocw-csat"), this.csatPanel.style.display = "none", this.awayNotice = o("div", "ocw-away"), this.awayNotice.style.display = "none", this.preChatPanel = o("div", "ocw-prechat"), this.preChatPanel.style.display = "none", this.deflectPanel = o("div", "ocw-deflect"), this.deflectPanel.style.display = "none", this.input = o("textarea", void 0), this.input.rows = 1, this.input.placeholder = ((U = a.i18n) == null ? void 0 : U.placeholder) ?? "Message…";
349
347
  const h = o("button", "ocw-sendbtn");
350
348
  h.type = "button";
351
- const v = (T = r.i18n) == null ? void 0 : T.send;
349
+ const v = (T = a.i18n) == null ? void 0 : T.send;
352
350
  v ? (h.textContent = v, h.classList.add("ocw-sendbtn-label"), h.setAttribute("aria-label", v)) : (h.innerHTML = Fe, h.setAttribute("aria-label", "Send message")), h.disabled = !0, this.sendBtn = h, h.addEventListener("click", () => this.flushSend()), this.input.addEventListener("input", () => {
353
- var m, S;
354
- this.sendBtn.disabled = this.input.value.trim().length === 0, this.autoGrowInput(), this.storeRef && !this.storeRef.messages().some((q) => q.senderRole === "guest") ? (S = (m = this.h).onDeflectQuery) == null || S.call(m, this.input.value) : this.hideDeflection();
355
- }), this.input.addEventListener("keydown", (m) => {
356
- m.isComposing || m.keyCode === 229 || (m.key === "Enter" && !m.shiftKey ? (m.preventDefault(), this.flushSend()) : this.signalTyping());
351
+ var g, S;
352
+ this.sendBtn.disabled = this.input.value.trim().length === 0, this.autoGrowInput(), this.storeRef && !this.storeRef.messages().some((q) => q.senderRole === "guest") ? (S = (g = this.h).onDeflectQuery) == null || S.call(g, this.input.value) : this.hideDeflection();
353
+ }), this.input.addEventListener("keydown", (g) => {
354
+ g.isComposing || g.keyCode === 229 || (g.key === "Enter" && !g.shiftKey ? (g.preventDefault(), this.flushSend()) : this.signalTyping());
357
355
  });
358
- const c = o("button", "ocw-attach", "📎");
359
- c.title = "Attach image or file";
356
+ const r = o("button", "ocw-attach", "📎");
357
+ r.title = "Attach image or file";
360
358
  const u = document.createElement("input");
361
- u.type = "file", u.accept = "image/*,.pdf,.txt,.doc,.docx", u.style.display = "none", c.addEventListener("click", () => u.click()), u.addEventListener("change", () => {
362
- var m;
363
- (m = u.files) != null && m[0] && this.h.onAttach && this.h.onAttach(u.files[0]), u.value = "";
359
+ u.type = "file", u.accept = "image/*,.pdf,.txt,.doc,.docx", u.style.display = "none", r.addEventListener("click", () => u.click()), u.addEventListener("change", () => {
360
+ var g;
361
+ (g = u.files) != null && g[0] && this.h.onAttach && this.h.onAttach(u.files[0]), u.value = "";
364
362
  });
365
363
  const l = o("div", "ocw-input");
366
- l.append(c, u, this.input, h);
364
+ l.append(r, u, this.input, h);
367
365
  const E = o("div", "ocw-footer");
368
- ((B = r.i18n) == null ? void 0 : B.poweredBy) !== void 0 ? E.textContent = r.i18n.poweredBy : E.innerHTML = 'Powered by <a href="https://relay.paramms.com" target="_blank" rel="noopener">Relay</a>', this.footer = E, e.append(a, this.chips, this.scroll, this.typing, this.quick, this.formHost, this.csatPanel, this.offlinePanel, this.preChatPanel, this.deflectPanel, l, this.footer), this.cobrowseCanvas = o("canvas", "ocw-cobrowse-canvas"), this.cobrowseToolbar = o("div", "ocw-cobrowse-toolbar");
369
- for (const m of ["#f5713c", "#1c1b1a", "#2563eb", "#16a34a", "#dc2626"]) {
366
+ (($ = a.i18n) == null ? void 0 : $.poweredBy) !== void 0 ? E.textContent = a.i18n.poweredBy : E.innerHTML = 'Powered by <a href="https://relay.paramms.com" target="_blank" rel="noopener">Relay</a>', this.footer = E, e.append(c, this.chips, this.scroll, this.typing, this.quick, this.formHost, this.csatPanel, this.preChatPanel, this.deflectPanel, this.awayNotice, l, this.footer), this.cobrowseCanvas = o("canvas", "ocw-cobrowse-canvas"), this.cobrowseToolbar = o("div", "ocw-cobrowse-toolbar");
367
+ for (const g of ["#f5713c", "#1c1b1a", "#2563eb", "#16a34a", "#dc2626"]) {
370
368
  const S = o("button", "ocw-cobrowse-swatch");
371
- S.style.background = m, S.type = "button", m === this.cobrowseColor && S.classList.add("sel"), S.addEventListener("click", () => {
372
- this.cobrowseColor = m;
369
+ S.style.background = g, S.type = "button", g === this.cobrowseColor && S.classList.add("sel"), S.addEventListener("click", () => {
370
+ this.cobrowseColor = g;
373
371
  for (const q of this.cobrowseToolbar.querySelectorAll(".ocw-cobrowse-swatch")) q.classList.remove("sel");
374
372
  S.classList.add("sel");
375
373
  }), this.cobrowseToolbar.append(S);
376
374
  }
377
- const g = o("button", "ocw-cobrowse-clear", "Clear");
378
- g.addEventListener("click", () => {
379
- var m, S;
380
- return (S = (m = this.h).onAnnotateClear) == null ? void 0 : S.call(m);
381
- }), this.cobrowseToolbar.append(g), this.cobrowseHint = o("div", "ocw-cobrowse-hint", "🖍 Draw to point things out — visible to both sides"), e.append(this.cobrowseCanvas, this.cobrowseToolbar, this.cobrowseHint), this.bindCobrowsePointerEvents();
382
- const w = (m) => {
383
- e.classList.toggle("ocw-compact", m > 0 && m < _e);
375
+ const m = o("button", "ocw-cobrowse-clear", "Clear");
376
+ m.addEventListener("click", () => {
377
+ var g, S;
378
+ return (S = (g = this.h).onAnnotateClear) == null ? void 0 : S.call(g);
379
+ }), this.cobrowseToolbar.append(m), this.cobrowseHint = o("div", "ocw-cobrowse-hint", "🖍 Draw to point things out — visible to both sides"), e.append(this.cobrowseCanvas, this.cobrowseToolbar, this.cobrowseHint), this.bindCobrowsePointerEvents();
380
+ const f = (g) => {
381
+ e.classList.toggle("ocw-compact", g > 0 && g < _e);
384
382
  };
385
- w(e.clientWidth), typeof ResizeObserver < "u" && (this.compactObserver = new ResizeObserver((m) => {
383
+ f(e.clientWidth), typeof ResizeObserver < "u" && (this.compactObserver = new ResizeObserver((g) => {
386
384
  var q;
387
- const S = ((q = m[0]) == null ? void 0 : q.contentRect.width) ?? e.clientWidth;
388
- w(S);
385
+ const S = ((q = g[0]) == null ? void 0 : q.contentRect.width) ?? e.clientWidth;
386
+ f(S);
389
387
  }), this.compactObserver.observe(e));
390
388
  }
391
389
  /** Returns the scroll container so history.ts can attach scroll listeners. */
@@ -420,30 +418,40 @@ class Ye {
420
418
  this.h.onTyping(!0, e), this.typingTimer && clearTimeout(this.typingTimer), this.typingTimer = setTimeout(() => this.h.onTyping(!1), 2e3);
421
419
  }
422
420
  render(e) {
423
- var c, u, l, E, g;
421
+ var r, u, l, E, m;
424
422
  if (this.storeRef = e, this.cobrowseBtn.classList.toggle("show", !!e.subject), !e.subject && this.cobrowseActive && (this.cobrowseActive = !1, this.updateCobrowseUI()), this.cobrowseActive && e.annotationVersion !== this.lastAnnotationVersion && (this.lastAnnotationVersion = e.annotationVersion, this.resizeCobrowseCanvas(), this.redrawCobrowse()), e.accent && this.root.style.setProperty("--ocw-accent", e.accent), this.e2eBadge.style.display = e.e2e ? "inline-flex" : "none", this.buildSubjectCard(e), e.subject) {
425
- const w = (c = this.cfg.subject) == null ? void 0 : c.ownerLabel;
426
- w && (this.headerName.textContent = w);
423
+ const f = (r = this.cfg.subject) == null ? void 0 : r.ownerLabel;
424
+ f && (this.headerName.textContent = f);
427
425
  }
428
426
  this.quick.style.display = e.messages().length === 0 ? "flex" : "none", this.chips.replaceChildren();
429
427
  const i = e.visibleActions();
430
428
  this.chips.style.display = i.length ? "flex" : "none";
431
- for (const w of i) this.chips.append(this.chipEl(w));
432
- const s = this.scroll.scrollHeight, r = this.scroll.scrollTop;
429
+ for (const f of i) this.chips.append(this.chipEl(f));
430
+ const s = this.scroll.scrollHeight, a = this.scroll.scrollTop;
433
431
  if (this.scroll.replaceChildren(), this.subjectCard.childNodes.length && this.scroll.append(this.subjectCard), e.hasMoreHistory) {
434
- const w = o("div", "ocw-load-more");
435
- w.textContent = "↑ Loading earlier messages…", w.style.pointerEvents = "none", this.scroll.append(w);
432
+ const f = o("div", "ocw-load-more");
433
+ f.textContent = "↑ Loading earlier messages…", f.style.pointerEvents = "none", this.scroll.append(f);
436
434
  }
437
- let a = 0;
438
- for (const w of e.messages())
439
- this.scroll.append(this.messageEl(w, e)), w.senderId !== this.me && w.seq > a && (a = w.seq);
440
- r > 20 ? this.scroll.scrollTop = this.scroll.scrollHeight - s + r : this.scroll.scrollTop = this.scroll.scrollHeight, a > 0 && this.h.onReadUpTo(a);
441
- const f = [...e.typing];
442
- this.typing.classList.toggle("active", f.length > 0);
435
+ let c = 0;
436
+ for (const f of e.messages())
437
+ this.scroll.append(this.messageEl(f, e)), f.senderId !== this.me && f.seq > c && (c = f.seq);
438
+ a > 20 ? this.scroll.scrollTop = this.scroll.scrollHeight - s + a : this.scroll.scrollTop = this.scroll.scrollHeight, c > 0 && this.h.onReadUpTo(c);
439
+ const w = [...e.typing];
440
+ this.typing.classList.toggle("active", w.length > 0);
443
441
  const b = this.typing.querySelector(".ocw-typing-bubble");
444
- b && b.setAttribute("aria-label", f.length ? "typing" : ""), this.footer.style.display = e.whiteLabel ? "none" : "block";
445
- const d = e.messages().some((w) => w.senderRole === "guest");
446
- !!((u = e.preChat) != null && u.enabled) && !this.preChatDone && !d && (e.preChat.showWhen !== "offline" || e.offline) ? (this.preChatBuilt || this.buildPreChatPanel(e.preChat), this.preChatPanel.style.display = "block", this.offlinePanel.style.display = "none", (l = this.root.querySelector(".ocw-input")) == null || l.style.setProperty("display", "none")) : (this.preChatPanel.style.display = "none", e.offline ? (this.offlinePanel.style.display === "none" && this.buildOfflinePanel(e.offlineMessage), this.offlinePanel.style.display = "block", (E = this.root.querySelector(".ocw-input")) == null || E.style.setProperty("display", "none")) : (this.offlinePanel.style.display = "none", (g = this.root.querySelector(".ocw-input")) == null || g.style.removeProperty("display")));
442
+ b && b.setAttribute("aria-label", w.length ? "typing" : ""), this.footer.style.display = e.whiteLabel ? "none" : "block";
443
+ const d = e.messages().some((f) => f.senderRole === "guest");
444
+ if (!!((u = e.preChat) != null && u.enabled) && !this.preChatDone && !d && (e.preChat.showWhen !== "offline" || e.offline))
445
+ this.preChatBuilt || this.buildPreChatPanel(e.preChat), this.preChatPanel.style.display = "block", this.awayNotice.style.display = "none", (l = this.root.querySelector(".ocw-input")) == null || l.style.setProperty("display", "none");
446
+ else {
447
+ if (this.preChatPanel.style.display = "none", e.offline) {
448
+ this.awayNotice.firstChild || this.awayNotice.append(o("span", "ocw-away-icon", "🌙"), o("span", "", ""));
449
+ const f = this.awayNotice.lastChild;
450
+ f.textContent = e.offlineMessage || ((E = this.cfg.i18n) == null ? void 0 : E.offline) || "We're away right now — send your message and we'll reply as soon as we're back.", this.awayNotice.style.display = "flex";
451
+ } else
452
+ this.awayNotice.style.display = "none";
453
+ (m = this.root.querySelector(".ocw-input")) == null || m.style.removeProperty("display");
454
+ }
447
455
  const v = ["resolved", "closed", "sold", "issued", "checked_out"];
448
456
  this.h.onCsat && !this.csatSubmitted && v.includes(e.state) && e.messages().length > 0 && (this.csatPanel.style.display === "none" && this.buildCsatPanel(), this.csatPanel.style.display = "block");
449
457
  }
@@ -456,23 +464,6 @@ class Ye {
456
464
  const s = e === "error";
457
465
  this.connStatus.className = `ocw-conn-status${s ? " err" : e === "reconnecting" ? " warn" : ""}`, this.connStatus.textContent = s ? `⚠ ${i ?? "Chat unavailable"}` : e === "reconnecting" ? i ?? "↻ reconnecting…" : "● connecting…";
458
466
  }
459
- buildOfflinePanel(e) {
460
- var b;
461
- this.offlinePanel.replaceChildren(), this.offlinePanel.append(o("div", "ocw-offline-icon", "🌙")), this.offlinePanel.append(o("div", "ocw-offline-title", ((b = this.cfg.i18n) == null ? void 0 : b.offline) ?? "We're offline right now")), this.offlinePanel.append(o("div", "ocw-offline-msg", e || "Leave your details and we'll get back to you soon."));
462
- const i = o("div", "ocw-offline-form"), s = o("input", "ocw-offline-input");
463
- s.placeholder = "Your name", s.type = "text";
464
- const r = o("input", "ocw-offline-input");
465
- r.placeholder = "Your email", r.type = "email";
466
- const a = o("textarea", "ocw-offline-input");
467
- a.placeholder = "Your message", a.rows = 3;
468
- const f = o("button", "ocw-offline-submit", "Send message");
469
- f.type = "button", f.addEventListener("click", () => {
470
- !r.value.trim() || !a.value.trim() || (f.disabled = !0, this.h.onSend(`[Offline form]
471
- Name: ${s.value || "Anonymous"}
472
- Email: ${r.value}
473
- Message: ${a.value}`), this.offlinePanel.replaceChildren(o("div", "ocw-offline-thanks", "✓ Message sent! We'll reply to your email.")));
474
- }), i.append(s, r, a, f), this.offlinePanel.append(i);
475
- }
476
467
  buildPreChatPanel(e) {
477
468
  var d;
478
469
  this.preChatBuilt = !0, this.preChatPanel.replaceChildren(), this.preChatPanel.append(o("div", "ocw-prechat-title", e.title ?? "Before we start…"));
@@ -481,44 +472,44 @@ Message: ${a.value}`), this.offlinePanel.replaceChildren(o("div", "ocw-offline-t
481
472
  const v = o("input", "ocw-offline-input");
482
473
  v.type = h === "email" ? "email" : h === "phone" ? "tel" : "text", v.placeholder = h === "name" ? "Your name" : h === "email" ? "Your email" : "Your phone number", s[h] = v, i.append(v);
483
474
  }
484
- let r = null;
475
+ let a = null;
485
476
  if ((d = e.topics) != null && d.length) {
486
- r = o("select", void 0);
477
+ a = o("select", void 0);
487
478
  const h = document.createElement("option");
488
- h.value = "", h.textContent = "What is this about?", r.append(h);
479
+ h.value = "", h.textContent = "What is this about?", a.append(h);
489
480
  for (const v of e.topics) {
490
- const c = document.createElement("option");
491
- c.value = v, c.textContent = v, r.append(c);
481
+ const r = document.createElement("option");
482
+ r.value = v, r.textContent = v, a.append(r);
492
483
  }
493
- i.append(r);
484
+ i.append(a);
494
485
  }
495
- let a = null, f = null;
486
+ let c = null, w = null;
496
487
  if (e.callbackOption) {
497
488
  const h = o("label", "ocw-prechat-cb");
498
- a = document.createElement("input"), a.type = "checkbox", h.append(a, document.createTextNode("📞 Request a call back")), i.append(h), s.phone || (f = o("input", "ocw-offline-input"), f.type = "tel", f.placeholder = "Phone number for the call", f.style.display = "none", a.addEventListener("change", () => f.style.setProperty("display", a.checked ? "block" : "none")), i.append(f));
489
+ c = document.createElement("input"), c.type = "checkbox", h.append(c, document.createTextNode("📞 Request a call back")), i.append(h), s.phone || (w = o("input", "ocw-offline-input"), w.type = "tel", w.placeholder = "Phone number for the call", w.style.display = "none", c.addEventListener("change", () => w.style.setProperty("display", c.checked ? "block" : "none")), i.append(w));
499
490
  }
500
491
  const b = o("button", "ocw-offline-submit", "Start chat");
501
492
  b.type = "button", b.addEventListener("click", () => {
502
- var u, l, E, g, w, k, I;
493
+ var u, l, E, m, f, k, I;
503
494
  const h = (u = s.email) == null ? void 0 : u.value.trim();
504
495
  if (s.email && (!h || !/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(h))) {
505
496
  s.email.focus();
506
497
  return;
507
498
  }
508
- const v = !!(a != null && a.checked), c = (((l = s.phone) == null ? void 0 : l.value) ?? (f == null ? void 0 : f.value) ?? "").trim();
509
- if (v && !c) {
510
- (E = s.phone ?? f) == null || E.focus();
499
+ const v = !!(c != null && c.checked), r = (((l = s.phone) == null ? void 0 : l.value) ?? (w == null ? void 0 : w.value) ?? "").trim();
500
+ if (v && !r) {
501
+ (E = s.phone ?? w) == null || E.focus();
511
502
  return;
512
503
  }
513
- if (r && ((g = e.topics) != null && g.length) && !r.value) {
514
- r.focus();
504
+ if (a && ((m = e.topics) != null && m.length) && !a.value) {
505
+ a.focus();
515
506
  return;
516
507
  }
517
508
  b.disabled = !0, this.completePreChat(), (I = (k = this.h).onPreChat) == null || I.call(k, {
518
- ...(w = s.name) != null && w.value.trim() ? { name: s.name.value.trim() } : {},
509
+ ...(f = s.name) != null && f.value.trim() ? { name: s.name.value.trim() } : {},
519
510
  ...h ? { email: h } : {},
520
- ...c ? { phone: c } : {},
521
- ...r != null && r.value ? { topic: r.value } : {},
511
+ ...r ? { phone: r } : {},
512
+ ...a != null && a.value ? { topic: a.value } : {},
522
513
  ...v ? { callback: !0 } : {}
523
514
  });
524
515
  }), i.append(b), this.preChatPanel.append(i);
@@ -544,11 +535,11 @@ Message: ${a.value}`), this.offlinePanel.replaceChildren(o("div", "ocw-offline-t
544
535
  this.csatPanel.replaceChildren(), this.csatPanel.append(o("div", "ocw-csat-title", "How did we do?"));
545
536
  const e = o("div", "ocw-csat-stars"), i = [];
546
537
  for (let s = 1; s <= 5; s++) {
547
- const r = o("button", "ocw-csat-star", "★");
548
- r.dataset.score = String(s), r.addEventListener("mouseenter", () => i.forEach((a, f) => a.classList.toggle("lit", f < s))), r.addEventListener("mouseleave", () => i.forEach((a) => a.classList.remove("lit"))), r.addEventListener("click", () => {
549
- var a, f;
550
- this.csatSubmitted = !0, this.csatPanel.replaceChildren(o("div", "ocw-csat-done", `Thanks for your ${s}★ rating!`)), (f = (a = this.h).onCsat) == null || f.call(a, s);
551
- }), i.push(r), e.append(r);
538
+ const a = o("button", "ocw-csat-star", "★");
539
+ a.dataset.score = String(s), a.addEventListener("mouseenter", () => i.forEach((c, w) => c.classList.toggle("lit", w < s))), a.addEventListener("mouseleave", () => i.forEach((c) => c.classList.remove("lit"))), a.addEventListener("click", () => {
540
+ var c, w;
541
+ this.csatSubmitted = !0, this.csatPanel.replaceChildren(o("div", "ocw-csat-done", `Thanks for your ${s}★ rating!`)), (w = (c = this.h).onCsat) == null || w.call(c, s);
542
+ }), i.push(a), e.append(a);
552
543
  }
553
544
  this.csatPanel.append(e);
554
545
  }
@@ -564,9 +555,9 @@ Message: ${a.value}`), this.offlinePanel.replaceChildren(o("div", "ocw-offline-t
564
555
  drawStroke(e) {
565
556
  const i = this.cobrowseCanvas.getContext("2d");
566
557
  if (!i || e.points.length < 2) return;
567
- const s = this.cobrowseCanvas.width, r = this.cobrowseCanvas.height;
568
- i.strokeStyle = e.color, i.lineWidth = Math.max(1, e.width * Math.min(s, r)), i.lineJoin = "round", i.lineCap = "round", i.beginPath(), i.moveTo(e.points[0].x * s, e.points[0].y * r);
569
- for (const a of e.points.slice(1)) i.lineTo(a.x * s, a.y * r);
558
+ const s = this.cobrowseCanvas.width, a = this.cobrowseCanvas.height;
559
+ i.strokeStyle = e.color, i.lineWidth = Math.max(1, e.width * Math.min(s, a)), i.lineJoin = "round", i.lineCap = "round", i.beginPath(), i.moveTo(e.points[0].x * s, e.points[0].y * a);
560
+ for (const c of e.points.slice(1)) i.lineTo(c.x * s, c.y * a);
570
561
  i.stroke();
571
562
  }
572
563
  redrawCobrowse() {
@@ -579,38 +570,38 @@ Message: ${a.value}`), this.offlinePanel.replaceChildren(o("div", "ocw-offline-t
579
570
  }
580
571
  bindCobrowsePointerEvents() {
581
572
  let e = !1, i = [];
582
- const s = (f) => {
583
- const b = this.cobrowseCanvas.getBoundingClientRect(), d = b.width > 0 ? (f.clientX - b.left) / b.width : 0, h = b.height > 0 ? (f.clientY - b.top) / b.height : 0;
573
+ const s = (w) => {
574
+ const b = this.cobrowseCanvas.getBoundingClientRect(), d = b.width > 0 ? (w.clientX - b.left) / b.width : 0, h = b.height > 0 ? (w.clientY - b.top) / b.height : 0;
584
575
  return { x: Math.min(1, Math.max(0, d)), y: Math.min(1, Math.max(0, h)) };
585
- }, r = 6e-3;
586
- this.cobrowseCanvas.addEventListener("pointerdown", (f) => {
587
- this.cobrowseActive && (e = !0, i = [s(f)], this.cobrowseCanvas.setPointerCapture(f.pointerId));
588
- }), this.cobrowseCanvas.addEventListener("pointermove", (f) => {
589
- e && (i.push(s(f)), this.redrawCobrowse(), this.drawStroke({ points: i, color: this.cobrowseColor, width: r }));
576
+ }, a = 6e-3;
577
+ this.cobrowseCanvas.addEventListener("pointerdown", (w) => {
578
+ this.cobrowseActive && (e = !0, i = [s(w)], this.cobrowseCanvas.setPointerCapture(w.pointerId));
579
+ }), this.cobrowseCanvas.addEventListener("pointermove", (w) => {
580
+ e && (i.push(s(w)), this.redrawCobrowse(), this.drawStroke({ points: i, color: this.cobrowseColor, width: a }));
590
581
  });
591
- const a = (f) => {
582
+ const c = (w) => {
592
583
  var b, d;
593
584
  if (e) {
594
- e = !1, i.length > 1 && ((d = (b = this.h).onAnnotate) == null || d.call(b, { id: `an_${Date.now()}_${Math.random().toString(36).slice(2)}`, points: i, color: this.cobrowseColor, width: r })), i = [];
585
+ e = !1, i.length > 1 && ((d = (b = this.h).onAnnotate) == null || d.call(b, { id: `an_${Date.now()}_${Math.random().toString(36).slice(2)}`, points: i, color: this.cobrowseColor, width: a })), i = [];
595
586
  try {
596
- this.cobrowseCanvas.releasePointerCapture(f.pointerId);
587
+ this.cobrowseCanvas.releasePointerCapture(w.pointerId);
597
588
  } catch {
598
589
  }
599
590
  }
600
591
  };
601
- this.cobrowseCanvas.addEventListener("pointerup", a), this.cobrowseCanvas.addEventListener("pointercancel", a);
592
+ this.cobrowseCanvas.addEventListener("pointerup", c), this.cobrowseCanvas.addEventListener("pointercancel", c);
602
593
  }
603
594
  buildSubjectCard(e) {
604
595
  if (this.subjectBuilt) return;
605
- const i = e.subject, s = this.cfg.subject, r = (i == null ? void 0 : i.title) ?? (s == null ? void 0 : s.title);
606
- if (!r) return;
607
- this.subjectBuilt = !0, this.subjectCard.replaceChildren(), this.subjectCard.append(o("div", "ocw-subject-title", r)), s != null && s.subtitle && this.subjectCard.append(o("div", "ocw-subject-sub", s.subtitle));
608
- const a = o("div", "ocw-tags");
609
- if (i) for (const [b, d] of Object.entries(i.fields)) a.append(o("span", "ocw-tag", `${b}: ${d}`));
610
- else for (const b of (s == null ? void 0 : s.tags) ?? []) a.append(o("span", "ocw-tag", b));
611
- a.childNodes.length && this.subjectCard.append(a);
612
- const f = (i == null ? void 0 : i.state) ?? (s == null ? void 0 : s.status);
613
- f && (this.statusBadge.textContent = f, this.statusBadge.style.display = "inline-flex");
596
+ const i = e.subject, s = this.cfg.subject, a = (i == null ? void 0 : i.title) ?? (s == null ? void 0 : s.title);
597
+ if (!a) return;
598
+ this.subjectBuilt = !0, this.subjectCard.replaceChildren(), this.subjectCard.append(o("div", "ocw-subject-title", a)), s != null && s.subtitle && this.subjectCard.append(o("div", "ocw-subject-sub", s.subtitle));
599
+ const c = o("div", "ocw-tags");
600
+ if (i) for (const [b, d] of Object.entries(i.fields)) c.append(o("span", "ocw-tag", `${b}: ${d}`));
601
+ else for (const b of (s == null ? void 0 : s.tags) ?? []) c.append(o("span", "ocw-tag", b));
602
+ c.childNodes.length && this.subjectCard.append(c);
603
+ const w = (i == null ? void 0 : i.state) ?? (s == null ? void 0 : s.status);
604
+ w && (this.statusBadge.textContent = w, this.statusBadge.style.display = "inline-flex");
614
605
  }
615
606
  chipEl(e) {
616
607
  const i = o("button", "ocw-chip", e.icon ? `${e.icon} ${e.label}` : e.label);
@@ -622,14 +613,14 @@ Message: ${a.value}`), this.offlinePanel.replaceChildren(o("div", "ocw-offline-t
622
613
  /** In-widget confirmation modal (replaces window.confirm). */
623
614
  confirm(e) {
624
615
  return new Promise((i) => {
625
- const s = o("div", "ocw-modal"), r = o("div", "ocw-modal-card");
626
- r.append(o("div", "ocw-modal-title", e)), r.append(o("div", "ocw-modal-body", `Confirm “${e}”?`));
627
- const a = o("div", "ocw-modal-actions"), f = o("button", "ocw-modal-cancel", "Cancel"), b = o("button", "ocw-modal-ok", "Confirm"), d = (h) => {
616
+ const s = o("div", "ocw-modal"), a = o("div", "ocw-modal-card");
617
+ a.append(o("div", "ocw-modal-title", e)), a.append(o("div", "ocw-modal-body", `Confirm “${e}”?`));
618
+ const c = o("div", "ocw-modal-actions"), w = o("button", "ocw-modal-cancel", "Cancel"), b = o("button", "ocw-modal-ok", "Confirm"), d = (h) => {
628
619
  s.remove(), i(h);
629
620
  };
630
- f.addEventListener("click", () => d(!1)), b.addEventListener("click", () => d(!0)), s.addEventListener("click", (h) => {
621
+ w.addEventListener("click", () => d(!1)), b.addEventListener("click", () => d(!0)), s.addEventListener("click", (h) => {
631
622
  h.target === s && d(!1);
632
- }), a.append(f, b), r.append(a), s.append(r), this.root.append(s), b.focus();
623
+ }), c.append(w, b), a.append(c), s.append(a), this.root.append(s), b.focus();
633
624
  });
634
625
  }
635
626
  /** Inline form for a form-effect action: typed inputs (date picker, number,
@@ -643,51 +634,51 @@ Message: ${a.value}`), this.offlinePanel.replaceChildren(o("div", "ocw-offline-t
643
634
  for (const h of e.input ?? []) {
644
635
  const v = o("label", "ocw-form-row");
645
636
  if (v.append(o("span", "ocw-form-lbl", h.label)), h.type === "select" && ((b = h.options) != null && b.length)) {
646
- const c = o("select", "ocw-form-input");
647
- h.required || c.append(o("option", void 0, "— select —"));
637
+ const r = o("select", "ocw-form-input");
638
+ h.required || r.append(o("option", void 0, "— select —"));
648
639
  for (const u of h.options) {
649
640
  const l = o("option");
650
- l.value = u, l.textContent = u, c.append(l);
641
+ l.value = u, l.textContent = u, r.append(l);
651
642
  }
652
- h.required && (c.required = !0), v.append(c), s.set(h.name, c);
643
+ h.required && (r.required = !0), v.append(r), s.set(h.name, r);
653
644
  } else {
654
- const c = o("input", "ocw-form-input");
655
- c.type = h.type === "number" ? "number" : h.type === "date" ? "datetime-local" : "text", h.required && (c.required = !0), v.append(c), s.set(h.name, c);
645
+ const r = o("input", "ocw-form-input");
646
+ r.type = h.type === "number" ? "number" : h.type === "date" ? "datetime-local" : "text", h.required && (r.required = !0), v.append(r), s.set(h.name, r);
656
647
  }
657
648
  i.append(v);
658
649
  }
659
- const r = o("div", "ocw-form-actions"), a = o("button", "ocw-form-cancel", "Cancel"), f = o("button", "ocw-form-submit", "Send");
660
- a.addEventListener("click", () => this.formHost.replaceChildren()), f.addEventListener("click", () => {
650
+ const a = o("div", "ocw-form-actions"), c = o("button", "ocw-form-cancel", "Cancel"), w = o("button", "ocw-form-submit", "Send");
651
+ c.addEventListener("click", () => this.formHost.replaceChildren()), w.addEventListener("click", () => {
661
652
  const h = {};
662
- for (const [v, c] of s) {
663
- if (c.required && !c.value) {
664
- c.style.borderColor = "#e5484d";
653
+ for (const [v, r] of s) {
654
+ if (r.required && !r.value) {
655
+ r.style.borderColor = "#e5484d";
665
656
  return;
666
657
  }
667
- h[v] = c.type === "number" ? Number(c.value) : c.value;
658
+ h[v] = r.type === "number" ? Number(r.value) : r.value;
668
659
  }
669
660
  this.formHost.replaceChildren(), this.h.onInvoke(e.id, h);
670
- }), r.append(a, f), i.append(r), this.formHost.append(i), (d = s.values().next().value) == null || d.focus();
661
+ }), a.append(c, w), i.append(a), this.formHost.append(i), (d = s.values().next().value) == null || d.focus();
671
662
  }
672
663
  messageEl(e, i) {
673
- var c;
664
+ var r;
674
665
  if (e.senderRole === "system") {
675
666
  const u = o("div", "ocw-sys");
676
667
  return u.textContent = e.deletedAt ? "message deleted" : ie(e.content), u;
677
668
  }
678
- const s = e.senderId === this.me, r = !!e.internal, a = o("div", `ocw-row ${r ? "ocw-note mine" : s ? "mine" : "theirs"} ${e.senderRole === "bot" ? "ocw-bot" : ""}`);
679
- !s && !r && a.append(o("div", "ocw-dot", e.senderRole === "bot" ? "🤖" : "🧑"));
680
- const f = o("div"), b = o("div", "ocw-bubble-wrap");
669
+ const s = e.senderId === this.me, a = !!e.internal, c = o("div", `ocw-row ${a ? "ocw-note mine" : s ? "mine" : "theirs"} ${e.senderRole === "bot" ? "ocw-bot" : ""}`);
670
+ !s && !a && c.append(o("div", "ocw-dot", e.senderRole === "bot" ? "🤖" : "🧑"));
671
+ const w = o("div"), b = o("div", "ocw-bubble-wrap");
681
672
  if (e.replyToId) {
682
673
  const u = o("div", "ocw-reply-to", "↩ replying to a message");
683
- u.style.cssText = "font-size:11px;color:var(--ocw-mut);margin-bottom:2px;font-style:italic", f.append(u);
674
+ u.style.cssText = "font-size:11px;color:var(--ocw-mut);margin-bottom:2px;font-style:italic", w.append(u);
684
675
  }
685
676
  const d = o("div", "ocw-bubble");
686
677
  let h = null;
687
678
  if (e.deletedAt) d.append(o("span", "ocw-deleted", "message deleted"));
688
679
  else if (e.content.kind === "attachment") {
689
680
  const u = e.content;
690
- if ((c = u.mime) != null && c.startsWith("image/")) {
681
+ if ((r = u.mime) != null && r.startsWith("image/")) {
691
682
  const l = document.createElement("img");
692
683
  l.src = u.url, l.alt = u.name ?? "image", l.style.cssText = "max-width:220px;max-height:160px;border-radius:10px;display:block;cursor:pointer", l.addEventListener("click", () => window.open(u.url, "_blank")), d.append(l);
693
684
  } else {
@@ -697,13 +688,13 @@ Message: ${a.value}`), this.offlinePanel.replaceChildren(o("div", "ocw-offline-t
697
688
  } else if (e.content.kind === "appointment") {
698
689
  const u = e.content, l = o("div", "ocw-appt");
699
690
  l.append(o("div", "ocw-appt-title", `📅 ${u.title}`)), l.append(o("div", "ocw-appt-time", new Date(u.startIso).toLocaleString() + " – " + new Date(u.endIso).toLocaleTimeString())), u.location && l.append(o("div", "ocw-appt-loc", `📍 ${u.location}`)), u.description && l.append(o("div", "ocw-appt-desc", u.description));
700
- const E = o("div", "ocw-appt-links"), g = document.createElement("a");
701
- g.href = u.googleUrl, g.target = "_blank", g.rel = "noopener", g.className = "ocw-appt-btn", g.textContent = "📅 Add to Google Calendar";
702
- const w = document.createElement("a");
703
- w.href = u.icalUrl, w.download = `${u.title}.ics`, w.className = "ocw-appt-btn ocw-appt-btn-sec", w.textContent = "🍎 Apple / iCal", E.append(g, w), l.append(E), d.append(l);
691
+ const E = o("div", "ocw-appt-links"), m = document.createElement("a");
692
+ m.href = u.googleUrl, m.target = "_blank", m.rel = "noopener", m.className = "ocw-appt-btn", m.textContent = "📅 Add to Google Calendar";
693
+ const f = document.createElement("a");
694
+ f.href = u.icalUrl, f.download = `${u.title}.ics`, f.className = "ocw-appt-btn ocw-appt-btn-sec", f.textContent = "🍎 Apple / iCal", E.append(m, f), l.append(E), d.append(l);
704
695
  } else
705
696
  h = document.createTextNode(ie(e.content)), d.append(h), e.editedAt && d.append(o("span", "ocw-edited", "(edited)"));
706
- if (b.append(d), !s && !r && this.h.onTranslate && e.content.kind === "text" && !e.deletedAt && e.seq > 0 && h) {
697
+ if (b.append(d), !s && !a && this.h.onTranslate && e.content.kind === "text" && !e.deletedAt && e.seq > 0 && h) {
707
698
  const u = e.content.text;
708
699
  if (u.trim()) {
709
700
  const l = o("button", "ocw-translate-btn", "🌐");
@@ -712,19 +703,19 @@ Message: ${a.value}`), this.offlinePanel.replaceChildren(o("div", "ocw-offline-t
712
703
  this.showingTranslation.delete(e.id), h.textContent = u, l.textContent = "🌐", l.title = "Translate";
713
704
  return;
714
705
  }
715
- const g = this.translationCache.get(e.id);
716
- if (g !== void 0) {
717
- this.showingTranslation.add(e.id), h.textContent = g, l.textContent = "↩", l.title = "Show original";
706
+ const m = this.translationCache.get(e.id);
707
+ if (m !== void 0) {
708
+ this.showingTranslation.add(e.id), h.textContent = m, l.textContent = "↩", l.title = "Show original";
718
709
  return;
719
710
  }
720
- l.textContent = "⏳", this.h.onTranslate(u).then((w) => {
721
- if (w === null) {
711
+ l.textContent = "⏳", this.h.onTranslate(u).then((f) => {
712
+ if (f === null) {
722
713
  l.textContent = "⚠️", l.title = "Translation unavailable", setTimeout(() => {
723
714
  l.textContent = "🌐", l.title = "Translate";
724
715
  }, 1500);
725
716
  return;
726
717
  }
727
- this.translationCache.set(e.id, w), this.showingTranslation.add(e.id), h.textContent = w, l.textContent = "↩", l.title = "Show original";
718
+ this.translationCache.set(e.id, f), this.showingTranslation.add(e.id), h.textContent = f, l.textContent = "↩", l.title = "Show original";
728
719
  });
729
720
  }), b.append(l);
730
721
  }
@@ -735,21 +726,21 @@ Message: ${a.value}`), this.offlinePanel.replaceChildren(o("div", "ocw-offline-t
735
726
  const l = o("button", void 0, "✏️");
736
727
  l.title = "Edit", l.addEventListener("click", (E) => {
737
728
  E.stopPropagation();
738
- const g = ie(e.content), w = document.createElement("textarea");
739
- w.value = g, w.rows = Math.min(4, Math.ceil(g.length / 40) + 1), w.style.cssText = "width:100%;resize:vertical;border:1px solid var(--ocw-accent);border-radius:8px;padding:6px 10px;font:inherit;font-size:14px;background:#fff;color:#1c1b1a;box-sizing:border-box";
729
+ const m = ie(e.content), f = document.createElement("textarea");
730
+ f.value = m, f.rows = Math.min(4, Math.ceil(m.length / 40) + 1), f.style.cssText = "width:100%;resize:vertical;border:1px solid var(--ocw-accent);border-radius:8px;padding:6px 10px;font:inherit;font-size:14px;background:#fff;color:#1c1b1a;box-sizing:border-box";
740
731
  const k = o("button", "ocw-form-submit", "Save");
741
732
  k.style.cssText = "margin-top:6px;padding:5px 14px;font-size:13px";
742
733
  const I = o("button", "ocw-form-cancel", "Cancel");
743
734
  I.style.cssText = "margin-top:6px;padding:5px 10px;font-size:13px";
744
- const j = o("div");
745
- j.style.cssText = "display:flex;gap:6px;justify-content:flex-end", j.append(I, k);
735
+ const P = o("div");
736
+ P.style.cssText = "display:flex;gap:6px;justify-content:flex-end", P.append(I, k);
746
737
  const C = o("div");
747
- C.append(w, j), d.replaceChildren(C), w.focus(), w.select();
748
- const R = () => d.replaceChildren(h ?? document.createTextNode(g));
738
+ C.append(f, P), d.replaceChildren(C), f.focus(), f.select();
739
+ const R = () => d.replaceChildren(h ?? document.createTextNode(m));
749
740
  I.addEventListener("click", R), k.addEventListener("click", () => {
750
- const A = w.value.trim();
751
- A && A !== g && this.h.onEdit(e.id, A), R();
752
- }), w.addEventListener("keydown", (A) => {
741
+ const A = f.value.trim();
742
+ A && A !== m && this.h.onEdit(e.id, A), R();
743
+ }), f.addEventListener("keydown", (A) => {
753
744
  A.key === "Enter" && !A.shiftKey && (A.preventDefault(), k.click()), A.key === "Escape" && R();
754
745
  });
755
746
  }), u.append(l);
@@ -762,43 +753,43 @@ Message: ${a.value}`), this.offlinePanel.replaceChildren(o("div", "ocw-offline-t
762
753
  }
763
754
  b.append(u);
764
755
  }
765
- if (f.append(b), this.h.onReact && !e.deletedAt && e.seq > 0) {
756
+ if (w.append(b), this.h.onReact && !e.deletedAt && e.seq > 0) {
766
757
  const u = o("div", "ocw-react-wrap"), l = o("div", "ocw-react");
767
758
  if (e.reactions && Object.keys(e.reactions).length)
768
- for (const [w, k] of Object.entries(e.reactions)) {
769
- const I = o("button", `ocw-react-pill${k.includes(this.me) ? " mine" : ""}`, `${w} ${k.length}`);
759
+ for (const [f, k] of Object.entries(e.reactions)) {
760
+ const I = o("button", `ocw-react-pill${k.includes(this.me) ? " mine" : ""}`, `${f} ${k.length}`);
770
761
  I.addEventListener("click", () => {
771
- var j, C;
772
- return (C = (j = this.h).onReact) == null ? void 0 : C.call(j, e.id, w, k.includes(this.me));
762
+ var P, C;
763
+ return (C = (P = this.h).onReact) == null ? void 0 : C.call(P, e.id, f, k.includes(this.me));
773
764
  }), l.append(I);
774
765
  }
775
- const E = o("button", "ocw-react-btn", "+"), g = o("div", "ocw-react-picker");
776
- for (const w of Ne) {
777
- const k = o("button", void 0, w);
766
+ const E = o("button", "ocw-react-btn", "+"), m = o("div", "ocw-react-picker");
767
+ for (const f of He) {
768
+ const k = o("button", void 0, f);
778
769
  k.addEventListener("click", (I) => {
779
- var C, R, A, O;
770
+ var C, R, A, N;
780
771
  I.stopPropagation();
781
- const j = (R = (C = e.reactions) == null ? void 0 : C[w]) == null ? void 0 : R.includes(this.me);
782
- (O = (A = this.h).onReact) == null || O.call(A, e.id, w, !!j), g.style.display = "none";
783
- }), g.append(k);
772
+ const P = (R = (C = e.reactions) == null ? void 0 : C[f]) == null ? void 0 : R.includes(this.me);
773
+ (N = (A = this.h).onReact) == null || N.call(A, e.id, f, !!P), m.style.display = "none";
774
+ }), m.append(k);
784
775
  }
785
- g.style.display = "none", E.addEventListener("click", (w) => {
786
- w.stopPropagation();
787
- const k = g.style.display === "none";
788
- g.style.display = k ? "flex" : "none", k && document.addEventListener("click", () => {
789
- g.style.display = "none";
776
+ m.style.display = "none", E.addEventListener("click", (f) => {
777
+ f.stopPropagation();
778
+ const k = m.style.display === "none";
779
+ m.style.display = k ? "flex" : "none", k && document.addEventListener("click", () => {
780
+ m.style.display = "none";
790
781
  }, { once: !0 });
791
- }), l.append(E), u.append(l, g), f.append(u);
792
- } else e.reactions && Object.keys(e.reactions).length && f.append(o("div", "ocw-react", Object.entries(e.reactions).map(([u, l]) => `${u}${l.length}`).join(" ")));
782
+ }), l.append(E), u.append(l, m), w.append(u);
783
+ } else e.reactions && Object.keys(e.reactions).length && w.append(o("div", "ocw-react", Object.entries(e.reactions).map(([u, l]) => `${u}${l.length}`).join(" ")));
793
784
  const v = o("div", "ocw-time ocw-meta", Ve(e.ts));
794
785
  if (s && e.status) {
795
- const u = o("span", `ocw-tick${e.status === "read" ? " read" : e.status === "delivered" ? " delivered" : ""}`, Ke(e.status));
786
+ const u = o("span", `ocw-tick${e.status === "read" ? " read" : e.status === "delivered" ? " delivered" : ""}`, Ge(e.status));
796
787
  v.append(u);
797
788
  }
798
- return s && e.seq > 0 && i.lastReadByOthers >= e.seq && v.append(o("span", "ocw-seen", " · Seen")), f.append(v), a.append(f), a;
789
+ return s && e.seq > 0 && i.lastReadByOthers >= e.seq && v.append(o("span", "ocw-seen", " · Seen")), w.append(v), c.append(w), c;
799
790
  }
800
791
  }
801
- function Ke(t) {
792
+ function Ge(t) {
802
793
  switch (t) {
803
794
  case "read":
804
795
  return "✓✓";
@@ -810,12 +801,12 @@ function Ke(t) {
810
801
  return "🕓";
811
802
  }
812
803
  }
813
- const H = /* @__PURE__ */ new WeakMap(), X = /* @__PURE__ */ new Map();
814
- function ge(t) {
804
+ const O = /* @__PURE__ */ new WeakMap(), X = /* @__PURE__ */ new Map();
805
+ function me(t) {
815
806
  return `relay-launcher::${t.profileId}::${t.subjectId ?? ""}`;
816
807
  }
817
808
  let F = null;
818
- function Ge() {
809
+ function Ye() {
819
810
  if (F && F.state !== "closed") return F;
820
811
  try {
821
812
  return F = new AudioContext(), F;
@@ -825,25 +816,25 @@ function Ge() {
825
816
  }
826
817
  function tt(t) {
827
818
  var e;
828
- (e = H.get(t)) == null || e.close(), H.delete(t);
819
+ (e = O.get(t)) == null || e.close(), O.delete(t);
829
820
  }
830
821
  function ot(t) {
831
822
  var le, de, pe, he, ue;
832
- H.has(t.el) && (H.get(t.el).close(), H.delete(t.el)), t.launcher && ((le = X.get(ge(t))) == null || le.close());
833
- const e = je();
823
+ O.has(t.el) && (O.get(t.el).close(), O.delete(t.el)), t.launcher && ((le = X.get(me(t))) == null || le.close());
824
+ const e = Pe();
834
825
  let i, s = !1;
835
- const r = t.token ?? t.userId ?? e, a = r !== e ? e : void 0, { wsUrl: f, httpBase: b } = Ae(t.url, t.apiUrl);
836
- let d = new Me(r);
837
- const h = t.subjectId ? `${r}::${t.subjectId}` : r, v = new Be(h);
838
- let c, u = !1, l = null, E = null, g = null, w = null;
826
+ const a = t.token ?? t.userId ?? e, c = a !== e ? e : void 0, { wsUrl: w, httpBase: b } = Ae(t.url, t.apiUrl);
827
+ let d = new Me(a);
828
+ const h = t.subjectId ? `${a}::${t.subjectId}` : a, v = new $e(h);
829
+ let r, u = !1, l = null, E = null, m = null, f = null;
839
830
  !t.launcher && !t.el.style.height && t.el.clientHeight === 0 && (t.el.style.width = t.el.style.width || "100%", t.el.style.height = "600px");
840
831
  for (const n of v.load()) d.addOptimistic(n.clientMsgId, n.content);
841
- let k = null, I = null, j = 0, C = !t.launcher;
832
+ let k = null, I = null, P = 0, C = !t.launcher;
842
833
  if (t.launcher) {
843
834
  const p = (t.position ?? "bottom-right").includes("right");
844
835
  k = document.createElement("div"), k.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`;
845
- const x = document.createElement("div"), L = typeof window < "u" && typeof window.matchMedia == "function" ? window.matchMedia("(max-width: 479px)") : null, V = (P) => {
846
- t.el.classList.toggle("ocw-fs", P), x.style.cssText = P ? [
836
+ const x = document.createElement("div"), j = typeof window < "u" && typeof window.matchMedia == "function" ? window.matchMedia("(max-width: 479px)") : null, V = (L) => {
837
+ t.el.classList.toggle("ocw-fs", L), x.style.cssText = L ? [
847
838
  "position:fixed",
848
839
  "inset:0",
849
840
  "width:100%",
@@ -872,9 +863,9 @@ function ot(t) {
872
863
  "transform:scale(.95)"
873
864
  ].join(";");
874
865
  };
875
- V((L == null ? void 0 : L.matches) ?? !1);
876
- const Y = (P) => V(P.matches);
877
- L == null || L.addEventListener("change", Y), l = L, E = Y, t.el.style.cssText = "width:100%;height:100%;overflow:hidden", x.append(t.el);
866
+ V((j == null ? void 0 : j.matches) ?? !1);
867
+ const K = (L) => V(L.matches);
868
+ j == null || j.addEventListener("change", K), l = j, E = K, t.el.style.cssText = "width:100%;height:100%;overflow:hidden", x.append(t.el);
878
869
  const Q = '<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>', M = document.createElement("button");
879
870
  M.type = "button", M.style.cssText = [
880
871
  "width:56px;height:56px;border-radius:50%",
@@ -889,11 +880,11 @@ function ot(t) {
889
880
  }, M.onmouseleave = () => {
890
881
  M.style.transform = "scale(1)";
891
882
  }, I = document.createElement("span"), I.style.cssText = "position:absolute;top:-4px;right:-4px;background:#ef4444;color:#fff;border-radius:50%;width:20px;height:20px;font-size:11px;font-weight:700;display:none;align-items:center;justify-content:center";
892
- const K = () => {
883
+ const G = () => {
893
884
  M.innerHTML = C ? Z : Q, M.setAttribute("aria-label", C ? "Close chat" : "Open chat"), M.setAttribute("aria-expanded", String(C)), M.append(I);
894
885
  };
895
- K(), k.append(x, M), document.body.append(k);
896
- const ee = `ocw-teaser-dismissed::${t.profileId}`, G = typeof t.launcherMessage == "string" ? { title: t.launcherMessage } : t.launcherMessage;
886
+ G(), k.append(x, M), document.body.append(k);
887
+ const ee = `ocw-teaser-dismissed::${t.profileId}`, Y = typeof t.launcherMessage == "string" ? { title: t.launcherMessage } : t.launcherMessage;
897
888
  let z = null;
898
889
  const Se = () => {
899
890
  try {
@@ -902,13 +893,13 @@ function ot(t) {
902
893
  return !1;
903
894
  }
904
895
  }, ze = '<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>', fe = () => {
905
- const P = G != null && G.title ? G : d.launcherMessage ?? void 0;
906
- if (!(!!(P != null && P.title) && !C && !Se())) {
896
+ const L = Y != null && Y.title ? Y : d.launcherMessage ?? void 0;
897
+ if (!(!!(L != null && L.title) && !C && !Se())) {
907
898
  z && (z.remove(), z = null);
908
899
  return;
909
900
  }
910
901
  if (z) return;
911
- z = document.createElement("div"), z.setAttribute("role", "button"), z.setAttribute("tabindex", "0"), z.setAttribute("aria-label", P.title), z.style.cssText = [
902
+ z = document.createElement("div"), z.setAttribute("role", "button"), z.setAttribute("tabindex", "0"), z.setAttribute("aria-label", L.title), z.style.cssText = [
912
903
  "max-width:280px",
913
904
  "background:#fff",
914
905
  "border-radius:14px",
@@ -921,60 +912,60 @@ function ot(t) {
921
912
  "animation:ocw-teaser-in .22s ease-out"
922
913
  ].join(";");
923
914
  const oe = document.createElement("div");
924
- if (oe.textContent = P.title, oe.style.cssText = "font-size:15px;font-weight:600;color:#111;line-height:1.35", z.append(oe), P.subtitle) {
915
+ if (oe.textContent = L.title, oe.style.cssText = "font-size:15px;font-weight:600;color:#111;line-height:1.35", z.append(oe), L.subtitle) {
925
916
  const D = document.createElement("div");
926
917
  D.style.cssText = "display:flex;align-items:center;gap:6px;margin-top:6px;font-size:13px;color:#6b7280";
927
918
  const ne = document.createElement("span");
928
919
  ne.innerHTML = ze, ne.style.cssText = `color:${t.accent ?? "#4F63F5"};display:inline-flex`;
929
920
  const be = document.createElement("span");
930
- be.textContent = P.subtitle, D.append(ne, be), z.append(D);
921
+ be.textContent = L.subtitle, D.append(ne, be), z.append(D);
931
922
  }
932
- const N = document.createElement("button");
933
- N.type = "button", N.setAttribute("aria-label", "Dismiss"), N.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>', N.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", N.addEventListener("click", (D) => {
923
+ const H = document.createElement("button");
924
+ H.type = "button", H.setAttribute("aria-label", "Dismiss"), H.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>', H.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", H.addEventListener("click", (D) => {
934
925
  D.stopPropagation();
935
926
  try {
936
927
  sessionStorage.setItem(ee, "1");
937
928
  } catch {
938
929
  }
939
930
  z && (z.remove(), z = null);
940
- }), z.append(N);
931
+ }), z.append(H);
941
932
  const we = () => {
942
- C || (C = !0, te(!0), K(), j = 0, I && (I.style.display = "none"), z && (z.remove(), z = null));
933
+ C || (C = !0, te(!0), G(), P = 0, I && (I.style.display = "none"), z && (z.remove(), z = null));
943
934
  };
944
935
  z.addEventListener("click", we), z.addEventListener("keydown", (D) => {
945
936
  (D.key === "Enter" || D.key === " ") && (D.preventDefault(), we());
946
937
  }), k.insertBefore(z, M);
947
938
  };
948
939
  if (!document.getElementById("ocw-teaser-style")) {
949
- const P = document.createElement("style");
950
- P.id = "ocw-teaser-style", P.textContent = "@keyframes ocw-teaser-in{from{opacity:0;transform:translateY(8px)}to{opacity:1;transform:translateY(0)}}", document.head.append(P);
940
+ const L = document.createElement("style");
941
+ L.id = "ocw-teaser-style", L.textContent = "@keyframes ocw-teaser-in{from{opacity:0;transform:translateY(8px)}to{opacity:1;transform:translateY(0)}}", document.head.append(L);
951
942
  }
952
- w = fe, fe();
953
- const te = (P) => {
954
- P ? (x.style.display = "flex", requestAnimationFrame(() => {
943
+ f = fe, fe();
944
+ const te = (L) => {
945
+ L ? (x.style.display = "flex", requestAnimationFrame(() => {
955
946
  x.style.opacity = "1", x.style.transform = "scale(1)";
956
947
  })) : (x.style.opacity = "0", x.style.transform = "scale(.95)", setTimeout(() => {
957
948
  C || (x.style.display = "none");
958
949
  }, 180));
959
950
  };
960
951
  M.addEventListener("click", () => {
961
- if (C = !C, te(C), K(), C) {
962
- j = 0, I && (I.style.display = "none");
952
+ if (C = !C, te(C), G(), C) {
953
+ P = 0, I && (I.style.display = "none");
963
954
  try {
964
955
  sessionStorage.setItem(ee, "1");
965
956
  } catch {
966
957
  }
967
958
  }
968
- w == null || w();
969
- }), g = (P) => {
970
- P.key === "Escape" && C && (C = !1, te(!1), K());
971
- }, document.addEventListener("keydown", g);
959
+ f == null || f();
960
+ }), m = (L) => {
961
+ L.key === "Escape" && C && (C = !1, te(!1), G());
962
+ }, document.addEventListener("keydown", m);
972
963
  }
973
964
  const R = () => {
974
- C || (j++, I && (I.textContent = String(j), I.style.display = "flex"));
965
+ C || (P++, I && (I.textContent = String(P), I.style.display = "flex"));
975
966
  }, A = () => {
976
967
  try {
977
- const n = Ge();
968
+ const n = Ye();
978
969
  if (!n) return;
979
970
  n.state === "suspended" && n.resume().catch(() => {
980
971
  });
@@ -982,24 +973,24 @@ function ot(t) {
982
973
  p.connect(x), x.connect(n.destination), p.frequency.setValueAtTime(880, n.currentTime), p.frequency.exponentialRampToValueAtTime(440, n.currentTime + 0.15), x.gain.setValueAtTime(0.3, n.currentTime), x.gain.exponentialRampToValueAtTime(1e-3, n.currentTime + 0.3), p.start(), p.stop(n.currentTime + 0.3);
983
974
  } catch {
984
975
  }
985
- }, O = [], U = (n) => {
986
- for (; O.length; ) {
987
- const p = O.shift();
976
+ }, N = [], U = (n) => {
977
+ for (; N.length; ) {
978
+ const p = N.shift();
988
979
  v.add({ clientMsgId: p.clientMsgId, content: p.content, ts: Date.now() }), T.send({ type: "send", conversationId: n, clientMsgId: p.clientMsgId, content: p.content });
989
980
  }
990
981
  };
991
982
  let T;
992
- const B = new qe(`ocw-e2e-${t.profileId}`);
993
- let m = !1;
983
+ const $ = new qe(`ocw-e2e-${t.profileId}`);
984
+ let g = !1;
994
985
  const S = [], q = [];
995
986
  let se = !1;
996
987
  const J = (n, p) => {
997
- B.sealText(p).then((x) => {
998
- c && T.send({ type: "send", conversationId: c, clientMsgId: n, content: x });
988
+ $.sealText(p).then((x) => {
989
+ r && T.send({ type: "send", conversationId: r, clientMsgId: n, content: x });
999
990
  });
1000
991
  }, ye = (n, p, x) => {
1001
- B.sealText(p, x).then((L) => {
1002
- c && T.send({ type: "send", conversationId: c, clientMsgId: n, content: L });
992
+ $.sealText(p, x).then((j) => {
993
+ r && T.send({ type: "send", conversationId: r, clientMsgId: n, content: j });
1003
994
  });
1004
995
  }, ve = () => {
1005
996
  for (; S.length; ) {
@@ -1014,42 +1005,42 @@ function ot(t) {
1014
1005
  T.send({ type: "fetchPrekey", targetUserId: n });
1015
1006
  }, Ce = t.i18n ?? {}, Te = ["ar", "he", "fa", "ur"], Ee = typeof navigator < "u" ? (navigator.language ?? "").slice(0, 2).toLowerCase() : "";
1016
1007
  Te.includes(Ee) && !t.el.dir && (t.el.dir = "rtl", t.el.style.fontFamily = t.el.style.fontFamily || "Tahoma,Arial,system-ui,sans-serif");
1017
- const re = new He(), ae = `oc_prechat_${t.profileId}_${r.slice(-8)}`, $ = new Ye(t.el, r, {
1008
+ const ae = new Oe(), re = `oc_prechat_${t.profileId}_${a.slice(-8)}`, B = new Ke(t.el, a, {
1018
1009
  onSend(n) {
1019
1010
  const p = `cm_${Math.random().toString(36).slice(2)}`, x = { kind: "text", text: n };
1020
- d.addOptimistic(p, x), $.render(d), d.e2e ? B.ready ? J(p, n) : se ? q.push({ clientMsgId: p, text: n }) : (S.push({ clientMsgId: p, text: n }), d.assignedAgentId && ke(d.assignedAgentId)) : c ? (v.add({ clientMsgId: p, content: x, ts: Date.now() }), T.send({ type: "send", conversationId: c, clientMsgId: p, content: x })) : O.push({ clientMsgId: p, content: x });
1011
+ d.addOptimistic(p, x), B.render(d), d.e2e ? $.ready ? J(p, n) : se ? q.push({ clientMsgId: p, text: n }) : (S.push({ clientMsgId: p, text: n }), d.assignedAgentId && ke(d.assignedAgentId)) : r ? (v.add({ clientMsgId: p, content: x, ts: Date.now() }), T.send({ type: "send", conversationId: r, clientMsgId: p, content: x })) : N.push({ clientMsgId: p, content: x });
1021
1012
  },
1022
1013
  async onAttach(n) {
1023
- if (!c) return;
1014
+ if (!r) return;
1024
1015
  const p = `${b}/upload?name=${encodeURIComponent(n.name)}`, x = `cm_${Math.random().toString(36).slice(2)}`;
1025
- d.addOptimistic(x, { kind: "text", text: `📎 Uploading ${n.name}…` }), $.render(d);
1016
+ d.addOptimistic(x, { kind: "text", text: `📎 Uploading ${n.name}…` }), B.render(d);
1026
1017
  try {
1027
- const L = await fetch(p, {
1018
+ const j = await fetch(p, {
1028
1019
  method: "POST",
1029
1020
  // Use the resolved connection token (a signed JWT, an explicit userId,
1030
1021
  // or the anonymous persistent uid) — NOT just opts.token. The server
1031
1022
  // requires an Authorization header, and the verifier accepts an
1032
1023
  // anonymous id as a guest; keying off opts.token alone meant anonymous
1033
1024
  // visitors (the common case) sent no auth and every upload 401'd.
1034
- headers: { "content-type": n.type, authorization: `Bearer ${r}` },
1025
+ headers: { "content-type": n.type, authorization: `Bearer ${a}` },
1035
1026
  body: n
1036
1027
  });
1037
- if (!L.ok) throw new Error(`Upload failed: ${L.status}`);
1038
- const { url: V, name: Y, mime: Q, size: Z } = await L.json();
1039
- T.send({ type: "send", conversationId: c, clientMsgId: x, content: { kind: "attachment", url: V, name: Y, mime: Q, size: Z } });
1040
- } catch (L) {
1041
- d.addOptimistic(x, { kind: "text", text: `⚠️ Upload failed: ${L.message}` }), $.render(d);
1028
+ if (!j.ok) throw new Error(`Upload failed: ${j.status}`);
1029
+ const { url: V, name: K, mime: Q, size: Z } = await j.json();
1030
+ T.send({ type: "send", conversationId: r, clientMsgId: x, content: { kind: "attachment", url: V, name: K, mime: Q, size: Z } });
1031
+ } catch (j) {
1032
+ d.addOptimistic(x, { kind: "text", text: `⚠️ Upload failed: ${j.message}` }), B.render(d);
1042
1033
  }
1043
1034
  },
1044
1035
  onInvoke(n, p) {
1045
- c && T.send({ type: "invoke", conversationId: c, actionId: n, clientInvokeId: `iv_${Math.random().toString(36).slice(2)}`, ...p ? { inputs: p } : {} });
1036
+ r && T.send({ type: "invoke", conversationId: r, actionId: n, clientInvokeId: `iv_${Math.random().toString(36).slice(2)}`, ...p ? { inputs: p } : {} });
1046
1037
  },
1047
1038
  onTyping(n, p) {
1048
- c && T.send({ type: "typing", conversationId: c, isTyping: n, ...p ? { preview: p } : {} });
1039
+ r && T.send({ type: "typing", conversationId: r, isTyping: n, ...p ? { preview: p } : {} });
1049
1040
  },
1050
1041
  onPreChat(n) {
1051
1042
  try {
1052
- localStorage.setItem(ae, "1");
1043
+ localStorage.setItem(re, "1");
1053
1044
  } catch {
1054
1045
  }
1055
1046
  T.send({
@@ -1066,57 +1057,57 @@ function ot(t) {
1066
1057
  }
1067
1058
  });
1068
1059
  const p = n.callback ? `📞 Call-back requested${n.phone ? `: ${n.phone}` : ""}${n.topic ? ` — ${n.topic}` : ""}` : n.topic ? `Topic: ${n.topic}` : "";
1069
- p && c && !d.e2e && T.send({ type: "send", conversationId: c, clientMsgId: `pc_${Math.random().toString(36).slice(2, 12)}`, content: { kind: "text", text: p } });
1060
+ p && r && !d.e2e && T.send({ type: "send", conversationId: r, clientMsgId: `pc_${Math.random().toString(36).slice(2, 12)}`, content: { kind: "text", text: p } });
1070
1061
  },
1071
1062
  onDeflectQuery(n) {
1072
1063
  if (s) return;
1073
1064
  clearTimeout(i);
1074
1065
  const p = n.trim();
1075
1066
  if (p.length < 3) {
1076
- $.hideDeflection();
1067
+ B.hideDeflection();
1077
1068
  return;
1078
1069
  }
1079
1070
  i = setTimeout(() => {
1080
- fetch(`${b}/kb/search?profileId=${encodeURIComponent(t.profileId)}&q=${encodeURIComponent(p.slice(0, 200))}`).then((x) => x.ok ? x.json() : { articles: [] }).then((x) => $.showDeflection(x.articles ?? [])).catch(() => $.hideDeflection());
1071
+ fetch(`${b}/kb/search?profileId=${encodeURIComponent(t.profileId)}&q=${encodeURIComponent(p.slice(0, 200))}`).then((x) => x.ok ? x.json() : { articles: [] }).then((x) => B.showDeflection(x.articles ?? [])).catch(() => B.hideDeflection());
1081
1072
  }, 350);
1082
1073
  },
1083
1074
  onReadUpTo(n) {
1084
- c && T.send({ type: "read", conversationId: c, seq: n });
1075
+ r && T.send({ type: "read", conversationId: r, seq: n });
1085
1076
  },
1086
1077
  onLoadMore() {
1087
- if (!c || !d.e2e) return;
1078
+ if (!r || !d.e2e) return;
1088
1079
  const n = d.messages()[0];
1089
- n && T.send({ type: "history", conversationId: c, beforeSeq: n.seq, limit: 20 });
1080
+ n && T.send({ type: "history", conversationId: r, beforeSeq: n.seq, limit: 20 });
1090
1081
  },
1091
1082
  onEdit(n, p) {
1092
- c && T.send({ type: "edit", conversationId: c, messageId: n, content: { kind: "text", text: p } });
1083
+ r && T.send({ type: "edit", conversationId: r, messageId: n, content: { kind: "text", text: p } });
1093
1084
  },
1094
1085
  onDelete(n) {
1095
- c && T.send({ type: "delete", conversationId: c, messageId: n });
1086
+ r && T.send({ type: "delete", conversationId: r, messageId: n });
1096
1087
  },
1097
1088
  onReact(n, p, x) {
1098
- c && T.send({ type: "react", conversationId: c, messageId: n, emoji: p, remove: x });
1089
+ r && T.send({ type: "react", conversationId: r, messageId: n, emoji: p, remove: x });
1099
1090
  },
1100
1091
  onCsat(n) {
1101
- c && fetch(`${b}/conversations/${c}/csat`, {
1092
+ r && fetch(`${b}/conversations/${r}/csat`, {
1102
1093
  method: "POST",
1103
- headers: { "Content-Type": "application/json", Authorization: `Bearer ${r}` },
1094
+ headers: { "Content-Type": "application/json", Authorization: `Bearer ${a}` },
1104
1095
  body: JSON.stringify({ score: n })
1105
1096
  }).catch(() => {
1106
1097
  });
1107
1098
  },
1108
1099
  onAnnotate(n) {
1109
- c && T.send({ type: "annotate", conversationId: c, stroke: n });
1100
+ r && T.send({ type: "annotate", conversationId: r, stroke: n });
1110
1101
  },
1111
1102
  onAnnotateClear() {
1112
- c && T.send({ type: "annotate_clear", conversationId: c });
1103
+ r && T.send({ type: "annotate_clear", conversationId: r });
1113
1104
  },
1114
1105
  ...t.translateLang ? {
1115
1106
  async onTranslate(n) {
1116
1107
  try {
1117
1108
  const p = await fetch(`${b}/translate`, {
1118
1109
  method: "POST",
1119
- headers: { "content-type": "application/json", authorization: `Bearer ${r}` },
1110
+ headers: { "content-type": "application/json", authorization: `Bearer ${a}` },
1120
1111
  body: JSON.stringify({ text: n, targetLang: t.translateLang })
1121
1112
  });
1122
1113
  if (!p.ok) return null;
@@ -1136,7 +1127,7 @@ function ot(t) {
1136
1127
  i18n: Ce
1137
1128
  });
1138
1129
  try {
1139
- localStorage.getItem(ae) && $.completePreChat();
1130
+ localStorage.getItem(re) && B.completePreChat();
1140
1131
  } catch {
1141
1132
  }
1142
1133
  const ce = t.user && (t.user.name || t.user.email || t.user.avatar || t.user.meta) ? {
@@ -1151,7 +1142,7 @@ function ot(t) {
1151
1142
  // server-derived and owner-keyed, so passing it as subjectId from the
1152
1143
  // NON-owner side would find-or-create a junk duplicate thread.
1153
1144
  ...t.kind === "direct" && t.peerId ? { kind: "direct", peerId: t.peerId } : t.subjectId ? { subjectId: t.subjectId } : {},
1154
- ...a ? { linkFrom: a } : {},
1145
+ ...c ? { linkFrom: c } : {},
1155
1146
  ...ce ? { userInfo: ce } : {},
1156
1147
  ...typeof location < "u" ? { pageUrl: location.href } : {},
1157
1148
  ...typeof document < "u" && document.title ? { pageTitle: document.title } : {},
@@ -1162,72 +1153,72 @@ function ot(t) {
1162
1153
  };
1163
1154
  T = new Re({
1164
1155
  ...t.refreshToken ? { refreshToken: t.refreshToken } : {},
1165
- url: f,
1166
- token: r,
1156
+ url: w,
1157
+ token: a,
1167
1158
  open: Ie,
1168
1159
  getCursor: () => d.highestSeq(),
1169
- onStatusChange: (n, p) => $.setConnStatus(n, p),
1160
+ onStatusChange: (n, p) => B.setConnStatus(n, p),
1170
1161
  onFrame(n) {
1171
- if (re.apply(n), n.type === "opened") {
1172
- if (c = n.conversation.id, !u) {
1162
+ if (ae.apply(n), n.type === "opened") {
1163
+ if (r = n.conversation.id, !u) {
1173
1164
  u = !0;
1174
1165
  for (const p of v.load())
1175
- T.send({ type: "send", conversationId: c, clientMsgId: p.clientMsgId, content: p.content });
1166
+ T.send({ type: "send", conversationId: r, clientMsgId: p.clientMsgId, content: p.content });
1176
1167
  }
1177
- $e(f, r, c, d, $, b), O.length && U(c);
1168
+ Be(w, a, r, d, B, b), N.length && U(r);
1178
1169
  }
1179
1170
  if (n.type === "ack" && v.remove(n.clientMsgId), n.type === "prekeyBundle") {
1180
- n.bundle && (se = !0, B.x3dhSendTo(n.bundle).then((p) => {
1171
+ n.bundle && (se = !0, $.x3dhSendTo(n.bundle).then((p) => {
1181
1172
  const x = [...S.splice(0), ...q.splice(0)];
1182
- for (const L of x) ye(L.clientMsgId, L.text, p);
1183
- $.render(d);
1173
+ for (const j of x) ye(j.clientMsgId, j.text, p);
1174
+ B.render(d);
1184
1175
  }));
1185
1176
  return;
1186
1177
  }
1187
1178
  if (n.type === "message" && d.e2e) {
1188
- const p = Oe(n.message.content);
1189
- if (p && !B.ready) {
1190
- B.x3dhReceiveFrom(p.x3dhIK, p.x3dhEK, p.x3dhSPK).then(async () => {
1191
- await B.openFrame(n), d.apply(n), $.render(d);
1179
+ const p = Ne(n.message.content);
1180
+ if (p && !$.ready) {
1181
+ $.x3dhReceiveFrom(p.x3dhIK, p.x3dhEK, p.x3dhSPK).then(async () => {
1182
+ await $.openFrame(n), d.apply(n), B.render(d);
1192
1183
  });
1193
1184
  return;
1194
1185
  }
1195
1186
  }
1196
1187
  if (n.type === "peerkey") {
1197
- B.onPeerKey(n.key).then(() => {
1198
- ve(), $.render(d);
1188
+ $.onPeerKey(n.key).then(() => {
1189
+ ve(), B.render(d);
1199
1190
  });
1200
1191
  return;
1201
1192
  }
1202
1193
  (async () => {
1203
- if (d.e2e && await B.openFrame(n), d.apply(n), n.type === "manifest" && (w == null || w()), n.type === "message" && n.message.senderId !== r && !n.message.internal && (R(), A()), d.e2e && c && !m) {
1204
- m = !0;
1205
- const p = await B.initX3DH();
1194
+ if (d.e2e && await $.openFrame(n), d.apply(n), n.type === "manifest" && (f == null || f()), n.type === "message" && n.message.senderId !== a && !n.message.internal && (R(), A()), d.e2e && r && !g) {
1195
+ g = !0;
1196
+ const p = await $.initX3DH();
1206
1197
  T.send({ type: "uploadPrekeys", ...p });
1207
- const x = await B.begin();
1208
- T.send({ type: "pubkey", conversationId: c, key: x });
1198
+ const x = await $.begin();
1199
+ T.send({ type: "pubkey", conversationId: r, key: x });
1209
1200
  }
1210
- $.render(d);
1201
+ B.render(d);
1211
1202
  })();
1212
1203
  }
1213
- }), T.connect(), $.render(d);
1214
- const _ = t.launcher ? ge(t) : null, W = { close: () => {
1215
- s = !0, clearTimeout(i), T.close(), k == null || k.remove(), $.destroy(), re.destroy(), l && E && l.removeEventListener("change", E), g && (document.removeEventListener("keydown", g), g = null), H.delete(t.el), _ && X.get(_) === W && X.delete(_);
1204
+ }), T.connect(), B.render(d);
1205
+ const _ = t.launcher ? me(t) : null, W = { close: () => {
1206
+ s = !0, clearTimeout(i), T.close(), k == null || k.remove(), B.destroy(), ae.destroy(), l && E && l.removeEventListener("change", E), m && (document.removeEventListener("keydown", m), m = null), O.delete(t.el), _ && X.get(_) === W && X.delete(_);
1216
1207
  } };
1217
- return H.set(t.el, W), _ && X.set(_, W), W;
1208
+ return O.set(t.el, W), _ && X.set(_, W), W;
1218
1209
  }
1219
1210
  export {
1220
1211
  Me as ChatStore,
1221
1212
  Re as ConnectionManager,
1222
1213
  qe as E2ESession,
1223
- Be as PersistentOutbox,
1224
- Ye as Renderer,
1225
- at as asConversationId,
1226
- Oe as extractX3DHInit,
1214
+ $e as PersistentOutbox,
1215
+ Ke as Renderer,
1216
+ rt as asConversationId,
1217
+ Ne as extractX3DHInit,
1227
1218
  st as httpBaseFromWsUrl,
1228
1219
  ot as mount,
1229
1220
  Ae as resolveRelayUrls,
1230
- $e as restoreHistory,
1221
+ Be as restoreHistory,
1231
1222
  tt as unmount
1232
1223
  };
1233
1224
  //# sourceMappingURL=index.js.map