prebid.js 9.26.0 → 9.28.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.
Files changed (305) hide show
  1. package/creative/renderers/native/renderer.js +29 -8
  2. package/dist/33acrossAnalyticsAdapter.js +1 -1
  3. package/dist/33acrossBidAdapter.js +1 -1
  4. package/dist/33acrossIdSystem.js +1 -1
  5. package/dist/BTBidAdapter.js +1 -1
  6. package/dist/acuityadsBidAdapter.js +1 -1
  7. package/dist/adagioAnalyticsAdapter.js +1 -1
  8. package/dist/adagioBidAdapter.js +1 -1
  9. package/dist/adagioRtdProvider.js +1 -1
  10. package/dist/adagioUtils.js +1 -1
  11. package/dist/addefendBidAdapter.js +1 -1
  12. package/dist/adgenerationBidAdapter.js +1 -1
  13. package/dist/adlooxAdServerVideo.js +1 -1
  14. package/dist/adlooxAnalyticsAdapter.js +1 -1
  15. package/dist/adlooxRtdProvider.js +1 -1
  16. package/dist/adqueryBidAdapter.js +1 -1
  17. package/dist/adrelevantisBidAdapter.js +1 -1
  18. package/dist/adstirBidAdapter.js +1 -1
  19. package/dist/adtrgtmeBidAdapter.js +1 -1
  20. package/dist/adxcgAnalyticsAdapter.js +1 -1
  21. package/dist/adxcgBidAdapter.js +1 -1
  22. package/dist/adyoulikeBidAdapter.js +1 -1
  23. package/dist/agmaAnalyticsAdapter.js +1 -1
  24. package/dist/ajaBidAdapter.js +1 -1
  25. package/dist/akamaiDapRtdProvider.js +1 -1
  26. package/dist/amxBidAdapter.js +1 -1
  27. package/dist/amxIdSystem.js +1 -1
  28. package/dist/aniviewBidAdapter.js +1 -1
  29. package/dist/appierAnalyticsAdapter.js +1 -1
  30. package/dist/appnexusBidAdapter.js +1 -1
  31. package/dist/asoBidAdapter.js +1 -1
  32. package/dist/axonixBidAdapter.js +1 -1
  33. package/dist/bidglassBidAdapter.js +1 -1
  34. package/dist/big-richmediaBidAdapter.js +1 -1
  35. package/dist/bitmediaBidAdapter.js +1 -1
  36. package/dist/blueBidAdapter.js +1 -0
  37. package/dist/bridBidAdapter.js +1 -1
  38. package/dist/bridgeuppBidAdapter.js +1 -1
  39. package/dist/bridgewellBidAdapter.js +1 -1
  40. package/dist/brightMountainMediaBidAdapter.js +1 -1
  41. package/dist/carodaBidAdapter.js +1 -1
  42. package/dist/chtnwBidAdapter.js +1 -1
  43. package/dist/chunk-core.js +1 -1
  44. package/dist/conceptxBidAdapter.js +1 -1
  45. package/dist/concertBidAdapter.js +1 -1
  46. package/dist/connectadBidAdapter.js +1 -1
  47. package/dist/consumableBidAdapter.js +1 -1
  48. package/dist/contxtfulBidAdapter.js +1 -1
  49. package/dist/contxtfulRtdProvider.js +1 -1
  50. package/dist/conversantAnalyticsAdapter.js +1 -1
  51. package/dist/conversantBidAdapter.js +1 -1
  52. package/dist/craftBidAdapter.js +1 -1
  53. package/dist/creative-renderer-native.js +1 -1
  54. package/dist/criteoBidAdapter.js +1 -1
  55. package/dist/cwireBidAdapter.js +1 -1
  56. package/dist/dailymotionBidAdapter.js +1 -1
  57. package/dist/dependencies.json +7 -1
  58. package/dist/dspxBidAdapter.js +1 -1
  59. package/dist/dxkultureBidAdapter.js +1 -1
  60. package/dist/eplanningBidAdapter.js +1 -1
  61. package/dist/equativBidAdapter.js +1 -1
  62. package/dist/escalaxBidAdapter.js +1 -1
  63. package/dist/eskimiBidAdapter.js +1 -1
  64. package/dist/euidIdSystem.js +1 -1
  65. package/dist/exadsBidAdapter.js +1 -1
  66. package/dist/feedadBidAdapter.js +1 -1
  67. package/dist/finativeBidAdapter.js +1 -1
  68. package/dist/freewheel-sspBidAdapter.js +1 -1
  69. package/dist/gmosspBidAdapter.js +1 -1
  70. package/dist/greenbidsAnalyticsAdapter.js +1 -1
  71. package/dist/greenbidsBidAdapter.js +1 -1
  72. package/dist/greenbidsRtdProvider.js +1 -1
  73. package/dist/gridBidAdapter.js +1 -1
  74. package/dist/gumgumBidAdapter.js +1 -1
  75. package/dist/h12mediaBidAdapter.js +1 -1
  76. package/dist/hypelabBidAdapter.js +1 -1
  77. package/dist/id5AnalyticsAdapter.js +1 -1
  78. package/dist/id5IdSystem.js +1 -1
  79. package/dist/imdsBidAdapter.js +1 -1
  80. package/dist/improvedigitalBidAdapter.js +1 -1
  81. package/dist/inmobiBidAdapter.js +1 -1
  82. package/dist/insticatorBidAdapter.js +1 -1
  83. package/dist/intentIqAnalyticsAdapter.js +1 -1
  84. package/dist/intentIqConstants.js +1 -1
  85. package/dist/ixBidAdapter.js +1 -1
  86. package/dist/jixieBidAdapter.js +1 -1
  87. package/dist/justpremiumBidAdapter.js +1 -1
  88. package/dist/jwplayerVideoProvider.js +1 -1
  89. package/dist/kargoBidAdapter.js +1 -1
  90. package/dist/kimberliteBidAdapter.js +1 -1
  91. package/dist/konduitAnalyticsAdapter.js +1 -1
  92. package/dist/kueezBidAdapter.js +1 -1
  93. package/dist/lassoBidAdapter.js +1 -1
  94. package/dist/lifestreetBidAdapter.js +1 -1
  95. package/dist/liveIntentId.js +1 -1
  96. package/dist/liveIntentIdSystem.js +1 -1
  97. package/dist/liveIntentRtdProvider.js +1 -0
  98. package/dist/logicadBidAdapter.js +1 -1
  99. package/dist/loglyliftBidAdapter.js +1 -1
  100. package/dist/luceadBidAdapter.js +1 -1
  101. package/dist/mabidderBidAdapter.js +1 -1
  102. package/dist/madsenseBidAdapter.js +1 -1
  103. package/dist/magniteAnalyticsAdapter.js +1 -1
  104. package/dist/malltvAnalyticsAdapter.js +1 -1
  105. package/dist/marsmediaBidAdapter.js +1 -1
  106. package/dist/mediafuseBidAdapter.js +1 -1
  107. package/dist/medianetAnalyticsAdapter.js +1 -1
  108. package/dist/medianetBidAdapter.js +1 -1
  109. package/dist/mediasquareBidAdapter.js +1 -1
  110. package/dist/mgidBidAdapter.js +1 -1
  111. package/dist/minutemediaBidAdapter.js +1 -1
  112. package/dist/missenaBidAdapter.js +1 -1
  113. package/dist/mspa.js +1 -1
  114. package/dist/nativeRendering.js +1 -1
  115. package/dist/nextMillenniumBidAdapter.js +1 -1
  116. package/dist/nexx360BidAdapter.js +1 -1
  117. package/dist/nobidAnalyticsAdapter.js +1 -1
  118. package/dist/nobidBidAdapter.js +1 -1
  119. package/dist/not-for-prod/prebid.js +193 -191
  120. package/dist/oguryBidAdapter.js +1 -1
  121. package/dist/omsBidAdapter.js +1 -1
  122. package/dist/onetagBidAdapter.js +1 -1
  123. package/dist/ooloAnalyticsAdapter.js +1 -1
  124. package/dist/openwebBidAdapter.js +1 -1
  125. package/dist/openxBidAdapter.js +1 -1
  126. package/dist/optidigitalBidAdapter.js +1 -1
  127. package/dist/orbidderBidAdapter.js +1 -1
  128. package/dist/orbitsoftBidAdapter.js +1 -1
  129. package/dist/outbrainBidAdapter.js +1 -1
  130. package/dist/pixfutureBidAdapter.js +1 -1
  131. package/dist/publinkIdSystem.js +1 -1
  132. package/dist/pubmaticAnalyticsAdapter.js +1 -1
  133. package/dist/pubmaticBidAdapter.js +1 -1
  134. package/dist/pubwiseAnalyticsAdapter.js +1 -1
  135. package/dist/pubxaiAnalyticsAdapter.js +1 -1
  136. package/dist/pxyzBidAdapter.js +1 -1
  137. package/dist/quantcastBidAdapter.js +1 -1
  138. package/dist/readpeakBidAdapter.js +1 -1
  139. package/dist/relaidoBidAdapter.js +1 -1
  140. package/dist/retailspotBidAdapter.js +1 -1
  141. package/dist/rhythmoneBidAdapter.js +1 -1
  142. package/dist/riseBidAdapter.js +1 -1
  143. package/dist/riseUtils.js +1 -1
  144. package/dist/rubiconBidAdapter.js +1 -1
  145. package/dist/seedingAllianceBidAdapter.js +1 -1
  146. package/dist/seedtagBidAdapter.js +1 -1
  147. package/dist/sharedIdSystem.js +1 -1
  148. package/dist/sharethroughAnalyticsAdapter.js +1 -1
  149. package/dist/sharethroughBidAdapter.js +1 -1
  150. package/dist/shinezBidAdapter.js +1 -1
  151. package/dist/showheroes-bsBidAdapter.js +1 -1
  152. package/dist/sizeUtils.js +1 -1
  153. package/dist/smaatoBidAdapter.js +1 -1
  154. package/dist/smartadserverBidAdapter.js +1 -1
  155. package/dist/smartxBidAdapter.js +1 -1
  156. package/dist/smilewantedBidAdapter.js +1 -1
  157. package/dist/snigelBidAdapter.js +1 -1
  158. package/dist/sonobiBidAdapter.js +1 -1
  159. package/dist/sovrnBidAdapter.js +1 -1
  160. package/dist/sparteoBidAdapter.js +1 -1
  161. package/dist/sspBCBidAdapter.js +1 -1
  162. package/dist/stnBidAdapter.js +1 -1
  163. package/dist/stvBidAdapter.js +1 -1
  164. package/dist/sublimeBidAdapter.js +1 -1
  165. package/dist/symitriDapRtdProvider.js +1 -1
  166. package/dist/taboolaBidAdapter.js +1 -1
  167. package/dist/tappxBidAdapter.js +1 -1
  168. package/dist/targetVideoBidAdapter.js +1 -1
  169. package/dist/teadsBidAdapter.js +1 -1
  170. package/dist/terceptAnalyticsAdapter.js +1 -1
  171. package/dist/themoneytizerBidAdapter.js +1 -1
  172. package/dist/trionBidAdapter.js +1 -1
  173. package/dist/tripleliftBidAdapter.js +1 -1
  174. package/dist/ttdBidAdapter.js +1 -1
  175. package/dist/ucfunnelAnalyticsAdapter.js +1 -1
  176. package/dist/uid2IdSystem.js +1 -1
  177. package/dist/underdogmediaBidAdapter.js +1 -1
  178. package/dist/undertoneBidAdapter.js +1 -1
  179. package/dist/unrulyBidAdapter.js +1 -1
  180. package/dist/userId.js +1 -1
  181. package/dist/vdoaiBidAdapter.js +1 -1
  182. package/dist/vidazooUtils.js +1 -1
  183. package/dist/videobyteBidAdapter.js +1 -1
  184. package/dist/visxBidAdapter.js +1 -1
  185. package/dist/vuukleBidAdapter.js +1 -1
  186. package/dist/widespaceBidAdapter.js +1 -1
  187. package/dist/winrBidAdapter.js +1 -1
  188. package/dist/wurflRtdProvider.js +1 -1
  189. package/dist/yahooAdsBidAdapter.js +1 -1
  190. package/dist/yieldlabBidAdapter.js +1 -1
  191. package/dist/yieldmoBidAdapter.js +1 -1
  192. package/dist/yieldoneAnalyticsAdapter.js +1 -1
  193. package/dist/zeta_global_sspAnalyticsAdapter.js +1 -1
  194. package/integrationExamples/gpt/liveIntentRtdProviderExample.html +164 -0
  195. package/integrationExamples/videoModule/jwplayer/bidMarkedAsUsed.html +3 -1
  196. package/integrationExamples/videoModule/jwplayer/bidRequestScheduling.html +2 -0
  197. package/integrationExamples/videoModule/jwplayer/bidsBackHandlerOverride.html +2 -0
  198. package/integrationExamples/videoModule/jwplayer/eventListeners.html +2 -0
  199. package/integrationExamples/videoModule/jwplayer/eventsUI.html +2 -0
  200. package/integrationExamples/videoModule/jwplayer/gamAdServerMediation.html +2 -0
  201. package/integrationExamples/videoModule/jwplayer/mediaMetadata.html +3 -1
  202. package/integrationExamples/videoModule/jwplayer/playlist.html +3 -1
  203. package/libraries/creative-renderer-native/renderer.js +1 -1
  204. package/libraries/intentIqConstants/intentIqConstants.js +1 -1
  205. package/libraries/liveIntentId/shared.js +18 -5
  206. package/libraries/mspa/activityControls.js +26 -7
  207. package/libraries/riseUtils/constants.js +20 -0
  208. package/libraries/riseUtils/index.js +143 -38
  209. package/libraries/sizeUtils/sizeUtils.js +25 -0
  210. package/libraries/vidazooUtils/bidderUtils.js +2 -0
  211. package/modules/33acrossIdSystem.js +64 -23
  212. package/modules/33acrossIdSystem.md +2 -1
  213. package/modules/acuityadsBidAdapter.js +1 -1
  214. package/modules/adagioRtdProvider.js +15 -9
  215. package/modules/adlooxAnalyticsAdapter.js +12 -6
  216. package/modules/blueBidAdapter.js +122 -0
  217. package/modules/blueBidAdapter.md +28 -0
  218. package/modules/conceptxBidAdapter.js +2 -0
  219. package/modules/consumableBidAdapter.js +3 -1
  220. package/modules/contxtfulBidAdapter.js +25 -13
  221. package/modules/contxtfulRtdProvider.js +9 -12
  222. package/modules/eplanningBidAdapter.js +5 -1
  223. package/modules/equativBidAdapter.js +13 -18
  224. package/modules/escalaxBidAdapter.js +2 -2
  225. package/modules/eskimiBidAdapter.js +4 -1
  226. package/modules/improvedigitalBidAdapter.js +0 -67
  227. package/modules/intentIqAnalyticsAdapter.js +1 -1
  228. package/modules/ixBidAdapter.js +7 -1
  229. package/modules/jwplayerVideoProvider.js +99 -6
  230. package/modules/liveIntentRtdProvider.js +52 -0
  231. package/modules/liveIntentRtdProvider.md +45 -0
  232. package/modules/minutemediaBidAdapter.js +6 -80
  233. package/modules/minutemediaBidAdapter.md +1 -1
  234. package/modules/missenaBidAdapter.js +2 -0
  235. package/modules/nativeRendering.js +2 -1
  236. package/modules/omsBidAdapter.js +25 -11
  237. package/modules/omsBidAdapter.md +15 -0
  238. package/modules/openwebBidAdapter.js +6 -81
  239. package/modules/openwebBidAdapter.md +1 -1
  240. package/modules/openxBidAdapter.js +19 -6
  241. package/modules/openxBidAdapter.md +46 -1
  242. package/modules/orbitsoftBidAdapter.js +1 -1
  243. package/modules/permutiveRtdProvider.md +6 -5
  244. package/modules/pubmaticAnalyticsAdapter.js +61 -19
  245. package/modules/riseBidAdapter.js +11 -92
  246. package/modules/riseBidAdapter.md +1 -1
  247. package/modules/sharedIdSystem.js +9 -3
  248. package/modules/shinezBidAdapter.js +4 -80
  249. package/modules/shinezBidAdapter.md +2 -2
  250. package/modules/stnBidAdapter.js +7 -86
  251. package/modules/stnBidAdapter.md +1 -1
  252. package/modules/symitriDapRtdProvider.js +4 -4
  253. package/modules/symitriDapRtdProvider.md +2 -2
  254. package/modules/userId/eids.js +32 -5
  255. package/modules/wurflRtdProvider.js +7 -1
  256. package/modules/wurflRtdProvider.md +1 -1
  257. package/modules/yieldlabBidAdapter.js +2 -2
  258. package/modules/zeta_global_sspAnalyticsAdapter.js +5 -2
  259. package/package.json +2 -2
  260. package/src/adapters/bidderFactory.js +7 -6
  261. package/src/adloader.js +0 -1
  262. package/src/native.js +6 -3
  263. package/test/spec/creative/nativeRenderer_spec.js +45 -10
  264. package/test/spec/libraries/mspa/activityControls_spec.js +63 -9
  265. package/test/spec/modules/33acrossIdSystem_spec.js +288 -2
  266. package/test/spec/modules/acuityadsBidAdapter_spec.js +49 -0
  267. package/test/spec/modules/adagioRtdProvider_spec.js +119 -3
  268. package/test/spec/modules/adlooxAdServerVideo_spec.js +0 -1
  269. package/test/spec/modules/adlooxAnalyticsAdapter_spec.js +31 -0
  270. package/test/spec/modules/blueBidAdapter_spec.js +91 -0
  271. package/test/spec/modules/consumableBidAdapter_spec.js +42 -0
  272. package/test/spec/modules/contxtfulRtdProvider_spec.js +37 -2
  273. package/test/spec/modules/eplanningBidAdapter_spec.js +74 -1
  274. package/test/spec/modules/equativBidAdapter_spec.js +5 -6
  275. package/test/spec/modules/excoBidAdapter_spec.js +33 -18
  276. package/test/spec/modules/illuminBidAdapter_spec.js +33 -18
  277. package/test/spec/modules/improvedigitalBidAdapter_spec.js +3 -3
  278. package/test/spec/modules/ixBidAdapter_spec.js +68 -2
  279. package/test/spec/modules/kueezRtbBidAdapter_spec.js +33 -18
  280. package/test/spec/modules/liveIntentExternalIdSystem_spec.js +16 -6
  281. package/test/spec/modules/liveIntentIdMinimalSystem_spec.js +16 -6
  282. package/test/spec/modules/liveIntentIdSystem_spec.js +49 -6
  283. package/test/spec/modules/liveIntentRtdProvider_spec.js +116 -0
  284. package/test/spec/modules/minutemediaBidAdapter_spec.js +126 -6
  285. package/test/spec/modules/missenaBidAdapter_spec.js +12 -3
  286. package/test/spec/modules/omsBidAdapter_spec.js +78 -0
  287. package/test/spec/modules/openwebBidAdapter_spec.js +126 -6
  288. package/test/spec/modules/openxBidAdapter_spec.js +236 -8
  289. package/test/spec/modules/pubmaticAnalyticsAdapter_spec.js +29 -36
  290. package/test/spec/modules/riseBidAdapter_spec.js +126 -6
  291. package/test/spec/modules/sharedIdSystem_spec.js +25 -1
  292. package/test/spec/modules/shinezBidAdapter_spec.js +133 -9
  293. package/test/spec/modules/shinezRtbBidAdapter_spec.js +33 -18
  294. package/test/spec/modules/stnBidAdapter_spec.js +126 -5
  295. package/test/spec/modules/symitriDapRtdProvider_spec.js +36 -0
  296. package/test/spec/modules/tagorasBidAdapter_spec.js +33 -18
  297. package/test/spec/modules/twistDigitalBidAdapter_spec.js +34 -18
  298. package/test/spec/modules/userId_spec.js +103 -2
  299. package/test/spec/modules/vidazooBidAdapter_spec.js +34 -18
  300. package/test/spec/modules/videoModule/submodules/jwplayerVideoProvider_spec.js +81 -0
  301. package/test/spec/modules/wurflRtdProvider_spec.js +8 -3
  302. package/test/spec/modules/yieldlabBidAdapter_spec.js +5 -5
  303. package/test/spec/modules/zeta_global_sspAnalyticsAdapter_spec.js +3 -2
  304. package/test/spec/native_spec.js +4 -2
  305. package/test/spec/unit/core/bidderFactory_spec.js +120 -43
