@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.mjs
CHANGED
|
@@ -4,26 +4,33 @@ var TraceEventType = {
|
|
|
4
4
|
TRACE_EVENT_TYPE_UNSPECIFIED: 0,
|
|
5
5
|
AUCTION_START: 1,
|
|
6
6
|
AUCTION_END: 2,
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
BID_WIN: 5,
|
|
10
|
-
BID_TIMEOUT: 6,
|
|
7
|
+
BID_RESPONSE: 3,
|
|
8
|
+
BID_WIN: 4,
|
|
11
9
|
/** IMPRESSION - ad rendered into DOM */
|
|
12
|
-
IMPRESSION:
|
|
10
|
+
IMPRESSION: 5,
|
|
13
11
|
/** VIEWABLE - IAB viewability threshold met (boolean, once per render cycle) */
|
|
14
|
-
VIEWABLE:
|
|
12
|
+
VIEWABLE: 6,
|
|
15
13
|
/** TIME_IN_VIEW - accumulated in-viewport duration (once per render cycle end) */
|
|
16
|
-
TIME_IN_VIEW:
|
|
17
|
-
REFRESH:
|
|
18
|
-
ERROR:
|
|
19
|
-
SLOT_DEFINED:
|
|
20
|
-
SLOT_DESTROYED:
|
|
14
|
+
TIME_IN_VIEW: 7,
|
|
15
|
+
REFRESH: 8,
|
|
16
|
+
ERROR: 9,
|
|
17
|
+
SLOT_DEFINED: 10,
|
|
18
|
+
SLOT_DESTROYED: 11,
|
|
21
19
|
/** CLICK - ad click-through */
|
|
22
|
-
CLICK:
|
|
23
|
-
/** NO_BID - bidder responded with no bid */
|
|
24
|
-
NO_BID: 15,
|
|
20
|
+
CLICK: 12,
|
|
25
21
|
/** AD_RENDER_FAILED - Prebid failed to render the winning ad */
|
|
26
|
-
AD_RENDER_FAILED:
|
|
22
|
+
AD_RENDER_FAILED: 13,
|
|
23
|
+
UNRECOGNIZED: -1
|
|
24
|
+
};
|
|
25
|
+
var BidderOutcome = {
|
|
26
|
+
BIDDER_OUTCOME_UNSPECIFIED: 0,
|
|
27
|
+
/** BIDDER_OUTCOME_BID - returned a bid (CPM > 0) */
|
|
28
|
+
BIDDER_OUTCOME_BID: 1,
|
|
29
|
+
BIDDER_OUTCOME_NO_BID: 2,
|
|
30
|
+
BIDDER_OUTCOME_TIMEOUT: 3,
|
|
31
|
+
BIDDER_OUTCOME_ERROR: 4,
|
|
32
|
+
/** BIDDER_OUTCOME_NO_RESPONSE - requested, nothing came back by auction end */
|
|
33
|
+
BIDDER_OUTCOME_NO_RESPONSE: 5,
|
|
27
34
|
UNRECOGNIZED: -1
|
|
28
35
|
};
|
|
29
36
|
function createBaseTraceEventBatch() {
|
|
@@ -254,7 +261,8 @@ function createBaseTraceEvent() {
|
|
|
254
261
|
namespace: "",
|
|
255
262
|
eventId: "",
|
|
256
263
|
metadata: {},
|
|
257
|
-
viewableDurationMs: void 0
|
|
264
|
+
viewableDurationMs: void 0,
|
|
265
|
+
bidderOutcomes: []
|
|
258
266
|
};
|
|
259
267
|
}
|
|
260
268
|
var TraceEvent = {
|
|
@@ -292,6 +300,11 @@ var TraceEvent = {
|
|
|
292
300
|
if (message.viewableDurationMs !== void 0) {
|
|
293
301
|
writer.uint32(89).double(message.viewableDurationMs);
|
|
294
302
|
}
|
|
303
|
+
if (message.bidderOutcomes !== void 0 && message.bidderOutcomes.length !== 0) {
|
|
304
|
+
for (const v of message.bidderOutcomes) {
|
|
305
|
+
BidderOutcomeEntry.encode(v, writer.uint32(98).fork()).join();
|
|
306
|
+
}
|
|
307
|
+
}
|
|
295
308
|
return writer;
|
|
296
309
|
},
|
|
297
310
|
decode(input, length) {
|
|
@@ -381,6 +394,16 @@ var TraceEvent = {
|
|
|
381
394
|
message.viewableDurationMs = reader.double();
|
|
382
395
|
continue;
|
|
383
396
|
}
|
|
397
|
+
case 12: {
|
|
398
|
+
if (tag !== 98) {
|
|
399
|
+
break;
|
|
400
|
+
}
|
|
401
|
+
const el = BidderOutcomeEntry.decode(reader, reader.uint32());
|
|
402
|
+
if (el !== void 0) {
|
|
403
|
+
message.bidderOutcomes.push(el);
|
|
404
|
+
}
|
|
405
|
+
continue;
|
|
406
|
+
}
|
|
384
407
|
}
|
|
385
408
|
if ((tag & 7) === 4 || tag === 0) {
|
|
386
409
|
break;
|
|
@@ -413,6 +436,7 @@ var TraceEvent = {
|
|
|
413
436
|
{}
|
|
414
437
|
);
|
|
415
438
|
message.viewableDurationMs = object.viewableDurationMs ?? void 0;
|
|
439
|
+
message.bidderOutcomes = object.bidderOutcomes?.map((e) => BidderOutcomeEntry.fromPartial(e)) || [];
|
|
416
440
|
return message;
|
|
417
441
|
}
|
|
418
442
|
};
|
|
@@ -468,6 +492,91 @@ var TraceEvent_MetadataEntry = {
|
|
|
468
492
|
return message;
|
|
469
493
|
}
|
|
470
494
|
};
|
|
495
|
+
function createBaseBidderOutcomeEntry() {
|
|
496
|
+
return { bidder: "", adUnitCode: "", mediaType: "", outcome: 0, latencyMs: 0 };
|
|
497
|
+
}
|
|
498
|
+
var BidderOutcomeEntry = {
|
|
499
|
+
encode(message, writer = new BinaryWriter()) {
|
|
500
|
+
if (message.bidder !== void 0 && message.bidder !== "") {
|
|
501
|
+
writer.uint32(10).string(message.bidder);
|
|
502
|
+
}
|
|
503
|
+
if (message.adUnitCode !== void 0 && message.adUnitCode !== "") {
|
|
504
|
+
writer.uint32(18).string(message.adUnitCode);
|
|
505
|
+
}
|
|
506
|
+
if (message.mediaType !== void 0 && message.mediaType !== "") {
|
|
507
|
+
writer.uint32(26).string(message.mediaType);
|
|
508
|
+
}
|
|
509
|
+
if (message.outcome !== void 0 && message.outcome !== 0) {
|
|
510
|
+
writer.uint32(32).int32(message.outcome);
|
|
511
|
+
}
|
|
512
|
+
if (message.latencyMs !== void 0 && message.latencyMs !== 0) {
|
|
513
|
+
writer.uint32(41).double(message.latencyMs);
|
|
514
|
+
}
|
|
515
|
+
return writer;
|
|
516
|
+
},
|
|
517
|
+
decode(input, length) {
|
|
518
|
+
const reader = input instanceof BinaryReader ? input : new BinaryReader(input);
|
|
519
|
+
const end = length === void 0 ? reader.len : reader.pos + length;
|
|
520
|
+
const message = createBaseBidderOutcomeEntry();
|
|
521
|
+
while (reader.pos < end) {
|
|
522
|
+
const tag = reader.uint32();
|
|
523
|
+
switch (tag >>> 3) {
|
|
524
|
+
case 1: {
|
|
525
|
+
if (tag !== 10) {
|
|
526
|
+
break;
|
|
527
|
+
}
|
|
528
|
+
message.bidder = reader.string();
|
|
529
|
+
continue;
|
|
530
|
+
}
|
|
531
|
+
case 2: {
|
|
532
|
+
if (tag !== 18) {
|
|
533
|
+
break;
|
|
534
|
+
}
|
|
535
|
+
message.adUnitCode = reader.string();
|
|
536
|
+
continue;
|
|
537
|
+
}
|
|
538
|
+
case 3: {
|
|
539
|
+
if (tag !== 26) {
|
|
540
|
+
break;
|
|
541
|
+
}
|
|
542
|
+
message.mediaType = reader.string();
|
|
543
|
+
continue;
|
|
544
|
+
}
|
|
545
|
+
case 4: {
|
|
546
|
+
if (tag !== 32) {
|
|
547
|
+
break;
|
|
548
|
+
}
|
|
549
|
+
message.outcome = reader.int32();
|
|
550
|
+
continue;
|
|
551
|
+
}
|
|
552
|
+
case 5: {
|
|
553
|
+
if (tag !== 41) {
|
|
554
|
+
break;
|
|
555
|
+
}
|
|
556
|
+
message.latencyMs = reader.double();
|
|
557
|
+
continue;
|
|
558
|
+
}
|
|
559
|
+
}
|
|
560
|
+
if ((tag & 7) === 4 || tag === 0) {
|
|
561
|
+
break;
|
|
562
|
+
}
|
|
563
|
+
reader.skip(tag & 7);
|
|
564
|
+
}
|
|
565
|
+
return message;
|
|
566
|
+
},
|
|
567
|
+
create(base) {
|
|
568
|
+
return BidderOutcomeEntry.fromPartial(base ?? {});
|
|
569
|
+
},
|
|
570
|
+
fromPartial(object) {
|
|
571
|
+
const message = createBaseBidderOutcomeEntry();
|
|
572
|
+
message.bidder = object.bidder ?? "";
|
|
573
|
+
message.adUnitCode = object.adUnitCode ?? "";
|
|
574
|
+
message.mediaType = object.mediaType ?? "";
|
|
575
|
+
message.outcome = object.outcome ?? 0;
|
|
576
|
+
message.latencyMs = object.latencyMs ?? 0;
|
|
577
|
+
return message;
|
|
578
|
+
}
|
|
579
|
+
};
|
|
471
580
|
function createBaseBidTrace() {
|
|
472
581
|
return {
|
|
473
582
|
bidder: "",
|
|
@@ -628,6 +737,8 @@ var MAX_QUEUE_SIZE = 200;
|
|
|
628
737
|
var MAX_SEND_BACKOFF_MS = 5 * 60 * 1e3;
|
|
629
738
|
var MAX_CONSECUTIVE_SEND_FAILURES = 10;
|
|
630
739
|
var MAX_PAYLOAD_BYTES = 32 * 1024;
|
|
740
|
+
var MAX_METADATA_VALUE_CHARS = 1024;
|
|
741
|
+
var MAX_METADATA_ENTRIES = 16;
|
|
631
742
|
var SAFE_CONTENT_TYPE = "text/plain";
|
|
632
743
|
var PENDING_BATCH_KEY_PREFIX = "_bidkernel_pending_";
|
|
633
744
|
var MAX_PENDING_BATCHES = 20;
|
|
@@ -636,11 +747,8 @@ var PENDING_BATCH_CLEANUP_DELAY_MS = 1e4;
|
|
|
636
747
|
var EVENT_NAME_TO_TYPE = {
|
|
637
748
|
auctionStart: TraceEventType.AUCTION_START,
|
|
638
749
|
auctionEnd: TraceEventType.AUCTION_END,
|
|
639
|
-
bidRequest: TraceEventType.BID_REQUEST,
|
|
640
750
|
bidResponse: TraceEventType.BID_RESPONSE,
|
|
641
|
-
bidTimeout: TraceEventType.BID_TIMEOUT,
|
|
642
751
|
bidWin: TraceEventType.BID_WIN,
|
|
643
|
-
noBid: TraceEventType.NO_BID,
|
|
644
752
|
adRenderFailed: TraceEventType.AD_RENDER_FAILED,
|
|
645
753
|
click: TraceEventType.CLICK,
|
|
646
754
|
impression: TraceEventType.IMPRESSION,
|
|
@@ -653,6 +761,10 @@ var IMMEDIATE_FLUSH_TYPES = /* @__PURE__ */ new Set([
|
|
|
653
761
|
TraceEventType.BID_WIN,
|
|
654
762
|
TraceEventType.CLICK
|
|
655
763
|
]);
|
|
764
|
+
var CACHED_BID_TTL_MS = 30 * 60 * 1e3;
|
|
765
|
+
var MAX_CACHED_BID_KEYS = 200;
|
|
766
|
+
var MAX_IMPRESSION_KEYS = 1e3;
|
|
767
|
+
var MAX_TRACKED_AUCTIONS = 50;
|
|
656
768
|
var SESSION_KEY = "_bidkernel_session";
|
|
657
769
|
var SESSION_TS_KEY = "_bidkernel_session_ts";
|
|
658
770
|
var THIRTY_MINUTES_MS = 30 * 60 * 1e3;
|
|
@@ -684,6 +796,46 @@ function base64ToBytes(b64) {
|
|
|
684
796
|
}
|
|
685
797
|
return bytes;
|
|
686
798
|
}
|
|
799
|
+
function isTrustedEndpoint(raw) {
|
|
800
|
+
if (!raw) return false;
|
|
801
|
+
let url;
|
|
802
|
+
try {
|
|
803
|
+
url = new URL(raw);
|
|
804
|
+
} catch {
|
|
805
|
+
return false;
|
|
806
|
+
}
|
|
807
|
+
if (url.username || url.password) return false;
|
|
808
|
+
if (url.protocol === "https:") return true;
|
|
809
|
+
if (url.protocol === "http:") {
|
|
810
|
+
return url.hostname === "localhost" || url.hostname === "127.0.0.1" || url.hostname === "[::1]";
|
|
811
|
+
}
|
|
812
|
+
return false;
|
|
813
|
+
}
|
|
814
|
+
function boundMetadata(metadata) {
|
|
815
|
+
const bounded = {};
|
|
816
|
+
let count = 0;
|
|
817
|
+
for (const key of Object.keys(metadata)) {
|
|
818
|
+
if (count >= MAX_METADATA_ENTRIES) break;
|
|
819
|
+
const value = metadata[key];
|
|
820
|
+
if (value === void 0 || value === null) continue;
|
|
821
|
+
const str = String(value);
|
|
822
|
+
bounded[key] = str.length > MAX_METADATA_VALUE_CHARS ? `${str.slice(0, MAX_METADATA_VALUE_CHARS)}...[truncated]` : str;
|
|
823
|
+
count++;
|
|
824
|
+
}
|
|
825
|
+
return bounded;
|
|
826
|
+
}
|
|
827
|
+
function isLegacyPendingKey(key) {
|
|
828
|
+
const parts = key.slice(PENDING_BATCH_KEY_PREFIX.length).split("_");
|
|
829
|
+
return parts.length === 2 && /^\d+$/.test(parts[0]);
|
|
830
|
+
}
|
|
831
|
+
function sameEndpointOrigin(a, b) {
|
|
832
|
+
if (!a || !b) return false;
|
|
833
|
+
try {
|
|
834
|
+
return new URL(a).origin === new URL(b).origin;
|
|
835
|
+
} catch {
|
|
836
|
+
return false;
|
|
837
|
+
}
|
|
838
|
+
}
|
|
687
839
|
function extendSession() {
|
|
688
840
|
const now = Date.now();
|
|
689
841
|
inMemorySessionTs = now;
|
|
@@ -800,22 +952,6 @@ var PrebidEventDeduper = class {
|
|
|
800
952
|
return false;
|
|
801
953
|
}
|
|
802
954
|
};
|
|
803
|
-
function parseSize(raw) {
|
|
804
|
-
if (!raw) return { width: 0, height: 0 };
|
|
805
|
-
let cur = raw;
|
|
806
|
-
while (Array.isArray(cur) && cur.length > 0 && Array.isArray(cur[0])) {
|
|
807
|
-
cur = cur[0];
|
|
808
|
-
}
|
|
809
|
-
if (Array.isArray(cur) && cur.length >= 2) {
|
|
810
|
-
const w = Number(cur[0]);
|
|
811
|
-
const h = Number(cur[1]);
|
|
812
|
-
return {
|
|
813
|
-
width: Number.isFinite(w) ? w : 0,
|
|
814
|
-
height: Number.isFinite(h) ? h : 0
|
|
815
|
-
};
|
|
816
|
-
}
|
|
817
|
-
return { width: 0, height: 0 };
|
|
818
|
-
}
|
|
819
955
|
function parseBidDimensions(bid) {
|
|
820
956
|
if (Number.isFinite(bid?.width) && Number.isFinite(bid?.height)) {
|
|
821
957
|
return { width: bid.width, height: bid.height };
|
|
@@ -831,8 +967,264 @@ function parseBidDimensions(bid) {
|
|
|
831
967
|
height: Number.isFinite(bid?.height) ? bid.height : 0
|
|
832
968
|
};
|
|
833
969
|
}
|
|
970
|
+
var adsLoaderListenerMap = /* @__PURE__ */ new WeakMap();
|
|
971
|
+
function hookAdsManagerLoadedEvent(loadedEventCtor) {
|
|
972
|
+
if (!loadedEventCtor) return;
|
|
973
|
+
try {
|
|
974
|
+
const loadedProto = loadedEventCtor.prototype;
|
|
975
|
+
if (loadedProto && typeof loadedProto.getAdsManager === "function" && !loadedProto.getAdsManager.__bidkernelHooked) {
|
|
976
|
+
const originalGetAdsManager = loadedProto.getAdsManager;
|
|
977
|
+
const hookedGetAdsManager = function(...args) {
|
|
978
|
+
const adsManager = originalGetAdsManager.apply(this, args);
|
|
979
|
+
if (adsManager) {
|
|
980
|
+
for (const instance of BidkernelPrebidAnalytics.getActiveInstances()) {
|
|
981
|
+
try {
|
|
982
|
+
instance.attachImaAdsManager(adsManager);
|
|
983
|
+
} catch {
|
|
984
|
+
}
|
|
985
|
+
}
|
|
986
|
+
}
|
|
987
|
+
return adsManager;
|
|
988
|
+
};
|
|
989
|
+
hookedGetAdsManager.__bidkernelHooked = true;
|
|
990
|
+
loadedProto.getAdsManager = hookedGetAdsManager;
|
|
991
|
+
}
|
|
992
|
+
} catch {
|
|
993
|
+
}
|
|
994
|
+
}
|
|
995
|
+
function hookAdsManagerPrototype(adsManagerCtorOrProto) {
|
|
996
|
+
if (!adsManagerCtorOrProto) return;
|
|
997
|
+
try {
|
|
998
|
+
const proto = adsManagerCtorOrProto.prototype || adsManagerCtorOrProto;
|
|
999
|
+
if (proto && typeof proto.init === "function" && !proto.init.__bidkernelHooked) {
|
|
1000
|
+
const origInit = proto.init;
|
|
1001
|
+
const hookedInit = function(...args) {
|
|
1002
|
+
for (const instance of BidkernelPrebidAnalytics.getActiveInstances()) {
|
|
1003
|
+
try {
|
|
1004
|
+
instance.attachImaAdsManager(this);
|
|
1005
|
+
} catch {
|
|
1006
|
+
}
|
|
1007
|
+
}
|
|
1008
|
+
return origInit.apply(this, args);
|
|
1009
|
+
};
|
|
1010
|
+
hookedInit.__bidkernelHooked = true;
|
|
1011
|
+
proto.init = hookedInit;
|
|
1012
|
+
}
|
|
1013
|
+
if (proto && typeof proto.start === "function" && !proto.start.__bidkernelHooked) {
|
|
1014
|
+
const origStart = proto.start;
|
|
1015
|
+
const hookedStart = function(...args) {
|
|
1016
|
+
for (const instance of BidkernelPrebidAnalytics.getActiveInstances()) {
|
|
1017
|
+
try {
|
|
1018
|
+
instance.attachImaAdsManager(this);
|
|
1019
|
+
} catch {
|
|
1020
|
+
}
|
|
1021
|
+
}
|
|
1022
|
+
return origStart.apply(this, args);
|
|
1023
|
+
};
|
|
1024
|
+
hookedStart.__bidkernelHooked = true;
|
|
1025
|
+
proto.start = hookedStart;
|
|
1026
|
+
}
|
|
1027
|
+
} catch {
|
|
1028
|
+
}
|
|
1029
|
+
}
|
|
1030
|
+
function hookAdsLoader(adsLoaderCtor) {
|
|
1031
|
+
if (!adsLoaderCtor) return;
|
|
1032
|
+
try {
|
|
1033
|
+
const proto = adsLoaderCtor.prototype;
|
|
1034
|
+
if (!proto) return;
|
|
1035
|
+
if (typeof proto.addEventListener === "function" && !proto.addEventListener.__bidkernelHooked) {
|
|
1036
|
+
const origAddEventListener = proto.addEventListener;
|
|
1037
|
+
const hookedAddEventListener = function(type, listener, ...rest) {
|
|
1038
|
+
if ((type === "adsManagerLoaded" || type === (this?.AdsManagerLoadedEvent?.Type?.ADS_MANAGER_LOADED || "adsManagerLoaded")) && typeof listener === "function") {
|
|
1039
|
+
let wrappedListener = adsLoaderListenerMap.get(listener);
|
|
1040
|
+
if (!wrappedListener) {
|
|
1041
|
+
wrappedListener = function(event) {
|
|
1042
|
+
if (event && typeof event.getAdsManager === "function" && !event.getAdsManager.__bidkernelHooked) {
|
|
1043
|
+
const origGetAdsManager = event.getAdsManager;
|
|
1044
|
+
event.getAdsManager = function(...args) {
|
|
1045
|
+
const adsManager = origGetAdsManager.apply(this, args);
|
|
1046
|
+
if (adsManager) {
|
|
1047
|
+
for (const sdk of BidkernelPrebidAnalytics.getActiveInstances()) {
|
|
1048
|
+
try {
|
|
1049
|
+
sdk.attachImaAdsManager(adsManager);
|
|
1050
|
+
} catch {
|
|
1051
|
+
}
|
|
1052
|
+
}
|
|
1053
|
+
}
|
|
1054
|
+
return adsManager;
|
|
1055
|
+
};
|
|
1056
|
+
event.getAdsManager.__bidkernelHooked = true;
|
|
1057
|
+
}
|
|
1058
|
+
return listener.apply(this, arguments);
|
|
1059
|
+
};
|
|
1060
|
+
adsLoaderListenerMap.set(listener, wrappedListener);
|
|
1061
|
+
}
|
|
1062
|
+
return origAddEventListener.call(this, type, wrappedListener, ...rest);
|
|
1063
|
+
}
|
|
1064
|
+
return origAddEventListener.call(this, type, listener, ...rest);
|
|
1065
|
+
};
|
|
1066
|
+
hookedAddEventListener.__bidkernelHooked = true;
|
|
1067
|
+
proto.addEventListener = hookedAddEventListener;
|
|
1068
|
+
}
|
|
1069
|
+
if (typeof proto.removeEventListener === "function" && !proto.removeEventListener.__bidkernelHooked) {
|
|
1070
|
+
const origRemoveEventListener = proto.removeEventListener;
|
|
1071
|
+
const hookedRemoveEventListener = function(type, listener, ...rest) {
|
|
1072
|
+
const wrapped = typeof listener === "function" ? adsLoaderListenerMap.get(listener) : void 0;
|
|
1073
|
+
return origRemoveEventListener.call(this, type, wrapped || listener, ...rest);
|
|
1074
|
+
};
|
|
1075
|
+
hookedRemoveEventListener.__bidkernelHooked = true;
|
|
1076
|
+
proto.removeEventListener = hookedRemoveEventListener;
|
|
1077
|
+
}
|
|
1078
|
+
} catch {
|
|
1079
|
+
}
|
|
1080
|
+
}
|
|
1081
|
+
function hookImaPrototype(ima) {
|
|
1082
|
+
if (!ima || typeof ima !== "object") return;
|
|
1083
|
+
try {
|
|
1084
|
+
if (ima.AdsManagerLoadedEvent) {
|
|
1085
|
+
hookAdsManagerLoadedEvent(ima.AdsManagerLoadedEvent);
|
|
1086
|
+
}
|
|
1087
|
+
const loadedDesc = Object.getOwnPropertyDescriptor(ima, "AdsManagerLoadedEvent");
|
|
1088
|
+
if (!loadedDesc || loadedDesc.configurable) {
|
|
1089
|
+
let _loadedEvent = ima.AdsManagerLoadedEvent;
|
|
1090
|
+
try {
|
|
1091
|
+
Object.defineProperty(ima, "AdsManagerLoadedEvent", {
|
|
1092
|
+
configurable: true,
|
|
1093
|
+
enumerable: true,
|
|
1094
|
+
get() {
|
|
1095
|
+
return _loadedEvent;
|
|
1096
|
+
},
|
|
1097
|
+
set(val) {
|
|
1098
|
+
_loadedEvent = val;
|
|
1099
|
+
hookAdsManagerLoadedEvent(val);
|
|
1100
|
+
}
|
|
1101
|
+
});
|
|
1102
|
+
} catch {
|
|
1103
|
+
}
|
|
1104
|
+
}
|
|
1105
|
+
if (ima.AdsLoader) {
|
|
1106
|
+
hookAdsLoader(ima.AdsLoader);
|
|
1107
|
+
}
|
|
1108
|
+
const loaderDesc = Object.getOwnPropertyDescriptor(ima, "AdsLoader");
|
|
1109
|
+
if (!loaderDesc || loaderDesc.configurable) {
|
|
1110
|
+
let _loader = ima.AdsLoader;
|
|
1111
|
+
try {
|
|
1112
|
+
Object.defineProperty(ima, "AdsLoader", {
|
|
1113
|
+
configurable: true,
|
|
1114
|
+
enumerable: true,
|
|
1115
|
+
get() {
|
|
1116
|
+
return _loader;
|
|
1117
|
+
},
|
|
1118
|
+
set(val) {
|
|
1119
|
+
_loader = val;
|
|
1120
|
+
hookAdsLoader(val);
|
|
1121
|
+
}
|
|
1122
|
+
});
|
|
1123
|
+
} catch {
|
|
1124
|
+
}
|
|
1125
|
+
}
|
|
1126
|
+
if (ima.AdsManager) {
|
|
1127
|
+
hookAdsManagerPrototype(ima.AdsManager);
|
|
1128
|
+
}
|
|
1129
|
+
const mgrDesc = Object.getOwnPropertyDescriptor(ima, "AdsManager");
|
|
1130
|
+
if (!mgrDesc || mgrDesc.configurable) {
|
|
1131
|
+
let _mgr = ima.AdsManager;
|
|
1132
|
+
try {
|
|
1133
|
+
Object.defineProperty(ima, "AdsManager", {
|
|
1134
|
+
configurable: true,
|
|
1135
|
+
enumerable: true,
|
|
1136
|
+
get() {
|
|
1137
|
+
return _mgr;
|
|
1138
|
+
},
|
|
1139
|
+
set(val) {
|
|
1140
|
+
_mgr = val;
|
|
1141
|
+
hookAdsManagerPrototype(val);
|
|
1142
|
+
}
|
|
1143
|
+
});
|
|
1144
|
+
} catch {
|
|
1145
|
+
}
|
|
1146
|
+
}
|
|
1147
|
+
} catch {
|
|
1148
|
+
}
|
|
1149
|
+
}
|
|
1150
|
+
function initImaInterception() {
|
|
1151
|
+
if (typeof window === "undefined") return;
|
|
1152
|
+
const win = window;
|
|
1153
|
+
if (win.google?.ima) {
|
|
1154
|
+
hookImaPrototype(win.google.ima);
|
|
1155
|
+
}
|
|
1156
|
+
if (win.google && typeof win.google === "object") {
|
|
1157
|
+
const imaDesc = Object.getOwnPropertyDescriptor(win.google, "ima");
|
|
1158
|
+
if (!imaDesc || imaDesc.configurable) {
|
|
1159
|
+
let _ima = win.google.ima;
|
|
1160
|
+
try {
|
|
1161
|
+
Object.defineProperty(win.google, "ima", {
|
|
1162
|
+
configurable: true,
|
|
1163
|
+
enumerable: true,
|
|
1164
|
+
get() {
|
|
1165
|
+
return _ima;
|
|
1166
|
+
},
|
|
1167
|
+
set(val) {
|
|
1168
|
+
_ima = val;
|
|
1169
|
+
hookImaPrototype(val);
|
|
1170
|
+
}
|
|
1171
|
+
});
|
|
1172
|
+
} catch {
|
|
1173
|
+
}
|
|
1174
|
+
}
|
|
1175
|
+
}
|
|
1176
|
+
const googleDesc = Object.getOwnPropertyDescriptor(win, "google");
|
|
1177
|
+
if (!googleDesc || googleDesc.configurable) {
|
|
1178
|
+
let _google = win.google;
|
|
1179
|
+
try {
|
|
1180
|
+
Object.defineProperty(win, "google", {
|
|
1181
|
+
configurable: true,
|
|
1182
|
+
enumerable: true,
|
|
1183
|
+
get() {
|
|
1184
|
+
return _google;
|
|
1185
|
+
},
|
|
1186
|
+
set(val) {
|
|
1187
|
+
_google = val;
|
|
1188
|
+
if (_google && typeof _google === "object") {
|
|
1189
|
+
if (_google.ima) {
|
|
1190
|
+
hookImaPrototype(_google.ima);
|
|
1191
|
+
}
|
|
1192
|
+
const iDesc = Object.getOwnPropertyDescriptor(_google, "ima");
|
|
1193
|
+
if (!iDesc || iDesc.configurable) {
|
|
1194
|
+
let _i = _google.ima;
|
|
1195
|
+
try {
|
|
1196
|
+
Object.defineProperty(_google, "ima", {
|
|
1197
|
+
configurable: true,
|
|
1198
|
+
enumerable: true,
|
|
1199
|
+
get() {
|
|
1200
|
+
return _i;
|
|
1201
|
+
},
|
|
1202
|
+
set(iv) {
|
|
1203
|
+
_i = iv;
|
|
1204
|
+
hookImaPrototype(iv);
|
|
1205
|
+
}
|
|
1206
|
+
});
|
|
1207
|
+
} catch {
|
|
1208
|
+
}
|
|
1209
|
+
}
|
|
1210
|
+
}
|
|
1211
|
+
}
|
|
1212
|
+
});
|
|
1213
|
+
} catch {
|
|
1214
|
+
}
|
|
1215
|
+
}
|
|
1216
|
+
}
|
|
1217
|
+
if (typeof window !== "undefined") {
|
|
1218
|
+
initImaInterception();
|
|
1219
|
+
}
|
|
834
1220
|
var BidkernelPrebidAnalytics = class _BidkernelPrebidAnalytics {
|
|
835
1221
|
static activeInstances = /* @__PURE__ */ new Set();
|
|
1222
|
+
static getActiveInstances() {
|
|
1223
|
+
return _BidkernelPrebidAnalytics.activeInstances;
|
|
1224
|
+
}
|
|
1225
|
+
static initImaInterception() {
|
|
1226
|
+
initImaInterception();
|
|
1227
|
+
}
|
|
836
1228
|
config;
|
|
837
1229
|
queue = [];
|
|
838
1230
|
errorCount = 0;
|
|
@@ -867,9 +1259,13 @@ var BidkernelPrebidAnalytics = class _BidkernelPrebidAnalytics {
|
|
|
867
1259
|
cachedWinningBids = /* @__PURE__ */ new Map();
|
|
868
1260
|
// Active video player attachment cleanup routines
|
|
869
1261
|
videoDetachCleanups = /* @__PURE__ */ new Set();
|
|
1262
|
+
// Compacted bidder participation map per auction: auctionId -> Map<`${bidder}:${adUnitCode}`, BidderOutcomeEntry>
|
|
1263
|
+
auctionBidderOutcomes = /* @__PURE__ */ new Map();
|
|
870
1264
|
constructor(config) {
|
|
1265
|
+
const requestedEndpoint = config.endpoint || "";
|
|
1266
|
+
const endpoint = !requestedEndpoint || isTrustedEndpoint(requestedEndpoint) ? requestedEndpoint : "";
|
|
871
1267
|
this.config = {
|
|
872
|
-
endpoint
|
|
1268
|
+
endpoint,
|
|
873
1269
|
propertyId: config.propertyId || "",
|
|
874
1270
|
pageviewId: config.pageviewId || generateUUID(),
|
|
875
1271
|
sessionId: config.sessionId || getOrCreateSessionId(),
|
|
@@ -885,6 +1281,12 @@ var BidkernelPrebidAnalytics = class _BidkernelPrebidAnalytics {
|
|
|
885
1281
|
pbjsGlobalName: config.pbjsGlobalName || "pbjs",
|
|
886
1282
|
attachPbjsListeners: config.attachPbjsListeners ?? true
|
|
887
1283
|
};
|
|
1284
|
+
if (requestedEndpoint && !endpoint) {
|
|
1285
|
+
this.log(
|
|
1286
|
+
"ERROR",
|
|
1287
|
+
`Rejected untrusted analytics endpoint ${requestedEndpoint}: must be an absolute https:// URL without embedded credentials. Events will not be transmitted.`
|
|
1288
|
+
);
|
|
1289
|
+
}
|
|
888
1290
|
this.boundFlushBeacon = () => {
|
|
889
1291
|
this.flushAllSlotsTimeInView();
|
|
890
1292
|
this.flushBeacon();
|
|
@@ -986,6 +1388,10 @@ var BidkernelPrebidAnalytics = class _BidkernelPrebidAnalytics {
|
|
|
986
1388
|
}
|
|
987
1389
|
this.flushTimer = setInterval(() => this.flush(), FLUSH_INTERVAL_MS);
|
|
988
1390
|
this.resendPersistedBatches();
|
|
1391
|
+
initImaInterception();
|
|
1392
|
+
if (window.google?.ima) {
|
|
1393
|
+
hookImaPrototype(window.google.ima);
|
|
1394
|
+
}
|
|
989
1395
|
}
|
|
990
1396
|
}
|
|
991
1397
|
disable() {
|
|
@@ -1022,6 +1428,7 @@ var BidkernelPrebidAnalytics = class _BidkernelPrebidAnalytics {
|
|
|
1022
1428
|
this.cachedWinningBids.clear();
|
|
1023
1429
|
this.slotEmittedImpressionKeys.clear();
|
|
1024
1430
|
this.slotLastAuctionIds.clear();
|
|
1431
|
+
this.auctionBidderOutcomes.clear();
|
|
1025
1432
|
if (this.flushTimer) {
|
|
1026
1433
|
clearInterval(this.flushTimer);
|
|
1027
1434
|
this.flushTimer = null;
|
|
@@ -1425,7 +1832,139 @@ var BidkernelPrebidAnalytics = class _BidkernelPrebidAnalytics {
|
|
|
1425
1832
|
this.slotEmittedImpressionKeys.delete(key);
|
|
1426
1833
|
}
|
|
1427
1834
|
}
|
|
1428
|
-
this.cachedWinningBids.
|
|
1835
|
+
const cached = this.cachedWinningBids.get(slotId);
|
|
1836
|
+
if (cached) this.deleteCachedBidEntry(cached);
|
|
1837
|
+
}
|
|
1838
|
+
// --- Bounded caches -------------------------------------------------------
|
|
1839
|
+
/**
|
|
1840
|
+
* Reads a cached winning bid, treating an entry past CACHED_BID_TTL_MS as
|
|
1841
|
+
* absent and dropping it. Every read goes through here so a stale bid can
|
|
1842
|
+
* never be married to a much later render.
|
|
1843
|
+
*/
|
|
1844
|
+
getCachedBid(key) {
|
|
1845
|
+
const entry = this.cachedWinningBids.get(key);
|
|
1846
|
+
if (!entry) return void 0;
|
|
1847
|
+
if (Date.now() - entry.timestamp > CACHED_BID_TTL_MS) {
|
|
1848
|
+
this.deleteCachedBidEntry(entry);
|
|
1849
|
+
return void 0;
|
|
1850
|
+
}
|
|
1851
|
+
return entry;
|
|
1852
|
+
}
|
|
1853
|
+
/** Removes every alias pointing at one entry. Aliases are stored by identity. */
|
|
1854
|
+
deleteCachedBidEntry(entry) {
|
|
1855
|
+
for (const [key, value] of Array.from(this.cachedWinningBids)) {
|
|
1856
|
+
if (value === entry) this.cachedWinningBids.delete(key);
|
|
1857
|
+
}
|
|
1858
|
+
}
|
|
1859
|
+
/**
|
|
1860
|
+
* Drops expired entries, then evicts oldest-first until the key cap holds.
|
|
1861
|
+
* Map iterates in insertion order and one win's aliases are written
|
|
1862
|
+
* consecutively, so eviction takes a whole bid's aliases together.
|
|
1863
|
+
*/
|
|
1864
|
+
pruneCachedWinningBids() {
|
|
1865
|
+
const now = Date.now();
|
|
1866
|
+
for (const [key, entry] of Array.from(this.cachedWinningBids)) {
|
|
1867
|
+
if (now - entry.timestamp > CACHED_BID_TTL_MS) this.cachedWinningBids.delete(key);
|
|
1868
|
+
}
|
|
1869
|
+
while (this.cachedWinningBids.size > MAX_CACHED_BID_KEYS) {
|
|
1870
|
+
const oldest = this.cachedWinningBids.keys().next();
|
|
1871
|
+
if (oldest.done) break;
|
|
1872
|
+
this.cachedWinningBids.delete(oldest.value);
|
|
1873
|
+
}
|
|
1874
|
+
}
|
|
1875
|
+
/**
|
|
1876
|
+
* Searches cached winning bids for an entry matching the given filters (creativeId,
|
|
1877
|
+
* adId, or mediaType), falling back to the most recent winning video bid.
|
|
1878
|
+
*/
|
|
1879
|
+
findCachedWinningBid(filter) {
|
|
1880
|
+
const now = Date.now();
|
|
1881
|
+
const isConsumed = (entry) => {
|
|
1882
|
+
return this.hasImpressionEmitted(
|
|
1883
|
+
entry.adUnitCode,
|
|
1884
|
+
void 0,
|
|
1885
|
+
entry.auctionId,
|
|
1886
|
+
entry.bidTrace.creativeId
|
|
1887
|
+
);
|
|
1888
|
+
};
|
|
1889
|
+
if (filter?.creativeId || filter?.adId) {
|
|
1890
|
+
for (const entry of Array.from(this.cachedWinningBids.values())) {
|
|
1891
|
+
if (now - entry.timestamp > CACHED_BID_TTL_MS) continue;
|
|
1892
|
+
if (filter.creativeId && (entry.bidTrace.creativeId === filter.creativeId || entry.rawBid?.creativeId === filter.creativeId) || filter.adId && (entry.rawBid?.adId === filter.adId || entry.adUnitCode === filter.adId)) {
|
|
1893
|
+
return entry;
|
|
1894
|
+
}
|
|
1895
|
+
}
|
|
1896
|
+
}
|
|
1897
|
+
let bestUnconsumedMatch;
|
|
1898
|
+
if (filter?.mediaType) {
|
|
1899
|
+
for (const entry of Array.from(this.cachedWinningBids.values())) {
|
|
1900
|
+
if (now - entry.timestamp > CACHED_BID_TTL_MS) continue;
|
|
1901
|
+
const isEntryVideo = entry.bidTrace.mediaType === filter.mediaType || entry.rawBid?.mediaType === filter.mediaType || filter.mediaType === "video" && entry.rawBid?.mediaTypes?.video !== void 0;
|
|
1902
|
+
if (isEntryVideo) {
|
|
1903
|
+
if (!isConsumed(entry)) {
|
|
1904
|
+
if (!bestUnconsumedMatch || entry.timestamp < bestUnconsumedMatch.timestamp) {
|
|
1905
|
+
bestUnconsumedMatch = entry;
|
|
1906
|
+
}
|
|
1907
|
+
}
|
|
1908
|
+
}
|
|
1909
|
+
}
|
|
1910
|
+
if (bestUnconsumedMatch) return bestUnconsumedMatch;
|
|
1911
|
+
let bestFallbackMatch;
|
|
1912
|
+
for (const entry of Array.from(this.cachedWinningBids.values())) {
|
|
1913
|
+
if (now - entry.timestamp > CACHED_BID_TTL_MS) continue;
|
|
1914
|
+
const isEntryVideo = entry.bidTrace.mediaType === filter.mediaType || entry.rawBid?.mediaType === filter.mediaType || filter.mediaType === "video" && entry.rawBid?.mediaTypes?.video !== void 0;
|
|
1915
|
+
if (isEntryVideo) {
|
|
1916
|
+
if (!bestFallbackMatch || entry.timestamp > bestFallbackMatch.timestamp) {
|
|
1917
|
+
bestFallbackMatch = entry;
|
|
1918
|
+
}
|
|
1919
|
+
}
|
|
1920
|
+
}
|
|
1921
|
+
if (bestFallbackMatch) return bestFallbackMatch;
|
|
1922
|
+
}
|
|
1923
|
+
for (const entry of Array.from(this.cachedWinningBids.values())) {
|
|
1924
|
+
if (now - entry.timestamp > CACHED_BID_TTL_MS) continue;
|
|
1925
|
+
if (!isConsumed(entry)) {
|
|
1926
|
+
if (!bestUnconsumedMatch || entry.timestamp > bestUnconsumedMatch.timestamp) {
|
|
1927
|
+
bestUnconsumedMatch = entry;
|
|
1928
|
+
}
|
|
1929
|
+
}
|
|
1930
|
+
}
|
|
1931
|
+
if (bestUnconsumedMatch) return bestUnconsumedMatch;
|
|
1932
|
+
let bestRecent;
|
|
1933
|
+
for (const entry of Array.from(this.cachedWinningBids.values())) {
|
|
1934
|
+
if (now - entry.timestamp > CACHED_BID_TTL_MS) continue;
|
|
1935
|
+
if (!bestRecent || entry.timestamp > bestRecent.timestamp) {
|
|
1936
|
+
bestRecent = entry;
|
|
1937
|
+
}
|
|
1938
|
+
}
|
|
1939
|
+
return bestRecent;
|
|
1940
|
+
}
|
|
1941
|
+
/** Records a dedup key, evicting oldest-first at the cap. */
|
|
1942
|
+
addImpressionKey(key) {
|
|
1943
|
+
if (this.slotEmittedImpressionKeys.has(key)) return;
|
|
1944
|
+
while (this.slotEmittedImpressionKeys.size >= MAX_IMPRESSION_KEYS) {
|
|
1945
|
+
const oldest = this.slotEmittedImpressionKeys.values().next();
|
|
1946
|
+
if (oldest.done) break;
|
|
1947
|
+
this.slotEmittedImpressionKeys.delete(oldest.value);
|
|
1948
|
+
}
|
|
1949
|
+
this.slotEmittedImpressionKeys.add(key);
|
|
1950
|
+
}
|
|
1951
|
+
/**
|
|
1952
|
+
* The bidder-outcome map for an auction, creating it if absent. Evicts the
|
|
1953
|
+
* oldest auction at the cap: without this, any auction whose auctionEnd never
|
|
1954
|
+
* fires (abandoned, navigated away from mid-flight) leaks its map forever.
|
|
1955
|
+
*/
|
|
1956
|
+
getOrCreateAuctionOutcomes(auctionId) {
|
|
1957
|
+
let auctionMap = this.auctionBidderOutcomes.get(auctionId);
|
|
1958
|
+
if (!auctionMap) {
|
|
1959
|
+
auctionMap = /* @__PURE__ */ new Map();
|
|
1960
|
+
this.auctionBidderOutcomes.set(auctionId, auctionMap);
|
|
1961
|
+
}
|
|
1962
|
+
while (this.auctionBidderOutcomes.size > MAX_TRACKED_AUCTIONS) {
|
|
1963
|
+
const oldest = this.auctionBidderOutcomes.keys().next();
|
|
1964
|
+
if (oldest.done || oldest.value === auctionId) break;
|
|
1965
|
+
this.auctionBidderOutcomes.delete(oldest.value);
|
|
1966
|
+
}
|
|
1967
|
+
return auctionMap;
|
|
1429
1968
|
}
|
|
1430
1969
|
hasImpressionEmitted(slotId, refreshIndex, auctionId, creativeId) {
|
|
1431
1970
|
const rIndex = refreshIndex ?? this.slotRefreshIndices.get(slotId) ?? 0;
|
|
@@ -1445,14 +1984,14 @@ var BidkernelPrebidAnalytics = class _BidkernelPrebidAnalytics {
|
|
|
1445
1984
|
}
|
|
1446
1985
|
markImpressionEmitted(slotId, refreshIndex, auctionId, creativeId) {
|
|
1447
1986
|
const baseSlotKey = `${escapeKeyPart(slotId)}:${refreshIndex}`;
|
|
1448
|
-
this.
|
|
1987
|
+
this.addImpressionKey(baseSlotKey);
|
|
1449
1988
|
if (creativeId) {
|
|
1450
|
-
this.
|
|
1989
|
+
this.addImpressionKey(`${baseSlotKey}:${escapeKeyPart(creativeId)}`);
|
|
1451
1990
|
}
|
|
1452
1991
|
if (auctionId) {
|
|
1453
|
-
this.
|
|
1992
|
+
this.addImpressionKey(`${baseSlotKey}:auc:${escapeKeyPart(auctionId)}`);
|
|
1454
1993
|
if (creativeId) {
|
|
1455
|
-
this.
|
|
1994
|
+
this.addImpressionKey(
|
|
1456
1995
|
`${baseSlotKey}:auc:${escapeKeyPart(auctionId)}:${escapeKeyPart(creativeId)}`
|
|
1457
1996
|
);
|
|
1458
1997
|
}
|
|
@@ -1462,7 +2001,7 @@ var BidkernelPrebidAnalytics = class _BidkernelPrebidAnalytics {
|
|
|
1462
2001
|
if (!this.isEnabled) return false;
|
|
1463
2002
|
const resolvedSlotId = slotId || options?.adUnitCode || "";
|
|
1464
2003
|
const adUnitCode = options?.adUnitCode || resolvedSlotId;
|
|
1465
|
-
const cached = (options?.auctionId && resolvedSlotId ? this.
|
|
2004
|
+
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);
|
|
1466
2005
|
const rawBid = options?.bid || cached?.rawBid || {};
|
|
1467
2006
|
const auctionId = options?.auctionId || rawBid.auctionId || cached?.auctionId || "";
|
|
1468
2007
|
const transactionId = options?.transactionId || rawBid.transactionId || cached?.transactionId || "";
|
|
@@ -1558,14 +2097,40 @@ var BidkernelPrebidAnalytics = class _BidkernelPrebidAnalytics {
|
|
|
1558
2097
|
return () => {
|
|
1559
2098
|
};
|
|
1560
2099
|
}
|
|
2100
|
+
if (!adsManager.__bidkernelAttachedInstances) {
|
|
2101
|
+
try {
|
|
2102
|
+
Object.defineProperty(adsManager, "__bidkernelAttachedInstances", {
|
|
2103
|
+
value: /* @__PURE__ */ new Set(),
|
|
2104
|
+
configurable: true,
|
|
2105
|
+
writable: true
|
|
2106
|
+
});
|
|
2107
|
+
} catch {
|
|
2108
|
+
adsManager.__bidkernelAttachedInstances = /* @__PURE__ */ new Set();
|
|
2109
|
+
}
|
|
2110
|
+
}
|
|
2111
|
+
if (adsManager.__bidkernelAttachedInstances.has(this)) {
|
|
2112
|
+
return () => {
|
|
2113
|
+
};
|
|
2114
|
+
}
|
|
2115
|
+
adsManager.__bidkernelAttachedInstances.add(this);
|
|
1561
2116
|
const slotId = options?.slotId || options?.adUnitCode || "video";
|
|
1562
2117
|
const adUnitCode = options?.adUnitCode || slotId;
|
|
1563
2118
|
const auctionId = options?.auctionId || "";
|
|
1564
2119
|
const transactionId = options?.transactionId || "";
|
|
1565
|
-
const getWinningBid = () => {
|
|
1566
|
-
|
|
2120
|
+
const getWinningBid = (adData) => {
|
|
2121
|
+
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);
|
|
2122
|
+
if (!cached) {
|
|
2123
|
+
cached = this.findCachedWinningBid({
|
|
2124
|
+
creativeId: adData?.creativeId,
|
|
2125
|
+
adId: adData?.adId,
|
|
2126
|
+
mediaType: "video"
|
|
2127
|
+
});
|
|
2128
|
+
}
|
|
2129
|
+
return cached;
|
|
1567
2130
|
};
|
|
2131
|
+
let adStarted = false;
|
|
1568
2132
|
const onAdStartedOrImpression = (event) => {
|
|
2133
|
+
adStarted = true;
|
|
1569
2134
|
this.log("DEBUG", "IMA AdEvent.STARTED / IMPRESSION received", event);
|
|
1570
2135
|
const ad = typeof event?.getAd === "function" ? event.getAd() : event?.ad;
|
|
1571
2136
|
const adData = {};
|
|
@@ -1576,16 +2141,20 @@ var BidkernelPrebidAnalytics = class _BidkernelPrebidAnalytics {
|
|
|
1576
2141
|
adData.duration = typeof ad.getDuration === "function" ? ad.getDuration() : ad.duration;
|
|
1577
2142
|
adData.advertiserName = typeof ad.getAdvertiserName === "function" ? ad.getAdvertiserName() : "";
|
|
1578
2143
|
}
|
|
1579
|
-
const cached = getWinningBid();
|
|
2144
|
+
const cached = getWinningBid(adData);
|
|
2145
|
+
const resolvedSlotId = options?.slotId && options.slotId !== "video" ? options.slotId : options?.adUnitCode && options.adUnitCode !== "video" ? options.adUnitCode : cached?.adUnitCode || options?.slotId || options?.adUnitCode || "video";
|
|
2146
|
+
const resolvedAdUnitCode = options?.adUnitCode && options.adUnitCode !== "video" ? options.adUnitCode : cached?.adUnitCode || resolvedSlotId;
|
|
2147
|
+
const resolvedAuctionId = auctionId || cached?.auctionId || "";
|
|
2148
|
+
const resolvedTransactionId = transactionId || cached?.transactionId || "";
|
|
1580
2149
|
const mergedBid = {
|
|
1581
2150
|
...cached?.rawBid || options?.bid,
|
|
1582
2151
|
mediaType: "video",
|
|
1583
2152
|
creativeId: adData.creativeId || cached?.bidTrace?.creativeId || options?.bid?.creativeId || ""
|
|
1584
2153
|
};
|
|
1585
|
-
const emitted = this.recordImpression(
|
|
1586
|
-
adUnitCode,
|
|
1587
|
-
auctionId:
|
|
1588
|
-
transactionId:
|
|
2154
|
+
const emitted = this.recordImpression(resolvedSlotId, {
|
|
2155
|
+
adUnitCode: resolvedAdUnitCode,
|
|
2156
|
+
auctionId: resolvedAuctionId,
|
|
2157
|
+
transactionId: resolvedTransactionId,
|
|
1589
2158
|
mediaType: "video",
|
|
1590
2159
|
bid: mergedBid,
|
|
1591
2160
|
metadata: {
|
|
@@ -1597,7 +2166,7 @@ var BidkernelPrebidAnalytics = class _BidkernelPrebidAnalytics {
|
|
|
1597
2166
|
});
|
|
1598
2167
|
if (emitted && options?.onImpression) {
|
|
1599
2168
|
try {
|
|
1600
|
-
options.onImpression(
|
|
2169
|
+
options.onImpression(resolvedSlotId, { ad, bid: mergedBid });
|
|
1601
2170
|
} catch (e) {
|
|
1602
2171
|
this.log("ERROR", "Error in onImpression callback", e);
|
|
1603
2172
|
}
|
|
@@ -1616,10 +2185,11 @@ var BidkernelPrebidAnalytics = class _BidkernelPrebidAnalytics {
|
|
|
1616
2185
|
const onAdClick = (event) => {
|
|
1617
2186
|
this.log("DEBUG", "IMA AdEvent.CLICK received", event);
|
|
1618
2187
|
const cached = getWinningBid();
|
|
2188
|
+
const resolvedAdUnitCode = options?.adUnitCode && options.adUnitCode !== "video" ? options.adUnitCode : cached?.adUnitCode || slotId;
|
|
1619
2189
|
this.enqueue(TraceEventType.CLICK, "click", {
|
|
1620
2190
|
auctionId: auctionId || cached?.auctionId,
|
|
1621
2191
|
transactionId: transactionId || cached?.transactionId,
|
|
1622
|
-
adUnitCode,
|
|
2192
|
+
adUnitCode: resolvedAdUnitCode,
|
|
1623
2193
|
bid: cached?.bidTrace || options?.bid,
|
|
1624
2194
|
metadata: {
|
|
1625
2195
|
...options?.metadata,
|
|
@@ -1633,14 +2203,16 @@ var BidkernelPrebidAnalytics = class _BidkernelPrebidAnalytics {
|
|
|
1633
2203
|
const msg = (err && typeof err.getMessage === "function" ? err.getMessage() : err?.message) || String(err || "IMA ad error");
|
|
1634
2204
|
const code = (err && typeof err.getErrorCode === "function" ? err.getErrorCode() : err?.code) || "";
|
|
1635
2205
|
const cached = getWinningBid();
|
|
2206
|
+
const resolvedAdUnitCode = options?.adUnitCode && options.adUnitCode !== "video" ? options.adUnitCode : cached?.adUnitCode || slotId;
|
|
1636
2207
|
this.enqueue(TraceEventType.AD_RENDER_FAILED, "adRenderFailed", {
|
|
1637
2208
|
auctionId: auctionId || cached?.auctionId,
|
|
1638
2209
|
transactionId: transactionId || cached?.transactionId,
|
|
1639
|
-
adUnitCode,
|
|
2210
|
+
adUnitCode: resolvedAdUnitCode,
|
|
1640
2211
|
bid: cached?.bidTrace || options?.bid,
|
|
1641
2212
|
metadata: {
|
|
1642
2213
|
...options?.metadata,
|
|
1643
|
-
reason: "ima_ad_error",
|
|
2214
|
+
reason: adStarted ? "ima_playback_error" : "ima_ad_error",
|
|
2215
|
+
playback_phase: adStarted ? "post_start" : "pre_start",
|
|
1644
2216
|
message: msg,
|
|
1645
2217
|
...code ? { ima_error_code: String(code) } : {}
|
|
1646
2218
|
},
|
|
@@ -1657,7 +2229,7 @@ var BidkernelPrebidAnalytics = class _BidkernelPrebidAnalytics {
|
|
|
1657
2229
|
const googleIma = typeof window !== "undefined" ? window.google?.ima : void 0;
|
|
1658
2230
|
const adEventType = googleIma?.AdEvent?.Type || {};
|
|
1659
2231
|
const adErrorEventType = googleIma?.AdErrorEvent?.Type || {};
|
|
1660
|
-
const
|
|
2232
|
+
const rawListeners = [
|
|
1661
2233
|
{ type: adEventType.STARTED || "started", handler: onAdStartedOrImpression },
|
|
1662
2234
|
{ type: adEventType.IMPRESSION || "impression", handler: onAdStartedOrImpression },
|
|
1663
2235
|
{
|
|
@@ -1673,6 +2245,14 @@ var BidkernelPrebidAnalytics = class _BidkernelPrebidAnalytics {
|
|
|
1673
2245
|
{ type: adEventType.CLICK || "click", handler: onAdClick },
|
|
1674
2246
|
{ type: adErrorEventType.AD_ERROR || "adError", handler: onAdError }
|
|
1675
2247
|
];
|
|
2248
|
+
const seenListenerTypes = /* @__PURE__ */ new Set();
|
|
2249
|
+
const listeners = [];
|
|
2250
|
+
for (const l of rawListeners) {
|
|
2251
|
+
if (!seenListenerTypes.has(l.type)) {
|
|
2252
|
+
seenListenerTypes.add(l.type);
|
|
2253
|
+
listeners.push(l);
|
|
2254
|
+
}
|
|
2255
|
+
}
|
|
1676
2256
|
for (const { type, handler } of listeners) {
|
|
1677
2257
|
try {
|
|
1678
2258
|
adsManager.addEventListener(type, handler);
|
|
@@ -1680,6 +2260,7 @@ var BidkernelPrebidAnalytics = class _BidkernelPrebidAnalytics {
|
|
|
1680
2260
|
}
|
|
1681
2261
|
}
|
|
1682
2262
|
const cleanup = () => {
|
|
2263
|
+
adsManager.__bidkernelAttachedInstances?.delete(this);
|
|
1683
2264
|
for (const { type, handler } of listeners) {
|
|
1684
2265
|
try {
|
|
1685
2266
|
adsManager.removeEventListener(type, handler);
|
|
@@ -1727,7 +2308,7 @@ var BidkernelPrebidAnalytics = class _BidkernelPrebidAnalytics {
|
|
|
1727
2308
|
const auctionId = options?.auctionId || "";
|
|
1728
2309
|
const transactionId = options?.transactionId || "";
|
|
1729
2310
|
const getWinningBid = () => {
|
|
1730
|
-
return (auctionId ? this.
|
|
2311
|
+
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);
|
|
1731
2312
|
};
|
|
1732
2313
|
let videoEl = null;
|
|
1733
2314
|
if (el) {
|
|
@@ -1963,6 +2544,10 @@ var BidkernelPrebidAnalytics = class _BidkernelPrebidAnalytics {
|
|
|
1963
2544
|
refreshIndex: record.refreshIndex
|
|
1964
2545
|
};
|
|
1965
2546
|
}
|
|
2547
|
+
/** The validated ingest endpoint in use, or "" when none passed validation. */
|
|
2548
|
+
getEndpoint() {
|
|
2549
|
+
return this.config.endpoint;
|
|
2550
|
+
}
|
|
1966
2551
|
getRefreshIndex(slotId) {
|
|
1967
2552
|
return this.slotRefreshIndices.get(slotId) ?? 0;
|
|
1968
2553
|
}
|
|
@@ -2003,17 +2588,29 @@ var BidkernelPrebidAnalytics = class _BidkernelPrebidAnalytics {
|
|
|
2003
2588
|
handleAuctionInit(data) {
|
|
2004
2589
|
if (this.isDuplicate("auctionInit", data)) return;
|
|
2005
2590
|
this.log("DEBUG", "auctionInit", data);
|
|
2591
|
+
const auctionId = data.auctionId || "";
|
|
2592
|
+
if (auctionId) {
|
|
2593
|
+
this.auctionBidderOutcomes.delete(auctionId);
|
|
2594
|
+
this.getOrCreateAuctionOutcomes(auctionId);
|
|
2595
|
+
}
|
|
2006
2596
|
this.enqueue(TraceEventType.AUCTION_START, "auctionStart", {
|
|
2007
|
-
auctionId
|
|
2597
|
+
auctionId,
|
|
2008
2598
|
transactionId: data.transactionId || ""
|
|
2009
2599
|
});
|
|
2010
2600
|
}
|
|
2011
2601
|
handleAuctionEnd(data) {
|
|
2012
2602
|
if (this.isDuplicate("auctionEnd", data)) return;
|
|
2013
2603
|
this.log("DEBUG", "auctionEnd", data);
|
|
2604
|
+
const auctionId = data.auctionId || "";
|
|
2605
|
+
const outcomesMap = auctionId ? this.auctionBidderOutcomes.get(auctionId) : void 0;
|
|
2606
|
+
const bidderOutcomes = outcomesMap ? Array.from(outcomesMap.values()) : [];
|
|
2607
|
+
if (auctionId) {
|
|
2608
|
+
this.auctionBidderOutcomes.delete(auctionId);
|
|
2609
|
+
}
|
|
2014
2610
|
this.enqueue(TraceEventType.AUCTION_END, "auctionEnd", {
|
|
2015
|
-
auctionId
|
|
2016
|
-
transactionId: data.transactionId || ""
|
|
2611
|
+
auctionId,
|
|
2612
|
+
transactionId: data.transactionId || "",
|
|
2613
|
+
bidderOutcomes
|
|
2017
2614
|
});
|
|
2018
2615
|
}
|
|
2019
2616
|
handleBidRequested(data) {
|
|
@@ -2021,88 +2618,100 @@ var BidkernelPrebidAnalytics = class _BidkernelPrebidAnalytics {
|
|
|
2021
2618
|
this.log("DEBUG", "bidRequested", data);
|
|
2022
2619
|
const auctionId = data.auctionId || "";
|
|
2023
2620
|
const bidder = data.bidderCode || data.bidder || "";
|
|
2621
|
+
if (!auctionId || !bidder) return;
|
|
2622
|
+
const auctionMap = this.getOrCreateAuctionOutcomes(auctionId);
|
|
2024
2623
|
if (Array.isArray(data.bids)) {
|
|
2025
2624
|
data.bids.forEach((bid) => {
|
|
2625
|
+
const adUnitCode = bid.adUnitCode || "";
|
|
2026
2626
|
const mediaTypes = Object.keys(bid.mediaTypes || {});
|
|
2027
|
-
const
|
|
2028
|
-
const
|
|
2029
|
-
if (
|
|
2030
|
-
|
|
2031
|
-
|
|
2032
|
-
|
|
2033
|
-
|
|
2034
|
-
|
|
2035
|
-
|
|
2036
|
-
gpid,
|
|
2037
|
-
bid: {
|
|
2038
|
-
bidder,
|
|
2039
|
-
mediaType,
|
|
2040
|
-
width,
|
|
2041
|
-
height
|
|
2042
|
-
}
|
|
2627
|
+
const mediaType = mediaTypes.length > 0 ? mediaTypes[0] : bid.mediaType || "banner";
|
|
2628
|
+
const key = `${bidder}:${adUnitCode}`;
|
|
2629
|
+
if (!auctionMap.has(key)) {
|
|
2630
|
+
auctionMap.set(key, {
|
|
2631
|
+
bidder,
|
|
2632
|
+
adUnitCode,
|
|
2633
|
+
mediaType,
|
|
2634
|
+
outcome: BidderOutcome.BIDDER_OUTCOME_NO_RESPONSE,
|
|
2635
|
+
latencyMs: 0
|
|
2043
2636
|
});
|
|
2044
|
-
return;
|
|
2045
2637
|
}
|
|
2046
|
-
mediaTypes.forEach((mediaType) => {
|
|
2047
|
-
let rawSize = null;
|
|
2048
|
-
if (mediaType === "banner") {
|
|
2049
|
-
rawSize = bid.mediaTypes?.banner?.sizes || bid.sizes;
|
|
2050
|
-
} else if (mediaType === "video") {
|
|
2051
|
-
rawSize = bid.mediaTypes?.video?.playerSize || bid.mediaTypes?.video?.sizes || bid.playerSize;
|
|
2052
|
-
} else {
|
|
2053
|
-
rawSize = bid.mediaTypes?.[mediaType]?.sizes;
|
|
2054
|
-
}
|
|
2055
|
-
const { width, height } = parseSize(rawSize);
|
|
2056
|
-
this.enqueue(TraceEventType.BID_REQUEST, "bidRequest", {
|
|
2057
|
-
auctionId,
|
|
2058
|
-
transactionId,
|
|
2059
|
-
adUnitCode: bid.adUnitCode || "",
|
|
2060
|
-
gpid,
|
|
2061
|
-
bid: {
|
|
2062
|
-
bidder,
|
|
2063
|
-
mediaType,
|
|
2064
|
-
width,
|
|
2065
|
-
height
|
|
2066
|
-
}
|
|
2067
|
-
});
|
|
2068
|
-
});
|
|
2069
2638
|
});
|
|
2070
2639
|
}
|
|
2071
2640
|
}
|
|
2072
2641
|
handleBidResponse(data) {
|
|
2073
2642
|
if (this.isDuplicate("bidResponse", data)) return;
|
|
2074
2643
|
this.log("DEBUG", "bidResponse", data);
|
|
2075
|
-
|
|
2076
|
-
|
|
2077
|
-
|
|
2078
|
-
|
|
2079
|
-
|
|
2080
|
-
|
|
2081
|
-
|
|
2082
|
-
|
|
2083
|
-
|
|
2084
|
-
|
|
2085
|
-
|
|
2086
|
-
|
|
2087
|
-
|
|
2088
|
-
|
|
2644
|
+
const auctionId = data.auctionId || "";
|
|
2645
|
+
const bidder = data.bidderCode || data.bidder || "";
|
|
2646
|
+
const adUnitCode = data.adUnitCode || "";
|
|
2647
|
+
const cpm = Number.isFinite(data.originalCpm) ? data.originalCpm : Number.isFinite(data.cpm) ? data.cpm : 0;
|
|
2648
|
+
const latencyMs = Number.isFinite(data.timeToRespond) ? data.timeToRespond : 0;
|
|
2649
|
+
const resMediaTypes = Object.keys(data.mediaTypes || {});
|
|
2650
|
+
const mediaType = data.mediaType || (data.mediaTypes?.video ? "video" : resMediaTypes.length > 0 ? resMediaTypes[0] : "banner");
|
|
2651
|
+
if (auctionId && bidder) {
|
|
2652
|
+
const auctionMap = this.getOrCreateAuctionOutcomes(auctionId);
|
|
2653
|
+
const key = `${bidder}:${adUnitCode}`;
|
|
2654
|
+
const entry = auctionMap.get(key);
|
|
2655
|
+
const outcome = cpm > 0 ? BidderOutcome.BIDDER_OUTCOME_BID : BidderOutcome.BIDDER_OUTCOME_NO_BID;
|
|
2656
|
+
if (entry) {
|
|
2657
|
+
entry.outcome = outcome;
|
|
2658
|
+
entry.latencyMs = latencyMs;
|
|
2659
|
+
if (mediaType) entry.mediaType = mediaType;
|
|
2660
|
+
} else {
|
|
2661
|
+
auctionMap.set(key, {
|
|
2662
|
+
bidder,
|
|
2663
|
+
adUnitCode,
|
|
2664
|
+
mediaType,
|
|
2665
|
+
outcome,
|
|
2666
|
+
latencyMs
|
|
2667
|
+
});
|
|
2089
2668
|
}
|
|
2090
|
-
}
|
|
2669
|
+
}
|
|
2670
|
+
if (cpm > 0) {
|
|
2671
|
+
this.enqueue(TraceEventType.BID_RESPONSE, "bidResponse", {
|
|
2672
|
+
auctionId,
|
|
2673
|
+
transactionId: data.transactionId || "",
|
|
2674
|
+
adUnitCode,
|
|
2675
|
+
bid: {
|
|
2676
|
+
bidder,
|
|
2677
|
+
cpm,
|
|
2678
|
+
currency: data.originalCurrency ?? data.currency ?? "USD",
|
|
2679
|
+
...parseBidDimensions(data),
|
|
2680
|
+
dealId: data.dealId || "",
|
|
2681
|
+
mediaType,
|
|
2682
|
+
latencyMs,
|
|
2683
|
+
advertiserDomain: data.meta?.advertiserDomains?.[0] || "",
|
|
2684
|
+
creativeId: data.creativeId || ""
|
|
2685
|
+
}
|
|
2686
|
+
});
|
|
2687
|
+
}
|
|
2091
2688
|
}
|
|
2092
2689
|
handleBidTimeout(data) {
|
|
2093
2690
|
if (this.isDuplicate("bidTimeout", data)) return;
|
|
2094
2691
|
this.log("DEBUG", "bidTimeout", data);
|
|
2095
2692
|
const items = Array.isArray(data) ? data : data ? [data] : [];
|
|
2096
2693
|
for (const t of items) {
|
|
2097
|
-
|
|
2098
|
-
|
|
2099
|
-
|
|
2100
|
-
|
|
2101
|
-
|
|
2102
|
-
|
|
2103
|
-
|
|
2694
|
+
const auctionId = t.auctionId || "";
|
|
2695
|
+
const bidder = t.bidderCode || t.bidder || "";
|
|
2696
|
+
const adUnitCode = t.adUnitCode || "";
|
|
2697
|
+
const latencyMs = Number.isFinite(t.timeout) ? t.timeout : 0;
|
|
2698
|
+
if (auctionId && bidder) {
|
|
2699
|
+
const auctionMap = this.getOrCreateAuctionOutcomes(auctionId);
|
|
2700
|
+
const key = `${bidder}:${adUnitCode}`;
|
|
2701
|
+
const entry = auctionMap.get(key);
|
|
2702
|
+
if (entry) {
|
|
2703
|
+
entry.outcome = BidderOutcome.BIDDER_OUTCOME_TIMEOUT;
|
|
2704
|
+
if (latencyMs > 0) entry.latencyMs = latencyMs;
|
|
2705
|
+
} else {
|
|
2706
|
+
auctionMap.set(key, {
|
|
2707
|
+
bidder,
|
|
2708
|
+
adUnitCode,
|
|
2709
|
+
mediaType: "banner",
|
|
2710
|
+
outcome: BidderOutcome.BIDDER_OUTCOME_TIMEOUT,
|
|
2711
|
+
latencyMs
|
|
2712
|
+
});
|
|
2104
2713
|
}
|
|
2105
|
-
}
|
|
2714
|
+
}
|
|
2106
2715
|
}
|
|
2107
2716
|
}
|
|
2108
2717
|
handleBidWon(data) {
|
|
@@ -2111,13 +2720,15 @@ var BidkernelPrebidAnalytics = class _BidkernelPrebidAnalytics {
|
|
|
2111
2720
|
const auctionId = data.auctionId || "";
|
|
2112
2721
|
const transactionId = data.transactionId || "";
|
|
2113
2722
|
const adUnitCode = data.adUnitCode || data.adId || "";
|
|
2723
|
+
const wonMediaTypes = Object.keys(data.mediaTypes || {});
|
|
2724
|
+
const resolvedMediaType = data.mediaType || (data.mediaTypes?.video ? "video" : wonMediaTypes.length > 0 ? wonMediaTypes[0] : "banner");
|
|
2114
2725
|
const bidTrace = {
|
|
2115
2726
|
bidder: data.bidderCode || data.bidder || "",
|
|
2116
2727
|
cpm: Number.isFinite(data.originalCpm) ? data.originalCpm : Number.isFinite(data.cpm) ? data.cpm : 0,
|
|
2117
2728
|
currency: data.originalCurrency ?? data.currency ?? "USD",
|
|
2118
2729
|
...parseBidDimensions(data),
|
|
2119
2730
|
dealId: data.dealId || "",
|
|
2120
|
-
mediaType:
|
|
2731
|
+
mediaType: resolvedMediaType,
|
|
2121
2732
|
latencyMs: Number.isFinite(data.timeToRespond) ? data.timeToRespond : 0,
|
|
2122
2733
|
advertiserDomain: data.meta?.advertiserDomains?.[0] || "",
|
|
2123
2734
|
creativeId: data.creativeId || ""
|
|
@@ -2141,6 +2752,7 @@ var BidkernelPrebidAnalytics = class _BidkernelPrebidAnalytics {
|
|
|
2141
2752
|
this.cachedWinningBids.set(`${auctionId}:${data.adId}`, cachedEntry);
|
|
2142
2753
|
}
|
|
2143
2754
|
}
|
|
2755
|
+
this.pruneCachedWinningBids();
|
|
2144
2756
|
}
|
|
2145
2757
|
this.enqueue(TraceEventType.BID_WIN, "bidWon", {
|
|
2146
2758
|
auctionId,
|
|
@@ -2152,14 +2764,27 @@ var BidkernelPrebidAnalytics = class _BidkernelPrebidAnalytics {
|
|
|
2152
2764
|
handleNoBid(data) {
|
|
2153
2765
|
if (this.isDuplicate("noBid", data)) return;
|
|
2154
2766
|
this.log("DEBUG", "noBid", data);
|
|
2155
|
-
|
|
2156
|
-
|
|
2157
|
-
|
|
2158
|
-
|
|
2159
|
-
|
|
2160
|
-
|
|
2767
|
+
const auctionId = data.auctionId || "";
|
|
2768
|
+
const bidder = data.bidderCode || data.bidder || "";
|
|
2769
|
+
const adUnitCode = data.adUnitCode || "";
|
|
2770
|
+
if (auctionId && bidder) {
|
|
2771
|
+
const auctionMap = this.getOrCreateAuctionOutcomes(auctionId);
|
|
2772
|
+
const key = `${bidder}:${adUnitCode}`;
|
|
2773
|
+
const entry = auctionMap.get(key);
|
|
2774
|
+
if (entry) {
|
|
2775
|
+
if (entry.outcome === BidderOutcome.BIDDER_OUTCOME_NO_RESPONSE) {
|
|
2776
|
+
entry.outcome = BidderOutcome.BIDDER_OUTCOME_NO_BID;
|
|
2777
|
+
}
|
|
2778
|
+
} else {
|
|
2779
|
+
auctionMap.set(key, {
|
|
2780
|
+
bidder,
|
|
2781
|
+
adUnitCode,
|
|
2782
|
+
mediaType: "banner",
|
|
2783
|
+
outcome: BidderOutcome.BIDDER_OUTCOME_NO_BID,
|
|
2784
|
+
latencyMs: 0
|
|
2785
|
+
});
|
|
2161
2786
|
}
|
|
2162
|
-
}
|
|
2787
|
+
}
|
|
2163
2788
|
}
|
|
2164
2789
|
handleAdRenderFailed(data) {
|
|
2165
2790
|
if (this.isDuplicate("adRenderFailed", data)) return;
|
|
@@ -2191,14 +2816,16 @@ var BidkernelPrebidAnalytics = class _BidkernelPrebidAnalytics {
|
|
|
2191
2816
|
const mediaType = bid.mediaType || "banner";
|
|
2192
2817
|
const slotKey = data.adUnitCode || bid.adUnitCode || "";
|
|
2193
2818
|
const altKey = data.adId || bid.adId || "";
|
|
2194
|
-
const cached = (auctionId && slotKey ? this.
|
|
2819
|
+
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);
|
|
2820
|
+
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";
|
|
2821
|
+
const resolvedMediaType = isVideo ? "video" : mediaType || cached?.bidTrace?.mediaType || "banner";
|
|
2195
2822
|
const bidTrace = {
|
|
2196
2823
|
bidder: bid.bidderCode || bid.bidder || cached?.bidTrace?.bidder || "",
|
|
2197
2824
|
cpm: Number.isFinite(bid.originalCpm) ? bid.originalCpm : Number.isFinite(bid.cpm) ? bid.cpm : cached?.bidTrace?.cpm ?? 0,
|
|
2198
2825
|
currency: bid.originalCurrency ?? bid.currency ?? cached?.bidTrace?.currency ?? "USD",
|
|
2199
2826
|
...parseBidDimensions(bid).width ? parseBidDimensions(bid) : cached?.bidTrace ? { width: cached.bidTrace.width, height: cached.bidTrace.height } : parseBidDimensions(bid),
|
|
2200
2827
|
dealId: bid.dealId || cached?.bidTrace?.dealId || "",
|
|
2201
|
-
mediaType:
|
|
2828
|
+
mediaType: resolvedMediaType,
|
|
2202
2829
|
latencyMs: Number.isFinite(bid.timeToRespond) ? bid.timeToRespond : cached?.bidTrace?.latencyMs ?? 0,
|
|
2203
2830
|
advertiserDomain: bid.meta?.advertiserDomains?.[0] || cached?.bidTrace?.advertiserDomain || "",
|
|
2204
2831
|
creativeId: bid.creativeId || cached?.bidTrace?.creativeId || ""
|
|
@@ -2237,28 +2864,35 @@ var BidkernelPrebidAnalytics = class _BidkernelPrebidAnalytics {
|
|
|
2237
2864
|
}
|
|
2238
2865
|
}
|
|
2239
2866
|
const currentRefreshIndex = adUnitCode ? this.slotRefreshIndices.get(adUnitCode) ?? (record ? record.refreshIndex : 0) : 0;
|
|
2240
|
-
|
|
2241
|
-
adUnitCode
|
|
2242
|
-
|
|
2243
|
-
|
|
2244
|
-
|
|
2245
|
-
|
|
2246
|
-
|
|
2247
|
-
if (
|
|
2248
|
-
|
|
2867
|
+
if (!isVideo) {
|
|
2868
|
+
const alreadyEmitted = adUnitCode ? this.hasImpressionEmitted(
|
|
2869
|
+
adUnitCode,
|
|
2870
|
+
currentRefreshIndex,
|
|
2871
|
+
resolvedAuctionId,
|
|
2872
|
+
bidTrace.creativeId
|
|
2873
|
+
) : false;
|
|
2874
|
+
if (!alreadyEmitted) {
|
|
2875
|
+
if (adUnitCode) {
|
|
2876
|
+
this.markImpressionEmitted(
|
|
2877
|
+
adUnitCode,
|
|
2878
|
+
currentRefreshIndex,
|
|
2879
|
+
resolvedAuctionId,
|
|
2880
|
+
bidTrace.creativeId
|
|
2881
|
+
);
|
|
2882
|
+
}
|
|
2883
|
+
this.enqueue(TraceEventType.IMPRESSION, "impression", {
|
|
2884
|
+
auctionId: resolvedAuctionId,
|
|
2885
|
+
transactionId: resolvedTransactionId,
|
|
2249
2886
|
adUnitCode,
|
|
2250
|
-
|
|
2251
|
-
|
|
2252
|
-
|
|
2253
|
-
);
|
|
2887
|
+
bid: bidTrace,
|
|
2888
|
+
metadata: { refresh_index: String(currentRefreshIndex) }
|
|
2889
|
+
});
|
|
2254
2890
|
}
|
|
2255
|
-
|
|
2256
|
-
|
|
2257
|
-
|
|
2258
|
-
adUnitCode
|
|
2259
|
-
|
|
2260
|
-
metadata: { refresh_index: String(currentRefreshIndex) }
|
|
2261
|
-
});
|
|
2891
|
+
} else {
|
|
2892
|
+
this.log(
|
|
2893
|
+
"DEBUG",
|
|
2894
|
+
`adRenderSucceeded received for video ad unit ${adUnitCode || "unknown"}: suppressing IMPRESSION until verified video lifecycle event`
|
|
2895
|
+
);
|
|
2262
2896
|
}
|
|
2263
2897
|
if (this.config.viewabilityEnabled && typeof document !== "undefined") {
|
|
2264
2898
|
let el = null;
|
|
@@ -2280,7 +2914,12 @@ var BidkernelPrebidAnalytics = class _BidkernelPrebidAnalytics {
|
|
|
2280
2914
|
}
|
|
2281
2915
|
if (!el && targetId) {
|
|
2282
2916
|
try {
|
|
2283
|
-
|
|
2917
|
+
for (const candidate of Array.from(document.querySelectorAll("[data-ad-slot]"))) {
|
|
2918
|
+
if (candidate.getAttribute("data-ad-slot") === targetId) {
|
|
2919
|
+
el = candidate;
|
|
2920
|
+
break;
|
|
2921
|
+
}
|
|
2922
|
+
}
|
|
2284
2923
|
} catch {
|
|
2285
2924
|
}
|
|
2286
2925
|
}
|
|
@@ -2289,7 +2928,7 @@ var BidkernelPrebidAnalytics = class _BidkernelPrebidAnalytics {
|
|
|
2289
2928
|
adUnitCode,
|
|
2290
2929
|
auctionId: resolvedAuctionId,
|
|
2291
2930
|
transactionId: resolvedTransactionId,
|
|
2292
|
-
mediaType,
|
|
2931
|
+
mediaType: resolvedMediaType,
|
|
2293
2932
|
bid: bidTrace,
|
|
2294
2933
|
refreshIndex: currentRefreshIndex,
|
|
2295
2934
|
emitRefreshEvent: false
|
|
@@ -2334,6 +2973,9 @@ var BidkernelPrebidAnalytics = class _BidkernelPrebidAnalytics {
|
|
|
2334
2973
|
if (data.viewableDurationMs !== void 0) {
|
|
2335
2974
|
protoEvent.viewableDurationMs = Number.isFinite(data.viewableDurationMs) ? data.viewableDurationMs : 0;
|
|
2336
2975
|
}
|
|
2976
|
+
if (data.bidderOutcomes && Array.isArray(data.bidderOutcomes)) {
|
|
2977
|
+
protoEvent.bidderOutcomes = data.bidderOutcomes;
|
|
2978
|
+
}
|
|
2337
2979
|
const metadata = { ...data.metadata };
|
|
2338
2980
|
if (data.error !== void 0 && data.error !== null) {
|
|
2339
2981
|
metadata.error = typeof data.error === "object" && data.error.message ? String(data.error.message) : String(data.error);
|
|
@@ -2344,8 +2986,9 @@ var BidkernelPrebidAnalytics = class _BidkernelPrebidAnalytics {
|
|
|
2344
2986
|
if (data.refreshIndex !== void 0 && metadata.refresh_index === void 0) {
|
|
2345
2987
|
metadata.refresh_index = String(data.refreshIndex);
|
|
2346
2988
|
}
|
|
2347
|
-
|
|
2348
|
-
|
|
2989
|
+
const boundedMetadata = boundMetadata(metadata);
|
|
2990
|
+
if (Object.keys(boundedMetadata).length > 0) {
|
|
2991
|
+
protoEvent.metadata = boundedMetadata;
|
|
2349
2992
|
}
|
|
2350
2993
|
this.queue.push(protoEvent);
|
|
2351
2994
|
if (this.queue.length > MAX_QUEUE_SIZE) {
|
|
@@ -2383,7 +3026,6 @@ var BidkernelPrebidAnalytics = class _BidkernelPrebidAnalytics {
|
|
|
2383
3026
|
// Shared by flush() and flushBeacon().
|
|
2384
3027
|
drainBatch() {
|
|
2385
3028
|
if (this.queue.length === 0 || !this.config.endpoint) return null;
|
|
2386
|
-
let events = this.queue;
|
|
2387
3029
|
const domain = typeof window !== "undefined" ? window.location.hostname : "";
|
|
2388
3030
|
const buildBatch = (evts) => ({
|
|
2389
3031
|
propertyId: this.config.propertyId,
|
|
@@ -2397,25 +3039,37 @@ var BidkernelPrebidAnalytics = class _BidkernelPrebidAnalytics {
|
|
|
2397
3039
|
domain,
|
|
2398
3040
|
events: evts
|
|
2399
3041
|
});
|
|
2400
|
-
|
|
2401
|
-
|
|
2402
|
-
|
|
2403
|
-
|
|
2404
|
-
events = events.slice(0, Math.floor(events.length / 2));
|
|
2405
|
-
encoded = TraceEventBatch.encode(
|
|
3042
|
+
for (; ; ) {
|
|
3043
|
+
if (this.queue.length === 0) return null;
|
|
3044
|
+
let events = this.queue;
|
|
3045
|
+
let encoded = TraceEventBatch.encode(
|
|
2406
3046
|
buildBatch(events)
|
|
2407
3047
|
).finish();
|
|
3048
|
+
while (events.length > 1 && encoded.byteLength > MAX_PAYLOAD_BYTES) {
|
|
3049
|
+
events = events.slice(0, Math.floor(events.length / 2));
|
|
3050
|
+
encoded = TraceEventBatch.encode(
|
|
3051
|
+
buildBatch(events)
|
|
3052
|
+
).finish();
|
|
3053
|
+
}
|
|
3054
|
+
if (encoded.byteLength > MAX_PAYLOAD_BYTES) {
|
|
3055
|
+
const [dropped] = this.queue.splice(0, 1);
|
|
3056
|
+
this.log(
|
|
3057
|
+
"WARN",
|
|
3058
|
+
`Dropping oversized event ${dropped?.eventName || dropped?.eventId} (${encoded.byteLength} bytes exceeds the ${MAX_PAYLOAD_BYTES}-byte cap on its own)`
|
|
3059
|
+
);
|
|
3060
|
+
continue;
|
|
3061
|
+
}
|
|
3062
|
+
this.queue = this.queue.slice(events.length);
|
|
3063
|
+
return {
|
|
3064
|
+
url: `${this.config.endpoint}/${this.config.propertyId}`,
|
|
3065
|
+
// protobufjs types finish() as Uint8Array<ArrayBufferLike>; the buffer is
|
|
3066
|
+
// always a plain ArrayBuffer, so narrow for fetch/Blob compatibility.
|
|
3067
|
+
encoded,
|
|
3068
|
+
events
|
|
3069
|
+
};
|
|
2408
3070
|
}
|
|
2409
|
-
this.queue = this.queue.slice(events.length);
|
|
2410
|
-
return {
|
|
2411
|
-
url: `${this.config.endpoint}/${this.config.propertyId}`,
|
|
2412
|
-
// protobufjs types finish() as Uint8Array<ArrayBufferLike>; the buffer is
|
|
2413
|
-
// always a plain ArrayBuffer, so narrow for fetch/Blob compatibility.
|
|
2414
|
-
encoded,
|
|
2415
|
-
events
|
|
2416
|
-
};
|
|
2417
3071
|
}
|
|
2418
|
-
sendFetch(payload, useKeepalive = false, onDelivered) {
|
|
3072
|
+
sendFetch(payload, useKeepalive = false, onDelivered, isReplay = false) {
|
|
2419
3073
|
const fetchOpts = {
|
|
2420
3074
|
method: "POST",
|
|
2421
3075
|
// Safelisted content type: no CORS preflight (see SAFE_CONTENT_TYPE).
|
|
@@ -2432,15 +3086,17 @@ var BidkernelPrebidAnalytics = class _BidkernelPrebidAnalytics {
|
|
|
2432
3086
|
this.log("WARN", `Dropping batch due to non-retryable client error HTTP ${res.status}`);
|
|
2433
3087
|
return;
|
|
2434
3088
|
}
|
|
2435
|
-
this.handleSendFailure(payload.events);
|
|
3089
|
+
if (!isReplay) this.handleSendFailure(payload.events);
|
|
2436
3090
|
} else {
|
|
2437
|
-
|
|
2438
|
-
|
|
3091
|
+
if (!isReplay) {
|
|
3092
|
+
this.consecutiveSendFailures = 0;
|
|
3093
|
+
this.nextSendAllowedAt = 0;
|
|
3094
|
+
}
|
|
2439
3095
|
if (onDelivered) onDelivered();
|
|
2440
3096
|
}
|
|
2441
3097
|
}).catch((err) => {
|
|
2442
3098
|
this.log("ERROR", "Failed to send batch", err);
|
|
2443
|
-
this.handleSendFailure(payload.events);
|
|
3099
|
+
if (!isReplay) this.handleSendFailure(payload.events);
|
|
2444
3100
|
});
|
|
2445
3101
|
const proc = typeof globalThis !== "undefined" ? globalThis.process : void 0;
|
|
2446
3102
|
if (proc && typeof proc._tickCallback === "function") {
|
|
@@ -2496,16 +3152,23 @@ var BidkernelPrebidAnalytics = class _BidkernelPrebidAnalytics {
|
|
|
2496
3152
|
this.schedulePersistedCleanup();
|
|
2497
3153
|
}
|
|
2498
3154
|
// --- Exit-batch persistence -----------------------------------------------
|
|
3155
|
+
// Key prefix for this instance's property. encodeURIComponent keeps the
|
|
3156
|
+
// property segment free of the "_" the timestamp suffix is parsed against,
|
|
3157
|
+
// so a property ID containing one cannot forge another property's prefix.
|
|
3158
|
+
pendingKeyPrefix() {
|
|
3159
|
+
return `${PENDING_BATCH_KEY_PREFIX}${encodeURIComponent(this.config.propertyId)}_`;
|
|
3160
|
+
}
|
|
2499
3161
|
persistBatch(encoded) {
|
|
2500
3162
|
try {
|
|
2501
3163
|
if (typeof localStorage === "undefined") return null;
|
|
3164
|
+
if (!this.config.propertyId) return null;
|
|
2502
3165
|
let pendingCount = 0;
|
|
2503
3166
|
for (let i = 0; i < localStorage.length; i++) {
|
|
2504
3167
|
const k = localStorage.key(i);
|
|
2505
3168
|
if (k && k.startsWith(PENDING_BATCH_KEY_PREFIX)) pendingCount++;
|
|
2506
3169
|
}
|
|
2507
3170
|
if (pendingCount >= MAX_PENDING_BATCHES) return null;
|
|
2508
|
-
const key = `${
|
|
3171
|
+
const key = `${this.pendingKeyPrefix()}${Date.now()}_${Math.floor(Math.random() * 1e6)}`;
|
|
2509
3172
|
localStorage.setItem(key, bytesToBase64(encoded));
|
|
2510
3173
|
this.persistedBatchKeys.push(key);
|
|
2511
3174
|
return key;
|
|
@@ -2536,16 +3199,33 @@ var BidkernelPrebidAnalytics = class _BidkernelPrebidAnalytics {
|
|
|
2536
3199
|
}, PENDING_BATCH_CLEANUP_DELAY_MS);
|
|
2537
3200
|
}
|
|
2538
3201
|
// Resend batches a previous pageview persisted at exit but could not
|
|
2539
|
-
// confirm.
|
|
2540
|
-
//
|
|
2541
|
-
//
|
|
3202
|
+
// confirm. Only this property's own keys are claimed: batches belonging to
|
|
3203
|
+
// another property sharing this origin are left for that property's next
|
|
3204
|
+
// pageview, since resending them here would file them under this property.
|
|
3205
|
+
// Keys are claimed (removed) before sending so concurrent tabs don't
|
|
3206
|
+
// double-send; the batch bytes carry their original pageview, session, and
|
|
3207
|
+
// event timestamps, so late rows attribute correctly.
|
|
2542
3208
|
resendPersistedBatches() {
|
|
2543
3209
|
try {
|
|
2544
3210
|
if (typeof localStorage === "undefined" || !this.config.endpoint) return;
|
|
3211
|
+
if (!this.config.propertyId) return;
|
|
3212
|
+
const ownPrefix = this.pendingKeyPrefix();
|
|
2545
3213
|
const keys = [];
|
|
3214
|
+
const legacyKeys = [];
|
|
2546
3215
|
for (let i = 0; i < localStorage.length; i++) {
|
|
2547
3216
|
const k = localStorage.key(i);
|
|
2548
|
-
if (k
|
|
3217
|
+
if (!k || !k.startsWith(PENDING_BATCH_KEY_PREFIX)) continue;
|
|
3218
|
+
if (k.startsWith(ownPrefix)) {
|
|
3219
|
+
keys.push(k);
|
|
3220
|
+
} else if (isLegacyPendingKey(k)) {
|
|
3221
|
+
legacyKeys.push(k);
|
|
3222
|
+
}
|
|
3223
|
+
}
|
|
3224
|
+
for (const key of legacyKeys) {
|
|
3225
|
+
try {
|
|
3226
|
+
localStorage.removeItem(key);
|
|
3227
|
+
} catch {
|
|
3228
|
+
}
|
|
2549
3229
|
}
|
|
2550
3230
|
for (const key of keys) {
|
|
2551
3231
|
let value = null;
|
|
@@ -2556,7 +3236,7 @@ var BidkernelPrebidAnalytics = class _BidkernelPrebidAnalytics {
|
|
|
2556
3236
|
continue;
|
|
2557
3237
|
}
|
|
2558
3238
|
if (!value) continue;
|
|
2559
|
-
const ts = parseInt(key.slice(
|
|
3239
|
+
const ts = parseInt(key.slice(ownPrefix.length), 10);
|
|
2560
3240
|
if (!Number.isFinite(ts) || Date.now() - ts > PENDING_BATCH_MAX_AGE_MS) continue;
|
|
2561
3241
|
let encoded;
|
|
2562
3242
|
try {
|
|
@@ -2566,11 +3246,16 @@ var BidkernelPrebidAnalytics = class _BidkernelPrebidAnalytics {
|
|
|
2566
3246
|
}
|
|
2567
3247
|
if (encoded.byteLength === 0) continue;
|
|
2568
3248
|
this.log("DEBUG", `Resending persisted exit batch (${encoded.byteLength} bytes)`);
|
|
2569
|
-
this.sendFetch(
|
|
2570
|
-
|
|
2571
|
-
|
|
2572
|
-
|
|
2573
|
-
|
|
3249
|
+
this.sendFetch(
|
|
3250
|
+
{
|
|
3251
|
+
url: `${this.config.endpoint}/${this.config.propertyId}`,
|
|
3252
|
+
encoded,
|
|
3253
|
+
events: []
|
|
3254
|
+
},
|
|
3255
|
+
false,
|
|
3256
|
+
void 0,
|
|
3257
|
+
true
|
|
3258
|
+
);
|
|
2574
3259
|
}
|
|
2575
3260
|
} catch {
|
|
2576
3261
|
}
|
|
@@ -2595,11 +3280,13 @@ var BidkernelPrebidAnalytics = class _BidkernelPrebidAnalytics {
|
|
|
2595
3280
|
}
|
|
2596
3281
|
}
|
|
2597
3282
|
};
|
|
2598
|
-
function extractAnalyticsOptions(config) {
|
|
3283
|
+
function extractAnalyticsOptions(config, allowProviderless = true) {
|
|
2599
3284
|
if (!config) return null;
|
|
2600
3285
|
if (Array.isArray(config)) {
|
|
2601
|
-
const matched = config.find((item) => item?.provider === "bidkernel") ?? config.find(
|
|
2602
|
-
|
|
3286
|
+
const matched = config.find((item) => item?.provider === "bidkernel") ?? (allowProviderless ? config.find(
|
|
3287
|
+
(item) => item && typeof item === "object" && item.provider === void 0
|
|
3288
|
+
) : void 0);
|
|
3289
|
+
return matched ? extractAnalyticsOptions(matched, allowProviderless) : null;
|
|
2603
3290
|
}
|
|
2604
3291
|
if (typeof config === "object") {
|
|
2605
3292
|
if (config.options && typeof config.options === "object") {
|
|
@@ -2641,18 +3328,27 @@ function registerPrebidAnalytics(pbjsGlobalName = "pbjs", defaults) {
|
|
|
2641
3328
|
win[pbjsGlobalName] = win[pbjsGlobalName] || {};
|
|
2642
3329
|
const pbjs = win[pbjsGlobalName];
|
|
2643
3330
|
const enableInstance = (options) => {
|
|
2644
|
-
|
|
3331
|
+
const previous = win._bidkernelPrebidAnalytics;
|
|
3332
|
+
const pinnedEndpoint = previous?.getEndpoint?.() || "";
|
|
3333
|
+
const merged = {
|
|
3334
|
+
pbjsGlobalName,
|
|
3335
|
+
...defaults,
|
|
3336
|
+
...options
|
|
3337
|
+
};
|
|
3338
|
+
if (pinnedEndpoint && !sameEndpointOrigin(merged.endpoint || "", pinnedEndpoint)) {
|
|
3339
|
+
console.warn(
|
|
3340
|
+
`[bidkernel] Ignoring analytics endpoint change to ${merged.endpoint || "(empty)"}: this page is pinned to ${pinnedEndpoint}. Reload to change the ingest endpoint.`
|
|
3341
|
+
);
|
|
3342
|
+
merged.endpoint = pinnedEndpoint;
|
|
3343
|
+
}
|
|
3344
|
+
if (previous) {
|
|
2645
3345
|
try {
|
|
2646
|
-
|
|
3346
|
+
previous.disable();
|
|
2647
3347
|
} catch (e) {
|
|
2648
3348
|
console.warn("[bidkernel] Failed to disable previous analytics instance:", e);
|
|
2649
3349
|
}
|
|
2650
3350
|
}
|
|
2651
|
-
const analytics = new BidkernelPrebidAnalytics(
|
|
2652
|
-
pbjsGlobalName,
|
|
2653
|
-
...defaults,
|
|
2654
|
-
...options
|
|
2655
|
-
});
|
|
3351
|
+
const analytics = new BidkernelPrebidAnalytics(merged);
|
|
2656
3352
|
analytics.enable();
|
|
2657
3353
|
win._bidkernelPrebidAnalytics = analytics;
|
|
2658
3354
|
return analytics;
|
|
@@ -2663,7 +3359,7 @@ function registerPrebidAnalytics(pbjsGlobalName = "pbjs", defaults) {
|
|
|
2663
3359
|
pbjs.adapterManager.registerAnalyticsAdapter({
|
|
2664
3360
|
adapter: {
|
|
2665
3361
|
enableAnalytics: (config) => {
|
|
2666
|
-
const options = extractAnalyticsOptions(config);
|
|
3362
|
+
const options = extractAnalyticsOptions(config, !Array.isArray(config));
|
|
2667
3363
|
if (options) {
|
|
2668
3364
|
enableInstance(options);
|
|
2669
3365
|
}
|
|
@@ -2728,5 +3424,8 @@ export {
|
|
|
2728
3424
|
PrebidEventDeduper,
|
|
2729
3425
|
getPrebidEventKey,
|
|
2730
3426
|
getbidkernel,
|
|
3427
|
+
hookImaPrototype,
|
|
3428
|
+
initImaInterception,
|
|
3429
|
+
isTrustedEndpoint,
|
|
2731
3430
|
registerPrebidAnalytics
|
|
2732
3431
|
};
|