@paramms/chat-widget 1.0.36 → 1.0.38

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,16 +1,16 @@
1
- var pe = Object.defineProperty;
2
- var he = (o, e, i) => e in o ? pe(o, e, { enumerable: !0, configurable: !0, writable: !0, value: i }) : o[e] = i;
3
- var y = (o, e, i) => he(o, typeof e != "symbol" ? e + "" : e, i);
4
- import { p as fe, r as ue, a as we } from "./uid.js";
5
- import { h as Me } from "./uid.js";
6
- import { P as be, C as xe, b as ge } from "./outbox.js";
7
- import { e as He } from "./outbox.js";
8
- import { E2ESession as me, extractX3DHInit as ye } from "./e2e.js";
9
- const te = "http://www.w3.org/2000/svg", ve = 8e3;
10
- class ke {
1
+ var be = Object.defineProperty;
2
+ var xe = (o, e, i) => e in o ? be(o, e, { enumerable: !0, configurable: !0, writable: !0, value: i }) : o[e] = i;
3
+ var v = (o, e, i) => xe(o, typeof e != "symbol" ? e + "" : e, i);
4
+ import { p as ge, r as me, a as ve } from "./codec.js";
5
+ import { h as We } from "./codec.js";
6
+ import { P as ye, C as ke, b as Ce } from "./outbox.js";
7
+ import { e as Ke } from "./outbox.js";
8
+ import { E2ESession as Te, extractX3DHInit as Ie } from "./e2e.js";
9
+ const ae = "http://www.w3.org/2000/svg", Se = 8e3;
10
+ class ze {
11
11
  constructor() {
12
- y(this, "svg", null);
13
- y(this, "timers", /* @__PURE__ */ new Set());
12
+ v(this, "svg", null);
13
+ v(this, "timers", /* @__PURE__ */ new Set());
14
14
  }
15
15
  /** Feed every server frame; the overlay reacts to annotation frames only. */
16
16
  apply(e) {
@@ -23,7 +23,7 @@ class ke {
23
23
  ensureSvg() {
24
24
  var i;
25
25
  if ((i = this.svg) != null && i.isConnected) return this.svg;
26
- const e = document.createElementNS(te, "svg");
26
+ const e = document.createElementNS(ae, "svg");
27
27
  return e.setAttribute("data-relay-annotations", ""), e.setAttribute("aria-hidden", "true"), e.setAttribute(
28
28
  "style",
29
29
  "position:fixed;inset:0;width:100vw;height:100vh;pointer-events:none;z-index:2147483000;"
@@ -32,15 +32,15 @@ class ke {
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, a = window.innerHeight, c = document.createElementNS(te, "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);
35
+ const i = this.ensureSvg(), s = window.innerWidth, a = window.innerHeight, r = document.createElementNS(ae, "polyline");
36
+ r.setAttribute("points", e.points.map((d) => `${(d.x * s).toFixed(1)},${(d.y * a).toFixed(1)}`).join(" ")), r.setAttribute("fill", "none"), r.setAttribute("stroke", e.color || "#ff3b30"), r.setAttribute("stroke-width", String(e.width || 3)), r.setAttribute("stroke-linecap", "round"), r.setAttribute("stroke-linejoin", "round"), r.setAttribute("data-stroke-id", e.id), i.append(r);
37
37
  const f = setTimeout(() => {
38
- c.style.transition = "opacity 600ms", c.style.opacity = "0";
38
+ r.style.transition = "opacity 600ms", r.style.opacity = "0";
39
39
  const d = setTimeout(() => {
40
- c.remove(), this.timers.delete(d);
40
+ r.remove(), this.timers.delete(d);
41
41
  }, 650);
42
42
  this.timers.add(d), this.timers.delete(f);
43
- }, ve);
43
+ }, Se);
44
44
  this.timers.add(f);
45
45
  }
46
46
  clear() {
@@ -53,19 +53,29 @@ class ke {
53
53
  this.timers.clear(), (e = this.svg) == null || e.remove(), this.svg = null;
54
54
  }
55
55
  }
56
- const oe = "objectchat-widget-styles", Ce = ["👍", "❤️", "😂", "😮", "😢", "🙏"], Te = `
56
+ const re = "objectchat-widget-styles", Ee = ["👍", "❤️", "😂", "😮", "😢", "🙏"], Pe = 400, Le = '<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>', je = `
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);
60
60
  font-family:-apple-system,BlinkMacSystemFont,'Segoe UI',system-ui,sans-serif; color:var(--ocw-ink); overflow:hidden; }
61
- @media (max-width:480px) {
62
- .ocw { min-height:100dvh; border-radius:0 !important; }
63
- .ocw-bubble { font-size:15px; }
64
- .ocw-input textarea { font-size:16px; } /* prevent iOS zoom on focus */
65
- .ocw-chip { padding:9px 14px; font-size:14px; }
66
- .ocw-modal-card { width:90%; }
67
- .ocw-row { max-width:94%; }
68
- }
61
+ /* ── Responsive sizing ──────────────────────────────────────────────────────
62
+ * Sizing is driven by the WIDGET'S OWN width (ResizeObserver toggles
63
+ * .ocw-compact below 400px), not the viewport — so a widget embedded in a
64
+ * narrow desktop sidebar sizes the same as one on a phone, and a tablet in
65
+ * landscape keeps comfortable desktop sizing. A viewport query alone can't
66
+ * see the container. Fullscreen (launcher on mobile) additionally gets
67
+ * .ocw-fs from the launcher, which is the only case that should remove the
68
+ * corner radius — an INLINE embed on a phone must NOT take over the page
69
+ * (the old blanket min-height:100dvh rule did exactly that). */
70
+ .ocw.ocw-fs { border-radius:0 !important; }
71
+ .ocw-compact .ocw-bubble { font-size:15px; }
72
+ .ocw-compact.ocw .ocw-input textarea { font-size:16px; } /* ≥16px prevents iOS zoom on focus */
73
+ .ocw-compact .ocw-chip { padding:9px 14px; font-size:14px; }
74
+ .ocw-compact .ocw-modal-card { width:90%; }
75
+ .ocw-compact .ocw-row { max-width:94%; }
76
+ .ocw-compact .ocw-sendbtn { min-width:44px; height:44px; }
77
+ .ocw-compact .ocw-back { width:34px; height:34px; }
78
+ .ocw-compact .ocw-quick button { padding:9px 15px; font-size:14px; }
69
79
  /* RTL support: when the host element has dir=rtl, flip layout direction */
70
80
  [dir="rtl"] .ocw-row.mine { flex-direction:row; }
71
81
  [dir="rtl"] .ocw-row.theirs { flex-direction:row-reverse; }
@@ -114,7 +124,6 @@ const oe = "objectchat-widget-styles", Ce = ["👍", "❤️", "😂", "😮", "
114
124
  .ocw-react-pill { display:inline-flex; align-items:center; gap:3px; border:1px solid #e3ded7; border-radius:999px; padding:2px 7px; background:#fff; font-size:12px; cursor:pointer; }
115
125
  .ocw-react-pill:hover { border-color:var(--ocw-accent); }
116
126
  .ocw-react-pill.mine { border-color:var(--ocw-accent); background:#fff8f5; }
117
- .ocw-react-add { display:none; position:absolute; bottom:100%; left:0; margin-bottom:4px; background:#fff; border:1px solid #e3ded7; border-radius:14px; padding:6px 8px; box-shadow:0 4px 16px rgba(0,0,0,.12); display:flex; gap:4px; z-index:10; }
118
127
  .ocw-react-wrap { position:relative; }
119
128
  .ocw-react-wrap:not(:hover) .ocw-react-picker { display:none; }
120
129
  .ocw-react-picker { position:absolute; bottom:calc(100% + 4px); left:0; background:#fff; border:1px solid #e3ded7; border-radius:14px; padding:6px 8px; box-shadow:0 4px 16px rgba(0,0,0,.12); display:flex; gap:4px; z-index:10; white-space:nowrap; }
@@ -203,10 +212,19 @@ const oe = "objectchat-widget-styles", Ce = ["👍", "❤️", "😂", "😮", "
203
212
  .ocw-footer a:hover { color:var(--ocw-accent); }
204
213
  .ocw-attach { background:none;border:none;cursor:pointer;font-size:18px;padding:4px 6px;opacity:.6;flex-none; }
205
214
  .ocw-attach:hover { opacity:1; }
206
- .ocw-input textarea { flex:1; resize:none; border:1px solid #e3ded7; border-radius:22px; padding:11px 16px; font:inherit; font-size:14px; background:#fff; outline:none; max-height:96px; }
215
+ .ocw-input textarea { flex:1; min-width:0; resize:none; border:1px solid #e3ded7; border-radius:22px; padding:11px 16px; font:inherit; font-size:14px; line-height:1.4; background:#fff; outline:none; max-height:120px; overflow-y:auto; }
207
216
  .ocw-input textarea:focus { border-color:var(--ocw-accent); }
208
- .ocw-sendbtn { width:42px; height:42px; border-radius:50%; border:none; background:var(--ocw-accent); color:#fff; font-size:18px; cursor:pointer; flex:none; display:flex; align-items:center; justify-content:center; }
217
+ /* Send button auto-sizes to its label: the default is a fixed circle around an
218
+ * inline SVG; a TEXT label (i18n.send: "Send", "보내기", "Enviar"…) switches to
219
+ * .ocw-sendbtn-label — a pill whose width follows the text. A fixed 42px
220
+ * circle with 18px type overflowed the moment anyone localized the label. */
221
+ .ocw-sendbtn { min-width:42px; height:42px; border-radius:999px; border:none; background:var(--ocw-accent); color:#fff; font:inherit; font-size:14px; font-weight:600; cursor:pointer; flex:none; display:flex; align-items:center; justify-content:center; padding:0; transition:opacity .15s, transform .1s; }
222
+ .ocw-sendbtn-label { padding:0 16px; white-space:nowrap; }
223
+ .ocw-sendbtn svg { width:19px; height:19px; display:block; }
224
+ .ocw-sendbtn:not(:disabled):hover { transform:scale(1.05); }
225
+ .ocw-sendbtn:not(:disabled):active { transform:scale(.96); }
209
226
  .ocw-sendbtn:disabled { opacity:.5; cursor:default; }
227
+ .ocw-sendbtn:focus-visible, .ocw-back:focus-visible, .ocw-chip:focus-visible { outline:2px solid var(--ocw-accent); outline-offset:2px; }
210
228
  .ocw-cobrowse-btn { display:none; }
211
229
  .ocw-cobrowse-btn.show { display:inline-flex; }
212
230
  .ocw-cobrowse-btn.on { color:var(--ocw-accent); border-color:var(--ocw-accent); }
@@ -226,23 +244,23 @@ const oe = "objectchat-widget-styles", Ce = ["👍", "❤️", "😂", "😮", "
226
244
  .ocw-bubble-wrap:hover .ocw-translate-btn { opacity:1; }
227
245
  .ocw-translated-tag { font-size:10px; color:var(--ocw-mut); margin-top:2px; }
228
246
  `;
229
- function Ie() {
230
- if (typeof document > "u" || document.getElementById(oe)) return;
247
+ function Ae() {
248
+ if (typeof document > "u" || document.getElementById(re)) return;
231
249
  const o = document.createElement("style");
232
- o.id = oe, o.textContent = Te, document.head.appendChild(o);
250
+ o.id = re, o.textContent = je, document.head.appendChild(o);
233
251
  }
234
252
  function t(o, e, i) {
235
253
  const s = document.createElement(o);
236
254
  return e && (s.className = e), i !== void 0 && (s.textContent = i), s;
237
255
  }
238
- function Se(o) {
256
+ function $e(o) {
239
257
  try {
240
258
  return new Date(o).toLocaleTimeString([], { hour: "2-digit", minute: "2-digit" });
241
259
  } catch {
242
260
  return "";
243
261
  }
244
262
  }
245
- function W(o) {
263
+ function X(o) {
246
264
  var e;
247
265
  switch (o.kind) {
248
266
  case "text":
@@ -259,61 +277,66 @@ function W(o) {
259
277
  return `📅 ${o.title} — ${new Date(o.startIso).toLocaleString()}`;
260
278
  }
261
279
  }
262
- class Ee {
280
+ class Be {
263
281
  /** Last seq the guest has seen per conversationId — used to compute unread badges. */
264
282
  constructor(e, i, s, a = {}) {
265
- y(this, "scroll");
266
- y(this, "chips");
267
- y(this, "typing");
268
- y(this, "quick");
269
- y(this, "formHost");
270
- y(this, "csatPanel");
271
- y(this, "offlinePanel");
272
- y(this, "preChatPanel");
273
- y(this, "deflectPanel");
274
- y(this, "preChatBuilt", !1);
275
- y(this, "preChatDone", !1);
276
- y(this, "footer");
277
- y(this, "input");
278
- y(this, "subjectCard");
279
- y(this, "e2eBadge");
280
- y(this, "statusBadge");
281
- y(this, "headerName");
282
- y(this, "connStatus");
283
- y(this, "typingTimer", null);
284
- y(this, "csatSubmitted", !1);
283
+ v(this, "scroll");
284
+ v(this, "chips");
285
+ v(this, "typing");
286
+ v(this, "quick");
287
+ v(this, "formHost");
288
+ v(this, "csatPanel");
289
+ v(this, "offlinePanel");
290
+ v(this, "preChatPanel");
291
+ v(this, "deflectPanel");
292
+ v(this, "preChatBuilt", !1);
293
+ v(this, "preChatDone", !1);
294
+ v(this, "footer");
295
+ v(this, "input");
296
+ v(this, "subjectCard");
297
+ v(this, "e2eBadge");
298
+ v(this, "statusBadge");
299
+ v(this, "headerName");
300
+ v(this, "connStatus");
301
+ v(this, "typingTimer", null);
302
+ v(this, "csatSubmitted", !1);
303
+ v(this, "sendBtn");
304
+ /** Container-driven responsive sizing — toggles .ocw-compact (see CSS note). */
305
+ v(this, "compactObserver", null);
285
306
  // ── Co-browsing (shared whiteboard) ─────────────────────────────────────
286
- y(this, "cobrowseBtn");
287
- y(this, "cobrowseCanvas");
288
- y(this, "cobrowseToolbar");
289
- y(this, "cobrowseHint");
290
- y(this, "cobrowseActive", !1);
291
- y(this, "cobrowseColor", "#f5713c");
292
- y(this, "lastAnnotationVersion", -1);
293
- y(this, "storeRef", null);
294
- y(this, "scrollCleanup", null);
307
+ v(this, "cobrowseBtn");
308
+ v(this, "cobrowseCanvas");
309
+ v(this, "cobrowseToolbar");
310
+ v(this, "cobrowseHint");
311
+ v(this, "cobrowseActive", !1);
312
+ v(this, "cobrowseColor", "#f5713c");
313
+ v(this, "lastAnnotationVersion", -1);
314
+ v(this, "storeRef", null);
315
+ v(this, "scrollCleanup", null);
295
316
  // ── Live translation ──────────────────────────────────────────────────-
296
- y(this, "translationCache", /* @__PURE__ */ new Map());
297
- y(this, "showingTranslation", /* @__PURE__ */ new Set());
298
- y(this, "subjectBuilt", !1);
299
- var m, h, I, T, $, A, P, z, k;
300
- this.root = e, this.me = i, this.h = s, this.cfg = a, Ie(), e.replaceChildren(), e.classList.add("ocw"), a.accent && e.style.setProperty("--ocw-accent", a.accent);
301
- const c = t("div", "ocw-head");
317
+ v(this, "translationCache", /* @__PURE__ */ new Map());
318
+ v(this, "showingTranslation", /* @__PURE__ */ new Set());
319
+ /** Whether the subject card (server Subject entity, mount config fallback)
320
+ * has been built built once when data first arrives. */
321
+ v(this, "subjectBuilt", !1);
322
+ var k, E, I, A, $, z, q, C, j, D;
323
+ this.root = e, this.me = i, this.h = s, this.cfg = a, Ae(), e.replaceChildren(), e.classList.add("ocw"), a.accent && e.style.setProperty("--ocw-accent", a.accent);
324
+ const r = t("div", "ocw-head");
302
325
  if (this.h.onBack) {
303
326
  const x = t("button", "ocw-back", "‹");
304
- x.type = "button", x.setAttribute("aria-label", "Back"), x.addEventListener("click", () => this.h.onBack()), c.append(x);
327
+ x.type = "button", x.setAttribute("aria-label", "Back"), x.addEventListener("click", () => this.h.onBack()), r.append(x);
305
328
  }
306
329
  const f = t("div", "ocw-avatar");
307
- if ((m = a.userInfo) != null && m.avatar) {
330
+ if ((k = a.userInfo) != null && k.avatar) {
308
331
  const x = document.createElement("img");
309
332
  x.src = a.userInfo.avatar, x.alt = a.userInfo.name ?? "You", x.style.cssText = "width:100%;height:100%;border-radius:50%;object-fit:cover", f.append(x);
310
333
  } else
311
- f.textContent = (h = a.userInfo) != null && h.name ? a.userInfo.name[0].toUpperCase() : "🧑";
312
- c.append(f);
334
+ f.textContent = (E = a.userInfo) != null && E.name ? a.userInfo.name[0].toUpperCase() : "🧑";
335
+ r.append(f);
313
336
  const b = t("div", "ocw-head-main");
314
- this.headerName = t("div", "ocw-head-name", ((I = a.subject) == null ? void 0 : I.ownerLabel) ?? ((T = a.subject) == null ? void 0 : T.title) ?? ""), b.append(this.headerName), ($ = a.subject) != null && $.subtitle && b.append(t("div", "ocw-head-meta", a.subject.subtitle)), c.append(b), this.statusBadge = t("span", "ocw-badge", ((A = a.subject) == null ? void 0 : A.status) ?? ""), (P = a.subject) != null && P.status || (this.statusBadge.style.display = "none"), c.append(this.statusBadge), this.e2eBadge = t("span", "ocw-e2e", "🔒 E2E"), this.e2eBadge.style.display = "none", c.append(this.e2eBadge), this.connStatus = t("span", "ocw-conn-status"), this.connStatus.style.display = "none", c.append(this.connStatus), this.cobrowseBtn = t("button", "ocw-menu ocw-cobrowse-btn", "🖍"), this.cobrowseBtn.title = "Shared whiteboard — draw to point things out together", this.cobrowseBtn.addEventListener("click", () => {
337
+ this.headerName = t("div", "ocw-head-name", ((I = a.subject) == null ? void 0 : I.ownerLabel) ?? ((A = a.subject) == null ? void 0 : A.title) ?? ""), b.append(this.headerName), ($ = a.subject) != null && $.subtitle && b.append(t("div", "ocw-head-meta", a.subject.subtitle)), r.append(b), this.statusBadge = t("span", "ocw-badge", ((z = a.subject) == null ? void 0 : z.status) ?? ""), (q = a.subject) != null && q.status || (this.statusBadge.style.display = "none"), r.append(this.statusBadge), this.e2eBadge = t("span", "ocw-e2e", "🔒 E2E"), this.e2eBadge.style.display = "none", r.append(this.e2eBadge), this.connStatus = t("span", "ocw-conn-status"), this.connStatus.style.display = "none", r.append(this.connStatus), this.cobrowseBtn = t("button", "ocw-menu ocw-cobrowse-btn", "🖍"), this.cobrowseBtn.title = "Shared whiteboard — draw to point things out together", this.cobrowseBtn.addEventListener("click", () => {
315
338
  this.cobrowseActive = !this.cobrowseActive, this.updateCobrowseUI();
316
- }), c.append(this.cobrowseBtn), c.append(t("button", "ocw-menu", "⋯")), this.chips = t("div", "ocw-chiprow"), this.scroll = t("div", "ocw-scroll"), this.subjectCard = t("div", "ocw-subject"), this.typing = t("div", "ocw-typing");
339
+ }), r.append(this.cobrowseBtn), r.append(t("button", "ocw-menu", "⋯")), this.chips = t("div", "ocw-chiprow"), this.scroll = t("div", "ocw-scroll"), this.subjectCard = t("div", "ocw-subject"), this.typing = t("div", "ocw-typing");
317
340
  const d = t("div", "ocw-typing-bubble");
318
341
  d.append(t("div", "ocw-typing-dot"), t("div", "ocw-typing-dot"), t("div", "ocw-typing-dot")), this.typing.append(t("div", "ocw-dot", "🧑"), d), this.quick = t("div", "ocw-quick");
319
342
  for (const x of a.quickReplies ?? []) {
@@ -322,38 +345,48 @@ class Ee {
322
345
  this.h.onSend(x), this.quick.style.display = "none";
323
346
  }), this.quick.append(S);
324
347
  }
325
- this.formHost = t("div", "ocw-form-host"), this.csatPanel = t("div", "ocw-csat"), this.csatPanel.style.display = "none", this.offlinePanel = t("div", "ocw-offline"), this.offlinePanel.style.display = "none", this.preChatPanel = t("div", "ocw-prechat"), this.preChatPanel.style.display = "none", this.deflectPanel = t("div", "ocw-deflect"), this.deflectPanel.style.display = "none", this.input = t("textarea", void 0), this.input.rows = 1, this.input.placeholder = "Message…";
326
- const w = t("button", "ocw-sendbtn", ((z = a.i18n) == null ? void 0 : z.send) ?? "➤");
327
- w.addEventListener("click", () => this.flushSend()), this.input.addEventListener("input", () => {
348
+ this.formHost = t("div", "ocw-form-host"), this.csatPanel = t("div", "ocw-csat"), this.csatPanel.style.display = "none", this.offlinePanel = t("div", "ocw-offline"), this.offlinePanel.style.display = "none", this.preChatPanel = t("div", "ocw-prechat"), this.preChatPanel.style.display = "none", this.deflectPanel = t("div", "ocw-deflect"), this.deflectPanel.style.display = "none", this.input = t("textarea", void 0), this.input.rows = 1, this.input.placeholder = ((C = a.i18n) == null ? void 0 : C.placeholder) ?? "Message…";
349
+ const h = t("button", "ocw-sendbtn");
350
+ h.type = "button";
351
+ const y = (j = a.i18n) == null ? void 0 : j.send;
352
+ y ? (h.textContent = y, h.classList.add("ocw-sendbtn-label"), h.setAttribute("aria-label", y)) : (h.innerHTML = Le, h.setAttribute("aria-label", "Send message")), h.disabled = !0, this.sendBtn = h, h.addEventListener("click", () => this.flushSend()), this.input.addEventListener("input", () => {
328
353
  var x, S;
329
- this.storeRef && !this.storeRef.messages().some((B) => B.senderRole === "guest") ? (S = (x = this.h).onDeflectQuery) == null || S.call(x, this.input.value) : this.hideDeflection();
354
+ this.sendBtn.disabled = this.input.value.trim().length === 0, this.autoGrowInput(), this.storeRef && !this.storeRef.messages().some((M) => M.senderRole === "guest") ? (S = (x = this.h).onDeflectQuery) == null || S.call(x, this.input.value) : this.hideDeflection();
330
355
  }), this.input.addEventListener("keydown", (x) => {
331
356
  x.isComposing || x.keyCode === 229 || (x.key === "Enter" && !x.shiftKey ? (x.preventDefault(), this.flushSend()) : this.signalTyping());
332
357
  });
333
- const v = t("button", "ocw-attach", "📎");
334
- v.title = "Attach image or file";
335
- const r = document.createElement("input");
336
- r.type = "file", r.accept = "image/*,.pdf,.txt,.doc,.docx", r.style.display = "none", v.addEventListener("click", () => r.click()), r.addEventListener("change", () => {
358
+ const c = t("button", "ocw-attach", "📎");
359
+ c.title = "Attach image or file";
360
+ 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", () => {
337
362
  var x;
338
- (x = r.files) != null && x[0] && this.h.onAttach && this.h.onAttach(r.files[0]), r.value = "";
363
+ (x = u.files) != null && x[0] && this.h.onAttach && this.h.onAttach(u.files[0]), u.value = "";
339
364
  });
340
- const u = t("div", "ocw-input");
341
- u.append(v, r, this.input, w);
342
- const l = t("div", "ocw-footer");
343
- ((k = a.i18n) == null ? void 0 : k.poweredBy) !== void 0 ? l.textContent = a.i18n.poweredBy : l.innerHTML = 'Powered by <a href="https://relay.paramms.com" target="_blank" rel="noopener">Relay</a>', this.footer = l, e.append(c, this.chips, this.scroll, this.typing, this.quick, this.formHost, this.csatPanel, this.offlinePanel, this.preChatPanel, this.deflectPanel, u, this.footer), this.cobrowseCanvas = t("canvas", "ocw-cobrowse-canvas"), this.cobrowseToolbar = t("div", "ocw-cobrowse-toolbar");
365
+ const l = t("div", "ocw-input");
366
+ l.append(c, u, this.input, h);
367
+ const T = t("div", "ocw-footer");
368
+ ((D = a.i18n) == null ? void 0 : D.poweredBy) !== void 0 ? T.textContent = a.i18n.poweredBy : T.innerHTML = 'Powered by <a href="https://relay.paramms.com" target="_blank" rel="noopener">Relay</a>', this.footer = T, e.append(r, this.chips, this.scroll, this.typing, this.quick, this.formHost, this.csatPanel, this.offlinePanel, this.preChatPanel, this.deflectPanel, l, this.footer), this.cobrowseCanvas = t("canvas", "ocw-cobrowse-canvas"), this.cobrowseToolbar = t("div", "ocw-cobrowse-toolbar");
344
369
  for (const x of ["#f5713c", "#1c1b1a", "#2563eb", "#16a34a", "#dc2626"]) {
345
370
  const S = t("button", "ocw-cobrowse-swatch");
346
371
  S.style.background = x, S.type = "button", x === this.cobrowseColor && S.classList.add("sel"), S.addEventListener("click", () => {
347
372
  this.cobrowseColor = x;
348
- for (const B of this.cobrowseToolbar.querySelectorAll(".ocw-cobrowse-swatch")) B.classList.remove("sel");
373
+ for (const M of this.cobrowseToolbar.querySelectorAll(".ocw-cobrowse-swatch")) M.classList.remove("sel");
349
374
  S.classList.add("sel");
350
375
  }), this.cobrowseToolbar.append(S);
351
376
  }
352
- const C = t("button", "ocw-cobrowse-clear", "Clear");
353
- C.addEventListener("click", () => {
377
+ const m = t("button", "ocw-cobrowse-clear", "Clear");
378
+ m.addEventListener("click", () => {
354
379
  var x, S;
355
380
  return (S = (x = this.h).onAnnotateClear) == null ? void 0 : S.call(x);
356
- }), this.cobrowseToolbar.append(C), this.cobrowseHint = t("div", "ocw-cobrowse-hint", "🖍 Draw to point things out — visible to both sides"), e.append(this.cobrowseCanvas, this.cobrowseToolbar, this.cobrowseHint), this.bindCobrowsePointerEvents();
381
+ }), this.cobrowseToolbar.append(m), this.cobrowseHint = t("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 = (x) => {
383
+ e.classList.toggle("ocw-compact", x > 0 && x < Pe);
384
+ };
385
+ w(e.clientWidth), typeof ResizeObserver < "u" && (this.compactObserver = new ResizeObserver((x) => {
386
+ var M;
387
+ const S = ((M = x[0]) == null ? void 0 : M.contentRect.width) ?? e.clientWidth;
388
+ w(S);
389
+ }), this.compactObserver.observe(e));
357
390
  }
358
391
  /** Returns the scroll container so history.ts can attach scroll listeners. */
359
392
  getScrollEl() {
@@ -366,50 +399,53 @@ class Ee {
366
399
  }
367
400
  /** Call when the widget is unmounted. Disconnects scroll listeners and clears timers. */
368
401
  destroy() {
369
- var e;
370
- (e = this.scrollCleanup) == null || e.call(this), this.scrollCleanup = null, this.typingTimer && (clearTimeout(this.typingTimer), this.typingTimer = null);
402
+ var e, i;
403
+ (e = this.scrollCleanup) == null || e.call(this), this.scrollCleanup = null, this.typingTimer && (clearTimeout(this.typingTimer), this.typingTimer = null), (i = this.compactObserver) == null || i.disconnect(), this.compactObserver = null;
371
404
  }
372
- /** Render list rows, optionally filtered by search query. */
373
- /** Build a single WhatsApp-style conversation row. */
374
- /** Returns true when the chat screen is visible (not the list). */
375
- /** Navigate to the chat screen (slide list left, slide chat in from right). */
376
- /** Navigate back to the list screen. */
377
405
  flushSend() {
378
406
  this.hideDeflection();
379
407
  const e = this.input.value.trim();
380
- e && (this.input.value = "", this.h.onTyping(!1), this.h.onSend(e));
408
+ e && (this.input.value = "", this.sendBtn.disabled = !0, this.autoGrowInput(), this.h.onTyping(!1), this.h.onSend(e));
409
+ }
410
+ /** Grow the composer with its content (up to the CSS max-height), collapse
411
+ * when cleared. scrollHeight is 0 in non-layout environments (jsdom) —
412
+ * skip there so tests and SSR-ish mounts are unaffected. */
413
+ autoGrowInput() {
414
+ this.input.style.height = "auto";
415
+ const e = this.input.scrollHeight;
416
+ e > 0 ? this.input.style.height = `${Math.min(e, 120)}px` : this.input.style.removeProperty("height");
381
417
  }
382
418
  signalTyping() {
383
419
  const e = this.input.value.trim().slice(0, 100) || void 0;
384
420
  this.h.onTyping(!0, e), this.typingTimer && clearTimeout(this.typingTimer), this.typingTimer = setTimeout(() => this.h.onTyping(!1), 2e3);
385
421
  }
386
422
  render(e) {
387
- var r, u, l, C, m;
423
+ var c, u, l, T, m;
388
424
  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) {
389
- const h = (r = this.cfg.subject) == null ? void 0 : r.ownerLabel;
390
- h && (this.headerName.textContent = h);
425
+ const w = (c = this.cfg.subject) == null ? void 0 : c.ownerLabel;
426
+ w && (this.headerName.textContent = w);
391
427
  }
392
428
  this.quick.style.display = e.messages().length === 0 ? "flex" : "none", this.chips.replaceChildren();
393
429
  const i = e.visibleActions();
394
430
  this.chips.style.display = i.length ? "flex" : "none";
395
- for (const h of i) this.chips.append(this.chipEl(h));
431
+ for (const w of i) this.chips.append(this.chipEl(w));
396
432
  const s = this.scroll.scrollHeight, a = this.scroll.scrollTop;
397
433
  if (this.scroll.replaceChildren(), this.subjectCard.childNodes.length && this.scroll.append(this.subjectCard), e.hasMoreHistory) {
398
- const h = t("div", "ocw-load-more");
399
- h.textContent = "↑ Loading earlier messages…", h.style.pointerEvents = "none", this.scroll.append(h);
434
+ const w = t("div", "ocw-load-more");
435
+ w.textContent = "↑ Loading earlier messages…", w.style.pointerEvents = "none", this.scroll.append(w);
400
436
  }
401
- let c = 0;
402
- for (const h of e.messages())
403
- this.scroll.append(this.messageEl(h, e)), h.senderId !== this.me && h.seq > c && (c = h.seq);
404
- a > 20 ? this.scroll.scrollTop = this.scroll.scrollHeight - s + a : this.scroll.scrollTop = this.scroll.scrollHeight, c > 0 && this.h.onReadUpTo(c);
437
+ let r = 0;
438
+ for (const w of e.messages())
439
+ this.scroll.append(this.messageEl(w, e)), w.senderId !== this.me && w.seq > r && (r = w.seq);
440
+ a > 20 ? this.scroll.scrollTop = this.scroll.scrollHeight - s + a : this.scroll.scrollTop = this.scroll.scrollHeight, r > 0 && this.h.onReadUpTo(r);
405
441
  const f = [...e.typing];
406
442
  this.typing.classList.toggle("active", f.length > 0);
407
443
  const b = this.typing.querySelector(".ocw-typing-bubble");
408
444
  b && b.setAttribute("aria-label", f.length ? "typing" : ""), this.footer.style.display = e.whiteLabel ? "none" : "block";
409
- const d = e.messages().some((h) => h.senderRole === "guest");
410
- !!((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", (C = this.root.querySelector(".ocw-input")) == null || C.style.setProperty("display", "none")) : (this.offlinePanel.style.display = "none", (m = this.root.querySelector(".ocw-input")) == null || m.style.removeProperty("display")));
411
- const v = ["resolved", "closed", "sold", "issued", "checked_out"];
412
- 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");
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", (T = this.root.querySelector(".ocw-input")) == null || T.style.setProperty("display", "none")) : (this.offlinePanel.style.display = "none", (m = this.root.querySelector(".ocw-input")) == null || m.style.removeProperty("display")));
447
+ const y = ["resolved", "closed", "sold", "issued", "checked_out"];
448
+ this.h.onCsat && !this.csatSubmitted && y.includes(e.state) && e.messages().length > 0 && (this.csatPanel.style.display === "none" && this.buildCsatPanel(), this.csatPanel.style.display = "block");
413
449
  }
414
450
  setConnStatus(e, i) {
415
451
  if (e === "open") {
@@ -427,63 +463,63 @@ class Ee {
427
463
  s.placeholder = "Your name", s.type = "text";
428
464
  const a = t("input", "ocw-offline-input");
429
465
  a.placeholder = "Your email", a.type = "email";
430
- const c = t("textarea", "ocw-offline-input");
431
- c.placeholder = "Your message", c.rows = 3;
466
+ const r = t("textarea", "ocw-offline-input");
467
+ r.placeholder = "Your message", r.rows = 3;
432
468
  const f = t("button", "ocw-offline-submit", "Send message");
433
- f.addEventListener("click", () => {
434
- !a.value.trim() || !c.value.trim() || (this.h.onSend(`[Offline form]
469
+ f.type = "button", f.addEventListener("click", () => {
470
+ !a.value.trim() || !r.value.trim() || (f.disabled = !0, this.h.onSend(`[Offline form]
435
471
  Name: ${s.value || "Anonymous"}
436
472
  Email: ${a.value}
437
- Message: ${c.value}`), this.offlinePanel.replaceChildren(t("div", "ocw-offline-thanks", "✓ Message sent! We'll reply to your email.")));
438
- }), i.append(s, a, c, f), this.offlinePanel.append(i);
473
+ Message: ${r.value}`), this.offlinePanel.replaceChildren(t("div", "ocw-offline-thanks", "✓ Message sent! We'll reply to your email.")));
474
+ }), i.append(s, a, r, f), this.offlinePanel.append(i);
439
475
  }
440
476
  buildPreChatPanel(e) {
441
477
  var d;
442
478
  this.preChatBuilt = !0, this.preChatPanel.replaceChildren(), this.preChatPanel.append(t("div", "ocw-prechat-title", e.title ?? "Before we start…"));
443
479
  const i = t("div", "ocw-offline-form"), s = {};
444
- for (const w of e.fields ?? ["name", "email"]) {
445
- const v = t("input", "ocw-offline-input");
446
- v.type = w === "email" ? "email" : w === "phone" ? "tel" : "text", v.placeholder = w === "name" ? "Your name" : w === "email" ? "Your email" : "Your phone number", s[w] = v, i.append(v);
480
+ for (const h of e.fields ?? ["name", "email"]) {
481
+ const y = t("input", "ocw-offline-input");
482
+ y.type = h === "email" ? "email" : h === "phone" ? "tel" : "text", y.placeholder = h === "name" ? "Your name" : h === "email" ? "Your email" : "Your phone number", s[h] = y, i.append(y);
447
483
  }
448
484
  let a = null;
449
485
  if ((d = e.topics) != null && d.length) {
450
486
  a = t("select", void 0);
451
- const w = document.createElement("option");
452
- w.value = "", w.textContent = "What is this about?", a.append(w);
453
- for (const v of e.topics) {
454
- const r = document.createElement("option");
455
- r.value = v, r.textContent = v, a.append(r);
487
+ const h = document.createElement("option");
488
+ h.value = "", h.textContent = "What is this about?", a.append(h);
489
+ for (const y of e.topics) {
490
+ const c = document.createElement("option");
491
+ c.value = y, c.textContent = y, a.append(c);
456
492
  }
457
493
  i.append(a);
458
494
  }
459
- let c = null, f = null;
495
+ let r = null, f = null;
460
496
  if (e.callbackOption) {
461
- const w = t("label", "ocw-prechat-cb");
462
- c = document.createElement("input"), c.type = "checkbox", w.append(c, document.createTextNode("📞 Request a call back")), i.append(w), s.phone || (f = t("input", "ocw-offline-input"), f.type = "tel", f.placeholder = "Phone number for the call", f.style.display = "none", c.addEventListener("change", () => f.style.setProperty("display", c.checked ? "block" : "none")), i.append(f));
497
+ const h = t("label", "ocw-prechat-cb");
498
+ r = document.createElement("input"), r.type = "checkbox", h.append(r, document.createTextNode("📞 Request a call back")), i.append(h), s.phone || (f = t("input", "ocw-offline-input"), f.type = "tel", f.placeholder = "Phone number for the call", f.style.display = "none", r.addEventListener("change", () => f.style.setProperty("display", r.checked ? "block" : "none")), i.append(f));
463
499
  }
464
500
  const b = t("button", "ocw-offline-submit", "Start chat");
465
- b.addEventListener("click", () => {
466
- var u, l, C, m, h, I, T;
467
- const w = (u = s.email) == null ? void 0 : u.value.trim();
468
- if (s.email && (!w || !/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(w))) {
501
+ b.type = "button", b.addEventListener("click", () => {
502
+ var u, l, T, m, w, k, E;
503
+ const h = (u = s.email) == null ? void 0 : u.value.trim();
504
+ if (s.email && (!h || !/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(h))) {
469
505
  s.email.focus();
470
506
  return;
471
507
  }
472
- const v = !!(c != null && c.checked), r = (((l = s.phone) == null ? void 0 : l.value) ?? (f == null ? void 0 : f.value) ?? "").trim();
473
- if (v && !r) {
474
- (C = s.phone ?? f) == null || C.focus();
508
+ const y = !!(r != null && r.checked), c = (((l = s.phone) == null ? void 0 : l.value) ?? (f == null ? void 0 : f.value) ?? "").trim();
509
+ if (y && !c) {
510
+ (T = s.phone ?? f) == null || T.focus();
475
511
  return;
476
512
  }
477
513
  if (a && ((m = e.topics) != null && m.length) && !a.value) {
478
514
  a.focus();
479
515
  return;
480
516
  }
481
- this.completePreChat(), (T = (I = this.h).onPreChat) == null || T.call(I, {
482
- ...(h = s.name) != null && h.value.trim() ? { name: s.name.value.trim() } : {},
483
- ...w ? { email: w } : {},
484
- ...r ? { phone: r } : {},
517
+ b.disabled = !0, this.completePreChat(), (E = (k = this.h).onPreChat) == null || E.call(k, {
518
+ ...(w = s.name) != null && w.value.trim() ? { name: s.name.value.trim() } : {},
519
+ ...h ? { email: h } : {},
520
+ ...c ? { phone: c } : {},
485
521
  ...a != null && a.value ? { topic: a.value } : {},
486
- ...v ? { callback: !0 } : {}
522
+ ...y ? { callback: !0 } : {}
487
523
  });
488
524
  }), i.append(b), this.preChatPanel.append(i);
489
525
  }
@@ -509,15 +545,13 @@ Message: ${c.value}`), this.offlinePanel.replaceChildren(t("div", "ocw-offline-t
509
545
  const e = t("div", "ocw-csat-stars"), i = [];
510
546
  for (let s = 1; s <= 5; s++) {
511
547
  const a = t("button", "ocw-csat-star", "★");
512
- a.dataset.score = String(s), a.addEventListener("mouseenter", () => i.forEach((c, f) => c.classList.toggle("lit", f < s))), a.addEventListener("mouseleave", () => i.forEach((c) => c.classList.remove("lit"))), a.addEventListener("click", () => {
513
- var c, f;
514
- this.csatSubmitted = !0, this.csatPanel.replaceChildren(t("div", "ocw-csat-done", `Thanks for your ${s}★ rating!`)), (f = (c = this.h).onCsat) == null || f.call(c, s);
548
+ a.dataset.score = String(s), a.addEventListener("mouseenter", () => i.forEach((r, f) => r.classList.toggle("lit", f < s))), a.addEventListener("mouseleave", () => i.forEach((r) => r.classList.remove("lit"))), a.addEventListener("click", () => {
549
+ var r, f;
550
+ this.csatSubmitted = !0, this.csatPanel.replaceChildren(t("div", "ocw-csat-done", `Thanks for your ${s}★ rating!`)), (f = (r = this.h).onCsat) == null || f.call(r, s);
515
551
  }), i.push(a), e.append(a);
516
552
  }
517
553
  this.csatPanel.append(e);
518
554
  }
519
- /** Subject card from the server's Subject entity (per chatroom), with the
520
- * mount config as a fallback. Built once when data first arrives. */
521
555
  // ── Co-browsing (shared whiteboard) ──────────────────────────────────────
522
556
  updateCobrowseUI() {
523
557
  this.cobrowseCanvas.classList.toggle("active", this.cobrowseActive), this.cobrowseToolbar.classList.toggle("active", this.cobrowseActive), this.cobrowseHint.classList.toggle("active", this.cobrowseActive), this.cobrowseBtn.classList.toggle("on", this.cobrowseActive), this.cobrowseActive && (this.resizeCobrowseCanvas(), this.redrawCobrowse());
@@ -532,7 +566,7 @@ Message: ${c.value}`), this.offlinePanel.replaceChildren(t("div", "ocw-offline-t
532
566
  if (!i || e.points.length < 2) return;
533
567
  const s = this.cobrowseCanvas.width, a = this.cobrowseCanvas.height;
534
568
  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);
535
- for (const c of e.points.slice(1)) i.lineTo(c.x * s, c.y * a);
569
+ for (const r of e.points.slice(1)) i.lineTo(r.x * s, r.y * a);
536
570
  i.stroke();
537
571
  }
538
572
  redrawCobrowse() {
@@ -546,15 +580,15 @@ Message: ${c.value}`), this.offlinePanel.replaceChildren(t("div", "ocw-offline-t
546
580
  bindCobrowsePointerEvents() {
547
581
  let e = !1, i = [];
548
582
  const s = (f) => {
549
- const b = this.cobrowseCanvas.getBoundingClientRect(), d = b.width > 0 ? (f.clientX - b.left) / b.width : 0, w = b.height > 0 ? (f.clientY - b.top) / b.height : 0;
550
- return { x: Math.min(1, Math.max(0, d)), y: Math.min(1, Math.max(0, w)) };
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;
584
+ return { x: Math.min(1, Math.max(0, d)), y: Math.min(1, Math.max(0, h)) };
551
585
  }, a = 6e-3;
552
586
  this.cobrowseCanvas.addEventListener("pointerdown", (f) => {
553
587
  this.cobrowseActive && (e = !0, i = [s(f)], this.cobrowseCanvas.setPointerCapture(f.pointerId));
554
588
  }), this.cobrowseCanvas.addEventListener("pointermove", (f) => {
555
589
  e && (i.push(s(f)), this.redrawCobrowse(), this.drawStroke({ points: i, color: this.cobrowseColor, width: a }));
556
590
  });
557
- const c = (f) => {
591
+ const r = (f) => {
558
592
  var b, d;
559
593
  if (e) {
560
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: a })), i = [];
@@ -564,17 +598,17 @@ Message: ${c.value}`), this.offlinePanel.replaceChildren(t("div", "ocw-offline-t
564
598
  }
565
599
  }
566
600
  };
567
- this.cobrowseCanvas.addEventListener("pointerup", c), this.cobrowseCanvas.addEventListener("pointercancel", c);
601
+ this.cobrowseCanvas.addEventListener("pointerup", r), this.cobrowseCanvas.addEventListener("pointercancel", r);
568
602
  }
569
603
  buildSubjectCard(e) {
570
604
  if (this.subjectBuilt) return;
571
605
  const i = e.subject, s = this.cfg.subject, a = (i == null ? void 0 : i.title) ?? (s == null ? void 0 : s.title);
572
606
  if (!a) return;
573
607
  this.subjectBuilt = !0, this.subjectCard.replaceChildren(), this.subjectCard.append(t("div", "ocw-subject-title", a)), s != null && s.subtitle && this.subjectCard.append(t("div", "ocw-subject-sub", s.subtitle));
574
- const c = t("div", "ocw-tags");
575
- if (i) for (const [b, d] of Object.entries(i.fields)) c.append(t("span", "ocw-tag", `${b}: ${d}`));
576
- else for (const b of (s == null ? void 0 : s.tags) ?? []) c.append(t("span", "ocw-tag", b));
577
- c.childNodes.length && this.subjectCard.append(c);
608
+ const r = t("div", "ocw-tags");
609
+ if (i) for (const [b, d] of Object.entries(i.fields)) r.append(t("span", "ocw-tag", `${b}: ${d}`));
610
+ else for (const b of (s == null ? void 0 : s.tags) ?? []) r.append(t("span", "ocw-tag", b));
611
+ r.childNodes.length && this.subjectCard.append(r);
578
612
  const f = (i == null ? void 0 : i.state) ?? (s == null ? void 0 : s.status);
579
613
  f && (this.statusBadge.textContent = f, this.statusBadge.style.display = "inline-flex");
580
614
  }
@@ -590,12 +624,12 @@ Message: ${c.value}`), this.offlinePanel.replaceChildren(t("div", "ocw-offline-t
590
624
  return new Promise((i) => {
591
625
  const s = t("div", "ocw-modal"), a = t("div", "ocw-modal-card");
592
626
  a.append(t("div", "ocw-modal-title", e)), a.append(t("div", "ocw-modal-body", `Confirm “${e}”?`));
593
- const c = t("div", "ocw-modal-actions"), f = t("button", "ocw-modal-cancel", "Cancel"), b = t("button", "ocw-modal-ok", "Confirm"), d = (w) => {
594
- s.remove(), i(w);
627
+ const r = t("div", "ocw-modal-actions"), f = t("button", "ocw-modal-cancel", "Cancel"), b = t("button", "ocw-modal-ok", "Confirm"), d = (h) => {
628
+ s.remove(), i(h);
595
629
  };
596
- f.addEventListener("click", () => d(!1)), b.addEventListener("click", () => d(!0)), s.addEventListener("click", (w) => {
597
- w.target === s && d(!1);
598
- }), c.append(f, b), a.append(c), s.append(a), this.root.append(s), b.focus();
630
+ f.addEventListener("click", () => d(!1)), b.addEventListener("click", () => d(!0)), s.addEventListener("click", (h) => {
631
+ h.target === s && d(!1);
632
+ }), r.append(f, b), a.append(r), s.append(a), this.root.append(s), b.focus();
599
633
  });
600
634
  }
601
635
  /** Inline form for a form-effect action: typed inputs (date picker, number,
@@ -606,54 +640,54 @@ Message: ${c.value}`), this.offlinePanel.replaceChildren(t("div", "ocw-offline-t
606
640
  const i = t("div", "ocw-form");
607
641
  i.append(t("div", "ocw-form-title", e.icon ? `${e.icon} ${e.label}` : e.label));
608
642
  const s = /* @__PURE__ */ new Map();
609
- for (const w of e.input ?? []) {
610
- const v = t("label", "ocw-form-row");
611
- if (v.append(t("span", "ocw-form-lbl", w.label)), w.type === "select" && ((b = w.options) != null && b.length)) {
612
- const r = t("select", "ocw-form-input");
613
- w.required || r.append(t("option", void 0, "— select —"));
614
- for (const u of w.options) {
643
+ for (const h of e.input ?? []) {
644
+ const y = t("label", "ocw-form-row");
645
+ if (y.append(t("span", "ocw-form-lbl", h.label)), h.type === "select" && ((b = h.options) != null && b.length)) {
646
+ const c = t("select", "ocw-form-input");
647
+ h.required || c.append(t("option", void 0, "— select —"));
648
+ for (const u of h.options) {
615
649
  const l = t("option");
616
- l.value = u, l.textContent = u, r.append(l);
650
+ l.value = u, l.textContent = u, c.append(l);
617
651
  }
618
- w.required && (r.required = !0), v.append(r), s.set(w.name, r);
652
+ h.required && (c.required = !0), y.append(c), s.set(h.name, c);
619
653
  } else {
620
- const r = t("input", "ocw-form-input");
621
- r.type = w.type === "number" ? "number" : w.type === "date" ? "datetime-local" : "text", w.required && (r.required = !0), v.append(r), s.set(w.name, r);
654
+ const c = t("input", "ocw-form-input");
655
+ c.type = h.type === "number" ? "number" : h.type === "date" ? "datetime-local" : "text", h.required && (c.required = !0), y.append(c), s.set(h.name, c);
622
656
  }
623
- i.append(v);
657
+ i.append(y);
624
658
  }
625
- const a = t("div", "ocw-form-actions"), c = t("button", "ocw-form-cancel", "Cancel"), f = t("button", "ocw-form-submit", "Send");
626
- c.addEventListener("click", () => this.formHost.replaceChildren()), f.addEventListener("click", () => {
627
- const w = {};
628
- for (const [v, r] of s) {
629
- if (r.required && !r.value) {
630
- r.style.borderColor = "#e5484d";
659
+ const a = t("div", "ocw-form-actions"), r = t("button", "ocw-form-cancel", "Cancel"), f = t("button", "ocw-form-submit", "Send");
660
+ r.addEventListener("click", () => this.formHost.replaceChildren()), f.addEventListener("click", () => {
661
+ const h = {};
662
+ for (const [y, c] of s) {
663
+ if (c.required && !c.value) {
664
+ c.style.borderColor = "#e5484d";
631
665
  return;
632
666
  }
633
- w[v] = r.type === "number" ? Number(r.value) : r.value;
667
+ h[y] = c.type === "number" ? Number(c.value) : c.value;
634
668
  }
635
- this.formHost.replaceChildren(), this.h.onInvoke(e.id, w);
636
- }), a.append(c, f), i.append(a), this.formHost.append(i), (d = s.values().next().value) == null || d.focus();
669
+ this.formHost.replaceChildren(), this.h.onInvoke(e.id, h);
670
+ }), a.append(r, f), i.append(a), this.formHost.append(i), (d = s.values().next().value) == null || d.focus();
637
671
  }
638
672
  messageEl(e, i) {
639
- var r;
673
+ var c;
640
674
  if (e.senderRole === "system") {
641
675
  const u = t("div", "ocw-sys");
642
- return u.textContent = e.deletedAt ? "message deleted" : W(e.content), u;
676
+ return u.textContent = e.deletedAt ? "message deleted" : X(e.content), u;
643
677
  }
644
- const s = e.senderId === this.me, a = !!e.internal, c = t("div", `ocw-row ${a ? "ocw-note mine" : s ? "mine" : "theirs"} ${e.senderRole === "bot" ? "ocw-bot" : ""}`);
645
- !s && !a && c.append(t("div", "ocw-dot", e.senderRole === "bot" ? "🤖" : "🧑"));
678
+ const s = e.senderId === this.me, a = !!e.internal, r = t("div", `ocw-row ${a ? "ocw-note mine" : s ? "mine" : "theirs"} ${e.senderRole === "bot" ? "ocw-bot" : ""}`);
679
+ !s && !a && r.append(t("div", "ocw-dot", e.senderRole === "bot" ? "🤖" : "🧑"));
646
680
  const f = t("div"), b = t("div", "ocw-bubble-wrap");
647
681
  if (e.replyToId) {
648
682
  const u = t("div", "ocw-reply-to", "↩ replying to a message");
649
683
  u.style.cssText = "font-size:11px;color:var(--ocw-mut);margin-bottom:2px;font-style:italic", f.append(u);
650
684
  }
651
685
  const d = t("div", "ocw-bubble");
652
- let w = null;
686
+ let h = null;
653
687
  if (e.deletedAt) d.append(t("span", "ocw-deleted", "message deleted"));
654
688
  else if (e.content.kind === "attachment") {
655
689
  const u = e.content;
656
- if ((r = u.mime) != null && r.startsWith("image/")) {
690
+ if ((c = u.mime) != null && c.startsWith("image/")) {
657
691
  const l = document.createElement("img");
658
692
  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);
659
693
  } else {
@@ -663,34 +697,34 @@ Message: ${c.value}`), this.offlinePanel.replaceChildren(t("div", "ocw-offline-t
663
697
  } else if (e.content.kind === "appointment") {
664
698
  const u = e.content, l = t("div", "ocw-appt");
665
699
  l.append(t("div", "ocw-appt-title", `📅 ${u.title}`)), l.append(t("div", "ocw-appt-time", new Date(u.startIso).toLocaleString() + " – " + new Date(u.endIso).toLocaleTimeString())), u.location && l.append(t("div", "ocw-appt-loc", `📍 ${u.location}`)), u.description && l.append(t("div", "ocw-appt-desc", u.description));
666
- const C = t("div", "ocw-appt-links"), m = document.createElement("a");
700
+ const T = t("div", "ocw-appt-links"), m = document.createElement("a");
667
701
  m.href = u.googleUrl, m.target = "_blank", m.rel = "noopener", m.className = "ocw-appt-btn", m.textContent = "📅 Add to Google Calendar";
668
- const h = document.createElement("a");
669
- h.href = u.icalUrl, h.download = `${u.title}.ics`, h.className = "ocw-appt-btn ocw-appt-btn-sec", h.textContent = "🍎 Apple / iCal", C.append(m, h), l.append(C), d.append(l);
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", T.append(m, w), l.append(T), d.append(l);
670
704
  } else
671
- w = document.createTextNode(W(e.content)), d.append(w), e.editedAt && d.append(t("span", "ocw-edited", "(edited)"));
672
- if (b.append(d), !s && !a && this.h.onTranslate && e.content.kind === "text" && !e.deletedAt && e.seq > 0 && w) {
705
+ h = document.createTextNode(X(e.content)), d.append(h), e.editedAt && d.append(t("span", "ocw-edited", "(edited)"));
706
+ if (b.append(d), !s && !a && this.h.onTranslate && e.content.kind === "text" && !e.deletedAt && e.seq > 0 && h) {
673
707
  const u = e.content.text;
674
708
  if (u.trim()) {
675
709
  const l = t("button", "ocw-translate-btn", "🌐");
676
- l.type = "button", l.title = "Translate", l.addEventListener("click", (C) => {
677
- if (C.stopPropagation(), this.showingTranslation.has(e.id)) {
678
- this.showingTranslation.delete(e.id), w.textContent = u, l.textContent = "🌐", l.title = "Translate";
710
+ l.type = "button", l.title = "Translate", l.addEventListener("click", (T) => {
711
+ if (T.stopPropagation(), this.showingTranslation.has(e.id)) {
712
+ this.showingTranslation.delete(e.id), h.textContent = u, l.textContent = "🌐", l.title = "Translate";
679
713
  return;
680
714
  }
681
715
  const m = this.translationCache.get(e.id);
682
716
  if (m !== void 0) {
683
- this.showingTranslation.add(e.id), w.textContent = m, l.textContent = "↩", l.title = "Show original";
717
+ this.showingTranslation.add(e.id), h.textContent = m, l.textContent = "↩", l.title = "Show original";
684
718
  return;
685
719
  }
686
- l.textContent = "⏳", this.h.onTranslate(u).then((h) => {
687
- if (h === null) {
720
+ l.textContent = "⏳", this.h.onTranslate(u).then((w) => {
721
+ if (w === null) {
688
722
  l.textContent = "⚠️", l.title = "Translation unavailable", setTimeout(() => {
689
723
  l.textContent = "🌐", l.title = "Translate";
690
724
  }, 1500);
691
725
  return;
692
726
  }
693
- this.translationCache.set(e.id, h), this.showingTranslation.add(e.id), w.textContent = h, l.textContent = "↩", l.title = "Show original";
727
+ this.translationCache.set(e.id, w), this.showingTranslation.add(e.id), h.textContent = w, l.textContent = "↩", l.title = "Show original";
694
728
  });
695
729
  }), b.append(l);
696
730
  }
@@ -699,31 +733,31 @@ Message: ${c.value}`), this.offlinePanel.replaceChildren(t("div", "ocw-offline-t
699
733
  const u = t("div", "ocw-msg-menu");
700
734
  if (this.h.onEdit) {
701
735
  const l = t("button", void 0, "✏️");
702
- l.title = "Edit", l.addEventListener("click", (C) => {
703
- C.stopPropagation();
704
- const m = W(e.content), h = document.createElement("textarea");
705
- h.value = m, h.rows = Math.min(4, Math.ceil(m.length / 40) + 1), h.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";
706
- const I = t("button", "ocw-form-submit", "Save");
707
- I.style.cssText = "margin-top:6px;padding:5px 14px;font-size:13px";
708
- const T = t("button", "ocw-form-cancel", "Cancel");
709
- T.style.cssText = "margin-top:6px;padding:5px 10px;font-size:13px";
710
- const $ = t("div");
711
- $.style.cssText = "display:flex;gap:6px;justify-content:flex-end", $.append(T, I);
736
+ l.title = "Edit", l.addEventListener("click", (T) => {
737
+ T.stopPropagation();
738
+ const m = X(e.content), w = document.createElement("textarea");
739
+ w.value = m, w.rows = Math.min(4, Math.ceil(m.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";
740
+ const k = t("button", "ocw-form-submit", "Save");
741
+ k.style.cssText = "margin-top:6px;padding:5px 14px;font-size:13px";
742
+ const E = t("button", "ocw-form-cancel", "Cancel");
743
+ E.style.cssText = "margin-top:6px;padding:5px 10px;font-size:13px";
744
+ const I = t("div");
745
+ I.style.cssText = "display:flex;gap:6px;justify-content:flex-end", I.append(E, k);
712
746
  const A = t("div");
713
- A.append(h, $), d.replaceChildren(A), h.focus(), h.select();
714
- const P = () => d.replaceChildren(w ?? document.createTextNode(m));
715
- T.addEventListener("click", P), I.addEventListener("click", () => {
716
- const z = h.value.trim();
717
- z && z !== m && this.h.onEdit(e.id, z), P();
718
- }), h.addEventListener("keydown", (z) => {
719
- z.key === "Enter" && !z.shiftKey && (z.preventDefault(), I.click()), z.key === "Escape" && P();
747
+ A.append(w, I), d.replaceChildren(A), w.focus(), w.select();
748
+ const $ = () => d.replaceChildren(h ?? document.createTextNode(m));
749
+ E.addEventListener("click", $), k.addEventListener("click", () => {
750
+ const z = w.value.trim();
751
+ z && z !== m && this.h.onEdit(e.id, z), $();
752
+ }), w.addEventListener("keydown", (z) => {
753
+ z.key === "Enter" && !z.shiftKey && (z.preventDefault(), k.click()), z.key === "Escape" && $();
720
754
  });
721
755
  }), u.append(l);
722
756
  }
723
757
  if (this.h.onDelete) {
724
758
  const l = t("button", "del", "🗑");
725
- l.title = "Delete", l.addEventListener("click", (C) => {
726
- C.stopPropagation(), this.h.onDelete(e.id);
759
+ l.title = "Delete", l.addEventListener("click", (T) => {
760
+ T.stopPropagation(), this.h.onDelete(e.id);
727
761
  }), u.append(l);
728
762
  }
729
763
  b.append(u);
@@ -731,38 +765,40 @@ Message: ${c.value}`), this.offlinePanel.replaceChildren(t("div", "ocw-offline-t
731
765
  if (f.append(b), this.h.onReact && !e.deletedAt && e.seq > 0) {
732
766
  const u = t("div", "ocw-react-wrap"), l = t("div", "ocw-react");
733
767
  if (e.reactions && Object.keys(e.reactions).length)
734
- for (const [h, I] of Object.entries(e.reactions)) {
735
- const T = t("button", `ocw-react-pill${I.includes(this.me) ? " mine" : ""}`, `${h} ${I.length}`);
736
- T.addEventListener("click", () => {
737
- var $, A;
738
- return (A = ($ = this.h).onReact) == null ? void 0 : A.call($, e.id, h, I.includes(this.me));
739
- }), l.append(T);
768
+ for (const [w, k] of Object.entries(e.reactions)) {
769
+ const E = t("button", `ocw-react-pill${k.includes(this.me) ? " mine" : ""}`, `${w} ${k.length}`);
770
+ E.addEventListener("click", () => {
771
+ var I, A;
772
+ return (A = (I = this.h).onReact) == null ? void 0 : A.call(I, e.id, w, k.includes(this.me));
773
+ }), l.append(E);
740
774
  }
741
- const C = t("button", "ocw-react-btn", "+"), m = t("div", "ocw-react-picker");
742
- for (const h of Ce) {
743
- const I = t("button", void 0, h);
744
- I.addEventListener("click", (T) => {
745
- var A, P, z, k;
746
- T.stopPropagation();
747
- const $ = (P = (A = e.reactions) == null ? void 0 : A[h]) == null ? void 0 : P.includes(this.me);
748
- (k = (z = this.h).onReact) == null || k.call(z, e.id, h, !!$), m.style.display = "none";
749
- }), m.append(I);
775
+ const T = t("button", "ocw-react-btn", "+"), m = t("div", "ocw-react-picker");
776
+ for (const w of Ee) {
777
+ const k = t("button", void 0, w);
778
+ k.addEventListener("click", (E) => {
779
+ var A, $, z, q;
780
+ E.stopPropagation();
781
+ const I = ($ = (A = e.reactions) == null ? void 0 : A[w]) == null ? void 0 : $.includes(this.me);
782
+ (q = (z = this.h).onReact) == null || q.call(z, e.id, w, !!I), m.style.display = "none";
783
+ }), m.append(k);
750
784
  }
751
- m.style.display = "none", C.addEventListener("click", (h) => {
752
- h.stopPropagation(), m.style.display = m.style.display === "none" ? "flex" : "none";
753
- }), document.addEventListener("click", () => {
754
- m.style.display = "none";
755
- }, { once: !0 }), l.append(C), u.append(l, m), f.append(u);
785
+ m.style.display = "none", T.addEventListener("click", (w) => {
786
+ w.stopPropagation();
787
+ const k = m.style.display === "none";
788
+ m.style.display = k ? "flex" : "none", k && document.addEventListener("click", () => {
789
+ m.style.display = "none";
790
+ }, { once: !0 });
791
+ }), l.append(T), u.append(l, m), f.append(u);
756
792
  } else e.reactions && Object.keys(e.reactions).length && f.append(t("div", "ocw-react", Object.entries(e.reactions).map(([u, l]) => `${u}${l.length}`).join(" ")));
757
- const v = t("div", "ocw-time ocw-meta", Se(e.ts));
793
+ const y = t("div", "ocw-time ocw-meta", $e(e.ts));
758
794
  if (s && e.status) {
759
- const u = t("span", `ocw-tick${e.status === "read" ? " read" : e.status === "delivered" ? " delivered" : ""}`, ze(e.status));
760
- v.append(u);
795
+ const u = t("span", `ocw-tick${e.status === "read" ? " read" : e.status === "delivered" ? " delivered" : ""}`, Me(e.status));
796
+ y.append(u);
761
797
  }
762
- return s && e.seq > 0 && i.lastReadByOthers >= e.seq && v.append(t("span", "ocw-seen", " · Seen")), f.append(v), c.append(f), c;
798
+ return s && e.seq > 0 && i.lastReadByOthers >= e.seq && y.append(t("span", "ocw-seen", " · Seen")), f.append(y), r.append(f), r;
763
799
  }
764
800
  }
765
- function ze(o) {
801
+ function Me(o) {
766
802
  switch (o) {
767
803
  case "read":
768
804
  return "✓✓";
@@ -774,35 +810,44 @@ function ze(o) {
774
810
  return "🕓";
775
811
  }
776
812
  }
777
- const R = /* @__PURE__ */ new WeakMap(), U = /* @__PURE__ */ new Map();
778
- function ne(o) {
813
+ const O = /* @__PURE__ */ new WeakMap(), W = /* @__PURE__ */ new Map();
814
+ function ce(o) {
779
815
  return `relay-launcher::${o.profileId}::${o.subjectId ?? ""}`;
780
816
  }
781
- function Ae(o) {
817
+ let N = null;
818
+ function Re() {
819
+ if (N && N.state !== "closed") return N;
820
+ try {
821
+ return N = new AudioContext(), N;
822
+ } catch {
823
+ return null;
824
+ }
825
+ }
826
+ function Ne(o) {
782
827
  var e;
783
- (e = R.get(o)) == null || e.close(), R.delete(o);
828
+ (e = O.get(o)) == null || e.close(), O.delete(o);
784
829
  }
785
- function Be(o) {
786
- var J, Q, G, Z, ee;
787
- R.has(o.el) && (R.get(o.el).close(), R.delete(o.el)), o.launcher && ((J = U.get(ne(o))) == null || J.close());
788
- const e = fe();
830
+ function _e(o) {
831
+ var ee, te, oe, ne, ie;
832
+ O.has(o.el) && (O.get(o.el).close(), O.delete(o.el)), o.launcher && ((ee = W.get(ce(o))) == null || ee.close());
833
+ const e = ge();
789
834
  let i, s = !1;
790
- const a = o.token ?? o.userId ?? e, c = a !== e ? e : void 0, { wsUrl: f, httpBase: b } = ue(o.url, o.apiUrl);
791
- let d = new xe(a);
792
- const w = o.subjectId ? `${a}::${o.subjectId}` : a, v = new be(w);
793
- let r, u = !1, l = null, C = null;
835
+ const a = o.token ?? o.userId ?? e, r = a !== e ? e : void 0, { wsUrl: f, httpBase: b } = me(o.url, o.apiUrl);
836
+ let d = new ke(a);
837
+ const h = o.subjectId ? `${a}::${o.subjectId}` : a, y = new ye(h);
838
+ let c, u = !1, l = null, T = null, m = null;
794
839
  !o.launcher && !o.el.style.height && o.el.clientHeight === 0 && (o.el.style.width = o.el.style.width || "100%", o.el.style.height = "600px");
795
- for (const n of v.load()) d.addOptimistic(n.clientMsgId, n.content);
796
- let m = null, h = null, I = 0, T = !o.launcher;
840
+ for (const n of y.load()) d.addOptimistic(n.clientMsgId, n.content);
841
+ let w = null, k = null, E = 0, I = !o.launcher;
797
842
  if (o.launcher) {
798
843
  const p = (o.position ?? "bottom-right").includes("right");
799
- m = document.createElement("div"), m.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`;
800
- const g = document.createElement("div"), E = typeof window < "u" ? window.matchMedia("(max-width: 479px)") : null, O = (q) => {
801
- g.style.cssText = q ? [
844
+ w = document.createElement("div"), w.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 g = document.createElement("div"), P = typeof window < "u" && typeof window.matchMedia == "function" ? window.matchMedia("(max-width: 479px)") : null, U = (R) => {
846
+ o.el.classList.toggle("ocw-fs", R), g.style.cssText = R ? [
802
847
  "position:fixed",
803
848
  "inset:0",
804
849
  "width:100%",
805
- "height:100%",
850
+ "height:100dvh",
806
851
  "border-radius:0",
807
852
  "overflow:hidden",
808
853
  "box-shadow:none",
@@ -813,8 +858,8 @@ function Be(o) {
813
858
  "opacity:0",
814
859
  "z-index:9998"
815
860
  ].join(";") : [
816
- "width:380px",
817
- "height:600px",
861
+ "width:min(380px, calc(100vw - 40px))",
862
+ "height:min(600px, calc(100dvh - 108px))",
818
863
  "border-radius:16px",
819
864
  "overflow:hidden",
820
865
  "box-shadow:0 8px 40px rgba(0,0,0,.18)",
@@ -827,109 +872,123 @@ function Be(o) {
827
872
  "transform:scale(.95)"
828
873
  ].join(";");
829
874
  };
830
- O((E == null ? void 0 : E.matches) ?? !1);
831
- const N = (q) => O(q.matches);
832
- E == null || E.addEventListener("change", N), l = E, C = N, o.el.style.cssText = "width:100%;height:100%;overflow:hidden", g.append(o.el);
833
- const L = document.createElement("button");
834
- L.style.cssText = [
875
+ U((P == null ? void 0 : P.matches) ?? !1);
876
+ const F = (R) => U(R.matches);
877
+ P == null || P.addEventListener("change", F), l = P, T = F, o.el.style.cssText = "width:100%;height:100%;overflow:hidden", g.append(o.el);
878
+ const K = '<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>', Y = '<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>', B = document.createElement("button");
879
+ B.type = "button", B.style.cssText = [
835
880
  "width:56px;height:56px;border-radius:50%",
836
881
  `background:${o.accent ?? "#4F63F5"}`,
837
- "color:#fff;border:none;font-size:24px;cursor:pointer",
882
+ "color:#fff;border:none;cursor:pointer",
838
883
  "box-shadow:0 4px 16px rgba(0,0,0,.25)",
839
884
  "position:relative;flex:none",
885
+ "display:flex;align-items:center;justify-content:center",
840
886
  "transition:transform .15s"
841
- ].join(";"), L.textContent = "💬", L.onmouseenter = () => {
842
- L.style.transform = "scale(1.08)";
843
- }, L.onmouseleave = () => {
844
- L.style.transform = "scale(1)";
845
- }, h = document.createElement("span"), h.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", L.append(h), m.append(g, L), document.body.append(m);
846
- const _ = (q) => {
847
- q ? (g.style.display = "flex", requestAnimationFrame(() => {
887
+ ].join(";"), B.onmouseenter = () => {
888
+ B.style.transform = "scale(1.08)";
889
+ }, B.onmouseleave = () => {
890
+ B.style.transform = "scale(1)";
891
+ }, k = document.createElement("span"), k.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 G = () => {
893
+ B.innerHTML = I ? Y : K, B.setAttribute("aria-label", I ? "Close chat" : "Open chat"), B.setAttribute("aria-expanded", String(I)), B.append(k);
894
+ };
895
+ G(), w.append(g, B), document.body.append(w);
896
+ const se = (R) => {
897
+ R ? (g.style.display = "flex", requestAnimationFrame(() => {
848
898
  g.style.opacity = "1", g.style.transform = "scale(1)";
849
899
  })) : (g.style.opacity = "0", g.style.transform = "scale(.95)", setTimeout(() => {
850
- T || (g.style.display = "none");
900
+ I || (g.style.display = "none");
851
901
  }, 180));
852
902
  };
853
- L.addEventListener("click", () => {
854
- T = !T, _(T), L.textContent = T ? "✕" : "💬", L.append(h), T && (I = 0, h && (h.style.display = "none"));
855
- }), document.addEventListener("keydown", (q) => {
856
- q.key === "Escape" && T && (T = !1, _(!1), L.textContent = "💬", L.append(h));
857
- });
903
+ B.addEventListener("click", () => {
904
+ I = !I, se(I), G(), I && (E = 0, k && (k.style.display = "none"));
905
+ }), m = (R) => {
906
+ R.key === "Escape" && I && (I = !1, se(!1), G());
907
+ }, document.addEventListener("keydown", m);
858
908
  }
859
- const $ = () => {
860
- T || (I++, h && (h.textContent = String(I), h.style.display = "flex"));
861
- }, A = () => {
909
+ const A = () => {
910
+ I || (E++, k && (k.textContent = String(E), k.style.display = "flex"));
911
+ }, $ = () => {
862
912
  try {
863
- const n = new AudioContext(), p = n.createOscillator(), g = n.createGain();
913
+ const n = Re();
914
+ if (!n) return;
915
+ n.state === "suspended" && n.resume().catch(() => {
916
+ });
917
+ const p = n.createOscillator(), g = n.createGain();
864
918
  p.connect(g), g.connect(n.destination), p.frequency.setValueAtTime(880, n.currentTime), p.frequency.exponentialRampToValueAtTime(440, n.currentTime + 0.15), g.gain.setValueAtTime(0.3, n.currentTime), g.gain.exponentialRampToValueAtTime(1e-3, n.currentTime + 0.3), p.start(), p.stop(n.currentTime + 0.3);
865
919
  } catch {
866
920
  }
867
- }, P = [], z = (n) => {
868
- for (; P.length; ) {
869
- const p = P.shift();
870
- v.add({ clientMsgId: p.clientMsgId, content: p.content, ts: Date.now() }), k.send({ type: "send", conversationId: n, clientMsgId: p.clientMsgId, content: p.content });
921
+ }, z = [], q = (n) => {
922
+ for (; z.length; ) {
923
+ const p = z.shift();
924
+ y.add({ clientMsgId: p.clientMsgId, content: p.content, ts: Date.now() }), C.send({ type: "send", conversationId: n, clientMsgId: p.clientMsgId, content: p.content });
871
925
  }
872
926
  };
873
- let k;
874
- const x = new me(`ocw-e2e-${o.profileId}`);
875
- let S = !1;
876
- const B = [], D = [];
877
- let Y = !1;
878
- const F = (n, p) => {
879
- x.sealText(p).then((g) => {
880
- r && k.send({ type: "send", conversationId: r, clientMsgId: n, content: g });
927
+ let C;
928
+ const j = new Te(`ocw-e2e-${o.profileId}`);
929
+ let D = !1;
930
+ const x = [], S = [];
931
+ let M = !1;
932
+ const V = (n, p) => {
933
+ j.sealText(p).then((g) => {
934
+ c && C.send({ type: "send", conversationId: c, clientMsgId: n, content: g });
881
935
  });
882
- }, ie = (n, p, g) => {
883
- x.sealText(p, g).then((E) => {
884
- r && k.send({ type: "send", conversationId: r, clientMsgId: n, content: E });
936
+ }, le = (n, p, g) => {
937
+ j.sealText(p, g).then((P) => {
938
+ c && C.send({ type: "send", conversationId: c, clientMsgId: n, content: P });
885
939
  });
886
- }, se = () => {
887
- for (; B.length; ) {
888
- const n = B.shift();
889
- F(n.clientMsgId, n.text);
940
+ }, de = () => {
941
+ for (; x.length; ) {
942
+ const n = x.shift();
943
+ V(n.clientMsgId, n.text);
890
944
  }
891
- for (; D.length; ) {
892
- const n = D.shift();
893
- F(n.clientMsgId, n.text);
945
+ for (; S.length; ) {
946
+ const n = S.shift();
947
+ V(n.clientMsgId, n.text);
894
948
  }
895
- }, ae = (n) => {
896
- k.send({ type: "fetchPrekey", targetUserId: n });
897
- }, re = o.i18n ?? {}, ce = ["ar", "he", "fa", "ur"], le = typeof navigator < "u" ? (navigator.language ?? "").slice(0, 2).toLowerCase() : "";
898
- ce.includes(le) && !o.el.dir && (o.el.dir = "rtl", o.el.style.fontFamily = o.el.style.fontFamily || "Tahoma,Arial,system-ui,sans-serif");
899
- const K = new ke(), V = `oc_prechat_${o.profileId}_${a.slice(-8)}`, j = new Ee(o.el, a, {
949
+ }, pe = (n) => {
950
+ C.send({ type: "fetchPrekey", targetUserId: n });
951
+ }, he = o.i18n ?? {}, ue = ["ar", "he", "fa", "ur"], fe = typeof navigator < "u" ? (navigator.language ?? "").slice(0, 2).toLowerCase() : "";
952
+ ue.includes(fe) && !o.el.dir && (o.el.dir = "rtl", o.el.style.fontFamily = o.el.style.fontFamily || "Tahoma,Arial,system-ui,sans-serif");
953
+ const J = new ze(), Q = `oc_prechat_${o.profileId}_${a.slice(-8)}`, L = new Be(o.el, a, {
900
954
  onSend(n) {
901
955
  const p = `cm_${Math.random().toString(36).slice(2)}`, g = { kind: "text", text: n };
902
- d.addOptimistic(p, g), j.render(d), d.e2e ? x.ready ? F(p, n) : Y ? D.push({ clientMsgId: p, text: n }) : (B.push({ clientMsgId: p, text: n }), d.assignedAgentId && ae(d.assignedAgentId)) : r ? (v.add({ clientMsgId: p, content: g, ts: Date.now() }), k.send({ type: "send", conversationId: r, clientMsgId: p, content: g })) : P.push({ clientMsgId: p, content: g });
956
+ d.addOptimistic(p, g), L.render(d), d.e2e ? j.ready ? V(p, n) : M ? S.push({ clientMsgId: p, text: n }) : (x.push({ clientMsgId: p, text: n }), d.assignedAgentId && pe(d.assignedAgentId)) : c ? (y.add({ clientMsgId: p, content: g, ts: Date.now() }), C.send({ type: "send", conversationId: c, clientMsgId: p, content: g })) : z.push({ clientMsgId: p, content: g });
903
957
  },
904
958
  async onAttach(n) {
905
- if (!r) return;
959
+ if (!c) return;
906
960
  const p = `${b}/upload?name=${encodeURIComponent(n.name)}`, g = `cm_${Math.random().toString(36).slice(2)}`;
907
- d.addOptimistic(g, { kind: "text", text: `📎 Uploading ${n.name}…` }), j.render(d);
961
+ d.addOptimistic(g, { kind: "text", text: `📎 Uploading ${n.name}…` }), L.render(d);
908
962
  try {
909
- const E = await fetch(p, {
963
+ const P = await fetch(p, {
910
964
  method: "POST",
911
- headers: { "content-type": n.type, ...o.token ? { authorization: `Bearer ${o.token}` } : {} },
965
+ // Use the resolved connection token (a signed JWT, an explicit userId,
966
+ // or the anonymous persistent uid) — NOT just opts.token. The server
967
+ // requires an Authorization header, and the verifier accepts an
968
+ // anonymous id as a guest; keying off opts.token alone meant anonymous
969
+ // visitors (the common case) sent no auth and every upload 401'd.
970
+ headers: { "content-type": n.type, authorization: `Bearer ${a}` },
912
971
  body: n
913
972
  });
914
- if (!E.ok) throw new Error(`Upload failed: ${E.status}`);
915
- const { url: O, name: N, mime: L, size: _ } = await E.json();
916
- k.send({ type: "send", conversationId: r, clientMsgId: g, content: { kind: "attachment", url: O, name: N, mime: L, size: _ } });
917
- } catch (E) {
918
- d.addOptimistic(g, { kind: "text", text: `⚠️ Upload failed: ${E.message}` }), j.render(d);
973
+ if (!P.ok) throw new Error(`Upload failed: ${P.status}`);
974
+ const { url: U, name: F, mime: K, size: Y } = await P.json();
975
+ C.send({ type: "send", conversationId: c, clientMsgId: g, content: { kind: "attachment", url: U, name: F, mime: K, size: Y } });
976
+ } catch (P) {
977
+ d.addOptimistic(g, { kind: "text", text: `⚠️ Upload failed: ${P.message}` }), L.render(d);
919
978
  }
920
979
  },
921
980
  onInvoke(n, p) {
922
- r && k.send({ type: "invoke", conversationId: r, actionId: n, clientInvokeId: `iv_${Math.random().toString(36).slice(2)}`, ...p ? { inputs: p } : {} });
981
+ c && C.send({ type: "invoke", conversationId: c, actionId: n, clientInvokeId: `iv_${Math.random().toString(36).slice(2)}`, ...p ? { inputs: p } : {} });
923
982
  },
924
983
  onTyping(n, p) {
925
- r && k.send({ type: "typing", conversationId: r, isTyping: n, ...p ? { preview: p } : {} });
984
+ c && C.send({ type: "typing", conversationId: c, isTyping: n, ...p ? { preview: p } : {} });
926
985
  },
927
986
  onPreChat(n) {
928
987
  try {
929
- localStorage.setItem(V, "1");
988
+ localStorage.setItem(Q, "1");
930
989
  } catch {
931
990
  }
932
- k.send({
991
+ C.send({
933
992
  type: "open",
934
993
  profileId: o.profileId,
935
994
  ...o.subjectId ? { subjectId: o.subjectId } : {},
@@ -943,39 +1002,39 @@ function Be(o) {
943
1002
  }
944
1003
  });
945
1004
  const p = n.callback ? `📞 Call-back requested${n.phone ? `: ${n.phone}` : ""}${n.topic ? ` — ${n.topic}` : ""}` : n.topic ? `Topic: ${n.topic}` : "";
946
- p && r && !d.e2e && k.send({ type: "send", conversationId: r, clientMsgId: `pc_${Math.random().toString(36).slice(2, 12)}`, content: { kind: "text", text: p } });
1005
+ p && c && !d.e2e && C.send({ type: "send", conversationId: c, clientMsgId: `pc_${Math.random().toString(36).slice(2, 12)}`, content: { kind: "text", text: p } });
947
1006
  },
948
1007
  onDeflectQuery(n) {
949
1008
  if (s) return;
950
1009
  clearTimeout(i);
951
1010
  const p = n.trim();
952
1011
  if (p.length < 3) {
953
- j.hideDeflection();
1012
+ L.hideDeflection();
954
1013
  return;
955
1014
  }
956
1015
  i = setTimeout(() => {
957
- fetch(`${b}/kb/search?profileId=${encodeURIComponent(o.profileId)}&q=${encodeURIComponent(p.slice(0, 200))}`).then((g) => g.ok ? g.json() : { articles: [] }).then((g) => j.showDeflection(g.articles ?? [])).catch(() => j.hideDeflection());
1016
+ fetch(`${b}/kb/search?profileId=${encodeURIComponent(o.profileId)}&q=${encodeURIComponent(p.slice(0, 200))}`).then((g) => g.ok ? g.json() : { articles: [] }).then((g) => L.showDeflection(g.articles ?? [])).catch(() => L.hideDeflection());
958
1017
  }, 350);
959
1018
  },
960
1019
  onReadUpTo(n) {
961
- r && k.send({ type: "read", conversationId: r, seq: n });
1020
+ c && C.send({ type: "read", conversationId: c, seq: n });
962
1021
  },
963
1022
  onLoadMore() {
964
- if (!r || !d.e2e) return;
1023
+ if (!c || !d.e2e) return;
965
1024
  const n = d.messages()[0];
966
- n && k.send({ type: "history", conversationId: r, beforeSeq: n.seq, limit: 20 });
1025
+ n && C.send({ type: "history", conversationId: c, beforeSeq: n.seq, limit: 20 });
967
1026
  },
968
1027
  onEdit(n, p) {
969
- r && k.send({ type: "edit", conversationId: r, messageId: n, content: { kind: "text", text: p } });
1028
+ c && C.send({ type: "edit", conversationId: c, messageId: n, content: { kind: "text", text: p } });
970
1029
  },
971
1030
  onDelete(n) {
972
- r && k.send({ type: "delete", conversationId: r, messageId: n });
1031
+ c && C.send({ type: "delete", conversationId: c, messageId: n });
973
1032
  },
974
1033
  onReact(n, p, g) {
975
- r && k.send({ type: "react", conversationId: r, messageId: n, emoji: p, remove: g });
1034
+ c && C.send({ type: "react", conversationId: c, messageId: n, emoji: p, remove: g });
976
1035
  },
977
1036
  onCsat(n) {
978
- r && fetch(`${b}/conversations/${r}/csat`, {
1037
+ c && fetch(`${b}/conversations/${c}/csat`, {
979
1038
  method: "POST",
980
1039
  headers: { "Content-Type": "application/json", Authorization: `Bearer ${a}` },
981
1040
  body: JSON.stringify({ score: n })
@@ -983,10 +1042,10 @@ function Be(o) {
983
1042
  });
984
1043
  },
985
1044
  onAnnotate(n) {
986
- r && k.send({ type: "annotate", conversationId: r, stroke: n });
1045
+ c && C.send({ type: "annotate", conversationId: c, stroke: n });
987
1046
  },
988
1047
  onAnnotateClear() {
989
- r && k.send({ type: "annotate_clear", conversationId: r });
1048
+ c && C.send({ type: "annotate_clear", conversationId: c });
990
1049
  },
991
1050
  ...o.translateLang ? {
992
1051
  async onTranslate(n) {
@@ -1009,102 +1068,102 @@ function Be(o) {
1009
1068
  ...o.subject ? { subject: o.subject } : {},
1010
1069
  ...o.quickReplies ? { quickReplies: o.quickReplies } : {},
1011
1070
  ...o.accent ? { accent: o.accent } : {},
1012
- ...(Q = o.user) != null && Q.name || (G = o.user) != null && G.avatar ? { userInfo: { ...o.user.name ? { name: o.user.name } : {}, ...o.user.avatar ? { avatar: o.user.avatar } : {} } } : {},
1013
- i18n: re
1071
+ ...(te = o.user) != null && te.name || (oe = o.user) != null && oe.avatar ? { userInfo: { ...o.user.name ? { name: o.user.name } : {}, ...o.user.avatar ? { avatar: o.user.avatar } : {} } } : {},
1072
+ i18n: he
1014
1073
  });
1015
1074
  try {
1016
- localStorage.getItem(V) && j.completePreChat();
1075
+ localStorage.getItem(Q) && L.completePreChat();
1017
1076
  } catch {
1018
1077
  }
1019
- const X = o.user && (o.user.name || o.user.email || o.user.avatar || o.user.meta) ? {
1078
+ const Z = o.user && (o.user.name || o.user.email || o.user.avatar || o.user.meta) ? {
1020
1079
  ...o.user.name ? { name: o.user.name } : {},
1021
1080
  ...o.user.email ? { email: o.user.email } : {},
1022
1081
  ...o.user.avatar ? { avatar: o.user.avatar } : {},
1023
1082
  ...o.user.meta ? { meta: o.user.meta } : {}
1024
- } : void 0, de = {
1083
+ } : void 0, we = {
1025
1084
  type: "open",
1026
1085
  profileId: o.profileId,
1027
1086
  // Direct conversations use the kind/peerId pair; the dm:… subject key is
1028
1087
  // server-derived and owner-keyed, so passing it as subjectId from the
1029
1088
  // NON-owner side would find-or-create a junk duplicate thread.
1030
1089
  ...o.kind === "direct" && o.peerId ? { kind: "direct", peerId: o.peerId } : o.subjectId ? { subjectId: o.subjectId } : {},
1031
- ...c ? { linkFrom: c } : {},
1032
- ...X ? { userInfo: X } : {},
1090
+ ...r ? { linkFrom: r } : {},
1091
+ ...Z ? { userInfo: Z } : {},
1033
1092
  ...typeof location < "u" ? { pageUrl: location.href } : {},
1034
1093
  ...typeof document < "u" && document.title ? { pageTitle: document.title } : {},
1035
1094
  // Pass subject display info so the server can persist it to the Subject record.
1036
1095
  // This is how listingTitle and listingMeta get saved without a separate API call.
1037
- ...(Z = o.subject) != null && Z.title ? { subjectTitle: o.subject.title } : {},
1038
- ...(ee = o.subject) != null && ee.subtitle ? { subjectMeta: o.subject.subtitle } : {}
1096
+ ...(ne = o.subject) != null && ne.title ? { subjectTitle: o.subject.title } : {},
1097
+ ...(ie = o.subject) != null && ie.subtitle ? { subjectMeta: o.subject.subtitle } : {}
1039
1098
  };
1040
- k = new ge({
1099
+ C = new Ce({
1041
1100
  ...o.refreshToken ? { refreshToken: o.refreshToken } : {},
1042
1101
  url: f,
1043
1102
  token: a,
1044
- open: de,
1103
+ open: we,
1045
1104
  getCursor: () => d.highestSeq(),
1046
- onStatusChange: (n, p) => j.setConnStatus(n, p),
1105
+ onStatusChange: (n, p) => L.setConnStatus(n, p),
1047
1106
  onFrame(n) {
1048
- if (K.apply(n), n.type === "opened") {
1049
- if (r = n.conversation.id, !u) {
1107
+ if (J.apply(n), n.type === "opened") {
1108
+ if (c = n.conversation.id, !u) {
1050
1109
  u = !0;
1051
- for (const p of v.load())
1052
- k.send({ type: "send", conversationId: r, clientMsgId: p.clientMsgId, content: p.content });
1110
+ for (const p of y.load())
1111
+ C.send({ type: "send", conversationId: c, clientMsgId: p.clientMsgId, content: p.content });
1053
1112
  }
1054
- we(f, a, r, d, j, b), P.length && z(r);
1113
+ ve(f, a, c, d, L, b), z.length && q(c);
1055
1114
  }
1056
- if (n.type === "ack" && v.remove(n.clientMsgId), n.type === "prekeyBundle") {
1057
- n.bundle && (Y = !0, x.x3dhSendTo(n.bundle).then((p) => {
1058
- const g = [...B.splice(0), ...D.splice(0)];
1059
- for (const E of g) ie(E.clientMsgId, E.text, p);
1060
- j.render(d);
1115
+ if (n.type === "ack" && y.remove(n.clientMsgId), n.type === "prekeyBundle") {
1116
+ n.bundle && (M = !0, j.x3dhSendTo(n.bundle).then((p) => {
1117
+ const g = [...x.splice(0), ...S.splice(0)];
1118
+ for (const P of g) le(P.clientMsgId, P.text, p);
1119
+ L.render(d);
1061
1120
  }));
1062
1121
  return;
1063
1122
  }
1064
1123
  if (n.type === "message" && d.e2e) {
1065
- const p = ye(n.message.content);
1066
- if (p && !x.ready) {
1067
- x.x3dhReceiveFrom(p.x3dhIK, p.x3dhEK, p.x3dhSPK).then(async () => {
1068
- await x.openFrame(n), d.apply(n), j.render(d);
1124
+ const p = Ie(n.message.content);
1125
+ if (p && !j.ready) {
1126
+ j.x3dhReceiveFrom(p.x3dhIK, p.x3dhEK, p.x3dhSPK).then(async () => {
1127
+ await j.openFrame(n), d.apply(n), L.render(d);
1069
1128
  });
1070
1129
  return;
1071
1130
  }
1072
1131
  }
1073
1132
  if (n.type === "peerkey") {
1074
- x.onPeerKey(n.key).then(() => {
1075
- se(), j.render(d);
1133
+ j.onPeerKey(n.key).then(() => {
1134
+ de(), L.render(d);
1076
1135
  });
1077
1136
  return;
1078
1137
  }
1079
1138
  (async () => {
1080
- if (d.e2e && await x.openFrame(n), d.apply(n), n.type === "message" && n.message.senderId !== a && !n.message.internal && ($(), A()), d.e2e && r && !S) {
1081
- S = !0;
1082
- const p = await x.initX3DH();
1083
- k.send({ type: "uploadPrekeys", ...p });
1084
- const g = await x.begin();
1085
- k.send({ type: "pubkey", conversationId: r, key: g });
1139
+ if (d.e2e && await j.openFrame(n), d.apply(n), n.type === "message" && n.message.senderId !== a && !n.message.internal && (A(), $()), d.e2e && c && !D) {
1140
+ D = !0;
1141
+ const p = await j.initX3DH();
1142
+ C.send({ type: "uploadPrekeys", ...p });
1143
+ const g = await j.begin();
1144
+ C.send({ type: "pubkey", conversationId: c, key: g });
1086
1145
  }
1087
- j.render(d);
1146
+ L.render(d);
1088
1147
  })();
1089
1148
  }
1090
- }), k.connect(), j.render(d);
1091
- const M = o.launcher ? ne(o) : null, H = { close: () => {
1092
- s = !0, clearTimeout(i), k.close(), m == null || m.remove(), j.destroy(), K.destroy(), l && C && l.removeEventListener("change", C), R.delete(o.el), M && U.get(M) === H && U.delete(M);
1149
+ }), C.connect(), L.render(d);
1150
+ const H = o.launcher ? ce(o) : null, _ = { close: () => {
1151
+ s = !0, clearTimeout(i), C.close(), w == null || w.remove(), L.destroy(), J.destroy(), l && T && l.removeEventListener("change", T), m && (document.removeEventListener("keydown", m), m = null), O.delete(o.el), H && W.get(H) === _ && W.delete(H);
1093
1152
  } };
1094
- return R.set(o.el, H), M && U.set(M, H), H;
1153
+ return O.set(o.el, _), H && W.set(H, _), _;
1095
1154
  }
1096
1155
  export {
1097
- xe as ChatStore,
1098
- ge as ConnectionManager,
1099
- me as E2ESession,
1100
- be as PersistentOutbox,
1101
- Ee as Renderer,
1102
- He as asConversationId,
1103
- ye as extractX3DHInit,
1104
- Me as httpBaseFromWsUrl,
1105
- Be as mount,
1106
- ue as resolveRelayUrls,
1107
- we as restoreHistory,
1108
- Ae as unmount
1156
+ ke as ChatStore,
1157
+ Ce as ConnectionManager,
1158
+ Te as E2ESession,
1159
+ ye as PersistentOutbox,
1160
+ Be as Renderer,
1161
+ Ke as asConversationId,
1162
+ Ie as extractX3DHInit,
1163
+ We as httpBaseFromWsUrl,
1164
+ _e as mount,
1165
+ me as resolveRelayUrls,
1166
+ ve as restoreHistory,
1167
+ Ne as unmount
1109
1168
  };
1110
1169
  //# sourceMappingURL=index.js.map