@@ -1,34 +1,135 @@
1
1
  import {
2
- isArray,
3
- isFn,
2
+ contains,
4
3
  deepAccess,
4
+ getBidIdParameter,
5
+ isArray,
5
6
  isEmpty,
6
- contains,
7
+ isFn,
7
8
  isInteger,
8
- getBidIdParameter,
9
- isPlainObject
9
+ isPlainObject,
10
+ logInfo,
11
+ triggerPixel
10
12
  } from '../../src/utils.js';
11
- import { BANNER, VIDEO } from '../../src/mediaTypes.js';
13
+ import {BANNER, NATIVE, VIDEO} from '../../src/mediaTypes.js';
12
14
  import {config} from '../../src/config.js';
15
+ import {ADAPTER_VERSION, DEFAULT_CURRENCY, DEFAULT_TTL, SUPPORTED_AD_TYPES} from './constants.js';
16
+
17
+ export const makeBaseSpec = (baseUrl, modes) => {
18
+ return {
19
+ version: ADAPTER_VERSION,
20
+ supportedMediaTypes: SUPPORTED_AD_TYPES,
21
+ buildRequests: function (validBidRequests, bidderRequest) {
22
+ const combinedRequestsObject = {};
23
+
24
+ // use data from the first bid, to create the general params for all bids
25
+ const generalObject = validBidRequests[0];
26
+ const testMode = generalObject.params.testMode;
27
+ const rtbDomain = generalObject.params.rtbDomain || baseUrl;
28
+
29
+ combinedRequestsObject.params = generateGeneralParams(generalObject, bidderRequest);
30
+ combinedRequestsObject.bids = generateBidsParams(validBidRequests, bidderRequest);
31
+
32
+ return {
33
+ method: 'POST',
34
+ url: getEndpoint(testMode, rtbDomain, modes),
35
+ data: combinedRequestsObject
36
+ }
37
+ },
38
+ interpretResponse: function ({ body }) {
39
+ const bidResponses = [];
40
+
41
+ if (body.bids) {
42
+ body.bids.forEach(adUnit => {
43
+ const bidResponse = buildBidResponse(adUnit);
44
+ bidResponses.push(bidResponse);
45
+ });
46
+ }
47
+
48
+ return bidResponses;
49
+ },
50
+ getUserSyncs: function (syncOptions, serverResponses) {
51
+ const syncs = [];
52
+ for (const response of serverResponses) {
53
+ if (syncOptions.iframeEnabled && deepAccess(response, 'body.params.userSyncURL')) {
54
+ syncs.push({
55
+ type: 'iframe',
56
+ url: deepAccess(response, 'body.params.userSyncURL')
57
+ });
58
+ }
59
+ if (syncOptions.pixelEnabled && isArray(deepAccess(response, 'body.params.userSyncPixels'))) {
60
+ const pixels = response.body.params.userSyncPixels.map(pixel => {
61
+ return {
62
+ type: 'image',
63
+ url: pixel
64
+ }
65
+ });
66
+ syncs.push(...pixels);
67
+ }
68
+ }
69
+ return syncs;
70
+ },
71
+ onBidWon: function (bid) {
72
+ if (bid == null) {
73
+ return;
74
+ }
75
+
76
+ logInfo('onBidWon:', bid);
77
+ if (bid.hasOwnProperty('nurl') && bid.nurl.length > 0) {
78
+ triggerPixel(bid.nurl);
79
+ }
80
+ }
81
+ }
82
+ }
83
+
84
+ export function getBidRequestMediaTypes(bidRequest) {
85
+ const mediaTypes = deepAccess(bidRequest, 'mediaTypes');
86
+ if (isPlainObject(mediaTypes)) {
87
+ return Object.keys(mediaTypes);
88
+ }
89
+ return [];
90
+ }
91
+
92
+ export function getPos(bidRequest) {
93
+ const mediaTypes = getBidRequestMediaTypes(bidRequest);
94
+ const firstMediaType = mediaTypes[0];
95
+ if (mediaTypes.length === 1) {
96
+ return deepAccess(bidRequest, `mediaTypes.${firstMediaType}.pos`);
97
+ }
98
+ }
99
+
100
+ export function getName(bidRequest) {
101
+ const mediaTypes = getBidRequestMediaTypes(bidRequest);
102
+ const firstMediaType = mediaTypes[0];
103
+ if (mediaTypes.length === 1) {
104
+ return deepAccess(bidRequest, `mediaTypes.${firstMediaType}.name`);
105
+ }
106
+ }
13
107
 
