@locdo.tech/botiq-chat-sdk 0.7.0 → 0.8.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -283,7 +283,7 @@ async function k(e, t, n, r, i) {
283
283
  };
284
284
  }
285
285
  }
286
- async function ee(e, t, n, r, i, a, o, s) {
286
+ async function A(e, t, n, r, i, a, o, s) {
287
287
  try {
288
288
  let c = D.getDefinitions(), l = await fetch(`${e}/widget/chat`, {
289
289
  method: "POST",
@@ -327,16 +327,16 @@ async function ee(e, t, n, r, i, a, o, s) {
327
327
  };
328
328
  }
329
329
  }
330
- var A = {
330
+ var j = {
331
331
  messages: [],
332
332
  hasMore: !1
333
333
  };
334
- function te(e) {
334
+ function M(e) {
335
335
  if (!e || typeof e != "object") return !1;
336
336
  let t = e;
337
337
  return typeof t.id == "string" && (t.role === "user" || t.role === "assistant") && typeof t.content == "string";
338
338
  }
339
- async function j(e, t, n, r, i, a) {
339
+ async function N(e, t, n, r, i, a) {
340
340
  try {
341
341
  let o = new URLSearchParams({
342
342
  sessionId: n,
@@ -351,26 +351,112 @@ async function j(e, t, n, r, i, a) {
351
351
  },
352
352
  referrerPolicy: "no-referrer-when-downgrade"
353
353
  });
354
- if (!s.ok) return A;
354
+ if (!s.ok) return j;
355
355
  let c = await s.json();
356
356
  return {
357
- messages: Array.isArray(c.messages) ? c.messages.filter(te) : [],
357
+ messages: Array.isArray(c.messages) ? c.messages.filter(M) : [],
358
358
  hasMore: c.hasMore === !0,
359
359
  escalated: c.escalated === !0
360
360
  };
361
361
  } catch {
362
- return A;
362
+ return j;
363
363
  }
364
364
  }
365
- function M(e, t, n, r, i) {
366
- return j(e, t, n, void 0, r, i);
365
+ function P(e, t, n, r, i) {
366
+ return N(e, t, n, void 0, r, i);
367
367
  }
368
- function ne(e, t, n, r, i, a) {
369
- return j(e, t, n, r, i, a);
368
+ function ee(e, t, n, r, i, a) {
369
+ return N(e, t, n, r, i, a);
370
+ }
371
+ //#endregion
372
+ //#region src/core/stream.ts
373
+ async function te(e) {
374
+ if (typeof ReadableStream > "u") return A(e.apiUrl, e.apiKey, e.sessionId, e.message, e.history, e.strings, e.visitorId, e.attachments);
375
+ let t = D.getDefinitions(), n = {
376
+ sessionId: e.sessionId,
377
+ message: e.message,
378
+ history: e.history,
379
+ ...t.length ? { availableActions: t } : {},
380
+ ...e.visitorId ? { visitorId: e.visitorId } : {},
381
+ ...e.attachments?.length ? { attachments: e.attachments } : {}
382
+ }, r;
383
+ try {
384
+ r = await fetch(`${e.apiUrl}/widget/chat/stream`, {
385
+ method: "POST",
386
+ headers: {
387
+ "Content-Type": "application/json",
388
+ "X-Api-Key": e.apiKey,
389
+ ...e.visitorId ? { "X-Visitor-Id": e.visitorId } : {}
390
+ },
391
+ referrerPolicy: "no-referrer-when-downgrade",
392
+ body: JSON.stringify(n)
393
+ });
394
+ } catch {
395
+ return A(e.apiUrl, e.apiKey, e.sessionId, e.message, e.history, e.strings, e.visitorId, e.attachments);
396
+ }
397
+ if (!r.ok) return r.status === 401 ? {
398
+ reply: e.strings.errorAuth,
399
+ error: !0
400
+ } : r.status === 403 ? {
401
+ reply: e.strings.errorForbidden,
402
+ error: !0
403
+ } : r.status === 429 ? {
404
+ reply: e.strings.errorQuota,
405
+ error: !0
406
+ } : A(e.apiUrl, e.apiKey, e.sessionId, e.message, e.history, e.strings, e.visitorId, e.attachments);
407
+ if (!r.body) return {
408
+ reply: e.strings.errorMessage,
409
+ error: !0
410
+ };
411
+ try {
412
+ return await ne(r.body, e);
413
+ } catch {
414
+ return {
415
+ reply: e.strings.errorMessage,
416
+ error: !0
417
+ };
418
+ }
419
+ }
420
+ async function ne(e, t) {
421
+ let n = e.getReader(), r = new TextDecoder(), i = "", a = "", o = null;
422
+ outer: for (;;) {
423
+ let { done: e, value: s } = await n.read();
424
+ if (e) break;
425
+ i += r.decode(s, { stream: !0 });
426
+ let c = i.split("\n");
427
+ i = c.pop() ?? "";
428
+ for (let e of c) {
429
+ if (!e.startsWith("data: ")) continue;
430
+ let n = e.slice(6).trim();
431
+ if (!n) continue;
432
+ let r;
433
+ try {
434
+ r = JSON.parse(n);
435
+ } catch {
436
+ continue;
437
+ }
438
+ if (r.type === "token") {
439
+ let e = String(r.delta ?? "");
440
+ e && (a += e, t.onToken(e));
441
+ } else if (r.type === "done") {
442
+ o = r;
443
+ break outer;
444
+ } else if (r.type === "error") return {
445
+ reply: t.strings.errorMessage,
446
+ error: !0
447
+ };
448
+ }
449
+ }
450
+ if (!o) throw Error("SSE stream ended without done event");
451
+ return {
452
+ reply: a || t.strings.errorMessage,
453
+ pageAction: o.pageAction,
454
+ blocks: o.blocks
455
+ };
370
456
  }
371
457
  //#endregion
372
458
  //#region src/core/state.ts
373
- var N = {
459
+ var F = {
374
460
  messages: [],
375
461
  isLoading: !1,
376
462
  isOpen: !1,
@@ -383,34 +469,34 @@ var N = {
383
469
  pendingAttachment: null,
384
470
  isUploading: !1,
385
471
  uploadError: null
386
- }, P = /* @__PURE__ */ new Set();
387
- function F() {
388
- return N;
472
+ }, I = /* @__PURE__ */ new Set();
473
+ function L() {
474
+ return F;
389
475
  }
390
- function I(e) {
391
- Object.assign(N, e);
476
+ function R(e) {
477
+ Object.assign(F, e);
392
478
  let t = {
393
- ...N,
394
- messages: [...N.messages],
395
- conversations: [...N.conversations]
479
+ ...F,
480
+ messages: [...F.messages],
481
+ conversations: [...F.conversations]
396
482
  };
397
- P.forEach((e) => e(t));
483
+ I.forEach((e) => e(t));
398
484
  }
399
485
  function re(e) {
400
- return P.add(e), () => P.delete(e);
486
+ return I.add(e), () => I.delete(e);
401
487
  }
402
488
  //#endregion
403
489
  //#region src/core/upload.ts
404
- var L = new Set([
490
+ var z = new Set([
405
491
  "image/jpeg",
406
492
  "image/png",
407
493
  "image/webp"
408
- ]), R = 25 * 1024 * 1024, z = 5 * 1024 * 1024, B = 1600, ie = .85, ae = .65;
409
- function oe(e) {
410
- return L.has(e);
411
- }
494
+ ]), B = 25 * 1024 * 1024, ie = 5 * 1024 * 1024, V = 1600, ae = .85, oe = .65;
412
495
  function se(e) {
413
- return oe(e.type) ? e.size > R ? {
496
+ return z.has(e);
497
+ }
498
+ function ce(e) {
499
+ return se(e.type) ? e.size > B ? {
414
500
  ok: !1,
415
501
  error: "Image too large (max 25 MB before compression)."
416
502
  } : { ok: !0 } : {
@@ -418,25 +504,25 @@ function se(e) {
418
504
  error: "Unsupported image type. Please use JPEG, PNG, or WebP."
419
505
  };
420
506
  }
421
- function ce(e, t) {
507
+ function le(e, t) {
422
508
  let n = Math.max(e, t);
423
- if (n <= B) return {
509
+ if (n <= V) return {
424
510
  width: e,
425
511
  height: t
426
512
  };
427
- let r = B / n;
513
+ let r = V / n;
428
514
  return {
429
515
  width: Math.floor(e * r),
430
516
  height: Math.floor(t * r)
431
517
  };
432
518
  }
433
- function le(e) {
434
- let t = se(e);
519
+ function ue(e) {
520
+ let t = ce(e);
435
521
  return t.ok ? new Promise((t, n) => {
436
522
  let r = new Image(), i = URL.createObjectURL(e);
437
523
  r.onload = () => {
438
524
  URL.revokeObjectURL(i);
439
- let { width: a, height: o } = ce(r.naturalWidth, r.naturalHeight), s = document.createElement("canvas");
525
+ let { width: a, height: o } = le(r.naturalWidth, r.naturalHeight), s = document.createElement("canvas");
440
526
  s.width = a, s.height = o;
441
527
  let c = s.getContext("2d");
442
528
  if (!c) {
@@ -450,7 +536,7 @@ function le(e) {
450
536
  n(/* @__PURE__ */ Error("Canvas toBlob returned null"));
451
537
  return;
452
538
  }
453
- if (e.size <= z) {
539
+ if (e.size <= ie) {
454
540
  t({
455
541
  blob: e,
456
542
  mimeType: l
@@ -462,7 +548,7 @@ function le(e) {
462
548
  n(/* @__PURE__ */ Error("Canvas toBlob (fallback quality) returned null"));
463
549
  return;
464
550
  }
465
- if (e.size > z) {
551
+ if (e.size > ie) {
466
552
  n(/* @__PURE__ */ Error("Image too large after compression (> 5 MB). Try a smaller image."));
467
553
  return;
468
554
  }
@@ -470,8 +556,8 @@ function le(e) {
470
556
  blob: e,
471
557
  mimeType: l
472
558
  });
473
- }, l, ae);
474
- }, l, ie);
559
+ }, l, oe);
560
+ }, l, ae);
475
561
  }, r.onerror = () => {
476
562
  URL.revokeObjectURL(i), n(/* @__PURE__ */ Error("Failed to load image"));
477
563
  }, r.src = i;
@@ -479,7 +565,7 @@ function le(e) {
479
565
  }
480
566
  //#endregion
481
567
  //#region src/core/styles.ts
482
- var V = {
568
+ var de = {
483
569
  inter: {
484
570
  url: "https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600&display=swap",
485
571
  family: "'Inter', system-ui, -apple-system, sans-serif"
@@ -506,16 +592,16 @@ function H(e, t) {
506
592
  let n = t.angle ?? 135;
507
593
  return t.type === "linear" ? `linear-gradient(${n}deg, ${t.from}, ${t.to})` : `radial-gradient(circle, ${t.from}, ${t.to})`;
508
594
  }
509
- function ue(e) {
595
+ function fe(e) {
510
596
  return e.replace(/\/\*[\s\S]*?\*\//g, "").replace(/\\[0-9a-fA-F]{1,6}\s?/g, "x").replace(/@import\b[^;]*;?/gi, "").replace(/url\s*\(\s*["']?\s*(?!data:)[^)]*["']?\s*\)/gi, "url(\"\")").replace(/expression\s*\(/gi, "expression_(").replace(/javascript\s*:/gi, "blocked:").replace(/-moz-binding\s*:/gi, "").replace(/\bbehavior\s*:/gi, "");
511
597
  }
512
- function de(e) {
598
+ function pe(e) {
513
599
  let t = e?.bubbleOpen ?? "none", n = e?.typingIndicator ?? "dots-bounce";
514
600
  return [t === "fade" ? "@keyframes biq-open-fade { from { opacity: 0; } to { opacity: 1; } }\n.chat-window.open { animation: biq-open-fade .22s ease forwards; }" : t === "slide-up" ? "@keyframes biq-open-slide { from { opacity: 0; transform: scale(1) translateY(20px); } to { opacity: 1; transform: scale(1) translateY(0); } }\n.chat-window.open { animation: biq-open-slide .25s cubic-bezier(.22,1,.36,1) forwards; }" : t === "bounce" ? "@keyframes biq-open-bounce { 0% { opacity: 0; transform: scale(.85) translateY(8px); } 60% { transform: scale(1.03) translateY(-3px); } 100% { opacity: 1; transform: scale(1) translateY(0); } }\n.chat-window.open { animation: biq-open-bounce .35s cubic-bezier(.34,1.56,.64,1) forwards; }" : "", n === "dots-pulse" ? "@keyframes biq-pulse { 0%, 100% { opacity: 0.3; transform: scale(1); } 50% { opacity: 1; transform: scale(1.3); } }\n.typing span { animation: biq-pulse 1.2s infinite ease-in-out; }" : n === "bar" ? ".typing { gap: 3px; align-items: flex-end; }\n.typing span { width: 3px; height: 14px; border-radius: 2px; animation: biq-bar 1s infinite ease-in-out; }\n.typing span:nth-child(1) { animation-delay: 0s; }\n.typing span:nth-child(2) { animation-delay: .15s; height: 20px; }\n.typing span:nth-child(3) { animation-delay: .3s; }\n@keyframes biq-bar { 0%, 100% { transform: scaleY(.4); opacity: .5; } 50% { transform: scaleY(1); opacity: 1; } }" : ""].filter(Boolean).join("\n");
515
601
  }
516
- var fe = "\n/* ── Rich Blocks ─────────────────────────── */\n.biq-blocks {\n margin-top: 8px;\n display: flex;\n flex-direction: column;\n gap: 8px;\n max-width: 100%;\n}\n\n/* ── Shared button style ─────────────────── */\n.biq-btn {\n display: inline-block;\n padding: 7px 14px;\n border-radius: 18px;\n font: inherit;\n font-size: 13px;\n font-weight: 500;\n cursor: pointer;\n transition: filter .15s, opacity .15s;\n text-decoration: none;\n border: 1.5px solid #F97316;\n background: transparent;\n color: #F97316;\n line-height: 1.3;\n white-space: nowrap;\n}\n.biq-btn:hover { filter: brightness(1.15); }\n.biq-btn--send { background: #F97316; color: #fff; }\n.biq-btn--send:hover { filter: brightness(0.9); }\n.biq-btn--url { background: transparent; color: #F97316; }\n.biq-btn--page_action { border-style: dashed; }\n\n/* ── Card ────────────────────────────────── */\n.biq-card {\n background: #1A1A1A;\n border: 1px solid #2D2D2D;\n border-radius: 12px;\n overflow: hidden;\n display: flex;\n flex-direction: column;\n min-width: 0;\n text-decoration: none;\n color: inherit;\n transition: border-color .15s;\n}\n.biq-card--link:hover { border-color: #F97316; }\n\n.biq-card-img {\n width: 100%;\n max-height: 160px;\n object-fit: cover;\n display: block;\n}\n\n.biq-card-title {\n font-size: 14px;\n font-weight: 600;\n color: #fff;\n padding: 10px 12px 2px;\n line-height: 1.3;\n}\n\n.biq-card-subtitle {\n font-size: 12px;\n color: #9CA3AF;\n padding: 0 12px 6px;\n line-height: 1.4;\n}\n\n.biq-card-price {\n font-size: 14px;\n font-weight: 600;\n color: #F97316;\n padding: 4px 12px 8px;\n}\n\n.biq-card-btns {\n display: flex;\n flex-wrap: wrap;\n gap: 6px;\n padding: 0 10px 10px;\n}\n\n/* ── Carousel ────────────────────────────── */\n.biq-carousel {\n display: flex;\n flex-direction: row;\n gap: 10px;\n overflow-x: auto;\n padding-bottom: 4px;\n scrollbar-width: thin;\n scrollbar-color: #2D2D2D transparent;\n /* Snap cards into position on scroll */\n scroll-snap-type: x mandatory;\n}\n.biq-carousel::-webkit-scrollbar { height: 4px; }\n.biq-carousel::-webkit-scrollbar-track { background: transparent; }\n.biq-carousel::-webkit-scrollbar-thumb { background: #2D2D2D; border-radius: 2px; }\n\n.biq-carousel .biq-card {\n flex: 0 0 200px;\n scroll-snap-align: start;\n max-width: 200px;\n}\n\n/* ── Quick Replies ───────────────────────── */\n.biq-quick-replies {\n display: flex;\n flex-wrap: wrap;\n gap: 6px;\n margin-top: 4px;\n}\n\n.biq-qr-pill {\n padding: 5px 14px;\n border-radius: 20px;\n border: 1.5px solid #F97316;\n background: transparent;\n color: #F97316;\n font: inherit;\n font-size: 13px;\n cursor: pointer;\n transition: background .15s, color .15s;\n white-space: nowrap;\n}\n.biq-qr-pill:hover { background: #F97316; color: #fff; }\n\n/* ── Buttons block ───────────────────────── */\n.biq-buttons {\n display: flex;\n flex-wrap: wrap;\n gap: 6px;\n margin-top: 4px;\n}\n", pe = "\n.botiq-confirm-overlay { position:absolute; inset:0; background:rgba(0,0,0,.7);\n display:flex; align-items:center; justify-content:center; z-index:999; }\n.botiq-confirm-dialog { background:#1A1A1A; border:1px solid #2D2D2D; border-radius:12px;\n padding:16px; max-width:320px; color:#fff; font-size:14px; }\n.botiq-confirm-header { font-weight:600; margin-bottom:8px; }\n.botiq-confirm-reason { color:#9CA3AF; margin-bottom:8px; }\n.botiq-confirm-params { background:#0a0a0a; padding:8px; border-radius:6px; font-size:12px;\n max-height:120px; overflow:auto; white-space:pre-wrap; }\n.botiq-confirm-actions { display:flex; gap:8px; margin-top:12px; }\n.botiq-confirm-yes { flex:1; padding:8px 12px; border-radius:6px; border:none;\n background:#F97316; color:#fff; cursor:pointer; }\n.botiq-confirm-yes[data-risk=\"high\"] { background:#DC2626; }\n.botiq-confirm-no { flex:1; padding:8px 12px; border-radius:6px; background:transparent;\n border:1px solid #2D2D2D; color:#fff; cursor:pointer; }\n.botiq-confirm-countdown { margin-top:8px; font-size:12px; color:#9CA3AF; }\n";
517
- function me(e) {
518
- let { colors: t, layout: n, font: r, gradient: i, animation: a, customCSS: o, whiteLabel: s } = e, c = V[r] ?? V.inter, l = n.buttonShape === "square" ? "14px" : "50%", u = n.position === "bottom-left" ? "right: auto; left: 24px;" : "right: 24px;", d = n.position === "bottom-left" ? "bottom left" : "bottom right", f = n.position === "bottom-left" ? "right: auto; left: 0;" : "right: 0;", p = n.fillHeight ? `min(${n.height}px, calc(100dvh - 48px))` : `${n.height}px`, m = H(t.primary, i), h = H(t.header, i), g = H(t.userBubble, i), _ = s ? ".botiq-badge { display: none !important; }" : "";
602
+ var me = "\n/* ── Rich Blocks ─────────────────────────── */\n.biq-blocks {\n margin-top: 8px;\n display: flex;\n flex-direction: column;\n gap: 8px;\n max-width: 100%;\n}\n\n/* ── Shared button style ─────────────────── */\n.biq-btn {\n display: inline-block;\n padding: 7px 14px;\n border-radius: 18px;\n font: inherit;\n font-size: 13px;\n font-weight: 500;\n cursor: pointer;\n transition: filter .15s, opacity .15s;\n text-decoration: none;\n border: 1.5px solid #F97316;\n background: transparent;\n color: #F97316;\n line-height: 1.3;\n white-space: nowrap;\n}\n.biq-btn:hover { filter: brightness(1.15); }\n.biq-btn--send { background: #F97316; color: #fff; }\n.biq-btn--send:hover { filter: brightness(0.9); }\n.biq-btn--url { background: transparent; color: #F97316; }\n.biq-btn--page_action { border-style: dashed; }\n\n/* ── Card ────────────────────────────────── */\n.biq-card {\n background: #1A1A1A;\n border: 1px solid #2D2D2D;\n border-radius: 12px;\n overflow: hidden;\n display: flex;\n flex-direction: column;\n min-width: 0;\n text-decoration: none;\n color: inherit;\n transition: border-color .15s;\n}\n.biq-card--link:hover { border-color: #F97316; }\n\n.biq-card-img {\n width: 100%;\n max-height: 160px;\n object-fit: cover;\n display: block;\n}\n\n.biq-card-title {\n font-size: 14px;\n font-weight: 600;\n color: #fff;\n padding: 10px 12px 2px;\n line-height: 1.3;\n}\n\n.biq-card-subtitle {\n font-size: 12px;\n color: #9CA3AF;\n padding: 0 12px 6px;\n line-height: 1.4;\n}\n\n.biq-card-price {\n font-size: 14px;\n font-weight: 600;\n color: #F97316;\n padding: 4px 12px 8px;\n}\n\n.biq-card-btns {\n display: flex;\n flex-wrap: wrap;\n gap: 6px;\n padding: 0 10px 10px;\n}\n\n/* ── Carousel ────────────────────────────── */\n.biq-carousel {\n display: flex;\n flex-direction: row;\n gap: 10px;\n overflow-x: auto;\n padding-bottom: 4px;\n scrollbar-width: thin;\n scrollbar-color: #2D2D2D transparent;\n /* Snap cards into position on scroll */\n scroll-snap-type: x mandatory;\n}\n.biq-carousel::-webkit-scrollbar { height: 4px; }\n.biq-carousel::-webkit-scrollbar-track { background: transparent; }\n.biq-carousel::-webkit-scrollbar-thumb { background: #2D2D2D; border-radius: 2px; }\n\n.biq-carousel .biq-card {\n flex: 0 0 200px;\n scroll-snap-align: start;\n max-width: 200px;\n}\n\n/* ── Quick Replies ───────────────────────── */\n.biq-quick-replies {\n display: flex;\n flex-wrap: wrap;\n gap: 6px;\n margin-top: 4px;\n}\n\n.biq-qr-pill {\n padding: 5px 14px;\n border-radius: 20px;\n border: 1.5px solid #F97316;\n background: transparent;\n color: #F97316;\n font: inherit;\n font-size: 13px;\n cursor: pointer;\n transition: background .15s, color .15s;\n white-space: nowrap;\n}\n.biq-qr-pill:hover { background: #F97316; color: #fff; }\n\n/* ── Buttons block ───────────────────────── */\n.biq-buttons {\n display: flex;\n flex-wrap: wrap;\n gap: 6px;\n margin-top: 4px;\n}\n", he = "\n.botiq-confirm-overlay { position:absolute; inset:0; background:rgba(0,0,0,.7);\n display:flex; align-items:center; justify-content:center; z-index:999; }\n.botiq-confirm-dialog { background:#1A1A1A; border:1px solid #2D2D2D; border-radius:12px;\n padding:16px; max-width:320px; color:#fff; font-size:14px; }\n.botiq-confirm-header { font-weight:600; margin-bottom:8px; }\n.botiq-confirm-reason { color:#9CA3AF; margin-bottom:8px; }\n.botiq-confirm-params { background:#0a0a0a; padding:8px; border-radius:6px; font-size:12px;\n max-height:120px; overflow:auto; white-space:pre-wrap; }\n.botiq-confirm-actions { display:flex; gap:8px; margin-top:12px; }\n.botiq-confirm-yes { flex:1; padding:8px 12px; border-radius:6px; border:none;\n background:#F97316; color:#fff; cursor:pointer; }\n.botiq-confirm-yes[data-risk=\"high\"] { background:#DC2626; }\n.botiq-confirm-no { flex:1; padding:8px 12px; border-radius:6px; background:transparent;\n border:1px solid #2D2D2D; color:#fff; cursor:pointer; }\n.botiq-confirm-countdown { margin-top:8px; font-size:12px; color:#9CA3AF; }\n";
603
+ function ge(e) {
604
+ let { colors: t, layout: n, font: r, gradient: i, animation: a, customCSS: o, whiteLabel: s } = e, c = de[r] ?? de.inter, l = n.buttonShape === "square" ? "14px" : "50%", u = n.position === "bottom-left" ? "right: auto; left: 24px;" : "right: 24px;", d = n.position === "bottom-left" ? "bottom left" : "bottom right", f = n.position === "bottom-left" ? "right: auto; left: 0;" : "right: 0;", p = n.fillHeight ? `min(${n.height}px, calc(100dvh - 48px))` : `${n.height}px`, m = H(t.primary, i), h = H(t.header, i), g = H(t.userBubble, i), _ = t.primary.length === 4 ? "#" + t.primary[1].repeat(2) + t.primary[2].repeat(2) + t.primary[3].repeat(2) : t.primary, v = s ? ".botiq-badge { display: none !important; }" : "";
519
605
  return `
520
606
  @import url('${c.url}');
521
607
 
@@ -533,6 +619,7 @@ function me(e) {
533
619
  --color-bg: ${t.background};
534
620
  --color-text: ${t.text};
535
621
  --color-input-bg: ${t.inputBackground};
622
+ --hover-bg: ${_}1A;
536
623
  --gray-50: #1A1A1A;
537
624
  --gray-100: #222222;
538
625
  --gray-200: #2D2D2D;
@@ -670,6 +757,9 @@ function me(e) {
670
757
  }
671
758
  .close-btn:hover { background: rgba(255,255,255,.25); }
672
759
 
760
+ /* Home view: hero banner acts as the header — hide the persistent header bar */
761
+ .chat-window[data-view="home"] .chat-header { display: none; }
762
+
673
763
  /* ── Chat body + panels ─────────────────── */
674
764
  .chat-body { flex: 1; display: flex; flex-direction: column; overflow: hidden; }
675
765
 
@@ -690,12 +780,17 @@ function me(e) {
690
780
  border: none;
691
781
  color: var(--gray-400);
692
782
  font: inherit;
693
- font-size: 12px;
694
- padding: 10px;
783
+ font-size: 11px;
784
+ padding: 8px 10px 10px;
695
785
  cursor: pointer;
696
786
  transition: color .15s;
787
+ display: flex;
788
+ flex-direction: column;
789
+ align-items: center;
790
+ gap: 3px;
697
791
  }
698
792
 
793
+ .nav-btn svg { width: 18px; height: 18px; fill: currentColor; }
699
794
  .nav-btn:hover { color: var(--color-text); }
700
795
  .nav-btn.active { color: var(--color-primary); }
701
796
 
@@ -716,7 +811,7 @@ function me(e) {
716
811
  font: inherit;
717
812
  }
718
813
 
719
- .msg-list-item:hover { background: var(--gray-50); }
814
+ .msg-list-item:hover { background: var(--hover-bg); }
720
815
 
721
816
  .msg-list-avatar {
722
817
  flex-shrink: 0;
@@ -777,35 +872,84 @@ function me(e) {
777
872
 
778
873
  .msg-list-new:hover { background: var(--color-primary); color: #fff; }
779
874
 
780
- /* ── Home panel ─────────────────────────── */
781
- .home-greeting {
782
- font-size: 20px;
783
- font-weight: 600;
784
- color: var(--color-text);
785
- padding: 24px 18px 8px;
875
+ /* ── Home panel hero banner ─────────────── */
876
+ .home-hero {
877
+ background: var(--color-primary);
878
+ padding: 22px 18px 20px;
879
+ flex-shrink: 0;
880
+ }
881
+
882
+ .home-hero-row {
883
+ display: flex;
884
+ align-items: center;
885
+ gap: 12px;
886
+ margin-bottom: 14px;
887
+ }
888
+
889
+ .home-hero-avatar {
890
+ width: 48px;
891
+ height: 48px;
892
+ border-radius: 50%;
893
+ overflow: hidden;
894
+ flex-shrink: 0;
895
+ background: rgba(255,255,255,.2);
896
+ }
897
+
898
+ .home-hero-name {
899
+ font-weight: 700;
900
+ font-size: 15px;
901
+ color: #fff;
902
+ }
903
+
904
+ .home-hero-status {
905
+ font-size: 12px;
906
+ color: rgba(255,255,255,.8);
907
+ margin-top: 2px;
908
+ }
909
+
910
+ .home-hero-greeting {
911
+ font-size: 15px;
912
+ line-height: 1.5;
913
+ color: rgba(255,255,255,.92);
786
914
  }
787
915
 
916
+ .home-hero-close {
917
+ width: 30px;
918
+ height: 30px;
919
+ border-radius: 50%;
920
+ background: rgba(255,255,255,.15);
921
+ border: none;
922
+ cursor: pointer;
923
+ color: #fff;
924
+ font-size: 18px;
925
+ display: flex;
926
+ align-items: center;
927
+ justify-content: center;
928
+ flex-shrink: 0;
929
+ margin-left: auto;
930
+ transition: background .15s;
931
+ }
932
+ .home-hero-close:hover { background: rgba(255,255,255,.25); }
933
+
934
+ /* ── Home panel CTA ─────────────────────── */
788
935
  .home-start {
789
- margin: 8px 18px;
936
+ margin: 14px 18px;
790
937
  padding: 14px;
791
938
  border-radius: 12px;
792
939
  border: 1.5px solid var(--color-primary);
793
940
  background: transparent;
794
941
  color: var(--color-primary);
795
- text-align: left;
942
+ text-align: center;
796
943
  cursor: pointer;
797
944
  font: inherit;
798
945
  font-size: 14px;
799
- font-weight: 500;
946
+ font-weight: 600;
947
+ width: calc(100% - 36px);
800
948
  transition: background .15s, color .15s;
801
949
  }
802
950
 
803
951
  .home-start:hover { background: var(--color-primary); color: #fff; }
804
952
 
805
- .home-status { margin: 8px 18px; font-size: 12px; }
806
- .home-status--online { color: #16A34A; }
807
- .home-status--offline { color: var(--gray-400); }
808
-
809
953
  /* ── Home recent conversations ──────────────── */
810
954
  .home-recent-label {
811
955
  margin: 16px 18px 6px;
@@ -830,7 +974,7 @@ function me(e) {
830
974
  text-align: left;
831
975
  }
832
976
 
833
- .home-recent-item:hover { background: var(--gray-50); }
977
+ .home-recent-item:hover { background: var(--hover-bg); }
834
978
 
835
979
  .home-recent-avatar {
836
980
  flex-shrink: 0;
@@ -1117,9 +1261,11 @@ function me(e) {
1117
1261
  color: var(--color-text);
1118
1262
  opacity: 0.4;
1119
1263
  text-decoration: none;
1120
- margin-top: 6px;
1264
+ padding: 5px 0 7px;
1121
1265
  letter-spacing: 0.02em;
1122
1266
  transition: opacity .15s;
1267
+ background: var(--color-bg);
1268
+ border-top: 1px solid var(--gray-100);
1123
1269
  }
1124
1270
  .botiq-badge:hover { opacity: 0.85; }
1125
1271
  .botiq-badge-name { font-weight: 600; color: var(--color-primary); }
@@ -1250,11 +1396,11 @@ function me(e) {
1250
1396
  }
1251
1397
  .emoji-item:hover { background: var(--gray-100); }
1252
1398
 
1253
- ${_}
1254
- ${de(a)}
1255
- ${o ? ue(o) : ""}
1256
- ${pe}
1257
- ${fe}
1399
+ ${v}
1400
+ ${pe(a)}
1401
+ ${o ? fe(o) : ""}
1402
+ ${he}
1403
+ ${me}
1258
1404
  @media (max-width: 480px) {
1259
1405
  :host { bottom: 0; right: 0; left: 0; }
1260
1406
  .chat-window {
@@ -1282,7 +1428,7 @@ function W(e, t, n) {
1282
1428
  let a = new Date(e);
1283
1429
  return `${U(a.getHours())}:${U(a.getMinutes())}`;
1284
1430
  }
1285
- function he(e, t, n) {
1431
+ function _e(e, t, n) {
1286
1432
  let r = (e) => {
1287
1433
  let t = new Date(e);
1288
1434
  return new Date(t.getFullYear(), t.getMonth(), t.getDate()).getTime();
@@ -1297,7 +1443,7 @@ function he(e, t, n) {
1297
1443
  function G(e) {
1298
1444
  return e.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;").replace(/"/g, "&quot;");
1299
1445
  }
1300
- function ge(e, t, n, r = "") {
1446
+ function ve(e, t, n, r = "") {
1301
1447
  let i = `<button class="msg-list-new" type="button">+ ${G(t.newConversation)}</button>`;
1302
1448
  return e.length === 0 ? `<div class="msg-list-empty">${G(t.noConversations)}</div>${i}` : `<div class="msg-list">${e.map((e) => {
1303
1449
  let i = e.lastMessageAt ? Date.parse(e.lastMessageAt) : n, a = Number.isFinite(i) ? W(i, n, "vi") : "", o = e.escalated ? `<span class="msg-list-badge">${G(t.waitingForHuman)}</span>` : "";
@@ -1311,8 +1457,8 @@ function ge(e, t, n, r = "") {
1311
1457
  </button>`;
1312
1458
  }).join("")}</div>${i}`;
1313
1459
  }
1314
- function _e(e, t, n = [], r = "", i = Date.now()) {
1315
- let a = e.status !== "offline", o = a ? t.statusOnline : t.statusPaused, s = G(e.design.content.greeting || t.homeGreeting), c = "";
1460
+ function ye(e, t, n = [], r = "", i = Date.now()) {
1461
+ let a = e.status === "offline" ? t.statusPaused : t.statusOnline, o = G(e.design.content.greeting || t.homeGreeting), s = "";
1316
1462
  if (n.length > 0) {
1317
1463
  let e = n.slice(0, 3).map((e) => {
1318
1464
  let t = e.lastMessageAt ? Date.parse(e.lastMessageAt) : i, n = Number.isFinite(t) ? W(t, i, "vi") : "";
@@ -1325,18 +1471,27 @@ function _e(e, t, n = [], r = "", i = Date.now()) {
1325
1471
  <span class="home-recent-time">${G(n)}</span>
1326
1472
  </button>`;
1327
1473
  }).join("");
1328
- c = `<div class="home-recent-label">${G(t.recentMessages)}</div>${e}`;
1474
+ s = `<div class="home-recent-label">${G(t.recentMessages)}</div>${e}`;
1329
1475
  }
1330
1476
  return `
1331
- <div class="home-greeting">${s}</div>
1332
- <button class="home-start" type="button">${G(t.startConversation)} ›</button>
1333
- ${c}
1334
- <div class="home-status home-status--${a ? "online" : "offline"}">● ${G(o)}</div>
1477
+ <div class="home-hero">
1478
+ <div class="home-hero-row">
1479
+ ${r ? `<div class="home-hero-avatar">${r}</div>` : ""}
1480
+ <div>
1481
+ <div class="home-hero-name">${G(e.name)}</div>
1482
+ <div class="home-hero-status">● ${G(a)}</div>
1483
+ </div>
1484
+ <button class="home-hero-close" type="button" aria-label="${G(t.ariaCloseChat)}">×</button>
1485
+ </div>
1486
+ <div class="home-hero-greeting">${o}</div>
1487
+ </div>
1488
+ <button class="home-start" type="button">${G(t.startConversation)}</button>
1489
+ ${s}
1335
1490
  `;
1336
1491
  }
1337
1492
  //#endregion
1338
1493
  //#region src/core/assets.ts
1339
- var ve = "data:image/png;base64,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";
1494
+ var be = "data:image/png;base64,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";
1340
1495
  //#endregion
1341
1496
  //#region src/core/history-pager.ts
1342
1497
  function K() {
@@ -1346,24 +1501,24 @@ function K() {
1346
1501
  cursorReady: !1
1347
1502
  };
1348
1503
  }
1349
- function ye(e) {
1504
+ function xe(e) {
1350
1505
  return {
1351
1506
  oldestCursor: e.messages[0]?.id ?? null,
1352
1507
  hasMore: e.hasMore,
1353
1508
  cursorReady: e.messages.length > 0
1354
1509
  };
1355
1510
  }
1356
- function be(e, t) {
1511
+ function Se(e, t) {
1357
1512
  return {
1358
1513
  oldestCursor: t.messages[0]?.id ?? e.oldestCursor,
1359
1514
  hasMore: t.hasMore,
1360
1515
  cursorReady: e.cursorReady
1361
1516
  };
1362
1517
  }
1363
- function xe(e, t) {
1518
+ function Ce(e, t) {
1364
1519
  return e.cursorReady && e.hasMore && !t && e.oldestCursor !== null;
1365
1520
  }
1366
- function Se(e, t, n) {
1521
+ function we(e, t, n) {
1367
1522
  return e + (n - t);
1368
1523
  }
1369
1524
  //#endregion
@@ -1371,7 +1526,7 @@ function Se(e, t, n) {
1371
1526
  function q(e) {
1372
1527
  return e.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;").replace(/"/g, "&quot;").replace(/'/g, "&#x27;");
1373
1528
  }
1374
- function Ce(e, t) {
1529
+ function Te(e, t) {
1375
1530
  let n = t.labels?.confirm ?? "Đồng ý", r = t.labels?.cancel ?? "Huỷ", i = t.labels?.countdownPrefix ?? "Tự động xác nhận sau ", a = t.labels?.countdownSuffix ?? "s…";
1376
1531
  return new Promise((o) => {
1377
1532
  let s = document.createElement("div");
@@ -1401,15 +1556,15 @@ function Ce(e, t) {
1401
1556
  }
1402
1557
  //#endregion
1403
1558
  //#region src/core/emoji.ts
1404
- function we(e, t) {
1559
+ function Ee(e, t) {
1405
1560
  let n = e.selectionStart ?? e.value.length, r = e.selectionEnd ?? e.value.length;
1406
1561
  e.value = e.value.slice(0, n) + t + e.value.slice(r), e.selectionStart = e.selectionEnd = n + t.length, e.dispatchEvent(new Event("input", { bubbles: !0 }));
1407
1562
  }
1408
1563
  var J = null;
1409
- async function Te() {
1564
+ async function De() {
1410
1565
  return J || (J = (await import("./emoji-data-DWiYsBZI.js")).EMOJIS, J);
1411
1566
  }
1412
- function Ee(e) {
1567
+ function Oe(e) {
1413
1568
  let t = document.createElement("button");
1414
1569
  t.type = "button", t.className = "emoji-btn", t.setAttribute("aria-label", "Emoji"), t.textContent = "🙂";
1415
1570
  let n = document.createElement("div");
@@ -1417,7 +1572,7 @@ function Ee(e) {
1417
1572
  let r = !1;
1418
1573
  return t.addEventListener("click", async () => {
1419
1574
  if (!r) {
1420
- let t = await Te();
1575
+ let t = await De();
1421
1576
  for (let r of t) {
1422
1577
  let t = document.createElement("button");
1423
1578
  t.type = "button", t.className = "emoji-item", t.textContent = r, t.addEventListener("click", () => {
@@ -1440,7 +1595,7 @@ function Y(e) {
1440
1595
  function X(e) {
1441
1596
  return /^https?:\/\//i.test(e) ? e : "";
1442
1597
  }
1443
- function De(e) {
1598
+ function ke(e) {
1444
1599
  let t = Y(e.label), n = Y(e.value), r = Y(e.action);
1445
1600
  if (e.action === "url") {
1446
1601
  let n = X(e.value);
@@ -1448,51 +1603,51 @@ function De(e) {
1448
1603
  }
1449
1604
  return `<button class="biq-btn biq-btn--${r}" type="button" data-action="${r}" data-value="${n}">${t}</button>`;
1450
1605
  }
1451
- function Oe(e) {
1606
+ function Ae(e) {
1452
1607
  let t = `${e.imageUrl ? (() => {
1453
1608
  let t = X(e.imageUrl);
1454
1609
  return t ? `<img class="biq-card-img" src="${Y(t)}" alt="" loading="lazy" />` : "";
1455
- })() : ""}${`<div class="biq-card-title">${Y(e.title)}</div>`}${e.subtitle ? `<div class="biq-card-subtitle">${Y(e.subtitle)}</div>` : ""}${e.price ? `<div class="biq-card-price">${Y(e.price)}</div>` : ""}${e.buttons && e.buttons.length > 0 ? `<div class="biq-card-btns">${e.buttons.map(De).join("")}</div>` : ""}`;
1610
+ })() : ""}${`<div class="biq-card-title">${Y(e.title)}</div>`}${e.subtitle ? `<div class="biq-card-subtitle">${Y(e.subtitle)}</div>` : ""}${e.price ? `<div class="biq-card-price">${Y(e.price)}</div>` : ""}${e.buttons && e.buttons.length > 0 ? `<div class="biq-card-btns">${e.buttons.map(ke).join("")}</div>` : ""}`;
1456
1611
  if (e.url) {
1457
1612
  let n = X(e.url);
1458
1613
  if (n) return `<a class="biq-card biq-card--link" href="${Y(n)}" target="_blank" rel="noopener noreferrer">${t}</a>`;
1459
1614
  }
1460
1615
  return `<div class="biq-card">${t}</div>`;
1461
1616
  }
1462
- function ke(e) {
1463
- return `<div class="biq-carousel">${e.cards.map(Oe).join("")}</div>`;
1617
+ function je(e) {
1618
+ return `<div class="biq-carousel">${e.cards.map(Ae).join("")}</div>`;
1464
1619
  }
1465
- function Ae(e) {
1620
+ function Me(e) {
1466
1621
  return `<div class="biq-quick-replies">${e.replies.map((e) => {
1467
1622
  let t = Y(e.label);
1468
1623
  return `<button class="biq-qr-pill" type="button" data-qr="1" data-value="${Y(e.value)}">${t}</button>`;
1469
1624
  }).join("")}</div>`;
1470
1625
  }
1471
- function je(e) {
1472
- return `<div class="biq-buttons">${e.buttons.map(De).join("")}</div>`;
1626
+ function Ne(e) {
1627
+ return `<div class="biq-buttons">${e.buttons.map(ke).join("")}</div>`;
1473
1628
  }
1474
- function Me(e) {
1629
+ function Pe(e) {
1475
1630
  return !e || e.length === 0 ? "" : e.map((e) => {
1476
1631
  switch (e.type) {
1477
- case "card": return Oe(e);
1478
- case "carousel": return ke(e);
1479
- case "quick_replies": return Ae(e);
1480
- case "buttons": return je(e);
1632
+ case "card": return Ae(e);
1633
+ case "carousel": return je(e);
1634
+ case "quick_replies": return Me(e);
1635
+ case "buttons": return Ne(e);
1481
1636
  default: return "";
1482
1637
  }
1483
1638
  }).join("");
1484
1639
  }
1485
1640
  //#endregion
1486
1641
  //#region src/core/ui.ts
1487
- var Ne = "https://bot-q-frontend.vercel.app/", Pe = "<svg viewBox=\"0 0 24 24\" xmlns=\"http://www.w3.org/2000/svg\">\n <path d=\"M20 2H4a2 2 0 00-2 2v18l4-4h14a2 2 0 002-2V4a2 2 0 00-2-2z\"/>\n</svg>", Fe = "<svg viewBox=\"0 0 24 24\" xmlns=\"http://www.w3.org/2000/svg\">\n <path d=\"M19 6.41L17.59 5 12 10.59 6.41 5 5 6.41 10.59 12 5 17.59 6.41 19 12 13.41 17.59 19 19 17.59 13.41 12z\"/>\n</svg>", Ie = `<img src="${ve}" alt="" style="width:100%;height:100%;object-fit:cover;border-radius:50%" />`, Le = "<svg viewBox=\"0 0 24 24\" xmlns=\"http://www.w3.org/2000/svg\">\n <path d=\"M2.01 21L23 12 2.01 3 2 10l15 2-15 2z\"/>\n</svg>", Re = "<svg viewBox=\"0 0 24 24\" xmlns=\"http://www.w3.org/2000/svg\">\n <path d=\"M20 2H4a2 2 0 00-2 2v18l4-4h14a2 2 0 002-2V4a2 2 0 00-2-2zm-2 10H6v-2h12v2zm0-3H6V7h12v2z\"/>\n</svg>", ze = "<svg viewBox=\"0 0 24 24\" xmlns=\"http://www.w3.org/2000/svg\">\n <path d=\"M21.44 11.05l-9.19 9.19a6 6 0 01-8.49-8.49l9.19-9.19a4 4 0 015.66 5.66l-9.2 9.19a2 2 0 01-2.83-2.83l8.49-8.48\"/>\n</svg>";
1488
- function Be(e) {
1489
- if (!e || e.type === "icon") return Ie;
1642
+ var Fe = "https://bot-q-frontend.vercel.app/", Ie = "<svg viewBox=\"0 0 24 24\" xmlns=\"http://www.w3.org/2000/svg\">\n <path d=\"M20 2H4a2 2 0 00-2 2v18l4-4h14a2 2 0 002-2V4a2 2 0 00-2-2z\"/>\n</svg>", Le = "<svg viewBox=\"0 0 24 24\" xmlns=\"http://www.w3.org/2000/svg\">\n <path d=\"M19 6.41L17.59 5 12 10.59 6.41 5 5 6.41 10.59 12 5 17.59 6.41 19 12 13.41 17.59 19 19 17.59 13.41 12z\"/>\n</svg>", Re = `<img src="${be}" alt="" style="width:100%;height:100%;object-fit:cover;border-radius:50%" />`, ze = "<svg viewBox=\"0 0 24 24\" xmlns=\"http://www.w3.org/2000/svg\">\n <path d=\"M2.01 21L23 12 2.01 3 2 10l15 2-15 2z\"/>\n</svg>", Be = "<svg viewBox=\"0 0 24 24\" xmlns=\"http://www.w3.org/2000/svg\">\n <path d=\"M20 2H4a2 2 0 00-2 2v18l4-4h14a2 2 0 002-2V4a2 2 0 00-2-2zm-2 10H6v-2h12v2zm0-3H6V7h12v2z\"/>\n</svg>", Ve = "<svg viewBox=\"0 0 24 24\" xmlns=\"http://www.w3.org/2000/svg\">\n <path d=\"M21.44 11.05l-9.19 9.19a6 6 0 01-8.49-8.49l9.19-9.19a4 4 0 015.66 5.66l-9.2 9.19a2 2 0 01-2.83-2.83l8.49-8.48\"/>\n</svg>", He = "<svg viewBox=\"0 0 24 24\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M10 20v-6h4v6h5v-8h3L12 3 2 12h3v8z\"/></svg>", Ue = "<svg viewBox=\"0 0 24 24\" xmlns=\"http://www.w3.org/2000/svg\"><path d=\"M20 2H4c-1.1 0-2 .9-2 2v18l4-4h14c1.1 0 2-.9 2-2V4c0-1.1-.9-2-2-2z\"/></svg>";
1643
+ function We(e) {
1644
+ if (!e || e.type === "icon") return Re;
1490
1645
  if (e.type === "emoji") return `<span style="font-size:22px;line-height:1;display:flex;align-items:center;justify-content:center;width:100%;height:100%">${Z(e.value)}</span>`;
1491
1646
  if (e.type === "initials") {
1492
1647
  let t = e.bgColor ?? "#F97316";
1493
1648
  return `<div style="width:100%;height:100%;border-radius:50%;background:${/^#[0-9A-Fa-f]{3,6}$/.test(t) ? t : "#F97316"};display:flex;align-items:center;justify-content:center;font-size:14px;font-weight:700;color:#fff">${Z(e.value.slice(0, 2).toUpperCase())}</div>`;
1494
1649
  }
1495
- return e.type === "image" ? `<img src="${Z(e.value)}" style="width:100%;height:100%;object-fit:cover;border-radius:50%" alt="" />` : Ie;
1650
+ return e.type === "image" ? `<img src="${Z(e.value)}" style="width:100%;height:100%;object-fit:cover;border-radius:50%" alt="" />` : Re;
1496
1651
  }
1497
1652
  function Z(e) {
1498
1653
  return e.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;").replace(/"/g, "&quot;").replace(/'/g, "&#x27;");
@@ -1501,27 +1656,27 @@ function Q(e) {
1501
1656
  let t = [];
1502
1657
  return e = e.replace(/`([^`]+)`/g, (e, n) => (t.push(`<code>${n}</code>`), `\x00CODE${t.length - 1}\x00`)), e = e.replace(/\*\*\*(.+?)\*\*\*/g, "<strong><em>$1</em></strong>"), e = e.replace(/\*\*(.+?)\*\*/g, "<strong>$1</strong>"), e = e.replace(/(?<!\*)\*(?!\*)(.+?)(?<!\*)\*(?!\*)/g, "<em>$1</em>"), e = e.replace(/~~(.+?)~~/g, "<del>$1</del>"), e = e.replace(/__(.+?)__/g, "<strong>$1</strong>"), e = e.replace(/(^|\s)_(?!_)(.+?)_(?!_)(?=\s|$)/g, "$1<em>$2</em>"), e = e.replace(/\[([^\]]+)\]\(([^()]*(?:\([^()]*\))*[^()]*)\)/g, (e, t, n) => /^https?:\/\//.test(n) ? `<a href="${n}" target="_blank" rel="noopener noreferrer">${t}</a>` : t), e = e.replace(/\x00CODE(\d+)\x00/g, (e, n) => t[Number(n)]), e;
1503
1658
  }
1504
- function Ve(e) {
1659
+ function Ge(e) {
1505
1660
  return /^\|[\s\-:|]+\|$/.test(e);
1506
1661
  }
1507
- function He(e) {
1662
+ function Ke(e) {
1508
1663
  return e.replace(/^\|/, "").replace(/\|$/, "").split("|").map((e) => e.trim());
1509
1664
  }
1510
- function Ue(e, t) {
1665
+ function qe(e, t) {
1511
1666
  return e ? `<div class="handoff-banner">⏳ ${Z(t.waitingForHuman)}</div>` : "";
1512
1667
  }
1513
- function We(e) {
1668
+ function Je(e) {
1514
1669
  return e <= 0 ? "" : `<span class="unread-badge">${e > 9 ? "9+" : String(e)}</span>`;
1515
1670
  }
1516
- function Ge(e) {
1671
+ function Ye(e) {
1517
1672
  let t = Z(e).replace(/\x00/g, "").split("\n"), n = [], r = 0;
1518
1673
  for (; r < t.length;) {
1519
1674
  let e = t[r].trim();
1520
1675
  if (e.startsWith("|") && e.endsWith("|")) {
1521
1676
  let e = [];
1522
1677
  for (; r < t.length && t[r].trim().startsWith("|") && t[r].trim().endsWith("|");) e.push(t[r].trim()), r++;
1523
- let i = e.findIndex(Ve), a = i > 0 ? e.slice(0, i) : [], o = i >= 0 ? e.slice(i + 1) : e, s = "<table>";
1524
- a.length > 0 && (s += "<thead>" + a.map((e) => "<tr>" + He(e).map((e) => `<th>${Q(e)}</th>`).join("") + "</tr>").join("") + "</thead>"), o.length > 0 && (s += "<tbody>" + o.map((e) => "<tr>" + He(e).map((e) => `<td>${Q(e)}</td>`).join("") + "</tr>").join("") + "</tbody>"), s += "</table>", n.push(s);
1678
+ let i = e.findIndex(Ge), a = i > 0 ? e.slice(0, i) : [], o = i >= 0 ? e.slice(i + 1) : e, s = "<table>";
1679
+ a.length > 0 && (s += "<thead>" + a.map((e) => "<tr>" + Ke(e).map((e) => `<th>${Q(e)}</th>`).join("") + "</tr>").join("") + "</thead>"), o.length > 0 && (s += "<tbody>" + o.map((e) => "<tr>" + Ke(e).map((e) => `<td>${Q(e)}</td>`).join("") + "</tr>").join("") + "</tbody>"), s += "</table>", n.push(s);
1525
1680
  continue;
1526
1681
  }
1527
1682
  if (/^-{3,}$/.test(e)) {
@@ -1555,41 +1710,41 @@ function Ge(e) {
1555
1710
  for (; n.length > 0 && n[n.length - 1] === "<br>";) n.pop();
1556
1711
  return n.join("");
1557
1712
  }
1558
- function Ke(e, t) {
1713
+ function Xe(e, t) {
1559
1714
  let { strings: n, content: r, botName: i, lang: a, now: o, contactInfo: s, richMessages: c } = t;
1560
1715
  if (e.messages.length === 0 && !e.isLoading) {
1561
1716
  let e = r.suggestionChips.length > 0 ? `<div class="chips">${r.suggestionChips.map((e) => `<button class="chip">${Z(e)}</button>`).join("")}</div>` : "";
1562
1717
  return `
1563
1718
  <div class="empty-state">
1564
- ${Re}
1719
+ ${Be}
1565
1720
  <span class="greeting">${Z(r.greeting || n.defaultGreeting)}</span>
1566
1721
  ${e}
1567
1722
  </div>
1568
1723
  `;
1569
1724
  }
1570
1725
  let l = "", u = e.messages.map((e) => {
1571
- let t = e.ts ?? o, r = he(t, o, a), u = r === l ? "" : `<div class="day-sep"><span>${Z(r)}</span></div>`;
1726
+ let t = e.ts ?? o, r = _e(t, o, a), u = r === l ? "" : `<div class="day-sep"><span>${Z(r)}</span></div>`;
1572
1727
  l = r;
1573
- let d = e.role === "assistant" ? Ge(e.content) : Z(e.content), f = e.role === "assistant" && !e.error ? `<div class="msg-meta">${Z(i)} · ${Z(W(t, o, a))}</div>` : "", p = e.error ? `<button class="retry-btn" type="button">↻ ${Z(n.retry)}</button>` : "", m = e.error && s ? `<div class="msg-contact">${Z(s)}</div>` : "", h = c && e.role === "assistant" && !e.error && e.blocks && e.blocks.length > 0 ? `<div class="biq-blocks">${Me(e.blocks)}</div>` : "";
1728
+ let d = e.role === "assistant" ? Ye(e.content) : Z(e.content), f = e.role === "assistant" && !e.error ? `<div class="msg-meta">${Z(i)} · ${Z(W(t, o, a))}</div>` : "", p = e.error ? `<button class="retry-btn" type="button">↻ ${Z(n.retry)}</button>` : "", m = e.error && s ? `<div class="msg-contact">${Z(s)}</div>` : "", h = c && e.role === "assistant" && !e.error && e.blocks && e.blocks.length > 0 ? `<div class="biq-blocks">${Pe(e.blocks)}</div>` : "";
1574
1729
  return `${u}<div class="${`message ${e.role}${e.error ? " error" : ""}`}"><div class="message-bubble">${d}</div>${p}${m}${f}${h}</div>`;
1575
1730
  }).join(""), d = e.loadingOlder ? "<div class=\"typing\"><span></span><span></span><span></span></div>" : "", f = e.isLoading ? "<div class=\"typing\"><span></span><span></span><span></span></div>" : "";
1576
1731
  return d + u + f;
1577
1732
  }
1578
- function qe(e, t, n, r) {
1579
- let { name: i, design: a } = t, o, s, c, l, u, d, f, p, m, h, g, _, v = null, y = null, b = null, { content: x } = a, S = t.imageInput === !0, C = Be(a.avatar), w = null;
1733
+ function Ze(e, t, n, r) {
1734
+ let { name: i, design: a } = t, o, s, c, l, u, d, f, p, m, h, g, _, v = null, y = null, b = null, { content: x } = a, S = t.imageInput === !0, C = We(a.avatar), w = null;
1580
1735
  function T(e) {
1581
1736
  e.setAttribute("data-position", a.layout.position), o = e.attachShadow({ mode: "closed" });
1582
1737
  let w = document.createElement("style");
1583
- w.textContent = me(a), o.appendChild(w), s = document.createElement("button"), s.className = "bubble", s.setAttribute("aria-label", n.ariaOpenChat), s.innerHTML = `
1584
- <span class="icon-chat">${Pe}</span>
1585
- <span class="icon-close">${Fe}</span>
1738
+ w.textContent = ge(a), o.appendChild(w), s = document.createElement("button"), s.className = "bubble", s.setAttribute("aria-label", n.ariaOpenChat), s.innerHTML = `
1739
+ <span class="icon-chat">${Ie}</span>
1740
+ <span class="icon-close">${Le}</span>
1586
1741
  <span class="unread-badge-slot"></span>
1587
1742
  `, s.addEventListener("click", () => r.onToggle()), o.appendChild(s), c = document.createElement("div"), c.className = "chat-window", c.setAttribute("role", "dialog"), c.setAttribute("aria-label", `${i} chat`), c.innerHTML = `
1588
1743
  <div class="chat-header">
1589
- <div class="avatar">${Be(a.avatar)}</div>
1744
+ <div class="avatar">${We(a.avatar)}</div>
1590
1745
  <div class="header-text">
1591
1746
  <span class="bot-name">${Z(i)}</span>
1592
- <span class="bot-status">${Z(n.statusOnline)}</span>
1747
+ <span class="bot-status">${Z(t.status === "offline" ? n.statusPaused : n.statusOnline)}</span>
1593
1748
  </div>
1594
1749
  <button class="close-btn" aria-label="${Z(n.ariaCloseChat)}">×</button>
1595
1750
  </div>
@@ -1602,7 +1757,7 @@ function qe(e, t, n, r) {
1602
1757
  <div class="chat-footer">
1603
1758
  <div class="attach-preview-slot"></div>
1604
1759
  <div class="input-row">
1605
- ${S ? `<button class="attach-btn" type="button" aria-label="${Z(n.imageAttach)}">${ze}</button>` : ""}
1760
+ ${S ? `<button class="attach-btn" type="button" aria-label="${Z(n.imageAttach)}">${Ve}</button>` : ""}
1606
1761
  <textarea
1607
1762
  class="input"
1608
1763
  placeholder="${Z(x.placeholder || n.inputPlaceholder)}"
@@ -1611,20 +1766,22 @@ function qe(e, t, n, r) {
1611
1766
  aria-label="Message input"
1612
1767
  ></textarea>
1613
1768
  <button class="send-btn" aria-label="${Z(n.ariaSendMessage)}">
1614
- ${Le}
1769
+ ${ze}
1615
1770
  </button>
1616
1771
  </div>
1617
- <a class="botiq-badge" href="${Ne}" target="_blank" rel="noopener noreferrer">
1618
- ${Z(n.poweredBy)} <span class="botiq-badge-name">BotIQ</span>
1619
- </a>
1620
1772
  </div>
1621
1773
  </div>
1622
1774
  </div>
1623
1775
  <div class="bottom-nav">
1624
- <button class="nav-btn" data-view="home">⌂ ${Z(n.navHome)}</button>
1625
- <button class="nav-btn" data-view="messages">💬 ${Z(n.navMessages)}</button>
1776
+ <button class="nav-btn" data-view="home">${He}<span>${Z(n.navHome)}</span></button>
1777
+ <button class="nav-btn" data-view="messages">${Ue}<span>${Z(n.navMessages)}</span></button>
1626
1778
  </div>
1627
- `, c.querySelector(".close-btn").addEventListener("click", () => r.onToggle()), l = c.querySelector(".panel-home"), u = c.querySelector(".panel-messages"), d = c.querySelector(".panel-conversation"), l.innerHTML = _e(t, n, [], C), l.querySelector(".home-start")?.addEventListener("click", () => {
1779
+ <a class="botiq-badge" href="${Fe}" target="_blank" rel="noopener noreferrer">
1780
+ ${Z(n.poweredBy)} <span class="botiq-badge-name">BotIQ</span>
1781
+ </a>
1782
+ `, c.querySelector(".close-btn").addEventListener("click", () => r.onToggle()), l = c.querySelector(".panel-home"), u = c.querySelector(".panel-messages"), d = c.querySelector(".panel-conversation"), l.innerHTML = ye(t, n, [], C), l.querySelector(".home-hero-close")?.addEventListener("click", () => {
1783
+ r.onToggle();
1784
+ }), l.querySelector(".home-start")?.addEventListener("click", () => {
1628
1785
  r.onNewConversation();
1629
1786
  }), f = c.querySelector(".nav-btn[data-view=\"home\"]"), p = c.querySelector(".nav-btn[data-view=\"messages\"]"), c.querySelectorAll(".nav-btn").forEach((e) => {
1630
1787
  e.addEventListener("click", () => {
@@ -1642,8 +1799,8 @@ function qe(e, t, n, r) {
1642
1799
  }), g.addEventListener("keydown", (e) => {
1643
1800
  e.key === "Enter" && !e.shiftKey && (e.preventDefault(), E());
1644
1801
  }), _.addEventListener("click", E);
1645
- let D = c.querySelector(".input-row"), { button: O, panel: k } = Ee((e) => {
1646
- we(g, e), g.focus();
1802
+ let D = c.querySelector(".input-row"), { button: O, panel: k } = Oe((e) => {
1803
+ Ee(g, e), g.focus();
1647
1804
  });
1648
1805
  D.insertBefore(O, _), c.querySelector(".chat-footer").appendChild(k), y = c.querySelector(".attach-preview-slot"), S && (v = c.querySelector(".attach-btn"), v && (b = document.createElement("input"), b.type = "file", b.accept = "image/jpeg,image/png,image/webp", b.style.display = "none", b.setAttribute("aria-hidden", "true"), o.appendChild(b), v.addEventListener("click", () => {
1649
1806
  b?.click();
@@ -1658,7 +1815,7 @@ function qe(e, t, n, r) {
1658
1815
  }
1659
1816
  function D(e) {
1660
1817
  let a = m.scrollHeight - m.scrollTop - m.clientHeight < 80, o = m.scrollTop, s = m.scrollHeight;
1661
- m.innerHTML = Ke(e, {
1818
+ m.innerHTML = Xe(e, {
1662
1819
  strings: n,
1663
1820
  content: x,
1664
1821
  botName: i,
@@ -1696,12 +1853,12 @@ function qe(e, t, n, r) {
1696
1853
  n && (n.style.display = "none");
1697
1854
  }
1698
1855
  });
1699
- }), a ? m.scrollTop = m.scrollHeight : m.scrollTop = Se(o, s, m.scrollHeight);
1856
+ }), a ? m.scrollTop = m.scrollHeight : m.scrollTop = we(o, s, m.scrollHeight);
1700
1857
  }
1701
1858
  function O(e) {
1702
1859
  e.isOpen ? (c.classList.add("open"), s.classList.add("open"), s.setAttribute("aria-label", n.ariaCloseChat), e.view === "conversation" && requestAnimationFrame(() => g.focus())) : (c.classList.remove("open"), s.classList.remove("open"), s.setAttribute("aria-label", n.ariaOpenChat));
1703
1860
  let i = s.querySelector(".unread-badge-slot");
1704
- if (i && (i.innerHTML = We(e.unreadCount)), _.disabled = e.isLoading || e.isUploading, y && S) if (e.pendingAttachment) {
1861
+ if (i && (i.innerHTML = Je(e.unreadCount)), _.disabled = e.isLoading || e.isUploading, y && S) if (e.pendingAttachment) {
1705
1862
  let t = e.pendingAttachment, i = e.isUploading, a = e.uploadError;
1706
1863
  y.innerHTML = `
1707
1864
  <div class="attach-preview">
@@ -1721,7 +1878,9 @@ function qe(e, t, n, r) {
1721
1878
  if (c.dataset.view = e.view, l.classList.toggle("active", e.view === "home"), u.classList.toggle("active", e.view === "messages"), d.classList.toggle("active", e.view === "conversation"), f.classList.toggle("active", e.view === "home"), p.classList.toggle("active", e.view === "messages"), e.view === "home" && e.conversations !== w) {
1722
1879
  w = e.conversations;
1723
1880
  let i = Date.now();
1724
- l.innerHTML = _e(t, n, e.conversations, C, i), l.querySelector(".home-start")?.addEventListener("click", () => {
1881
+ l.innerHTML = ye(t, n, e.conversations, C, i), l.querySelector(".home-hero-close")?.addEventListener("click", () => {
1882
+ r.onToggle();
1883
+ }), l.querySelector(".home-start")?.addEventListener("click", () => {
1725
1884
  r.onNewConversation();
1726
1885
  }), l.querySelectorAll(".home-recent-item").forEach((e) => {
1727
1886
  e.addEventListener("click", () => {
@@ -1730,7 +1889,7 @@ function qe(e, t, n, r) {
1730
1889
  });
1731
1890
  });
1732
1891
  }
1733
- e.view === "conversation" && (D(e), h.innerHTML = Ue(e.escalated, n)), e.view === "messages" && (u.innerHTML = ge(e.conversations, n, Date.now(), C), u.querySelectorAll(".msg-list-item").forEach((e) => {
1892
+ e.view === "conversation" && (D(e), h.innerHTML = qe(e.escalated, n)), e.view === "messages" && (u.innerHTML = ve(e.conversations, n, Date.now(), C), u.querySelectorAll(".msg-list-item").forEach((e) => {
1734
1893
  e.addEventListener("click", () => {
1735
1894
  let t = e.dataset.session;
1736
1895
  t && r.onOpenConversation(t);
@@ -1740,7 +1899,7 @@ function qe(e, t, n, r) {
1740
1899
  }));
1741
1900
  }
1742
1901
  function k(e) {
1743
- return Ce(o, {
1902
+ return Te(o, {
1744
1903
  ...e,
1745
1904
  labels: {
1746
1905
  confirm: n.confirmYes,
@@ -1758,7 +1917,7 @@ function qe(e, t, n, r) {
1758
1917
  }
1759
1918
  //#endregion
1760
1919
  //#region src/i18n/vi.ts
1761
- var Je = {
1920
+ var Qe = {
1762
1921
  statusOnline: "Trực tuyến",
1763
1922
  statusPaused: "Tạm ngừng",
1764
1923
  navHome: "Trang chủ",
@@ -1799,7 +1958,7 @@ var Je = {
1799
1958
  imageUploadTooLarge: "Ảnh quá lớn (tối đa 5 MB sau khi nén).",
1800
1959
  imageUploadRateLimit: "Gửi quá nhanh. Vui lòng thử lại.",
1801
1960
  imageUploadError: "Tải ảnh thất bại. Vui lòng thử lại."
1802
- }, Ye = {
1961
+ }, $e = {
1803
1962
  statusOnline: "Online",
1804
1963
  statusPaused: "Paused",
1805
1964
  navHome: "Home",
@@ -1843,20 +2002,20 @@ var Je = {
1843
2002
  };
1844
2003
  //#endregion
1845
2004
  //#region src/i18n/index.ts
1846
- function Xe(e) {
1847
- return e === "en" ? Ye : Je;
2005
+ function et(e) {
2006
+ return e === "en" ? $e : Qe;
1848
2007
  }
1849
2008
  //#endregion
1850
2009
  //#region src/core/declarative-executor.ts
1851
- var Ze = /^[a-zA-Z0-9_-]*$/;
1852
- function Qe(e, t) {
2010
+ var tt = /^[a-zA-Z0-9_-]*$/;
2011
+ function nt(e, t) {
1853
2012
  return e.replace(/\{([a-zA-Z][a-zA-Z0-9_]*)\}/g, (e, n) => {
1854
2013
  let r = t[n], i = r == null ? "" : String(r);
1855
- if (!Ze.test(i)) throw Error(`Unsafe param value for "${n}"`);
2014
+ if (!tt.test(i)) throw Error(`Unsafe param value for "${n}"`);
1856
2015
  return i;
1857
2016
  });
1858
2017
  }
1859
- function $e(e, t) {
2018
+ function rt(e, t) {
1860
2019
  let n = typeof location < "u" ? location.origin : "https://placeholder.local", r, i;
1861
2020
  try {
1862
2021
  r = new URL(e, n), i = new URL(t.replace(/\{[a-zA-Z][a-zA-Z0-9_]*\}/g, "x"), n);
@@ -1866,10 +2025,10 @@ function $e(e, t) {
1866
2025
  if (!/^https?:$/.test(r.protocol)) throw Error("Navigation must be http(s)");
1867
2026
  if (r.origin !== i.origin) throw Error("Navigation origin not allowed");
1868
2027
  }
1869
- async function et(e, t) {
2028
+ async function it(e, t) {
1870
2029
  let n = e.config;
1871
2030
  if (e.operation === "click") {
1872
- let e = Qe(String(n.selectorTemplate ?? ""), t), r = document.querySelector(e);
2031
+ let e = nt(String(n.selectorTemplate ?? ""), t), r = document.querySelector(e);
1873
2032
  if (!r) throw Error(`No element for selector: ${e}`);
1874
2033
  r.click();
1875
2034
  return;
@@ -1884,15 +2043,15 @@ async function et(e, t) {
1884
2043
  return;
1885
2044
  }
1886
2045
  if (e.operation === "navigate") {
1887
- let e = String(n.urlTemplate ?? ""), r = Qe(e, t);
1888
- $e(r, e), location.assign(r);
2046
+ let e = String(n.urlTemplate ?? ""), r = nt(e, t);
2047
+ rt(r, e), location.assign(r);
1889
2048
  return;
1890
2049
  }
1891
2050
  throw Error(`Unknown operation: ${String(e.operation)}`);
1892
2051
  }
1893
2052
  //#endregion
1894
2053
  //#region src/core/page-action-executor.ts
1895
- async function tt(e, t) {
2054
+ async function at(e, t) {
1896
2055
  let n = t.registry.get(e.actionName);
1897
2056
  if (!n) return {
1898
2057
  status: "unknown",
@@ -1917,26 +2076,26 @@ async function tt(e, t) {
1917
2076
  //#endregion
1918
2077
  //#region src/builds/npm/index.ts
1919
2078
  var $ = 10;
1920
- function nt(e) {
1921
- if (D.setDeclarativeRunner(et), typeof window < "u" && (window.botiq = window.botiq ?? {}, window.botiq.registerActions = (e) => D.register(e)), !e.apiKey) return console.warn("[BotIQ] apiKey is required"), () => void 0;
2079
+ function ot(e) {
2080
+ if (D.setDeclarativeRunner(it), typeof window < "u" && (window.botiq = window.botiq ?? {}, window.botiq.registerActions = (e) => D.register(e)), !e.apiKey) return console.warn("[BotIQ] apiKey is required"), () => void 0;
1922
2081
  let t = p(e);
1923
2082
  y();
1924
2083
  let n = t.apiKey.slice(-16), r = C(), i = b(n), a = x(n, i);
1925
- I({
2084
+ R({
1926
2085
  messages: a,
1927
2086
  view: "home",
1928
2087
  currentSessionId: i
1929
2088
  });
1930
2089
  let o = K(), s = document.createElement("div");
1931
2090
  document.body.appendChild(s);
1932
- let c = () => void 0, l = !1, u = Xe(void 0), d = null, m = null, h = null, g = null;
2091
+ let c = () => void 0, l = !1, u = et(void 0), d = null, m = null, h = null, g = null;
1933
2092
  function _() {
1934
2093
  g ||= setTimeout(async () => {
1935
- if (g = null, !(!F().escalated || !F().isOpen)) try {
1936
- let e = await M(t.apiUrl, t.apiKey, F().currentSessionId, $, r);
1937
- e.messages.length > 0 && I({ messages: e.messages.map(j) }), I({ escalated: e.escalated === !0 });
2094
+ if (g = null, !(!L().escalated || !L().isOpen)) try {
2095
+ let e = await P(t.apiUrl, t.apiKey, L().currentSessionId, $, r);
2096
+ e.messages.length > 0 && R({ messages: e.messages.map(M) }), R({ escalated: e.escalated === !0 });
1938
2097
  } catch {} finally {
1939
- F().escalated && F().isOpen && _();
2098
+ L().escalated && L().isOpen && _();
1940
2099
  }
1941
2100
  }, 1e4);
1942
2101
  }
@@ -1946,23 +2105,23 @@ function nt(e) {
1946
2105
  console.warn("[BotIQ] Widget not authorised on this origin — skipped mount"), s.remove();
1947
2106
  return;
1948
2107
  }
1949
- h = e, u = Xe(e.widgetLanguage), e.pageActions?.length && D.seed(e.pageActions);
1950
- let n = qe(t, e, u, {
1951
- onSend: oe,
1952
- onToggle: H,
1953
- onScrollTop: P,
1954
- onRetry: ce,
2108
+ h = e, u = et(e.widgetLanguage), e.pageActions?.length && D.seed(e.pageActions);
2109
+ let n = Ze(t, e, u, {
2110
+ onSend: ae,
2111
+ onToggle: le,
2112
+ onScrollTop: ne,
2113
+ onRetry: oe,
1955
2114
  onNavigate: E,
1956
- onOpenConversation: te,
2115
+ onOpenConversation: j,
1957
2116
  onNewConversation: A,
1958
2117
  onAttachImage: ie,
1959
- onRemoveAttachment: ae,
1960
- onBlockPageAction: V
2118
+ onRemoveAttachment: V,
2119
+ onBlockPageAction: se
1961
2120
  });
1962
- d = n, n.mount(s), c = re((e) => n.update(e)), n.update(F()), e.proactive?.enabled && (m = setTimeout(() => {
1963
- if (F().isOpen) return;
2121
+ d = n, n.mount(s), c = re((e) => n.update(e)), n.update(L()), e.proactive?.enabled && (m = setTimeout(() => {
2122
+ if (L().isOpen) return;
1964
2123
  let t = w();
1965
- I({
2124
+ R({
1966
2125
  messages: [{
1967
2126
  role: "assistant",
1968
2127
  content: e.proactive.message,
@@ -1970,7 +2129,7 @@ function nt(e) {
1970
2129
  }],
1971
2130
  view: "conversation",
1972
2131
  currentSessionId: t,
1973
- unreadCount: F().unreadCount + 1
2132
+ unreadCount: L().unreadCount + 1
1974
2133
  });
1975
2134
  }, e.proactive.delayMs ?? 8e3)), a.length > 0 && N(i);
1976
2135
  });
@@ -1979,31 +2138,31 @@ function nt(e) {
1979
2138
  if (!v) {
1980
2139
  v = !0;
1981
2140
  try {
1982
- I({ conversations: await O(t.apiUrl, t.apiKey, r) });
2141
+ R({ conversations: await O(t.apiUrl, t.apiKey, r) });
1983
2142
  } finally {
1984
2143
  v = !1;
1985
2144
  }
1986
2145
  }
1987
2146
  }
1988
2147
  function E(e) {
1989
- I({ view: e }), (e === "home" || e === "messages") && T();
2148
+ R({ view: e }), (e === "home" || e === "messages") && T();
1990
2149
  }
1991
2150
  function A() {
1992
- I({
2151
+ R({
1993
2152
  view: "conversation",
1994
2153
  currentSessionId: w(),
1995
2154
  messages: [],
1996
2155
  escalated: !1
1997
2156
  }), o = K();
1998
2157
  }
1999
- function te(e) {
2000
- I({
2158
+ function j(e) {
2159
+ R({
2001
2160
  view: "conversation",
2002
2161
  currentSessionId: e,
2003
2162
  messages: x(n, e)
2004
2163
  }), o = K(), N(e);
2005
2164
  }
2006
- function j(e) {
2165
+ function M(e) {
2007
2166
  let t = Date.parse(e.createdAt);
2008
2167
  return {
2009
2168
  role: e.role,
@@ -2013,44 +2172,65 @@ function nt(e) {
2013
2172
  };
2014
2173
  }
2015
2174
  async function N(e) {
2016
- let n = await M(t.apiUrl, t.apiKey, e, $, r);
2017
- n.messages.length > 0 && (o = ye(n), I({ messages: n.messages.map(j) })), I({ escalated: n.escalated === !0 }), F().escalated && _();
2175
+ let n = await P(t.apiUrl, t.apiKey, e, $, r);
2176
+ L().currentSessionId === e && (n.messages.length > 0 && (o = xe(n), R({ messages: n.messages.map(M) })), R({ escalated: n.escalated === !0 }), L().escalated && _());
2018
2177
  }
2019
- async function P() {
2020
- if (xe(o, F().loadingOlder)) {
2021
- I({ loadingOlder: !0 });
2178
+ async function ne() {
2179
+ if (Ce(o, L().loadingOlder)) {
2180
+ R({ loadingOlder: !0 });
2022
2181
  try {
2023
- let e = F().currentSessionId, n = await ne(t.apiUrl, t.apiKey, e, o.oldestCursor, $);
2024
- n.messages.length > 0 && I({ messages: [...n.messages.map(j), ...F().messages] }), o = be(o, n);
2182
+ let e = L().currentSessionId, n = await ee(t.apiUrl, t.apiKey, e, o.oldestCursor, $);
2183
+ n.messages.length > 0 && R({ messages: [...n.messages.map(M), ...L().messages] }), o = Se(o, n);
2025
2184
  } finally {
2026
- I({ loadingOlder: !1 });
2185
+ R({ loadingOlder: !1 });
2027
2186
  }
2028
2187
  }
2029
2188
  }
2030
- let L = "", R = null, z = null;
2189
+ let F = "", I = null, z = null;
2031
2190
  async function B(e, i, a) {
2032
- let o = F().currentSessionId, s = x(n, o).length === 0 && F().messages.filter((e) => e.role === "user").length === 1;
2033
- I({ isLoading: !0 });
2191
+ let o = L().currentSessionId, s = x(n, o).length === 0 && L().messages.filter((e) => e.role === "user").length === 1;
2192
+ R({ isLoading: !0 });
2034
2193
  try {
2035
2194
  let c = i && a ? [{
2036
2195
  url: i,
2037
2196
  mimeType: a
2038
- }] : void 0, l = await ee(t.apiUrl, t.apiKey, o, e, F().messages.filter((e) => !e.error), u, r, c), f = {
2197
+ }] : void 0, l = await te({
2198
+ apiUrl: t.apiUrl,
2199
+ apiKey: t.apiKey,
2200
+ sessionId: o,
2201
+ message: e,
2202
+ history: L().messages.filter((e) => !e.error && !e.streaming),
2203
+ strings: u,
2204
+ visitorId: r,
2205
+ attachments: c,
2206
+ onToken(e) {
2207
+ let t = L().messages, n = t[t.length - 1];
2208
+ n?.role === "assistant" && n.streaming ? R({ messages: [...t.slice(0, -1), {
2209
+ ...n,
2210
+ content: n.content + e
2211
+ }] }) : R({ messages: [...t, {
2212
+ role: "assistant",
2213
+ content: e,
2214
+ ts: Date.now(),
2215
+ streaming: !0
2216
+ }] });
2217
+ }
2218
+ }), f = L().messages.filter((e) => !e.streaming), p = {
2039
2219
  role: "assistant",
2040
2220
  content: l.reply,
2041
2221
  ts: Date.now(),
2042
2222
  ...l.error ? { error: !0 } : {},
2043
2223
  ...h?.richMessages && l.blocks?.length ? { blocks: l.blocks } : {}
2044
2224
  };
2045
- if (I({
2046
- messages: [...F().messages, f],
2225
+ if (R({
2226
+ messages: [...f, p],
2047
2227
  isLoading: !1
2048
- }), l.error || S(n, o, [f]), !l.error && s && T(), l.error || M(t.apiUrl, t.apiKey, o, $, r).then((e) => {
2049
- I({ escalated: e.escalated === !0 }), F().escalated && _();
2228
+ }), l.error || S(n, o, [p]), !l.error && s && T(), l.error || P(t.apiUrl, t.apiKey, o, $, r).then((e) => {
2229
+ R({ escalated: e.escalated === !0 }), L().escalated && _();
2050
2230
  }), !l.error && l.pageAction && d) {
2051
2231
  let e = d;
2052
2232
  try {
2053
- let t = await tt(l.pageAction, {
2233
+ let t = await at(l.pageAction, {
2054
2234
  registry: D,
2055
2235
  confirm: (t) => e.confirmAction(t)
2056
2236
  });
@@ -2060,7 +2240,7 @@ function nt(e) {
2060
2240
  content: t.status === "executed" ? u.actionDone : t.status === "cancelled" ? u.actionCancelled : t.status === "unknown" ? `⚠ ${t.message ?? u.actionUnavailable}` : `⚠ ${t.message ?? u.actionError}`,
2061
2241
  ts: Date.now()
2062
2242
  };
2063
- I({ messages: [...F().messages, r] }), S(n, o, [r]);
2243
+ R({ messages: [...L().messages, r] }), S(n, o, [r]);
2064
2244
  } catch {
2065
2245
  if (!d) return;
2066
2246
  let e = {
@@ -2068,23 +2248,23 @@ function nt(e) {
2068
2248
  content: u.actionError,
2069
2249
  ts: Date.now()
2070
2250
  };
2071
- I({ messages: [...F().messages, e] }), S(n, o, [e]);
2251
+ R({ messages: [...L().messages, e] }), S(n, o, [e]);
2072
2252
  }
2073
2253
  }
2074
2254
  } catch {
2075
- I({ isLoading: !1 });
2255
+ R({ isLoading: !1 });
2076
2256
  }
2077
2257
  }
2078
2258
  async function ie(e) {
2079
- let t = se(e);
2259
+ let t = ce(e);
2080
2260
  if (!t.ok) {
2081
- I({ uploadError: t.error });
2261
+ R({ uploadError: t.error });
2082
2262
  return;
2083
2263
  }
2084
- I({ uploadError: null });
2264
+ R({ uploadError: null });
2085
2265
  try {
2086
- let { blob: t, mimeType: n } = await le(e), r = F().pendingAttachment;
2087
- r && URL.revokeObjectURL(r.previewUrl), I({
2266
+ let { blob: t, mimeType: n } = await ue(e), r = L().pendingAttachment;
2267
+ r && URL.revokeObjectURL(r.previewUrl), R({
2088
2268
  pendingAttachment: {
2089
2269
  blob: t,
2090
2270
  previewUrl: URL.createObjectURL(t),
@@ -2093,51 +2273,51 @@ function nt(e) {
2093
2273
  uploadError: null
2094
2274
  });
2095
2275
  } catch {
2096
- I({ uploadError: u.imageUploadError });
2276
+ R({ uploadError: u.imageUploadError });
2097
2277
  }
2098
2278
  }
2099
- function ae() {
2100
- let e = F().pendingAttachment;
2101
- e && URL.revokeObjectURL(e.previewUrl), I({
2279
+ function V() {
2280
+ let e = L().pendingAttachment;
2281
+ e && URL.revokeObjectURL(e.previewUrl), R({
2102
2282
  pendingAttachment: null,
2103
2283
  uploadError: null
2104
2284
  });
2105
2285
  }
2106
- async function oe(e) {
2107
- if (F().isLoading || F().isUploading) return;
2108
- let i = F().pendingAttachment;
2286
+ async function ae(e) {
2287
+ if (L().isLoading || L().isUploading) return;
2288
+ let i = L().pendingAttachment;
2109
2289
  if (!e && !i) return;
2110
- I({ uploadError: null }), L = e, R = null, z = null;
2111
- let a = F().currentSessionId, o = {
2290
+ R({ uploadError: null }), F = e, I = null, z = null;
2291
+ let a = L().currentSessionId, o = {
2112
2292
  role: "user",
2113
2293
  content: e,
2114
2294
  ts: Date.now()
2115
2295
  };
2116
- if (I({ messages: [...F().messages, o] }), S(n, a, [o]), i) {
2117
- I({
2296
+ if (R({ messages: [...L().messages, o] }), S(n, a, [o]), i) {
2297
+ R({
2118
2298
  isUploading: !0,
2119
2299
  uploadError: null
2120
2300
  });
2121
2301
  let e = await k(t.apiUrl, t.apiKey, i.blob, r, u);
2122
- if (I({ isUploading: !1 }), !e.ok) {
2123
- I({ uploadError: e.error });
2124
- let t = F().messages;
2125
- I({ messages: t.slice(0, -1) });
2302
+ if (R({ isUploading: !1 }), !e.ok) {
2303
+ R({ uploadError: e.error });
2304
+ let t = L().messages;
2305
+ R({ messages: t.slice(0, -1) });
2126
2306
  return;
2127
2307
  }
2128
- R = e.url, z = i.mimeType, URL.revokeObjectURL(i.previewUrl), I({
2308
+ I = e.url, z = i.mimeType, URL.revokeObjectURL(i.previewUrl), R({
2129
2309
  pendingAttachment: null,
2130
2310
  uploadError: null
2131
2311
  });
2132
2312
  }
2133
- await B(e, R ?? void 0, z ?? void 0);
2313
+ await B(e, I ?? void 0, z ?? void 0);
2134
2314
  }
2135
- function ce() {
2136
- if (F().isLoading || !L) return;
2137
- let e = F().messages;
2138
- I({ messages: e.length > 0 && e[e.length - 1].error ? e.slice(0, -1) : e }), B(L, R ?? void 0, z ?? void 0);
2315
+ function oe() {
2316
+ if (L().isLoading || !F) return;
2317
+ let e = L().messages;
2318
+ R({ messages: e.length > 0 && e[e.length - 1].error ? e.slice(0, -1) : e }), B(F, I ?? void 0, z ?? void 0);
2139
2319
  }
2140
- async function V(e) {
2320
+ async function se(e) {
2141
2321
  if (!d) return;
2142
2322
  if (!D.has(e)) {
2143
2323
  let e = {
@@ -2145,12 +2325,12 @@ function nt(e) {
2145
2325
  content: `⚠ ${u.actionUnavailable}`,
2146
2326
  ts: Date.now()
2147
2327
  };
2148
- I({ messages: [...F().messages, e] });
2328
+ R({ messages: [...L().messages, e] });
2149
2329
  return;
2150
2330
  }
2151
2331
  let t = d;
2152
2332
  try {
2153
- let n = await tt({
2333
+ let n = await at({
2154
2334
  actionName: e,
2155
2335
  params: {},
2156
2336
  reason: ""
@@ -2164,7 +2344,7 @@ function nt(e) {
2164
2344
  content: n.status === "executed" ? u.actionDone : n.status === "cancelled" ? u.actionCancelled : n.status === "unknown" ? `⚠ ${n.message ?? u.actionUnavailable}` : `⚠ ${n.message ?? u.actionError}`,
2165
2345
  ts: Date.now()
2166
2346
  };
2167
- I({ messages: [...F().messages, r] });
2347
+ R({ messages: [...L().messages, r] });
2168
2348
  } catch {
2169
2349
  if (!d) return;
2170
2350
  let e = {
@@ -2172,24 +2352,24 @@ function nt(e) {
2172
2352
  content: u.actionError,
2173
2353
  ts: Date.now()
2174
2354
  };
2175
- I({ messages: [...F().messages, e] });
2355
+ R({ messages: [...L().messages, e] });
2176
2356
  }
2177
2357
  }
2178
- function H() {
2179
- let e = !F().isOpen, t = F().view;
2180
- I({
2358
+ function le() {
2359
+ let e = !L().isOpen, t = L().view;
2360
+ R({
2181
2361
  isOpen: e,
2182
2362
  ...e ? { unreadCount: 0 } : {}
2183
2363
  }), e && t === "home" && T();
2184
2364
  }
2185
2365
  return () => {
2186
2366
  l = !0, d = null, c(), m && clearTimeout(m), g &&= (clearTimeout(g), null);
2187
- let e = F().pendingAttachment;
2188
- e && URL.revokeObjectURL(e.previewUrl), I({
2367
+ let e = L().pendingAttachment;
2368
+ e && URL.revokeObjectURL(e.previewUrl), R({
2189
2369
  pendingAttachment: null,
2190
2370
  uploadError: null
2191
2371
  }), s.remove();
2192
2372
  };
2193
2373
  }
2194
2374
  //#endregion
2195
- export { nt as t };
2375
+ export { ot as t };