prebid.js 9.0.0 → 9.2.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 (307) hide show
  1. package/.nvmrc +1 -1
  2. package/browsers.json +3 -3
  3. package/dist/33acrossAnalyticsAdapter.js +1 -1
  4. package/dist/33acrossBidAdapter.js +1 -1
  5. package/dist/33acrossIdSystem.js +1 -1
  6. package/dist/BTBidAdapter.js +1 -1
  7. package/dist/acuityadsBidAdapter.js +1 -1
  8. package/dist/adagioAnalyticsAdapter.js +1 -1
  9. package/dist/adagioBidAdapter.js +1 -1
  10. package/dist/adagioRtdProvider.js +1 -1
  11. package/dist/adagioUtils.js +1 -0
  12. package/dist/adgenerationBidAdapter.js +1 -1
  13. package/dist/admanBidAdapter.js +1 -1
  14. package/dist/adpod.js +1 -1
  15. package/dist/adprimeBidAdapter.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/adxcgBidAdapter.js +1 -1
  21. package/dist/adyoulikeBidAdapter.js +1 -1
  22. package/dist/agmaAnalyticsAdapter.js +1 -1
  23. package/dist/ajaBidAdapter.js +1 -1
  24. package/dist/amxBidAdapter.js +1 -1
  25. package/dist/amxIdSystem.js +1 -1
  26. package/dist/appierAnalyticsAdapter.js +1 -1
  27. package/dist/appnexusBidAdapter.js +1 -1
  28. package/dist/appnexusUtils.js +1 -1
  29. package/dist/asoBidAdapter.js +1 -1
  30. package/dist/autoplayDetection.js +1 -1
  31. package/dist/axisBidAdapter.js +1 -1
  32. package/dist/axonixBidAdapter.js +1 -1
  33. package/dist/beyondmediaBidAdapter.js +1 -1
  34. package/dist/bidglassBidAdapter.js +1 -1
  35. package/dist/big-richmediaBidAdapter.js +1 -1
  36. package/dist/bliinkBidAdapter.js +1 -1
  37. package/dist/boldwinBidAdapter.js +1 -1
  38. package/dist/bridBidAdapter.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/compassBidAdapter.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/contentexchangeBidAdapter.js +1 -1
  49. package/dist/conversantAnalyticsAdapter.js +1 -1
  50. package/dist/conversantBidAdapter.js +1 -1
  51. package/dist/craftBidAdapter.js +1 -1
  52. package/dist/criteoBidAdapter.js +1 -1
  53. package/dist/cwireBidAdapter.js +1 -1
  54. package/dist/dailymotionBidAdapter.js +1 -1
  55. package/dist/dependencies.json +83 -4
  56. package/dist/dspxBidAdapter.js +1 -1
  57. package/dist/dxkultureBidAdapter.js +1 -1
  58. package/dist/e_volutionBidAdapter.js +1 -1
  59. package/dist/emtvBidAdapter.js +1 -1
  60. package/dist/eplanningBidAdapter.js +1 -1
  61. package/dist/euidIdSystem.js +1 -1
  62. package/dist/exadsBidAdapter.js +1 -1
  63. package/dist/feedadBidAdapter.js +1 -1
  64. package/dist/finativeBidAdapter.js +1 -1
  65. package/dist/freewheel-sspBidAdapter.js +1 -1
  66. package/dist/globalsunBidAdapter.js +1 -1
  67. package/dist/gmosspBidAdapter.js +1 -1
  68. package/dist/goldbachBidAdapter.js +1 -1
  69. package/dist/greenbidsAnalyticsAdapter.js +1 -1
  70. package/dist/greenbidsRtdProvider.js +1 -1
  71. package/dist/gridBidAdapter.js +1 -1
  72. package/dist/gumgumBidAdapter.js +1 -1
  73. package/dist/h12mediaBidAdapter.js +1 -1
  74. package/dist/hypelabBidAdapter.js +1 -1
  75. package/dist/id5IdSystem.js +1 -1
  76. package/dist/illuminBidAdapter.js +1 -1
  77. package/dist/imdsBidAdapter.js +1 -1
  78. package/dist/improvedigitalBidAdapter.js +1 -1
  79. package/dist/insticatorBidAdapter.js +1 -1
  80. package/dist/iqzoneBidAdapter.js +1 -1
  81. package/dist/ixBidAdapter.js +1 -1
  82. package/dist/jixieBidAdapter.js +1 -1
  83. package/dist/justpremiumBidAdapter.js +1 -1
  84. package/dist/kargoBidAdapter.js +1 -1
  85. package/dist/kimberliteBidAdapter.js +1 -1
  86. package/dist/kiviadsBidAdapter.js +1 -1
  87. package/dist/konduitAnalyticsAdapter.js +1 -1
  88. package/dist/krushmediaBidAdapter.js +1 -1
  89. package/dist/kueezBidAdapter.js +1 -1
  90. package/dist/kueezRtbBidAdapter.js +1 -1
  91. package/dist/lassoBidAdapter.js +1 -1
  92. package/dist/lifestreetBidAdapter.js +1 -1
  93. package/dist/liveIntentIdSystem.js +1 -1
  94. package/dist/logicadBidAdapter.js +1 -1
  95. package/dist/loglyliftBidAdapter.js +1 -1
  96. package/dist/loyalBidAdapter.js +1 -1
  97. package/dist/luceadBidAdapter.js +1 -1
  98. package/dist/lunamediahbBidAdapter.js +1 -1
  99. package/dist/magniteAnalyticsAdapter.js +1 -1
  100. package/dist/malltvAnalyticsAdapter.js +1 -1
  101. package/dist/marsmediaBidAdapter.js +1 -1
  102. package/dist/mathildeadsBidAdapter.js +1 -1
  103. package/dist/mediafuseBidAdapter.js +1 -1
  104. package/dist/mediasquareBidAdapter.js +1 -1
  105. package/dist/mgidBidAdapter.js +1 -1
  106. package/dist/mgidXBidAdapter.js +1 -1
  107. package/dist/minutemediaBidAdapter.js +1 -1
  108. package/dist/missenaBidAdapter.js +1 -1
  109. package/dist/mobfoxpbBidAdapter.js +1 -1
  110. package/dist/mobianRtdProvider.js +1 -0
  111. package/dist/nexx360BidAdapter.js +1 -1
  112. package/dist/nobidAnalyticsAdapter.js +1 -1
  113. package/dist/nobidBidAdapter.js +1 -1
  114. package/dist/not-for-prod/prebid.js +190 -186
  115. package/dist/oguryBidAdapter.js +1 -1
  116. package/dist/onetagBidAdapter.js +1 -1
  117. package/dist/ooloAnalyticsAdapter.js +1 -1
  118. package/dist/openwebBidAdapter.js +1 -1
  119. package/dist/openxBidAdapter.js +1 -1
  120. package/dist/optidigitalBidAdapter.js +1 -1
  121. package/dist/ortbConverter.js +1 -1
  122. package/dist/outbrainBidAdapter.js +1 -1
  123. package/dist/ozoneBidAdapter.js +1 -1
  124. package/dist/paapi.js +1 -1
  125. package/dist/pgamsspBidAdapter.js +1 -1
  126. package/dist/pixfutureBidAdapter.js +1 -1
  127. package/dist/playdigoBidAdapter.js +1 -1
  128. package/dist/prebidServerBidAdapter.js +1 -1
  129. package/dist/pubCircleBidAdapter.js +1 -1
  130. package/dist/publinkIdSystem.js +1 -1
  131. package/dist/publirBidAdapter.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/qtBidAdapter.js +1 -1
  138. package/dist/quantcastBidAdapter.js +1 -1
  139. package/dist/raynRtdProvider.js +1 -1
  140. package/dist/readpeakBidAdapter.js +1 -1
  141. package/dist/relaidoBidAdapter.js +1 -1
  142. package/dist/retailspotBidAdapter.js +1 -1
  143. package/dist/rhythmoneBidAdapter.js +1 -1
  144. package/dist/richaudienceBidAdapter.js +1 -0
  145. package/dist/ringieraxelspringerBidAdapter.js +1 -1
  146. package/dist/riseBidAdapter.js +1 -1
  147. package/dist/rubiconBidAdapter.js +1 -1
  148. package/dist/seedingAllianceBidAdapter.js +1 -1
  149. package/dist/seedtagBidAdapter.js +1 -1
  150. package/dist/setupadBidAdapter.js +1 -1
  151. package/dist/sharethroughAnalyticsAdapter.js +1 -1
  152. package/dist/sharethroughBidAdapter.js +1 -1
  153. package/dist/shinezBidAdapter.js +1 -1
  154. package/dist/shinezRtbBidAdapter.js +1 -1
  155. package/dist/smaatoBidAdapter.js +1 -1
  156. package/dist/smartadserverBidAdapter.js +1 -1
  157. package/dist/smartxBidAdapter.js +1 -1
  158. package/dist/smartytechBidAdapter.js +1 -1
  159. package/dist/smilewantedBidAdapter.js +1 -1
  160. package/dist/sonobiBidAdapter.js +1 -1
  161. package/dist/sovrnBidAdapter.js +1 -1
  162. package/dist/sspBCBidAdapter.js +1 -1
  163. package/dist/stnBidAdapter.js +1 -1
  164. package/dist/stvBidAdapter.js +1 -1
  165. package/dist/sublimeBidAdapter.js +1 -1
  166. package/dist/taboolaBidAdapter.js +1 -1
  167. package/dist/tagorasBidAdapter.js +1 -1
  168. package/dist/targetVideoBidAdapter.js +1 -1
  169. package/dist/teadsBidAdapter.js +1 -1
  170. package/dist/teqblazeUtils.js +1 -0
  171. package/dist/themoneytizerBidAdapter.js +1 -1
  172. package/dist/topicsFpdModule.js +1 -1
  173. package/dist/trionBidAdapter.js +1 -1
  174. package/dist/tripleliftBidAdapter.js +1 -1
  175. package/dist/ttdBidAdapter.js +1 -1
  176. package/dist/twistDigitalBidAdapter.js +1 -1
  177. package/dist/ucfunnelAnalyticsAdapter.js +1 -1
  178. package/dist/uid2IdSystem.js +1 -1
  179. package/dist/underdogmediaBidAdapter.js +1 -1
  180. package/dist/undertoneBidAdapter.js +1 -1
  181. package/dist/unrulyBidAdapter.js +1 -1
  182. package/dist/vidazooBidAdapter.js +1 -1
  183. package/dist/videobyteBidAdapter.js +1 -1
  184. package/dist/visiblemeasuresBidAdapter.js +1 -1
  185. package/dist/visxBidAdapter.js +1 -1
  186. package/dist/vuukleBidAdapter.js +1 -1
  187. package/dist/widespaceBidAdapter.js +1 -1
  188. package/dist/winrBidAdapter.js +1 -1
  189. package/dist/yahooAdsBidAdapter.js +1 -1
  190. package/dist/yieldmoBidAdapter.js +1 -1
  191. package/dist/yieldoneAnalyticsAdapter.js +1 -1
  192. package/dist/zeta_global_sspAnalyticsAdapter.js +1 -1
  193. package/integrationExamples/gpt/raynRtdProvider_example.html +1 -0
  194. package/libraries/adagioUtils/adagioUtils.js +35 -0
  195. package/libraries/appnexusUtils/anUtils.js +1 -0
  196. package/libraries/autoplayDetection/autoplay.js +8 -1
  197. package/libraries/ortbConverter/converter.js +1 -1
  198. package/libraries/teqblazeUtils/bidderUtils.js +253 -0
  199. package/modules/.submodules.json +1 -0
  200. package/modules/acuityadsBidAdapter.js +5 -203
  201. package/modules/adagioBidAdapter.js +1 -17
  202. package/modules/adagioRtdProvider.js +41 -51
  203. package/modules/adagioRtdProvider.md +1 -0
  204. package/modules/admanBidAdapter.js +31 -188
  205. package/modules/adprimeBidAdapter.js +28 -165
  206. package/modules/axisBidAdapter.js +33 -165
  207. package/modules/beyondmediaBidAdapter.js +5 -189
  208. package/modules/bliinkBidAdapter.js +3 -31
  209. package/modules/boldwinBidAdapter.js +21 -159
  210. package/modules/ceeIdSystem.js +1 -1
  211. package/modules/compassBidAdapter.js +5 -198
  212. package/modules/contentexchangeBidAdapter.js +5 -200
  213. package/modules/conversantBidAdapter.js +1 -0
  214. package/modules/dailymotionBidAdapter.js +1 -1
  215. package/modules/e_volutionBidAdapter.js +4 -186
  216. package/modules/emtvBidAdapter.js +5 -198
  217. package/modules/globalsunBidAdapter.js +5 -199
  218. package/modules/id5IdSystem.js +31 -2
  219. package/modules/id5IdSystem.md +67 -2
  220. package/modules/iqzoneBidAdapter.js +5 -224
  221. package/modules/kiviadsBidAdapter.js +5 -199
  222. package/modules/krushmediaBidAdapter.js +25 -143
  223. package/modules/loyalBidAdapter.js +4 -178
  224. package/modules/lunamediahbBidAdapter.js +5 -118
  225. package/modules/mathildeadsBidAdapter.js +5 -198
  226. package/modules/mgidXBidAdapter.js +14 -209
  227. package/modules/mobfoxpbBidAdapter.js +4 -135
  228. package/modules/mobianRtdProvider.js +52 -0
  229. package/modules/mobianRtdProvider.md +11 -0
  230. package/modules/nobidAnalyticsAdapter.js +2 -3
  231. package/modules/novatiqIdSystem.md +2 -3
  232. package/modules/ozoneBidAdapter.js +117 -58
  233. package/modules/paapi.js +2 -1
  234. package/modules/pgamsspBidAdapter.js +5 -240
  235. package/modules/playdigoBidAdapter.js +4 -186
  236. package/modules/prebidServerBidAdapter/index.js +9 -2
  237. package/modules/pubCircleBidAdapter.js +5 -218
  238. package/modules/pubmaticAnalyticsAdapter.js +21 -8
  239. package/modules/pubxaiAnalyticsAdapter.js +1 -5
  240. package/modules/qtBidAdapter.js +5 -224
  241. package/modules/raynRtdProvider.js +36 -3
  242. package/modules/richaudienceBidAdapter.js +375 -0
  243. package/modules/richaudienceBidAdapter.md +1 -1
  244. package/modules/seedtagBidAdapter.js +1 -0
  245. package/modules/setupadBidAdapter.js +76 -153
  246. package/modules/setupadBidAdapter.md +1 -1
  247. package/modules/smaatoBidAdapter.js +17 -6
  248. package/modules/smartytechBidAdapter.js +7 -2
  249. package/modules/topicsFpdModule.js +1 -1
  250. package/modules/uid2IdSystem.js +0 -1
  251. package/modules/uid2IdSystem_shared.js +0 -1
  252. package/modules/visiblemeasuresBidAdapter.js +5 -199
  253. package/modules/zeta_global_sspAnalyticsAdapter.js +8 -4
  254. package/package.json +1 -1
  255. package/src/auction.js +5 -63
  256. package/src/utils/focusTimeout.js +41 -0
  257. package/src/utils/ttlCollection.js +2 -1
  258. package/src/utils.js +42 -0
  259. package/src/videoCache.js +72 -0
  260. package/test/mocks/videoCacheStub.js +1 -1
  261. package/test/spec/auctionmanager_spec.js +16 -1
  262. package/test/spec/libraries/teqblazeUtils/bidderUtils_spec.js +519 -0
  263. package/test/spec/modules/acuityadsBidAdapter_spec.js +79 -43
  264. package/test/spec/modules/adagioRtdProvider_spec.js +62 -1
  265. package/test/spec/modules/admanBidAdapter_spec.js +370 -247
  266. package/test/spec/modules/adprimeBidAdapter_spec.js +225 -78
  267. package/test/spec/modules/axisBidAdapter_spec.js +78 -14
  268. package/test/spec/modules/beyondmediaBidAdapter_spec.js +80 -18
  269. package/test/spec/modules/bliinkBidAdapter_spec.js +8 -2
  270. package/test/spec/modules/boldwinBidAdapter_spec.js +221 -75
  271. package/test/spec/modules/compassBidAdapter_spec.js +130 -16
  272. package/test/spec/modules/contentexchangeBidAdapter_spec.js +134 -21
  273. package/test/spec/modules/conversantBidAdapter_spec.js +7 -0
  274. package/test/spec/modules/dailymotionBidAdapter_spec.js +3 -3
  275. package/test/spec/modules/e_volutionBidAdapter_spec.js +65 -3
  276. package/test/spec/modules/emtvBidAdapter_spec.js +131 -16
  277. package/test/spec/modules/globalsunBidAdapter_spec.js +130 -16
  278. package/test/spec/modules/id5IdSystem_spec.js +79 -3
  279. package/test/spec/modules/iqzoneBidAdapter_spec.js +66 -12
  280. package/test/spec/modules/kiviadsBidAdapter_spec.js +131 -20
  281. package/test/spec/modules/krushmediaBidAdapter_spec.js +272 -90
  282. package/test/spec/modules/loyalBidAdapter_spec.js +114 -14
  283. package/test/spec/modules/lunamediahbBidAdapter_spec.js +221 -87
  284. package/test/spec/modules/mathildeadsBidAdapter_spec.js +87 -18
  285. package/test/spec/modules/mgidXBidAdapter_spec.js +11 -3
  286. package/test/spec/modules/mobfoxpbBidAdapter_spec.js +229 -91
  287. package/test/spec/modules/mobianRtdProvider_spec.js +107 -0
  288. package/test/spec/modules/ozoneBidAdapter_spec.js +192 -22
  289. package/test/spec/modules/paapi_spec.js +5 -5
  290. package/test/spec/modules/pgamsspBidAdapter_spec.js +83 -16
  291. package/test/spec/modules/playdigoBidAdapter_spec.js +38 -9
  292. package/test/spec/modules/prebidServerBidAdapter_spec.js +14 -0
  293. package/test/spec/modules/pubCircleBidAdapter_spec.js +82 -17
  294. package/test/spec/modules/pubmaticAnalyticsAdapter_spec.js +52 -5
  295. package/test/spec/modules/qtBidAdapter_spec.js +15 -3
  296. package/test/spec/modules/raynRtdProvider_spec.js +25 -0
  297. package/test/spec/modules/richaudienceBidAdapter_spec.js +1304 -0
  298. package/test/spec/modules/seedtagBidAdapter_spec.js +2 -0
  299. package/test/spec/modules/setupadBidAdapter_spec.js +139 -97
  300. package/test/spec/modules/smaatoBidAdapter_spec.js +27 -0
  301. package/test/spec/modules/smartytechBidAdapter_spec.js +5 -1
  302. package/test/spec/modules/topicsFpdModule_spec.js +43 -59
  303. package/test/spec/modules/visiblemeasuresBidAdapter_spec.js +130 -16
  304. package/test/spec/modules/zeta_global_sspAnalyticsAdapter_spec.js +4 -0
  305. package/test/spec/ortbConverter/converter_spec.js +7 -3
  306. package/test/spec/unit/utils/focusTimeout_spec.js +60 -0
  307. package/test/spec/videoCache_spec.js +56 -53
