@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.
- package/dist/sdk/index.js +1 -1
- package/dist/sdk/{npm-ClWjnXje.js → npm-CjQcAuJy.js} +388 -234
- package/dist/sdk/react.js +1 -1
- package/dist/sdk/vue.js +1 -1
- package/package.json +2 -2
|
@@ -283,7 +283,7 @@ async function k(e, t, n, r, i) {
|
|
|
283
283
|
};
|
|
284
284
|
}
|
|
285
285
|
}
|
|
286
|
-
async function
|
|
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
|
|
330
|
+
var j = {
|
|
331
331
|
messages: [],
|
|
332
332
|
hasMore: !1
|
|
333
333
|
};
|
|
334
|
-
function
|
|
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
|
|
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
|
|
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(
|
|
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
|
|
362
|
+
return j;
|
|
363
363
|
}
|
|
364
364
|
}
|
|
365
|
-
function
|
|
366
|
-
return
|
|
365
|
+
function P(e, t, n, r, i) {
|
|
366
|
+
return N(e, t, n, void 0, r, i);
|
|
367
367
|
}
|
|
368
|
-
function
|
|
369
|
-
return
|
|
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
|
|
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
|
-
},
|
|
387
|
-
function
|
|
388
|
-
return
|
|
472
|
+
}, I = /* @__PURE__ */ new Set();
|
|
473
|
+
function L() {
|
|
474
|
+
return F;
|
|
389
475
|
}
|
|
390
|
-
function
|
|
391
|
-
Object.assign(
|
|
476
|
+
function R(e) {
|
|
477
|
+
Object.assign(F, e);
|
|
392
478
|
let t = {
|
|
393
|
-
...
|
|
394
|
-
messages: [...
|
|
395
|
-
conversations: [...
|
|
479
|
+
...F,
|
|
480
|
+
messages: [...F.messages],
|
|
481
|
+
conversations: [...F.conversations]
|
|
396
482
|
};
|
|
397
|
-
|
|
483
|
+
I.forEach((e) => e(t));
|
|
398
484
|
}
|
|
399
485
|
function re(e) {
|
|
400
|
-
return
|
|
486
|
+
return I.add(e), () => I.delete(e);
|
|
401
487
|
}
|
|
402
488
|
//#endregion
|
|
403
489
|
//#region src/core/upload.ts
|
|
404
|
-
var
|
|
490
|
+
var z = new Set([
|
|
405
491
|
"image/jpeg",
|
|
406
492
|
"image/png",
|
|
407
493
|
"image/webp"
|
|
408
|
-
]),
|
|
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
|
|
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
|
|
507
|
+
function le(e, t) {
|
|
422
508
|
let n = Math.max(e, t);
|
|
423
|
-
if (n <=
|
|
509
|
+
if (n <= V) return {
|
|
424
510
|
width: e,
|
|
425
511
|
height: t
|
|
426
512
|
};
|
|
427
|
-
let r =
|
|
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
|
|
434
|
-
let t =
|
|
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 } =
|
|
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 <=
|
|
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 >
|
|
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,
|
|
474
|
-
}, l,
|
|
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
|
|
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
|
|
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
|
|
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
|
|
517
|
-
function
|
|
518
|
-
let { colors: t, layout: n, font: r, gradient: i, animation: a, customCSS: o, whiteLabel: s } = e, c =
|
|
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:
|
|
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(--
|
|
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-
|
|
782
|
-
|
|
783
|
-
|
|
784
|
-
|
|
785
|
-
|
|
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:
|
|
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:
|
|
921
|
+
text-align: center;
|
|
796
922
|
cursor: pointer;
|
|
797
923
|
font: inherit;
|
|
798
924
|
font-size: 14px;
|
|
799
|
-
font-weight:
|
|
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(--
|
|
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
|
-
|
|
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
|
-
${
|
|
1255
|
-
${o ?
|
|
1256
|
-
${
|
|
1257
|
-
${
|
|
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
|
|
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, "&").replace(/</g, "<").replace(/>/g, ">").replace(/"/g, """);
|
|
1299
1424
|
}
|
|
1300
|
-
function
|
|
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
|
|
1315
|
-
let a = e.status
|
|
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
|
-
|
|
1453
|
+
s = `<div class="home-recent-label">${G(t.recentMessages)}</div>${e}`;
|
|
1329
1454
|
}
|
|
1330
1455
|
return `
|
|
1331
|
-
<div class="home-
|
|
1332
|
-
|
|
1333
|
-
|
|
1334
|
-
|
|
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
|
|
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
|
|
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
|
|
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
|
|
1496
|
+
function Ce(e, t) {
|
|
1364
1497
|
return e.cursorReady && e.hasMore && !t && e.oldestCursor !== null;
|
|
1365
1498
|
}
|
|
1366
|
-
function
|
|
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, "&").replace(/</g, "<").replace(/>/g, ">").replace(/"/g, """).replace(/'/g, "'");
|
|
1373
1506
|
}
|
|
1374
|
-
function
|
|
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
|
|
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
|
|
1542
|
+
async function De() {
|
|
1410
1543
|
return J || (J = (await import("./emoji-data-DWiYsBZI.js")).EMOJIS, J);
|
|
1411
1544
|
}
|
|
1412
|
-
function
|
|
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
|
|
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
|
|
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
|
|
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(
|
|
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
|
|
1463
|
-
return `<div class="biq-carousel">${e.cards.map(
|
|
1595
|
+
function je(e) {
|
|
1596
|
+
return `<div class="biq-carousel">${e.cards.map(Ae).join("")}</div>`;
|
|
1464
1597
|
}
|
|
1465
|
-
function
|
|
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
|
|
1472
|
-
return `<div class="biq-buttons">${e.buttons.map(
|
|
1604
|
+
function Ne(e) {
|
|
1605
|
+
return `<div class="biq-buttons">${e.buttons.map(ke).join("")}</div>`;
|
|
1473
1606
|
}
|
|
1474
|
-
function
|
|
1607
|
+
function Pe(e) {
|
|
1475
1608
|
return !e || e.length === 0 ? "" : e.map((e) => {
|
|
1476
1609
|
switch (e.type) {
|
|
1477
|
-
case "card": return
|
|
1478
|
-
case "carousel": return
|
|
1479
|
-
case "quick_replies": return
|
|
1480
|
-
case "buttons": return
|
|
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
|
|
1488
|
-
function
|
|
1489
|
-
if (!e || e.type === "icon") return
|
|
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="" />` :
|
|
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, "&").replace(/</g, "<").replace(/>/g, ">").replace(/"/g, """).replace(/'/g, "'");
|
|
@@ -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
|
|
1637
|
+
function Ge(e) {
|
|
1505
1638
|
return /^\|[\s\-:|]+\|$/.test(e);
|
|
1506
1639
|
}
|
|
1507
|
-
function
|
|
1640
|
+
function Ke(e) {
|
|
1508
1641
|
return e.replace(/^\|/, "").replace(/\|$/, "").split("|").map((e) => e.trim());
|
|
1509
1642
|
}
|
|
1510
|
-
function
|
|
1643
|
+
function qe(e, t) {
|
|
1511
1644
|
return e ? `<div class="handoff-banner">⏳ ${Z(t.waitingForHuman)}</div>` : "";
|
|
1512
1645
|
}
|
|
1513
|
-
function
|
|
1646
|
+
function Je(e) {
|
|
1514
1647
|
return e <= 0 ? "" : `<span class="unread-badge">${e > 9 ? "9+" : String(e)}</span>`;
|
|
1515
1648
|
}
|
|
1516
|
-
function
|
|
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(
|
|
1524
|
-
a.length > 0 && (s += "<thead>" + a.map((e) => "<tr>" +
|
|
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
|
|
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
|
-
${
|
|
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 =
|
|
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" ?
|
|
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
|
|
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 =
|
|
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 =
|
|
1584
|
-
<span class="icon-chat">${
|
|
1585
|
-
<span class="icon-close">${
|
|
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">${
|
|
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)}">${
|
|
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
|
-
${
|
|
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"
|
|
1625
|
-
<button class="nav-btn" data-view="messages"
|
|
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
|
-
|
|
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 } =
|
|
1646
|
-
|
|
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 =
|
|
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 =
|
|
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 =
|
|
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 =
|
|
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 =
|
|
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
|
|
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
|
|
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
|
-
},
|
|
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
|
|
1847
|
-
return e === "en" ?
|
|
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
|
|
1852
|
-
function
|
|
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 (!
|
|
1988
|
+
if (!tt.test(i)) throw Error(`Unsafe param value for "${n}"`);
|
|
1856
1989
|
return i;
|
|
1857
1990
|
});
|
|
1858
1991
|
}
|
|
1859
|
-
function
|
|
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
|
|
2002
|
+
async function it(e, t) {
|
|
1870
2003
|
let n = e.config;
|
|
1871
2004
|
if (e.operation === "click") {
|
|
1872
|
-
let 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 =
|
|
1888
|
-
|
|
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
|
|
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
|
|
1921
|
-
if (D.setDeclarativeRunner(
|
|
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
|
-
|
|
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 =
|
|
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, !(!
|
|
1936
|
-
let e = await
|
|
1937
|
-
e.messages.length > 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
|
-
|
|
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 =
|
|
1950
|
-
let n =
|
|
1951
|
-
onSend:
|
|
1952
|
-
onToggle:
|
|
1953
|
-
onScrollTop:
|
|
1954
|
-
onRetry:
|
|
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:
|
|
2089
|
+
onOpenConversation: j,
|
|
1957
2090
|
onNewConversation: A,
|
|
1958
2091
|
onAttachImage: ie,
|
|
1959
|
-
onRemoveAttachment:
|
|
1960
|
-
onBlockPageAction:
|
|
2092
|
+
onRemoveAttachment: V,
|
|
2093
|
+
onBlockPageAction: se
|
|
1961
2094
|
});
|
|
1962
|
-
d = n, n.mount(s), c = re((e) => n.update(e)), n.update(
|
|
1963
|
-
if (
|
|
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
|
-
|
|
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:
|
|
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
|
-
|
|
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
|
-
|
|
2122
|
+
R({ view: e }), (e === "home" || e === "messages") && T();
|
|
1990
2123
|
}
|
|
1991
2124
|
function A() {
|
|
1992
|
-
|
|
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
|
|
2000
|
-
|
|
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
|
|
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
|
|
2017
|
-
n.messages.length > 0 && (o =
|
|
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
|
|
2020
|
-
if (
|
|
2021
|
-
|
|
2152
|
+
async function ne() {
|
|
2153
|
+
if (Ce(o, L().loadingOlder)) {
|
|
2154
|
+
R({ loadingOlder: !0 });
|
|
2022
2155
|
try {
|
|
2023
|
-
let e =
|
|
2024
|
-
n.messages.length > 0 &&
|
|
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
|
-
|
|
2159
|
+
R({ loadingOlder: !1 });
|
|
2027
2160
|
}
|
|
2028
2161
|
}
|
|
2029
2162
|
}
|
|
2030
|
-
let
|
|
2163
|
+
let F = "", I = null, z = null;
|
|
2031
2164
|
async function B(e, i, a) {
|
|
2032
|
-
let o =
|
|
2033
|
-
|
|
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
|
|
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 (
|
|
2046
|
-
messages: [...
|
|
2199
|
+
if (R({
|
|
2200
|
+
messages: [...f, p],
|
|
2047
2201
|
isLoading: !1
|
|
2048
|
-
}), l.error || S(n, o, [
|
|
2049
|
-
|
|
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
|
|
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
|
-
|
|
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
|
-
|
|
2225
|
+
R({ messages: [...L().messages, e] }), S(n, o, [e]);
|
|
2072
2226
|
}
|
|
2073
2227
|
}
|
|
2074
2228
|
} catch {
|
|
2075
|
-
|
|
2229
|
+
R({ isLoading: !1 });
|
|
2076
2230
|
}
|
|
2077
2231
|
}
|
|
2078
2232
|
async function ie(e) {
|
|
2079
|
-
let t =
|
|
2233
|
+
let t = ce(e);
|
|
2080
2234
|
if (!t.ok) {
|
|
2081
|
-
|
|
2235
|
+
R({ uploadError: t.error });
|
|
2082
2236
|
return;
|
|
2083
2237
|
}
|
|
2084
|
-
|
|
2238
|
+
R({ uploadError: null });
|
|
2085
2239
|
try {
|
|
2086
|
-
let { blob: t, mimeType: n } = await
|
|
2087
|
-
r && URL.revokeObjectURL(r.previewUrl),
|
|
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
|
-
|
|
2250
|
+
R({ uploadError: u.imageUploadError });
|
|
2097
2251
|
}
|
|
2098
2252
|
}
|
|
2099
|
-
function
|
|
2100
|
-
let e =
|
|
2101
|
-
e && URL.revokeObjectURL(e.previewUrl),
|
|
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
|
|
2107
|
-
if (
|
|
2108
|
-
let i =
|
|
2260
|
+
async function ae(e) {
|
|
2261
|
+
if (L().isLoading || L().isUploading) return;
|
|
2262
|
+
let i = L().pendingAttachment;
|
|
2109
2263
|
if (!e && !i) return;
|
|
2110
|
-
|
|
2111
|
-
let a =
|
|
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 (
|
|
2117
|
-
|
|
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 (
|
|
2123
|
-
|
|
2124
|
-
let t =
|
|
2125
|
-
|
|
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
|
-
|
|
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,
|
|
2287
|
+
await B(e, I ?? void 0, z ?? void 0);
|
|
2134
2288
|
}
|
|
2135
|
-
function
|
|
2136
|
-
if (
|
|
2137
|
-
let e =
|
|
2138
|
-
|
|
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
|
|
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
|
-
|
|
2302
|
+
R({ messages: [...L().messages, e] });
|
|
2149
2303
|
return;
|
|
2150
2304
|
}
|
|
2151
2305
|
let t = d;
|
|
2152
2306
|
try {
|
|
2153
|
-
let n = await
|
|
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
|
-
|
|
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
|
-
|
|
2329
|
+
R({ messages: [...L().messages, e] });
|
|
2176
2330
|
}
|
|
2177
2331
|
}
|
|
2178
|
-
function
|
|
2179
|
-
let e = !
|
|
2180
|
-
|
|
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 =
|
|
2188
|
-
e && URL.revokeObjectURL(e.previewUrl),
|
|
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 {
|
|
2349
|
+
export { ot as t };
|