@action-x/ad-sdk 0.1.5 → 0.1.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.cjs +30 -34
- package/dist/index.d.ts +19 -8
- package/dist/index.js +287 -249
- package/dist/index.umd.js +22 -26
- package/dist/style.css +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
class
|
|
1
|
+
class O {
|
|
2
2
|
constructor() {
|
|
3
3
|
this.events = {};
|
|
4
4
|
}
|
|
@@ -42,7 +42,16 @@ class B {
|
|
|
42
42
|
return ((t = this.events[e]) == null ? void 0 : t.length) || 0;
|
|
43
43
|
}
|
|
44
44
|
}
|
|
45
|
-
class
|
|
45
|
+
class w {
|
|
46
|
+
static getClickUrl(e) {
|
|
47
|
+
return e.tracking.clickUrl || e.tracking.click_url || "#";
|
|
48
|
+
}
|
|
49
|
+
static getImpressionUrl(e) {
|
|
50
|
+
return e.tracking.impressionUrl || e.tracking.impression_url || "";
|
|
51
|
+
}
|
|
52
|
+
static getCtaText(e) {
|
|
53
|
+
return e.adapted.ctaText || e.adapted.cta_text || "Learn More";
|
|
54
|
+
}
|
|
46
55
|
/**
|
|
47
56
|
* Render Action Card ad as HTML string
|
|
48
57
|
*
|
|
@@ -51,37 +60,33 @@ class v {
|
|
|
51
60
|
* @returns HTML string
|
|
52
61
|
*/
|
|
53
62
|
static renderActionCard(e, t = {}) {
|
|
54
|
-
var
|
|
55
|
-
const { variant: i = "horizontal", includeWrapper: s = !0 } = t, n = e.adapted,
|
|
63
|
+
var f;
|
|
64
|
+
const { variant: i = "horizontal", includeWrapper: s = !0 } = t, n = e.adapted, o = this.getClickUrl(e), a = this.getImpressionUrl(e), c = s ? `<div class="ax-ad-card ax-ad-card-${i}" data-ad-id="${e.original.id}">` : "", l = (f = n.image) != null && f.url ? `<img
|
|
56
65
|
src="${n.image.url}"
|
|
57
66
|
alt="${n.title}"
|
|
58
67
|
class="ax-ad-image"
|
|
59
68
|
loading="lazy"
|
|
60
|
-
/>` : "", d = n.
|
|
61
|
-
|
|
62
|
-
</div>` : "", u = n.brand ? `<span class="ax-ad-brand">${n.brand}</span>` : "", f = `
|
|
63
|
-
${c}
|
|
69
|
+
/>` : "", d = (n.brand || "").trim(), u = d && d.toLowerCase() !== "unknown" ? `<span class="ax-ad-brand">${n.brand}</span>` : "", h = `
|
|
70
|
+
${l}
|
|
64
71
|
<div class="ax-ad-content">
|
|
65
72
|
${u}
|
|
66
73
|
<h3 class="ax-ad-title">${n.title}</h3>
|
|
67
74
|
${n.body ? `<p class="ax-ad-body">${n.body}</p>` : ""}
|
|
68
|
-
${l}
|
|
69
75
|
<div class="ax-ad-footer">
|
|
70
|
-
${d}
|
|
71
76
|
<a
|
|
72
|
-
href="${
|
|
77
|
+
href="${o}"
|
|
73
78
|
class="ax-ad-cta"
|
|
74
79
|
target="_blank"
|
|
75
80
|
rel="sponsored noopener noreferrer"
|
|
76
81
|
data-ad-id="${e.original.id}"
|
|
77
|
-
data-impression-url="${
|
|
82
|
+
data-impression-url="${a}"
|
|
78
83
|
>
|
|
79
|
-
${
|
|
84
|
+
${this.getCtaText(e)}
|
|
80
85
|
</a>
|
|
81
86
|
</div>
|
|
82
87
|
</div>
|
|
83
88
|
`, p = s ? "</div>" : "";
|
|
84
|
-
return
|
|
89
|
+
return c + h + p;
|
|
85
90
|
}
|
|
86
91
|
/**
|
|
87
92
|
* Render Suffix ad as HTML string
|
|
@@ -90,21 +95,21 @@ class v {
|
|
|
90
95
|
* @returns HTML string
|
|
91
96
|
*/
|
|
92
97
|
static renderSuffixAd(e) {
|
|
93
|
-
const t = e.adapted, i = e.
|
|
98
|
+
const t = e.adapted, i = this.getClickUrl(e), s = this.getImpressionUrl(e);
|
|
94
99
|
return `
|
|
95
100
|
<div class="ax-ad-suffix" data-ad-id="${e.original.id}">
|
|
96
101
|
<div class="ax-ad-suffix-content">
|
|
97
102
|
${t.title ? `<h4 class="ax-ad-suffix-title">${t.title}</h4>` : ""}
|
|
98
103
|
${t.body ? `<p class="ax-ad-suffix-body">${t.body}</p>` : ""}
|
|
99
104
|
<a
|
|
100
|
-
href="${i
|
|
105
|
+
href="${i}"
|
|
101
106
|
class="ax-ad-suffix-link"
|
|
102
107
|
target="_blank"
|
|
103
108
|
rel="sponsored noopener noreferrer"
|
|
104
109
|
data-ad-id="${e.original.id}"
|
|
105
|
-
data-impression-url="${
|
|
110
|
+
data-impression-url="${s}"
|
|
106
111
|
>
|
|
107
|
-
${
|
|
112
|
+
${this.getCtaText(e)}
|
|
108
113
|
</a>
|
|
109
114
|
</div>
|
|
110
115
|
</div>
|
|
@@ -117,19 +122,19 @@ class v {
|
|
|
117
122
|
* @returns HTML string
|
|
118
123
|
*/
|
|
119
124
|
static renderSponsoredSource(e) {
|
|
120
|
-
var
|
|
121
|
-
const t = e.adapted, i = e.
|
|
125
|
+
var n;
|
|
126
|
+
const t = e.adapted, i = this.getClickUrl(e), s = this.getImpressionUrl(e);
|
|
122
127
|
return `
|
|
123
128
|
<div class="ax-ad-source" data-ad-id="${e.original.id}">
|
|
124
129
|
<a
|
|
125
|
-
href="${i
|
|
130
|
+
href="${i}"
|
|
126
131
|
class="ax-ad-source-link"
|
|
127
132
|
target="_blank"
|
|
128
133
|
rel="sponsored noopener noreferrer"
|
|
129
134
|
data-ad-id="${e.original.id}"
|
|
130
|
-
data-impression-url="${
|
|
135
|
+
data-impression-url="${s}"
|
|
131
136
|
>
|
|
132
|
-
${(
|
|
137
|
+
${(n = t.image) != null && n.url ? `<img src="${t.image.url}" alt="" class="ax-ad-source-icon" />` : ""}
|
|
133
138
|
<div class="ax-ad-source-info">
|
|
134
139
|
<span class="ax-ad-source-name">${t.title}</span>
|
|
135
140
|
${t.body ? `<span class="ax-ad-source-desc">${t.body}</span>` : ""}
|
|
@@ -146,21 +151,21 @@ class v {
|
|
|
146
151
|
* @returns HTML string
|
|
147
152
|
*/
|
|
148
153
|
static renderLeadGenAd(e) {
|
|
149
|
-
const t = e.adapted, i = e.
|
|
154
|
+
const t = e.adapted, i = this.getClickUrl(e), s = this.getImpressionUrl(e);
|
|
150
155
|
return `
|
|
151
156
|
<div class="ax-ad-leadgen" data-ad-id="${e.original.id}">
|
|
152
157
|
<div class="ax-ad-leadgen-content">
|
|
153
158
|
${t.title ? `<h3 class="ax-ad-leadgen-title">${t.title}</h3>` : ""}
|
|
154
159
|
${t.body ? `<p class="ax-ad-leadgen-body">${t.body}</p>` : ""}
|
|
155
160
|
<a
|
|
156
|
-
href="${i
|
|
161
|
+
href="${i}"
|
|
157
162
|
class="ax-ad-leadgen-cta"
|
|
158
163
|
target="_blank"
|
|
159
164
|
rel="sponsored noopener noreferrer"
|
|
160
165
|
data-ad-id="${e.original.id}"
|
|
161
|
-
data-impression-url="${
|
|
166
|
+
data-impression-url="${s}"
|
|
162
167
|
>
|
|
163
|
-
${
|
|
168
|
+
${this.getCtaText(e)}
|
|
164
169
|
</a>
|
|
165
170
|
</div>
|
|
166
171
|
</div>
|
|
@@ -173,21 +178,25 @@ class v {
|
|
|
173
178
|
* @param renderFn - Render function to use
|
|
174
179
|
* @returns HTML string with all ads
|
|
175
180
|
*/
|
|
176
|
-
static renderAds(e, t =
|
|
181
|
+
static renderAds(e, t = w.renderActionCard.bind(w)) {
|
|
177
182
|
return e.map(t).join(`
|
|
178
183
|
`);
|
|
179
184
|
}
|
|
180
185
|
}
|
|
181
|
-
const
|
|
182
|
-
function
|
|
186
|
+
const q = "ad_session_id";
|
|
187
|
+
function L() {
|
|
183
188
|
if (typeof window < "u") {
|
|
184
|
-
const
|
|
185
|
-
if (
|
|
186
|
-
return
|
|
189
|
+
const r = window.__AD_CONFIG__;
|
|
190
|
+
if (r != null && r.apiKey)
|
|
191
|
+
return r.apiKey;
|
|
187
192
|
}
|
|
188
193
|
}
|
|
189
|
-
function
|
|
190
|
-
|
|
194
|
+
function R() {
|
|
195
|
+
var r;
|
|
196
|
+
return typeof window < "u" ? !!((r = window.__AD_CONFIG__) != null && r.debug) : !1;
|
|
197
|
+
}
|
|
198
|
+
function U(r) {
|
|
199
|
+
if (r) return r;
|
|
191
200
|
if (typeof window < "u") {
|
|
192
201
|
const e = window.__AD_CONFIG__;
|
|
193
202
|
if (e != null && e.apiBaseUrl)
|
|
@@ -195,9 +204,9 @@ function C(o) {
|
|
|
195
204
|
}
|
|
196
205
|
return "/api/v1";
|
|
197
206
|
}
|
|
198
|
-
class
|
|
207
|
+
class P {
|
|
199
208
|
constructor(e = {}) {
|
|
200
|
-
this.memoryCache = /* @__PURE__ */ new Map(), this.sessionKey = e.sessionKey ||
|
|
209
|
+
this.memoryCache = /* @__PURE__ */ new Map(), this.sessionKey = e.sessionKey || q, this.storage = e.storage || "sessionStorage", (typeof window > "u" || typeof window.sessionStorage > "u") && (this.storage = "memory");
|
|
201
210
|
}
|
|
202
211
|
/**
|
|
203
212
|
* 获取 Session ID
|
|
@@ -231,7 +240,7 @@ class _ {
|
|
|
231
240
|
this.storage === "sessionStorage" ? sessionStorage.removeItem(this.sessionKey) : this.memoryCache.delete(this.sessionKey);
|
|
232
241
|
}
|
|
233
242
|
}
|
|
234
|
-
const
|
|
243
|
+
const K = new P(), m = () => K.getSessionId();
|
|
235
244
|
class x {
|
|
236
245
|
constructor(e = {}) {
|
|
237
246
|
this.explicitBaseUrl = e.baseUrl, this.timeout = e.timeout || 1e4, this.retryAttempts = e.retryAttempts ?? 2, this.retryDelay = e.retryDelay || 1e3, this.debug = e.debug || !1;
|
|
@@ -241,7 +250,7 @@ class x {
|
|
|
241
250
|
*/
|
|
242
251
|
async trackImpression(e) {
|
|
243
252
|
return this.sendRequest(
|
|
244
|
-
`${
|
|
253
|
+
`${U(this.explicitBaseUrl)}/ads/impression`,
|
|
245
254
|
e,
|
|
246
255
|
"impression"
|
|
247
256
|
);
|
|
@@ -251,7 +260,7 @@ class x {
|
|
|
251
260
|
*/
|
|
252
261
|
async trackClick(e) {
|
|
253
262
|
return this.sendRequest(
|
|
254
|
-
`${
|
|
263
|
+
`${U(this.explicitBaseUrl)}/ads/click`,
|
|
255
264
|
e,
|
|
256
265
|
"click"
|
|
257
266
|
);
|
|
@@ -262,27 +271,29 @@ class x {
|
|
|
262
271
|
*/
|
|
263
272
|
async sendRequest(e, t, i) {
|
|
264
273
|
let s = null;
|
|
265
|
-
for (let n = 0; n <= this.retryAttempts; n++)
|
|
274
|
+
for (let n = 0; n <= this.retryAttempts; n++) {
|
|
275
|
+
const o = this.debug || R();
|
|
266
276
|
try {
|
|
267
|
-
|
|
268
|
-
const
|
|
277
|
+
o && (console.log(`[Analytics] Request URL (${i}):`, e), console.log(`[Analytics] Sending ${i} event (attempt ${n + 1}):`, t));
|
|
278
|
+
const a = new AbortController(), c = setTimeout(() => a.abort(), this.timeout), l = {
|
|
269
279
|
"Content-Type": "application/json"
|
|
270
|
-
}, d =
|
|
271
|
-
d && (
|
|
272
|
-
const
|
|
280
|
+
}, d = L();
|
|
281
|
+
d && (l["X-API-Key"] = d, o && console.log(`[Analytics] Adding X-API-Key header for ${i} event`));
|
|
282
|
+
const u = await fetch(e, {
|
|
273
283
|
method: "POST",
|
|
274
|
-
headers:
|
|
284
|
+
headers: l,
|
|
275
285
|
body: JSON.stringify(t),
|
|
276
286
|
keepalive: !0,
|
|
277
|
-
signal:
|
|
287
|
+
signal: a.signal
|
|
278
288
|
});
|
|
279
|
-
if (clearTimeout(
|
|
280
|
-
throw new Error(`HTTP ${
|
|
281
|
-
const
|
|
282
|
-
return
|
|
283
|
-
} catch (
|
|
284
|
-
s =
|
|
289
|
+
if (clearTimeout(c), !u.ok)
|
|
290
|
+
throw new Error(`HTTP ${u.status}: ${u.statusText}`);
|
|
291
|
+
const h = await u.json();
|
|
292
|
+
return o && console.log(`[Analytics] ${i} event tracked successfully:`, h), h;
|
|
293
|
+
} catch (a) {
|
|
294
|
+
s = a, o && console.warn(`[Analytics] ${i} tracking failed (attempt ${n + 1}):`, a), n < this.retryAttempts && await this.delay(this.retryDelay * (n + 1));
|
|
285
295
|
}
|
|
296
|
+
}
|
|
286
297
|
return console.error(`[Analytics] ${i} tracking failed after ${this.retryAttempts + 1} attempts:`, s), null;
|
|
287
298
|
}
|
|
288
299
|
/**
|
|
@@ -292,37 +303,47 @@ class x {
|
|
|
292
303
|
return new Promise((t) => setTimeout(t, e));
|
|
293
304
|
}
|
|
294
305
|
}
|
|
295
|
-
const
|
|
296
|
-
function
|
|
297
|
-
return `vt_${
|
|
306
|
+
const B = new x(), I = (r, e) => e != null && e.baseUrl ? new x({ baseUrl: e.baseUrl }).trackImpression(r) : B.trackImpression(r), T = (r, e) => e != null && e.baseUrl ? new x({ baseUrl: e.baseUrl }).trackClick(r) : B.trackClick(r);
|
|
307
|
+
function G(r, e) {
|
|
308
|
+
return `vt_${r}_${e}`;
|
|
298
309
|
}
|
|
299
|
-
async function
|
|
300
|
-
return Promise.all(
|
|
310
|
+
async function z(r) {
|
|
311
|
+
return Promise.all(r.map((e) => I(e)));
|
|
301
312
|
}
|
|
302
|
-
async function
|
|
303
|
-
return Promise.all(
|
|
313
|
+
async function j(r) {
|
|
314
|
+
return Promise.all(r.map((e) => T(e)));
|
|
304
315
|
}
|
|
305
|
-
function
|
|
306
|
-
const e = new x(
|
|
316
|
+
function W(r) {
|
|
317
|
+
const e = new x(r);
|
|
307
318
|
return {
|
|
308
319
|
trackImpression: (t) => e.trackImpression(t),
|
|
309
320
|
trackClick: (t) => e.trackClick(t)
|
|
310
321
|
};
|
|
311
322
|
}
|
|
312
|
-
function
|
|
313
|
-
const e = new
|
|
323
|
+
function Q(r = {}) {
|
|
324
|
+
const e = new P(r);
|
|
314
325
|
return {
|
|
315
326
|
getSessionId: () => e.getSessionId(),
|
|
316
327
|
regenerateSessionId: () => e.regenerateSessionId(),
|
|
317
328
|
clearSessionId: () => e.clearSessionId()
|
|
318
329
|
};
|
|
319
330
|
}
|
|
320
|
-
const
|
|
331
|
+
const C = class C {
|
|
332
|
+
static isDebugEnabled() {
|
|
333
|
+
var e;
|
|
334
|
+
return typeof window < "u" ? !!((e = window.__AD_CONFIG__) != null && e.debug) : !1;
|
|
335
|
+
}
|
|
336
|
+
static getClickUrl(e) {
|
|
337
|
+
return e.tracking.clickUrl || e.tracking.click_url || "";
|
|
338
|
+
}
|
|
339
|
+
static getViewToken(e) {
|
|
340
|
+
return e.tracking.viewToken || e.tracking.view_token;
|
|
341
|
+
}
|
|
321
342
|
/**
|
|
322
343
|
* Render Action Card ad into container
|
|
323
344
|
*/
|
|
324
345
|
static renderActionCard(e, t, i = {}) {
|
|
325
|
-
t.innerHTML =
|
|
346
|
+
t.innerHTML = w.renderActionCard(e, i);
|
|
326
347
|
const s = t.querySelector(".ax-ad-cta");
|
|
327
348
|
return s && s.addEventListener("click", (n) => {
|
|
328
349
|
n.preventDefault(), this.handleClick(e, i);
|
|
@@ -335,8 +356,8 @@ const M = class M {
|
|
|
335
356
|
const s = i.variant || "block";
|
|
336
357
|
t.innerHTML = this.generateSuffixAdHTML(e, s);
|
|
337
358
|
const n = t.querySelector(".ax-ad-suffix-link");
|
|
338
|
-
return n && n.addEventListener("click", (
|
|
339
|
-
|
|
359
|
+
return n && n.addEventListener("click", (o) => {
|
|
360
|
+
o.preventDefault(), this.handleClick(e, i);
|
|
340
361
|
}), this.trackImpression(e, t, i), t;
|
|
341
362
|
}
|
|
342
363
|
/**
|
|
@@ -346,15 +367,15 @@ const M = class M {
|
|
|
346
367
|
const s = i.variant || "card";
|
|
347
368
|
t.innerHTML = this.generateSponsoredSourceHTML(e, s);
|
|
348
369
|
const n = t.querySelector(".ax-ad-source-link");
|
|
349
|
-
return n && n.addEventListener("click", (
|
|
350
|
-
|
|
370
|
+
return n && n.addEventListener("click", (o) => {
|
|
371
|
+
o.preventDefault(), this.handleClick(e, i);
|
|
351
372
|
}), this.trackImpression(e, t, i), t;
|
|
352
373
|
}
|
|
353
374
|
/**
|
|
354
375
|
* Render Lead Gen ad into container
|
|
355
376
|
*/
|
|
356
377
|
static renderLeadGenAd(e, t, i = {}) {
|
|
357
|
-
t.innerHTML =
|
|
378
|
+
t.innerHTML = w.renderLeadGenAd(e);
|
|
358
379
|
const s = t.querySelector(".ax-ad-leadgen-cta");
|
|
359
380
|
return s && s.addEventListener("click", (n) => {
|
|
360
381
|
n.preventDefault(), this.handleClick(e, i);
|
|
@@ -366,9 +387,9 @@ const M = class M {
|
|
|
366
387
|
static renderAds(e, t, i = this.renderActionCard.bind(this), s) {
|
|
367
388
|
t.innerHTML = "";
|
|
368
389
|
const n = document.createElement("div");
|
|
369
|
-
return n.className = "ax-ads-container", e.forEach((
|
|
390
|
+
return n.className = "ax-ads-container", e.forEach((o) => {
|
|
370
391
|
const a = document.createElement("div");
|
|
371
|
-
a.className = "ax-ad-wrapper", i.call(this,
|
|
392
|
+
a.className = "ax-ad-wrapper", i.call(this, o, a, s), n.appendChild(a);
|
|
372
393
|
}), t.appendChild(n), t;
|
|
373
394
|
}
|
|
374
395
|
/**
|
|
@@ -376,32 +397,37 @@ const M = class M {
|
|
|
376
397
|
* First tracks the click (async, non-blocking), then opens the URL.
|
|
377
398
|
*/
|
|
378
399
|
static handleClick(e, t) {
|
|
379
|
-
const { analytics: i, onClick: s } = t;
|
|
400
|
+
const { analytics: i, onClick: s } = t, n = this.getClickUrl(e);
|
|
401
|
+
if (!n) {
|
|
402
|
+
console.warn("[DOMRenderer] Missing click url for ad:", e.original.id);
|
|
403
|
+
return;
|
|
404
|
+
}
|
|
380
405
|
s && s(e), i && T({
|
|
381
406
|
requestId: i.requestId,
|
|
382
407
|
adId: e.original.id,
|
|
383
|
-
destinationUrl:
|
|
408
|
+
destinationUrl: n,
|
|
384
409
|
slotId: i.slotId,
|
|
385
410
|
sessionId: m(),
|
|
386
411
|
adTitle: e.adapted.title,
|
|
387
|
-
format: e.original.type
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
412
|
+
format: e.original.type,
|
|
413
|
+
userId: i.userId
|
|
414
|
+
}, { baseUrl: i.apiBaseUrl }).catch((o) => {
|
|
415
|
+
console.error("[DOMRenderer] Analytics click tracking failed:", o);
|
|
416
|
+
}), this.isDebugEnabled() && console.log("[DOMRenderer] Redirect URL:", n), window.open(n, "_blank", "noopener,noreferrer");
|
|
391
417
|
}
|
|
392
418
|
/**
|
|
393
419
|
* Track ad impression using IntersectionObserver (50% visible + 1000ms delay)
|
|
394
420
|
* Falls back to immediate tracking if IntersectionObserver is unavailable.
|
|
395
421
|
*/
|
|
396
422
|
static trackImpression(e, t, i) {
|
|
397
|
-
const { analytics: s, onImpression: n } = i,
|
|
398
|
-
if (this.trackedImpressionKeys.has(
|
|
423
|
+
const { analytics: s, onImpression: n } = i, o = s ? `${s.requestId}:${s.slotId}:${e.original.id}:${this.getViewToken(e) || ""}` : `no-analytics:${e.original.id}:${this.getViewToken(e) || ""}`;
|
|
424
|
+
if (this.trackedImpressionKeys.has(o))
|
|
399
425
|
return;
|
|
400
426
|
let a = !1;
|
|
401
427
|
const c = () => {
|
|
402
|
-
a || this.trackedImpressionKeys.has(
|
|
403
|
-
},
|
|
404
|
-
s ?
|
|
428
|
+
a || this.trackedImpressionKeys.has(o) || (a = !0, this.trackedImpressionKeys.add(o), l());
|
|
429
|
+
}, l = () => {
|
|
430
|
+
s ? I({
|
|
405
431
|
requestId: s.requestId,
|
|
406
432
|
adId: e.original.id,
|
|
407
433
|
slotId: s.slotId,
|
|
@@ -411,26 +437,27 @@ const M = class M {
|
|
|
411
437
|
adTitle: e.adapted.title,
|
|
412
438
|
format: e.original.type,
|
|
413
439
|
source: "internal",
|
|
414
|
-
viewToken: e
|
|
440
|
+
viewToken: this.getViewToken(e),
|
|
441
|
+
userId: s.userId
|
|
415
442
|
}, { baseUrl: s.apiBaseUrl }).then(() => {
|
|
416
443
|
n && n(e);
|
|
417
|
-
}).catch((
|
|
418
|
-
console.error("[DOMRenderer] Analytics impression tracking failed:",
|
|
444
|
+
}).catch((d) => {
|
|
445
|
+
console.error("[DOMRenderer] Analytics impression tracking failed:", d);
|
|
419
446
|
}) : n && n(e);
|
|
420
447
|
};
|
|
421
448
|
if (typeof IntersectionObserver < "u") {
|
|
422
|
-
let
|
|
423
|
-
const
|
|
424
|
-
(
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
u = null,
|
|
449
|
+
let d = !1, u = null;
|
|
450
|
+
const h = new IntersectionObserver(
|
|
451
|
+
(f) => {
|
|
452
|
+
f.forEach((v) => {
|
|
453
|
+
d = v.isIntersecting && v.intersectionRatio >= 0.5, d ? u || (u = setTimeout(() => {
|
|
454
|
+
u = null, d && (c(), h.disconnect());
|
|
428
455
|
}, 1e3)) : u && (clearTimeout(u), u = null);
|
|
429
456
|
});
|
|
430
457
|
},
|
|
431
458
|
{ threshold: 0.5 }
|
|
432
459
|
), p = t.querySelector(`[data-ad-id="${e.original.id}"]`) || t;
|
|
433
|
-
|
|
460
|
+
h.observe(p);
|
|
434
461
|
} else
|
|
435
462
|
c();
|
|
436
463
|
}
|
|
@@ -469,8 +496,8 @@ const M = class M {
|
|
|
469
496
|
* Generate HTML for Sponsored Source Ad variants
|
|
470
497
|
*/
|
|
471
498
|
static generateSponsoredSourceHTML(e, t) {
|
|
472
|
-
var
|
|
473
|
-
const i = e.adapted.title || "", s = e.adapted.body || "", n = ((
|
|
499
|
+
var o;
|
|
500
|
+
const i = e.adapted.title || "", s = e.adapted.body || "", n = ((o = e.adapted.image) == null ? void 0 : o.url) || "";
|
|
474
501
|
return t === "list-item" ? `
|
|
475
502
|
<div class="ax-ad-source ax-ad-variant-list-item" data-ad-id="${e.original.id}">
|
|
476
503
|
${n ? `<img src="${n}" alt="${i}" loading="lazy" />` : ""}
|
|
@@ -507,9 +534,9 @@ const M = class M {
|
|
|
507
534
|
`;
|
|
508
535
|
}
|
|
509
536
|
};
|
|
510
|
-
|
|
511
|
-
let y =
|
|
512
|
-
class
|
|
537
|
+
C.trackedImpressionKeys = /* @__PURE__ */ new Set();
|
|
538
|
+
let y = C;
|
|
539
|
+
class S {
|
|
513
540
|
constructor() {
|
|
514
541
|
this.cachedStaticInfo = null, this.cacheTimestamp = 0, this.CACHE_TTL = 36e5;
|
|
515
542
|
}
|
|
@@ -596,7 +623,7 @@ class $ {
|
|
|
596
623
|
* Get singleton instance
|
|
597
624
|
*/
|
|
598
625
|
static getInstance() {
|
|
599
|
-
return this.instance || (this.instance = new
|
|
626
|
+
return this.instance || (this.instance = new S()), this.instance;
|
|
600
627
|
}
|
|
601
628
|
/**
|
|
602
629
|
* Collect all available client information
|
|
@@ -677,7 +704,7 @@ class $ {
|
|
|
677
704
|
collectUserInfo() {
|
|
678
705
|
let e;
|
|
679
706
|
try {
|
|
680
|
-
e = localStorage.getItem("
|
|
707
|
+
e = localStorage.getItem("actionx_user_id") || "", e || (e = this.generateUUID(), localStorage.setItem("actionx_user_id", e));
|
|
681
708
|
} catch {
|
|
682
709
|
e = this.generateUUID();
|
|
683
710
|
}
|
|
@@ -752,8 +779,8 @@ class $ {
|
|
|
752
779
|
const n = e.match(/(MI|Redmi|POCO)\s([\w\s]+)/);
|
|
753
780
|
if (n) return n[1] + " " + n[2];
|
|
754
781
|
if (/OnePlus/.test(e)) {
|
|
755
|
-
const
|
|
756
|
-
return
|
|
782
|
+
const o = e.match(/OnePlus\s([A-Z\d]+)/);
|
|
783
|
+
return o ? "OnePlus " + o[1] : "OnePlus";
|
|
757
784
|
}
|
|
758
785
|
}
|
|
759
786
|
/**
|
|
@@ -899,101 +926,105 @@ class $ {
|
|
|
899
926
|
this.cachedStaticInfo = null, this.cacheTimestamp = 0;
|
|
900
927
|
}
|
|
901
928
|
}
|
|
902
|
-
const
|
|
903
|
-
function b(
|
|
904
|
-
return
|
|
929
|
+
const $ = () => S.getInstance();
|
|
930
|
+
function b(r) {
|
|
931
|
+
return $().collect(r);
|
|
905
932
|
}
|
|
906
|
-
function
|
|
933
|
+
function J() {
|
|
907
934
|
return b().device;
|
|
908
935
|
}
|
|
909
|
-
function
|
|
936
|
+
function N() {
|
|
910
937
|
return b().user;
|
|
911
938
|
}
|
|
912
|
-
function
|
|
939
|
+
function X() {
|
|
913
940
|
return b().app;
|
|
914
941
|
}
|
|
915
|
-
function
|
|
942
|
+
function Z() {
|
|
916
943
|
return b().geo;
|
|
917
944
|
}
|
|
918
|
-
function
|
|
919
|
-
return
|
|
945
|
+
function Y() {
|
|
946
|
+
return N().id;
|
|
920
947
|
}
|
|
921
|
-
function
|
|
922
|
-
|
|
948
|
+
function ee() {
|
|
949
|
+
$().clearCache();
|
|
923
950
|
}
|
|
924
|
-
function
|
|
925
|
-
const e = b(
|
|
951
|
+
function te(r) {
|
|
952
|
+
const e = b(r);
|
|
926
953
|
return JSON.stringify(e, null, 2);
|
|
927
954
|
}
|
|
928
|
-
function
|
|
955
|
+
function ie() {
|
|
929
956
|
var t;
|
|
930
|
-
const
|
|
957
|
+
const r = b();
|
|
931
958
|
return [
|
|
932
|
-
|
|
933
|
-
|
|
934
|
-
|
|
935
|
-
|
|
936
|
-
((t =
|
|
959
|
+
r.device.os,
|
|
960
|
+
r.device.osv,
|
|
961
|
+
r.app.name,
|
|
962
|
+
r.user.id.slice(0, 8) + "...",
|
|
963
|
+
((t = r.geo) == null ? void 0 : t.country) || "Unknown"
|
|
937
964
|
].join(" / ");
|
|
938
965
|
}
|
|
939
|
-
function
|
|
966
|
+
function M() {
|
|
967
|
+
var r;
|
|
968
|
+
return typeof window < "u" ? !!((r = window.__AD_CONFIG__) != null && r.debug) : !1;
|
|
969
|
+
}
|
|
970
|
+
function se(r) {
|
|
940
971
|
var e, t;
|
|
941
972
|
return {
|
|
942
|
-
id:
|
|
943
|
-
type:
|
|
944
|
-
score:
|
|
973
|
+
id: r.original.id,
|
|
974
|
+
type: r.original.type,
|
|
975
|
+
score: r.original.score,
|
|
945
976
|
source: "internal",
|
|
946
977
|
// Default source
|
|
947
978
|
content: {
|
|
948
|
-
title:
|
|
949
|
-
body:
|
|
950
|
-
image: (e =
|
|
951
|
-
cta_text:
|
|
952
|
-
price: (t =
|
|
953
|
-
rating:
|
|
954
|
-
brand:
|
|
979
|
+
title: r.adapted.title,
|
|
980
|
+
body: r.adapted.body,
|
|
981
|
+
image: (e = r.adapted.image) == null ? void 0 : e.url,
|
|
982
|
+
cta_text: r.adapted.ctaText,
|
|
983
|
+
price: (t = r.adapted.price) == null ? void 0 : t.display,
|
|
984
|
+
rating: r.adapted.rating,
|
|
985
|
+
brand: r.adapted.brand
|
|
955
986
|
},
|
|
956
987
|
tracking: {
|
|
957
|
-
click_url:
|
|
958
|
-
impression_url:
|
|
988
|
+
click_url: r.tracking.clickUrl || r.tracking.click_url || "",
|
|
989
|
+
impression_url: r.tracking.impressionUrl || r.tracking.impression_url || ""
|
|
959
990
|
},
|
|
960
991
|
metadata: {
|
|
961
|
-
viewToken:
|
|
962
|
-
styling:
|
|
992
|
+
viewToken: r.tracking.viewToken || r.tracking.view_token,
|
|
993
|
+
styling: r.adapted.styling
|
|
963
994
|
}
|
|
964
995
|
};
|
|
965
996
|
}
|
|
966
|
-
async function
|
|
967
|
-
const t = e.apiBaseUrl || "/api/v1", s =
|
|
968
|
-
...
|
|
997
|
+
async function D(r, e = {}) {
|
|
998
|
+
const t = e.apiBaseUrl || "/api/v1", s = $().collect(), n = {
|
|
999
|
+
...r,
|
|
969
1000
|
clientInfo: s
|
|
970
1001
|
// Auto-injected
|
|
971
|
-
},
|
|
1002
|
+
}, o = {
|
|
972
1003
|
"Content-Type": "application/json"
|
|
973
1004
|
};
|
|
974
|
-
e.apiKey && (
|
|
1005
|
+
e.apiKey && (o["X-API-Key"] = e.apiKey), M() && (console.log("[fetchAds] Request URL:", `${t}/ads/request`), console.log("[fetchAds] Request params:", r), console.log("[fetchAds] Request body:", n));
|
|
975
1006
|
const a = await fetch(`${t}/ads/request`, {
|
|
976
1007
|
method: "POST",
|
|
977
|
-
headers:
|
|
1008
|
+
headers: o,
|
|
978
1009
|
body: JSON.stringify(n)
|
|
979
1010
|
});
|
|
980
1011
|
if (!a.ok)
|
|
981
1012
|
throw new Error(`Ad request failed: ${a.status} ${a.statusText}`);
|
|
982
1013
|
const c = await a.json();
|
|
983
|
-
if (!c.success)
|
|
1014
|
+
if (M() && console.log("[fetchAds] Response:", c), !c.success)
|
|
984
1015
|
throw new Error(c.error || "Ad request failed");
|
|
985
1016
|
return c.data;
|
|
986
1017
|
}
|
|
987
|
-
const
|
|
1018
|
+
const H = { width: 400, height: 200 }, A = {
|
|
988
1019
|
variant: "horizontal",
|
|
989
1020
|
count: 1,
|
|
990
1021
|
preferences: {}
|
|
991
1022
|
};
|
|
992
|
-
function
|
|
1023
|
+
function _(r = {}) {
|
|
993
1024
|
const e = {
|
|
994
|
-
variant:
|
|
995
|
-
count:
|
|
996
|
-
preferences: { ...A.preferences, ...
|
|
1025
|
+
variant: r.variant ?? A.variant,
|
|
1026
|
+
count: r.count ?? A.count,
|
|
1027
|
+
preferences: { ...A.preferences, ...r.preferences }
|
|
997
1028
|
};
|
|
998
1029
|
return [
|
|
999
1030
|
{
|
|
@@ -1001,7 +1032,7 @@ function U(o = {}) {
|
|
|
1001
1032
|
slotName: "Action Card",
|
|
1002
1033
|
format: "action_card",
|
|
1003
1034
|
variant: e.variant,
|
|
1004
|
-
size:
|
|
1035
|
+
size: H,
|
|
1005
1036
|
count: e.count,
|
|
1006
1037
|
preferences: e.preferences,
|
|
1007
1038
|
placement: { position: "below_fold", context: "post_response" }
|
|
@@ -1010,10 +1041,11 @@ function U(o = {}) {
|
|
|
1010
1041
|
}
|
|
1011
1042
|
const g = class g {
|
|
1012
1043
|
constructor(e) {
|
|
1013
|
-
this.slots = {}, this.isLoading = !1, this.currentRequestId = null, this.adsAnalyticsMap = /* @__PURE__ */ new Map(), this.config = e, this.enabled = e.enabled !== !1, this.eventBus = new
|
|
1044
|
+
this.slots = {}, this.isLoading = !1, this.currentRequestId = null, this.adsAnalyticsMap = /* @__PURE__ */ new Map(), this.config = e, this.enabled = e.enabled !== !1, this.eventBus = new O(), this.slots_config = _(e.cardOption), typeof window < "u" && (window.__AD_CONFIG__ = {
|
|
1014
1045
|
...window.__AD_CONFIG__ || {},
|
|
1015
1046
|
apiKey: e.apiKey,
|
|
1016
|
-
apiBaseUrl: e.apiBaseUrl
|
|
1047
|
+
apiBaseUrl: e.apiBaseUrl,
|
|
1048
|
+
debug: !!e.debug
|
|
1017
1049
|
}), this.config.debug && console.log("[AdManager] Initialized with config:", {
|
|
1018
1050
|
apiBaseUrl: e.apiBaseUrl,
|
|
1019
1051
|
hasApiKey: !!e.apiKey,
|
|
@@ -1021,7 +1053,10 @@ const g = class g {
|
|
|
1021
1053
|
});
|
|
1022
1054
|
}
|
|
1023
1055
|
async requestAds(e) {
|
|
1024
|
-
|
|
1056
|
+
var o;
|
|
1057
|
+
const t = "conversationContext" in e ? e : { conversationContext: e };
|
|
1058
|
+
this.currentUserId = (o = t.userContext) == null ? void 0 : o.userId;
|
|
1059
|
+
const i = this.buildRequestKey(t), s = g.inFlightRequests.get(i);
|
|
1025
1060
|
if (s)
|
|
1026
1061
|
return this.config.debug && console.log("[AdManager] Reusing in-flight request for identical context"), s;
|
|
1027
1062
|
if (!this.enabled)
|
|
@@ -1031,7 +1066,7 @@ const g = class g {
|
|
|
1031
1066
|
this.isLoading = !0, this.eventBus.emit("adsLoading"), this.config.debug && console.log("[AdManager] Starting ad request...");
|
|
1032
1067
|
const n = (async () => {
|
|
1033
1068
|
try {
|
|
1034
|
-
const
|
|
1069
|
+
const a = await D(
|
|
1035
1070
|
{
|
|
1036
1071
|
conversationContext: t.conversationContext,
|
|
1037
1072
|
userContext: t.userContext ? { ...t.userContext, sessionId: t.userContext.sessionId ?? m() } : { sessionId: m() },
|
|
@@ -1042,28 +1077,29 @@ const g = class g {
|
|
|
1042
1077
|
apiKey: this.config.apiKey
|
|
1043
1078
|
}
|
|
1044
1079
|
);
|
|
1045
|
-
this.currentRequestId =
|
|
1046
|
-
|
|
1047
|
-
const
|
|
1048
|
-
this.adsAnalyticsMap.set(
|
|
1049
|
-
requestId:
|
|
1050
|
-
slotId:
|
|
1051
|
-
position:
|
|
1052
|
-
totalAds:
|
|
1053
|
-
apiBaseUrl: this.config.apiBaseUrl
|
|
1080
|
+
this.currentRequestId = a.requestId, this.adsAnalyticsMap.clear(), a.slots.forEach((l) => {
|
|
1081
|
+
l.ads.forEach((d, u) => {
|
|
1082
|
+
const h = d.original.id;
|
|
1083
|
+
this.adsAnalyticsMap.set(h, {
|
|
1084
|
+
requestId: a.requestId,
|
|
1085
|
+
slotId: l.slotId,
|
|
1086
|
+
position: u,
|
|
1087
|
+
totalAds: l.ads.length,
|
|
1088
|
+
apiBaseUrl: this.config.apiBaseUrl,
|
|
1089
|
+
userId: this.currentUserId
|
|
1054
1090
|
});
|
|
1055
1091
|
});
|
|
1056
1092
|
});
|
|
1057
|
-
const
|
|
1058
|
-
return
|
|
1059
|
-
|
|
1060
|
-
}), this.slots =
|
|
1093
|
+
const c = {};
|
|
1094
|
+
return a.slots.forEach((l) => {
|
|
1095
|
+
c[l.slotId] = l;
|
|
1096
|
+
}), this.slots = c, this.eventBus.emit("adsUpdated", this.slots), this.config.debug && console.log("[AdManager] Ads received:", {
|
|
1061
1097
|
slotCount: Object.keys(this.slots).length,
|
|
1062
1098
|
slots: Object.keys(this.slots)
|
|
1063
|
-
}),
|
|
1064
|
-
} catch (
|
|
1065
|
-
const
|
|
1066
|
-
throw this.eventBus.emit("adsError",
|
|
1099
|
+
}), a;
|
|
1100
|
+
} catch (a) {
|
|
1101
|
+
const c = a;
|
|
1102
|
+
throw this.eventBus.emit("adsError", c), c;
|
|
1067
1103
|
} finally {
|
|
1068
1104
|
this.isLoading = !1, g.inFlightRequests.delete(i);
|
|
1069
1105
|
}
|
|
@@ -1080,24 +1116,24 @@ const g = class g {
|
|
|
1080
1116
|
});
|
|
1081
1117
|
}
|
|
1082
1118
|
render(e, t, i = {}) {
|
|
1083
|
-
const s = typeof e != "string", n = s ? g.DEFAULT_SLOT_ID : e,
|
|
1084
|
-
if (!
|
|
1119
|
+
const s = typeof e != "string", n = s ? g.DEFAULT_SLOT_ID : e, o = s ? e : t, a = (s ? t : i) || {};
|
|
1120
|
+
if (!o)
|
|
1085
1121
|
return this.config.debug && console.warn("[AdManager] Render container is required"), null;
|
|
1086
1122
|
const c = this.slots[n];
|
|
1087
1123
|
if (!c || !c.ads || c.ads.length === 0)
|
|
1088
1124
|
return this.config.debug && console.warn("[AdManager] No ads in slot:", n), null;
|
|
1089
|
-
const
|
|
1090
|
-
if (!
|
|
1091
|
-
return this.config.debug && console.warn(`[AdManager] Ad at index ${
|
|
1092
|
-
const u = this.adsAnalyticsMap.get(
|
|
1093
|
-
|
|
1094
|
-
const
|
|
1125
|
+
const l = a.adIndex ?? 0, d = c.ads[l];
|
|
1126
|
+
if (!d)
|
|
1127
|
+
return this.config.debug && console.warn(`[AdManager] Ad at index ${l} not found in slot:`, n), null;
|
|
1128
|
+
const u = this.adsAnalyticsMap.get(d.original.id), h = this.slots_config.find((v) => v.slotId === n), p = (h == null ? void 0 : h.format) || "action_card";
|
|
1129
|
+
o.innerHTML = "";
|
|
1130
|
+
const f = {
|
|
1095
1131
|
analytics: u,
|
|
1096
1132
|
variant: a.variant,
|
|
1097
1133
|
onClick: a.onClick,
|
|
1098
1134
|
onImpression: a.onImpression
|
|
1099
1135
|
};
|
|
1100
|
-
return p === "suffix" ? y.renderSuffixAd(
|
|
1136
|
+
return p === "suffix" ? y.renderSuffixAd(d, o, f) : p === "source" ? y.renderSponsoredSource(d, o, f) : p === "lead_gen" ? y.renderLeadGenAd(d, o, f) : y.renderActionCard(d, o, f);
|
|
1101
1137
|
}
|
|
1102
1138
|
/**
|
|
1103
1139
|
* Get ad slots data
|
|
@@ -1136,7 +1172,7 @@ const g = class g {
|
|
|
1136
1172
|
* Update configuration
|
|
1137
1173
|
*/
|
|
1138
1174
|
updateConfig(e) {
|
|
1139
|
-
this.config = { ...this.config, ...e }, e.cardOption !== void 0 && (this.slots_config =
|
|
1175
|
+
this.config = { ...this.config, ...e }, e.cardOption !== void 0 && (this.slots_config = _(this.config.cardOption)), this.config.debug && console.log("[AdManager] Config updated:", e);
|
|
1140
1176
|
}
|
|
1141
1177
|
/**
|
|
1142
1178
|
* Clear all slot data
|
|
@@ -1191,7 +1227,7 @@ const g = class g {
|
|
|
1191
1227
|
const s = this.adsAnalyticsMap.get(e);
|
|
1192
1228
|
if (!s || !this.currentRequestId)
|
|
1193
1229
|
return this.config.debug && console.warn("[AdManager] No analytics info for ad:", e), null;
|
|
1194
|
-
const n = m(),
|
|
1230
|
+
const n = m(), o = await T({
|
|
1195
1231
|
requestId: this.currentRequestId,
|
|
1196
1232
|
adId: e,
|
|
1197
1233
|
destinationUrl: t,
|
|
@@ -1199,9 +1235,10 @@ const g = class g {
|
|
|
1199
1235
|
slotId: s.slotId,
|
|
1200
1236
|
adTitle: i == null ? void 0 : i.title,
|
|
1201
1237
|
format: i == null ? void 0 : i.format,
|
|
1202
|
-
source: i == null ? void 0 : i.source
|
|
1238
|
+
source: i == null ? void 0 : i.source,
|
|
1239
|
+
userId: s.userId ?? this.currentUserId
|
|
1203
1240
|
}, { baseUrl: s.apiBaseUrl });
|
|
1204
|
-
return
|
|
1241
|
+
return o && (this.eventBus.emit("adClicked", e, s.slotId), this.config.debug && console.log("[AdManager] Click tracked via Analytics API:", o.eventId)), o;
|
|
1205
1242
|
}
|
|
1206
1243
|
/**
|
|
1207
1244
|
* Track ad impression using Analytics API
|
|
@@ -1210,7 +1247,7 @@ const g = class g {
|
|
|
1210
1247
|
const i = this.adsAnalyticsMap.get(e);
|
|
1211
1248
|
if (!i || !this.currentRequestId)
|
|
1212
1249
|
return this.config.debug && console.warn("[AdManager] No analytics info for ad:", e), null;
|
|
1213
|
-
const s = m(), n = await
|
|
1250
|
+
const s = m(), n = await I({
|
|
1214
1251
|
requestId: this.currentRequestId,
|
|
1215
1252
|
adId: e,
|
|
1216
1253
|
slotId: i.slotId,
|
|
@@ -1220,7 +1257,8 @@ const g = class g {
|
|
|
1220
1257
|
adTitle: t == null ? void 0 : t.title,
|
|
1221
1258
|
format: t == null ? void 0 : t.format,
|
|
1222
1259
|
source: t == null ? void 0 : t.source,
|
|
1223
|
-
viewToken: t == null ? void 0 : t.viewToken
|
|
1260
|
+
viewToken: t == null ? void 0 : t.viewToken,
|
|
1261
|
+
userId: i.userId ?? this.currentUserId
|
|
1224
1262
|
}, { baseUrl: i.apiBaseUrl });
|
|
1225
1263
|
return n && (this.eventBus.emit("adImpression", e, i.slotId), this.config.debug && console.log("[AdManager] Impression tracked via Analytics API:", n.eventId)), n;
|
|
1226
1264
|
}
|
|
@@ -1235,12 +1273,12 @@ g.DEFAULT_SLOT_ID = "action_card", g.inFlightRequests = /* @__PURE__ */ new Map(
|
|
|
1235
1273
|
let V = g;
|
|
1236
1274
|
function E() {
|
|
1237
1275
|
if (typeof window < "u") {
|
|
1238
|
-
const
|
|
1239
|
-
if (
|
|
1240
|
-
return
|
|
1276
|
+
const r = window.__AD_CONFIG__;
|
|
1277
|
+
if (r != null && r.apiKey)
|
|
1278
|
+
return r.apiKey;
|
|
1241
1279
|
}
|
|
1242
1280
|
}
|
|
1243
|
-
class
|
|
1281
|
+
class F {
|
|
1244
1282
|
constructor(e = {}, t = "/api/v1") {
|
|
1245
1283
|
var i, s;
|
|
1246
1284
|
this.observers = /* @__PURE__ */ new Map(), this.metrics = /* @__PURE__ */ new Map(), this.timers = /* @__PURE__ */ new Map(), this.batchTimers = /* @__PURE__ */ new Map(), this.eventQueue = /* @__PURE__ */ new Map(), this.isTracking = /* @__PURE__ */ new Map(), this.config = {
|
|
@@ -1263,7 +1301,7 @@ class H {
|
|
|
1263
1301
|
return;
|
|
1264
1302
|
}
|
|
1265
1303
|
this.log(`[ViewabilityTracker] Starting tracking for ${e}`);
|
|
1266
|
-
const
|
|
1304
|
+
const o = {
|
|
1267
1305
|
visiblePercentage: 0,
|
|
1268
1306
|
maxVisiblePercentage: 0,
|
|
1269
1307
|
totalVisibleTimeMs: 0,
|
|
@@ -1273,9 +1311,9 @@ class H {
|
|
|
1273
1311
|
enteredViewportAt: null,
|
|
1274
1312
|
enterCount: 0
|
|
1275
1313
|
};
|
|
1276
|
-
this.metrics.set(e,
|
|
1314
|
+
this.metrics.set(e, o), this.isTracking.set(e, !0), this.eventQueue.set(e, []);
|
|
1277
1315
|
const a = new IntersectionObserver(
|
|
1278
|
-
(
|
|
1316
|
+
(l) => this.handleIntersection(e, l[0], i, s, n),
|
|
1279
1317
|
{
|
|
1280
1318
|
threshold: this.createThresholds()
|
|
1281
1319
|
}
|
|
@@ -1303,54 +1341,54 @@ class H {
|
|
|
1303
1341
|
* Event-driven: Only process when state actually changes
|
|
1304
1342
|
*/
|
|
1305
1343
|
handleIntersection(e, t, i, s, n) {
|
|
1306
|
-
const
|
|
1307
|
-
if (!
|
|
1308
|
-
const a =
|
|
1309
|
-
|
|
1310
|
-
const
|
|
1311
|
-
if (
|
|
1344
|
+
const o = this.metrics.get(e);
|
|
1345
|
+
if (!o || !this.isTracking.get(e)) return;
|
|
1346
|
+
const a = o.isViewable, c = Math.round(t.intersectionRatio * 100);
|
|
1347
|
+
o.visiblePercentage = c, o.maxVisiblePercentage = Math.max(o.maxVisiblePercentage, c);
|
|
1348
|
+
const l = Date.now(), d = c >= this.config.minVisiblePercentage;
|
|
1349
|
+
if (d && !o.enteredViewportAt && (o.enteredViewportAt = l, o.enterCount++, this.log(`[ViewabilityTracker] ${e} entered viewport at ${l}`), this.queueEvent(e, {
|
|
1312
1350
|
adId: e,
|
|
1313
1351
|
sessionId: i,
|
|
1314
1352
|
requestId: s,
|
|
1315
1353
|
viewToken: n,
|
|
1316
1354
|
eventType: "enter_viewport",
|
|
1317
1355
|
visiblePercentage: c,
|
|
1318
|
-
maxVisiblePercentage:
|
|
1319
|
-
totalVisibleTimeMs:
|
|
1356
|
+
maxVisiblePercentage: o.maxVisiblePercentage,
|
|
1357
|
+
totalVisibleTimeMs: o.totalVisibleTimeMs,
|
|
1320
1358
|
isViewable: !1,
|
|
1321
|
-
timestamp:
|
|
1322
|
-
})), !
|
|
1323
|
-
const u =
|
|
1324
|
-
|
|
1359
|
+
timestamp: l
|
|
1360
|
+
})), !d && o.enteredViewportAt) {
|
|
1361
|
+
const u = l - o.enteredViewportAt;
|
|
1362
|
+
o.totalVisibleTimeMs += u, o.enteredViewportAt = null, o.currentVisibleTimeMs = 0, this.log(`[ViewabilityTracker] ${e} exited viewport, total visible: ${o.totalVisibleTimeMs}ms`), this.queueEvent(e, {
|
|
1325
1363
|
adId: e,
|
|
1326
1364
|
sessionId: i,
|
|
1327
1365
|
requestId: s,
|
|
1328
1366
|
viewToken: n,
|
|
1329
1367
|
eventType: "exit_viewport",
|
|
1330
1368
|
visiblePercentage: c,
|
|
1331
|
-
maxVisiblePercentage:
|
|
1332
|
-
totalVisibleTimeMs:
|
|
1333
|
-
isViewable:
|
|
1334
|
-
timestamp:
|
|
1369
|
+
maxVisiblePercentage: o.maxVisiblePercentage,
|
|
1370
|
+
totalVisibleTimeMs: o.totalVisibleTimeMs,
|
|
1371
|
+
isViewable: o.isViewable,
|
|
1372
|
+
timestamp: l
|
|
1335
1373
|
});
|
|
1336
1374
|
}
|
|
1337
|
-
|
|
1375
|
+
o.isViewable !== a && o.isViewable && this.log(`[ViewabilityTracker] ${e} became VIEWABLE!`), this.metrics.set(e, o);
|
|
1338
1376
|
}
|
|
1339
1377
|
/**
|
|
1340
1378
|
* Start monitoring loop for tracking duration
|
|
1341
1379
|
* Runs every 100ms to track continuous visible time
|
|
1342
1380
|
*/
|
|
1343
1381
|
startMonitoring(e, t, i, s) {
|
|
1344
|
-
const
|
|
1382
|
+
const o = setInterval(() => {
|
|
1345
1383
|
const a = this.metrics.get(e);
|
|
1346
1384
|
if (!a || !this.isTracking.get(e)) {
|
|
1347
|
-
clearInterval(
|
|
1385
|
+
clearInterval(o);
|
|
1348
1386
|
return;
|
|
1349
1387
|
}
|
|
1350
|
-
const c = Date.now(),
|
|
1388
|
+
const c = Date.now(), l = a.isViewable;
|
|
1351
1389
|
if (a.enteredViewportAt) {
|
|
1352
|
-
const
|
|
1353
|
-
a.currentVisibleTimeMs =
|
|
1390
|
+
const d = c - a.enteredViewportAt;
|
|
1391
|
+
a.currentVisibleTimeMs = d, d >= this.config.minViewableDuration && a.visiblePercentage >= this.config.minVisiblePercentage && (a.isViewable = !0, l || (a.viewableAt = a.enteredViewportAt, this.log(`[ViewabilityTracker] ${e} BECAME VIEWABLE at ${a.viewableAt}`), this.queueEvent(e, {
|
|
1354
1392
|
adId: e,
|
|
1355
1393
|
sessionId: t,
|
|
1356
1394
|
requestId: i,
|
|
@@ -1365,13 +1403,13 @@ class H {
|
|
|
1365
1403
|
}
|
|
1366
1404
|
a.enteredViewportAt && (a.totalVisibleTimeMs += 100), this.metrics.set(e, a);
|
|
1367
1405
|
}, 100);
|
|
1368
|
-
this.timers.set(`${e}_monitoring`,
|
|
1406
|
+
this.timers.set(`${e}_monitoring`, o);
|
|
1369
1407
|
}
|
|
1370
1408
|
/**
|
|
1371
1409
|
* Queue an event to be sent (batched)
|
|
1372
1410
|
*/
|
|
1373
1411
|
queueEvent(e, t) {
|
|
1374
|
-
var n,
|
|
1412
|
+
var n, o;
|
|
1375
1413
|
const i = this.eventQueue.get(e);
|
|
1376
1414
|
if (!i) {
|
|
1377
1415
|
this.log(`[ViewabilityTracker] No queue found for ${e}, skipping event`);
|
|
@@ -1384,10 +1422,10 @@ class H {
|
|
|
1384
1422
|
else {
|
|
1385
1423
|
const a = this.batchTimers.get(e);
|
|
1386
1424
|
a && clearTimeout(a);
|
|
1387
|
-
const c = ((
|
|
1425
|
+
const c = ((o = this.config.batchConfig) == null ? void 0 : o.maxBatchWaitMs) ?? 1e4, l = setTimeout(() => {
|
|
1388
1426
|
this.flushQueue(e);
|
|
1389
1427
|
}, c);
|
|
1390
|
-
this.batchTimers.set(e,
|
|
1428
|
+
this.batchTimers.set(e, l);
|
|
1391
1429
|
}
|
|
1392
1430
|
}
|
|
1393
1431
|
/**
|
|
@@ -1418,7 +1456,7 @@ class H {
|
|
|
1418
1456
|
const n = this.metrics.get(e);
|
|
1419
1457
|
if (!n) return;
|
|
1420
1458
|
this.log(`[ViewabilityTracker] Ending tracking for ${e}`), this.flushQueue(e);
|
|
1421
|
-
const
|
|
1459
|
+
const o = Date.now();
|
|
1422
1460
|
this.queueEvent(e, {
|
|
1423
1461
|
adId: e,
|
|
1424
1462
|
sessionId: t,
|
|
@@ -1429,7 +1467,7 @@ class H {
|
|
|
1429
1467
|
maxVisiblePercentage: n.maxVisiblePercentage,
|
|
1430
1468
|
totalVisibleTimeMs: n.totalVisibleTimeMs,
|
|
1431
1469
|
isViewable: n.isViewable,
|
|
1432
|
-
timestamp:
|
|
1470
|
+
timestamp: o
|
|
1433
1471
|
}), this.flushQueue(e), this.cleanup(e);
|
|
1434
1472
|
}
|
|
1435
1473
|
/**
|
|
@@ -1488,38 +1526,38 @@ class H {
|
|
|
1488
1526
|
}
|
|
1489
1527
|
}
|
|
1490
1528
|
let k = null;
|
|
1491
|
-
function
|
|
1492
|
-
return k || (k = new
|
|
1529
|
+
function ne(r, e) {
|
|
1530
|
+
return k || (k = new F(r, e), k.setupBeforeUnload()), k;
|
|
1493
1531
|
}
|
|
1494
|
-
const
|
|
1532
|
+
const re = "0.1.0";
|
|
1495
1533
|
export {
|
|
1496
1534
|
V as AdManager,
|
|
1497
1535
|
x as AnalyticsSender,
|
|
1498
|
-
|
|
1536
|
+
S as ClientInfoCollector,
|
|
1499
1537
|
y as DOMRenderer,
|
|
1500
|
-
|
|
1501
|
-
|
|
1502
|
-
|
|
1503
|
-
|
|
1504
|
-
|
|
1505
|
-
|
|
1506
|
-
|
|
1507
|
-
|
|
1508
|
-
|
|
1509
|
-
|
|
1510
|
-
|
|
1538
|
+
w as HTMLRenderer,
|
|
1539
|
+
re as SDK_VERSION,
|
|
1540
|
+
P as SessionManager,
|
|
1541
|
+
F as ViewabilityTracker,
|
|
1542
|
+
se as adaptAdToKoahAd,
|
|
1543
|
+
ee as clearClientInfoCache,
|
|
1544
|
+
W as createAnalytics,
|
|
1545
|
+
Q as createSession,
|
|
1546
|
+
D as fetchAds,
|
|
1547
|
+
G as generateViewToken,
|
|
1548
|
+
X as getAppInfo,
|
|
1511
1549
|
b as getClientInfo,
|
|
1512
|
-
|
|
1513
|
-
|
|
1514
|
-
|
|
1515
|
-
|
|
1516
|
-
|
|
1550
|
+
$ as getClientInfoCollector,
|
|
1551
|
+
te as getClientInfoJSON,
|
|
1552
|
+
ie as getClientInfoSummary,
|
|
1553
|
+
J as getDeviceInfo,
|
|
1554
|
+
Z as getGeoInfo,
|
|
1517
1555
|
m as getSessionId,
|
|
1518
|
-
|
|
1519
|
-
|
|
1520
|
-
|
|
1556
|
+
Y as getUserId,
|
|
1557
|
+
N as getUserInfo,
|
|
1558
|
+
ne as getViewabilityTracker,
|
|
1521
1559
|
T as trackAdClick,
|
|
1522
|
-
|
|
1523
|
-
|
|
1524
|
-
|
|
1560
|
+
I as trackAdImpression,
|
|
1561
|
+
j as trackClicksBatch,
|
|
1562
|
+
z as trackImpressionsBatch
|
|
1525
1563
|
};
|