@action-x/ad-sdk 0.1.5 → 0.1.6

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