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

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;
@@ -690,12 +777,17 @@ function me(e) {
690
777
  border: none;
691
778
  color: var(--gray-400);
692
779
  font: inherit;
693
- font-size: 12px;
694
- padding: 10px;
780
+ font-size: 11px;
781
+ padding: 8px 10px 10px;
695
782
  cursor: pointer;
696
783
  transition: color .15s;
784
+ display: flex;
785
+ flex-direction: column;
786
+ align-items: center;
787
+ gap: 3px;
697
788
  }
698
789
 
790
+ .nav-btn svg { width: 18px; height: 18px; fill: currentColor; }
699
791
  .nav-btn:hover { color: var(--color-text); }
700
792
  .nav-btn.active { color: var(--color-primary); }
701
793
 
@@ -716,7 +808,7 @@ function me(e) {
716
808
  font: inherit;
717
809
  }
718
810
 
719
- .msg-list-item:hover { background: var(--gray-50); }
811
+ .msg-list-item:hover { background: var(--hover-bg); }
720
812
 
721
813
  .msg-list-avatar {
722
814
  flex-shrink: 0;
@@ -777,35 +869,66 @@ function me(e) {
777
869
 
778
870
  .msg-list-new:hover { background: var(--color-primary); color: #fff; }
779
871
 
780
- /* ── Home panel ─────────────────────────── */
781
- .home-greeting {
782
- font-size: 20px;
783
- font-weight: 600;
784
- color: var(--color-text);
785
- padding: 24px 18px 8px;
872
+ /* ── Home panel hero banner ─────────────── */
873
+ .home-hero {
874
+ background: var(--color-primary);
875
+ padding: 22px 18px 20px;
876
+ flex-shrink: 0;
877
+ }
878
+
879
+ .home-hero-row {
880
+ display: flex;
881
+ align-items: center;
882
+ gap: 12px;
883
+ margin-bottom: 14px;
884
+ }
885
+
886
+ .home-hero-avatar {
887
+ width: 48px;
888
+ height: 48px;
889
+ border-radius: 50%;
890
+ overflow: hidden;
891
+ flex-shrink: 0;
892
+ background: rgba(255,255,255,.2);
786
893
  }
787
894
 
895
+ .home-hero-name {
896
+ font-weight: 700;
897
+ font-size: 15px;
898
+ color: #fff;
899
+ }
900
+
901
+ .home-hero-status {
902
+ font-size: 12px;
903
+ color: rgba(255,255,255,.8);
904
+ margin-top: 2px;
905
+ }
906
+
907
+ .home-hero-greeting {
908
+ font-size: 15px;
909
+ line-height: 1.5;
910
+ color: rgba(255,255,255,.92);
911
+ }
912
+
913
+ /* ── Home panel CTA ─────────────────────── */
788
914
  .home-start {
789
- margin: 8px 18px;
915
+ margin: 14px 18px;
790
916
  padding: 14px;
791
917
  border-radius: 12px;
792
918
  border: 1.5px solid var(--color-primary);
793
919
  background: transparent;
794
920
  color: var(--color-primary);
795
- text-align: left;
921
+ text-align: center;
796
922
  cursor: pointer;
797
923
  font: inherit;
798
924
  font-size: 14px;
799
- font-weight: 500;
925
+ font-weight: 600;
926
+ width: calc(100% - 36px);
800
927
  transition: background .15s, color .15s;
801
928
  }
802
929
 
803
930
  .home-start:hover { background: var(--color-primary); color: #fff; }
804
931
 
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
932
  /* ── Home recent conversations ──────────────── */
810
933
  .home-recent-label {
811
934
  margin: 16px 18px 6px;
@@ -830,7 +953,7 @@ function me(e) {
830
953
  text-align: left;
831
954
  }
832
955
 
833
- .home-recent-item:hover { background: var(--gray-50); }
956
+ .home-recent-item:hover { background: var(--hover-bg); }
834
957
 
835
958
  .home-recent-avatar {
836
959
  flex-shrink: 0;
@@ -1117,9 +1240,11 @@ function me(e) {
1117
1240
  color: var(--color-text);
1118
1241
  opacity: 0.4;
1119
1242
  text-decoration: none;
1120
- margin-top: 6px;
1243
+ padding: 5px 0 7px;
1121
1244
  letter-spacing: 0.02em;
1122
1245
  transition: opacity .15s;
1246
+ background: var(--color-bg);
1247
+ border-top: 1px solid var(--gray-100);
1123
1248
  }
1124
1249
  .botiq-badge:hover { opacity: 0.85; }
1125
1250
  .botiq-badge-name { font-weight: 600; color: var(--color-primary); }
@@ -1250,11 +1375,11 @@ function me(e) {
1250
1375
  }
1251
1376
  .emoji-item:hover { background: var(--gray-100); }
1252
1377
 
1253
- ${_}
1254
- ${de(a)}
1255
- ${o ? ue(o) : ""}
1256
- ${pe}
1257
- ${fe}
1378
+ ${v}
1379
+ ${pe(a)}
1380
+ ${o ? fe(o) : ""}
1381
+ ${he}
1382
+ ${me}
1258
1383
  @media (max-width: 480px) {
1259
1384
  :host { bottom: 0; right: 0; left: 0; }
1260
1385
  .chat-window {
@@ -1282,7 +1407,7 @@ function W(e, t, n) {
1282
1407
  let a = new Date(e);
1283
1408
  return `${U(a.getHours())}:${U(a.getMinutes())}`;
1284
1409
  }
1285
- function he(e, t, n) {
1410
+ function _e(e, t, n) {
1286
1411
  let r = (e) => {
1287
1412
  let t = new Date(e);
1288
1413
  return new Date(t.getFullYear(), t.getMonth(), t.getDate()).getTime();
@@ -1297,7 +1422,7 @@ function he(e, t, n) {
1297
1422
  function G(e) {
1298
1423
  return e.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;").replace(/"/g, "&quot;");
1299
1424
  }
1300
- function ge(e, t, n, r = "") {
1425
+ function ve(e, t, n, r = "") {
1301
1426
  let i = `<button class="msg-list-new" type="button">+ ${G(t.newConversation)}</button>`;
1302
1427
  return e.length === 0 ? `<div class="msg-list-empty">${G(t.noConversations)}</div>${i}` : `<div class="msg-list">${e.map((e) => {
1303
1428
  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 +1436,8 @@ function ge(e, t, n, r = "") {
1311
1436
  </button>`;
1312
1437
  }).join("")}</div>${i}`;
1313
1438
  }
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 = "";
1439
+ function ye(e, t, n = [], r = "", i = Date.now()) {
1440
+ let a = e.status === "offline" ? t.statusPaused : t.statusOnline, o = G(e.design.content.greeting || t.homeGreeting), s = "";
1316
1441
  if (n.length > 0) {
1317
1442
  let e = n.slice(0, 3).map((e) => {
1318
1443
  let t = e.lastMessageAt ? Date.parse(e.lastMessageAt) : i, n = Number.isFinite(t) ? W(t, i, "vi") : "";
@@ -1325,18 +1450,26 @@ function _e(e, t, n = [], r = "", i = Date.now()) {
1325
1450
  <span class="home-recent-time">${G(n)}</span>
1326
1451
  </button>`;
1327
1452
  }).join("");
1328
- c = `<div class="home-recent-label">${G(t.recentMessages)}</div>${e}`;
1453
+ s = `<div class="home-recent-label">${G(t.recentMessages)}</div>${e}`;
1329
1454
  }
1330
1455
  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>
1456
+ <div class="home-hero">
1457
+ <div class="home-hero-row">
1458
+ ${r ? `<div class="home-hero-avatar">${r}</div>` : ""}
1459
+ <div>
1460
+ <div class="home-hero-name">${G(e.name)}</div>
1461
+ <div class="home-hero-status">● ${G(a)}</div>
1462
+ </div>
1463
+ </div>
1464
+ <div class="home-hero-greeting">${o}</div>
1465
+ </div>
1466
+ <button class="home-start" type="button">${G(t.startConversation)}</button>
1467
+ ${s}
1335
1468
  `;
1336
1469
  }
1337
1470
  //#endregion
1338
1471
  //#region src/core/assets.ts
1339
- var ve = "data:image/png;base64,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";
1472
+ var be = "data:image/png;base64,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";
1340
1473
  //#endregion
1341
1474
  //#region src/core/history-pager.ts
1342
1475
  function K() {
@@ -1346,24 +1479,24 @@ function K() {
1346
1479
  cursorReady: !1
1347
1480
  };
1348
1481
  }
1349
- function ye(e) {
1482
+ function xe(e) {
1350
1483
  return {
1351
1484
  oldestCursor: e.messages[0]?.id ?? null,
1352
1485
  hasMore: e.hasMore,
1353
1486
  cursorReady: e.messages.length > 0
1354
1487
  };
1355
1488
  }
1356
- function be(e, t) {
1489
+ function Se(e, t) {
1357
1490
  return {
1358
1491
  oldestCursor: t.messages[0]?.id ?? e.oldestCursor,
1359
1492
  hasMore: t.hasMore,
1360
1493
  cursorReady: e.cursorReady
1361
1494
  };
1362
1495
  }
1363
- function xe(e, t) {
1496
+ function Ce(e, t) {
1364
1497
  return e.cursorReady && e.hasMore && !t && e.oldestCursor !== null;
1365
1498
  }
1366
- function Se(e, t, n) {
1499
+ function we(e, t, n) {
1367
1500
  return e + (n - t);
1368
1501
  }
1369
1502
  //#endregion
@@ -1371,7 +1504,7 @@ function Se(e, t, n) {
1371
1504
  function q(e) {
1372
1505
  return e.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;").replace(/"/g, "&quot;").replace(/'/g, "&#x27;");
1373
1506
  }
1374
- function Ce(e, t) {
1507
+ function Te(e, t) {
1375
1508
  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
1509
  return new Promise((o) => {
1377
1510
  let s = document.createElement("div");
@@ -1401,15 +1534,15 @@ function Ce(e, t) {
1401
1534
  }
1402
1535
  //#endregion
1403
1536
  //#region src/core/emoji.ts
1404
- function we(e, t) {
1537
+ function Ee(e, t) {
1405
1538
  let n = e.selectionStart ?? e.value.length, r = e.selectionEnd ?? e.value.length;
1406
1539
  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
1540
  }
1408
1541
  var J = null;
1409
- async function Te() {
1542
+ async function De() {
1410
1543
  return J || (J = (await import("./emoji-data-DWiYsBZI.js")).EMOJIS, J);
1411
1544
  }
1412
- function Ee(e) {
1545
+ function Oe(e) {
1413
1546
  let t = document.createElement("button");
1414
1547
  t.type = "button", t.className = "emoji-btn", t.setAttribute("aria-label", "Emoji"), t.textContent = "🙂";
1415
1548
  let n = document.createElement("div");
@@ -1417,7 +1550,7 @@ function Ee(e) {
1417
1550
  let r = !1;
1418
1551
  return t.addEventListener("click", async () => {
1419
1552
  if (!r) {
1420
- let t = await Te();
1553
+ let t = await De();
1421
1554
  for (let r of t) {
1422
1555
  let t = document.createElement("button");
1423
1556
  t.type = "button", t.className = "emoji-item", t.textContent = r, t.addEventListener("click", () => {
@@ -1440,7 +1573,7 @@ function Y(e) {
1440
1573
  function X(e) {
1441
1574
  return /^https?:\/\//i.test(e) ? e : "";
1442
1575
  }
1443
- function De(e) {
1576
+ function ke(e) {
1444
1577
  let t = Y(e.label), n = Y(e.value), r = Y(e.action);
1445
1578
  if (e.action === "url") {
1446
1579
  let n = X(e.value);
@@ -1448,51 +1581,51 @@ function De(e) {
1448
1581
  }
1449
1582
  return `<button class="biq-btn biq-btn--${r}" type="button" data-action="${r}" data-value="${n}">${t}</button>`;
1450
1583
  }
1451
- function Oe(e) {
1584
+ function Ae(e) {
1452
1585
  let t = `${e.imageUrl ? (() => {
1453
1586
  let t = X(e.imageUrl);
1454
1587
  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>` : ""}`;
1588
+ })() : ""}${`<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
1589
  if (e.url) {
1457
1590
  let n = X(e.url);
1458
1591
  if (n) return `<a class="biq-card biq-card--link" href="${Y(n)}" target="_blank" rel="noopener noreferrer">${t}</a>`;
1459
1592
  }
1460
1593
  return `<div class="biq-card">${t}</div>`;
1461
1594
  }
1462
- function ke(e) {
1463
- return `<div class="biq-carousel">${e.cards.map(Oe).join("")}</div>`;
1595
+ function je(e) {
1596
+ return `<div class="biq-carousel">${e.cards.map(Ae).join("")}</div>`;
1464
1597
  }
1465
- function Ae(e) {
1598
+ function Me(e) {
1466
1599
  return `<div class="biq-quick-replies">${e.replies.map((e) => {
1467
1600
  let t = Y(e.label);
1468
1601
  return `<button class="biq-qr-pill" type="button" data-qr="1" data-value="${Y(e.value)}">${t}</button>`;
1469
1602
  }).join("")}</div>`;
1470
1603
  }
1471
- function je(e) {
1472
- return `<div class="biq-buttons">${e.buttons.map(De).join("")}</div>`;
1604
+ function Ne(e) {
1605
+ return `<div class="biq-buttons">${e.buttons.map(ke).join("")}</div>`;
1473
1606
  }
1474
- function Me(e) {
1607
+ function Pe(e) {
1475
1608
  return !e || e.length === 0 ? "" : e.map((e) => {
1476
1609
  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);
1610
+ case "card": return Ae(e);
1611
+ case "carousel": return je(e);
1612
+ case "quick_replies": return Me(e);
1613
+ case "buttons": return Ne(e);
1481
1614
  default: return "";
1482
1615
  }
1483
1616
  }).join("");
1484
1617
  }
1485
1618
  //#endregion
1486
1619
  //#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;
1620
+ 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>";
1621
+ function We(e) {
1622
+ if (!e || e.type === "icon") return Re;
1490
1623
  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
1624
  if (e.type === "initials") {
1492
1625
  let t = e.bgColor ?? "#F97316";
1493
1626
  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
1627
  }
1495
- return e.type === "image" ? `<img src="${Z(e.value)}" style="width:100%;height:100%;object-fit:cover;border-radius:50%" alt="" />` : Ie;
1628
+ return e.type === "image" ? `<img src="${Z(e.value)}" style="width:100%;height:100%;object-fit:cover;border-radius:50%" alt="" />` : Re;
1496
1629
  }
1497
1630
  function Z(e) {
1498
1631
  return e.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;").replace(/"/g, "&quot;").replace(/'/g, "&#x27;");
@@ -1501,27 +1634,27 @@ function Q(e) {
1501
1634
  let t = [];
1502
1635
  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
1636
  }
1504
- function Ve(e) {
1637
+ function Ge(e) {
1505
1638
  return /^\|[\s\-:|]+\|$/.test(e);
1506
1639
  }
1507
- function He(e) {
1640
+ function Ke(e) {
1508
1641
  return e.replace(/^\|/, "").replace(/\|$/, "").split("|").map((e) => e.trim());
1509
1642
  }
1510
- function Ue(e, t) {
1643
+ function qe(e, t) {
1511
1644
  return e ? `<div class="handoff-banner">⏳ ${Z(t.waitingForHuman)}</div>` : "";
1512
1645
  }
1513
- function We(e) {
1646
+ function Je(e) {
1514
1647
  return e <= 0 ? "" : `<span class="unread-badge">${e > 9 ? "9+" : String(e)}</span>`;
1515
1648
  }
1516
- function Ge(e) {
1649
+ function Ye(e) {
1517
1650
  let t = Z(e).replace(/\x00/g, "").split("\n"), n = [], r = 0;
1518
1651
  for (; r < t.length;) {
1519
1652
  let e = t[r].trim();
1520
1653
  if (e.startsWith("|") && e.endsWith("|")) {
1521
1654
  let e = [];
1522
1655
  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);
1656
+ let i = e.findIndex(Ge), a = i > 0 ? e.slice(0, i) : [], o = i >= 0 ? e.slice(i + 1) : e, s = "<table>";
1657
+ 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
1658
  continue;
1526
1659
  }
1527
1660
  if (/^-{3,}$/.test(e)) {
@@ -1555,41 +1688,41 @@ function Ge(e) {
1555
1688
  for (; n.length > 0 && n[n.length - 1] === "<br>";) n.pop();
1556
1689
  return n.join("");
1557
1690
  }
1558
- function Ke(e, t) {
1691
+ function Xe(e, t) {
1559
1692
  let { strings: n, content: r, botName: i, lang: a, now: o, contactInfo: s, richMessages: c } = t;
1560
1693
  if (e.messages.length === 0 && !e.isLoading) {
1561
1694
  let e = r.suggestionChips.length > 0 ? `<div class="chips">${r.suggestionChips.map((e) => `<button class="chip">${Z(e)}</button>`).join("")}</div>` : "";
1562
1695
  return `
1563
1696
  <div class="empty-state">
1564
- ${Re}
1697
+ ${Be}
1565
1698
  <span class="greeting">${Z(r.greeting || n.defaultGreeting)}</span>
1566
1699
  ${e}
1567
1700
  </div>
1568
1701
  `;
1569
1702
  }
1570
1703
  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>`;
1704
+ let t = e.ts ?? o, r = _e(t, o, a), u = r === l ? "" : `<div class="day-sep"><span>${Z(r)}</span></div>`;
1572
1705
  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>` : "";
1706
+ 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
1707
  return `${u}<div class="${`message ${e.role}${e.error ? " error" : ""}`}"><div class="message-bubble">${d}</div>${p}${m}${f}${h}</div>`;
1575
1708
  }).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
1709
  return d + u + f;
1577
1710
  }
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;
1711
+ function Ze(e, t, n, r) {
1712
+ 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
1713
  function T(e) {
1581
1714
  e.setAttribute("data-position", a.layout.position), o = e.attachShadow({ mode: "closed" });
1582
1715
  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>
1716
+ w.textContent = ge(a), o.appendChild(w), s = document.createElement("button"), s.className = "bubble", s.setAttribute("aria-label", n.ariaOpenChat), s.innerHTML = `
1717
+ <span class="icon-chat">${Ie}</span>
1718
+ <span class="icon-close">${Le}</span>
1586
1719
  <span class="unread-badge-slot"></span>
1587
1720
  `, 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
1721
  <div class="chat-header">
1589
- <div class="avatar">${Be(a.avatar)}</div>
1722
+ <div class="avatar">${We(a.avatar)}</div>
1590
1723
  <div class="header-text">
1591
1724
  <span class="bot-name">${Z(i)}</span>
1592
- <span class="bot-status">${Z(n.statusOnline)}</span>
1725
+ <span class="bot-status">${Z(t.status === "offline" ? n.statusPaused : n.statusOnline)}</span>
1593
1726
  </div>
1594
1727
  <button class="close-btn" aria-label="${Z(n.ariaCloseChat)}">×</button>
1595
1728
  </div>
@@ -1602,7 +1735,7 @@ function qe(e, t, n, r) {
1602
1735
  <div class="chat-footer">
1603
1736
  <div class="attach-preview-slot"></div>
1604
1737
  <div class="input-row">
1605
- ${S ? `<button class="attach-btn" type="button" aria-label="${Z(n.imageAttach)}">${ze}</button>` : ""}
1738
+ ${S ? `<button class="attach-btn" type="button" aria-label="${Z(n.imageAttach)}">${Ve}</button>` : ""}
1606
1739
  <textarea
1607
1740
  class="input"
1608
1741
  placeholder="${Z(x.placeholder || n.inputPlaceholder)}"
@@ -1611,20 +1744,20 @@ function qe(e, t, n, r) {
1611
1744
  aria-label="Message input"
1612
1745
  ></textarea>
1613
1746
  <button class="send-btn" aria-label="${Z(n.ariaSendMessage)}">
1614
- ${Le}
1747
+ ${ze}
1615
1748
  </button>
1616
1749
  </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
1750
  </div>
1621
1751
  </div>
1622
1752
  </div>
1623
1753
  <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>
1754
+ <button class="nav-btn" data-view="home">${He}<span>${Z(n.navHome)}</span></button>
1755
+ <button class="nav-btn" data-view="messages">${Ue}<span>${Z(n.navMessages)}</span></button>
1626
1756
  </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", () => {
1757
+ <a class="botiq-badge" href="${Fe}" target="_blank" rel="noopener noreferrer">
1758
+ ${Z(n.poweredBy)} <span class="botiq-badge-name">BotIQ</span>
1759
+ </a>
1760
+ `, 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-start")?.addEventListener("click", () => {
1628
1761
  r.onNewConversation();
1629
1762
  }), f = c.querySelector(".nav-btn[data-view=\"home\"]"), p = c.querySelector(".nav-btn[data-view=\"messages\"]"), c.querySelectorAll(".nav-btn").forEach((e) => {
1630
1763
  e.addEventListener("click", () => {
@@ -1642,8 +1775,8 @@ function qe(e, t, n, r) {
1642
1775
  }), g.addEventListener("keydown", (e) => {
1643
1776
  e.key === "Enter" && !e.shiftKey && (e.preventDefault(), E());
1644
1777
  }), _.addEventListener("click", E);
1645
- let D = c.querySelector(".input-row"), { button: O, panel: k } = Ee((e) => {
1646
- we(g, e), g.focus();
1778
+ let D = c.querySelector(".input-row"), { button: O, panel: k } = Oe((e) => {
1779
+ Ee(g, e), g.focus();
1647
1780
  });
1648
1781
  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
1782
  b?.click();
@@ -1658,7 +1791,7 @@ function qe(e, t, n, r) {
1658
1791
  }
1659
1792
  function D(e) {
1660
1793
  let a = m.scrollHeight - m.scrollTop - m.clientHeight < 80, o = m.scrollTop, s = m.scrollHeight;
1661
- m.innerHTML = Ke(e, {
1794
+ m.innerHTML = Xe(e, {
1662
1795
  strings: n,
1663
1796
  content: x,
1664
1797
  botName: i,
@@ -1696,12 +1829,12 @@ function qe(e, t, n, r) {
1696
1829
  n && (n.style.display = "none");
1697
1830
  }
1698
1831
  });
1699
- }), a ? m.scrollTop = m.scrollHeight : m.scrollTop = Se(o, s, m.scrollHeight);
1832
+ }), a ? m.scrollTop = m.scrollHeight : m.scrollTop = we(o, s, m.scrollHeight);
1700
1833
  }
1701
1834
  function O(e) {
1702
1835
  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
1836
  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) {
1837
+ if (i && (i.innerHTML = Je(e.unreadCount)), _.disabled = e.isLoading || e.isUploading, y && S) if (e.pendingAttachment) {
1705
1838
  let t = e.pendingAttachment, i = e.isUploading, a = e.uploadError;
1706
1839
  y.innerHTML = `
1707
1840
  <div class="attach-preview">
@@ -1721,7 +1854,7 @@ function qe(e, t, n, r) {
1721
1854
  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
1855
  w = e.conversations;
1723
1856
  let i = Date.now();
1724
- l.innerHTML = _e(t, n, e.conversations, C, i), l.querySelector(".home-start")?.addEventListener("click", () => {
1857
+ l.innerHTML = ye(t, n, e.conversations, C, i), l.querySelector(".home-start")?.addEventListener("click", () => {
1725
1858
  r.onNewConversation();
1726
1859
  }), l.querySelectorAll(".home-recent-item").forEach((e) => {
1727
1860
  e.addEventListener("click", () => {
@@ -1730,7 +1863,7 @@ function qe(e, t, n, r) {
1730
1863
  });
1731
1864
  });
1732
1865
  }
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) => {
1866
+ 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
1867
  e.addEventListener("click", () => {
1735
1868
  let t = e.dataset.session;
1736
1869
  t && r.onOpenConversation(t);
@@ -1740,7 +1873,7 @@ function qe(e, t, n, r) {
1740
1873
  }));
1741
1874
  }
1742
1875
  function k(e) {
1743
- return Ce(o, {
1876
+ return Te(o, {
1744
1877
  ...e,
1745
1878
  labels: {
1746
1879
  confirm: n.confirmYes,
@@ -1758,7 +1891,7 @@ function qe(e, t, n, r) {
1758
1891
  }
1759
1892
  //#endregion
1760
1893
  //#region src/i18n/vi.ts
1761
- var Je = {
1894
+ var Qe = {
1762
1895
  statusOnline: "Trực tuyến",
1763
1896
  statusPaused: "Tạm ngừng",
1764
1897
  navHome: "Trang chủ",
@@ -1799,7 +1932,7 @@ var Je = {
1799
1932
  imageUploadTooLarge: "Ảnh quá lớn (tối đa 5 MB sau khi nén).",
1800
1933
  imageUploadRateLimit: "Gửi quá nhanh. Vui lòng thử lại.",
1801
1934
  imageUploadError: "Tải ảnh thất bại. Vui lòng thử lại."
1802
- }, Ye = {
1935
+ }, $e = {
1803
1936
  statusOnline: "Online",
1804
1937
  statusPaused: "Paused",
1805
1938
  navHome: "Home",
@@ -1843,20 +1976,20 @@ var Je = {
1843
1976
  };
1844
1977
  //#endregion
1845
1978
  //#region src/i18n/index.ts
1846
- function Xe(e) {
1847
- return e === "en" ? Ye : Je;
1979
+ function et(e) {
1980
+ return e === "en" ? $e : Qe;
1848
1981
  }
1849
1982
  //#endregion
1850
1983
  //#region src/core/declarative-executor.ts
1851
- var Ze = /^[a-zA-Z0-9_-]*$/;
1852
- function Qe(e, t) {
1984
+ var tt = /^[a-zA-Z0-9_-]*$/;
1985
+ function nt(e, t) {
1853
1986
  return e.replace(/\{([a-zA-Z][a-zA-Z0-9_]*)\}/g, (e, n) => {
1854
1987
  let r = t[n], i = r == null ? "" : String(r);
1855
- if (!Ze.test(i)) throw Error(`Unsafe param value for "${n}"`);
1988
+ if (!tt.test(i)) throw Error(`Unsafe param value for "${n}"`);
1856
1989
  return i;
1857
1990
  });
1858
1991
  }
1859
- function $e(e, t) {
1992
+ function rt(e, t) {
1860
1993
  let n = typeof location < "u" ? location.origin : "https://placeholder.local", r, i;
1861
1994
  try {
1862
1995
  r = new URL(e, n), i = new URL(t.replace(/\{[a-zA-Z][a-zA-Z0-9_]*\}/g, "x"), n);
@@ -1866,10 +1999,10 @@ function $e(e, t) {
1866
1999
  if (!/^https?:$/.test(r.protocol)) throw Error("Navigation must be http(s)");
1867
2000
  if (r.origin !== i.origin) throw Error("Navigation origin not allowed");
1868
2001
  }
1869
- async function et(e, t) {
2002
+ async function it(e, t) {
1870
2003
  let n = e.config;
1871
2004
  if (e.operation === "click") {
1872
- let e = Qe(String(n.selectorTemplate ?? ""), t), r = document.querySelector(e);
2005
+ let e = nt(String(n.selectorTemplate ?? ""), t), r = document.querySelector(e);
1873
2006
  if (!r) throw Error(`No element for selector: ${e}`);
1874
2007
  r.click();
1875
2008
  return;
@@ -1884,15 +2017,15 @@ async function et(e, t) {
1884
2017
  return;
1885
2018
  }
1886
2019
  if (e.operation === "navigate") {
1887
- let e = String(n.urlTemplate ?? ""), r = Qe(e, t);
1888
- $e(r, e), location.assign(r);
2020
+ let e = String(n.urlTemplate ?? ""), r = nt(e, t);
2021
+ rt(r, e), location.assign(r);
1889
2022
  return;
1890
2023
  }
1891
2024
  throw Error(`Unknown operation: ${String(e.operation)}`);
1892
2025
  }
1893
2026
  //#endregion
1894
2027
  //#region src/core/page-action-executor.ts
1895
- async function tt(e, t) {
2028
+ async function at(e, t) {
1896
2029
  let n = t.registry.get(e.actionName);
1897
2030
  if (!n) return {
1898
2031
  status: "unknown",
@@ -1917,26 +2050,26 @@ async function tt(e, t) {
1917
2050
  //#endregion
1918
2051
  //#region src/builds/npm/index.ts
1919
2052
  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;
2053
+ function ot(e) {
2054
+ 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
2055
  let t = p(e);
1923
2056
  y();
1924
2057
  let n = t.apiKey.slice(-16), r = C(), i = b(n), a = x(n, i);
1925
- I({
2058
+ R({
1926
2059
  messages: a,
1927
2060
  view: "home",
1928
2061
  currentSessionId: i
1929
2062
  });
1930
2063
  let o = K(), s = document.createElement("div");
1931
2064
  document.body.appendChild(s);
1932
- let c = () => void 0, l = !1, u = Xe(void 0), d = null, m = null, h = null, g = null;
2065
+ let c = () => void 0, l = !1, u = et(void 0), d = null, m = null, h = null, g = null;
1933
2066
  function _() {
1934
2067
  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 });
2068
+ if (g = null, !(!L().escalated || !L().isOpen)) try {
2069
+ let e = await P(t.apiUrl, t.apiKey, L().currentSessionId, $, r);
2070
+ e.messages.length > 0 && R({ messages: e.messages.map(M) }), R({ escalated: e.escalated === !0 });
1938
2071
  } catch {} finally {
1939
- F().escalated && F().isOpen && _();
2072
+ L().escalated && L().isOpen && _();
1940
2073
  }
1941
2074
  }, 1e4);
1942
2075
  }
@@ -1946,23 +2079,23 @@ function nt(e) {
1946
2079
  console.warn("[BotIQ] Widget not authorised on this origin — skipped mount"), s.remove();
1947
2080
  return;
1948
2081
  }
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,
2082
+ h = e, u = et(e.widgetLanguage), e.pageActions?.length && D.seed(e.pageActions);
2083
+ let n = Ze(t, e, u, {
2084
+ onSend: ae,
2085
+ onToggle: le,
2086
+ onScrollTop: ne,
2087
+ onRetry: oe,
1955
2088
  onNavigate: E,
1956
- onOpenConversation: te,
2089
+ onOpenConversation: j,
1957
2090
  onNewConversation: A,
1958
2091
  onAttachImage: ie,
1959
- onRemoveAttachment: ae,
1960
- onBlockPageAction: V
2092
+ onRemoveAttachment: V,
2093
+ onBlockPageAction: se
1961
2094
  });
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;
2095
+ d = n, n.mount(s), c = re((e) => n.update(e)), n.update(L()), e.proactive?.enabled && (m = setTimeout(() => {
2096
+ if (L().isOpen) return;
1964
2097
  let t = w();
1965
- I({
2098
+ R({
1966
2099
  messages: [{
1967
2100
  role: "assistant",
1968
2101
  content: e.proactive.message,
@@ -1970,7 +2103,7 @@ function nt(e) {
1970
2103
  }],
1971
2104
  view: "conversation",
1972
2105
  currentSessionId: t,
1973
- unreadCount: F().unreadCount + 1
2106
+ unreadCount: L().unreadCount + 1
1974
2107
  });
1975
2108
  }, e.proactive.delayMs ?? 8e3)), a.length > 0 && N(i);
1976
2109
  });
@@ -1979,31 +2112,31 @@ function nt(e) {
1979
2112
  if (!v) {
1980
2113
  v = !0;
1981
2114
  try {
1982
- I({ conversations: await O(t.apiUrl, t.apiKey, r) });
2115
+ R({ conversations: await O(t.apiUrl, t.apiKey, r) });
1983
2116
  } finally {
1984
2117
  v = !1;
1985
2118
  }
1986
2119
  }
1987
2120
  }
1988
2121
  function E(e) {
1989
- I({ view: e }), (e === "home" || e === "messages") && T();
2122
+ R({ view: e }), (e === "home" || e === "messages") && T();
1990
2123
  }
1991
2124
  function A() {
1992
- I({
2125
+ R({
1993
2126
  view: "conversation",
1994
2127
  currentSessionId: w(),
1995
2128
  messages: [],
1996
2129
  escalated: !1
1997
2130
  }), o = K();
1998
2131
  }
1999
- function te(e) {
2000
- I({
2132
+ function j(e) {
2133
+ R({
2001
2134
  view: "conversation",
2002
2135
  currentSessionId: e,
2003
2136
  messages: x(n, e)
2004
2137
  }), o = K(), N(e);
2005
2138
  }
2006
- function j(e) {
2139
+ function M(e) {
2007
2140
  let t = Date.parse(e.createdAt);
2008
2141
  return {
2009
2142
  role: e.role,
@@ -2013,44 +2146,65 @@ function nt(e) {
2013
2146
  };
2014
2147
  }
2015
2148
  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 && _();
2149
+ let n = await P(t.apiUrl, t.apiKey, e, $, r);
2150
+ L().currentSessionId === e && (n.messages.length > 0 && (o = xe(n), R({ messages: n.messages.map(M) })), R({ escalated: n.escalated === !0 }), L().escalated && _());
2018
2151
  }
2019
- async function P() {
2020
- if (xe(o, F().loadingOlder)) {
2021
- I({ loadingOlder: !0 });
2152
+ async function ne() {
2153
+ if (Ce(o, L().loadingOlder)) {
2154
+ R({ loadingOlder: !0 });
2022
2155
  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);
2156
+ let e = L().currentSessionId, n = await ee(t.apiUrl, t.apiKey, e, o.oldestCursor, $);
2157
+ n.messages.length > 0 && R({ messages: [...n.messages.map(M), ...L().messages] }), o = Se(o, n);
2025
2158
  } finally {
2026
- I({ loadingOlder: !1 });
2159
+ R({ loadingOlder: !1 });
2027
2160
  }
2028
2161
  }
2029
2162
  }
2030
- let L = "", R = null, z = null;
2163
+ let F = "", I = null, z = null;
2031
2164
  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 });
2165
+ let o = L().currentSessionId, s = x(n, o).length === 0 && L().messages.filter((e) => e.role === "user").length === 1;
2166
+ R({ isLoading: !0 });
2034
2167
  try {
2035
2168
  let c = i && a ? [{
2036
2169
  url: i,
2037
2170
  mimeType: a
2038
- }] : void 0, l = await ee(t.apiUrl, t.apiKey, o, e, F().messages.filter((e) => !e.error), u, r, c), f = {
2171
+ }] : void 0, l = await te({
2172
+ apiUrl: t.apiUrl,
2173
+ apiKey: t.apiKey,
2174
+ sessionId: o,
2175
+ message: e,
2176
+ history: L().messages.filter((e) => !e.error && !e.streaming),
2177
+ strings: u,
2178
+ visitorId: r,
2179
+ attachments: c,
2180
+ onToken(e) {
2181
+ let t = L().messages, n = t[t.length - 1];
2182
+ n?.role === "assistant" && n.streaming ? R({ messages: [...t.slice(0, -1), {
2183
+ ...n,
2184
+ content: n.content + e
2185
+ }] }) : R({ messages: [...t, {
2186
+ role: "assistant",
2187
+ content: e,
2188
+ ts: Date.now(),
2189
+ streaming: !0
2190
+ }] });
2191
+ }
2192
+ }), f = L().messages.filter((e) => !e.streaming), p = {
2039
2193
  role: "assistant",
2040
2194
  content: l.reply,
2041
2195
  ts: Date.now(),
2042
2196
  ...l.error ? { error: !0 } : {},
2043
2197
  ...h?.richMessages && l.blocks?.length ? { blocks: l.blocks } : {}
2044
2198
  };
2045
- if (I({
2046
- messages: [...F().messages, f],
2199
+ if (R({
2200
+ messages: [...f, p],
2047
2201
  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 && _();
2202
+ }), l.error || S(n, o, [p]), !l.error && s && T(), l.error || P(t.apiUrl, t.apiKey, o, $, r).then((e) => {
2203
+ R({ escalated: e.escalated === !0 }), L().escalated && _();
2050
2204
  }), !l.error && l.pageAction && d) {
2051
2205
  let e = d;
2052
2206
  try {
2053
- let t = await tt(l.pageAction, {
2207
+ let t = await at(l.pageAction, {
2054
2208
  registry: D,
2055
2209
  confirm: (t) => e.confirmAction(t)
2056
2210
  });
@@ -2060,7 +2214,7 @@ function nt(e) {
2060
2214
  content: t.status === "executed" ? u.actionDone : t.status === "cancelled" ? u.actionCancelled : t.status === "unknown" ? `⚠ ${t.message ?? u.actionUnavailable}` : `⚠ ${t.message ?? u.actionError}`,
2061
2215
  ts: Date.now()
2062
2216
  };
2063
- I({ messages: [...F().messages, r] }), S(n, o, [r]);
2217
+ R({ messages: [...L().messages, r] }), S(n, o, [r]);
2064
2218
  } catch {
2065
2219
  if (!d) return;
2066
2220
  let e = {
@@ -2068,23 +2222,23 @@ function nt(e) {
2068
2222
  content: u.actionError,
2069
2223
  ts: Date.now()
2070
2224
  };
2071
- I({ messages: [...F().messages, e] }), S(n, o, [e]);
2225
+ R({ messages: [...L().messages, e] }), S(n, o, [e]);
2072
2226
  }
2073
2227
  }
2074
2228
  } catch {
2075
- I({ isLoading: !1 });
2229
+ R({ isLoading: !1 });
2076
2230
  }
2077
2231
  }
2078
2232
  async function ie(e) {
2079
- let t = se(e);
2233
+ let t = ce(e);
2080
2234
  if (!t.ok) {
2081
- I({ uploadError: t.error });
2235
+ R({ uploadError: t.error });
2082
2236
  return;
2083
2237
  }
2084
- I({ uploadError: null });
2238
+ R({ uploadError: null });
2085
2239
  try {
2086
- let { blob: t, mimeType: n } = await le(e), r = F().pendingAttachment;
2087
- r && URL.revokeObjectURL(r.previewUrl), I({
2240
+ let { blob: t, mimeType: n } = await ue(e), r = L().pendingAttachment;
2241
+ r && URL.revokeObjectURL(r.previewUrl), R({
2088
2242
  pendingAttachment: {
2089
2243
  blob: t,
2090
2244
  previewUrl: URL.createObjectURL(t),
@@ -2093,51 +2247,51 @@ function nt(e) {
2093
2247
  uploadError: null
2094
2248
  });
2095
2249
  } catch {
2096
- I({ uploadError: u.imageUploadError });
2250
+ R({ uploadError: u.imageUploadError });
2097
2251
  }
2098
2252
  }
2099
- function ae() {
2100
- let e = F().pendingAttachment;
2101
- e && URL.revokeObjectURL(e.previewUrl), I({
2253
+ function V() {
2254
+ let e = L().pendingAttachment;
2255
+ e && URL.revokeObjectURL(e.previewUrl), R({
2102
2256
  pendingAttachment: null,
2103
2257
  uploadError: null
2104
2258
  });
2105
2259
  }
2106
- async function oe(e) {
2107
- if (F().isLoading || F().isUploading) return;
2108
- let i = F().pendingAttachment;
2260
+ async function ae(e) {
2261
+ if (L().isLoading || L().isUploading) return;
2262
+ let i = L().pendingAttachment;
2109
2263
  if (!e && !i) return;
2110
- I({ uploadError: null }), L = e, R = null, z = null;
2111
- let a = F().currentSessionId, o = {
2264
+ R({ uploadError: null }), F = e, I = null, z = null;
2265
+ let a = L().currentSessionId, o = {
2112
2266
  role: "user",
2113
2267
  content: e,
2114
2268
  ts: Date.now()
2115
2269
  };
2116
- if (I({ messages: [...F().messages, o] }), S(n, a, [o]), i) {
2117
- I({
2270
+ if (R({ messages: [...L().messages, o] }), S(n, a, [o]), i) {
2271
+ R({
2118
2272
  isUploading: !0,
2119
2273
  uploadError: null
2120
2274
  });
2121
2275
  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) });
2276
+ if (R({ isUploading: !1 }), !e.ok) {
2277
+ R({ uploadError: e.error });
2278
+ let t = L().messages;
2279
+ R({ messages: t.slice(0, -1) });
2126
2280
  return;
2127
2281
  }
2128
- R = e.url, z = i.mimeType, URL.revokeObjectURL(i.previewUrl), I({
2282
+ I = e.url, z = i.mimeType, URL.revokeObjectURL(i.previewUrl), R({
2129
2283
  pendingAttachment: null,
2130
2284
  uploadError: null
2131
2285
  });
2132
2286
  }
2133
- await B(e, R ?? void 0, z ?? void 0);
2287
+ await B(e, I ?? void 0, z ?? void 0);
2134
2288
  }
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);
2289
+ function oe() {
2290
+ if (L().isLoading || !F) return;
2291
+ let e = L().messages;
2292
+ R({ messages: e.length > 0 && e[e.length - 1].error ? e.slice(0, -1) : e }), B(F, I ?? void 0, z ?? void 0);
2139
2293
  }
2140
- async function V(e) {
2294
+ async function se(e) {
2141
2295
  if (!d) return;
2142
2296
  if (!D.has(e)) {
2143
2297
  let e = {
@@ -2145,12 +2299,12 @@ function nt(e) {
2145
2299
  content: `⚠ ${u.actionUnavailable}`,
2146
2300
  ts: Date.now()
2147
2301
  };
2148
- I({ messages: [...F().messages, e] });
2302
+ R({ messages: [...L().messages, e] });
2149
2303
  return;
2150
2304
  }
2151
2305
  let t = d;
2152
2306
  try {
2153
- let n = await tt({
2307
+ let n = await at({
2154
2308
  actionName: e,
2155
2309
  params: {},
2156
2310
  reason: ""
@@ -2164,7 +2318,7 @@ function nt(e) {
2164
2318
  content: n.status === "executed" ? u.actionDone : n.status === "cancelled" ? u.actionCancelled : n.status === "unknown" ? `⚠ ${n.message ?? u.actionUnavailable}` : `⚠ ${n.message ?? u.actionError}`,
2165
2319
  ts: Date.now()
2166
2320
  };
2167
- I({ messages: [...F().messages, r] });
2321
+ R({ messages: [...L().messages, r] });
2168
2322
  } catch {
2169
2323
  if (!d) return;
2170
2324
  let e = {
@@ -2172,24 +2326,24 @@ function nt(e) {
2172
2326
  content: u.actionError,
2173
2327
  ts: Date.now()
2174
2328
  };
2175
- I({ messages: [...F().messages, e] });
2329
+ R({ messages: [...L().messages, e] });
2176
2330
  }
2177
2331
  }
2178
- function H() {
2179
- let e = !F().isOpen, t = F().view;
2180
- I({
2332
+ function le() {
2333
+ let e = !L().isOpen, t = L().view;
2334
+ R({
2181
2335
  isOpen: e,
2182
2336
  ...e ? { unreadCount: 0 } : {}
2183
2337
  }), e && t === "home" && T();
2184
2338
  }
2185
2339
  return () => {
2186
2340
  l = !0, d = null, c(), m && clearTimeout(m), g &&= (clearTimeout(g), null);
2187
- let e = F().pendingAttachment;
2188
- e && URL.revokeObjectURL(e.previewUrl), I({
2341
+ let e = L().pendingAttachment;
2342
+ e && URL.revokeObjectURL(e.previewUrl), R({
2189
2343
  pendingAttachment: null,
2190
2344
  uploadError: null
2191
2345
  }), s.remove();
2192
2346
  };
2193
2347
  }
2194
2348
  //#endregion
2195
- export { nt as t };
2349
+ export { ot as t };