@active-reach/web-sdk 1.20.0 → 1.21.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/aegis.min.js +1 -1
- package/dist/aegis.min.js.map +1 -1
- package/dist/cdn.d.ts.map +1 -1
- package/dist/chat/AegisChat.d.ts +24 -0
- package/dist/chat/AegisChat.d.ts.map +1 -1
- package/dist/chat/index.d.ts +1 -1
- package/dist/chat/index.d.ts.map +1 -1
- package/dist/inapp/AegisInAppManager.d.ts +17 -1
- package/dist/inapp/AegisInAppManager.d.ts.map +1 -1
- package/dist/inapp/renderPreview.d.ts +16 -1
- package/dist/inapp/renderPreview.d.ts.map +1 -1
- package/dist/inapp/renderers/active-web-chat.d.ts +7 -0
- package/dist/inapp/renderers/active-web-chat.d.ts.map +1 -1
- package/dist/inapp/renderers/hero.d.ts +23 -0
- package/dist/inapp/renderers/hero.d.ts.map +1 -0
- package/dist/inapp/renderers/index.d.ts +1 -0
- package/dist/inapp/renderers/index.d.ts.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +582 -126
- package/dist/index.js.map +1 -1
- package/dist/runtime/AegisMessageRuntime.d.ts +1 -1
- package/dist/runtime/AegisMessageRuntime.d.ts.map +1 -1
- package/package.json +2 -2
package/dist/index.js
CHANGED
|
@@ -2095,7 +2095,7 @@ function renderGame(ctx, subType) {
|
|
|
2095
2095
|
fn(ctx);
|
|
2096
2096
|
return true;
|
|
2097
2097
|
}
|
|
2098
|
-
const ASPECT = { "16:9": "16 / 9", "9:16": "9 / 16", "1:1": "1 / 1", "4:5": "4 / 5" };
|
|
2098
|
+
const ASPECT$1 = { "16:9": "16 / 9", "9:16": "9 / 16", "1:1": "1 / 1", "4:5": "4 / 5" };
|
|
2099
2099
|
function buildVideo(ctx, aspect, autoplay, loop) {
|
|
2100
2100
|
var _a;
|
|
2101
2101
|
const { campaign, sanitizeUrl } = ctx;
|
|
@@ -2103,7 +2103,7 @@ function buildVideo(ctx, aspect, autoplay, loop) {
|
|
|
2103
2103
|
const videoUrl = sanitizeUrl(ic.video_url || campaign.video_url || "");
|
|
2104
2104
|
const poster = campaign.image_url ? sanitizeUrl(campaign.image_url) : null;
|
|
2105
2105
|
const wrap = document.createElement("div");
|
|
2106
|
-
wrap.style.cssText = `position:relative;width:100%;aspect-ratio:${ASPECT[aspect] || ASPECT["16:9"]};background:#0b1220;border-radius:14px;overflow:hidden;`;
|
|
2106
|
+
wrap.style.cssText = `position:relative;width:100%;aspect-ratio:${ASPECT$1[aspect] || ASPECT$1["16:9"]};background:#0b1220;border-radius:14px;overflow:hidden;`;
|
|
2107
2107
|
if (videoUrl) {
|
|
2108
2108
|
const vid = document.createElement("video");
|
|
2109
2109
|
vid.src = videoUrl;
|
|
@@ -2272,11 +2272,179 @@ function renderVideoInline(ctx, target) {
|
|
|
2272
2272
|
target.appendChild(banner);
|
|
2273
2273
|
return true;
|
|
2274
2274
|
}
|
|
2275
|
+
const HEX = /^#[0-9a-fA-F]{3,8}$/;
|
|
2276
|
+
function safeColor(c, fallback) {
|
|
2277
|
+
return c && HEX.test(c) ? c : fallback;
|
|
2278
|
+
}
|
|
2279
|
+
const RADIUS = { none: "0", lg: "12px", xl: "16px", "2xl": "20px" };
|
|
2280
|
+
const ASPECT = { "16:9": "16 / 9", "4:3": "4 / 3", "21:9": "21 / 9" };
|
|
2281
|
+
function cardHeadline(c) {
|
|
2282
|
+
return c.headline ?? c.title ?? "";
|
|
2283
|
+
}
|
|
2284
|
+
function cardSub(c) {
|
|
2285
|
+
return c.subhead ?? c.body ?? "";
|
|
2286
|
+
}
|
|
2287
|
+
function cardCta(c) {
|
|
2288
|
+
return c.cta_label ?? c.cta_text ?? "";
|
|
2289
|
+
}
|
|
2290
|
+
function cardUrl(c) {
|
|
2291
|
+
if (c.cta_url) return c.cta_url;
|
|
2292
|
+
const t = c.cta_target;
|
|
2293
|
+
if (t && t.value) return t.type === "category" ? `?category=${encodeURIComponent(t.value)}` : t.value;
|
|
2294
|
+
return "";
|
|
2295
|
+
}
|
|
2296
|
+
function renderHeroInline(ctx, target) {
|
|
2297
|
+
const { campaign, sanitizeUrl, trackEvent } = ctx;
|
|
2298
|
+
const ic = campaign.interactive_config || {};
|
|
2299
|
+
const cards = Array.isArray(ic.cards) ? ic.cards : [];
|
|
2300
|
+
if (cards.length === 0) return false;
|
|
2301
|
+
const chrome = ic.chrome || {};
|
|
2302
|
+
const accent = safeColor(
|
|
2303
|
+
chrome.accent && chrome.accent !== "brand" ? chrome.accent : campaign.background_color,
|
|
2304
|
+
"#4169e1"
|
|
2305
|
+
);
|
|
2306
|
+
const radius = RADIUS[chrome.radius ?? "2xl"] ?? RADIUS["2xl"];
|
|
2307
|
+
const variant = chrome.variant ?? "hero_fullbleed";
|
|
2308
|
+
if (variant === "announcement_bar") {
|
|
2309
|
+
const c = cards[0];
|
|
2310
|
+
const bar = document.createElement("div");
|
|
2311
|
+
bar.style.cssText = `display:flex;align-items:center;justify-content:center;gap:10px;background:${accent};color:#fff;padding:8px 14px;font:600 13px/1.3 Inter,system-ui,sans-serif;text-align:center;`;
|
|
2312
|
+
bar.textContent = [cardHeadline(c), cardSub(c)].filter(Boolean).join(" · ");
|
|
2313
|
+
const url = sanitizeUrl(cardUrl(c));
|
|
2314
|
+
if (url && cardCta(c)) {
|
|
2315
|
+
const a = document.createElement("span");
|
|
2316
|
+
a.style.cssText = "text-decoration:underline;cursor:pointer;white-space:nowrap;";
|
|
2317
|
+
a.textContent = cardCta(c);
|
|
2318
|
+
a.addEventListener("click", () => {
|
|
2319
|
+
var _a;
|
|
2320
|
+
trackEvent(campaign.id, "clicked");
|
|
2321
|
+
(_a = ctx.navigate) == null ? void 0 : _a.call(ctx, url);
|
|
2322
|
+
});
|
|
2323
|
+
bar.appendChild(a);
|
|
2324
|
+
}
|
|
2325
|
+
target.appendChild(bar);
|
|
2326
|
+
trackEvent(campaign.id, "impression");
|
|
2327
|
+
return true;
|
|
2328
|
+
}
|
|
2329
|
+
const root = document.createElement("div");
|
|
2330
|
+
root.style.cssText = `position:relative;width:100%;overflow:hidden;border-radius:${radius};box-shadow:0 1px 2px rgba(16,24,40,0.06);${chrome.aspect_ratio && ASPECT[chrome.aspect_ratio] ? `aspect-ratio:${ASPECT[chrome.aspect_ratio]};` : "min-height:300px;"}`;
|
|
2331
|
+
root.setAttribute("data-campaign-id", campaign.id);
|
|
2332
|
+
const track = document.createElement("div");
|
|
2333
|
+
track.style.cssText = "display:flex;height:100%;width:100%;transition:transform 0.5s ease;";
|
|
2334
|
+
root.appendChild(track);
|
|
2335
|
+
const overlayCss = chrome.overlay === "none" ? "" : chrome.overlay === "full-scrim" ? "background:linear-gradient(0deg,rgba(0,0,0,0.55),rgba(0,0,0,0.25));" : "background:linear-gradient(to top right,rgba(0,0,0,0.7),rgba(0,0,0,0.25) 45%,transparent);";
|
|
2336
|
+
const justify = chrome.text_position === "center" ? "center" : "flex-end";
|
|
2337
|
+
const align = chrome.text_position === "bottom-left" || !chrome.text_position ? "flex-start" : "center";
|
|
2338
|
+
cards.forEach((c, i) => {
|
|
2339
|
+
const slide = document.createElement("div");
|
|
2340
|
+
slide.style.cssText = "position:relative;flex:0 0 100%;width:100%;height:100%;min-height:inherit;background:#f1f5f9;";
|
|
2341
|
+
const videoUrl = sanitizeUrl(c.video_url ?? "");
|
|
2342
|
+
const isVideo = !!videoUrl || c.media_type === "video";
|
|
2343
|
+
const mediaUrl = isVideo ? videoUrl || sanitizeUrl(c.media_url ?? "") : sanitizeUrl(c.image_url ?? c.media_url ?? "");
|
|
2344
|
+
if (mediaUrl) {
|
|
2345
|
+
if (isVideo) {
|
|
2346
|
+
const v = document.createElement("video");
|
|
2347
|
+
v.src = mediaUrl;
|
|
2348
|
+
v.autoplay = true;
|
|
2349
|
+
v.muted = true;
|
|
2350
|
+
v.loop = true;
|
|
2351
|
+
v.playsInline = true;
|
|
2352
|
+
v.style.cssText = "position:absolute;inset:0;width:100%;height:100%;object-fit:cover;";
|
|
2353
|
+
slide.appendChild(v);
|
|
2354
|
+
} else {
|
|
2355
|
+
const img = document.createElement("div");
|
|
2356
|
+
img.style.cssText = `position:absolute;inset:0;background:url("${mediaUrl}") center/cover no-repeat;`;
|
|
2357
|
+
slide.appendChild(img);
|
|
2358
|
+
}
|
|
2359
|
+
}
|
|
2360
|
+
if (overlayCss) {
|
|
2361
|
+
const scrim = document.createElement("div");
|
|
2362
|
+
scrim.style.cssText = `position:absolute;inset:0;${overlayCss}`;
|
|
2363
|
+
slide.appendChild(scrim);
|
|
2364
|
+
}
|
|
2365
|
+
const content = document.createElement("div");
|
|
2366
|
+
content.style.cssText = `position:absolute;inset:0;display:flex;flex-direction:column;justify-content:${justify};align-items:${align};gap:6px;padding:24px;text-align:${align === "center" ? "center" : "left"};`;
|
|
2367
|
+
const h = cardHeadline(c);
|
|
2368
|
+
if (h) {
|
|
2369
|
+
const head = document.createElement("h2");
|
|
2370
|
+
head.textContent = h;
|
|
2371
|
+
head.style.cssText = "margin:0;color:#fff;font:800 24px/1.2 Inter Tight,Inter,system-ui,sans-serif;letter-spacing:-0.02em;text-shadow:0 1px 8px rgba(0,0,0,0.35);max-width:90%;";
|
|
2372
|
+
content.appendChild(head);
|
|
2373
|
+
}
|
|
2374
|
+
const s = cardSub(c);
|
|
2375
|
+
if (s) {
|
|
2376
|
+
const sub = document.createElement("p");
|
|
2377
|
+
sub.textContent = s;
|
|
2378
|
+
sub.style.cssText = "margin:0;color:rgba(255,255,255,0.92);font:500 14px/1.4 Inter,system-ui,sans-serif;text-shadow:0 1px 6px rgba(0,0,0,0.3);max-width:90%;";
|
|
2379
|
+
content.appendChild(sub);
|
|
2380
|
+
}
|
|
2381
|
+
const cta = cardCta(c);
|
|
2382
|
+
const url = sanitizeUrl(cardUrl(c));
|
|
2383
|
+
if (cta && chrome.cta_style !== "none") {
|
|
2384
|
+
const btn = document.createElement("button");
|
|
2385
|
+
btn.textContent = cta;
|
|
2386
|
+
btn.style.cssText = chrome.cta_style === "underline" ? `margin-top:6px;background:none;border:none;color:#fff;font:700 14px Inter,system-ui,sans-serif;text-decoration:underline;cursor:pointer;padding:0;` : `margin-top:8px;background:${accent};color:#fff;border:none;border-radius:999px;padding:9px 18px;font:700 13px Inter,system-ui,sans-serif;cursor:pointer;box-shadow:0 4px 12px rgba(0,0,0,0.2);`;
|
|
2387
|
+
btn.addEventListener("click", () => {
|
|
2388
|
+
var _a;
|
|
2389
|
+
trackEvent(campaign.id, "clicked", { stepId: `card_${i}` });
|
|
2390
|
+
if (url) (_a = ctx.navigate) == null ? void 0 : _a.call(ctx, url);
|
|
2391
|
+
});
|
|
2392
|
+
content.appendChild(btn);
|
|
2393
|
+
}
|
|
2394
|
+
slide.appendChild(content);
|
|
2395
|
+
track.appendChild(slide);
|
|
2396
|
+
});
|
|
2397
|
+
const dotEls = [];
|
|
2398
|
+
let activeIdx = 0;
|
|
2399
|
+
const goto = (idx) => {
|
|
2400
|
+
activeIdx = (idx % cards.length + cards.length) % cards.length;
|
|
2401
|
+
track.style.transform = `translateX(-${activeIdx * 100}%)`;
|
|
2402
|
+
dotEls.forEach((d, i) => {
|
|
2403
|
+
d.style.width = i === activeIdx ? "18px" : "6px";
|
|
2404
|
+
d.style.background = i === activeIdx ? accent : "rgba(255,255,255,0.7)";
|
|
2405
|
+
});
|
|
2406
|
+
};
|
|
2407
|
+
const dots = document.createElement("div");
|
|
2408
|
+
dots.style.cssText = "position:absolute;bottom:8px;left:50%;transform:translateX(-50%);display:flex;gap:6px;z-index:2;";
|
|
2409
|
+
if (cards.length > 1) {
|
|
2410
|
+
cards.forEach((_, i) => {
|
|
2411
|
+
const dot = document.createElement("span");
|
|
2412
|
+
dot.style.cssText = "width:6px;height:6px;border-radius:999px;background:rgba(255,255,255,0.7);transition:all 0.25s;cursor:pointer;";
|
|
2413
|
+
dot.addEventListener("click", () => goto(i));
|
|
2414
|
+
dotEls.push(dot);
|
|
2415
|
+
dots.appendChild(dot);
|
|
2416
|
+
});
|
|
2417
|
+
root.appendChild(dots);
|
|
2418
|
+
}
|
|
2419
|
+
target.appendChild(root);
|
|
2420
|
+
goto(0);
|
|
2421
|
+
if (cards.length > 1 && chrome.loop !== false) {
|
|
2422
|
+
const ms = typeof chrome.autoplay_ms === "number" && chrome.autoplay_ms >= 1500 ? chrome.autoplay_ms : 4e3;
|
|
2423
|
+
let timer = window.setInterval(() => goto(activeIdx + 1), ms);
|
|
2424
|
+
root.addEventListener("mouseenter", () => window.clearInterval(timer));
|
|
2425
|
+
root.addEventListener("mouseleave", () => {
|
|
2426
|
+
timer = window.setInterval(() => goto(activeIdx + 1), ms);
|
|
2427
|
+
});
|
|
2428
|
+
}
|
|
2429
|
+
trackEvent(campaign.id, "impression");
|
|
2430
|
+
return true;
|
|
2431
|
+
}
|
|
2275
2432
|
const STYLE_ID = "aegis-chat-styles";
|
|
2276
2433
|
const POLL_INTERVAL_MS = 5e3;
|
|
2434
|
+
let currentLauncher = null;
|
|
2435
|
+
function getCurrentLauncher() {
|
|
2436
|
+
return currentLauncher;
|
|
2437
|
+
}
|
|
2438
|
+
function openChat(prefill) {
|
|
2439
|
+
currentLauncher == null ? void 0 : currentLauncher.openPanel(prefill);
|
|
2440
|
+
}
|
|
2441
|
+
function closeChat() {
|
|
2442
|
+
currentLauncher == null ? void 0 : currentLauncher.closePanel();
|
|
2443
|
+
}
|
|
2277
2444
|
const ATTENTION_DELAY_MS = 4500;
|
|
2278
2445
|
class AegisChat {
|
|
2279
2446
|
constructor(config) {
|
|
2447
|
+
this.sessionResumed = false;
|
|
2280
2448
|
this.open = false;
|
|
2281
2449
|
this.initialized = false;
|
|
2282
2450
|
this.unread = 0;
|
|
@@ -2294,12 +2462,14 @@ class AegisChat {
|
|
|
2294
2462
|
this.icon = config.icon ?? "sparkle";
|
|
2295
2463
|
this.logoUrl = config.logoUrl;
|
|
2296
2464
|
this.position = config.position ?? "bottom-right";
|
|
2465
|
+
this.displayMode = config.displayMode ?? "bubble";
|
|
2297
2466
|
this.agentPersona = config.agentPersona;
|
|
2298
2467
|
this.quickReplies = config.quickReplies;
|
|
2299
2468
|
this.onSessionStart = config.onSessionStart;
|
|
2300
2469
|
this.onSessionEnd = config.onSessionEnd;
|
|
2301
2470
|
this.onMessageSent = config.onMessageSent;
|
|
2302
2471
|
this.anonymousId = this.readAnonId();
|
|
2472
|
+
this.contactId = this.contactId ?? this.readStoredContactId();
|
|
2303
2473
|
}
|
|
2304
2474
|
// ── Lifecycle ────────────────────────────────────────────────────────────
|
|
2305
2475
|
initialize() {
|
|
@@ -2307,7 +2477,8 @@ class AegisChat {
|
|
|
2307
2477
|
this.initialized = true;
|
|
2308
2478
|
this.injectStyles();
|
|
2309
2479
|
this.mount();
|
|
2310
|
-
this
|
|
2480
|
+
currentLauncher = this;
|
|
2481
|
+
if (this.displayMode !== "nav") this.scheduleAttention();
|
|
2311
2482
|
}
|
|
2312
2483
|
/** Called by the runtime when the visitor identifies. */
|
|
2313
2484
|
updateContactId(contactId) {
|
|
@@ -2330,7 +2501,7 @@ class AegisChat {
|
|
|
2330
2501
|
(_c = this.bubble) == null ? void 0 : _c.classList.add("aegis-chat-bubble--hidden");
|
|
2331
2502
|
this.clearUnread();
|
|
2332
2503
|
if (prefill && this.input) this.input.value = prefill;
|
|
2333
|
-
void this.
|
|
2504
|
+
void this.resumeSession();
|
|
2334
2505
|
this.startPolling();
|
|
2335
2506
|
(_d = this.input) == null ? void 0 : _d.focus();
|
|
2336
2507
|
}
|
|
@@ -2355,13 +2526,22 @@ class AegisChat {
|
|
|
2355
2526
|
this.stopPolling();
|
|
2356
2527
|
(_a = this.root) == null ? void 0 : _a.remove();
|
|
2357
2528
|
this.initialized = false;
|
|
2529
|
+
if (currentLauncher === this) currentLauncher = null;
|
|
2358
2530
|
}
|
|
2359
2531
|
// ── Send ─────────────────────────────────────────────────────────────────
|
|
2360
|
-
async send(text) {
|
|
2532
|
+
async send(text, media) {
|
|
2361
2533
|
var _a;
|
|
2362
|
-
const
|
|
2363
|
-
if (!
|
|
2364
|
-
|
|
2534
|
+
const caption2 = text.trim();
|
|
2535
|
+
if (!caption2 && !media) return;
|
|
2536
|
+
const message = caption2 || (media ? media.type === "image" ? "Sent a photo 📷" : "Sent a file 📎" : "");
|
|
2537
|
+
this.appendBubble({
|
|
2538
|
+
id: `local_${Date.now()}`,
|
|
2539
|
+
sender: "customer",
|
|
2540
|
+
role: "user",
|
|
2541
|
+
content: message,
|
|
2542
|
+
media_url: (media == null ? void 0 : media.url) ?? null,
|
|
2543
|
+
media_type: (media == null ? void 0 : media.type) ?? null
|
|
2544
|
+
});
|
|
2365
2545
|
this.pendingEcho.push(message);
|
|
2366
2546
|
if (this.input) {
|
|
2367
2547
|
this.input.value = "";
|
|
@@ -2377,6 +2557,8 @@ class AegisChat {
|
|
|
2377
2557
|
channel: this.channel,
|
|
2378
2558
|
anonymous_id: this.anonymousId,
|
|
2379
2559
|
contact_id: this.contactId,
|
|
2560
|
+
media_url: media == null ? void 0 : media.url,
|
|
2561
|
+
media_type: media == null ? void 0 : media.type,
|
|
2380
2562
|
// Active Web Chat — binds the campaign-configured persona. Optional;
|
|
2381
2563
|
// the backend falls back to the tenant default if unknown/absent
|
|
2382
2564
|
// (honored server-side in Phase E). JSON.stringify drops it if absent.
|
|
@@ -2395,6 +2577,7 @@ class AegisChat {
|
|
|
2395
2577
|
} catch {
|
|
2396
2578
|
}
|
|
2397
2579
|
this.contactId = data.contact_id;
|
|
2580
|
+
this.persistContactId(data.contact_id);
|
|
2398
2581
|
this.sseTicket = data.sse_ticket;
|
|
2399
2582
|
this.connectSSE(data.sse_ticket);
|
|
2400
2583
|
void this.refreshHistory();
|
|
@@ -2403,6 +2586,51 @@ class AegisChat {
|
|
|
2403
2586
|
this.appendSystem("Sorry — your message could not be delivered. Please try again.");
|
|
2404
2587
|
}
|
|
2405
2588
|
}
|
|
2589
|
+
// ── Media attachments ─────────────────────────────────────────────────────
|
|
2590
|
+
/** Validate + upload a picked file, then send it as a media message. */
|
|
2591
|
+
async handleFile(file) {
|
|
2592
|
+
var _a;
|
|
2593
|
+
const allowed = /* @__PURE__ */ new Set(["image/jpeg", "image/png", "image/gif", "image/webp", "application/pdf"]);
|
|
2594
|
+
if (!allowed.has(file.type)) {
|
|
2595
|
+
this.appendSystem("That file type isn’t supported (images or PDF only).");
|
|
2596
|
+
return;
|
|
2597
|
+
}
|
|
2598
|
+
if (file.size > 8 * 1024 * 1024) {
|
|
2599
|
+
this.appendSystem("That file is too large (max 8 MB).");
|
|
2600
|
+
return;
|
|
2601
|
+
}
|
|
2602
|
+
try {
|
|
2603
|
+
const data = await this.fileToBase64(file);
|
|
2604
|
+
const res = await fetch(`${this.apiHost}/v1/chat/upload`, {
|
|
2605
|
+
method: "POST",
|
|
2606
|
+
headers: { "Content-Type": "application/json", "X-Aegis-Write-Key": this.writeKey },
|
|
2607
|
+
body: JSON.stringify({ data, content_type: file.type, filename: file.name })
|
|
2608
|
+
});
|
|
2609
|
+
if (!res.ok) {
|
|
2610
|
+
this.log("upload failed", res.status);
|
|
2611
|
+
this.appendSystem("Sorry — that attachment couldn’t be uploaded.");
|
|
2612
|
+
return;
|
|
2613
|
+
}
|
|
2614
|
+
const out = await res.json();
|
|
2615
|
+
await this.send(((_a = this.input) == null ? void 0 : _a.value) ?? "", { url: out.media_url, type: out.media_type });
|
|
2616
|
+
} catch (err) {
|
|
2617
|
+
this.log("upload error", err);
|
|
2618
|
+
this.appendSystem("Sorry — that attachment couldn’t be uploaded.");
|
|
2619
|
+
}
|
|
2620
|
+
}
|
|
2621
|
+
/** Read a File as bare base64 (strip the `data:…;base64,` prefix). */
|
|
2622
|
+
fileToBase64(file) {
|
|
2623
|
+
return new Promise((resolve, reject) => {
|
|
2624
|
+
const reader = new FileReader();
|
|
2625
|
+
reader.onload = () => {
|
|
2626
|
+
const result = String(reader.result || "");
|
|
2627
|
+
const comma = result.indexOf(",");
|
|
2628
|
+
resolve(comma >= 0 ? result.slice(comma + 1) : result);
|
|
2629
|
+
};
|
|
2630
|
+
reader.onerror = () => reject(reader.error);
|
|
2631
|
+
reader.readAsDataURL(file);
|
|
2632
|
+
});
|
|
2633
|
+
}
|
|
2406
2634
|
// ── Reply transport: SSE nudge + history refetch (poll fallback) ──────────
|
|
2407
2635
|
connectSSE(ticket) {
|
|
2408
2636
|
if (!this.open) return;
|
|
@@ -2540,6 +2768,21 @@ class AegisChat {
|
|
|
2540
2768
|
void this.send(input.value);
|
|
2541
2769
|
}
|
|
2542
2770
|
});
|
|
2771
|
+
const fileInput = document.createElement("input");
|
|
2772
|
+
fileInput.type = "file";
|
|
2773
|
+
fileInput.accept = "image/*,application/pdf";
|
|
2774
|
+
fileInput.className = "aegis-chat-fileinput";
|
|
2775
|
+
fileInput.addEventListener("change", () => {
|
|
2776
|
+
const f = fileInput.files && fileInput.files[0];
|
|
2777
|
+
if (f) void this.handleFile(f);
|
|
2778
|
+
fileInput.value = "";
|
|
2779
|
+
});
|
|
2780
|
+
const attachBtn = document.createElement("button");
|
|
2781
|
+
attachBtn.type = "button";
|
|
2782
|
+
attachBtn.className = "aegis-chat-attach";
|
|
2783
|
+
attachBtn.setAttribute("aria-label", "Attach a file");
|
|
2784
|
+
attachBtn.innerHTML = '<svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M21.44 11.05l-9.19 9.19a6 6 0 0 1-8.49-8.49l9.19-9.19a4 4 0 0 1 5.66 5.66l-9.2 9.19a2 2 0 0 1-2.83-2.83l8.49-8.48"/></svg>';
|
|
2785
|
+
attachBtn.addEventListener("click", () => fileInput.click());
|
|
2543
2786
|
const sendBtn = document.createElement("button");
|
|
2544
2787
|
sendBtn.type = "submit";
|
|
2545
2788
|
sendBtn.className = "aegis-chat-send";
|
|
@@ -2549,8 +2792,10 @@ class AegisChat {
|
|
|
2549
2792
|
e.preventDefault();
|
|
2550
2793
|
void this.send(input.value);
|
|
2551
2794
|
});
|
|
2795
|
+
composer.appendChild(attachBtn);
|
|
2552
2796
|
composer.appendChild(input);
|
|
2553
2797
|
composer.appendChild(sendBtn);
|
|
2798
|
+
composer.appendChild(fileInput);
|
|
2554
2799
|
panel.appendChild(header);
|
|
2555
2800
|
panel.appendChild(thread);
|
|
2556
2801
|
panel.appendChild(composer);
|
|
@@ -2570,8 +2815,10 @@ class AegisChat {
|
|
|
2570
2815
|
tip.appendChild(tipClose);
|
|
2571
2816
|
tip.addEventListener("click", () => this.openPanel());
|
|
2572
2817
|
root.appendChild(panel);
|
|
2573
|
-
|
|
2574
|
-
|
|
2818
|
+
if (this.displayMode !== "nav") {
|
|
2819
|
+
root.appendChild(tip);
|
|
2820
|
+
root.appendChild(bubble);
|
|
2821
|
+
}
|
|
2575
2822
|
document.body.appendChild(root);
|
|
2576
2823
|
this.greetingTip = tip;
|
|
2577
2824
|
this.root = root;
|
|
@@ -2609,6 +2856,26 @@ class AegisChat {
|
|
|
2609
2856
|
if (msg.id) this.renderedIds.add(msg.id);
|
|
2610
2857
|
const row = document.createElement("div");
|
|
2611
2858
|
row.className = `aegis-chat-msg aegis-chat-msg--${msg.sender}`;
|
|
2859
|
+
if (msg.media_url) {
|
|
2860
|
+
if (msg.media_type === "image") {
|
|
2861
|
+
const img = document.createElement("img");
|
|
2862
|
+
img.className = "aegis-chat-media-img";
|
|
2863
|
+
img.src = msg.media_url;
|
|
2864
|
+
img.alt = "attachment";
|
|
2865
|
+
img.loading = "lazy";
|
|
2866
|
+
const url = msg.media_url;
|
|
2867
|
+
img.addEventListener("click", () => window.open(url, "_blank", "noopener"));
|
|
2868
|
+
row.appendChild(img);
|
|
2869
|
+
} else {
|
|
2870
|
+
const a = document.createElement("a");
|
|
2871
|
+
a.className = "aegis-chat-media-file";
|
|
2872
|
+
a.href = msg.media_url;
|
|
2873
|
+
a.target = "_blank";
|
|
2874
|
+
a.rel = "noopener noreferrer";
|
|
2875
|
+
a.textContent = "📎 Attachment";
|
|
2876
|
+
row.appendChild(a);
|
|
2877
|
+
}
|
|
2878
|
+
}
|
|
2612
2879
|
if (msg.content) {
|
|
2613
2880
|
const bubble = document.createElement("div");
|
|
2614
2881
|
bubble.className = "aegis-chat-bubbletext";
|
|
@@ -2700,6 +2967,54 @@ class AegisChat {
|
|
|
2700
2967
|
return void 0;
|
|
2701
2968
|
}
|
|
2702
2969
|
}
|
|
2970
|
+
readStoredContactId() {
|
|
2971
|
+
if (typeof document === "undefined") return void 0;
|
|
2972
|
+
try {
|
|
2973
|
+
return new Storage().get("aegis_chat_cid") ?? void 0;
|
|
2974
|
+
} catch {
|
|
2975
|
+
return void 0;
|
|
2976
|
+
}
|
|
2977
|
+
}
|
|
2978
|
+
persistContactId(id) {
|
|
2979
|
+
if (!id || typeof document === "undefined") return;
|
|
2980
|
+
try {
|
|
2981
|
+
new Storage().set("aegis_chat_cid", id, 365);
|
|
2982
|
+
} catch {
|
|
2983
|
+
}
|
|
2984
|
+
}
|
|
2985
|
+
/** Restore a returning visitor's thread on open. Resolves an existing contact
|
|
2986
|
+
* + mints a per-session ticket WITHOUT sending a message (history is ticket-
|
|
2987
|
+
* gated). No-ops for brand-new visitors and once a ticket is already held. */
|
|
2988
|
+
async resumeSession() {
|
|
2989
|
+
if (this.sseTicket) {
|
|
2990
|
+
void this.refreshHistory();
|
|
2991
|
+
return;
|
|
2992
|
+
}
|
|
2993
|
+
if (this.sessionResumed) return;
|
|
2994
|
+
this.sessionResumed = true;
|
|
2995
|
+
if (!this.contactId && !this.anonymousId) return;
|
|
2996
|
+
try {
|
|
2997
|
+
const res = await fetch(`${this.apiHost}/v1/chat/session`, {
|
|
2998
|
+
method: "POST",
|
|
2999
|
+
headers: { "Content-Type": "application/json", "X-Aegis-Write-Key": this.writeKey },
|
|
3000
|
+
body: JSON.stringify({
|
|
3001
|
+
anonymous_id: this.anonymousId,
|
|
3002
|
+
contact_id: this.contactId,
|
|
3003
|
+
channel: this.channel
|
|
3004
|
+
})
|
|
3005
|
+
});
|
|
3006
|
+
if (!res.ok) return;
|
|
3007
|
+
const data = await res.json();
|
|
3008
|
+
if (!data.contact_id || !data.sse_ticket) return;
|
|
3009
|
+
this.contactId = data.contact_id;
|
|
3010
|
+
this.sseTicket = data.sse_ticket;
|
|
3011
|
+
this.persistContactId(data.contact_id);
|
|
3012
|
+
await this.refreshHistory();
|
|
3013
|
+
if (this.open) this.connectSSE(data.sse_ticket);
|
|
3014
|
+
} catch (err) {
|
|
3015
|
+
this.log("resume session failed", err);
|
|
3016
|
+
}
|
|
3017
|
+
}
|
|
2703
3018
|
// ── Typing indicator ───────────────────────────────────────────────────────
|
|
2704
3019
|
showTyping() {
|
|
2705
3020
|
if (!this.thread || this.typingEl) return;
|
|
@@ -2800,11 +3115,19 @@ const CHAT_CSS = `
|
|
|
2800
3115
|
.aegis-chat-input{flex:1;resize:none;border:1px solid #e2e8f0;border-radius:12px;padding:9px 12px;font-size:14px;font-family:inherit;max-height:96px;outline:none}
|
|
2801
3116
|
.aegis-chat-input:focus{border-color:var(--aegis-chat-accent,#4169e1)}
|
|
2802
3117
|
.aegis-chat-send{width:40px;height:40px;border-radius:9999px;border:none;background:var(--aegis-chat-accent,#4169e1);color:#fff;display:flex;align-items:center;justify-content:center;cursor:pointer;flex:0 0 auto}
|
|
3118
|
+
.aegis-chat-attach{width:38px;height:38px;border-radius:9999px;border:none;background:transparent;color:#64748b;display:flex;align-items:center;justify-content:center;cursor:pointer;flex:0 0 auto;transition:background .15s ease,color .15s ease}
|
|
3119
|
+
.aegis-chat-attach:hover{background:#f1f5f9;color:var(--aegis-chat-accent,#4169e1)}
|
|
3120
|
+
.aegis-chat-fileinput{display:none}
|
|
3121
|
+
.aegis-chat-media-img{max-width:200px;max-height:200px;border-radius:12px;object-fit:cover;cursor:pointer;display:block}
|
|
3122
|
+
.aegis-chat-media-file{display:inline-flex;align-items:center;gap:6px;padding:8px 12px;border-radius:12px;background:#fff;border:1px solid #e2e8f0;font-size:13px;color:#0f172a;text-decoration:none;max-width:220px}
|
|
3123
|
+
.aegis-chat-msg--customer .aegis-chat-media-file{background:rgba(255,255,255,.18);border-color:transparent;color:#fff}
|
|
2803
3124
|
/* Mobile: raise the bubble above the storefront's full-width cart bar so they
|
|
2804
3125
|
never overlap; widen the panel and reduce the tooltip width. */
|
|
2805
|
-
@media (max-width:
|
|
3126
|
+
@media (max-width:767px){
|
|
2806
3127
|
.aegis-chat-root{bottom:84px;right:16px}
|
|
2807
|
-
|
|
3128
|
+
/* Full-page chat on mobile — the open panel covers the whole viewport (incl.
|
|
3129
|
+
the bottom nav) like a native chat screen, instead of a floating card. */
|
|
3130
|
+
.aegis-chat-panel{position:fixed;inset:0;left:0;right:0;width:100vw;height:100vh;height:100dvh;max-width:none;max-height:none;border-radius:0}
|
|
2808
3131
|
.aegis-chat-tip{max-width:200px}
|
|
2809
3132
|
}
|
|
2810
3133
|
`;
|
|
@@ -3376,6 +3699,10 @@ function renderActiveWebChat(ctx, creds) {
|
|
|
3376
3699
|
icon: icon === "sparkle" || icon === "chat" || icon === "logo" ? icon : void 0,
|
|
3377
3700
|
logoUrl: logo ? ctx.sanitizeUrl(logo) ?? void 0 : void 0,
|
|
3378
3701
|
position: ic.chat_position === "bottom-left" ? "bottom-left" : void 0,
|
|
3702
|
+
// 'nav' = headless (no bubble); the host opens it via aegis.chat.open() or a
|
|
3703
|
+
// client_trigger. Defaults to 'bubble'. Per-device override via device_type
|
|
3704
|
+
// targeting on the campaign (e.g. a mobile campaign with chat_display_mode='nav').
|
|
3705
|
+
displayMode: ic.chat_display_mode === "nav" ? "nav" : void 0,
|
|
3379
3706
|
agentPersona: str(ic.chat_agent_persona),
|
|
3380
3707
|
quickReplies: Array.isArray(ic.chat_quick_replies) ? ic.chat_quick_replies.filter((q) => typeof q === "string") : void 0,
|
|
3381
3708
|
// Bridge the engine's session lifecycle to campaign analytics. Per the
|
|
@@ -3436,6 +3763,7 @@ const _AegisInAppManager = class _AegisInAppManager {
|
|
|
3436
3763
|
constructor(config) {
|
|
3437
3764
|
this.campaigns = [];
|
|
3438
3765
|
this.displayedCampaigns = /* @__PURE__ */ new Set();
|
|
3766
|
+
this._displaySizeMul = 1;
|
|
3439
3767
|
this.suppressedUntil = /* @__PURE__ */ new Map();
|
|
3440
3768
|
this.isInitialized = false;
|
|
3441
3769
|
this.reconnectAttempts = 0;
|
|
@@ -4015,7 +4343,13 @@ const _AegisInAppManager = class _AegisInAppManager {
|
|
|
4015
4343
|
const list = eligibleByCategory.get(key);
|
|
4016
4344
|
if (!list || list.length === 0) return;
|
|
4017
4345
|
slot.querySelectorAll(":scope > [data-aegis-slot-default]").forEach((d) => d.remove());
|
|
4018
|
-
const
|
|
4346
|
+
const attrMs = parseInt(slot.getAttribute("data-aegis-slot-rotate") || "0", 10);
|
|
4347
|
+
const declaredMs = list.reduce((m2, c) => {
|
|
4348
|
+
var _a;
|
|
4349
|
+
const v = Number((_a = c.interactive_config) == null ? void 0 : _a.slot_rotate_ms);
|
|
4350
|
+
return Number.isFinite(v) && v > m2 ? v : m2;
|
|
4351
|
+
}, 0);
|
|
4352
|
+
const rotateMs = attrMs > 0 ? attrMs : declaredMs;
|
|
4019
4353
|
if (rotateMs > 0 && list.length > 1) {
|
|
4020
4354
|
this.renderRotatingSlot(slot, list, rotateMs);
|
|
4021
4355
|
} else {
|
|
@@ -4198,6 +4532,13 @@ const _AegisInAppManager = class _AegisInAppManager {
|
|
|
4198
4532
|
this.displayedCampaigns.add(campaign.id);
|
|
4199
4533
|
this.addAnimationStyles();
|
|
4200
4534
|
const ic = campaign.interactive_config || {};
|
|
4535
|
+
const inlineMul = this._sizeMul(ic);
|
|
4536
|
+
if (inlineMul !== 1) {
|
|
4537
|
+
const sizer = document.createElement("div");
|
|
4538
|
+
sizer.style.cssText = `transform: scale(${inlineMul}); transform-origin: top center;`;
|
|
4539
|
+
target.appendChild(sizer);
|
|
4540
|
+
target = sizer;
|
|
4541
|
+
}
|
|
4201
4542
|
const { bg, text } = this._surfacePalette(campaign);
|
|
4202
4543
|
const submitUrl = options == null ? void 0 : options.submitUrl;
|
|
4203
4544
|
const _formFields = Array.isArray(ic.form_fields) ? ic.form_fields : null;
|
|
@@ -4214,70 +4555,73 @@ const _AegisInAppManager = class _AegisInAppManager {
|
|
|
4214
4555
|
}
|
|
4215
4556
|
return;
|
|
4216
4557
|
}
|
|
4217
|
-
|
|
4218
|
-
|
|
4219
|
-
|
|
4220
|
-
|
|
4221
|
-
|
|
4222
|
-
|
|
4223
|
-
|
|
4224
|
-
|
|
4225
|
-
|
|
4226
|
-
|
|
4227
|
-
|
|
4228
|
-
|
|
4229
|
-
|
|
4230
|
-
|
|
4231
|
-
|
|
4232
|
-
|
|
4233
|
-
|
|
4234
|
-
|
|
4235
|
-
|
|
4236
|
-
|
|
4237
|
-
|
|
4238
|
-
|
|
4239
|
-
|
|
4240
|
-
|
|
4241
|
-
|
|
4242
|
-
|
|
4243
|
-
|
|
4244
|
-
|
|
4245
|
-
|
|
4246
|
-
|
|
4247
|
-
|
|
4248
|
-
|
|
4249
|
-
|
|
4250
|
-
|
|
4251
|
-
|
|
4252
|
-
|
|
4253
|
-
|
|
4254
|
-
|
|
4255
|
-
|
|
4256
|
-
|
|
4257
|
-
|
|
4258
|
-
|
|
4259
|
-
|
|
4260
|
-
|
|
4261
|
-
|
|
4262
|
-
|
|
4263
|
-
|
|
4264
|
-
|
|
4265
|
-
|
|
4266
|
-
|
|
4267
|
-
|
|
4268
|
-
|
|
4269
|
-
|
|
4558
|
+
if (campaign.widget_category === "hero") {
|
|
4559
|
+
rendered = renderHeroInline(this.buildRenderContext(campaign), target);
|
|
4560
|
+
} else
|
|
4561
|
+
switch (campaign.sub_type) {
|
|
4562
|
+
case "star_rating":
|
|
4563
|
+
rendered = this.renderStarRatingSlot(
|
|
4564
|
+
campaign,
|
|
4565
|
+
ic,
|
|
4566
|
+
bg,
|
|
4567
|
+
text,
|
|
4568
|
+
target,
|
|
4569
|
+
submitUrl
|
|
4570
|
+
);
|
|
4571
|
+
break;
|
|
4572
|
+
case "nps_survey":
|
|
4573
|
+
rendered = this.renderNPSSurveySlot(
|
|
4574
|
+
campaign,
|
|
4575
|
+
ic,
|
|
4576
|
+
bg,
|
|
4577
|
+
text,
|
|
4578
|
+
target,
|
|
4579
|
+
submitUrl
|
|
4580
|
+
);
|
|
4581
|
+
break;
|
|
4582
|
+
// Parity tracker — built-in embedded gamification renderers (no
|
|
4583
|
+
// AegisMessageRuntime callback needed, so they work on the bill).
|
|
4584
|
+
case "spin_wheel":
|
|
4585
|
+
rendered = this.renderSpinWheelSlot(campaign, ic, bg, text, target);
|
|
4586
|
+
break;
|
|
4587
|
+
case "quick_poll":
|
|
4588
|
+
rendered = this.renderQuickPollSlot(campaign, ic, bg, text, target);
|
|
4589
|
+
break;
|
|
4590
|
+
case "carousel_cards":
|
|
4591
|
+
rendered = this.renderCarouselCardsSlot(campaign, ic, bg, text, target);
|
|
4592
|
+
break;
|
|
4593
|
+
case "countdown_offer":
|
|
4594
|
+
rendered = this.renderCountdownSlot(campaign, ic, bg, text, target);
|
|
4595
|
+
break;
|
|
4596
|
+
case "scratch_card":
|
|
4597
|
+
rendered = this.renderScratchCardSlot(campaign, ic, bg, text, target);
|
|
4598
|
+
break;
|
|
4599
|
+
case "custom_html":
|
|
4600
|
+
rendered = this.renderCustomHtmlSlot(campaign, ic, bg, text, target);
|
|
4601
|
+
break;
|
|
4602
|
+
case "stories":
|
|
4603
|
+
rendered = renderStoriesRings(this.buildRenderContext(campaign), target);
|
|
4604
|
+
break;
|
|
4605
|
+
case "video":
|
|
4606
|
+
rendered = renderVideoInline(this.buildRenderContext(campaign), target);
|
|
4607
|
+
break;
|
|
4608
|
+
case "progress_bar":
|
|
4609
|
+
rendered = renderProgressBarInline(this.buildRenderContext(campaign), target);
|
|
4610
|
+
break;
|
|
4611
|
+
case "quiz":
|
|
4612
|
+
rendered = this.renderQuizSlot(campaign, ic, bg, text, target);
|
|
4613
|
+
if (!rendered) {
|
|
4614
|
+
rendered = this.renderGenericCardSlot(campaign, ic, bg, text, target);
|
|
4615
|
+
}
|
|
4616
|
+
break;
|
|
4617
|
+
// Remaining sub_types (sticky_bar, progress_bar,
|
|
4618
|
+
// product_recommendation) render as a generic card on the bill slot
|
|
4619
|
+
// (overlay path handles their full UX); dedicated slot variants get added
|
|
4620
|
+
// here as merchants need them.
|
|
4621
|
+
default:
|
|
4270
4622
|
rendered = this.renderGenericCardSlot(campaign, ic, bg, text, target);
|
|
4271
|
-
|
|
4272
|
-
|
|
4273
|
-
// Remaining sub_types (sticky_bar, progress_bar,
|
|
4274
|
-
// product_recommendation) render as a generic card on the bill slot
|
|
4275
|
-
// (overlay path handles their full UX); dedicated slot variants get added
|
|
4276
|
-
// here as merchants need them.
|
|
4277
|
-
default:
|
|
4278
|
-
rendered = this.renderGenericCardSlot(campaign, ic, bg, text, target);
|
|
4279
|
-
break;
|
|
4280
|
-
}
|
|
4623
|
+
break;
|
|
4624
|
+
}
|
|
4281
4625
|
if (!rendered) return;
|
|
4282
4626
|
if (!(options == null ? void 0 : options.deferImpression)) {
|
|
4283
4627
|
this.trackEvent(campaign.id, "impression");
|
|
@@ -4618,6 +4962,8 @@ const _AegisInAppManager = class _AegisInAppManager {
|
|
|
4618
4962
|
const hubImg = cfgStr("spin_hub_image_url");
|
|
4619
4963
|
const wheelBgImg = cfgStr("wheel_background_url");
|
|
4620
4964
|
const pointerImg = cfgStr("pointer_image_url");
|
|
4965
|
+
const pointerCenter = (cfgStr("spin_pointer_position") || "top") === "center";
|
|
4966
|
+
const pointerBase = pointerCenter ? "translate(-50%, -100%)" : "translateX(-50%)";
|
|
4621
4967
|
const isUrl = (s) => /^https?:\/\//i.test(s);
|
|
4622
4968
|
const now = () => typeof performance !== "undefined" && performance.now ? performance.now() : Date.now();
|
|
4623
4969
|
let rotation = 0;
|
|
@@ -4677,7 +5023,7 @@ const _AegisInAppManager = class _AegisInAppManager {
|
|
|
4677
5023
|
vibrate(18);
|
|
4678
5024
|
};
|
|
4679
5025
|
const body = document.createElement("div");
|
|
4680
|
-
body.style.cssText = `padding: ${st.padY ?? 22}px ${st.padX ?? 20}px 20px; display: flex; flex-direction: column; align-items: center; gap:
|
|
5026
|
+
body.style.cssText = `padding: ${st.padY ?? 22}px ${st.padX ?? 20}px 20px; display: flex; flex-direction: column; align-items: center; gap: 10px;`;
|
|
4681
5027
|
if (campaign.title) {
|
|
4682
5028
|
const t = document.createElement("div");
|
|
4683
5029
|
t.style.cssText = `font-size: 18px; font-weight: 800; letter-spacing: -0.01em; text-align: center; font-family: 'Inter Tight', Inter, system-ui, -apple-system, sans-serif;`;
|
|
@@ -4695,11 +5041,55 @@ const _AegisInAppManager = class _AegisInAppManager {
|
|
|
4695
5041
|
const wheelWrap = document.createElement("div");
|
|
4696
5042
|
wheelWrap.style.cssText = `position: relative; width: ${SIZE}px; height: ${SIZE}px; filter: drop-shadow(0 10px 22px rgba(0,0,0,0.30));`;
|
|
4697
5043
|
const pointer = document.createElement("div");
|
|
4698
|
-
|
|
5044
|
+
if (pointerCenter) {
|
|
5045
|
+
const needleH = Math.round(radius * 0.42);
|
|
5046
|
+
pointer.style.cssText = `position: absolute; left: 50%; top: 50%; width: 20px; height: ${needleH}px; transform: ${pointerBase}; transform-origin: 50% 100%; z-index: 6; pointer-events: none;`;
|
|
5047
|
+
if (pointerImg) {
|
|
5048
|
+
const pim = document.createElement("img");
|
|
5049
|
+
pim.src = pointerImg;
|
|
5050
|
+
pim.alt = "";
|
|
5051
|
+
pim.style.cssText = "width: 100%; height: 100%; object-fit: contain; object-position: top; display: block; filter: drop-shadow(0 1px 2px rgba(0,0,0,0.4));";
|
|
5052
|
+
pointer.appendChild(pim);
|
|
5053
|
+
} else {
|
|
5054
|
+
const stem = document.createElement("div");
|
|
5055
|
+
stem.style.cssText = `position: absolute; left: 50%; bottom: 0; transform: translateX(-50%); width: 4px; height: 100%; background: ${pointerColor}; border-radius: 2px; box-shadow: 0 1px 2px rgba(0,0,0,0.35);`;
|
|
5056
|
+
const head = document.createElement("div");
|
|
5057
|
+
head.style.cssText = `position: absolute; left: 50%; top: -1px; transform: translateX(-50%); width: 0; height: 0; border-left: 8px solid transparent; border-right: 8px solid transparent; border-bottom: 14px solid ${pointerColor}; filter: drop-shadow(0 1px 1px rgba(0,0,0,0.4));`;
|
|
5058
|
+
pointer.appendChild(stem);
|
|
5059
|
+
pointer.appendChild(head);
|
|
5060
|
+
}
|
|
5061
|
+
} else if (pointerImg) {
|
|
5062
|
+
pointer.style.cssText = `position: absolute; left: 50%; top: -12px; transform: ${pointerBase}; transform-origin: 50% 0; width: 30px; height: 34px; z-index: 5;`;
|
|
5063
|
+
const pim = document.createElement("img");
|
|
5064
|
+
pim.src = pointerImg;
|
|
5065
|
+
pim.alt = "";
|
|
5066
|
+
pim.style.cssText = "width: 100%; height: 100%; object-fit: contain; display: block; filter: drop-shadow(0 2px 2px rgba(0,0,0,0.35));";
|
|
5067
|
+
pointer.appendChild(pim);
|
|
5068
|
+
} else {
|
|
5069
|
+
pointer.style.cssText = `position: absolute; left: 50%; top: -7px; transform: ${pointerBase}; transform-origin: 50% 0; width: 0; height: 0; border-left: 9px solid transparent; border-right: 9px solid transparent; border-top: 16px solid ${pointerColor}; z-index: 5; filter: drop-shadow(0 2px 2px rgba(0,0,0,0.35));`;
|
|
5070
|
+
}
|
|
4699
5071
|
const wheel = document.createElement("div");
|
|
4700
5072
|
const wheelFace = wheelBgImg ? `center / cover no-repeat url("${wheelBgImg}")` : `conic-gradient(${stops})`;
|
|
4701
|
-
|
|
5073
|
+
const wheelRim = wheelBgImg ? "0" : "5px solid #ffffff";
|
|
5074
|
+
const wheelShadow = wheelBgImg ? `0 0 0 2px ${text}2e` : `0 0 0 2px ${text}2e, inset 0 0 22px rgba(0,0,0,0.20)`;
|
|
5075
|
+
wheel.style.cssText = `position: relative; width: ${SIZE}px; height: ${SIZE}px; border-radius: 50%; border: ${wheelRim}; box-shadow: ${wheelShadow}; background: ${wheelFace}; overflow: hidden; will-change: transform; touch-action: none; cursor: ${spinMode === "button" ? "default" : "grab"};`;
|
|
4702
5076
|
if (idleAnim === "wobble") wheel.style.animation = "aegisSpinWobble 3s ease-in-out infinite";
|
|
5077
|
+
const sliceImgFrac = Math.max(40, Math.min(100, Number(ic.spin_slice_image_size) || 100)) / 100;
|
|
5078
|
+
if (!wheelBgImg) shown.forEach((s, i) => {
|
|
5079
|
+
const simg = typeof s.image_url === "string" ? s.image_url : "";
|
|
5080
|
+
if (!simg || !isUrl(simg)) return;
|
|
5081
|
+
const pts = ["50% 50%"];
|
|
5082
|
+
const steps = Math.max(2, Math.ceil(spans[i] / 6));
|
|
5083
|
+
for (let st2 = 0; st2 <= steps; st2++) {
|
|
5084
|
+
const a = (starts[i] + spans[i] * st2 / steps) * Math.PI / 180;
|
|
5085
|
+
const x = 50 + 50 * sliceImgFrac * Math.sin(a);
|
|
5086
|
+
const y = 50 - 50 * sliceImgFrac * Math.cos(a);
|
|
5087
|
+
pts.push(`${x.toFixed(2)}% ${y.toFixed(2)}%`);
|
|
5088
|
+
}
|
|
5089
|
+
const segEl = document.createElement("div");
|
|
5090
|
+
segEl.style.cssText = `position: absolute; inset: 0; background: center / cover no-repeat url("${simg}"); clip-path: polygon(${pts.join(",")}); pointer-events: none;`;
|
|
5091
|
+
wheel.appendChild(segEl);
|
|
5092
|
+
});
|
|
4703
5093
|
if (!wheelBgImg) starts.forEach((b) => {
|
|
4704
5094
|
const ln = document.createElement("div");
|
|
4705
5095
|
ln.style.cssText = `position: absolute; left: 50%; top: 0; width: 1.5px; height: 50%; background: rgba(255,255,255,0.55); transform-origin: bottom center; transform: translateX(-50%) rotate(${b}deg); pointer-events: none;`;
|
|
@@ -4711,17 +5101,6 @@ const _AegisInAppManager = class _AegisInAppManager {
|
|
|
4711
5101
|
const rText = (rHub + rRim) / 2;
|
|
4712
5102
|
if (!wheelBgImg) labels.forEach((label, i) => {
|
|
4713
5103
|
const mid = midOf(i);
|
|
4714
|
-
const wedgeImg = shown[i] && typeof shown[i].image_url === "string" ? shown[i].image_url : "";
|
|
4715
|
-
if (wedgeImg && isUrl(wedgeImg)) {
|
|
4716
|
-
const flipImg = mid > 180 && mid < 360;
|
|
4717
|
-
const isz = Math.max(18, Math.min(40, bandLen * 0.62));
|
|
4718
|
-
const wim = document.createElement("img");
|
|
4719
|
-
wim.src = wedgeImg;
|
|
4720
|
-
wim.alt = label || "";
|
|
4721
|
-
wim.style.cssText = `position: absolute; left: 50%; top: 50%; width: ${isz}px; height: ${isz}px; object-fit: contain; transform: translate(-50%, -50%) rotate(${mid}deg) translateY(-${rText}px) rotate(${flipImg ? 90 : -90}deg); filter: drop-shadow(0 1px 3px rgba(0,0,0,0.55)); pointer-events: none;`;
|
|
4722
|
-
wheel.appendChild(wim);
|
|
4723
|
-
return;
|
|
4724
|
-
}
|
|
4725
5104
|
const icoVal = shown[i] && typeof shown[i].icon === "string" ? shown[i].icon : "";
|
|
4726
5105
|
const chord = 2 * rText * Math.sin(spans[i] * Math.PI / 180 / 2);
|
|
4727
5106
|
const byThickness = chord * 0.6;
|
|
@@ -4765,28 +5144,13 @@ const _AegisInAppManager = class _AegisInAppManager {
|
|
|
4765
5144
|
const hub = document.createElement("div");
|
|
4766
5145
|
hub.style.cssText = `position: absolute; left: 50%; top: 50%; width: 40px; height: 40px; transform: translate(-50%, -50%); border-radius: 50%; background: radial-gradient(circle at 35% 30%, #ffffff, #e9edf5); border: 3px solid #fff; box-shadow: 0 3px 8px rgba(0,0,0,0.30); z-index: 4; overflow: hidden; display: flex; align-items: center; justify-content: center;`;
|
|
4767
5146
|
if (hubImg) {
|
|
4768
|
-
|
|
4769
|
-
|
|
4770
|
-
|
|
4771
|
-
hc.style.cssText = "width: 100%; height: 100%;";
|
|
4772
|
-
const hcx = hc.getContext("2d");
|
|
4773
|
-
const him = new Image();
|
|
4774
|
-
him.crossOrigin = "anonymous";
|
|
4775
|
-
him.onload = () => {
|
|
4776
|
-
if (!hcx) return;
|
|
4777
|
-
const ar = him.width / him.height || 1;
|
|
4778
|
-
let w = 32, h = 32;
|
|
4779
|
-
if (ar > 1) h = 32 / ar;
|
|
4780
|
-
else w = 32 * ar;
|
|
4781
|
-
hcx.drawImage(him, (40 - w) / 2, (40 - h) / 2, w, h);
|
|
4782
|
-
hcx.globalCompositeOperation = "source-in";
|
|
4783
|
-
hcx.fillStyle = "#5b626e";
|
|
4784
|
-
hcx.fillRect(0, 0, 40, 40);
|
|
4785
|
-
};
|
|
4786
|
-
him.onerror = () => {
|
|
4787
|
-
};
|
|
5147
|
+
hub.style.border = "none";
|
|
5148
|
+
hub.style.background = "transparent";
|
|
5149
|
+
const him = document.createElement("img");
|
|
4788
5150
|
him.src = hubImg;
|
|
4789
|
-
|
|
5151
|
+
him.alt = "";
|
|
5152
|
+
him.style.cssText = "width: 100%; height: 100%; object-fit: cover; border-radius: 50%; display: block;";
|
|
5153
|
+
hub.appendChild(him);
|
|
4790
5154
|
} else {
|
|
4791
5155
|
const hubDot = document.createElement("div");
|
|
4792
5156
|
hubDot.style.cssText = `width: 11px; height: 11px; border-radius: 50%; background: ${bg};`;
|
|
@@ -4800,7 +5164,7 @@ const _AegisInAppManager = class _AegisInAppManager {
|
|
|
4800
5164
|
body.appendChild(wheelWrap);
|
|
4801
5165
|
if (!card.style.position) card.style.position = "relative";
|
|
4802
5166
|
const result = document.createElement("div");
|
|
4803
|
-
result.style.cssText = "font-size: 14px; font-weight: 800; min-height:
|
|
5167
|
+
result.style.cssText = "font-size: 14px; font-weight: 800; min-height: 0; text-align: center; letter-spacing: 0.2px;";
|
|
4804
5168
|
if (ic.spin_sound_enabled !== false) {
|
|
4805
5169
|
const soundBtn = document.createElement("button");
|
|
4806
5170
|
soundBtn.type = "button";
|
|
@@ -4815,7 +5179,7 @@ const _AegisInAppManager = class _AegisInAppManager {
|
|
|
4815
5179
|
}
|
|
4816
5180
|
const btn = document.createElement("button");
|
|
4817
5181
|
btn.textContent = campaign.button_text || "Spin the wheel";
|
|
4818
|
-
btn.style.cssText = `padding:
|
|
5182
|
+
btn.style.cssText = `padding: 9px 22px; border-radius: 999px; border: none; background: ${text}; color: ${bg}; font-size: 13px; font-weight: 700; letter-spacing: 0.2px; cursor: pointer; box-shadow: 0 4px 12px rgba(0,0,0,0.20); transition: transform 0.15s, box-shadow 0.15s; font-family: 'Inter Tight', Inter, system-ui, -apple-system, sans-serif;`;
|
|
4819
5183
|
btn.addEventListener("mouseenter", () => {
|
|
4820
5184
|
if (btn.disabled) return;
|
|
4821
5185
|
btn.style.transform = "translateY(-1px)";
|
|
@@ -4844,12 +5208,12 @@ const _AegisInAppManager = class _AegisInAppManager {
|
|
|
4844
5208
|
pVel *= 0.7;
|
|
4845
5209
|
pDefl += pVel;
|
|
4846
5210
|
if (Math.abs(pDefl) > 0.06 || Math.abs(pVel) > 0.06) {
|
|
4847
|
-
pointer.style.transform =
|
|
5211
|
+
pointer.style.transform = `${pointerBase} rotate(${pDefl.toFixed(2)}deg)`;
|
|
4848
5212
|
pointerRaf = requestAnimationFrame(stepPointer);
|
|
4849
5213
|
} else {
|
|
4850
5214
|
pDefl = 0;
|
|
4851
5215
|
pVel = 0;
|
|
4852
|
-
pointer.style.transform =
|
|
5216
|
+
pointer.style.transform = `${pointerBase} rotate(0deg)`;
|
|
4853
5217
|
pointerRaf = 0;
|
|
4854
5218
|
}
|
|
4855
5219
|
};
|
|
@@ -5383,6 +5747,34 @@ const _AegisInAppManager = class _AegisInAppManager {
|
|
|
5383
5747
|
target.appendChild(card);
|
|
5384
5748
|
return true;
|
|
5385
5749
|
}
|
|
5750
|
+
/** Foil palette — a brushed-metal gradient + a contrast "ink" (for the
|
|
5751
|
+
* SCRATCH-HERE text, sparkle motif, and logo tint) derived from the operator's
|
|
5752
|
+
* chosen foil colour (brand primary / custom hex). Unset / invalid → the
|
|
5753
|
+
* default silver. Light foils get dark ink, dark foils get white ink, so the
|
|
5754
|
+
* prompt stays legible on any colour. */
|
|
5755
|
+
_scratchFoilPalette(hex) {
|
|
5756
|
+
const clean = (hex || "").trim().replace(/^#/, "");
|
|
5757
|
+
if (!/^[0-9a-fA-F]{6}$/.test(clean)) {
|
|
5758
|
+
return { g0: "#d7dbe2", g1: "#b4bac4", g2: "#c9cdd6", ink: "#6b7280" };
|
|
5759
|
+
}
|
|
5760
|
+
const r = parseInt(clean.slice(0, 2), 16);
|
|
5761
|
+
const g = parseInt(clean.slice(2, 4), 16);
|
|
5762
|
+
const b = parseInt(clean.slice(4, 6), 16);
|
|
5763
|
+
const toward = (amt) => {
|
|
5764
|
+
const m2 = (c) => Math.round(c + (255 - c) * amt);
|
|
5765
|
+
return `rgb(${m2(r)}, ${m2(g)}, ${m2(b)})`;
|
|
5766
|
+
};
|
|
5767
|
+
const lum = (0.299 * r + 0.587 * g + 0.114 * b) / 255;
|
|
5768
|
+
return {
|
|
5769
|
+
g0: toward(0.34),
|
|
5770
|
+
// bright sheen
|
|
5771
|
+
g1: `#${clean}`,
|
|
5772
|
+
// base colour
|
|
5773
|
+
g2: toward(0.18),
|
|
5774
|
+
// soft sheen
|
|
5775
|
+
ink: lum > 0.62 ? "#5b6270" : "rgba(255,255,255,0.92)"
|
|
5776
|
+
};
|
|
5777
|
+
}
|
|
5386
5778
|
/** Built-in embedded SCRATCH CARD — a canvas foil the customer scratches to
|
|
5387
5779
|
* reveal the server-picked prize, then submits (records + grants). Confetti
|
|
5388
5780
|
* on reveal. No AegisMessageRuntime callback dependency (works on the bill). */
|
|
@@ -5400,6 +5792,7 @@ const _AegisInAppManager = class _AegisInAppManager {
|
|
|
5400
5792
|
let soundOn = ic.scratch_sound_enabled !== false;
|
|
5401
5793
|
const revealImg = cfgStr("reveal_image_url");
|
|
5402
5794
|
const foilImg = cfgStr("scratch_foil_image_url");
|
|
5795
|
+
const foilPal = this._scratchFoilPalette(cfgStr("scratch_foil_color"));
|
|
5403
5796
|
const pool = Array.isArray(ic.prize_pool) ? ic.prize_pool : [];
|
|
5404
5797
|
const isUrl = (s) => /^https?:\/\//i.test(s);
|
|
5405
5798
|
const sampleWin = pool.find(
|
|
@@ -5542,9 +5935,9 @@ const _AegisInAppManager = class _AegisInAppManager {
|
|
|
5542
5935
|
if (!ctx) return;
|
|
5543
5936
|
ctx.globalCompositeOperation = "source-over";
|
|
5544
5937
|
const foil = ctx.createLinearGradient(0, 0, CW, CH);
|
|
5545
|
-
foil.addColorStop(0,
|
|
5546
|
-
foil.addColorStop(0.5,
|
|
5547
|
-
foil.addColorStop(1,
|
|
5938
|
+
foil.addColorStop(0, foilPal.g0);
|
|
5939
|
+
foil.addColorStop(0.5, foilPal.g1);
|
|
5940
|
+
foil.addColorStop(1, foilPal.g2);
|
|
5548
5941
|
ctx.fillStyle = foil;
|
|
5549
5942
|
ctx.fillRect(0, 0, CW, CH);
|
|
5550
5943
|
ctx.textAlign = "center";
|
|
@@ -5553,17 +5946,19 @@ const _AegisInAppManager = class _AegisInAppManager {
|
|
|
5553
5946
|
ctx.globalAlpha = 0.6;
|
|
5554
5947
|
ctx.drawImage(logo, (CW - logo.width) / 2, CH * 0.42 - logo.height / 2, logo.width, logo.height);
|
|
5555
5948
|
ctx.globalAlpha = 1;
|
|
5556
|
-
ctx.fillStyle =
|
|
5949
|
+
ctx.fillStyle = foilPal.ink;
|
|
5557
5950
|
ctx.font = "700 12px system-ui, sans-serif";
|
|
5558
5951
|
ctx.fillText("SCRATCH HERE", CW / 2, CH * 0.84);
|
|
5559
5952
|
} else {
|
|
5560
|
-
ctx.
|
|
5953
|
+
ctx.globalAlpha = 0.22;
|
|
5954
|
+
ctx.fillStyle = foilPal.ink;
|
|
5561
5955
|
ctx.font = "12px system-ui, sans-serif";
|
|
5562
5956
|
for (let gy = 18; gy < CH; gy += 30) {
|
|
5563
5957
|
const off = (gy / 30 | 0) % 2 ? 16 : 0;
|
|
5564
5958
|
for (let gx = 16 + off; gx < CW; gx += 32) ctx.fillText("✦", gx, gy);
|
|
5565
5959
|
}
|
|
5566
|
-
ctx.
|
|
5960
|
+
ctx.globalAlpha = 1;
|
|
5961
|
+
ctx.fillStyle = foilPal.ink;
|
|
5567
5962
|
ctx.font = "700 13px system-ui, sans-serif";
|
|
5568
5963
|
ctx.fillText("SCRATCH HERE", CW / 2, CH / 2);
|
|
5569
5964
|
}
|
|
@@ -5590,7 +5985,7 @@ const _AegisInAppManager = class _AegisInAppManager {
|
|
|
5590
5985
|
if (!lctx) return;
|
|
5591
5986
|
lctx.drawImage(im, 0, 0, lc.width, lc.height);
|
|
5592
5987
|
lctx.globalCompositeOperation = "source-in";
|
|
5593
|
-
lctx.fillStyle =
|
|
5988
|
+
lctx.fillStyle = foilPal.ink;
|
|
5594
5989
|
lctx.fillRect(0, 0, lc.width, lc.height);
|
|
5595
5990
|
paintFoil(lc);
|
|
5596
5991
|
};
|
|
@@ -6315,6 +6710,9 @@ const _AegisInAppManager = class _AegisInAppManager {
|
|
|
6315
6710
|
return;
|
|
6316
6711
|
}
|
|
6317
6712
|
this.displayedCampaigns.add(campaign.id);
|
|
6713
|
+
this._displaySizeMul = this._sizeMul(
|
|
6714
|
+
campaign.interactive_config
|
|
6715
|
+
);
|
|
6318
6716
|
const interactiveSubTypes = /* @__PURE__ */ new Set([
|
|
6319
6717
|
"spin_wheel",
|
|
6320
6718
|
"scratch_card",
|
|
@@ -6507,6 +6905,14 @@ const _AegisInAppManager = class _AegisInAppManager {
|
|
|
6507
6905
|
* slot renderers (`renderSpinWheelSlot` / `renderScratchCardSlot`) in a modal
|
|
6508
6906
|
* so the gamified widget is fully playable — not a dead frame.
|
|
6509
6907
|
*/
|
|
6908
|
+
/** Display-size multiplier — operator control over how big a bounded overlay
|
|
6909
|
+
* renders (small 0.82 / medium 1 / large 1.18). Default medium = prior size.
|
|
6910
|
+
* Read from interactive_config.display_size; mirrors the schema enum + the
|
|
6911
|
+
* dashboard preview harness so the operator's choice is honored identically. */
|
|
6912
|
+
_sizeMul(ic) {
|
|
6913
|
+
const s = ic && typeof ic.display_size === "string" ? ic.display_size : "medium";
|
|
6914
|
+
return s === "small" ? 0.82 : s === "large" ? 1.18 : 1;
|
|
6915
|
+
}
|
|
6510
6916
|
renderGamificationOverlay(campaign, ic, bg, text) {
|
|
6511
6917
|
const overlay = this.createOverlay(`aegis-in-app-${campaign.sub_type}-overlay`);
|
|
6512
6918
|
const modal = document.createElement("div");
|
|
@@ -6521,7 +6927,11 @@ const _AegisInAppManager = class _AegisInAppManager {
|
|
|
6521
6927
|
this.renderSpinWheelSlot(campaign, ic, bg, text, modal);
|
|
6522
6928
|
}
|
|
6523
6929
|
this._addCornerClose(modal, overlay, campaign.id, text);
|
|
6524
|
-
|
|
6930
|
+
const mul = this._sizeMul(ic);
|
|
6931
|
+
const sizer = document.createElement("div");
|
|
6932
|
+
sizer.style.cssText = `display: flex; justify-content: center; align-items: center; width: 100%; transform: scale(${mul}); transform-origin: center;`;
|
|
6933
|
+
sizer.appendChild(modal);
|
|
6934
|
+
overlay.appendChild(sizer);
|
|
6525
6935
|
this.addAnimationStyles();
|
|
6526
6936
|
document.body.appendChild(overlay);
|
|
6527
6937
|
}
|
|
@@ -7184,8 +7594,30 @@ const _AegisInAppManager = class _AegisInAppManager {
|
|
|
7184
7594
|
background: rgba(0,0,0,0.5); display: flex; align-items: center;
|
|
7185
7595
|
justify-content: center; z-index: 99999; animation: aegisFadeIn 0.3s ease;
|
|
7186
7596
|
`;
|
|
7597
|
+
if (this._displaySizeMul !== 1) {
|
|
7598
|
+
const mul = this._displaySizeMul;
|
|
7599
|
+
queueMicrotask(() => {
|
|
7600
|
+
const card = overlay.firstElementChild;
|
|
7601
|
+
if (!card || card.dataset.aegisSized) return;
|
|
7602
|
+
card.dataset.aegisSized = "1";
|
|
7603
|
+
const wrap = document.createElement("div");
|
|
7604
|
+
wrap.style.cssText = `display: flex; align-items: center; justify-content: center; transform: scale(${mul}); transform-origin: center;`;
|
|
7605
|
+
overlay.insertBefore(wrap, card);
|
|
7606
|
+
wrap.appendChild(card);
|
|
7607
|
+
});
|
|
7608
|
+
}
|
|
7187
7609
|
return overlay;
|
|
7188
7610
|
}
|
|
7611
|
+
/** Wrap a card in a display-size scaling container (no-op at medium/×1). Used
|
|
7612
|
+
* by formats that build their overlay inline (renderModal) rather than via
|
|
7613
|
+
* createOverlay, so size is honored identically. */
|
|
7614
|
+
_wrapScaled(card) {
|
|
7615
|
+
if (this._displaySizeMul === 1) return card;
|
|
7616
|
+
const wrap = document.createElement("div");
|
|
7617
|
+
wrap.style.cssText = `display: flex; align-items: center; justify-content: center; transform: scale(${this._displaySizeMul}); transform-origin: center;`;
|
|
7618
|
+
wrap.appendChild(card);
|
|
7619
|
+
return wrap;
|
|
7620
|
+
}
|
|
7189
7621
|
createCTAButton(campaign, bg, text) {
|
|
7190
7622
|
const btn = document.createElement("button");
|
|
7191
7623
|
btn.className = "aegis-cta";
|
|
@@ -7618,7 +8050,7 @@ const _AegisInAppManager = class _AegisInAppManager {
|
|
|
7618
8050
|
actions.appendChild(closeButton);
|
|
7619
8051
|
content.appendChild(actions);
|
|
7620
8052
|
modal.appendChild(content);
|
|
7621
|
-
overlay.appendChild(modal);
|
|
8053
|
+
overlay.appendChild(this._wrapScaled(modal));
|
|
7622
8054
|
if (ic.modal_dismiss_on_overlay !== false) {
|
|
7623
8055
|
overlay.addEventListener("click", (e) => {
|
|
7624
8056
|
if (e.target === overlay) {
|
|
@@ -9054,7 +9486,7 @@ _AegisInAppManager.KNOWN_SURFACES = /* @__PURE__ */ new Set([
|
|
|
9054
9486
|
]);
|
|
9055
9487
|
_AegisInAppManager.SERVED_DEDUP_PREFIX = "aegis_served_fired:";
|
|
9056
9488
|
let AegisInAppManager = _AegisInAppManager;
|
|
9057
|
-
function renderPreview(config) {
|
|
9489
|
+
function renderPreview(config, opts) {
|
|
9058
9490
|
document.querySelectorAll(
|
|
9059
9491
|
'[class^="aegis-in-app-"]'
|
|
9060
9492
|
).forEach((el) => {
|
|
@@ -9078,12 +9510,33 @@ function renderPreview(config) {
|
|
|
9078
9510
|
writeKey: "preview-mode",
|
|
9079
9511
|
apiHost: "",
|
|
9080
9512
|
debugMode: false,
|
|
9081
|
-
enableSSE: false
|
|
9513
|
+
enableSSE: false,
|
|
9514
|
+
...(opts == null ? void 0 : opts.cart) ? { getCartState: () => opts.cart } : {}
|
|
9082
9515
|
});
|
|
9083
9516
|
const m2 = manager;
|
|
9084
9517
|
m2.trackEvent = async () => {
|
|
9085
9518
|
};
|
|
9086
9519
|
m2.addAnimationStyles();
|
|
9520
|
+
const cfgRec = config;
|
|
9521
|
+
const deliveryModes = Array.isArray(cfgRec.delivery_modes) ? cfgRec.delivery_modes : [];
|
|
9522
|
+
const widgetCategory = typeof cfgRec.widget_category === "string" ? cfgRec.widget_category : "";
|
|
9523
|
+
const inline = deliveryModes.includes("embedded_card") && !!widgetCategory;
|
|
9524
|
+
const coGroup = (opts == null ? void 0 : opts.coGroup) ?? [];
|
|
9525
|
+
if (typeof document !== "undefined" && (coGroup.length > 0 || inline)) {
|
|
9526
|
+
const anchors = document.querySelectorAll("[data-aegis-slot]");
|
|
9527
|
+
if (anchors.length > 0) {
|
|
9528
|
+
try {
|
|
9529
|
+
anchors.forEach((slot) => {
|
|
9530
|
+
slot.querySelectorAll(":scope > :not([data-aegis-slot-default])").forEach((el) => el.remove());
|
|
9531
|
+
});
|
|
9532
|
+
const mm = manager;
|
|
9533
|
+
mm.campaigns = (inline ? [config, ...coGroup] : coGroup).map((c) => ({ ...c, surface: void 0, target_screens: void 0 })).sort((a, b) => (b.priority || 0) - (a.priority || 0));
|
|
9534
|
+
mm.renderIntoSlots();
|
|
9535
|
+
if (inline) return;
|
|
9536
|
+
} catch {
|
|
9537
|
+
}
|
|
9538
|
+
}
|
|
9539
|
+
}
|
|
9087
9540
|
if (config.type === "stories" || config.sub_type === "stories") {
|
|
9088
9541
|
const host = document.createElement("div");
|
|
9089
9542
|
host.className = "aegis-in-app-stories-host";
|
|
@@ -12592,10 +13045,13 @@ export {
|
|
|
12592
13045
|
TriggerEngine,
|
|
12593
13046
|
U as UserNamespace,
|
|
12594
13047
|
bootstrap,
|
|
13048
|
+
closeChat,
|
|
12595
13049
|
debounce,
|
|
12596
13050
|
aegis as default,
|
|
12597
13051
|
deriveDeviceFingerprint,
|
|
13052
|
+
getCurrentLauncher,
|
|
12598
13053
|
m as murmurhash3_x86_32,
|
|
13054
|
+
openChat,
|
|
12599
13055
|
readFirstPartyCookie,
|
|
12600
13056
|
renderPreview,
|
|
12601
13057
|
throttle,
|