@@ -1,190 +1,53 @@
1
- import { isFn, deepAccess, logMessage, logError } from '../src/utils.js';
2
- import { convertOrtbRequestToProprietaryNative } from '../src/native.js';
3
-
1
+ import { deepAccess } from '../src/utils.js';
4
2
  import { registerBidder } from '../src/adapters/bidderFactory.js';
5
3
  import { BANNER, NATIVE, VIDEO } from '../src/mediaTypes.js';
6
4
  import { config } from '../src/config.js';
5
+ import {
6
+ isBidRequestValid,
7
+ buildRequestsBase,
8
+ interpretResponse,
9
+ buildPlacementProcessingFunction,
10
+ } from '../libraries/teqblazeUtils/bidderUtils.js';
7
11
 
8
12
  const BIDDER_CODE = 'axis';
9
13
  const AD_URL = 'https://prebid.axis-marketplace.com/pbjs';
10
14
  const SYNC_URL = 'https://cs.axis-marketplace.com';
11
15
 
12
- function isBidResponseValid(bid) {
13
- if (!bid.requestId || !bid.cpm || !bid.creativeId || !bid.ttl || !bid.currency) {
14
- return false;
15
- }
16
-
17
- switch (bid.mediaType) {
18
- case BANNER:
19
- return Boolean(bid.width && bid.height && bid.ad);
20
- case VIDEO:
21
- return Boolean(bid.vastUrl || bid.vastXml);
22
- case NATIVE:
23
- return Boolean(bid.native && bid.native.impressionTrackers && bid.native.impressionTrackers.length);
24
- default:
25
- return false;
26
- }
27
- }
28
-
29
- function getPlacementReqData(bid) {
30
- const { params, bidId, mediaTypes } = bid;
31
- const schain = bid.schain || {};
32
- const { integration, token } = params;
33
- const bidfloor = getBidFloor(bid);
16
+ const addPlacementType = (bid, bidderRequest, placement) => {
17
+ placement.integration = bid.params.integration;
18
+ placement.token = bid.params.token;
19
+ };
34
20
 
35
- const placement = {
36
- integration,
37
- token,
38
- bidId,
39
- schain,
40
- bidfloor
41
- };
21
+ const addCustomFieldsToPlacement = (bid, bidderRequest, placement) => {
22
+ const { mediaTypes } = bid;
42
23
 
43
- if (mediaTypes && mediaTypes[BANNER]) {
44
- placement.adFormat = BANNER;
24
+ if (placement.adFormat === BANNER) {
45
25
  placement.pos = mediaTypes[BANNER].pos;
46
- placement.sizes = mediaTypes[BANNER].sizes;
47
- } else if (mediaTypes && mediaTypes[VIDEO]) {
48
- placement.adFormat = VIDEO;
26
+ } else if (placement.adFormat === VIDEO) {
49
27
  placement.pos = mediaTypes[VIDEO].pos;
50
- placement.playerSize = mediaTypes[VIDEO].playerSize;
51
- placement.minduration = mediaTypes[VIDEO].minduration;
52
- placement.maxduration = mediaTypes[VIDEO].maxduration;
53
- placement.mimes = mediaTypes[VIDEO].mimes;
54
- placement.protocols = mediaTypes[VIDEO].protocols;
55
- placement.startdelay = mediaTypes[VIDEO].startdelay;
56
- placement.plcmt = mediaTypes[VIDEO].plcmt;
57
- placement.placement = mediaTypes[VIDEO].placement;
58
- placement.skip = mediaTypes[VIDEO].skip;
59
- placement.skipafter = mediaTypes[VIDEO].skipafter;
60
- placement.minbitrate = mediaTypes[VIDEO].minbitrate;
61
- placement.maxbitrate = mediaTypes[VIDEO].maxbitrate;
62
- placement.delivery = mediaTypes[VIDEO].delivery;
63
- placement.playbackmethod = mediaTypes[VIDEO].playbackmethod;
64
- placement.api = mediaTypes[VIDEO].api;
65
- placement.linearity = mediaTypes[VIDEO].linearity;
66
28
  placement.context = mediaTypes[VIDEO].context;
67
- } else if (mediaTypes && mediaTypes[NATIVE]) {
68
- placement.native = mediaTypes[NATIVE];
69
- placement.adFormat = NATIVE;
70
29
  }
30
+ };
71
31
 
72
- return placement;
73
- }
32
+ const placementProcessingFunction = buildPlacementProcessingFunction({ addPlacementType, addCustomFieldsToPlacement });
74
33
 
75
- function getBidFloor(bid) {
76
- if (!isFn(bid.getFloor)) {
77
- return deepAccess(bid, 'params.bidfloor', 0);
78
- }
34
+ const buildRequests = (validBidRequests = [], bidderRequest = {}) => {
35
+ const request = buildRequestsBase({ adUrl: AD_URL, validBidRequests, bidderRequest, placementProcessingFunction });
79
36
 
80
- try {
81
- const bidFloor = bid.getFloor({
82
- currency: 'USD',
83
- mediaType: '*',
84
- size: '*',
85
- });
86
- return bidFloor.floor;
87
- } catch (e) {
88
- logError(e);
89
- return 0;
90
- }
91
- }
37
+ request.data.iabCat = deepAccess(bidderRequest, 'ortb2.site.cat');
38
+
39
+ return request;
40
+ };
92
41
 
93
42
  export const spec = {
94
43
  code: BIDDER_CODE,
95
44
  supportedMediaTypes: [BANNER, VIDEO, NATIVE],
96
45
 
97
- isBidRequestValid: (bid = {}) => {
98
- const { params, bidId, mediaTypes } = bid;
99
- let valid = Boolean(bidId && params && params.integration && params.token);
100
-
101
- if (mediaTypes && mediaTypes[BANNER]) {
102
- valid = valid && Boolean(mediaTypes[BANNER] && mediaTypes[BANNER].sizes);
103
- } else if (mediaTypes && mediaTypes[VIDEO]) {
104
- valid = valid && Boolean(mediaTypes[VIDEO] && mediaTypes[VIDEO].playerSize);
105
- } else if (mediaTypes && mediaTypes[NATIVE]) {
106
- valid = valid && Boolean(mediaTypes[NATIVE]);
107
- } else {
108
- valid = false;
109
- }
110
- return valid;
111
- },
112
-
113
- buildRequests: (validBidRequests = [], bidderRequest = {}) => {
114
- // convert Native ORTB definition to old-style prebid native definition
115
- validBidRequests = convertOrtbRequestToProprietaryNative(validBidRequests);
46
+ isBidRequestValid: isBidRequestValid(['integration', 'token'], 'every'),
47
+ buildRequests,
48
+ interpretResponse,
116
49
 
117
- let deviceWidth = 0;
118
- let deviceHeight = 0;
119
-
120
- let winLocation;
121
- try {
122
- const winTop = window.top;
123
- deviceWidth = winTop.screen.width;
124
- deviceHeight = winTop.screen.height;
125
- winLocation = winTop.location;
126
- } catch (e) {
127
- logMessage(e);
128
- winLocation = window.location;
129
- }
130
-
131
- const refferUrl = bidderRequest.refererInfo && bidderRequest.refererInfo.page;
132
- let refferLocation;
133
- try {
134
- refferLocation = refferUrl && new URL(refferUrl);
135
- } catch (e) {
136
- logMessage(e);
137
- }
138
-
139
- let location = refferLocation || winLocation;
140
- const language = (navigator && navigator.language) ? navigator.language.split('-')[0] : '';
141
- const host = location.host;
142
- const page = location.pathname;
143
- const secure = location.protocol === 'https:' ? 1 : 0;
144
- const placements = [];
145
- const request = {
146
- deviceWidth,
147
- deviceHeight,
148
- language,
149
- secure,
150
- host,
151
- page,
152
- placements,
153
- iabCat: deepAccess(bidderRequest, 'ortb2.site.cat'),
154
- coppa: deepAccess(bidderRequest, 'ortb2.regs.coppa') ? 1 : 0,
155
- ccpa: bidderRequest.uspConsent || undefined,
156
- gdpr: bidderRequest.gdprConsent || undefined,
157
- tmax: bidderRequest.timeout || 3000,
158
- };
159
-
160
- const len = validBidRequests.length;
161
- for (let i = 0; i < len; i++) {
162
- const bid = validBidRequests[i];
163
- placements.push(getPlacementReqData(bid));
164
- }
165
-
166
- return {
167
- method: 'POST',
168
- url: AD_URL,
169
- data: request
170
- };
171
- },
172
-
173
- interpretResponse: (serverResponse) => {
174
- let response = [];
175
- for (let i = 0; i < serverResponse.body.length; i++) {
176
- let resItem = serverResponse.body[i];
177
- if (isBidResponseValid(resItem)) {
178
- const advertiserDomains = resItem.adomain && resItem.adomain.length ? resItem.adomain : [];
179
- resItem.meta = { ...resItem.meta, advertiserDomains };
180
-
181
- response.push(resItem);
182
- }
183
- }
184
- return response;
185
- },
186
-
187
- getUserSyncs: (syncOptions, serverResponses, gdprConsent, uspConsent) => {
50
+ getUserSyncs: (syncOptions, serverResponses, gdprConsent, uspConsent, gppConsent) => {
188
51
  let syncType = syncOptions.iframeEnabled ? 'iframe' : 'image';
189
52
  let syncUrl = SYNC_URL + `/${syncType}?pbjs=1`;
190
53
  if (gdprConsent && gdprConsent.consentString) {
@@ -198,6 +61,11 @@ export const spec = {
198
61
  syncUrl += `&ccpa=${uspConsent.consentString}`;
199
62
  }
200
63
 
64
+ if (gppConsent?.gppString && gppConsent?.applicableSections?.length) {
65
+ syncUrl += '&gpp=' + gppConsent.gppString;
66
+ syncUrl += '&gpp_sid=' + gppConsent.applicableSections.join(',');
67
+ }
68
+
201
69
  const coppa = config.getConfig('coppa') ? 1 : 0;
202
70
  syncUrl += `&coppa=${coppa}`;
203
71
 
@@ -206,6 +74,6 @@ export const spec = {
206
74
  url: syncUrl
207
75
  }];
208
76
  }
209
- };
77
+ }
210
78
 
211
79
  registerBidder(spec);
@@ -1,203 +1,19 @@
1
- import { isFn, deepAccess, logMessage, logError } from '../src/utils.js';
2
-
3
1
  import { registerBidder } from '../src/adapters/bidderFactory.js';
4
2
  import { BANNER, NATIVE, VIDEO } from '../src/mediaTypes.js';
5
- import { config } from '../src/config.js';
3
+ import { isBidRequestValid, buildRequests, interpretResponse, getUserSyncs } from '../libraries/teqblazeUtils/bidderUtils.js';
6
4
 
7
5
  const BIDDER_CODE = 'beyondmedia';
8
6
  const AD_URL = 'https://backend.andbeyond.media/pbjs';
9
7
  const SYNC_URL = 'https://cookies.andbeyond.media';
10
8
 
11
- function isBidResponseValid(bid) {
12
- if (!bid.requestId || !bid.cpm || !bid.creativeId || !bid.ttl || !bid.currency) {
13
- return false;
14
- }
15
-
16
- switch (bid.mediaType) {
17
- case BANNER:
18
- return Boolean(bid.width && bid.height && bid.ad);
19
- case VIDEO:
20
- return Boolean(bid.vastUrl || bid.vastXml);
21
- case NATIVE:
22
- return Boolean(bid.native && bid.native.impressionTrackers && bid.native.impressionTrackers.length);
23
- default:
24
- return false;
25
- }
26
- }
27
-
28
- function getPlacementReqData(bid) {
29
- const { params, bidId, mediaTypes } = bid;
30
- const schain = bid.schain || {};
31
- const { placementId } = params;
32
- const bidfloor = getBidFloor(bid);
33
-
34
- const placement = {
35
- bidId,
36
- schain,
37
- bidfloor
38
- };
39
-
40
- placement.placementId = placementId;
41
- placement.type = 'publisher';
42
-
43
- if (mediaTypes && mediaTypes[BANNER]) {
44
- placement.adFormat = BANNER;
45
- placement.sizes = mediaTypes[BANNER].sizes;
46
- } else if (mediaTypes && mediaTypes[VIDEO]) {
47
- placement.adFormat = VIDEO;
48
- placement.playerSize = mediaTypes[VIDEO].playerSize;
49
- placement.minduration = mediaTypes[VIDEO].minduration;
50
- placement.maxduration = mediaTypes[VIDEO].maxduration;
51
- placement.mimes = mediaTypes[VIDEO].mimes;
52
- placement.protocols = mediaTypes[VIDEO].protocols;
53
- placement.startdelay = mediaTypes[VIDEO].startdelay;
54
- placement.placement = mediaTypes[VIDEO].placement;
55
- placement.plcmt = mediaTypes[VIDEO].plcmt;
56
- placement.skip = mediaTypes[VIDEO].skip;
57
- placement.skipafter = mediaTypes[VIDEO].skipafter;
58
- placement.minbitrate = mediaTypes[VIDEO].minbitrate;
59
- placement.maxbitrate = mediaTypes[VIDEO].maxbitrate;
60
- placement.delivery = mediaTypes[VIDEO].delivery;
61
- placement.playbackmethod = mediaTypes[VIDEO].playbackmethod;
62
- placement.api = mediaTypes[VIDEO].api;
63
- placement.linearity = mediaTypes[VIDEO].linearity;
64
- } else if (mediaTypes && mediaTypes[NATIVE]) {
65
- placement.native = mediaTypes[NATIVE];
66
- placement.adFormat = NATIVE;
67
- }
68
-
69
- return placement;
70
- }
71
-
72
- function getBidFloor(bid) {
73
- if (!isFn(bid.getFloor)) {
74
- return deepAccess(bid, 'params.bidfloor', 0);
75
- }
76
-
77
- try {
78
- const bidFloor = bid.getFloor({
79
- currency: 'USD',
80
- mediaType: '*',
81
- size: '*',
82
- });
83
- return bidFloor.floor;
84
- } catch (err) {
85
- logError(err);
86
- return 0;
87
- }
88
- }
89
-
90
9
  export const spec = {
91
10
  code: BIDDER_CODE,
92
11
  supportedMediaTypes: [BANNER, VIDEO, NATIVE],
93
12
 
94
- isBidRequestValid: (bid = {}) => {
95
- const { params, bidId, mediaTypes } = bid;
96
- let valid = Boolean(bidId && params && params.placementId);
97
-
98
- if (mediaTypes && mediaTypes[BANNER]) {
99
- valid = valid && Boolean(mediaTypes[BANNER] && mediaTypes[BANNER].sizes);
100
- } else if (mediaTypes && mediaTypes[VIDEO]) {
101
- valid = valid && Boolean(mediaTypes[VIDEO] && mediaTypes[VIDEO].playerSize);
102
- } else if (mediaTypes && mediaTypes[NATIVE]) {
103
- valid = valid && Boolean(mediaTypes[NATIVE]);
104
- }
105
-
106
- return valid;
107
- },
108
-
109
- buildRequests: (validBidRequests = [], bidderRequest = {}) => {
110
- let deviceWidth = 0;
111
- let deviceHeight = 0;
112
-
113
- let winLocation;
114
- try {
115
- const winTop = window.top;
116
- deviceWidth = winTop.screen.width;
117
- deviceHeight = winTop.screen.height;
118
- winLocation = winTop.location;
119
- } catch (e) {
120
- logMessage(e);
121
- winLocation = window.location;
122
- }
123
-
124
- const refferUrl = bidderRequest.refererInfo && bidderRequest.refererInfo.page;
125
- let refferLocation;
126
- try {
127
- refferLocation = refferUrl && new URL(refferUrl);
128
- } catch (e) {
129
- logMessage(e);
130
- }
131
-
132
- let location = refferLocation || winLocation;
133
- const language = (navigator && navigator.language) ? navigator.language.split('-')[0] : '';
134
- const host = location.host;
135
- const page = location.pathname;
136
- const secure = location.protocol === 'https:' ? 1 : 0;
137
- const placements = [];
138
- const request = {
139
- deviceWidth,
140
- deviceHeight,
141
- language,
142
- secure,
143
- host,
144
- page,
145
- placements,
146
- coppa: config.getConfig('coppa') === true ? 1 : 0,
147
- ccpa: bidderRequest.uspConsent || undefined,
148
- gdpr: bidderRequest.gdprConsent || undefined,
149
- tmax: bidderRequest.timeout
150
- };
151
-
152
- const len = validBidRequests.length;
153
- for (let i = 0; i < len; i++) {
154
- const bid = validBidRequests[i];
155
- placements.push(getPlacementReqData(bid));
156
- }
157
-
158
- return {
159
- method: 'POST',
160
- url: AD_URL,
161
- data: request
162
- };
163
- },
164
-
165
- interpretResponse: (serverResponse) => {
166
- let response = [];
167
- for (let i = 0; i < serverResponse.body.length; i++) {
168
- let resItem = serverResponse.body[i];
169
- if (isBidResponseValid(resItem)) {
170
- const advertiserDomains = resItem.adomain && resItem.adomain.length ? resItem.adomain : [];
171
- resItem.meta = { ...resItem.meta, advertiserDomains };
172
-
173
- response.push(resItem);
174
- }
175
- }
176
- return response;
177
- },
178
-
179
- getUserSyncs: (syncOptions, serverResponses, gdprConsent, uspConsent) => {
180
- let syncType = syncOptions.iframeEnabled ? 'iframe' : 'image';
181
- let syncUrl = SYNC_URL + `/${syncType}?pbjs=1`;
182
- if (gdprConsent && gdprConsent.consentString) {
183
- if (typeof gdprConsent.gdprApplies === 'boolean') {
184
- syncUrl += `&gdpr=${Number(gdprConsent.gdprApplies)}&gdpr_consent=${gdprConsent.consentString}`;
185
- } else {
186
- syncUrl += `&gdpr=0&gdpr_consent=${gdprConsent.consentString}`;
187
- }
188
- }
189
- if (uspConsent && uspConsent.consentString) {
190
- syncUrl += `&ccpa_consent=${uspConsent.consentString}`;
191
- }
192
-
193
- const coppa = config.getConfig('coppa') ? 1 : 0;
194
- syncUrl += `&coppa=${coppa}`;
195
-
196
- return [{
197
- type: syncType,
198
- url: syncUrl
199
- }];
200
- }
13
+ isBidRequestValid: isBidRequestValid(['placementId']),
14
+ buildRequests: buildRequests(AD_URL),
15
+ interpretResponse,
16
+ getUserSyncs: getUserSyncs(SYNC_URL)
201
17
  };
202
18
 
203
19
  registerBidder(spec);
@@ -1,6 +1,6 @@
1
1
  import { registerBidder } from '../src/adapters/bidderFactory.js'
2
2
  import { config } from '../src/config.js'
3
- import { _each, deepAccess, deepSetValue, getWindowSelf, getWindowTop } from '../src/utils.js'
3
+ import { _each, canAccessWindowTop, deepAccess, deepSetValue, getDomLoadingDuration, getWindowSelf, getWindowTop } from '../src/utils.js'
4
4
  export const BIDDER_CODE = 'bliink'
5
5
  export const GVL_ID = 658
6
6
  export const BLIINK_ENDPOINT_ENGINE = 'https://engine.bliink.io/prebid'
@@ -121,35 +121,6 @@ export function getKeywords() {
121
121
  return [];
122
122
  }
123
123
 
124
- function canAccessTopWindow() {
125
- try {
126
- if (getWindowTop().location.href) {
127
- return true;
128
- }
129
- } catch (error) {
130
- return false;
131
- }
132
- }
133
-
134
- /**
135
- * domLoading feature is computed on window.top if reachable.
136
- */
137
- export function getDomLoadingDuration() {
138
- let domLoadingDuration = -1;
139
- let performance;
140
-
141
- performance = (canAccessTopWindow()) ? getWindowTop().performance : getWindowSelf().performance;
142
-
143
- if (performance && performance.timing && performance.timing.navigationStart > 0) {
144
- const val = performance.timing.domLoading - performance.timing.navigationStart;
145
- if (val > 0) {
146
- domLoadingDuration = val;
147
- }
148
- }
149
-
150
- return domLoadingDuration;
151
- }
152
-
153
124
  /**
154
125
  * @param bidResponse
155
126
  * @return {({cpm, netRevenue: boolean, requestId, width: number, currency, ttl: number, creativeId, height: number}&{mediaType: string, vastXml})|null}
@@ -208,7 +179,8 @@ export const isBidRequestValid = (bid) => {
208
179
  */
209
180
  export const buildRequests = (validBidRequests, bidderRequest) => {
210
181
  if (!validBidRequests || !bidderRequest || !bidderRequest.bids) return null
211
- const domLoadingDuration = getDomLoadingDuration().toString();
182
+ const w = (canAccessWindowTop()) ? getWindowTop() : getWindowSelf();
183
+ const domLoadingDuration = getDomLoadingDuration(w).toString();
212
184
  const tags = bidderRequest.bids.map((bid) => {
213
185
  let bidFloor;
214
186
  const sizes = bid.sizes.map((size) => ({ w: size[0], h: size[1] }));
@@ -1,176 +1,38 @@
1
- import { isFn, deepAccess, logMessage } from '../src/utils.js';
2
- import {registerBidder} from '../src/adapters/bidderFactory.js';
1
+ import { registerBidder } from '../src/adapters/bidderFactory.js';
3
2
  import { BANNER, NATIVE, VIDEO } from '../src/mediaTypes.js';
4
- import { convertOrtbRequestToProprietaryNative } from '../src/native.js';
3
+ import {
4
+ isBidRequestValid,
5
+ buildRequestsBase,
6
+ interpretResponse,
7
+ getUserSyncs,
8
+ buildPlacementProcessingFunction,
9
+ } from '../libraries/teqblazeUtils/bidderUtils.js';
5
10
 
6
11
  const BIDDER_CODE = 'boldwin';
7
12
  const AD_URL = 'https://ssp.videowalldirect.com/pbjs';
8
13
  const SYNC_URL = 'https://sync.videowalldirect.com';
9
14
 
10
- function isBidResponseValid(bid) {
11
- if (!bid.requestId || !bid.cpm || !bid.creativeId ||
12
- !bid.ttl || !bid.currency) {
13
- return false;
15
+ const addCustomFieldsToPlacement = (bid, bidderRequest, placement) => {
16
+ if (placement.adFormat === VIDEO) {
17
+ placement.wPlayer = placement.playerSize?.[0]?.[0];
18
+ placement.hPlayer = placement.playerSize?.[0]?.[1];
14
19
  }
15
- switch (bid.mediaType) {
16
- case BANNER:
17
- return Boolean(bid.width && bid.height && bid.ad);
18
- case VIDEO:
19
- return Boolean(bid.vastUrl);
20
- case NATIVE:
21
- return Boolean(bid.native && bid.native.title && bid.native.image && bid.native.impressionTrackers);
22
- default:
23
- return false;
24
- }
25
- }
20
+ };
26
21
 
27
- function getBidFloor(bid) {
28
- if (!isFn(bid.getFloor)) {
29
- return deepAccess(bid, 'params.bidfloor', 0);
30
- }
22
+ const placementProcessingFunction = buildPlacementProcessingFunction({ addCustomFieldsToPlacement });
31
23
 
32
- try {
33
- const bidFloor = bid.getFloor({
34
- currency: 'USD',
35
- mediaType: '*',
36
- size: '*',
37
- });
38
- return bidFloor.floor;
39
- } catch (_) {
40
- return 0
41
- }
42
- }
24
+ const buildRequests = (validBidRequests = [], bidderRequest = {}) => {
25
+ return buildRequestsBase({ adUrl: AD_URL, validBidRequests, bidderRequest, placementProcessingFunction });
26
+ };
43
27
 
44
28
  export const spec = {
45
29
  code: BIDDER_CODE,
46
30
  supportedMediaTypes: [BANNER, VIDEO, NATIVE],
47
31
 
48
- isBidRequestValid: (bid) => {
49
- return Boolean(bid.bidId && bid.params && (bid.params.placementId || bid.params.endpointId));
50
- },
51
-
52
- buildRequests: (validBidRequests = [], bidderRequest) => {
53
- // convert Native ORTB definition to old-style prebid native definition
54
- validBidRequests = convertOrtbRequestToProprietaryNative(validBidRequests);
55
-
56
- let winTop = window;
57
- let location;
58
- // TODO: this odd try-catch block was copied in several adapters; it doesn't seem to be correct for cross-origin
59
- try {
60
- location = new URL(bidderRequest.refererInfo.page);
61
- winTop = window.top;
62
- } catch (e) {
63
- location = winTop.location;
64
- logMessage(e);
65
- };
66
- let placements = [];
67
- let request = {
68
- 'deviceWidth': winTop.screen.width,
69
- 'deviceHeight': winTop.screen.height,
70
- 'language': (navigator && navigator.language) ? navigator.language.split('-')[0] : '',
71
- 'secure': 1,
72
- 'host': location.host,
73
- 'page': location.pathname,
74
- 'placements': placements
75
- };
76
- if (bidderRequest) {
77
- if (bidderRequest.uspConsent) {
78
- request.ccpa = bidderRequest.uspConsent;
79
- }
80
- if (bidderRequest.gdprConsent) {
81
- request.gdpr = bidderRequest.gdprConsent;
82
- }
83
-
84
- // Add GPP consent
85
- if (bidderRequest.gppConsent) {
86
- request.gpp = bidderRequest.gppConsent.gppString;
87
- request.gpp_sid = bidderRequest.gppConsent.applicableSections;
88
- } else if (bidderRequest.ortb2?.regs?.gpp) {
89
- request.gpp = bidderRequest.ortb2.regs.gpp;
90
- request.gpp_sid = bidderRequest.ortb2.regs.gpp_sid;
91
- }
92
- }
93
- const len = validBidRequests.length;
94
-
95
- for (let i = 0; i < len; i++) {
96
- let bid = validBidRequests[i];
97
- const { mediaTypes, params } = bid;
98
- const placement = {};
99
- let sizes;
100
- if (mediaTypes) {
101
- if (mediaTypes[BANNER] && mediaTypes[BANNER].sizes) {
102
- placement.adFormat = BANNER;
103
- sizes = mediaTypes[BANNER].sizes;
104
- } else if (mediaTypes[VIDEO] && mediaTypes[VIDEO].playerSize) {
105
- placement.adFormat = VIDEO;
106
- sizes = mediaTypes[VIDEO].playerSize;
107
- placement.minduration = mediaTypes[VIDEO].minduration;
108
- placement.maxduration = mediaTypes[VIDEO].maxduration;
109
- placement.mimes = mediaTypes[VIDEO].mimes;
110
- placement.protocols = mediaTypes[VIDEO].protocols;
111
- placement.startdelay = mediaTypes[VIDEO].startdelay;
112
- placement.placement = mediaTypes[VIDEO].placement;
113
- placement.plcmt = mediaTypes[VIDEO].plcmt;
114
- placement.skip = mediaTypes[VIDEO].skip;
115
- placement.skipafter = mediaTypes[VIDEO].skipafter;
116
- placement.minbitrate = mediaTypes[VIDEO].minbitrate;
117
- placement.maxbitrate = mediaTypes[VIDEO].maxbitrate;
118
- placement.delivery = mediaTypes[VIDEO].delivery;
119
- placement.playbackmethod = mediaTypes[VIDEO].playbackmethod;
120
- placement.api = mediaTypes[VIDEO].api;
121
- placement.linearity = mediaTypes[VIDEO].linearity;
122
- } else {
123
- placement.adFormat = NATIVE;
124
- placement.native = mediaTypes[NATIVE];
125
- }
126
- }
127
-
128
- const { placementId, endpointId } = params;
129
- if (placementId) {
130
- placement.placementId = placementId;
131
- placement.type = 'publisher';
132
- } else if (endpointId) {
133
- placement.endpointId = endpointId;
134
- placement.type = 'network';
135
- }
136
-
137
- placements.push({
138
- ...placement,
139
- bidId: bid.bidId,
140
- sizes: sizes || [],
141
- wPlayer: sizes ? sizes[0] : 0,
142
- hPlayer: sizes ? sizes[1] : 0,
143
- schain: bid.schain || {},
144
- bidFloor: getBidFloor(bid),
145
- });
146
- }
147
- return {
148
- method: 'POST',
149
- url: AD_URL,
150
- data: request
151
- };
152
- },
153
-
154
- interpretResponse: (serverResponse) => {
155
- let response = [];
156
- for (let i = 0; i < serverResponse.body.length; i++) {
157
- let resItem = serverResponse.body[i];
158
- if (isBidResponseValid(resItem)) {
159
- const advertiserDomains = resItem.adomain && resItem.adomain.length ? resItem.adomain : [];
160
- resItem.meta = { ...resItem.meta, advertiserDomains };
161
-
162
- response.push(resItem);
163
- }
164
- }
165
- return response;
166
- },
167
-
168
- getUserSyncs: () => {
169
- return [{
170
- type: 'image',
171
- url: SYNC_URL
172
- }];
173
- }
32
+ isBidRequestValid: isBidRequestValid(),
33
+ buildRequests,
34
+ interpretResponse,
35
+ getUserSyncs: getUserSyncs(SYNC_URL)
174
36
  };
175
37
 
176
38
  registerBidder(spec);