@bidkernel/analytics 0.7.0 → 0.10.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/README.md +13 -13
- package/dist/analytics.global.js +1 -1
- package/dist/index.d.mts +56 -1
- package/dist/index.d.ts +56 -1
- package/dist/index.js +899 -197
- package/dist/index.mjs +896 -197
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -24,6 +24,9 @@ __export(src_exports, {
|
|
|
24
24
|
PrebidEventDeduper: () => PrebidEventDeduper,
|
|
25
25
|
getPrebidEventKey: () => getPrebidEventKey,
|
|
26
26
|
getbidkernel: () => getbidkernel,
|
|
27
|
+
hookImaPrototype: () => hookImaPrototype,
|
|
28
|
+
initImaInterception: () => initImaInterception,
|
|
29
|
+
isTrustedEndpoint: () => isTrustedEndpoint,
|
|
27
30
|
registerPrebidAnalytics: () => registerPrebidAnalytics
|
|
28
31
|
});
|
|
29
32
|
module.exports = __toCommonJS(src_exports);
|
|
@@ -34,26 +37,33 @@ var TraceEventType = {
|
|
|
34
37
|
TRACE_EVENT_TYPE_UNSPECIFIED: 0,
|
|
35
38
|
AUCTION_START: 1,
|
|
36
39
|
AUCTION_END: 2,
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
BID_WIN: 5,
|
|
40
|
-
BID_TIMEOUT: 6,
|
|
40
|
+
BID_RESPONSE: 3,
|
|
41
|
+
BID_WIN: 4,
|
|
41
42
|
/** IMPRESSION - ad rendered into DOM */
|
|
42
|
-
IMPRESSION:
|
|
43
|
+
IMPRESSION: 5,
|
|
43
44
|
/** VIEWABLE - IAB viewability threshold met (boolean, once per render cycle) */
|
|
44
|
-
VIEWABLE:
|
|
45
|
+
VIEWABLE: 6,
|
|
45
46
|
/** TIME_IN_VIEW - accumulated in-viewport duration (once per render cycle end) */
|
|
46
|
-
TIME_IN_VIEW:
|
|
47
|
-
REFRESH:
|
|
48
|
-
ERROR:
|
|
49
|
-
SLOT_DEFINED:
|
|
50
|
-
SLOT_DESTROYED:
|
|
47
|
+
TIME_IN_VIEW: 7,
|
|
48
|
+
REFRESH: 8,
|
|
49
|
+
ERROR: 9,
|
|
50
|
+
SLOT_DEFINED: 10,
|
|
51
|
+
SLOT_DESTROYED: 11,
|
|
51
52
|
/** CLICK - ad click-through */
|
|
52
|
-
CLICK:
|
|
53
|
-
/** NO_BID - bidder responded with no bid */
|
|
54
|
-
NO_BID: 15,
|
|
53
|
+
CLICK: 12,
|
|
55
54
|
/** AD_RENDER_FAILED - Prebid failed to render the winning ad */
|
|
56
|
-
AD_RENDER_FAILED:
|
|
55
|
+
AD_RENDER_FAILED: 13,
|
|
56
|
+
UNRECOGNIZED: -1
|
|
57
|
+
};
|
|
58
|
+
var BidderOutcome = {
|
|
59
|
+
BIDDER_OUTCOME_UNSPECIFIED: 0,
|
|
60
|
+
/** BIDDER_OUTCOME_BID - returned a bid (CPM > 0) */
|
|
61
|
+
BIDDER_OUTCOME_BID: 1,
|
|
62
|
+
BIDDER_OUTCOME_NO_BID: 2,
|
|
63
|
+
BIDDER_OUTCOME_TIMEOUT: 3,
|
|
64
|
+
BIDDER_OUTCOME_ERROR: 4,
|
|
65
|
+
/** BIDDER_OUTCOME_NO_RESPONSE - requested, nothing came back by auction end */
|
|
66
|
+
BIDDER_OUTCOME_NO_RESPONSE: 5,
|
|
57
67
|
UNRECOGNIZED: -1
|
|
58
68
|
};
|
|
59
69
|
function createBaseTraceEventBatch() {
|
|
@@ -284,7 +294,8 @@ function createBaseTraceEvent() {
|
|
|
284
294
|
namespace: "",
|
|
285
295
|
eventId: "",
|
|
286
296
|
metadata: {},
|
|
287
|
-
viewableDurationMs: void 0
|
|
297
|
+
viewableDurationMs: void 0,
|
|
298
|
+
bidderOutcomes: []
|
|
288
299
|
};
|
|
289
300
|
}
|
|
290
301
|
var TraceEvent = {
|
|
@@ -322,6 +333,11 @@ var TraceEvent = {
|
|
|
322
333
|
if (message.viewableDurationMs !== void 0) {
|
|
323
334
|
writer.uint32(89).double(message.viewableDurationMs);
|
|
324
335
|
}
|
|
336
|
+
if (message.bidderOutcomes !== void 0 && message.bidderOutcomes.length !== 0) {
|
|
337
|
+
for (const v of message.bidderOutcomes) {
|
|
338
|
+
BidderOutcomeEntry.encode(v, writer.uint32(98).fork()).join();
|
|
339
|
+
}
|
|
340
|
+
}
|
|
325
341
|
return writer;
|
|
326
342
|
},
|
|
327
343
|
decode(input, length) {
|
|
@@ -411,6 +427,16 @@ var TraceEvent = {
|
|
|
411
427
|
message.viewableDurationMs = reader.double();
|
|
412
428
|
continue;
|
|
413
429
|
}
|
|
430
|
+
case 12: {
|
|
431
|
+
if (tag !== 98) {
|
|
432
|
+
break;
|
|
433
|
+
}
|
|
434
|
+
const el = BidderOutcomeEntry.decode(reader, reader.uint32());
|
|
435
|
+
if (el !== void 0) {
|
|
436
|
+
message.bidderOutcomes.push(el);
|
|
437
|
+
}
|
|
438
|
+
continue;
|
|
439
|
+
}
|
|
414
440
|
}
|
|
415
441
|
if ((tag & 7) === 4 || tag === 0) {
|
|
416
442
|
break;
|
|
@@ -443,6 +469,7 @@ var TraceEvent = {
|
|
|
443
469
|
{}
|
|
444
470
|
);
|
|
445
471
|
message.viewableDurationMs = object.viewableDurationMs ?? void 0;
|
|
472
|
+
message.bidderOutcomes = object.bidderOutcomes?.map((e) => BidderOutcomeEntry.fromPartial(e)) || [];
|
|
446
473
|
return message;
|
|
447
474
|
}
|
|
448
475
|
};
|
|
@@ -498,6 +525,91 @@ var TraceEvent_MetadataEntry = {
|
|
|
498
525
|
return message;
|
|
499
526
|
}
|
|
500
527
|
};
|
|
528
|
+
function createBaseBidderOutcomeEntry() {
|
|
529
|
+
return { bidder: "", adUnitCode: "", mediaType: "", outcome: 0, latencyMs: 0 };
|
|
530
|
+
}
|
|
531
|
+
var BidderOutcomeEntry = {
|
|
532
|
+
encode(message, writer = new import_wire.BinaryWriter()) {
|
|
533
|
+
if (message.bidder !== void 0 && message.bidder !== "") {
|
|
534
|
+
writer.uint32(10).string(message.bidder);
|
|
535
|
+
}
|
|
536
|
+
if (message.adUnitCode !== void 0 && message.adUnitCode !== "") {
|
|
537
|
+
writer.uint32(18).string(message.adUnitCode);
|
|
538
|
+
}
|
|
539
|
+
if (message.mediaType !== void 0 && message.mediaType !== "") {
|
|
540
|
+
writer.uint32(26).string(message.mediaType);
|
|
541
|
+
}
|
|
542
|
+
if (message.outcome !== void 0 && message.outcome !== 0) {
|
|
543
|
+
writer.uint32(32).int32(message.outcome);
|
|
544
|
+
}
|
|
545
|
+
if (message.latencyMs !== void 0 && message.latencyMs !== 0) {
|
|
546
|
+
writer.uint32(41).double(message.latencyMs);
|
|
547
|
+
}
|
|
548
|
+
return writer;
|
|
549
|
+
},
|
|
550
|
+
decode(input, length) {
|
|
551
|
+
const reader = input instanceof import_wire.BinaryReader ? input : new import_wire.BinaryReader(input);
|
|
552
|
+
const end = length === void 0 ? reader.len : reader.pos + length;
|
|
553
|
+
const message = createBaseBidderOutcomeEntry();
|
|
554
|
+
while (reader.pos < end) {
|
|
555
|
+
const tag = reader.uint32();
|
|
556
|
+
switch (tag >>> 3) {
|
|
557
|
+
case 1: {
|
|
558
|
+
if (tag !== 10) {
|
|
559
|
+
break;
|
|
560
|
+
}
|
|
561
|
+
message.bidder = reader.string();
|
|
562
|
+
continue;
|
|
563
|
+
}
|
|
564
|
+
case 2: {
|
|
565
|
+
if (tag !== 18) {
|
|
566
|
+
break;
|
|
567
|
+
}
|
|
568
|
+
message.adUnitCode = reader.string();
|
|
569
|
+
continue;
|
|
570
|
+
}
|
|
571
|
+
case 3: {
|
|
572
|
+
if (tag !== 26) {
|
|
573
|
+
break;
|
|
574
|
+
}
|
|
575
|
+
message.mediaType = reader.string();
|
|
576
|
+
continue;
|
|
577
|
+
}
|
|
578
|
+
case 4: {
|
|
579
|
+
if (tag !== 32) {
|
|
580
|
+
break;
|
|
581
|
+
}
|
|
582
|
+
message.outcome = reader.int32();
|
|
583
|
+
continue;
|
|
584
|
+
}
|
|
585
|
+
case 5: {
|
|
586
|
+
if (tag !== 41) {
|
|
587
|
+
break;
|
|
588
|
+
}
|
|
589
|
+
message.latencyMs = reader.double();
|
|
590
|
+
continue;
|
|
591
|
+
}
|
|
592
|
+
}
|
|
593
|
+
if ((tag & 7) === 4 || tag === 0) {
|
|
594
|
+
break;
|
|
595
|
+
}
|
|
596
|
+
reader.skip(tag & 7);
|
|
597
|
+
}
|
|
598
|
+
return message;
|
|
599
|
+
},
|
|
600
|
+
create(base) {
|
|
601
|
+
return BidderOutcomeEntry.fromPartial(base ?? {});
|
|
602
|
+
},
|
|
603
|
+
fromPartial(object) {
|
|
604
|
+
const message = createBaseBidderOutcomeEntry();
|
|
605
|
+
message.bidder = object.bidder ?? "";
|
|
606
|
+
message.adUnitCode = object.adUnitCode ?? "";
|
|
607
|
+
message.mediaType = object.mediaType ?? "";
|
|
608
|
+
message.outcome = object.outcome ?? 0;
|
|
609
|
+
message.latencyMs = object.latencyMs ?? 0;
|
|
610
|
+
return message;
|
|
611
|
+
}
|
|
612
|
+
};
|
|
501
613
|
function createBaseBidTrace() {
|
|
502
614
|
return {
|
|
503
615
|
bidder: "",
|
|
@@ -658,6 +770,8 @@ var MAX_QUEUE_SIZE = 200;
|
|
|
658
770
|
var MAX_SEND_BACKOFF_MS = 5 * 60 * 1e3;
|
|
659
771
|
var MAX_CONSECUTIVE_SEND_FAILURES = 10;
|
|
660
772
|
var MAX_PAYLOAD_BYTES = 32 * 1024;
|
|
773
|
+
var MAX_METADATA_VALUE_CHARS = 1024;
|
|
774
|
+
var MAX_METADATA_ENTRIES = 16;
|
|
661
775
|
var SAFE_CONTENT_TYPE = "text/plain";
|
|
662
776
|
var PENDING_BATCH_KEY_PREFIX = "_bidkernel_pending_";
|
|
663
777
|
var MAX_PENDING_BATCHES = 20;
|
|
@@ -666,11 +780,8 @@ var PENDING_BATCH_CLEANUP_DELAY_MS = 1e4;
|
|
|
666
780
|
var EVENT_NAME_TO_TYPE = {
|
|
667
781
|
auctionStart: TraceEventType.AUCTION_START,
|
|
668
782
|
auctionEnd: TraceEventType.AUCTION_END,
|
|
669
|
-
bidRequest: TraceEventType.BID_REQUEST,
|
|
670
783
|
bidResponse: TraceEventType.BID_RESPONSE,
|
|
671
|
-
bidTimeout: TraceEventType.BID_TIMEOUT,
|
|
672
784
|
bidWin: TraceEventType.BID_WIN,
|
|
673
|
-
noBid: TraceEventType.NO_BID,
|
|
674
785
|
adRenderFailed: TraceEventType.AD_RENDER_FAILED,
|
|
675
786
|
click: TraceEventType.CLICK,
|
|
676
787
|
impression: TraceEventType.IMPRESSION,
|
|
@@ -683,6 +794,10 @@ var IMMEDIATE_FLUSH_TYPES = /* @__PURE__ */ new Set([
|
|
|
683
794
|
TraceEventType.BID_WIN,
|
|
684
795
|
TraceEventType.CLICK
|
|
685
796
|
]);
|
|
797
|
+
var CACHED_BID_TTL_MS = 30 * 60 * 1e3;
|
|
798
|
+
var MAX_CACHED_BID_KEYS = 200;
|
|
799
|
+
var MAX_IMPRESSION_KEYS = 1e3;
|
|
800
|
+
var MAX_TRACKED_AUCTIONS = 50;
|
|
686
801
|
var SESSION_KEY = "_bidkernel_session";
|
|
687
802
|
var SESSION_TS_KEY = "_bidkernel_session_ts";
|
|
688
803
|
var THIRTY_MINUTES_MS = 30 * 60 * 1e3;
|
|
@@ -714,6 +829,46 @@ function base64ToBytes(b64) {
|
|
|
714
829
|
}
|
|
715
830
|
return bytes;
|
|
716
831
|
}
|
|
832
|
+
function isTrustedEndpoint(raw) {
|
|
833
|
+
if (!raw) return false;
|
|
834
|
+
let url;
|
|
835
|
+
try {
|
|
836
|
+
url = new URL(raw);
|
|
837
|
+
} catch {
|
|
838
|
+
return false;
|
|
839
|
+
}
|
|
840
|
+
if (url.username || url.password) return false;
|
|
841
|
+
if (url.protocol === "https:") return true;
|
|
842
|
+
if (url.protocol === "http:") {
|
|
843
|
+
return url.hostname === "localhost" || url.hostname === "127.0.0.1" || url.hostname === "[::1]";
|
|
844
|
+
}
|
|
845
|
+
return false;
|
|
846
|
+
}
|
|
847
|
+
function boundMetadata(metadata) {
|
|
848
|
+
const bounded = {};
|
|
849
|
+
let count = 0;
|
|
850
|
+
for (const key of Object.keys(metadata)) {
|
|
851
|
+
if (count >= MAX_METADATA_ENTRIES) break;
|
|
852
|
+
const value = metadata[key];
|
|
853
|
+
if (value === void 0 || value === null) continue;
|
|
854
|
+
const str = String(value);
|
|
855
|
+
bounded[key] = str.length > MAX_METADATA_VALUE_CHARS ? `${str.slice(0, MAX_METADATA_VALUE_CHARS)}...[truncated]` : str;
|
|
856
|
+
count++;
|
|
857
|
+
}
|
|
858
|
+
return bounded;
|
|
859
|
+
}
|
|
860
|
+
function isLegacyPendingKey(key) {
|
|
861
|
+
const parts = key.slice(PENDING_BATCH_KEY_PREFIX.length).split("_");
|
|
862
|
+
return parts.length === 2 && /^\d+$/.test(parts[0]);
|
|
863
|
+
}
|
|
864
|
+
function sameEndpointOrigin(a, b) {
|
|
865
|
+
if (!a || !b) return false;
|
|
866
|
+
try {
|
|
867
|
+
return new URL(a).origin === new URL(b).origin;
|
|
868
|
+
} catch {
|
|
869
|
+
return false;
|
|
870
|
+
}
|
|
871
|
+
}
|
|
717
872
|
function extendSession() {
|
|
718
873
|
const now = Date.now();
|
|
719
874
|
inMemorySessionTs = now;
|
|
@@ -830,22 +985,6 @@ var PrebidEventDeduper = class {
|
|
|
830
985
|
return false;
|
|
831
986
|
}
|
|
832
987
|
};
|
|
833
|
-
function parseSize(raw) {
|
|
834
|
-
if (!raw) return { width: 0, height: 0 };
|
|
835
|
-
let cur = raw;
|
|
836
|
-
while (Array.isArray(cur) && cur.length > 0 && Array.isArray(cur[0])) {
|
|
837
|
-
cur = cur[0];
|
|
838
|
-
}
|
|
839
|
-
if (Array.isArray(cur) && cur.length >= 2) {
|
|
840
|
-
const w = Number(cur[0]);
|
|
841
|
-
const h = Number(cur[1]);
|
|
842
|
-
return {
|
|
843
|
-
width: Number.isFinite(w) ? w : 0,
|
|
844
|
-
height: Number.isFinite(h) ? h : 0
|
|
845
|
-
};
|
|
846
|
-
}
|
|
847
|
-
return { width: 0, height: 0 };
|
|
848
|
-
}
|
|
849
988
|
function parseBidDimensions(bid) {
|
|
850
989
|
if (Number.isFinite(bid?.width) && Number.isFinite(bid?.height)) {
|
|
851
990
|
return { width: bid.width, height: bid.height };
|
|
@@ -861,8 +1000,264 @@ function parseBidDimensions(bid) {
|
|
|
861
1000
|
height: Number.isFinite(bid?.height) ? bid.height : 0
|
|
862
1001
|
};
|
|
863
1002
|
}
|
|
1003
|
+
var adsLoaderListenerMap = /* @__PURE__ */ new WeakMap();
|
|
1004
|
+
function hookAdsManagerLoadedEvent(loadedEventCtor) {
|
|
1005
|
+
if (!loadedEventCtor) return;
|
|
1006
|
+
try {
|
|
1007
|
+
const loadedProto = loadedEventCtor.prototype;
|
|
1008
|
+
if (loadedProto && typeof loadedProto.getAdsManager === "function" && !loadedProto.getAdsManager.__bidkernelHooked) {
|
|
1009
|
+
const originalGetAdsManager = loadedProto.getAdsManager;
|
|
1010
|
+
const hookedGetAdsManager = function(...args) {
|
|
1011
|
+
const adsManager = originalGetAdsManager.apply(this, args);
|
|
1012
|
+
if (adsManager) {
|
|
1013
|
+
for (const instance of BidkernelPrebidAnalytics.getActiveInstances()) {
|
|
1014
|
+
try {
|
|
1015
|
+
instance.attachImaAdsManager(adsManager);
|
|
1016
|
+
} catch {
|
|
1017
|
+
}
|
|
1018
|
+
}
|
|
1019
|
+
}
|
|
1020
|
+
return adsManager;
|
|
1021
|
+
};
|
|
1022
|
+
hookedGetAdsManager.__bidkernelHooked = true;
|
|
1023
|
+
loadedProto.getAdsManager = hookedGetAdsManager;
|
|
1024
|
+
}
|
|
1025
|
+
} catch {
|
|
1026
|
+
}
|
|
1027
|
+
}
|
|
1028
|
+
function hookAdsManagerPrototype(adsManagerCtorOrProto) {
|
|
1029
|
+
if (!adsManagerCtorOrProto) return;
|
|
1030
|
+
try {
|
|
1031
|
+
const proto = adsManagerCtorOrProto.prototype || adsManagerCtorOrProto;
|
|
1032
|
+
if (proto && typeof proto.init === "function" && !proto.init.__bidkernelHooked) {
|
|
1033
|
+
const origInit = proto.init;
|
|
1034
|
+
const hookedInit = function(...args) {
|
|
1035
|
+
for (const instance of BidkernelPrebidAnalytics.getActiveInstances()) {
|
|
1036
|
+
try {
|
|
1037
|
+
instance.attachImaAdsManager(this);
|
|
1038
|
+
} catch {
|
|
1039
|
+
}
|
|
1040
|
+
}
|
|
1041
|
+
return origInit.apply(this, args);
|
|
1042
|
+
};
|
|
1043
|
+
hookedInit.__bidkernelHooked = true;
|
|
1044
|
+
proto.init = hookedInit;
|
|
1045
|
+
}
|
|
1046
|
+
if (proto && typeof proto.start === "function" && !proto.start.__bidkernelHooked) {
|
|
1047
|
+
const origStart = proto.start;
|
|
1048
|
+
const hookedStart = function(...args) {
|
|
1049
|
+
for (const instance of BidkernelPrebidAnalytics.getActiveInstances()) {
|
|
1050
|
+
try {
|
|
1051
|
+
instance.attachImaAdsManager(this);
|
|
1052
|
+
} catch {
|
|
1053
|
+
}
|
|
1054
|
+
}
|
|
1055
|
+
return origStart.apply(this, args);
|
|
1056
|
+
};
|
|
1057
|
+
hookedStart.__bidkernelHooked = true;
|
|
1058
|
+
proto.start = hookedStart;
|
|
1059
|
+
}
|
|
1060
|
+
} catch {
|
|
1061
|
+
}
|
|
1062
|
+
}
|
|
1063
|
+
function hookAdsLoader(adsLoaderCtor) {
|
|
1064
|
+
if (!adsLoaderCtor) return;
|
|
1065
|
+
try {
|
|
1066
|
+
const proto = adsLoaderCtor.prototype;
|
|
1067
|
+
if (!proto) return;
|
|
1068
|
+
if (typeof proto.addEventListener === "function" && !proto.addEventListener.__bidkernelHooked) {
|
|
1069
|
+
const origAddEventListener = proto.addEventListener;
|
|
1070
|
+
const hookedAddEventListener = function(type, listener, ...rest) {
|
|
1071
|
+
if ((type === "adsManagerLoaded" || type === (this?.AdsManagerLoadedEvent?.Type?.ADS_MANAGER_LOADED || "adsManagerLoaded")) && typeof listener === "function") {
|
|
1072
|
+
let wrappedListener = adsLoaderListenerMap.get(listener);
|
|
1073
|
+
if (!wrappedListener) {
|
|
1074
|
+
wrappedListener = function(event) {
|
|
1075
|
+
if (event && typeof event.getAdsManager === "function" && !event.getAdsManager.__bidkernelHooked) {
|
|
1076
|
+
const origGetAdsManager = event.getAdsManager;
|
|
1077
|
+
event.getAdsManager = function(...args) {
|
|
1078
|
+
const adsManager = origGetAdsManager.apply(this, args);
|
|
1079
|
+
if (adsManager) {
|
|
1080
|
+
for (const sdk of BidkernelPrebidAnalytics.getActiveInstances()) {
|
|
1081
|
+
try {
|
|
1082
|
+
sdk.attachImaAdsManager(adsManager);
|
|
1083
|
+
} catch {
|
|
1084
|
+
}
|
|
1085
|
+
}
|
|
1086
|
+
}
|
|
1087
|
+
return adsManager;
|
|
1088
|
+
};
|
|
1089
|
+
event.getAdsManager.__bidkernelHooked = true;
|
|
1090
|
+
}
|
|
1091
|
+
return listener.apply(this, arguments);
|
|
1092
|
+
};
|
|
1093
|
+
adsLoaderListenerMap.set(listener, wrappedListener);
|
|
1094
|
+
}
|
|
1095
|
+
return origAddEventListener.call(this, type, wrappedListener, ...rest);
|
|
1096
|
+
}
|
|
1097
|
+
return origAddEventListener.call(this, type, listener, ...rest);
|
|
1098
|
+
};
|
|
1099
|
+
hookedAddEventListener.__bidkernelHooked = true;
|
|
1100
|
+
proto.addEventListener = hookedAddEventListener;
|
|
1101
|
+
}
|
|
1102
|
+
if (typeof proto.removeEventListener === "function" && !proto.removeEventListener.__bidkernelHooked) {
|
|
1103
|
+
const origRemoveEventListener = proto.removeEventListener;
|
|
1104
|
+
const hookedRemoveEventListener = function(type, listener, ...rest) {
|
|
1105
|
+
const wrapped = typeof listener === "function" ? adsLoaderListenerMap.get(listener) : void 0;
|
|
1106
|
+
return origRemoveEventListener.call(this, type, wrapped || listener, ...rest);
|
|
1107
|
+
};
|
|
1108
|
+
hookedRemoveEventListener.__bidkernelHooked = true;
|
|
1109
|
+
proto.removeEventListener = hookedRemoveEventListener;
|
|
1110
|
+
}
|
|
1111
|
+
} catch {
|
|
1112
|
+
}
|
|
1113
|
+
}
|
|
1114
|
+
function hookImaPrototype(ima) {
|
|
1115
|
+
if (!ima || typeof ima !== "object") return;
|
|
1116
|
+
try {
|
|
1117
|
+
if (ima.AdsManagerLoadedEvent) {
|
|
1118
|
+
hookAdsManagerLoadedEvent(ima.AdsManagerLoadedEvent);
|
|
1119
|
+
}
|
|
1120
|
+
const loadedDesc = Object.getOwnPropertyDescriptor(ima, "AdsManagerLoadedEvent");
|
|
1121
|
+
if (!loadedDesc || loadedDesc.configurable) {
|
|
1122
|
+
let _loadedEvent = ima.AdsManagerLoadedEvent;
|
|
1123
|
+
try {
|
|
1124
|
+
Object.defineProperty(ima, "AdsManagerLoadedEvent", {
|
|
1125
|
+
configurable: true,
|
|
1126
|
+
enumerable: true,
|
|
1127
|
+
get() {
|
|
1128
|
+
return _loadedEvent;
|
|
1129
|
+
},
|
|
1130
|
+
set(val) {
|
|
1131
|
+
_loadedEvent = val;
|
|
1132
|
+
hookAdsManagerLoadedEvent(val);
|
|
1133
|
+
}
|
|
1134
|
+
});
|
|
1135
|
+
} catch {
|
|
1136
|
+
}
|
|
1137
|
+
}
|
|
1138
|
+
if (ima.AdsLoader) {
|
|
1139
|
+
hookAdsLoader(ima.AdsLoader);
|
|
1140
|
+
}
|
|
1141
|
+
const loaderDesc = Object.getOwnPropertyDescriptor(ima, "AdsLoader");
|
|
1142
|
+
if (!loaderDesc || loaderDesc.configurable) {
|
|
1143
|
+
let _loader = ima.AdsLoader;
|
|
1144
|
+
try {
|
|
1145
|
+
Object.defineProperty(ima, "AdsLoader", {
|
|
1146
|
+
configurable: true,
|
|
1147
|
+
enumerable: true,
|
|
1148
|
+
get() {
|
|
1149
|
+
return _loader;
|
|
1150
|
+
},
|
|
1151
|
+
set(val) {
|
|
1152
|
+
_loader = val;
|
|
1153
|
+
hookAdsLoader(val);
|
|
1154
|
+
}
|
|
1155
|
+
});
|
|
1156
|
+
} catch {
|
|
1157
|
+
}
|
|
1158
|
+
}
|
|
1159
|
+
if (ima.AdsManager) {
|
|
1160
|
+
hookAdsManagerPrototype(ima.AdsManager);
|
|
1161
|
+
}
|
|
1162
|
+
const mgrDesc = Object.getOwnPropertyDescriptor(ima, "AdsManager");
|
|
1163
|
+
if (!mgrDesc || mgrDesc.configurable) {
|
|
1164
|
+
let _mgr = ima.AdsManager;
|
|
1165
|
+
try {
|
|
1166
|
+
Object.defineProperty(ima, "AdsManager", {
|
|
1167
|
+
configurable: true,
|
|
1168
|
+
enumerable: true,
|
|
1169
|
+
get() {
|
|
1170
|
+
return _mgr;
|
|
1171
|
+
},
|
|
1172
|
+
set(val) {
|
|
1173
|
+
_mgr = val;
|
|
1174
|
+
hookAdsManagerPrototype(val);
|
|
1175
|
+
}
|
|
1176
|
+
});
|
|
1177
|
+
} catch {
|
|
1178
|
+
}
|
|
1179
|
+
}
|
|
1180
|
+
} catch {
|
|
1181
|
+
}
|
|
1182
|
+
}
|
|
1183
|
+
function initImaInterception() {
|
|
1184
|
+
if (typeof window === "undefined") return;
|
|
1185
|
+
const win = window;
|
|
1186
|
+
if (win.google?.ima) {
|
|
1187
|
+
hookImaPrototype(win.google.ima);
|
|
1188
|
+
}
|
|
1189
|
+
if (win.google && typeof win.google === "object") {
|
|
1190
|
+
const imaDesc = Object.getOwnPropertyDescriptor(win.google, "ima");
|
|
1191
|
+
if (!imaDesc || imaDesc.configurable) {
|
|
1192
|
+
let _ima = win.google.ima;
|
|
1193
|
+
try {
|
|
1194
|
+
Object.defineProperty(win.google, "ima", {
|
|
1195
|
+
configurable: true,
|
|
1196
|
+
enumerable: true,
|
|
1197
|
+
get() {
|
|
1198
|
+
return _ima;
|
|
1199
|
+
},
|
|
1200
|
+
set(val) {
|
|
1201
|
+
_ima = val;
|
|
1202
|
+
hookImaPrototype(val);
|
|
1203
|
+
}
|
|
1204
|
+
});
|
|
1205
|
+
} catch {
|
|
1206
|
+
}
|
|
1207
|
+
}
|
|
1208
|
+
}
|
|
1209
|
+
const googleDesc = Object.getOwnPropertyDescriptor(win, "google");
|
|
1210
|
+
if (!googleDesc || googleDesc.configurable) {
|
|
1211
|
+
let _google = win.google;
|
|
1212
|
+
try {
|
|
1213
|
+
Object.defineProperty(win, "google", {
|
|
1214
|
+
configurable: true,
|
|
1215
|
+
enumerable: true,
|
|
1216
|
+
get() {
|
|
1217
|
+
return _google;
|
|
1218
|
+
},
|
|
1219
|
+
set(val) {
|
|
1220
|
+
_google = val;
|
|
1221
|
+
if (_google && typeof _google === "object") {
|
|
1222
|
+
if (_google.ima) {
|
|
1223
|
+
hookImaPrototype(_google.ima);
|
|
1224
|
+
}
|
|
1225
|
+
const iDesc = Object.getOwnPropertyDescriptor(_google, "ima");
|
|
1226
|
+
if (!iDesc || iDesc.configurable) {
|
|
1227
|
+
let _i = _google.ima;
|
|
1228
|
+
try {
|
|
1229
|
+
Object.defineProperty(_google, "ima", {
|
|
1230
|
+
configurable: true,
|
|
1231
|
+
enumerable: true,
|
|
1232
|
+
get() {
|
|
1233
|
+
return _i;
|
|
1234
|
+
},
|
|
1235
|
+
set(iv) {
|
|
1236
|
+
_i = iv;
|
|
1237
|
+
hookImaPrototype(iv);
|
|
1238
|
+
}
|
|
1239
|
+
});
|
|
1240
|
+
} catch {
|
|
1241
|
+
}
|
|
1242
|
+
}
|
|
1243
|
+
}
|
|
1244
|
+
}
|
|
1245
|
+
});
|
|
1246
|
+
} catch {
|
|
1247
|
+
}
|
|
1248
|
+
}
|
|
1249
|
+
}
|
|
1250
|
+
if (typeof window !== "undefined") {
|
|
1251
|
+
initImaInterception();
|
|
1252
|
+
}
|
|
864
1253
|
var BidkernelPrebidAnalytics = class _BidkernelPrebidAnalytics {
|
|
865
1254
|
static activeInstances = /* @__PURE__ */ new Set();
|
|
1255
|
+
static getActiveInstances() {
|
|
1256
|
+
return _BidkernelPrebidAnalytics.activeInstances;
|
|
1257
|
+
}
|
|
1258
|
+
static initImaInterception() {
|
|
1259
|
+
initImaInterception();
|
|
1260
|
+
}
|
|
866
1261
|
config;
|
|
867
1262
|
queue = [];
|
|
868
1263
|
errorCount = 0;
|
|
@@ -897,9 +1292,13 @@ var BidkernelPrebidAnalytics = class _BidkernelPrebidAnalytics {
|
|
|
897
1292
|
cachedWinningBids = /* @__PURE__ */ new Map();
|
|
898
1293
|
// Active video player attachment cleanup routines
|
|
899
1294
|
videoDetachCleanups = /* @__PURE__ */ new Set();
|
|
1295
|
+
// Compacted bidder participation map per auction: auctionId -> Map<`${bidder}:${adUnitCode}`, BidderOutcomeEntry>
|
|
1296
|
+
auctionBidderOutcomes = /* @__PURE__ */ new Map();
|
|
900
1297
|
constructor(config) {
|
|
1298
|
+
const requestedEndpoint = config.endpoint || "";
|
|
1299
|
+
const endpoint = !requestedEndpoint || isTrustedEndpoint(requestedEndpoint) ? requestedEndpoint : "";
|
|
901
1300
|
this.config = {
|
|
902
|
-
endpoint
|
|
1301
|
+
endpoint,
|
|
903
1302
|
propertyId: config.propertyId || "",
|
|
904
1303
|
pageviewId: config.pageviewId || generateUUID(),
|
|
905
1304
|
sessionId: config.sessionId || getOrCreateSessionId(),
|
|
@@ -915,6 +1314,12 @@ var BidkernelPrebidAnalytics = class _BidkernelPrebidAnalytics {
|
|
|
915
1314
|
pbjsGlobalName: config.pbjsGlobalName || "pbjs",
|
|
916
1315
|
attachPbjsListeners: config.attachPbjsListeners ?? true
|
|
917
1316
|
};
|
|
1317
|
+
if (requestedEndpoint && !endpoint) {
|
|
1318
|
+
this.log(
|
|
1319
|
+
"ERROR",
|
|
1320
|
+
`Rejected untrusted analytics endpoint ${requestedEndpoint}: must be an absolute https:// URL without embedded credentials. Events will not be transmitted.`
|
|
1321
|
+
);
|
|
1322
|
+
}
|
|
918
1323
|
this.boundFlushBeacon = () => {
|
|
919
1324
|
this.flushAllSlotsTimeInView();
|
|
920
1325
|
this.flushBeacon();
|
|
@@ -1016,6 +1421,10 @@ var BidkernelPrebidAnalytics = class _BidkernelPrebidAnalytics {
|
|
|
1016
1421
|
}
|
|
1017
1422
|
this.flushTimer = setInterval(() => this.flush(), FLUSH_INTERVAL_MS);
|
|
1018
1423
|
this.resendPersistedBatches();
|
|
1424
|
+
initImaInterception();
|
|
1425
|
+
if (window.google?.ima) {
|
|
1426
|
+
hookImaPrototype(window.google.ima);
|
|
1427
|
+
}
|
|
1019
1428
|
}
|
|
1020
1429
|
}
|
|
1021
1430
|
disable() {
|
|
@@ -1052,6 +1461,7 @@ var BidkernelPrebidAnalytics = class _BidkernelPrebidAnalytics {
|
|
|
1052
1461
|
this.cachedWinningBids.clear();
|
|
1053
1462
|
this.slotEmittedImpressionKeys.clear();
|
|
1054
1463
|
this.slotLastAuctionIds.clear();
|
|
1464
|
+
this.auctionBidderOutcomes.clear();
|
|
1055
1465
|
if (this.flushTimer) {
|
|
1056
1466
|
clearInterval(this.flushTimer);
|
|
1057
1467
|
this.flushTimer = null;
|
|
@@ -1455,7 +1865,139 @@ var BidkernelPrebidAnalytics = class _BidkernelPrebidAnalytics {
|
|
|
1455
1865
|
this.slotEmittedImpressionKeys.delete(key);
|
|
1456
1866
|
}
|
|
1457
1867
|
}
|
|
1458
|
-
this.cachedWinningBids.
|
|
1868
|
+
const cached = this.cachedWinningBids.get(slotId);
|
|
1869
|
+
if (cached) this.deleteCachedBidEntry(cached);
|
|
1870
|
+
}
|
|
1871
|
+
// --- Bounded caches -------------------------------------------------------
|
|
1872
|
+
/**
|
|
1873
|
+
* Reads a cached winning bid, treating an entry past CACHED_BID_TTL_MS as
|
|
1874
|
+
* absent and dropping it. Every read goes through here so a stale bid can
|
|
1875
|
+
* never be married to a much later render.
|
|
1876
|
+
*/
|
|
1877
|
+
getCachedBid(key) {
|
|
1878
|
+
const entry = this.cachedWinningBids.get(key);
|
|
1879
|
+
if (!entry) return void 0;
|
|
1880
|
+
if (Date.now() - entry.timestamp > CACHED_BID_TTL_MS) {
|
|
1881
|
+
this.deleteCachedBidEntry(entry);
|
|
1882
|
+
return void 0;
|
|
1883
|
+
}
|
|
1884
|
+
return entry;
|
|
1885
|
+
}
|
|
1886
|
+
/** Removes every alias pointing at one entry. Aliases are stored by identity. */
|
|
1887
|
+
deleteCachedBidEntry(entry) {
|
|
1888
|
+
for (const [key, value] of Array.from(this.cachedWinningBids)) {
|
|
1889
|
+
if (value === entry) this.cachedWinningBids.delete(key);
|
|
1890
|
+
}
|
|
1891
|
+
}
|
|
1892
|
+
/**
|
|
1893
|
+
* Drops expired entries, then evicts oldest-first until the key cap holds.
|
|
1894
|
+
* Map iterates in insertion order and one win's aliases are written
|
|
1895
|
+
* consecutively, so eviction takes a whole bid's aliases together.
|
|
1896
|
+
*/
|
|
1897
|
+
pruneCachedWinningBids() {
|
|
1898
|
+
const now = Date.now();
|
|
1899
|
+
for (const [key, entry] of Array.from(this.cachedWinningBids)) {
|
|
1900
|
+
if (now - entry.timestamp > CACHED_BID_TTL_MS) this.cachedWinningBids.delete(key);
|
|
1901
|
+
}
|
|
1902
|
+
while (this.cachedWinningBids.size > MAX_CACHED_BID_KEYS) {
|
|
1903
|
+
const oldest = this.cachedWinningBids.keys().next();
|
|
1904
|
+
if (oldest.done) break;
|
|
1905
|
+
this.cachedWinningBids.delete(oldest.value);
|
|
1906
|
+
}
|
|
1907
|
+
}
|
|
1908
|
+
/**
|
|
1909
|
+
* Searches cached winning bids for an entry matching the given filters (creativeId,
|
|
1910
|
+
* adId, or mediaType), falling back to the most recent winning video bid.
|
|
1911
|
+
*/
|
|
1912
|
+
findCachedWinningBid(filter) {
|
|
1913
|
+
const now = Date.now();
|
|
1914
|
+
const isConsumed = (entry) => {
|
|
1915
|
+
return this.hasImpressionEmitted(
|
|
1916
|
+
entry.adUnitCode,
|
|
1917
|
+
void 0,
|
|
1918
|
+
entry.auctionId,
|
|
1919
|
+
entry.bidTrace.creativeId
|
|
1920
|
+
);
|
|
1921
|
+
};
|
|
1922
|
+
if (filter?.creativeId || filter?.adId) {
|
|
1923
|
+
for (const entry of Array.from(this.cachedWinningBids.values())) {
|
|
1924
|
+
if (now - entry.timestamp > CACHED_BID_TTL_MS) continue;
|
|
1925
|
+
if (filter.creativeId && (entry.bidTrace.creativeId === filter.creativeId || entry.rawBid?.creativeId === filter.creativeId) || filter.adId && (entry.rawBid?.adId === filter.adId || entry.adUnitCode === filter.adId)) {
|
|
1926
|
+
return entry;
|
|
1927
|
+
}
|
|
1928
|
+
}
|
|
1929
|
+
}
|
|
1930
|
+
let bestUnconsumedMatch;
|
|
1931
|
+
if (filter?.mediaType) {
|
|
1932
|
+
for (const entry of Array.from(this.cachedWinningBids.values())) {
|
|
1933
|
+
if (now - entry.timestamp > CACHED_BID_TTL_MS) continue;
|
|
1934
|
+
const isEntryVideo = entry.bidTrace.mediaType === filter.mediaType || entry.rawBid?.mediaType === filter.mediaType || filter.mediaType === "video" && entry.rawBid?.mediaTypes?.video !== void 0;
|
|
1935
|
+
if (isEntryVideo) {
|
|
1936
|
+
if (!isConsumed(entry)) {
|
|
1937
|
+
if (!bestUnconsumedMatch || entry.timestamp < bestUnconsumedMatch.timestamp) {
|
|
1938
|
+
bestUnconsumedMatch = entry;
|
|
1939
|
+
}
|
|
1940
|
+
}
|
|
1941
|
+
}
|
|
1942
|
+
}
|
|
1943
|
+
if (bestUnconsumedMatch) return bestUnconsumedMatch;
|
|
1944
|
+
let bestFallbackMatch;
|
|
1945
|
+
for (const entry of Array.from(this.cachedWinningBids.values())) {
|
|
1946
|
+
if (now - entry.timestamp > CACHED_BID_TTL_MS) continue;
|
|
1947
|
+
const isEntryVideo = entry.bidTrace.mediaType === filter.mediaType || entry.rawBid?.mediaType === filter.mediaType || filter.mediaType === "video" && entry.rawBid?.mediaTypes?.video !== void 0;
|
|
1948
|
+
if (isEntryVideo) {
|
|
1949
|
+
if (!bestFallbackMatch || entry.timestamp > bestFallbackMatch.timestamp) {
|
|
1950
|
+
bestFallbackMatch = entry;
|
|
1951
|
+
}
|
|
1952
|
+
}
|
|
1953
|
+
}
|
|
1954
|
+
if (bestFallbackMatch) return bestFallbackMatch;
|
|
1955
|
+
}
|
|
1956
|
+
for (const entry of Array.from(this.cachedWinningBids.values())) {
|
|
1957
|
+
if (now - entry.timestamp > CACHED_BID_TTL_MS) continue;
|
|
1958
|
+
if (!isConsumed(entry)) {
|
|
1959
|
+
if (!bestUnconsumedMatch || entry.timestamp > bestUnconsumedMatch.timestamp) {
|
|
1960
|
+
bestUnconsumedMatch = entry;
|
|
1961
|
+
}
|
|
1962
|
+
}
|
|
1963
|
+
}
|
|
1964
|
+
if (bestUnconsumedMatch) return bestUnconsumedMatch;
|
|
1965
|
+
let bestRecent;
|
|
1966
|
+
for (const entry of Array.from(this.cachedWinningBids.values())) {
|
|
1967
|
+
if (now - entry.timestamp > CACHED_BID_TTL_MS) continue;
|
|
1968
|
+
if (!bestRecent || entry.timestamp > bestRecent.timestamp) {
|
|
1969
|
+
bestRecent = entry;
|
|
1970
|
+
}
|
|
1971
|
+
}
|
|
1972
|
+
return bestRecent;
|
|
1973
|
+
}
|
|
1974
|
+
/** Records a dedup key, evicting oldest-first at the cap. */
|
|
1975
|
+
addImpressionKey(key) {
|
|
1976
|
+
if (this.slotEmittedImpressionKeys.has(key)) return;
|
|
1977
|
+
while (this.slotEmittedImpressionKeys.size >= MAX_IMPRESSION_KEYS) {
|
|
1978
|
+
const oldest = this.slotEmittedImpressionKeys.values().next();
|
|
1979
|
+
if (oldest.done) break;
|
|
1980
|
+
this.slotEmittedImpressionKeys.delete(oldest.value);
|
|
1981
|
+
}
|
|
1982
|
+
this.slotEmittedImpressionKeys.add(key);
|
|
1983
|
+
}
|
|
1984
|
+
/**
|
|
1985
|
+
* The bidder-outcome map for an auction, creating it if absent. Evicts the
|
|
1986
|
+
* oldest auction at the cap: without this, any auction whose auctionEnd never
|
|
1987
|
+
* fires (abandoned, navigated away from mid-flight) leaks its map forever.
|
|
1988
|
+
*/
|
|
1989
|
+
getOrCreateAuctionOutcomes(auctionId) {
|
|
1990
|
+
let auctionMap = this.auctionBidderOutcomes.get(auctionId);
|
|
1991
|
+
if (!auctionMap) {
|
|
1992
|
+
auctionMap = /* @__PURE__ */ new Map();
|
|
1993
|
+
this.auctionBidderOutcomes.set(auctionId, auctionMap);
|
|
1994
|
+
}
|
|
1995
|
+
while (this.auctionBidderOutcomes.size > MAX_TRACKED_AUCTIONS) {
|
|
1996
|
+
const oldest = this.auctionBidderOutcomes.keys().next();
|
|
1997
|
+
if (oldest.done || oldest.value === auctionId) break;
|
|
1998
|
+
this.auctionBidderOutcomes.delete(oldest.value);
|
|
1999
|
+
}
|
|
2000
|
+
return auctionMap;
|
|
1459
2001
|
}
|
|
1460
2002
|
hasImpressionEmitted(slotId, refreshIndex, auctionId, creativeId) {
|
|
1461
2003
|
const rIndex = refreshIndex ?? this.slotRefreshIndices.get(slotId) ?? 0;
|
|
@@ -1475,14 +2017,14 @@ var BidkernelPrebidAnalytics = class _BidkernelPrebidAnalytics {
|
|
|
1475
2017
|
}
|
|
1476
2018
|
markImpressionEmitted(slotId, refreshIndex, auctionId, creativeId) {
|
|
1477
2019
|
const baseSlotKey = `${escapeKeyPart(slotId)}:${refreshIndex}`;
|
|
1478
|
-
this.
|
|
2020
|
+
this.addImpressionKey(baseSlotKey);
|
|
1479
2021
|
if (creativeId) {
|
|
1480
|
-
this.
|
|
2022
|
+
this.addImpressionKey(`${baseSlotKey}:${escapeKeyPart(creativeId)}`);
|
|
1481
2023
|
}
|
|
1482
2024
|
if (auctionId) {
|
|
1483
|
-
this.
|
|
2025
|
+
this.addImpressionKey(`${baseSlotKey}:auc:${escapeKeyPart(auctionId)}`);
|
|
1484
2026
|
if (creativeId) {
|
|
1485
|
-
this.
|
|
2027
|
+
this.addImpressionKey(
|
|
1486
2028
|
`${baseSlotKey}:auc:${escapeKeyPart(auctionId)}:${escapeKeyPart(creativeId)}`
|
|
1487
2029
|
);
|
|
1488
2030
|
}
|
|
@@ -1492,7 +2034,7 @@ var BidkernelPrebidAnalytics = class _BidkernelPrebidAnalytics {
|
|
|
1492
2034
|
if (!this.isEnabled) return false;
|
|
1493
2035
|
const resolvedSlotId = slotId || options?.adUnitCode || "";
|
|
1494
2036
|
const adUnitCode = options?.adUnitCode || resolvedSlotId;
|
|
1495
|
-
const cached = (options?.auctionId && resolvedSlotId ? this.
|
|
2037
|
+
const cached = (options?.auctionId && resolvedSlotId ? this.getCachedBid(`${options.auctionId}:${resolvedSlotId}`) : void 0) || (options?.auctionId && adUnitCode ? this.getCachedBid(`${options.auctionId}:${adUnitCode}`) : void 0) || (resolvedSlotId ? this.getCachedBid(resolvedSlotId) : void 0) || (adUnitCode ? this.getCachedBid(adUnitCode) : void 0);
|
|
1496
2038
|
const rawBid = options?.bid || cached?.rawBid || {};
|
|
1497
2039
|
const auctionId = options?.auctionId || rawBid.auctionId || cached?.auctionId || "";
|
|
1498
2040
|
const transactionId = options?.transactionId || rawBid.transactionId || cached?.transactionId || "";
|
|
@@ -1588,14 +2130,40 @@ var BidkernelPrebidAnalytics = class _BidkernelPrebidAnalytics {
|
|
|
1588
2130
|
return () => {
|
|
1589
2131
|
};
|
|
1590
2132
|
}
|
|
2133
|
+
if (!adsManager.__bidkernelAttachedInstances) {
|
|
2134
|
+
try {
|
|
2135
|
+
Object.defineProperty(adsManager, "__bidkernelAttachedInstances", {
|
|
2136
|
+
value: /* @__PURE__ */ new Set(),
|
|
2137
|
+
configurable: true,
|
|
2138
|
+
writable: true
|
|
2139
|
+
});
|
|
2140
|
+
} catch {
|
|
2141
|
+
adsManager.__bidkernelAttachedInstances = /* @__PURE__ */ new Set();
|
|
2142
|
+
}
|
|
2143
|
+
}
|
|
2144
|
+
if (adsManager.__bidkernelAttachedInstances.has(this)) {
|
|
2145
|
+
return () => {
|
|
2146
|
+
};
|
|
2147
|
+
}
|
|
2148
|
+
adsManager.__bidkernelAttachedInstances.add(this);
|
|
1591
2149
|
const slotId = options?.slotId || options?.adUnitCode || "video";
|
|
1592
2150
|
const adUnitCode = options?.adUnitCode || slotId;
|
|
1593
2151
|
const auctionId = options?.auctionId || "";
|
|
1594
2152
|
const transactionId = options?.transactionId || "";
|
|
1595
|
-
const getWinningBid = () => {
|
|
1596
|
-
|
|
2153
|
+
const getWinningBid = (adData) => {
|
|
2154
|
+
let cached = (auctionId ? this.getCachedBid(`${auctionId}:${adUnitCode}`) : void 0) || (auctionId && slotId !== adUnitCode ? this.getCachedBid(`${auctionId}:${slotId}`) : void 0) || (adUnitCode !== "video" ? this.getCachedBid(adUnitCode) : void 0) || (slotId !== adUnitCode && slotId !== "video" ? this.getCachedBid(slotId) : void 0);
|
|
2155
|
+
if (!cached) {
|
|
2156
|
+
cached = this.findCachedWinningBid({
|
|
2157
|
+
creativeId: adData?.creativeId,
|
|
2158
|
+
adId: adData?.adId,
|
|
2159
|
+
mediaType: "video"
|
|
2160
|
+
});
|
|
2161
|
+
}
|
|
2162
|
+
return cached;
|
|
1597
2163
|
};
|
|
2164
|
+
let adStarted = false;
|
|
1598
2165
|
const onAdStartedOrImpression = (event) => {
|
|
2166
|
+
adStarted = true;
|
|
1599
2167
|
this.log("DEBUG", "IMA AdEvent.STARTED / IMPRESSION received", event);
|
|
1600
2168
|
const ad = typeof event?.getAd === "function" ? event.getAd() : event?.ad;
|
|
1601
2169
|
const adData = {};
|
|
@@ -1606,16 +2174,20 @@ var BidkernelPrebidAnalytics = class _BidkernelPrebidAnalytics {
|
|
|
1606
2174
|
adData.duration = typeof ad.getDuration === "function" ? ad.getDuration() : ad.duration;
|
|
1607
2175
|
adData.advertiserName = typeof ad.getAdvertiserName === "function" ? ad.getAdvertiserName() : "";
|
|
1608
2176
|
}
|
|
1609
|
-
const cached = getWinningBid();
|
|
2177
|
+
const cached = getWinningBid(adData);
|
|
2178
|
+
const resolvedSlotId = options?.slotId && options.slotId !== "video" ? options.slotId : options?.adUnitCode && options.adUnitCode !== "video" ? options.adUnitCode : cached?.adUnitCode || options?.slotId || options?.adUnitCode || "video";
|
|
2179
|
+
const resolvedAdUnitCode = options?.adUnitCode && options.adUnitCode !== "video" ? options.adUnitCode : cached?.adUnitCode || resolvedSlotId;
|
|
2180
|
+
const resolvedAuctionId = auctionId || cached?.auctionId || "";
|
|
2181
|
+
const resolvedTransactionId = transactionId || cached?.transactionId || "";
|
|
1610
2182
|
const mergedBid = {
|
|
1611
2183
|
...cached?.rawBid || options?.bid,
|
|
1612
2184
|
mediaType: "video",
|
|
1613
2185
|
creativeId: adData.creativeId || cached?.bidTrace?.creativeId || options?.bid?.creativeId || ""
|
|
1614
2186
|
};
|
|
1615
|
-
const emitted = this.recordImpression(
|
|
1616
|
-
adUnitCode,
|
|
1617
|
-
auctionId:
|
|
1618
|
-
transactionId:
|
|
2187
|
+
const emitted = this.recordImpression(resolvedSlotId, {
|
|
2188
|
+
adUnitCode: resolvedAdUnitCode,
|
|
2189
|
+
auctionId: resolvedAuctionId,
|
|
2190
|
+
transactionId: resolvedTransactionId,
|
|
1619
2191
|
mediaType: "video",
|
|
1620
2192
|
bid: mergedBid,
|
|
1621
2193
|
metadata: {
|
|
@@ -1627,7 +2199,7 @@ var BidkernelPrebidAnalytics = class _BidkernelPrebidAnalytics {
|
|
|
1627
2199
|
});
|
|
1628
2200
|
if (emitted && options?.onImpression) {
|
|
1629
2201
|
try {
|
|
1630
|
-
options.onImpression(
|
|
2202
|
+
options.onImpression(resolvedSlotId, { ad, bid: mergedBid });
|
|
1631
2203
|
} catch (e) {
|
|
1632
2204
|
this.log("ERROR", "Error in onImpression callback", e);
|
|
1633
2205
|
}
|
|
@@ -1646,10 +2218,11 @@ var BidkernelPrebidAnalytics = class _BidkernelPrebidAnalytics {
|
|
|
1646
2218
|
const onAdClick = (event) => {
|
|
1647
2219
|
this.log("DEBUG", "IMA AdEvent.CLICK received", event);
|
|
1648
2220
|
const cached = getWinningBid();
|
|
2221
|
+
const resolvedAdUnitCode = options?.adUnitCode && options.adUnitCode !== "video" ? options.adUnitCode : cached?.adUnitCode || slotId;
|
|
1649
2222
|
this.enqueue(TraceEventType.CLICK, "click", {
|
|
1650
2223
|
auctionId: auctionId || cached?.auctionId,
|
|
1651
2224
|
transactionId: transactionId || cached?.transactionId,
|
|
1652
|
-
adUnitCode,
|
|
2225
|
+
adUnitCode: resolvedAdUnitCode,
|
|
1653
2226
|
bid: cached?.bidTrace || options?.bid,
|
|
1654
2227
|
metadata: {
|
|
1655
2228
|
...options?.metadata,
|
|
@@ -1663,14 +2236,16 @@ var BidkernelPrebidAnalytics = class _BidkernelPrebidAnalytics {
|
|
|
1663
2236
|
const msg = (err && typeof err.getMessage === "function" ? err.getMessage() : err?.message) || String(err || "IMA ad error");
|
|
1664
2237
|
const code = (err && typeof err.getErrorCode === "function" ? err.getErrorCode() : err?.code) || "";
|
|
1665
2238
|
const cached = getWinningBid();
|
|
2239
|
+
const resolvedAdUnitCode = options?.adUnitCode && options.adUnitCode !== "video" ? options.adUnitCode : cached?.adUnitCode || slotId;
|
|
1666
2240
|
this.enqueue(TraceEventType.AD_RENDER_FAILED, "adRenderFailed", {
|
|
1667
2241
|
auctionId: auctionId || cached?.auctionId,
|
|
1668
2242
|
transactionId: transactionId || cached?.transactionId,
|
|
1669
|
-
adUnitCode,
|
|
2243
|
+
adUnitCode: resolvedAdUnitCode,
|
|
1670
2244
|
bid: cached?.bidTrace || options?.bid,
|
|
1671
2245
|
metadata: {
|
|
1672
2246
|
...options?.metadata,
|
|
1673
|
-
reason: "ima_ad_error",
|
|
2247
|
+
reason: adStarted ? "ima_playback_error" : "ima_ad_error",
|
|
2248
|
+
playback_phase: adStarted ? "post_start" : "pre_start",
|
|
1674
2249
|
message: msg,
|
|
1675
2250
|
...code ? { ima_error_code: String(code) } : {}
|
|
1676
2251
|
},
|
|
@@ -1687,7 +2262,7 @@ var BidkernelPrebidAnalytics = class _BidkernelPrebidAnalytics {
|
|
|
1687
2262
|
const googleIma = typeof window !== "undefined" ? window.google?.ima : void 0;
|
|
1688
2263
|
const adEventType = googleIma?.AdEvent?.Type || {};
|
|
1689
2264
|
const adErrorEventType = googleIma?.AdErrorEvent?.Type || {};
|
|
1690
|
-
const
|
|
2265
|
+
const rawListeners = [
|
|
1691
2266
|
{ type: adEventType.STARTED || "started", handler: onAdStartedOrImpression },
|
|
1692
2267
|
{ type: adEventType.IMPRESSION || "impression", handler: onAdStartedOrImpression },
|
|
1693
2268
|
{
|
|
@@ -1703,6 +2278,14 @@ var BidkernelPrebidAnalytics = class _BidkernelPrebidAnalytics {
|
|
|
1703
2278
|
{ type: adEventType.CLICK || "click", handler: onAdClick },
|
|
1704
2279
|
{ type: adErrorEventType.AD_ERROR || "adError", handler: onAdError }
|
|
1705
2280
|
];
|
|
2281
|
+
const seenListenerTypes = /* @__PURE__ */ new Set();
|
|
2282
|
+
const listeners = [];
|
|
2283
|
+
for (const l of rawListeners) {
|
|
2284
|
+
if (!seenListenerTypes.has(l.type)) {
|
|
2285
|
+
seenListenerTypes.add(l.type);
|
|
2286
|
+
listeners.push(l);
|
|
2287
|
+
}
|
|
2288
|
+
}
|
|
1706
2289
|
for (const { type, handler } of listeners) {
|
|
1707
2290
|
try {
|
|
1708
2291
|
adsManager.addEventListener(type, handler);
|
|
@@ -1710,6 +2293,7 @@ var BidkernelPrebidAnalytics = class _BidkernelPrebidAnalytics {
|
|
|
1710
2293
|
}
|
|
1711
2294
|
}
|
|
1712
2295
|
const cleanup = () => {
|
|
2296
|
+
adsManager.__bidkernelAttachedInstances?.delete(this);
|
|
1713
2297
|
for (const { type, handler } of listeners) {
|
|
1714
2298
|
try {
|
|
1715
2299
|
adsManager.removeEventListener(type, handler);
|
|
@@ -1757,7 +2341,7 @@ var BidkernelPrebidAnalytics = class _BidkernelPrebidAnalytics {
|
|
|
1757
2341
|
const auctionId = options?.auctionId || "";
|
|
1758
2342
|
const transactionId = options?.transactionId || "";
|
|
1759
2343
|
const getWinningBid = () => {
|
|
1760
|
-
return (auctionId ? this.
|
|
2344
|
+
return (auctionId ? this.getCachedBid(`${auctionId}:${adUnitCode}`) : void 0) || (auctionId && slotId !== adUnitCode ? this.getCachedBid(`${auctionId}:${slotId}`) : void 0) || this.getCachedBid(adUnitCode) || (slotId !== adUnitCode ? this.getCachedBid(slotId) : void 0);
|
|
1761
2345
|
};
|
|
1762
2346
|
let videoEl = null;
|
|
1763
2347
|
if (el) {
|
|
@@ -1993,6 +2577,10 @@ var BidkernelPrebidAnalytics = class _BidkernelPrebidAnalytics {
|
|
|
1993
2577
|
refreshIndex: record.refreshIndex
|
|
1994
2578
|
};
|
|
1995
2579
|
}
|
|
2580
|
+
/** The validated ingest endpoint in use, or "" when none passed validation. */
|
|
2581
|
+
getEndpoint() {
|
|
2582
|
+
return this.config.endpoint;
|
|
2583
|
+
}
|
|
1996
2584
|
getRefreshIndex(slotId) {
|
|
1997
2585
|
return this.slotRefreshIndices.get(slotId) ?? 0;
|
|
1998
2586
|
}
|
|
@@ -2033,17 +2621,29 @@ var BidkernelPrebidAnalytics = class _BidkernelPrebidAnalytics {
|
|
|
2033
2621
|
handleAuctionInit(data) {
|
|
2034
2622
|
if (this.isDuplicate("auctionInit", data)) return;
|
|
2035
2623
|
this.log("DEBUG", "auctionInit", data);
|
|
2624
|
+
const auctionId = data.auctionId || "";
|
|
2625
|
+
if (auctionId) {
|
|
2626
|
+
this.auctionBidderOutcomes.delete(auctionId);
|
|
2627
|
+
this.getOrCreateAuctionOutcomes(auctionId);
|
|
2628
|
+
}
|
|
2036
2629
|
this.enqueue(TraceEventType.AUCTION_START, "auctionStart", {
|
|
2037
|
-
auctionId
|
|
2630
|
+
auctionId,
|
|
2038
2631
|
transactionId: data.transactionId || ""
|
|
2039
2632
|
});
|
|
2040
2633
|
}
|
|
2041
2634
|
handleAuctionEnd(data) {
|
|
2042
2635
|
if (this.isDuplicate("auctionEnd", data)) return;
|
|
2043
2636
|
this.log("DEBUG", "auctionEnd", data);
|
|
2637
|
+
const auctionId = data.auctionId || "";
|
|
2638
|
+
const outcomesMap = auctionId ? this.auctionBidderOutcomes.get(auctionId) : void 0;
|
|
2639
|
+
const bidderOutcomes = outcomesMap ? Array.from(outcomesMap.values()) : [];
|
|
2640
|
+
if (auctionId) {
|
|
2641
|
+
this.auctionBidderOutcomes.delete(auctionId);
|
|
2642
|
+
}
|
|
2044
2643
|
this.enqueue(TraceEventType.AUCTION_END, "auctionEnd", {
|
|
2045
|
-
auctionId
|
|
2046
|
-
transactionId: data.transactionId || ""
|
|
2644
|
+
auctionId,
|
|
2645
|
+
transactionId: data.transactionId || "",
|
|
2646
|
+
bidderOutcomes
|
|
2047
2647
|
});
|
|
2048
2648
|
}
|
|
2049
2649
|
handleBidRequested(data) {
|
|
@@ -2051,88 +2651,100 @@ var BidkernelPrebidAnalytics = class _BidkernelPrebidAnalytics {
|
|
|
2051
2651
|
this.log("DEBUG", "bidRequested", data);
|
|
2052
2652
|
const auctionId = data.auctionId || "";
|
|
2053
2653
|
const bidder = data.bidderCode || data.bidder || "";
|
|
2654
|
+
if (!auctionId || !bidder) return;
|
|
2655
|
+
const auctionMap = this.getOrCreateAuctionOutcomes(auctionId);
|
|
2054
2656
|
if (Array.isArray(data.bids)) {
|
|
2055
2657
|
data.bids.forEach((bid) => {
|
|
2658
|
+
const adUnitCode = bid.adUnitCode || "";
|
|
2056
2659
|
const mediaTypes = Object.keys(bid.mediaTypes || {});
|
|
2057
|
-
const
|
|
2058
|
-
const
|
|
2059
|
-
if (
|
|
2060
|
-
|
|
2061
|
-
|
|
2062
|
-
|
|
2063
|
-
|
|
2064
|
-
|
|
2065
|
-
|
|
2066
|
-
gpid,
|
|
2067
|
-
bid: {
|
|
2068
|
-
bidder,
|
|
2069
|
-
mediaType,
|
|
2070
|
-
width,
|
|
2071
|
-
height
|
|
2072
|
-
}
|
|
2660
|
+
const mediaType = mediaTypes.length > 0 ? mediaTypes[0] : bid.mediaType || "banner";
|
|
2661
|
+
const key = `${bidder}:${adUnitCode}`;
|
|
2662
|
+
if (!auctionMap.has(key)) {
|
|
2663
|
+
auctionMap.set(key, {
|
|
2664
|
+
bidder,
|
|
2665
|
+
adUnitCode,
|
|
2666
|
+
mediaType,
|
|
2667
|
+
outcome: BidderOutcome.BIDDER_OUTCOME_NO_RESPONSE,
|
|
2668
|
+
latencyMs: 0
|
|
2073
2669
|
});
|
|
2074
|
-
return;
|
|
2075
2670
|
}
|
|
2076
|
-
mediaTypes.forEach((mediaType) => {
|
|
2077
|
-
let rawSize = null;
|
|
2078
|
-
if (mediaType === "banner") {
|
|
2079
|
-
rawSize = bid.mediaTypes?.banner?.sizes || bid.sizes;
|
|
2080
|
-
} else if (mediaType === "video") {
|
|
2081
|
-
rawSize = bid.mediaTypes?.video?.playerSize || bid.mediaTypes?.video?.sizes || bid.playerSize;
|
|
2082
|
-
} else {
|
|
2083
|
-
rawSize = bid.mediaTypes?.[mediaType]?.sizes;
|
|
2084
|
-
}
|
|
2085
|
-
const { width, height } = parseSize(rawSize);
|
|
2086
|
-
this.enqueue(TraceEventType.BID_REQUEST, "bidRequest", {
|
|
2087
|
-
auctionId,
|
|
2088
|
-
transactionId,
|
|
2089
|
-
adUnitCode: bid.adUnitCode || "",
|
|
2090
|
-
gpid,
|
|
2091
|
-
bid: {
|
|
2092
|
-
bidder,
|
|
2093
|
-
mediaType,
|
|
2094
|
-
width,
|
|
2095
|
-
height
|
|
2096
|
-
}
|
|
2097
|
-
});
|
|
2098
|
-
});
|
|
2099
2671
|
});
|
|
2100
2672
|
}
|
|
2101
2673
|
}
|
|
2102
2674
|
handleBidResponse(data) {
|
|
2103
2675
|
if (this.isDuplicate("bidResponse", data)) return;
|
|
2104
2676
|
this.log("DEBUG", "bidResponse", data);
|
|
2105
|
-
|
|
2106
|
-
|
|
2107
|
-
|
|
2108
|
-
|
|
2109
|
-
|
|
2110
|
-
|
|
2111
|
-
|
|
2112
|
-
|
|
2113
|
-
|
|
2114
|
-
|
|
2115
|
-
|
|
2116
|
-
|
|
2117
|
-
|
|
2118
|
-
|
|
2677
|
+
const auctionId = data.auctionId || "";
|
|
2678
|
+
const bidder = data.bidderCode || data.bidder || "";
|
|
2679
|
+
const adUnitCode = data.adUnitCode || "";
|
|
2680
|
+
const cpm = Number.isFinite(data.originalCpm) ? data.originalCpm : Number.isFinite(data.cpm) ? data.cpm : 0;
|
|
2681
|
+
const latencyMs = Number.isFinite(data.timeToRespond) ? data.timeToRespond : 0;
|
|
2682
|
+
const resMediaTypes = Object.keys(data.mediaTypes || {});
|
|
2683
|
+
const mediaType = data.mediaType || (data.mediaTypes?.video ? "video" : resMediaTypes.length > 0 ? resMediaTypes[0] : "banner");
|
|
2684
|
+
if (auctionId && bidder) {
|
|
2685
|
+
const auctionMap = this.getOrCreateAuctionOutcomes(auctionId);
|
|
2686
|
+
const key = `${bidder}:${adUnitCode}`;
|
|
2687
|
+
const entry = auctionMap.get(key);
|
|
2688
|
+
const outcome = cpm > 0 ? BidderOutcome.BIDDER_OUTCOME_BID : BidderOutcome.BIDDER_OUTCOME_NO_BID;
|
|
2689
|
+
if (entry) {
|
|
2690
|
+
entry.outcome = outcome;
|
|
2691
|
+
entry.latencyMs = latencyMs;
|
|
2692
|
+
if (mediaType) entry.mediaType = mediaType;
|
|
2693
|
+
} else {
|
|
2694
|
+
auctionMap.set(key, {
|
|
2695
|
+
bidder,
|
|
2696
|
+
adUnitCode,
|
|
2697
|
+
mediaType,
|
|
2698
|
+
outcome,
|
|
2699
|
+
latencyMs
|
|
2700
|
+
});
|
|
2119
2701
|
}
|
|
2120
|
-
}
|
|
2702
|
+
}
|
|
2703
|
+
if (cpm > 0) {
|
|
2704
|
+
this.enqueue(TraceEventType.BID_RESPONSE, "bidResponse", {
|
|
2705
|
+
auctionId,
|
|
2706
|
+
transactionId: data.transactionId || "",
|
|
2707
|
+
adUnitCode,
|
|
2708
|
+
bid: {
|
|
2709
|
+
bidder,
|
|
2710
|
+
cpm,
|
|
2711
|
+
currency: data.originalCurrency ?? data.currency ?? "USD",
|
|
2712
|
+
...parseBidDimensions(data),
|
|
2713
|
+
dealId: data.dealId || "",
|
|
2714
|
+
mediaType,
|
|
2715
|
+
latencyMs,
|
|
2716
|
+
advertiserDomain: data.meta?.advertiserDomains?.[0] || "",
|
|
2717
|
+
creativeId: data.creativeId || ""
|
|
2718
|
+
}
|
|
2719
|
+
});
|
|
2720
|
+
}
|
|
2121
2721
|
}
|
|
2122
2722
|
handleBidTimeout(data) {
|
|
2123
2723
|
if (this.isDuplicate("bidTimeout", data)) return;
|
|
2124
2724
|
this.log("DEBUG", "bidTimeout", data);
|
|
2125
2725
|
const items = Array.isArray(data) ? data : data ? [data] : [];
|
|
2126
2726
|
for (const t of items) {
|
|
2127
|
-
|
|
2128
|
-
|
|
2129
|
-
|
|
2130
|
-
|
|
2131
|
-
|
|
2132
|
-
|
|
2133
|
-
|
|
2727
|
+
const auctionId = t.auctionId || "";
|
|
2728
|
+
const bidder = t.bidderCode || t.bidder || "";
|
|
2729
|
+
const adUnitCode = t.adUnitCode || "";
|
|
2730
|
+
const latencyMs = Number.isFinite(t.timeout) ? t.timeout : 0;
|
|
2731
|
+
if (auctionId && bidder) {
|
|
2732
|
+
const auctionMap = this.getOrCreateAuctionOutcomes(auctionId);
|
|
2733
|
+
const key = `${bidder}:${adUnitCode}`;
|
|
2734
|
+
const entry = auctionMap.get(key);
|
|
2735
|
+
if (entry) {
|
|
2736
|
+
entry.outcome = BidderOutcome.BIDDER_OUTCOME_TIMEOUT;
|
|
2737
|
+
if (latencyMs > 0) entry.latencyMs = latencyMs;
|
|
2738
|
+
} else {
|
|
2739
|
+
auctionMap.set(key, {
|
|
2740
|
+
bidder,
|
|
2741
|
+
adUnitCode,
|
|
2742
|
+
mediaType: "banner",
|
|
2743
|
+
outcome: BidderOutcome.BIDDER_OUTCOME_TIMEOUT,
|
|
2744
|
+
latencyMs
|
|
2745
|
+
});
|
|
2134
2746
|
}
|
|
2135
|
-
}
|
|
2747
|
+
}
|
|
2136
2748
|
}
|
|
2137
2749
|
}
|
|
2138
2750
|
handleBidWon(data) {
|
|
@@ -2141,13 +2753,15 @@ var BidkernelPrebidAnalytics = class _BidkernelPrebidAnalytics {
|
|
|
2141
2753
|
const auctionId = data.auctionId || "";
|
|
2142
2754
|
const transactionId = data.transactionId || "";
|
|
2143
2755
|
const adUnitCode = data.adUnitCode || data.adId || "";
|
|
2756
|
+
const wonMediaTypes = Object.keys(data.mediaTypes || {});
|
|
2757
|
+
const resolvedMediaType = data.mediaType || (data.mediaTypes?.video ? "video" : wonMediaTypes.length > 0 ? wonMediaTypes[0] : "banner");
|
|
2144
2758
|
const bidTrace = {
|
|
2145
2759
|
bidder: data.bidderCode || data.bidder || "",
|
|
2146
2760
|
cpm: Number.isFinite(data.originalCpm) ? data.originalCpm : Number.isFinite(data.cpm) ? data.cpm : 0,
|
|
2147
2761
|
currency: data.originalCurrency ?? data.currency ?? "USD",
|
|
2148
2762
|
...parseBidDimensions(data),
|
|
2149
2763
|
dealId: data.dealId || "",
|
|
2150
|
-
mediaType:
|
|
2764
|
+
mediaType: resolvedMediaType,
|
|
2151
2765
|
latencyMs: Number.isFinite(data.timeToRespond) ? data.timeToRespond : 0,
|
|
2152
2766
|
advertiserDomain: data.meta?.advertiserDomains?.[0] || "",
|
|
2153
2767
|
creativeId: data.creativeId || ""
|
|
@@ -2171,6 +2785,7 @@ var BidkernelPrebidAnalytics = class _BidkernelPrebidAnalytics {
|
|
|
2171
2785
|
this.cachedWinningBids.set(`${auctionId}:${data.adId}`, cachedEntry);
|
|
2172
2786
|
}
|
|
2173
2787
|
}
|
|
2788
|
+
this.pruneCachedWinningBids();
|
|
2174
2789
|
}
|
|
2175
2790
|
this.enqueue(TraceEventType.BID_WIN, "bidWon", {
|
|
2176
2791
|
auctionId,
|
|
@@ -2182,14 +2797,27 @@ var BidkernelPrebidAnalytics = class _BidkernelPrebidAnalytics {
|
|
|
2182
2797
|
handleNoBid(data) {
|
|
2183
2798
|
if (this.isDuplicate("noBid", data)) return;
|
|
2184
2799
|
this.log("DEBUG", "noBid", data);
|
|
2185
|
-
|
|
2186
|
-
|
|
2187
|
-
|
|
2188
|
-
|
|
2189
|
-
|
|
2190
|
-
|
|
2800
|
+
const auctionId = data.auctionId || "";
|
|
2801
|
+
const bidder = data.bidderCode || data.bidder || "";
|
|
2802
|
+
const adUnitCode = data.adUnitCode || "";
|
|
2803
|
+
if (auctionId && bidder) {
|
|
2804
|
+
const auctionMap = this.getOrCreateAuctionOutcomes(auctionId);
|
|
2805
|
+
const key = `${bidder}:${adUnitCode}`;
|
|
2806
|
+
const entry = auctionMap.get(key);
|
|
2807
|
+
if (entry) {
|
|
2808
|
+
if (entry.outcome === BidderOutcome.BIDDER_OUTCOME_NO_RESPONSE) {
|
|
2809
|
+
entry.outcome = BidderOutcome.BIDDER_OUTCOME_NO_BID;
|
|
2810
|
+
}
|
|
2811
|
+
} else {
|
|
2812
|
+
auctionMap.set(key, {
|
|
2813
|
+
bidder,
|
|
2814
|
+
adUnitCode,
|
|
2815
|
+
mediaType: "banner",
|
|
2816
|
+
outcome: BidderOutcome.BIDDER_OUTCOME_NO_BID,
|
|
2817
|
+
latencyMs: 0
|
|
2818
|
+
});
|
|
2191
2819
|
}
|
|
2192
|
-
}
|
|
2820
|
+
}
|
|
2193
2821
|
}
|
|
2194
2822
|
handleAdRenderFailed(data) {
|
|
2195
2823
|
if (this.isDuplicate("adRenderFailed", data)) return;
|
|
@@ -2221,14 +2849,16 @@ var BidkernelPrebidAnalytics = class _BidkernelPrebidAnalytics {
|
|
|
2221
2849
|
const mediaType = bid.mediaType || "banner";
|
|
2222
2850
|
const slotKey = data.adUnitCode || bid.adUnitCode || "";
|
|
2223
2851
|
const altKey = data.adId || bid.adId || "";
|
|
2224
|
-
const cached = (auctionId && slotKey ? this.
|
|
2852
|
+
const cached = (auctionId && slotKey ? this.getCachedBid(`${auctionId}:${slotKey}`) : void 0) || (auctionId && altKey ? this.getCachedBid(`${auctionId}:${altKey}`) : void 0) || (slotKey ? this.getCachedBid(slotKey) : void 0) || (altKey ? this.getCachedBid(altKey) : void 0);
|
|
2853
|
+
const isVideo = mediaType === "video" || bid.mediaType === "video" || bid.mediaTypes?.video !== void 0 || cached?.bidTrace?.mediaType === "video" || cached?.rawBid?.mediaType === "video" || adUnitCode && this.slotViewabilityRecords.get(adUnitCode)?.mediaType === "video";
|
|
2854
|
+
const resolvedMediaType = isVideo ? "video" : mediaType || cached?.bidTrace?.mediaType || "banner";
|
|
2225
2855
|
const bidTrace = {
|
|
2226
2856
|
bidder: bid.bidderCode || bid.bidder || cached?.bidTrace?.bidder || "",
|
|
2227
2857
|
cpm: Number.isFinite(bid.originalCpm) ? bid.originalCpm : Number.isFinite(bid.cpm) ? bid.cpm : cached?.bidTrace?.cpm ?? 0,
|
|
2228
2858
|
currency: bid.originalCurrency ?? bid.currency ?? cached?.bidTrace?.currency ?? "USD",
|
|
2229
2859
|
...parseBidDimensions(bid).width ? parseBidDimensions(bid) : cached?.bidTrace ? { width: cached.bidTrace.width, height: cached.bidTrace.height } : parseBidDimensions(bid),
|
|
2230
2860
|
dealId: bid.dealId || cached?.bidTrace?.dealId || "",
|
|
2231
|
-
mediaType:
|
|
2861
|
+
mediaType: resolvedMediaType,
|
|
2232
2862
|
latencyMs: Number.isFinite(bid.timeToRespond) ? bid.timeToRespond : cached?.bidTrace?.latencyMs ?? 0,
|
|
2233
2863
|
advertiserDomain: bid.meta?.advertiserDomains?.[0] || cached?.bidTrace?.advertiserDomain || "",
|
|
2234
2864
|
creativeId: bid.creativeId || cached?.bidTrace?.creativeId || ""
|
|
@@ -2267,28 +2897,35 @@ var BidkernelPrebidAnalytics = class _BidkernelPrebidAnalytics {
|
|
|
2267
2897
|
}
|
|
2268
2898
|
}
|
|
2269
2899
|
const currentRefreshIndex = adUnitCode ? this.slotRefreshIndices.get(adUnitCode) ?? (record ? record.refreshIndex : 0) : 0;
|
|
2270
|
-
|
|
2271
|
-
adUnitCode
|
|
2272
|
-
|
|
2273
|
-
|
|
2274
|
-
|
|
2275
|
-
|
|
2276
|
-
|
|
2277
|
-
if (
|
|
2278
|
-
|
|
2900
|
+
if (!isVideo) {
|
|
2901
|
+
const alreadyEmitted = adUnitCode ? this.hasImpressionEmitted(
|
|
2902
|
+
adUnitCode,
|
|
2903
|
+
currentRefreshIndex,
|
|
2904
|
+
resolvedAuctionId,
|
|
2905
|
+
bidTrace.creativeId
|
|
2906
|
+
) : false;
|
|
2907
|
+
if (!alreadyEmitted) {
|
|
2908
|
+
if (adUnitCode) {
|
|
2909
|
+
this.markImpressionEmitted(
|
|
2910
|
+
adUnitCode,
|
|
2911
|
+
currentRefreshIndex,
|
|
2912
|
+
resolvedAuctionId,
|
|
2913
|
+
bidTrace.creativeId
|
|
2914
|
+
);
|
|
2915
|
+
}
|
|
2916
|
+
this.enqueue(TraceEventType.IMPRESSION, "impression", {
|
|
2917
|
+
auctionId: resolvedAuctionId,
|
|
2918
|
+
transactionId: resolvedTransactionId,
|
|
2279
2919
|
adUnitCode,
|
|
2280
|
-
|
|
2281
|
-
|
|
2282
|
-
|
|
2283
|
-
);
|
|
2920
|
+
bid: bidTrace,
|
|
2921
|
+
metadata: { refresh_index: String(currentRefreshIndex) }
|
|
2922
|
+
});
|
|
2284
2923
|
}
|
|
2285
|
-
|
|
2286
|
-
|
|
2287
|
-
|
|
2288
|
-
adUnitCode
|
|
2289
|
-
|
|
2290
|
-
metadata: { refresh_index: String(currentRefreshIndex) }
|
|
2291
|
-
});
|
|
2924
|
+
} else {
|
|
2925
|
+
this.log(
|
|
2926
|
+
"DEBUG",
|
|
2927
|
+
`adRenderSucceeded received for video ad unit ${adUnitCode || "unknown"}: suppressing IMPRESSION until verified video lifecycle event`
|
|
2928
|
+
);
|
|
2292
2929
|
}
|
|
2293
2930
|
if (this.config.viewabilityEnabled && typeof document !== "undefined") {
|
|
2294
2931
|
let el = null;
|
|
@@ -2310,7 +2947,12 @@ var BidkernelPrebidAnalytics = class _BidkernelPrebidAnalytics {
|
|
|
2310
2947
|
}
|
|
2311
2948
|
if (!el && targetId) {
|
|
2312
2949
|
try {
|
|
2313
|
-
|
|
2950
|
+
for (const candidate of Array.from(document.querySelectorAll("[data-ad-slot]"))) {
|
|
2951
|
+
if (candidate.getAttribute("data-ad-slot") === targetId) {
|
|
2952
|
+
el = candidate;
|
|
2953
|
+
break;
|
|
2954
|
+
}
|
|
2955
|
+
}
|
|
2314
2956
|
} catch {
|
|
2315
2957
|
}
|
|
2316
2958
|
}
|
|
@@ -2319,7 +2961,7 @@ var BidkernelPrebidAnalytics = class _BidkernelPrebidAnalytics {
|
|
|
2319
2961
|
adUnitCode,
|
|
2320
2962
|
auctionId: resolvedAuctionId,
|
|
2321
2963
|
transactionId: resolvedTransactionId,
|
|
2322
|
-
mediaType,
|
|
2964
|
+
mediaType: resolvedMediaType,
|
|
2323
2965
|
bid: bidTrace,
|
|
2324
2966
|
refreshIndex: currentRefreshIndex,
|
|
2325
2967
|
emitRefreshEvent: false
|
|
@@ -2364,6 +3006,9 @@ var BidkernelPrebidAnalytics = class _BidkernelPrebidAnalytics {
|
|
|
2364
3006
|
if (data.viewableDurationMs !== void 0) {
|
|
2365
3007
|
protoEvent.viewableDurationMs = Number.isFinite(data.viewableDurationMs) ? data.viewableDurationMs : 0;
|
|
2366
3008
|
}
|
|
3009
|
+
if (data.bidderOutcomes && Array.isArray(data.bidderOutcomes)) {
|
|
3010
|
+
protoEvent.bidderOutcomes = data.bidderOutcomes;
|
|
3011
|
+
}
|
|
2367
3012
|
const metadata = { ...data.metadata };
|
|
2368
3013
|
if (data.error !== void 0 && data.error !== null) {
|
|
2369
3014
|
metadata.error = typeof data.error === "object" && data.error.message ? String(data.error.message) : String(data.error);
|
|
@@ -2374,8 +3019,9 @@ var BidkernelPrebidAnalytics = class _BidkernelPrebidAnalytics {
|
|
|
2374
3019
|
if (data.refreshIndex !== void 0 && metadata.refresh_index === void 0) {
|
|
2375
3020
|
metadata.refresh_index = String(data.refreshIndex);
|
|
2376
3021
|
}
|
|
2377
|
-
|
|
2378
|
-
|
|
3022
|
+
const boundedMetadata = boundMetadata(metadata);
|
|
3023
|
+
if (Object.keys(boundedMetadata).length > 0) {
|
|
3024
|
+
protoEvent.metadata = boundedMetadata;
|
|
2379
3025
|
}
|
|
2380
3026
|
this.queue.push(protoEvent);
|
|
2381
3027
|
if (this.queue.length > MAX_QUEUE_SIZE) {
|
|
@@ -2413,7 +3059,6 @@ var BidkernelPrebidAnalytics = class _BidkernelPrebidAnalytics {
|
|
|
2413
3059
|
// Shared by flush() and flushBeacon().
|
|
2414
3060
|
drainBatch() {
|
|
2415
3061
|
if (this.queue.length === 0 || !this.config.endpoint) return null;
|
|
2416
|
-
let events = this.queue;
|
|
2417
3062
|
const domain = typeof window !== "undefined" ? window.location.hostname : "";
|
|
2418
3063
|
const buildBatch = (evts) => ({
|
|
2419
3064
|
propertyId: this.config.propertyId,
|
|
@@ -2427,25 +3072,37 @@ var BidkernelPrebidAnalytics = class _BidkernelPrebidAnalytics {
|
|
|
2427
3072
|
domain,
|
|
2428
3073
|
events: evts
|
|
2429
3074
|
});
|
|
2430
|
-
|
|
2431
|
-
|
|
2432
|
-
|
|
2433
|
-
|
|
2434
|
-
events = events.slice(0, Math.floor(events.length / 2));
|
|
2435
|
-
encoded = TraceEventBatch.encode(
|
|
3075
|
+
for (; ; ) {
|
|
3076
|
+
if (this.queue.length === 0) return null;
|
|
3077
|
+
let events = this.queue;
|
|
3078
|
+
let encoded = TraceEventBatch.encode(
|
|
2436
3079
|
buildBatch(events)
|
|
2437
3080
|
).finish();
|
|
3081
|
+
while (events.length > 1 && encoded.byteLength > MAX_PAYLOAD_BYTES) {
|
|
3082
|
+
events = events.slice(0, Math.floor(events.length / 2));
|
|
3083
|
+
encoded = TraceEventBatch.encode(
|
|
3084
|
+
buildBatch(events)
|
|
3085
|
+
).finish();
|
|
3086
|
+
}
|
|
3087
|
+
if (encoded.byteLength > MAX_PAYLOAD_BYTES) {
|
|
3088
|
+
const [dropped] = this.queue.splice(0, 1);
|
|
3089
|
+
this.log(
|
|
3090
|
+
"WARN",
|
|
3091
|
+
`Dropping oversized event ${dropped?.eventName || dropped?.eventId} (${encoded.byteLength} bytes exceeds the ${MAX_PAYLOAD_BYTES}-byte cap on its own)`
|
|
3092
|
+
);
|
|
3093
|
+
continue;
|
|
3094
|
+
}
|
|
3095
|
+
this.queue = this.queue.slice(events.length);
|
|
3096
|
+
return {
|
|
3097
|
+
url: `${this.config.endpoint}/${this.config.propertyId}`,
|
|
3098
|
+
// protobufjs types finish() as Uint8Array<ArrayBufferLike>; the buffer is
|
|
3099
|
+
// always a plain ArrayBuffer, so narrow for fetch/Blob compatibility.
|
|
3100
|
+
encoded,
|
|
3101
|
+
events
|
|
3102
|
+
};
|
|
2438
3103
|
}
|
|
2439
|
-
this.queue = this.queue.slice(events.length);
|
|
2440
|
-
return {
|
|
2441
|
-
url: `${this.config.endpoint}/${this.config.propertyId}`,
|
|
2442
|
-
// protobufjs types finish() as Uint8Array<ArrayBufferLike>; the buffer is
|
|
2443
|
-
// always a plain ArrayBuffer, so narrow for fetch/Blob compatibility.
|
|
2444
|
-
encoded,
|
|
2445
|
-
events
|
|
2446
|
-
};
|
|
2447
3104
|
}
|
|
2448
|
-
sendFetch(payload, useKeepalive = false, onDelivered) {
|
|
3105
|
+
sendFetch(payload, useKeepalive = false, onDelivered, isReplay = false) {
|
|
2449
3106
|
const fetchOpts = {
|
|
2450
3107
|
method: "POST",
|
|
2451
3108
|
// Safelisted content type: no CORS preflight (see SAFE_CONTENT_TYPE).
|
|
@@ -2462,15 +3119,17 @@ var BidkernelPrebidAnalytics = class _BidkernelPrebidAnalytics {
|
|
|
2462
3119
|
this.log("WARN", `Dropping batch due to non-retryable client error HTTP ${res.status}`);
|
|
2463
3120
|
return;
|
|
2464
3121
|
}
|
|
2465
|
-
this.handleSendFailure(payload.events);
|
|
3122
|
+
if (!isReplay) this.handleSendFailure(payload.events);
|
|
2466
3123
|
} else {
|
|
2467
|
-
|
|
2468
|
-
|
|
3124
|
+
if (!isReplay) {
|
|
3125
|
+
this.consecutiveSendFailures = 0;
|
|
3126
|
+
this.nextSendAllowedAt = 0;
|
|
3127
|
+
}
|
|
2469
3128
|
if (onDelivered) onDelivered();
|
|
2470
3129
|
}
|
|
2471
3130
|
}).catch((err) => {
|
|
2472
3131
|
this.log("ERROR", "Failed to send batch", err);
|
|
2473
|
-
this.handleSendFailure(payload.events);
|
|
3132
|
+
if (!isReplay) this.handleSendFailure(payload.events);
|
|
2474
3133
|
});
|
|
2475
3134
|
const proc = typeof globalThis !== "undefined" ? globalThis.process : void 0;
|
|
2476
3135
|
if (proc && typeof proc._tickCallback === "function") {
|
|
@@ -2526,16 +3185,23 @@ var BidkernelPrebidAnalytics = class _BidkernelPrebidAnalytics {
|
|
|
2526
3185
|
this.schedulePersistedCleanup();
|
|
2527
3186
|
}
|
|
2528
3187
|
// --- Exit-batch persistence -----------------------------------------------
|
|
3188
|
+
// Key prefix for this instance's property. encodeURIComponent keeps the
|
|
3189
|
+
// property segment free of the "_" the timestamp suffix is parsed against,
|
|
3190
|
+
// so a property ID containing one cannot forge another property's prefix.
|
|
3191
|
+
pendingKeyPrefix() {
|
|
3192
|
+
return `${PENDING_BATCH_KEY_PREFIX}${encodeURIComponent(this.config.propertyId)}_`;
|
|
3193
|
+
}
|
|
2529
3194
|
persistBatch(encoded) {
|
|
2530
3195
|
try {
|
|
2531
3196
|
if (typeof localStorage === "undefined") return null;
|
|
3197
|
+
if (!this.config.propertyId) return null;
|
|
2532
3198
|
let pendingCount = 0;
|
|
2533
3199
|
for (let i = 0; i < localStorage.length; i++) {
|
|
2534
3200
|
const k = localStorage.key(i);
|
|
2535
3201
|
if (k && k.startsWith(PENDING_BATCH_KEY_PREFIX)) pendingCount++;
|
|
2536
3202
|
}
|
|
2537
3203
|
if (pendingCount >= MAX_PENDING_BATCHES) return null;
|
|
2538
|
-
const key = `${
|
|
3204
|
+
const key = `${this.pendingKeyPrefix()}${Date.now()}_${Math.floor(Math.random() * 1e6)}`;
|
|
2539
3205
|
localStorage.setItem(key, bytesToBase64(encoded));
|
|
2540
3206
|
this.persistedBatchKeys.push(key);
|
|
2541
3207
|
return key;
|
|
@@ -2566,16 +3232,33 @@ var BidkernelPrebidAnalytics = class _BidkernelPrebidAnalytics {
|
|
|
2566
3232
|
}, PENDING_BATCH_CLEANUP_DELAY_MS);
|
|
2567
3233
|
}
|
|
2568
3234
|
// Resend batches a previous pageview persisted at exit but could not
|
|
2569
|
-
// confirm.
|
|
2570
|
-
//
|
|
2571
|
-
//
|
|
3235
|
+
// confirm. Only this property's own keys are claimed: batches belonging to
|
|
3236
|
+
// another property sharing this origin are left for that property's next
|
|
3237
|
+
// pageview, since resending them here would file them under this property.
|
|
3238
|
+
// Keys are claimed (removed) before sending so concurrent tabs don't
|
|
3239
|
+
// double-send; the batch bytes carry their original pageview, session, and
|
|
3240
|
+
// event timestamps, so late rows attribute correctly.
|
|
2572
3241
|
resendPersistedBatches() {
|
|
2573
3242
|
try {
|
|
2574
3243
|
if (typeof localStorage === "undefined" || !this.config.endpoint) return;
|
|
3244
|
+
if (!this.config.propertyId) return;
|
|
3245
|
+
const ownPrefix = this.pendingKeyPrefix();
|
|
2575
3246
|
const keys = [];
|
|
3247
|
+
const legacyKeys = [];
|
|
2576
3248
|
for (let i = 0; i < localStorage.length; i++) {
|
|
2577
3249
|
const k = localStorage.key(i);
|
|
2578
|
-
if (k
|
|
3250
|
+
if (!k || !k.startsWith(PENDING_BATCH_KEY_PREFIX)) continue;
|
|
3251
|
+
if (k.startsWith(ownPrefix)) {
|
|
3252
|
+
keys.push(k);
|
|
3253
|
+
} else if (isLegacyPendingKey(k)) {
|
|
3254
|
+
legacyKeys.push(k);
|
|
3255
|
+
}
|
|
3256
|
+
}
|
|
3257
|
+
for (const key of legacyKeys) {
|
|
3258
|
+
try {
|
|
3259
|
+
localStorage.removeItem(key);
|
|
3260
|
+
} catch {
|
|
3261
|
+
}
|
|
2579
3262
|
}
|
|
2580
3263
|
for (const key of keys) {
|
|
2581
3264
|
let value = null;
|
|
@@ -2586,7 +3269,7 @@ var BidkernelPrebidAnalytics = class _BidkernelPrebidAnalytics {
|
|
|
2586
3269
|
continue;
|
|
2587
3270
|
}
|
|
2588
3271
|
if (!value) continue;
|
|
2589
|
-
const ts = parseInt(key.slice(
|
|
3272
|
+
const ts = parseInt(key.slice(ownPrefix.length), 10);
|
|
2590
3273
|
if (!Number.isFinite(ts) || Date.now() - ts > PENDING_BATCH_MAX_AGE_MS) continue;
|
|
2591
3274
|
let encoded;
|
|
2592
3275
|
try {
|
|
@@ -2596,11 +3279,16 @@ var BidkernelPrebidAnalytics = class _BidkernelPrebidAnalytics {
|
|
|
2596
3279
|
}
|
|
2597
3280
|
if (encoded.byteLength === 0) continue;
|
|
2598
3281
|
this.log("DEBUG", `Resending persisted exit batch (${encoded.byteLength} bytes)`);
|
|
2599
|
-
this.sendFetch(
|
|
2600
|
-
|
|
2601
|
-
|
|
2602
|
-
|
|
2603
|
-
|
|
3282
|
+
this.sendFetch(
|
|
3283
|
+
{
|
|
3284
|
+
url: `${this.config.endpoint}/${this.config.propertyId}`,
|
|
3285
|
+
encoded,
|
|
3286
|
+
events: []
|
|
3287
|
+
},
|
|
3288
|
+
false,
|
|
3289
|
+
void 0,
|
|
3290
|
+
true
|
|
3291
|
+
);
|
|
2604
3292
|
}
|
|
2605
3293
|
} catch {
|
|
2606
3294
|
}
|
|
@@ -2625,11 +3313,13 @@ var BidkernelPrebidAnalytics = class _BidkernelPrebidAnalytics {
|
|
|
2625
3313
|
}
|
|
2626
3314
|
}
|
|
2627
3315
|
};
|
|
2628
|
-
function extractAnalyticsOptions(config) {
|
|
3316
|
+
function extractAnalyticsOptions(config, allowProviderless = true) {
|
|
2629
3317
|
if (!config) return null;
|
|
2630
3318
|
if (Array.isArray(config)) {
|
|
2631
|
-
const matched = config.find((item) => item?.provider === "bidkernel") ?? config.find(
|
|
2632
|
-
|
|
3319
|
+
const matched = config.find((item) => item?.provider === "bidkernel") ?? (allowProviderless ? config.find(
|
|
3320
|
+
(item) => item && typeof item === "object" && item.provider === void 0
|
|
3321
|
+
) : void 0);
|
|
3322
|
+
return matched ? extractAnalyticsOptions(matched, allowProviderless) : null;
|
|
2633
3323
|
}
|
|
2634
3324
|
if (typeof config === "object") {
|
|
2635
3325
|
if (config.options && typeof config.options === "object") {
|
|
@@ -2671,18 +3361,27 @@ function registerPrebidAnalytics(pbjsGlobalName = "pbjs", defaults) {
|
|
|
2671
3361
|
win[pbjsGlobalName] = win[pbjsGlobalName] || {};
|
|
2672
3362
|
const pbjs = win[pbjsGlobalName];
|
|
2673
3363
|
const enableInstance = (options) => {
|
|
2674
|
-
|
|
3364
|
+
const previous = win._bidkernelPrebidAnalytics;
|
|
3365
|
+
const pinnedEndpoint = previous?.getEndpoint?.() || "";
|
|
3366
|
+
const merged = {
|
|
3367
|
+
pbjsGlobalName,
|
|
3368
|
+
...defaults,
|
|
3369
|
+
...options
|
|
3370
|
+
};
|
|
3371
|
+
if (pinnedEndpoint && !sameEndpointOrigin(merged.endpoint || "", pinnedEndpoint)) {
|
|
3372
|
+
console.warn(
|
|
3373
|
+
`[bidkernel] Ignoring analytics endpoint change to ${merged.endpoint || "(empty)"}: this page is pinned to ${pinnedEndpoint}. Reload to change the ingest endpoint.`
|
|
3374
|
+
);
|
|
3375
|
+
merged.endpoint = pinnedEndpoint;
|
|
3376
|
+
}
|
|
3377
|
+
if (previous) {
|
|
2675
3378
|
try {
|
|
2676
|
-
|
|
3379
|
+
previous.disable();
|
|
2677
3380
|
} catch (e) {
|
|
2678
3381
|
console.warn("[bidkernel] Failed to disable previous analytics instance:", e);
|
|
2679
3382
|
}
|
|
2680
3383
|
}
|
|
2681
|
-
const analytics = new BidkernelPrebidAnalytics(
|
|
2682
|
-
pbjsGlobalName,
|
|
2683
|
-
...defaults,
|
|
2684
|
-
...options
|
|
2685
|
-
});
|
|
3384
|
+
const analytics = new BidkernelPrebidAnalytics(merged);
|
|
2686
3385
|
analytics.enable();
|
|
2687
3386
|
win._bidkernelPrebidAnalytics = analytics;
|
|
2688
3387
|
return analytics;
|
|
@@ -2693,7 +3392,7 @@ function registerPrebidAnalytics(pbjsGlobalName = "pbjs", defaults) {
|
|
|
2693
3392
|
pbjs.adapterManager.registerAnalyticsAdapter({
|
|
2694
3393
|
adapter: {
|
|
2695
3394
|
enableAnalytics: (config) => {
|
|
2696
|
-
const options = extractAnalyticsOptions(config);
|
|
3395
|
+
const options = extractAnalyticsOptions(config, !Array.isArray(config));
|
|
2697
3396
|
if (options) {
|
|
2698
3397
|
enableInstance(options);
|
|
2699
3398
|
}
|
|
@@ -2759,5 +3458,8 @@ function getbidkernel(alias = "bidkernel") {
|
|
|
2759
3458
|
PrebidEventDeduper,
|
|
2760
3459
|
getPrebidEventKey,
|
|
2761
3460
|
getbidkernel,
|
|
3461
|
+
hookImaPrototype,
|
|
3462
|
+
initImaInterception,
|
|
3463
|
+
isTrustedEndpoint,
|
|
2762
3464
|
registerPrebidAnalytics
|
|
2763
3465
|
});
|