14
- export function getFloor(bid, mediaType) {
108
+ export function getFloor(bid) {
15
109
  if (!isFn(bid.getFloor)) {
16
110
  return 0;
17
111
  }
112
+
113
+ const mediaTypes = getBidRequestMediaTypes(bid)
114
+ const firstMediaType = mediaTypes[0];
115
+
18
116
  let floorResult = bid.getFloor({
19
117
  currency: 'USD',
20
- mediaType: mediaType,
118
+ mediaType: mediaTypes.length === 1 ? firstMediaType : '*',
21
119
  size: '*'
22
120
  });
23
121
  return isPlainObject(floorResult) && floorResult.currency === 'USD' && floorResult.floor ? floorResult.floor : 0;
24
122
  }
25
123
 
26
- export function getSizesArray(bid, mediaType) {
124
+ export function getSizesArray(bid) {
27
125
  let sizesArray = [];
28
126
 
29
- if (deepAccess(bid, `mediaTypes.${mediaType}.sizes`)) {
30
- sizesArray = bid.mediaTypes[mediaType].sizes;
31
- } else if (Array.isArray(bid.sizes) && bid.sizes.length > 0) {
127
+ const mediaTypes = getBidRequestMediaTypes(bid);
128
+ const firstMediaType = mediaTypes[0];
129
+
130
+ if (mediaTypes.length === 1 && deepAccess(bid, `mediaTypes.${firstMediaType}.sizes`)) {
131
+ sizesArray = bid.mediaTypes[firstMediaType].sizes;
132
+ } else if (isArray(bid.sizes) && bid.sizes.length > 0) {
32
133
  sizesArray = bid.sizes;
33
134
  }
34
135
 
@@ -111,18 +212,17 @@ export function generateBidsParams(validBidRequests, bidderRequest) {
111
212
 
112
213
  export function generateBidParameters(bid, bidderRequest) {
113
214
  const { params } = bid;
114
- const mediaType = isBanner(bid) ? BANNER : VIDEO;
115
- const sizesArray = getSizesArray(bid, mediaType);
215
+ const mediaTypes = getBidRequestMediaTypes(bid);
116
216
 
117
217
  if (isNaN(params.floorPrice)) {
118
218
  params.floorPrice = 0;
119
219
  }
120
220
 
121
221
  const bidObject = {
122
- mediaType,
222
+ mediaType: mediaTypes.join(','),
123
223
  adUnitCode: getBidIdParameter('adUnitCode', bid),
124
- sizes: sizesArray,
125
- floorPrice: Math.max(getFloor(bid, mediaType), params.floorPrice),
224
+ sizes: getSizesArray(bid),
225
+ floorPrice: Math.max(getFloor(bid), params.floorPrice),
126
226
  bidId: getBidIdParameter('bidId', bid),
127
227
  loop: bid.bidderRequestsCount || 0,
128
228
  bidderRequestId: getBidIdParameter('bidderRequestId', bid),
@@ -130,8 +230,8 @@ export function generateBidParameters(bid, bidderRequest) {
130
230
  coppa: 0,
131
231
  };
132
232
 
133
- const pos = deepAccess(bid, `mediaTypes.${mediaType}.pos`);
134
- if (pos) {
233
+ const pos = getPos(bid);
234
+ if (isInteger(pos)) {
135
235
  bidObject.pos = pos;
136
236
  }
137
237
 
@@ -140,21 +240,11 @@ export function generateBidParameters(bid, bidderRequest) {
140
240
  bidObject.gpid = gpid;
141
241
  }
142
242
 
143
- const placementId = params.placementId || deepAccess(bid, `mediaTypes.${mediaType}.name`);
243
+ const placementId = params.placementId || getName(bid);
144
244
  if (placementId) {
145
245
  bidObject.placementId = placementId;
146
246
  }
147
247
 
148
- const mimes = deepAccess(bid, `mediaTypes.${mediaType}.mimes`);
149
- if (mimes) {
150
- bidObject.mimes = mimes;
151
- }
152
-
153
- const api = deepAccess(bid, `mediaTypes.${mediaType}.api`);
154
- if (api) {
155
- bidObject.api = api;
156
- }
157
-
158
248
  const sua = deepAccess(bid, `ortb2.device.sua`);
159
249
  if (sua) {
160
250
  bidObject.sua = sua;
@@ -165,11 +255,11 @@ export function generateBidParameters(bid, bidderRequest) {
165
255
  bidObject.coppa = 1;
166
256
  }
167
257
 
168
- if (mediaType === VIDEO) {
258
+ if (mediaTypes.includes(VIDEO)) {
169
259
  const playbackMethod = deepAccess(bid, `mediaTypes.video.playbackmethod`);
170
260
  let playbackMethodValue;
171
261
 
172
- if (Array.isArray(playbackMethod) && isInteger(playbackMethod[0])) {
262
+ if (isArray(playbackMethod) && isInteger(playbackMethod[0])) {
173
263
  playbackMethodValue = playbackMethod[0];
174
264
  } else if (isInteger(playbackMethod)) {
175
265
  playbackMethodValue = playbackMethod;
@@ -213,19 +303,36 @@ export function generateBidParameters(bid, bidderRequest) {
213
303
  if (plcmt) {
214
304
  bidObject.plcmt = plcmt;
215
305
  }
306
+
307
+ const mimes = deepAccess(bid, `mediaTypes.video.mimes`);
308
+ if (mimes) {
309
+ bidObject.mimes = mimes;
310
+ }
311
+
312
+ const api = deepAccess(bid, `mediaTypes.video.api`);
313
+ if (api) {
314
+ bidObject.api = api;
315
+ }
316
+ }
317
+
318
+ if (mediaTypes.includes(NATIVE)) {
319
+ const nativeOrtbRequest = deepAccess(bid, `nativeOrtbRequest`);
320
+ if (nativeOrtbRequest) {
321
+ bidObject.nativeOrtbRequest = nativeOrtbRequest;
322
+ }
216
323
  }
217
324
 
218
325
  return bidObject;
219
326
  }
220
327
 
221
- export function buildBidResponse(adUnit, DEFAULT_CURRENCY, TTL, VIDEO, BANNER) {
328
+ export function buildBidResponse(adUnit) {
222
329
  const bidResponse = {
223
330
  requestId: adUnit.requestId,
224
331
  cpm: adUnit.cpm,
225
332
  currency: adUnit.currency || DEFAULT_CURRENCY,
226
333
  width: adUnit.width,
227
334
  height: adUnit.height,
228
- ttl: adUnit.ttl || TTL,
335
+ ttl: adUnit.ttl || DEFAULT_TTL,
229
336
  creativeId: adUnit.creativeId,
230
337
  netRevenue: adUnit.netRevenue || true,
231
338
  nurl: adUnit.nurl,
@@ -239,6 +346,8 @@ export function buildBidResponse(adUnit, DEFAULT_CURRENCY, TTL, VIDEO, BANNER) {
239
346
  bidResponse.vastXml = adUnit.vastXml;
240
347
  } else if (adUnit.mediaType === BANNER) {
241
348
  bidResponse.ad = adUnit.ad;
349
+ } else if (adUnit.mediaType === NATIVE) {
350
+ bidResponse.native = {ortb: adUnit.native};
242
351
  }
243
352
 
244
353
  if (adUnit.adomain && adUnit.adomain.length) {
@@ -248,10 +357,6 @@ export function buildBidResponse(adUnit, DEFAULT_CURRENCY, TTL, VIDEO, BANNER) {
248
357
  return bidResponse;
249
358
  }
250
359
 
251
- function isBanner(bid) {
252
- return bid.mediaTypes && bid.mediaTypes.banner;
253
- }
254
-
255
360
  export function generateGeneralParams(generalObject, bidderRequest, adapterVersion) {
256
361
  const domain = window.location.hostname;
257
362
  const { syncEnabled, filterSettings } = config.getConfig('userSync') || {};
@@ -27,3 +27,28 @@ export function getAdUnitSizes(adUnit) {
27
27
  }
28
28
  return sizes;
29
29
  }
30
+
31
+ /**
32
+ * Normalize adUnit.mediaTypes.banner.sizes to Array.<Array.<number>>
33
+ *
34
+ * @param {Array.<number|string> | Array.<Array.<number|string>>} bidSizes - value of adUnit.mediaTypes.banner.sizes.
35
+ * @returns {Array.<Array.<number>>} - Normalized value.
36
+ */
37
+
38
+ export function normalizeBannerSizes(bidSizes) {
39
+ let sizes = [];
40
+ if (Array.isArray(bidSizes) && bidSizes.length === 2 && !Array.isArray(bidSizes[0])) {
41
+ sizes.push({
42
+ width: parseInt(bidSizes[0], 10),
43
+ height: parseInt(bidSizes[1], 10),
44
+ });
45
+ } else if (Array.isArray(bidSizes) && Array.isArray(bidSizes[0])) {
46
+ bidSizes.forEach((size) => {
47
+ sizes.push({
48
+ width: parseInt(size[0], 10),
49
+ height: parseInt(size[1], 10),
50
+ });
51
+ });
52
+ }
53
+ return sizes;
54
+ }
@@ -247,6 +247,7 @@ export function buildRequestData(bid, topWindowUrl, sizes, bidderRequest, bidder
247
247
  const userData = deepAccess(bidderRequest, 'ortb2.user.data', []);
248
248
  const contentLang = deepAccess(bidderRequest, 'ortb2.site.content.language') || document.documentElement.lang;
249
249
  const coppa = deepAccess(bidderRequest, 'ortb2.regs.coppa', 0);
250
+ const device = deepAccess(bidderRequest, 'ortb2.device', {});
250
251
 
251
252
  if (isFn(bid.getFloor)) {
252
253
  const floorInfo = bid.getFloor({
@@ -290,6 +291,7 @@ export function buildRequestData(bid, topWindowUrl, sizes, bidderRequest, bidder
290
291
  bidderRequestsCount: bidderRequestsCount,
291
292
  bidderWinsCount: bidderWinsCount,
292
293
  bidderTimeout: bidderTimeout,
294
+ device,
293
295
  ...uniqueRequestData
294
296
  };
295
297
 
@@ -60,7 +60,7 @@ function calculateResponseObj(response) {
60
60
  };
61
61
  }
62
62
 
63
- function calculateQueryStringParams({ pid, hem }, gdprConsentData, enabledStorageTypes) {
63
+ function calculateQueryStringParams({ pid, pubProvidedHem }, gdprConsentData, enabledStorageTypes) {
64
64
  const uspString = uspDataHandler.getConsentData();
65
65
  const coppaValue = coppaDataHandler.getCoppa();
66
66
  const gppConsent = gppDataHandler.getConsentData();
@@ -98,9 +98,9 @@ function calculateQueryStringParams({ pid, hem }, gdprConsentData, enabledStorag
98
98
  params.tp = encodeURIComponent(tp);
99
99
  }
100
100
 
101
- const hemParam = hem || getStoredValue(STORAGE_HEM_KEY, enabledStorageTypes);
102
- if (hemParam) {
103
- params.sha256 = encodeURIComponent(hemParam);
101
+ const hem = pubProvidedHem || getStoredValue(STORAGE_HEM_KEY, enabledStorageTypes);
102
+ if (hem) {
103
+ params.sha256 = encodeURIComponent(hem);
104
104
  }
105
105
 
106
106
  return params;
@@ -145,10 +145,51 @@ function getStoredValue(key, enabledStorageTypes) {
145
145
  return storedValue;
146
146
  }
147
147
 
148
- function handleSupplementalId(key, id, storageConfig) {
149
- id
150
- ? storeValue(key, id, storageConfig)
151
- : deleteFromStorage(key);
148
+ function filterEnabledSupplementalIds({ tp, fp, hem }, { storeFpid, storeTpid, envelopeAvailable }) {
149
+ const ids = [];
150
+
151
+ if (storeFpid) {
152
+ ids.push(
153
+ /**
154
+ * [
155
+ * <storage key>,
156
+ * < ID value to store or remove >,
157
+ * < clear flag: indicates if existing storage item should be removed or not based on certain condition>
158
+ * ]
159
+ */
160
+ [STORAGE_FPID_KEY, fp, !fp],
161
+ [STORAGE_HEM_KEY, hem, !envelopeAvailable] // Clear hashed email if envelope is not available
162
+ );
163
+ }
164
+
165
+ if (storeTpid) {
166
+ ids.push([STORAGE_TPID_KEY, tp, !tp]);
167
+ }
168
+
169
+ return ids;
170
+ }
171
+
172
+ function updateSupplementalIdStorage(supplementalId, storageConfig) {
173
+ const [ key, id, clear ] = supplementalId;
174
+
175
+ if (clear) {
176
+ deleteFromStorage(key);
177
+
178
+ return;
179
+ }
180
+
181
+ if (id) {
182
+ storeValue(key, id, storageConfig);
183
+ }
184
+ }
185
+
186
+ function handleSupplementalIds(ids, { enabledStorageTypes, expires, ...options }) {
187
+ filterEnabledSupplementalIds(ids, options).forEach((supplementalId) => {
188
+ updateSupplementalIdStorage(supplementalId, {
189
+ enabledStorageTypes,
190
+ expires
191
+ })
192
+ });
152
193
  }
153
194
 
154
195
  /** @type {Submodule} */
@@ -197,8 +238,10 @@ export const thirtyThreeAcrossIdSubmodule = {
197
238
  const {
198
239
  storeFpid = DEFAULT_1PID_SUPPORT,
199
240
  storeTpid = DEFAULT_TPID_SUPPORT, apiUrl = API_URL,
200
- ...options
241
+ pid,
242
+ hem
201
243
  } = params;
244
+ const pubProvidedHem = hem || window._33across?.hem?.sha256;
202
245
 
203
246
  return {
204
247
  callback(cb) {
@@ -218,19 +261,17 @@ export const thirtyThreeAcrossIdSubmodule = {
218
261
  });
219
262
  }
220
263
 
221
- if (storeFpid) {
222
- handleSupplementalId(STORAGE_FPID_KEY, responseObj.fp, {
223
- enabledStorageTypes,
224
- expires: storageConfig.expires
225
- });
226
- }
227
-
228
- if (storeTpid) {
229
- handleSupplementalId(STORAGE_TPID_KEY, responseObj.tp, {
230
- enabledStorageTypes,
231
- expires: storageConfig.expires
232
- });
233
- }
264
+ handleSupplementalIds({
265
+ fp: responseObj.fp,
266
+ tp: responseObj.tp,
267
+ hem: pubProvidedHem
268
+ }, {
269
+ storeFpid,
270
+ storeTpid,
271
+ envelopeAvailable: !!responseObj.envelope,
272
+ enabledStorageTypes,
273
+ expires: storageConfig.expires
274
+ });
234
275
 
235
276
  cb(responseObj.envelope);
236
277
  },
@@ -239,7 +280,7 @@ export const thirtyThreeAcrossIdSubmodule = {
239
280
 
240
281
  cb();
241
282
  }
242
- }, calculateQueryStringParams(options, gdprConsentData, enabledStorageTypes), {
283
+ }, calculateQueryStringParams({ pid, pubProvidedHem }, gdprConsentData, enabledStorageTypes), {
243
284
  method: 'GET',
244
285
  withCredentials: true
245
286
  });
@@ -57,4 +57,5 @@ The following settings are available in the `params` property in `userSync.userI
57
57
 
58
58
  ### HEM Collection
59
59
 
60
- 33Across ID System supports user's hashed email, if available in storage.
60
+ 33Across ID System supports user's hashed emails (HEMs). HEMs could be collected from 3 different sources in following
61
+ priority order: `hem` configuration parameter, global `_33across.hem.sha256` field or from storage (cookie or local storage).
@@ -12,7 +12,7 @@ export const spec = {
12
12
  gvlid: GVLID,
13
13
  supportedMediaTypes: [BANNER, VIDEO, NATIVE],
14
14
 
15
- isBidRequestValid: isBidRequestValid(['placementId']),
15
+ isBidRequestValid: isBidRequestValid(),
16
16
  buildRequests: buildRequests(AD_URL),
17
17
  interpretResponse,
18
18
  getUserSyncs: getUserSyncs(SYNC_URL)
@@ -76,15 +76,17 @@ const _SESSION = (function() {
76
76
 
77
77
  const isNewSess = isNewSession(expiry);
78
78
 
79
- // if lastActivityTime is defined it means that the website is using the original version of the snippet
80
- const v = !lastActivityTime ? LATEST_ABTEST_VERSION : undefined;
79
+ const abTest = _internal.getAbTestFromLocalStorage(storageValue);
80
+
81
+ // if abTest is defined it means that the website is using the new version of the snippet
82
+ const v = abTest ? LATEST_ABTEST_VERSION : undefined;
81
83
 
82
84
  data.session = {
83
- v,
84
85
  rnd,
85
86
  pages: pages || 1,
86
87
  new: isNewSess, // legacy: `new` was used but the choosen name is not good.
87
88
  // Don't use values if they are not defined.
89
+ ...(v !== undefined && { v }),
88
90
  ...(vwSmplg !== undefined && { vwSmplg }),
89
91
  ...(vwSmplgNxt !== undefined && { vwSmplgNxt }),
90
92
  ...(expiry !== undefined && { expiry }),
@@ -98,15 +100,19 @@ const _SESSION = (function() {
98
100
  data.session.rnd = Math.random();
99
101
  }
100
102
 
101
- const { testName, testVersion, expiry: abTestExpiry, sessionId } = _internal.getAbTestFromLocalStorage(storageValue);
102
103
  if (v === LATEST_ABTEST_VERSION) {
104
+ const { testName, testVersion, expiry: abTestExpiry, sessionId } = abTest;
103
105
  if (abTestExpiry && abTestExpiry > Date.now() && (!sessionId || sessionId === data.session.id)) { // if AbTest didn't set a session id, it's probably because it's a new one and it didn't retrieve it yet, assume it's okay to get test Name and Version.
104
- data.session.testName = testName;
105
- data.session.testVersion = testVersion;
106
+ if (testName && testVersion) {
107
+ data.session.testName = testName;
108
+ data.session.testVersion = testVersion;
109
+ }
106
110
  }
107
111
  } else {
108
- data.session.testName = legacyTestName;
109
- data.session.testVersion = legacyTestVersion;
112
+ if (legacyTestName && legacyTestVersion) {
113
+ data.session.testName = legacyTestName;
114
+ data.session.testVersion = legacyTestVersion;
115
+ }
110
116
  }
111
117
 
112
118
  _internal.getAdagioNs().queue.push({
@@ -215,7 +221,7 @@ export const _internal = {
215
221
  getAbTestFromLocalStorage: function(storageValue) {
216
222
  const obj = this.getObjFromStorageValue(storageValue);
217
223
 
218
- return (!obj || !obj.abTest) ? {} : obj.abTest;
224
+ return (!obj || !obj.abTest) ? null : obj.abTest;
219
225
  },
220
226
 
221
227
  /**
@@ -81,8 +81,6 @@ const PARAMS_DEFAULT = {
81
81
  'id11': '$ADLOOX_WEBSITE'
82
82
  };
83
83
 
84
- const NOOP = function() {};
85
-
86
84
  let analyticsAdapter = Object.assign(adapter({ analyticsType: 'endpoint' }), {
87
85
  track({ eventType, args }) {
88
86
  if (!analyticsAdapter[`handle_${eventType}`]) return;
@@ -109,6 +107,10 @@ analyticsAdapter.enableAnalytics = function(config) {
109
107
  logError(MODULE, 'invalid js options value');
110
108
  return;
111
109
  }
110
+ if (isStr(config.options.js) && !/\.adlooxtracking\.(com|ru)$/.test(parseUrl(config.options.js, { 'noDecodeWholeURL': true }).host)) {
111
+ logError(MODULE, "invalid js options value, must be a sub-domain of 'adlooxtracking.com'");
112
+ return;
113
+ }
112
114
  if (!(config.options.toselector === undefined || isFn(config.options.toselector))) {
113
115
  logError(MODULE, 'invalid toselector options value');
114
116
  return;
@@ -221,20 +223,24 @@ analyticsAdapter.url = function(url, args, bid) {
221
223
  return url + a2qs(args);
222
224
  }
223
225
 
226
+ const preloaded = {};
224
227
  analyticsAdapter[`handle_${EVENTS.AUCTION_END}`] = function(auctionDetails) {
225
228
  if (!(auctionDetails.auctionStatus == AUCTION_COMPLETED && auctionDetails.bidsReceived.length > 0)) return;
226
- analyticsAdapter[`handle_${EVENTS.AUCTION_END}`] = NOOP;
227
-
228
- logMessage(MODULE, 'preloading verification JS');
229
229
 
230
230
  const uri = parseUrl(analyticsAdapter.url(`${analyticsAdapter.context.js}#`));
231
+ const href = `${uri.protocol}://${uri.host}${uri.pathname}`;
232
+ if (preloaded[href]) return;
233
+
234
+ logMessage(MODULE, 'preloading verification JS');
231
235
 
232
236
  const link = document.createElement('link');
233
- link.setAttribute('href', `${uri.protocol}://${uri.host}${uri.pathname}`);
237
+ link.setAttribute('href', href);
234
238
  link.setAttribute('rel', 'preload');
235
239
  link.setAttribute('as', 'script');
236
240
  // TODO fix rules violation
237
241
  insertElement(link);
242
+
243
+ preloaded[href] = true;
238
244
  }
239
245
 
240
246
  analyticsAdapter[`handle_${EVENTS.BID_WON}`] = function(bid) {
@@ -0,0 +1,122 @@
1
+ import { ortbConverter } from '../libraries/ortbConverter/converter.js';
2
+ import { registerBidder } from '../src/adapters/bidderFactory.js';
3
+ import { BANNER } from '../src/mediaTypes.js';
4
+ import { getStorageManager } from '../src/storageManager.js';
5
+ import { deepSetValue, isFn, isPlainObject } from '../src/utils.js';
6
+
7
+ const BIDDER_CODE = 'blue';
8
+ const ENDPOINT_URL = 'https://bidder-us-east-1.getblue.io/engine/?src=prebid';
9
+ const GVLID = 620; // GVLID for your bidder
10
+ const COOKIE_NAME = 'ckid'; // Cookie name for identifying users
11
+ const CURRENCY = 'USD'; // Currency used in bid floors
12
+
13
+ export const storage = getStorageManager({ bidderCode: BIDDER_CODE });
14
+
15
+ const converter = ortbConverter({
16
+ context: {
17
+ netRevenue: true, // Default netRevenue setting
18
+ ttl: 100, // Default time-to-live for bid responses
19
+ },
20
+ imp,
21
+ request,
22
+ });
23
+
24
+ function request(buildRequest, imps, bidderRequest, context) {
25
+ let request = buildRequest(imps, bidderRequest, context);
26
+ deepSetValue(request, 'site.publisher.id', context.publisherId);
27
+ return request;
28
+ }
29
+
30
+ function imp(buildImp, bidRequest, context) {
31
+ const imp = buildImp(bidRequest, context);
32
+ const floor = getBidFloor(bidRequest);
33
+ if (floor) {
34
+ imp.bidfloor = floor;
35
+ imp.bidfloorcur = CURRENCY;
36
+ }
37
+ return imp;
38
+ }
39
+
40
+ function getBidFloor(bid) {
41
+ if (isFn(bid.getFloor)) {
42
+ let floor = bid.getFloor({
43
+ currency: CURRENCY,
44
+ mediaType: BANNER,
45
+ size: '*',
46
+ });
47
+ if (
48
+ isPlainObject(floor) &&
49
+ !isNaN(floor.floor) &&
50
+ floor.currency === CURRENCY
51
+ ) {
52
+ return floor.floor;
53
+ }
54
+ }
55
+ return null;
56
+ }
57
+
58
+ export const spec = {
59
+ code: BIDDER_CODE,
60
+ gvlid: GVLID,
61
+ supportedMediaTypes: [BANNER], // Supported ad types
62
+
63
+ // Validate bid request
64
+ isBidRequestValid: function (bid) {
65
+ return !!bid.params.placementId && !!bid.params.publisherId;
66
+ },
67
+
68
+ // Build OpenRTB requests using `ortbConverter`
69
+ buildRequests: function (validBidRequests, bidderRequest) {
70
+ const context = {
71
+ publisherId: validBidRequests.find(
72
+ (bidRequest) => bidRequest.params?.publisherId
73
+ )?.params.publisherId,
74
+ };
75
+
76
+ const ortbRequest = converter.toORTB({
77
+ bidRequests: validBidRequests,
78
+ bidderRequest,
79
+ context,
80
+ });
81
+
82
+ // Add GVLID and cookie ID to the request
83
+ ortbRequest.ext = ortbRequest.ext || {};
84
+ deepSetValue(ortbRequest, 'ext.gvlid', GVLID);
85
+
86
+ // Include user cookie if available
87
+ const ckid = storage.getDataFromLocalStorage('blueID') || storage.getCookie(COOKIE_NAME) || null;
88
+ if (ckid) {
89
+ deepSetValue(ortbRequest, 'user.ext.buyerid', ckid);
90
+ }
91
+
92
+ return {
93
+ method: 'POST',
94
+ url: ENDPOINT_URL,
95
+ data: JSON.stringify(ortbRequest),
96
+ options: {
97
+ contentType: 'text/plain',
98
+ },
99
+ };
100
+ },
101
+
102
+ // Interpret OpenRTB responses using `ortbConverter`
103
+ interpretResponse: function (serverResponse, request) {
104
+ const ortbResponse = serverResponse.body;
105
+
106
+ // Parse the OpenRTB response into Prebid bid responses
107
+ const prebidResponses = converter.fromORTB({
108
+ response: ortbResponse,
109
+ request: request.data,
110
+ }).bids;
111
+
112
+ // Example: Modify bid responses if needed
113
+ prebidResponses.forEach((bid) => {
114
+ bid.meta = bid.meta || {};
115
+ bid.meta.adapterVersion = '1.0.0';
116
+ });
117
+
118
+ return prebidResponses;
119
+ },
120
+ };
121
+
122
+ registerBidder(spec);