From 92bfb1954d38a1efc6354a2b7a504a6e3598660f Mon Sep 17 00:00:00 2001 From: bretg Date: Fri, 3 Feb 2023 09:54:54 -0500 Subject: [PATCH 001/762] pbs gpp (#4331) --- prebid-server/features/pbs-feature-idx.md | 3 ++- prebid-server/features/pbs-privacy.md | 12 ++++++++++++ 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/prebid-server/features/pbs-feature-idx.md b/prebid-server/features/pbs-feature-idx.md index 4931b72c..19ef265c 100644 --- a/prebid-server/features/pbs-feature-idx.md +++ b/prebid-server/features/pbs-feature-idx.md @@ -31,8 +31,9 @@ title: Prebid Server | Features | GDPR | TCF 2 Geo-Fencing | If the incoming request contains device.geo.country, PBS will enforce the EEA if the request is flagged as being in GDPR scope. | | | | GDPR | TCF 2 Geo-Lookup | Can use a geographic lookup service to help determine whether the incoming request is in-scope for GDPR. | | | | GDPR | TCF 2 channel exception | Can be configured to turn off GDPR checks for a specific account and a specific channel. e.g. Account 123 has a different legal basis for AMP. | | | -| [US Privacy](/prebid-server/features/pbs-privacy.html) | USP core | Able to: read the US Privacy consent string (CCPA) and [take appropriate enforcement action](https://github.com/prebid/prebid-server/issues/1129). | | | +| [US Privacy](/prebid-server/features/pbs-privacy.html#ccpa--us-privacy) | USP core | Able to: read the US Privacy consent string (CCPA) and [take appropriate enforcement action](https://github.com/prebid/prebid-server/issues/1129). | | | | US Privacy | USP AMP support | Able to: read the US Privacy consent string from AMP requests and [take appropriate enforcement action](https://github.com/prebid/prebid-server/issues/1176). | | | +| [GPP](/prebid-server/features/pbs-privacy.html#gpp) | GPP Passthrough | Global Privacy Platform parameters are passed through auction and usersync requests. | | | | COPPA | Core | Able to read the COPPA flag and [take appropriate enforcement action](https://github.com/prebid/prebid-server/issues/929). | | | | Global Privacy Control | Core | Passes the Sec-GPC header through to bidders. | | | | [Cache](/prebid-server/features/pbs-caching.html) | Bids core | Accepts the ext.prebid.cache.bids parameter, storing bid objects in PBC. | | | diff --git a/prebid-server/features/pbs-privacy.md b/prebid-server/features/pbs-privacy.md index bc83cc5a..4d74a99e 100644 --- a/prebid-server/features/pbs-privacy.md +++ b/prebid-server/features/pbs-privacy.md @@ -66,6 +66,18 @@ consider: The specific details vary between [PBS-Go](https://github.com/prebid/prebid-server/blob/master/config/config.go) and [PBS-Java](https://github.com/prebid/prebid-server-java/blob/master/docs/config-app.md), so check the version-specific documentation for more information. +## GPP + +The IAB's [Global Privacy Platform](https://iabtechlab.com/gpp/) is container for +privacy regulations aimed at helping the ad tech ecosystem bring disparate reguations +under one communication path. + +Prebid Server support for this protocol is still being developed: + +1. (done) Passthrough - GPP parameters are forwarded through auction and usersync signals. In ORTB 2.6, these are regs.gpp and regs.gpp_sid. For url protocols, look for `gpp` and `gpp_sid`. +1. (in-progress) GPP as a TCF and USP wrapper - PBS parses the GPP container for TCF2 and USP strings, extracting them to the original ORTB location. +1. (planned) GPP infrastructure - the ability to plug new regulations into PBS, and the first sub-module, the IAB's US [National Privacy Specification](https://github.com/InteractiveAdvertisingBureau/Global-Privacy-Platform/blob/main/Sections/US-National/IAB%20Privacy%E2%80%99s%20National%20Privacy%20Technical%20Specification.md). + ## COPPA The [Children's Online Privacy Protection Act (COPPA)](https://www.ftc.gov/enforcement/rules/rulemaking-regulatory-reform-proceedings/childrens-online-privacy-protection-rule) is a law in the US which imposes certain requirements on operators of websites or online services directed to children under 13 years of age, and on operators of other websites or online services that have actual knowledge that they are collecting personal information online from a child under 13 years of age. From 91fb41825726cc205d15802adeafbdfa35bcbdc6 Mon Sep 17 00:00:00 2001 From: Ho Chia Leung Date: Fri, 3 Feb 2023 16:36:45 +0100 Subject: [PATCH 002/762] Update android-sdk-integration-admob.md (#4330) 1. add bannerView to the view tree 2. use PrebidBannerAdapter instead of PrebidInterstitialAdapter --- .../modules/rendering/android-sdk-integration-admob.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/prebid-mobile/modules/rendering/android-sdk-integration-admob.md b/prebid-mobile/modules/rendering/android-sdk-integration-admob.md index 6f3cbf41..80d90545 100644 --- a/prebid-mobile/modules/rendering/android-sdk-integration-admob.md +++ b/prebid-mobile/modules/rendering/android-sdk-integration-admob.md @@ -64,11 +64,12 @@ Integration example: bannerView = AdView(activity) bannerView?.adSize = AdSize.BANNER bannerView?.adUnitId = adUnitId +adWrapperView.addView(bannerView) val extras = Bundle() val request = AdRequest .Builder() - .addNetworkExtrasBundle(PrebidInterstitialAdapter::class.java, extras) + .addNetworkExtrasBundle(PrebidBannerAdapter::class.java, extras) .build() // 2. Create AdMobBannerMediationUtils From c2b9cee9d1a6877332e6ed1f3dc62fd038770571 Mon Sep 17 00:00:00 2001 From: ahmadlob <109217988+ahmadlob@users.noreply.github.com> Date: Fri, 3 Feb 2023 18:25:09 +0200 Subject: [PATCH 003/762] Taboola Bid Adapter: Supporting First Party Data (#4235) * taboola-first-party-data-support * additional-params * additional-params * additional-params * additional-params * additional-params --- dev-docs/bidders/taboola.md | 56 +++++++++++++++++++++++++++++++------ 1 file changed, 47 insertions(+), 9 deletions(-) diff --git a/dev-docs/bidders/taboola.md b/dev-docs/bidders/taboola.md index 258721c0..056f319e 100644 --- a/dev-docs/bidders/taboola.md +++ b/dev-docs/bidders/taboola.md @@ -15,7 +15,7 @@ gvl_id: 42 prebid_member: true floors_supported: true safeframes_ok: true -fpd_supported: false +fpd_supported: true ortb_blocking_supported: partial deals_supported: false pbs_app_supported: false @@ -31,19 +31,55 @@ sidebarType: 1 The Taboola Adapter requires setup before beginning. Please contact us at prebid@taboola.com. +### First Party Data +Publishers can use the `ortb2` configuration parameter to provide First Party Data. + +#### OpenRTB Parameters +The following table contains currently supported parameters we parse. + +{: .table .table-bordered .table-striped } + +| Name | Scope | Description | Example | Type | +|--------------------|----------|---------------------------------------------------------------|-------------------|----------------| +| `bcat` | optional | List of blocked advertiser categories (IAB) | `['IAB1-1']` | `string array` | +| `badv` | optional | Blocked Advertiser Domains | `['example.com']` | `string array` | +| `wlang` | optional | Allow List of languages for creatives using ISO-639-1-alpha-2 | `['fr', 'en']` | `string array` | + +Notes: +- will extract the page,ref,domain if passed within `ortb2.site` +- will extract the pageType if passed within the preferred field `ortb2.ext.data.pageType` or `ortb2.ext.data.section` + +Example configuration: +``` +pbjs.setConfig({ + ortb2: { + bcat: ['IAB1-1'], + badv: ['example.com'], + wlang: ['fr', 'en'] + } +}); +``` + + ### Bid Params {: .table .table-bordered .table-striped } -| Name | Scope | Description | Example | Type | -|-------------------|----------|---------------------------------------------------|-----------------------|--------------| -| `tagId` | required | Tag ID / Placement Name
| `'Below The Article'` | `String` | -| `publisherId` | required | Numeric Publisher ID
(as provided by Taboola) | `'1234567'` | `String` | -| `publisherDomain` | optional | Publisher Domain (server-side adapter only) | `'example.com'` | `String` | -| `bcat` | optional | List of blocked advertiser categories (IAB) | `['IAB1-1']` | `Array` | -| `badv` | optional | Blocked Advertiser Domains | `'example.com'` | `String Url` | -| `bidfloor` | optional | CPM bid floor | `0.25` | `Float` | +| Name | Scope | Description | Example | Type | +|-------------------|------------------------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|-----------------------|--------------| +| `tagId` | required | Tag ID / Unique Placement Name
| `'Below The Article'` | `String` | +| `publisherId` | required | Numeric Publisher ID
(as provided by Taboola) | `'1234567'` | `String` | +| `pageType` | optional, recommended | Kind of content present in the page | `'homepage'` | `String` | +| `position` | optional, recommended | Identify the placement position on screen. Possible values: 0 - 7

0 Unknown
1 Above The Fold
2 Locked (i.e., fixed position)
3 Below The Fold
4 Header
5 Footer
6 Sidebar
7 Fullscreen
| `2` | `Integer` | +| `publisherDomain` | optional | Publisher Domain (server-side adapter only) | `'example.com'` | `String` | +| `bidfloor` | optional | CPM bid floor | `0.25` | `Float` | +| `bcat` | optional | List of blocked advertiser categories (IAB) | `['IAB1-1']` | `Array` | +| `badv` | optional | Blocked Advertiser Domains | `'example.com'` | `String Url` | +Notes: +- Preferred to provide the `bcat` and `badv` within the first party data (above). When both methods are provided, first party data values will be prioritized. +- If `pageType` or `publisherDomain` provided within the first party data (as explained above), first party data properties will be prioritized. +- `tagId` is an identifier for specific ad placement, and should be the same unique `tagId` per placement/ad unit in all Bid Requests. ### Example Ad Unit ```javascript @@ -60,6 +96,8 @@ The Taboola Adapter requires setup before beginning. Please contact us at prebid tagId: 'Placement Name', publisherId: 'your-publisher-id', publisherDomain: 'example.com',// Optional (server-side adapter only) + pageType: 'news',// Optional + position: 6,// Optional bidfloor: 0.25, // Optional - default is null bcat: ['IAB1-1'], // Optional - default is [] badv: ['example.com'] // Optional - default is [] From 8a6fa580c46637b45e88a2589dfd95d5e5909aee Mon Sep 17 00:00:00 2001 From: Demetrio Girardi Date: Fri, 3 Feb 2023 11:20:40 -0700 Subject: [PATCH 004/762] Prebid.js: update docs for `bidCpmAdjustment` and `inverseCpmAdjutment` (#4300) * Prebid.js: update docs for `bidCpmAdjustment` and `inverseCpmAdjutment` * Update bidderSettings.md --- .../publisher-api-reference/bidderSettings.md | 45 ++++++++++++++++--- 1 file changed, 38 insertions(+), 7 deletions(-) diff --git a/dev-docs/publisher-api-reference/bidderSettings.md b/dev-docs/publisher-api-reference/bidderSettings.md index 0aabb488..59ee2f39 100644 --- a/dev-docs/publisher-api-reference/bidderSettings.md +++ b/dev-docs/publisher-api-reference/bidderSettings.md @@ -41,7 +41,8 @@ Some sample scenarios where publishers may wish to alter the default settings: | Attribute | Scope | Version | Default | Description | | --- | --- | --- | --- | --- | | adserverTargeting | standard or adapter-specific | all | see below | Define which key/value pairs are sent to the ad server. | -| bidCpmAdjustment | standard or adapter-specific | all | n/a | Could, for example, adjust a bidder's gross-price bid to net price. | +| bidCpmAdjustment | standard or adapter-specific | all | n/a | Custom CPM adjustment function. Could, for example, adjust a bidder's gross-price bid to net price. | +| inverseCpmAdjustment | standard or adapter-specific | 7.33.0 | n/a | Inverse of `bidCpmAdjustment` | | sendStandardTargeting | adapter-specific | 0.13.0 | true | If adapter-specific targeting is specified, can be used to suppress the standard targeting for that adapter. | | suppressEmptyKeys | standard or adapter-specific | 0.13.0 | false | If custom adserverTargeting functions are specified that may generate empty keys, this can be used to suppress them. | | allowZeroCpmBids | standard or adapter-specific | 6.2.0 | false | Would allow bids with a 0 CPM to be accepted by Prebid.js and could be passed to the ad server. | @@ -192,6 +193,11 @@ In this case, the publisher may want to adjust the bidder's returned price to ru header bidding auction. Otherwise, this bidder's gross price will unfairly win over your other demand sources who report the real price. +Custom adjustment can be provided as a function taking 3 arguments: `bidCpmAdjustment(cpm, bidResponse, bidRequest)`. +Note that either `bidResponse` or `bidRequest` may be missing, although at least one of them is guaranteed to be present. This is because Prebid will sometimes need to run adjustment when no bid has been made yet; see [inverseCpmAdjustment](#inverseCpmAdjustment) below. + +For example: + {% highlight js %} pbjs.bidderSettings = { @@ -209,7 +215,32 @@ pbjs.bidderSettings = { In the above example, the AOL bidder will inherit from "standard" adserverTargeting keys, so that you don't have to define the targeting keywords again. -##### 2.3. sendStandardTargeting +##### 2.3. inverseCpmAdjustment + +When using [price floors](dev-docs/modules/floors.html), Prebid attempts to calculate the inverse of `bidCpmAdjustment`, so that the floor values it requests from SSPs take into account how the bid will be adjusted. +For example, if the adjustment is `bidCpm * .85` as above, floors are adjusted by `bidFloor * 1 / .85`. + +The automatically derived inverse function is correct only when `bidCpmAdjustment` is a simple multiplication. If it isn't, the inverse should also be provided through `inverseCpmAdjustment`. For example: + +{% highlight js %} + +pbjs.bidderSettings = { + aol: { + bidCpmAdjustment : function(cpm) { + return Math.max(0.2, (cpm - 0.2) * .85) + } + inverseCpmAdjustment: function(cpm) { + return Math.max(0.2, (cpm / .85) + 0.2) + } + } +} +}; + +{% endhighlight %} + + + +##### 2.4. sendStandardTargeting This boolean flag minimizes key/value pairs sent to the ad server when adapter-specific targeting is specified. By default, the platform will send both adapter-specific adServerTargeting as well as the standard adServerTargeting. @@ -219,17 +250,17 @@ suppress the standard targeting for adapters that define their own. See the [example above](#key-targeting-specific-bidder) for example usage. -##### 2.4. suppressEmptyKeys +##### 2.5. suppressEmptyKeys If a custom adServerTargeting function can return an empty value, this boolean flag can be used to avoid sending those empty values to the ad server. -##### 2.5. allowZeroCpmBids +##### 2.6. allowZeroCpmBids By default, 0 CPM bids are ignored by Prebid.js entirely. However if there's a valid business reason to allow these bids, this setting can be enabled to allow either specific bid adapter(s) or all bid adapters the permission for these bids to be processed by Prebid.js and potentially sent to the respective ad server (depending on the Prebid.js auction results). -##### 2.6. storageAllowed +##### 2.7. storageAllowed This flag defines if the bid adapter can access browser cookies and local storage.
Default value is `true` in version 6.x @@ -241,14 +272,14 @@ Note that: -##### 2.7. allowAlternateBidderCodes +##### 2.8. allowAlternateBidderCodes If this flag is set to `true`, bidders that have not been explicitly requested in [`adUnit.bids`](../adunit-reference.html#adunitbids) may take part in the auction.
Default value is `true` in version 6.x
Default value will be `false` from version 7.0 -##### 2.8. allowedAlternateBidderCodes +##### 2.9. allowedAlternateBidderCodes This array will work in conjunction with `allowAlternateBidderCodes`. In this array, you can specify the names of the bidder for which an adapter can accept the bid. If the value is not specified for the array or `[‘*’]` is specified, Prebid will accept bids of all the bidders for the given adapter. From ae1295f131458774224b1aca5bf87c4371d9a9d3 Mon Sep 17 00:00:00 2001 From: Muki Seiler Date: Fri, 3 Feb 2023 19:28:59 +0100 Subject: [PATCH 005/762] Enhance pr template Adding PR links in a list adds a better preview to see if the related PR was merged or is still open --- .github/pull_request_template.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/pull_request_template.md b/.github/pull_request_template.md index d744f1cc..62115a2f 100644 --- a/.github/pull_request_template.md +++ b/.github/pull_request_template.md @@ -14,5 +14,5 @@ Please give a short description and check the matching checkboxes to help us rev ## 📋 Checklist -- [ ] Related pull requests in prebid.js or server are linked +- [ ] Related pull requests in prebid.js or server are linked -> Paste link in this list or reference it on the PR itself - [ ] For new adapters check [submitting your adapter docs](https://docs.prebid.org/dev-docs/bidder-adaptor.html#submitting-your-adapter) From 72822d244fbdc2919d8429f2d6353918356a29c8 Mon Sep 17 00:00:00 2001 From: Chris Huie Date: Fri, 3 Feb 2023 11:34:30 -0700 Subject: [PATCH 006/762] Update onetag.md (#4326) --- dev-docs/bidders/onetag.md | 1 + 1 file changed, 1 insertion(+) diff --git a/dev-docs/bidders/onetag.md b/dev-docs/bidders/onetag.md index 82e2b9dc..2251a1e4 100644 --- a/dev-docs/bidders/onetag.md +++ b/dev-docs/bidders/onetag.md @@ -7,6 +7,7 @@ pbs: true biddercode: onetag media_types: banner, video gdpr_supported: true +gpp_supported: true gvl_id: 241 usp_supported: true userIds: britepoolId, criteo, id5Id, identityLink, liveIntentId, netId, parrableId, pubCommonId, unifiedId From bd808261552daa9dd176fc8c3e0f251ed47e66c4 Mon Sep 17 00:00:00 2001 From: Denis Logachov Date: Fri, 3 Feb 2023 20:46:53 +0200 Subject: [PATCH 007/762] Adkernel: consistent zoneId parameter type across aliases (#4317) * Update adkernel.md * Update headbidding.md * Update audiencemedia.md * Update houseofpubs.md * Update adbite.md * Update sonic_twist.md * Update rtbdemand_com.md * Update waardex_ak.md * Update bcm.md * Update adsolut.md --- dev-docs/bidders/adbite.md | 2 +- dev-docs/bidders/adkernel.md | 2 +- dev-docs/bidders/adsolut.md | 2 +- dev-docs/bidders/audiencemedia.md | 2 +- dev-docs/bidders/bcm.md | 2 +- dev-docs/bidders/headbidding.md | 2 +- dev-docs/bidders/houseofpubs.md | 2 +- dev-docs/bidders/rtbdemand_com.md | 2 +- dev-docs/bidders/sonic_twist.md | 2 +- dev-docs/bidders/waardex_ak.md | 2 +- 10 files changed, 10 insertions(+), 10 deletions(-) diff --git a/dev-docs/bidders/adbite.md b/dev-docs/bidders/adbite.md index 16d5e2a6..dcc8dc08 100644 --- a/dev-docs/bidders/adbite.md +++ b/dev-docs/bidders/adbite.md @@ -31,4 +31,4 @@ The adbite Bidding adaptor requires setup and approval before beginning. Please | Name | Scope | Description | Example | Type | |----------|----------|-----------------------|---------------------------|----------| | `host` | required | Our Host | `'cpm.adbite.com'` | `string` | -| `zoneId` | required | Example RTB zone id | `'12345'`| `string` | +| `zoneId` | required | Example RTB zone id | `12345`| `integer` | diff --git a/dev-docs/bidders/adkernel.md b/dev-docs/bidders/adkernel.md index 5324bdcf..a29d9877 100644 --- a/dev-docs/bidders/adkernel.md +++ b/dev-docs/bidders/adkernel.md @@ -31,4 +31,4 @@ The Adkernel Bidding adaptor requires setup and approval before beginning. Pleas | Name | Scope | Description | Example | Type | |----------|----------|-----------------------|---------------------------|----------| | `host` | required | Ad network's RTB host | `'cpm.metaadserving.com'` | `string` | -| `zoneId` | required | RTB zone id | `'30164'` | `string` | +| `zoneId` | required | RTB zone id | `30164` | `integer` | diff --git a/dev-docs/bidders/adsolut.md b/dev-docs/bidders/adsolut.md index 20a352d9..163d9025 100644 --- a/dev-docs/bidders/adsolut.md +++ b/dev-docs/bidders/adsolut.md @@ -31,4 +31,4 @@ The adsolut Bidding adaptor requires setup and approval before beginning. Please | Name | Scope | Description | Example | Type | |----------|----------|-----------------------|---------------------------|----------| | `host` | required | Ad network's RTB host | `'cpm.adsolut.in'` | `string` | -| `zoneId` | required | RTB zone id | `'30164'` | `string` | +| `zoneId` | required | RTB zone id | `30164` | `integer` | diff --git a/dev-docs/bidders/audiencemedia.md b/dev-docs/bidders/audiencemedia.md index 888e0ae9..9c3843ad 100644 --- a/dev-docs/bidders/audiencemedia.md +++ b/dev-docs/bidders/audiencemedia.md @@ -27,4 +27,4 @@ sidebarType: 1 | Name | Scope | Description | Example | Type | |----------|----------|-----------------------|---------------------------|----------| | `host` | required | Ad network's RTB host | `'cpm.audience.media'` | `string` | -| `zoneId` | required | Zone ID | `'76156'` | `string` | +| `zoneId` | required | Zone ID | `76156` | `integer` | diff --git a/dev-docs/bidders/bcm.md b/dev-docs/bidders/bcm.md index 6e0fa8e8..0915698f 100644 --- a/dev-docs/bidders/bcm.md +++ b/dev-docs/bidders/bcm.md @@ -32,4 +32,4 @@ The BCM adapter requires approval and setup. Please reach out to contact@bcm.ltd | Name | Scope | Description | Example | Type | |----------|----------|-----------------------|---------------------------|----------| | `host` | required | Our Host - Do Not Change | `'serve.datacygnal.io'` | `string` | -| `zoneId` | required | Example RTB zone id | `'12345'` | `string` | +| `zoneId` | required | Example RTB zone id | `12345` | `integer` | diff --git a/dev-docs/bidders/headbidding.md b/dev-docs/bidders/headbidding.md index 8494174d..2c687660 100644 --- a/dev-docs/bidders/headbidding.md +++ b/dev-docs/bidders/headbidding.md @@ -33,7 +33,7 @@ sidebarType: 1 {: .table .table-bordered .table-striped } | Name | Scope | Description | Example | Type | |----------|----------|-------------|---------|----------| -| `zoneId` | required | | | `string` | +| `zoneId` | required | | | `integer` | | `host` | required | | | `string` | Head Bidding is an aliased bidder for AdKernel diff --git a/dev-docs/bidders/houseofpubs.md b/dev-docs/bidders/houseofpubs.md index 419a3b88..24e6da73 100644 --- a/dev-docs/bidders/houseofpubs.md +++ b/dev-docs/bidders/houseofpubs.md @@ -32,4 +32,4 @@ Please contact info@houseofpubs.com for any questions or for information about o | Name | Scope | Description | Example | Type | |----------|----------|-----------------------|---------------------------|----------| | `host` | required | Our Host | `'cpm.houseofpubs.com'` | `string` | -| `zoneId` | required | Example RTB zone id | `'12345'` | `string` | +| `zoneId` | required | Example RTB zone id | `12345` | `integer` | diff --git a/dev-docs/bidders/rtbdemand_com.md b/dev-docs/bidders/rtbdemand_com.md index 87dee72b..9efaa65e 100644 --- a/dev-docs/bidders/rtbdemand_com.md +++ b/dev-docs/bidders/rtbdemand_com.md @@ -31,4 +31,4 @@ The RtbDemand.com bidding adaptor requires setup and approval before beginning. | Name | Scope | Description | Example | Type | |----------|----------|-----------------------|---------------------------|----------| | `host` | required | Our Host | `' cpm.rtbdemand.com'` | `string` | -| `zoneId` | required | Example RTB zone id | `'12345'` | `string` | +| `zoneId` | required | Example RTB zone id | `12345` | `integer` | diff --git a/dev-docs/bidders/sonic_twist.md b/dev-docs/bidders/sonic_twist.md index e4d5a17d..63bfcb81 100644 --- a/dev-docs/bidders/sonic_twist.md +++ b/dev-docs/bidders/sonic_twist.md @@ -31,4 +31,4 @@ The Sonic Twist Media Bidding adaptor requires setup and approval before beginni | Name | Scope | Description | Example | Type | |----------|----------|-----------------------|---------------------------|----------| | `host` | required | Our Host | `'cpm.andbeyond.media'` | `string` | -| `zoneId` | required | Example RTB zone id | `'12345'` | `string` | +| `zoneId` | required | Example RTB zone id | `12345` | `integer` | diff --git a/dev-docs/bidders/waardex_ak.md b/dev-docs/bidders/waardex_ak.md index 84b23d20..d40c1415 100644 --- a/dev-docs/bidders/waardex_ak.md +++ b/dev-docs/bidders/waardex_ak.md @@ -31,4 +31,4 @@ The WaardeX Bidding adaptor requires setup and approval before beginning. Please | Name | Scope | Description | Example | Type | |----------|----------|-----------------------|---------------------------|----------| | `host` | required | Ad network's RTB host | `'cpm.webtradingspot.com'` | `string` | -| `zoneId` | required | RTB zone id | `'30164'` | `string` | +| `zoneId` | required | RTB zone id | `30164` | `integer` | From 21f6cb03340fd3cd155eb677fd517a86370f6971 Mon Sep 17 00:00:00 2001 From: Jason Quaccia Date: Fri, 3 Feb 2023 10:48:21 -0800 Subject: [PATCH 008/762] updated consent management docs to include info about actionTimeout (#4315) --- dev-docs/modules/consentManagement.md | 24 ++++++++++++++++++++++-- 1 file changed, 22 insertions(+), 2 deletions(-) diff --git a/dev-docs/modules/consentManagement.md b/dev-docs/modules/consentManagement.md index 45f868fc..963b003d 100644 --- a/dev-docs/modules/consentManagement.md +++ b/dev-docs/modules/consentManagement.md @@ -72,6 +72,7 @@ but we recommend migrating to the new config structure as soon as possible. | gdpr | `Object` | | | | gdpr.cmpApi | `string` | The CMP interface that is in use. Supported values are **'iab'** or **'static'**. Static allows integrations where IAB-formatted consent strings are provided in a non-standard way. Default is `'iab'`. | `'iab'` | | gdpr.timeout | `integer` | Length of time (in milliseconds) to allow the CMP to obtain the GDPR consent string. Default is `10000`. | `10000` | +| gdpr.actionTimeout | `integer` | Length of time (in milliseconds) to allow the user to take action to consent if they have not already done so. The actionTimer first waits for the CMP to load, then the actionTimeout begins for the specified duration. Default is `undefined`. | `10000` | | gdpr.defaultGdprScope | `boolean` | Defines what the `gdprApplies` flag should be when the CMP doesn't respond in time or the static data doesn't supply. Defaults to `false`. | `true` | | gdpr.consentData | `Object` | An object representing the GDPR consent data being passed directly; only used when cmpApi is 'static'. Default is `undefined`. | | | gdpr.consentData.getTCData.tcString | `string` | Base64url-encoded TCF v2.0 string with segments. | | @@ -95,7 +96,7 @@ A related parameter is `deviceAccess`, which is at the global level of Prebid.js ### TCF v2.0 Examples -Example 1: IAB CMP using custom timeout and setting GDPR in-scope by default +Example 1: IAB CMP using custom timeout and setting GDPR in-scope by default. {% highlight js %} var pbjs = pbjs || {}; @@ -113,7 +114,26 @@ Example 1: IAB CMP using custom timeout and setting GDPR in-scope by default }); {% endhighlight %} -Example 2: Static CMP using custom data passing. +Example 2: IAB CMP using custom timeout in combination with actionTimeout and setting GDPR in-scope by default. The following will wait `500ms` for the CMP to load, if it does an additional `10000ms` will be waited for a user to provide consent (if none had yet been provided). + +{% highlight js %} + var pbjs = pbjs || {}; + pbjs.que = pbjs.que || []; + pbjs.que.push(function() { + pbjs.setConfig({ + consentManagement: { + gdpr: { + cmpApi: 'iab', + timeout: 500, + actionTimeout: 10000, + defaultGdprScope: true + } + } + }); + }); +{% endhighlight %} + +Example 3: Static CMP using custom data passing. {% highlight js %} var pbjs = pbjs || {}; From 20d507f49e1cbd1b4a856ed075c57fd3150bab4d Mon Sep 17 00:00:00 2001 From: Jason Quaccia Date: Fri, 3 Feb 2023 10:58:14 -0800 Subject: [PATCH 009/762] Publisher API Reference: Added doc page for pbjs.aliasRegistry (#4308) * added doc page for pbjs.aliasRegistry * updated aliasRegistry docs --- .../publisher-api-reference/aliasRegistry.md | 24 +++++++++++++++++++ dev-docs/publisher-api-reference/setConfig.md | 16 +++++++++++++ 2 files changed, 40 insertions(+) create mode 100644 dev-docs/publisher-api-reference/aliasRegistry.md diff --git a/dev-docs/publisher-api-reference/aliasRegistry.md b/dev-docs/publisher-api-reference/aliasRegistry.md new file mode 100644 index 00000000..f3773f55 --- /dev/null +++ b/dev-docs/publisher-api-reference/aliasRegistry.md @@ -0,0 +1,24 @@ +--- +layout: api_prebidjs +title: pbjs.aliasRegistry +description: +sidebarType: 1 +--- + + +Exposes the aliasRegistry. It can be used to fetch the entire aliasRegistry object or an individual adapter code by alias name. + +{% highlight js %} + +pbjs.aliasRegistry; or pbjs.aliasRegistry[aliasName]; + +{% endhighlight %} + +{: .alert.alert-warning :} +Note that by default, the alias registry will be made public. If you would like the registry to be private, you can utilize the `setConfig` option below: + +``` +pbjs.setConfig({aliasRegistry: 'private'}) +``` + +
diff --git a/dev-docs/publisher-api-reference/setConfig.md b/dev-docs/publisher-api-reference/setConfig.md index 3fed1308..d13f5728 100644 --- a/dev-docs/publisher-api-reference/setConfig.md +++ b/dev-docs/publisher-api-reference/setConfig.md @@ -39,6 +39,7 @@ Core config: + [Caching VAST XML](#setConfig-vast-cache) + [Site Metadata](#setConfig-site) + [Disable performance metrics](#setConfig-performanceMetrics) ++ [Setting alias registry to private](#setConfig-aliasRegistry) + [Generic Configuration](#setConfig-Generic-Configuration) + [Troubleshooting configuration](#setConfig-Troubleshooting-your-configuration) @@ -1461,6 +1462,21 @@ Since version 7.17, Prebid collects fine-grained performance metrics and attache pbjs.setConfig({performanceMetrics: false}) ``` +
+#### Setting alias registry to private + +The alias registry is made public by default during an auction. It can be referenced in the following way: + +``` +pbjs.aliasRegistry or pbjs.aliasRegistry[aliasName]; +``` + +Inversely, if you wish for the alias registry to be private you can do so by using the option below (causing `pbjs.aliasRegistry` to return undefined): + +``` +pbjs.setConfig({aliasRegistry: 'private'}) +``` + #### Generic setConfig Configuration From e67afd2d5396a91bee26e524e20c5e1e2128a341 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Udi=20Talias=20=E2=9A=9B=EF=B8=8F?= Date: Sun, 5 Feb 2023 16:35:29 +0200 Subject: [PATCH 010/762] vidazoo - bidFloor is optional param (#4333) --- dev-docs/bidders/vidazoo.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dev-docs/bidders/vidazoo.md b/dev-docs/bidders/vidazoo.md index 6ef93c2d..e2c94d5d 100644 --- a/dev-docs/bidders/vidazoo.md +++ b/dev-docs/bidders/vidazoo.md @@ -18,5 +18,5 @@ sidebarType: 1 |------------|----------|------------------------------------------------------------------------------------------|------------------------------|----------| | `cId` | required | The connection ID from Vidazoo. | `'562524b21b1c1f08117fc7f9'` | `string` | | `pId` | required | The publisher ID from Vidazoo. | `'59ac17c192832d0011283fe3'` | `string` | -| `bidFloor` | required | The minimum bid value desired. Vidazoo will not respond with bids lower than this value. | `0.90` | `float` | +| `bidFloor` | optional | The minimum bid value desired. Vidazoo will not respond with bids lower than this value. | `0.90` | `float` | | `subDomain`| optional | Sets the server subdomain, default: 'prebid'. | `'prebid'` | `string` | From a9241b5cf053f2b6bf8a36728349801952c7b5cf Mon Sep 17 00:00:00 2001 From: Noam Tzuberi Date: Sun, 5 Feb 2023 16:37:29 +0200 Subject: [PATCH 011/762] Fix rise docs & add is_wrapper private param (#4236) * Update Rise readme * fix rise doc * change rise docs * fix rise docs * added is_wrapper parameter to rise doc * changed is_wrapper to boolean --------- Co-authored-by: innay --- dev-docs/bidders/rise.md | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/dev-docs/bidders/rise.md b/dev-docs/bidders/rise.md index 48c840a9..5a6efbfe 100644 --- a/dev-docs/bidders/rise.md +++ b/dev-docs/bidders/rise.md @@ -31,6 +31,7 @@ The Rise adapter requires setup and approval. Please reach out to prebid-rise-en | `placementId` | optional | String | A unique placement identifier | "12345678" | `testMode` | optional | Boolean | This activates the test mode | false | `rtbDomain` | optional | String | Sets the seller end point | "www.test.com" +| `is_wrapper` | private | Boolean | Please don't use unless your account manager asked you to | false ## Example ```javascript @@ -50,7 +51,7 @@ var adUnits = [{ org: '1234567890abcdef12345678', // Required floorPrice: 0.05, // Optional placementId: '12345678', // Optional - testMode: false // Optional, + testMode: false, // Optional, rtbDomain: 'www.test.com' //Optional } }] @@ -74,7 +75,7 @@ var adUnits = [{ org: '1234567890abcdef12345678', // Required floorPrice: 5.00, // Optional placementId: '12345678', // Optional - testMode: false // Optional, + testMode: false, // Optional, rtbDomain: 'www.test.com' //Optional } }] From 865f85554e6ca6e3e5b1d57a2d8b32887b6bc4fa Mon Sep 17 00:00:00 2001 From: bretg Date: Mon, 6 Feb 2023 11:26:49 -0500 Subject: [PATCH 012/762] link to moved cookie policy (#4337) --- cookies.html | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 cookies.html diff --git a/cookies.html b/cookies.html new file mode 100644 index 00000000..ee74f1b4 --- /dev/null +++ b/cookies.html @@ -0,0 +1,5 @@ + + +Redirecting to https://docs.prebid.org/policies/cookies.html + + From 582854a3edaf548573340de53d363b017654441e Mon Sep 17 00:00:00 2001 From: msmeza Date: Mon, 6 Feb 2023 22:46:14 +0100 Subject: [PATCH 013/762] Fix for TOC issue (#4335) There's an issue in `integrate-with-the-prebid-analytics-api.md` that causes the list of benefits of integrating with the Prebid Analytics API to not be rendered in the HTML, probably because of the instruction used to generate the table of contents. The proposed fix is to separate the list and the TOC by introducing some text that will not be rendered in the HTML. --- dev-docs/integrate-with-the-prebid-analytics-api.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/dev-docs/integrate-with-the-prebid-analytics-api.md b/dev-docs/integrate-with-the-prebid-analytics-api.md index a3988e14..78311d54 100644 --- a/dev-docs/integrate-with-the-prebid-analytics-api.md +++ b/dev-docs/integrate-with-the-prebid-analytics-api.md @@ -22,6 +22,8 @@ The Prebid Analytics API provides a way to get analytics data from `Prebid.js` a + Since this API separates your analytics provider's code from `Prebid.js`, the upgrade and maintenance of the two systems are separate. If you want to upgrade your analytics library, there is no need to upgrade or test the core of `Prebid.js`. +[//]: # (This comment is a separator that allows the list above and the TOC to be rendered at the same time) + * TOC {:toc } From aad364086fd490f02aedf53b7a01ca350f669a0e Mon Sep 17 00:00:00 2001 From: Samuel Adu Date: Wed, 8 Feb 2023 14:58:35 +0000 Subject: [PATCH 014/762] Update ConnectId example value to reflect what is really sent to bid adapters (#4345) Co-authored-by: slimkrazy --- dev-docs/modules/userId.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/dev-docs/modules/userId.md b/dev-docs/modules/userId.md index f60ffad8..10c306a4 100644 --- a/dev-docs/modules/userId.md +++ b/dev-docs/modules/userId.md @@ -66,7 +66,7 @@ Publishers that want to do this should design their workflow and then set `_pbjs By including this module and one or more of the sub-modules, a number of new options become available in `setConfig()`, under the `userSync` object as attributes of the `userIds` array of sub-objects. -The `value` parameter can be used to indicate an identifier the publisher has obtained via a direct integration with that identity provider that the publisher wishes to make available to Prebid.js bidders. +The `value` parameter can be used to indicate an identifier the publisher has obtained via a direct integration with that identity provider that the publisher wishes to make available to Prebid.js bidders. Publishers using Google AdManager may want to sync one of the identifiers as their Google PPID for frequency capping or reporting. The PPID in GAM (which is unrelated to the PPID UserId Submodule) has strict rules; refer to [Google AdManager documentation](https://support.google.com/admanager/answer/2880055?hl=en) for them. Please note, Prebid uses a [GPT command](https://developers.google.com/publisher-tag/reference#googletag.PubAdsService) to sync identifiers for publisher convenience. It doesn't currently work for instream video requests, as Prebid typically interacts with the player, which in turn may interact with IMA. IMA does has a [similar method](https://developers.google.com/interactive-media-ads/docs/sdks/html5/client-side/reference/js/google.ima.ImaSdkSettings#setPpid) as GPT, but IMA does not gather this ID from GPT. @@ -164,7 +164,7 @@ The Rubicon bid adapter would then receive ## Bidder Adapter Implementation If your ID structure is complicated, it is helpful to add tests for `pbjs.getUserIds()`, `pbjs.getUserIdsAsEids()` and `pbjs.getUserIdsAsync()`. - + To add a custom data type for the response of `pbjs.getUserIdsAsEids()`, see other examples within the `createEidsArray` method in [/modules/userId/eid.js](https://github.com/prebid/Prebid.js/blob/master/modules/userId/eids.js). ### Prebid.js Adapters @@ -211,7 +211,7 @@ Bidders that want to support the User ID module in Prebid.js need to update thei | SharedID (PBJS 5.x) | n/a | pubcid | pubcid.org | "1111" | | SharedID (PBJS 4.x)| Prebid | sharedid | sharedid.org | {"id":"01EAJWWN...", "third":"01EAJ..."} | | Unified ID | Trade Desk | tdid | adserver.org | "1111" | -| ConnectID | Yahoo | connectId | yahoo.com | "72d04af6..." | +| ConnectID | Yahoo | connectId | yahoo.com | {"connectId": "72d04af6..."} | For example, the adapter code might do something like: From de283a73773e2caf8bce0cd1448ff8991a24908e Mon Sep 17 00:00:00 2001 From: Nick Jacob Date: Thu, 9 Feb 2023 10:49:04 -0500 Subject: [PATCH 015/762] update amxid documentation (#4338) --- dev-docs/modules/userId.md | 2 +- dev-docs/modules/userid-submodules/amxrtb.md | 12 ++++++------ 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/dev-docs/modules/userId.md b/dev-docs/modules/userId.md index 10c306a4..691132f5 100644 --- a/dev-docs/modules/userId.md +++ b/dev-docs/modules/userId.md @@ -179,7 +179,7 @@ Bidders that want to support the User ID module in Prebid.js need to update thei | adQuery QiD | adQuery | qid | adquery.io | "p9v2dpnuckkzhuc..." | | Adriver ID | Adriver | adriverId | adriver.ru | "1111" | | Adtelligent ID | Adtelligent | bidRequest.userId.adtelligentId | `"1111"` | -| AMX RTB ID | AMX RTB | amxId | amxrtb.com | "3ca11058-..." | +| AMX ID | AMX | amxId | amxdt.net | "3ca11058-..." | | BritePool ID | BritePool | britepoolid | britepool.com | "1111" | | AudienceOne ID | DAC | dacId | dac.co.jp | {"id": "1111"} | | DeepIntent ID | Deep Intent | deepintentId | deepintent.com | "1111" | diff --git a/dev-docs/modules/userid-submodules/amxrtb.md b/dev-docs/modules/userid-submodules/amxrtb.md index 87ff9cf4..8ab6d0ee 100644 --- a/dev-docs/modules/userid-submodules/amxrtb.md +++ b/dev-docs/modules/userid-submodules/amxrtb.md @@ -1,16 +1,16 @@ --- layout: userid -title: AMX RTB ID -description: AMX RTB ID User ID sub-module +title: AMX ID +description: AMX ID User ID sub-module useridmodule: amxIdSystem --- -The AMX RTB ID is a first-party identifier designed for publishers using the AMX RTB adapter. For more information please contact [prebid@amxrtb.com](mailto:prebid@amxrtb.com) +The AMX ID is a first-party identifier designed for publishers using the AMX RTB adapter. For more information please contact [info@amxdt.net](mailto:info@amxdt.net) -## AMX RTB ID Configuration +## AMX ID Configuration -First, add the AMX RTB ID module to your Prebid.js build: +First, add the AMX ID module to your Prebid.js build: ```shell gulp build --modules=userId,amxIdSystem @@ -33,7 +33,7 @@ pbjs.setConfig({ }); ``` -This will add a `userId.amxId` property to all bidRequests. This will be read by the AMX RTB bid adapter, and any other adapters that support EIDs: +This will add a `userId.amxId` property to all bidRequests: ```javascript { From ccbb83c55f2522f1cc7fdb8dabd0953057d53146 Mon Sep 17 00:00:00 2001 From: ccorbo Date: Thu, 9 Feb 2023 10:49:34 -0500 Subject: [PATCH 016/762] IX Bid Adapter: add UserID documentation for imuid (#4328) Co-authored-by: Chris Corbo --- dev-docs/bidders/ix.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dev-docs/bidders/ix.md b/dev-docs/bidders/ix.md index 09daf85d..72997706 100644 --- a/dev-docs/bidders/ix.md +++ b/dev-docs/bidders/ix.md @@ -5,7 +5,7 @@ description: Prebid Index Exchange Bidder Adapter biddercode: ix pbjs: true pbs: false -userIds: identityLink, netId, fabrickId, zeotapIdPlus, uid2, unifiedId, id5Id, lotamePanoramaId, publinkId, hadronId, pubcid +userIds: identityLink, netId, fabrickId, zeotapIdPlus, uid2, unifiedId, id5Id, lotamePanoramaId, publinkId, hadronId, pubcid, imuid pbs_app_supported: true schain_supported: true coppa_supported: true From df71a8114f40eb795cf1eddce2b5a2bf4981318e Mon Sep 17 00:00:00 2001 From: EMX Digital <43830380+EMXDigital@users.noreply.github.com> Date: Thu, 9 Feb 2023 07:50:11 -0800 Subject: [PATCH 017/762] Updating EMXDigital Doc to include floors support (#4342) * adding video to supported mediatypes * Adding tcfv2, ccpa and schain support * removing bidder_support_deals * supporting liveramp and uid2 userids * Updating doc for floors support (#2) --------- Co-authored-by: Rakesh Balakrishnan --- dev-docs/bidders/emx_digital.md | 1 + 1 file changed, 1 insertion(+) diff --git a/dev-docs/bidders/emx_digital.md b/dev-docs/bidders/emx_digital.md index 5c6df766..d9dbf610 100644 --- a/dev-docs/bidders/emx_digital.md +++ b/dev-docs/bidders/emx_digital.md @@ -10,6 +10,7 @@ gdpr_supported: true gvl_id: 183 usp_supported: true schain_supported: true +floors_supported: true userIds: identityLink, uid2 sidebarType: 1 --- From 487c8dba36f771523eeddf013f2cee970e595525 Mon Sep 17 00:00:00 2001 From: jsnellbaker <31102355+jsnellbaker@users.noreply.github.com> Date: Thu, 9 Feb 2023 10:51:26 -0500 Subject: [PATCH 018/762] appnexus bidder doc - userid update (#4339) --- dev-docs/bidders/appnexus.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dev-docs/bidders/appnexus.md b/dev-docs/bidders/appnexus.md index 6941b5dc..b3571cfe 100644 --- a/dev-docs/bidders/appnexus.md +++ b/dev-docs/bidders/appnexus.md @@ -6,7 +6,7 @@ biddercode: appnexus media_types: banner, video, native gdpr_supported: true prebid_member: true -userIds: criteo, identityLink, netId, pubProvidedId, uid2, unifiedId, +userIds: all (with commercial activation) schain_supported: true coppa_supported: true usp_supported: true From d2f6270a375448e145a04b306d32fae5c3d2a344 Mon Sep 17 00:00:00 2001 From: Jose Cabal-Ugaz <6942011+josecu@users.noreply.github.com> Date: Thu, 9 Feb 2023 10:53:20 -0500 Subject: [PATCH 019/762] Feature/arcspan rtd provider (#4304) * Added doc for ArcSpan RTD Provider * Added more detail to ArcSpan RTD Provider doc * Added more detail to ArcSpan RTD Provider doc * Clarify ArcSpan RTD Module Documentation * Clarify ArcSpan RTD Module Documentation --- dev-docs/modules/arcspanRtdProvider.md | 61 ++++++++++++++++++++++++++ 1 file changed, 61 insertions(+) create mode 100644 dev-docs/modules/arcspanRtdProvider.md diff --git a/dev-docs/modules/arcspanRtdProvider.md b/dev-docs/modules/arcspanRtdProvider.md new file mode 100644 index 00000000..1b4f3c35 --- /dev/null +++ b/dev-docs/modules/arcspanRtdProvider.md @@ -0,0 +1,61 @@ +--- +layout: page_v2 +title: ArcSpan Contextual APP +display_name: ArcSpan Contextual APP RTD Provider +description: Surfaces contextual classification signals in the bid request to enhance the addressability of ad impressions and increase buyer demand +page_type: module +module_type: rtd +module_code : arcspanRtdProvider +enable_download : true +vendor_specific: true +sidebarType : 1 +--- + +# ArcSpan Contextual APP RTD Provider +{:.no_toc} + +* TOC +{:toc} + +## Prebid Config for ArcSpan RTD Module + +This module attaches contextual classification signals to the site object in the bid request, with the goal of enhancing the addressability of ad impressions and increasing buyer demand. + +{: .alert.alert-warning :} +Disclosure: This module loads external code that is not open source and has not been reviewed by Prebid.org. + +### Usage + +Compile the ArcSpan RTD Module into your Prebid build: + +``` +gulp build --modules=rtdModule,arcspanRtdProvider +``` + +{: .alert.alert-warning :} +Note that the global RTD module, `rtdModule`, is a prerequisite of the ArcSpan RTD Module. + +You then need to enable the ArcSpan RTD Module in your Prebid configuration, using the format below. + +{: .alert.alert-warning :} +Please replace the `silo` parameter value with the one provided by your ArcSpan representative. This will load the latest version of ArcSpan's JavaScript tag that is specific to your ArcSpan seat. + +```javascript +pbjs.setConfig({ + ..., + realTimeData: { + auctionDelay: 50, // optional auction delay + dataProviders: [{ + name: 'arcspan', + waitForIt: true, // should be true if there's an `auctionDelay` + params: { + silo: 1 + } + }] + }, + ... +}) +``` + +{: .alert.alert-info :} +For best results, we recommend that you also deploy ArcSpan's JavaScript tag in your tag management solution, as instructed in the implementation overview you received from your ArcSpan representative. This will ensure that more of your auctions contain ArcSpan's contextual signals. Please reach out to your ArcSpan representative if you have any questions. \ No newline at end of file From 8341db663f689ab2b3c70e9ab4e26918df9cc6cb Mon Sep 17 00:00:00 2001 From: bretg Date: Thu, 9 Feb 2023 12:31:07 -0500 Subject: [PATCH 020/762] Added cookie privacy section (#4350) --- guide.md | 30 +++++++++++++++++++++++++++--- 1 file changed, 27 insertions(+), 3 deletions(-) diff --git a/guide.md b/guide.md index c402b733..b914330d 100644 --- a/guide.md +++ b/guide.md @@ -8,11 +8,12 @@ sidebarType: 0 --- # Prebid Website Maintenance Guide +{:.no_toc} -v 1.2 -Sept 24, 2021 +Updated Feb 9, 2023 -*** +* TOC +{:toc} ## Reviewing Pull Requests and Issues @@ -298,3 +299,26 @@ We use Algolia for site search. - The configuration defining the search parameters is at https://github.com/algolia/docsearch-configs/blob/master/configs/prebid.json - Only elements p, th, td, li, code, and h1-h3 are indexed - Code implementation in _includes/body-end.html and a the 'site-search' div in the header. + +## Cookie Privacy + +Prebid websites don't set their own cookies, but vendor products we use do. So we use the OneTrust CookiePro library to pop up a cookie banner. If the user hasn't consented to setting cookies, they will find reduced functionality on the site -- they won't be able to view JSFiddle examples or example videos. + +This is implemented with the [OptAnon](https://community.cookiepro.com/s/article/UUID-730ad441-6c4d-7877-7f85-36f1e801e8ca?language=en_US) library. See layout/example.md for how the OptAnon.InsertHtml function is used. +The last argument to that function is the "group id", which declares what kind of cookies this vendor script is +going to set. Here's how OneTrust defines the groups: + +1. Strictly Necessary cookies +2. Performance cookies +3. Function cookies +4. Targeting cookies + +OneTrust categorizes cookies on their own, and it seems pretty random to us. Our guideline is to define tools as group 3 for small trusted vendors, or group 4 for large vendors that probably have a database of users. + +The test case for vendor code that drops cookies is simple: + +- clear your prebid.org cookies +- reload the page +- confirm the cookie banner appears +- confirm the vendor's functionality doesn't appear +- confirm that the vendor didn't set any cookies From 4ae32a7a3af346fb82567bf354a44e19b03d5e6d Mon Sep 17 00:00:00 2001 From: Muki Seiler Date: Thu, 9 Feb 2023 19:13:03 +0100 Subject: [PATCH 021/762] Remove google fonts (#4349) --- _includes/head--common.html | 1 - 1 file changed, 1 deletion(-) diff --git a/_includes/head--common.html b/_includes/head--common.html index 92d292a4..04ec6bbc 100644 --- a/_includes/head--common.html +++ b/_includes/head--common.html @@ -1,6 +1,5 @@ - From db67b68791edd396b1988146fa96e43e6bd4d245 Mon Sep 17 00:00:00 2001 From: Chris Huie Date: Thu, 9 Feb 2023 13:59:41 -0700 Subject: [PATCH 022/762] Update Debugging Page with Professor Prebid and Debug Module (#4348) * Update debugging.md * add link to prof prebid * changing the headers added a TOC --------- Co-authored-by: bretg --- debugging/debugging.md | 23 +++++++++++++---------- 1 file changed, 13 insertions(+), 10 deletions(-) diff --git a/debugging/debugging.md b/debugging/debugging.md index 3bc3f007..1ebb13e8 100644 --- a/debugging/debugging.md +++ b/debugging/debugging.md @@ -1,23 +1,26 @@ --- layout: page_v2 -title: Debugging | Prebid -description: Debugging Prebid Extension +title: Debugging | Prebid.js +description: Debugging Prebid.js sidebarType: 1 --- -# Chrome Extension for Debugging Prebid.js +# Debugging Prebid.js +{:.no_toc} -Prebid.Org supports the Chrome extension [Headerbid Expert](https://chrome.google.com/webstore/detail/headerbid-expert/cgfkddgbnfplidghapbbnngaogeldmop). Web publishers can use this tool to understand how their Prebid.js header bidding partners are doing. For example: +* TOC +{:toc} -- What's the latency from each header bidding partner? -- Do they load asynchronously or are they blocking my pages? -- Are they all loaded together in parallel? +## Professor Prebid Chrome Extension for Debugging Prebid.js -Use the tool to determine whether a page might be under-monetized or could -benefit from implementation improvements. +Prebid has a Chrome extension that can be utilized for debugging called [Professor Prebid](https://chrome.google.com/webstore/detail/professor-prebid/kdnllijdimhbledmfdbljampcdphcbdc). Publishers are able to utilize this extension to view Adunits, Bids, Auction Timeline, User IDs, and other details of the ad auctions on a given page. This information can be easily viewed in the various tabs of the extension itself or through a debug page that opens with all the details inside a single page format. In the Professor Prebid ***Tools*** tab you will find this feature along with the ability to easily enable the Prebid.js Debbugging Module (described below) that can also be helpful in debugging. To learn more about all the features and how to utilize this extension please refer to [Professor Prebid](https://docs.prebid.org/tools/professor-prebid.html). -## Further Reading +## Debugging Module + +The Prebid.js debugging module enables the "intercepting" of bids and replacing of the contents with data for testing purposes. To learn more about how to utilize this module please refer to the [Debugging Module](https://docs.prebid.org/dev-docs/modules/debugging.html). + +## Related Reading + [Prebid.js Troubleshooting Guide](/dev-docs/prebid-troubleshooting-guide.html) From 5d2e8f1468cb1126d4e3850dee9733fdcd34837d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Udi=20Talias=20=E2=9A=9B=EF=B8=8F?= Date: Fri, 10 Feb 2023 12:01:09 +0200 Subject: [PATCH 023/762] docs(module): MinuteMediaPlus bid adapter dev-docs (#4281) * MinuteMediaPlus dev docs * bidder code changed to --- dev-docs/bidders/minutemediaplus.md | 34 +++++++++++++++++++++++++++++ 1 file changed, 34 insertions(+) create mode 100644 dev-docs/bidders/minutemediaplus.md diff --git a/dev-docs/bidders/minutemediaplus.md b/dev-docs/bidders/minutemediaplus.md new file mode 100644 index 00000000..800caa33 --- /dev/null +++ b/dev-docs/bidders/minutemediaplus.md @@ -0,0 +1,34 @@ +--- +layout: bidder +title: MinuteMediaPlus +description: Prebid Minute Media Plus Bidder Adaptor +biddercode: mmplus +filename: minutemediaplusBidAdapter +userIds: britepoolId, criteo, id5Id, identityLink, liveIntentId, netId, parrableId, pubCommonId, unifiedId +gdpr_supported: true +usp_supported: true +coppa_supported: false +schain_supported: true +floors_supported: true +media_types: banner, video +prebid_member: false +safeframes_ok: false +deals_supported: false +pbs_app_supported: false +fpd_supported: false +ortb_blocking_supported: false +multiformat_supported: will-bid-on-one +gvl_id: 918 +pbjs: true +sidebarType: 1 +--- + +### Bid Params + +{: .table .table-bordered .table-striped } +| Name | Scope | Description | Example | Type | +|------------|----------|--------------------------------------------------------------------------------------------------|------------------------------|----------| +| `cId` | required | The connection ID from MinuteMediaPlus. | `'562524b21b1c1f08117fc7f9'` | `string` | +| `pId` | required | The publisher ID from MinuteMediaPlus. | `'59ac17c192832d0011283fe3'` | `string` | +| `bidFloor` | required | The minimum bid value desired. MinuteMediaPlus will not respond with bids lower than this value. | `0.90` | `float` | +| `subDomain`| optional | Sets the server subdomain, default: 'exchange'. | `'exchange'` | `string` | From a2c2b42f20f848b5f814403325d9d2696c7f7044 Mon Sep 17 00:00:00 2001 From: danielpfei <122355648+danielpfei@users.noreply.github.com> Date: Fri, 10 Feb 2023 11:01:43 +0100 Subject: [PATCH 024/762] Documentation for Adsinteractive Adapter (#4282) Co-authored-by: balintvargha <122350182+balintvargha@users.noreply.github.com> --- dev-docs/bidders/adsinteractive.md | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) create mode 100644 dev-docs/bidders/adsinteractive.md diff --git a/dev-docs/bidders/adsinteractive.md b/dev-docs/bidders/adsinteractive.md new file mode 100644 index 00000000..71a7ef87 --- /dev/null +++ b/dev-docs/bidders/adsinteractive.md @@ -0,0 +1,21 @@ +--- +layout: bidder +title: AdsInteractive +description: Prebid AdsInteractive Bidder Adapter +biddercode: adsinteractive +media_types: banner +pbjs: true +pbs: true +deals_supported: false +--- + +### Registration + +The AdsInteractive adapter requires setup and approval. Please reach out to it@adsinteractive.com to setup your account. + +### Bid Params + +{: .table .table-bordered .table-striped } +| Name | Scope | Description | Example | Type | +|---------------|----------|--------------|-----------|----------| +| `adUnit` | required | adUnit tag name | `'example_adunit_1'` | `string` | From b7e7475d84c94fd4fbf12147d8fb8d766cda6b65 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Maxime=20DEYM=C3=88S?= <47388595+MaxSmileWanted@users.noreply.github.com> Date: Fri, 10 Feb 2023 11:02:15 +0100 Subject: [PATCH 025/762] SmileWanted Adapter : Update support of eids (#4289) --- dev-docs/bidders/smilewanted.md | 1 + 1 file changed, 1 insertion(+) diff --git a/dev-docs/bidders/smilewanted.md b/dev-docs/bidders/smilewanted.md index 946e42d5..a56e2e1e 100644 --- a/dev-docs/bidders/smilewanted.md +++ b/dev-docs/bidders/smilewanted.md @@ -8,6 +8,7 @@ pbs: true biddercode: smilewanted gdpr_supported: true usp_supported: true +userIds: all gvl_id: 639 sidebarType: 1 --- From 3f0270fc3342e7064ea76ffb55bdd2de5ba9d719 Mon Sep 17 00:00:00 2001 From: bretg Date: Fri, 10 Feb 2023 11:44:28 -0500 Subject: [PATCH 026/762] PBS fledge (#4356) --- dev-docs/modules/fledgeForGpt.md | 2 +- .../endpoints/openrtb2/pbs-endpoint-auction.md | 14 ++++++++++++++ prebid-server/features/pbs-feature-idx.md | 1 + 3 files changed, 16 insertions(+), 1 deletion(-) diff --git a/dev-docs/modules/fledgeForGpt.md b/dev-docs/modules/fledgeForGpt.md index 265944e7..f26d439b 100644 --- a/dev-docs/modules/fledgeForGpt.md +++ b/dev-docs/modules/fledgeForGpt.md @@ -9,7 +9,7 @@ enable_download : true sidebarType : 1 --- -# Overview +# Fledge for GPT Module This module allows Prebid.js to support FLEDGE by integrating it with GPT's [experimental FLEDGE support](https://github.com/google/ads-privacy/tree/master/proposals/fledge-multiple-seller-testing). diff --git a/prebid-server/endpoints/openrtb2/pbs-endpoint-auction.md b/prebid-server/endpoints/openrtb2/pbs-endpoint-auction.md index 6eced100..9d30996b 100644 --- a/prebid-server/endpoints/openrtb2/pbs-endpoint-auction.md +++ b/prebid-server/endpoints/openrtb2/pbs-endpoint-auction.md @@ -110,6 +110,18 @@ This is a corresponding sample response to a sample OpenRTB 2.5 bid request: } } ``` + +#### Fledge Auctions + +[Fledge](https://github.com/google/ads-privacy/tree/master/proposals/fledge-multiple-seller-testing) is an experimental approach to running online ad auctions with enhanced privacy. + +Prebid Server's support for Fledge is a passthrough: + +1. If the request contains `imp.ext.ae: 1` +2. Bid adapters may respond with 'auction config' that's placed in `ext.prebid.fledge.auctionconfigs[]`. + +The auction config must then be used by the client. See the Prebid.js [Fledge for GPT](/dev-docs/modules/fledgeForGpt.html) module for more information. + ### OpenRTB Fields Prebid Server accepts all OpenRTB 2.5 fields and passes them in the request to all bid and analytics adapters. Some fields are processed by Prebid Server in the following ways: @@ -1532,6 +1544,7 @@ The Prebid SDK version comes from: | ext.prebid.pbs.endpoint | additional Prebid Server metadata | string | yes | | ext.prebid.floors | PBS floors data | object | no | | imp.ext.prebid.adunitcode | Prebid.js adunit code | string | yes | +| imp.ext.ae | If 1, signals bid adapters that Fledge auction config is accepted on the response. (ae stands for auction environment) | integer | yes | | app.ext.prebid.source | The client that created this ORTB. Normally "prebid-mobile" | string | yes | | app.ext.prebid.version | The version of the client that created this ORTB. e.g. "1.1" | string | yes | @@ -1556,6 +1569,7 @@ The Prebid SDK version comes from: | ext.errors.BIDDER | Debug Mode: errors from the named bidder | object | | ext.responsetimemillisv.BIDDER | Debug Mode: how long the named bidder took to respond with a bid. | integer | | ext.prebid.passthrough | Copy of request ext.prebid.passthrough, see [passthrough](#request-passthrough). | object| +| ext.prebid.fledge.auctionconfigs | Bidder-supplied [Fledge](https://github.com/google/ads-privacy/tree/master/proposals/fledge-multiple-seller-testing) responses. | array of objects | ### Further Reading diff --git a/prebid-server/features/pbs-feature-idx.md b/prebid-server/features/pbs-feature-idx.md index 19ef265c..3ad6fc3e 100644 --- a/prebid-server/features/pbs-feature-idx.md +++ b/prebid-server/features/pbs-feature-idx.md @@ -91,5 +91,6 @@ title: Prebid Server | Features | Modules | [ortb2-blocking](/prebid-server/pbs-modules/ortb2-blocking.html) | Configure per-account OpenRTB blocking details. | | | | Anti-Fraud | Ads.Cert 2.0 Authenticated Connections | Includes authenticated connection signing header on outgoing bid requests to supported adapters. * | | | | Request Enrichment | Enhanced tid and request IDs | Fills out id, imp.id, source.tid, and imp.ext.tid | | | +| Auction Response | Bidders can supply [Fledge](https://github.com/google/ads-privacy/tree/master/proposals/fledge-multiple-seller-testing) auction config | If the request contains imp.ext.ae, bid adapters can return ext.prebid.fledge.auctionconfigs | | | \* Experimental feature not yet recommended for production. From b7640170f8466bf6ab51fd18bcc2b80d774ede6c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dani=C3=ABl=20Hoeksema?= <37441336+danielsao@users.noreply.github.com> Date: Fri, 10 Feb 2023 18:29:20 +0100 Subject: [PATCH 027/762] Update ramp.md (#4343) --- dev-docs/modules/userid-submodules/ramp.md | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/dev-docs/modules/userid-submodules/ramp.md b/dev-docs/modules/userid-submodules/ramp.md index ad9ca698..b521e645 100644 --- a/dev-docs/modules/userid-submodules/ramp.md +++ b/dev-docs/modules/userid-submodules/ramp.md @@ -1,7 +1,7 @@ --- layout: userid -title: RampID -description: RampID User ID sub-module +title: LiveRamp RampID +description: LiveRamp RampID User ID sub-module useridmodule: identityLinkIdSystem --- @@ -26,8 +26,8 @@ The RampID privacy policy is at [https://liveramp.com/privacy/service-privacy-po | --- | --- | --- | --- | --- | | name | Required | String | The name of LiveRamp's user ID module. | `"identityLink"` | | params | Required | Object | Container of all module params. | | -| params.pid | Required | String | This is the Placement ID, a unique identifier that is used to identify each publisher, obtained from registering with LiveRamp. | `999` | -| params.notUse3P | Not required | Boolean | Property for choosing if a cookieable envelope should be set and stored until the user authenticates and a RampID envelope can be created (either `true` or `false`). | `false` | +| params.pid | Required | String | This is the Placement ID, a unique identifier that is used to identify each publisher, obtained from registering with LiveRamp. | `"999"` | +| params.notUse3P | Not required | Boolean | Property for choosing if a cookieable RampID envelope (RTIS) should be set and stored until the user authenticates which then will be replaced by an authenticated RampID envelope (ATS) (either `true` or `false`). | `false` | | storage | Required | Object | This object defines where and for how long the results of the call to get a RampID envelope will be stored. | | storage.type | Required | String | This parameter defines where the resolved RampID envelope will be stored (either `"cookie"` or `"html5"` localStorage). | `"cookie"` | | storage.name | Required | String | The name of the cookie or html5 localstorage where the resolved RampID envelope will be stored. LiveRamp requires `"idl_env"`. | `"idl_env"` | @@ -39,7 +39,7 @@ The RampID privacy policy is at [https://liveramp.com/privacy/service-privacy-po ## RampID Examples -1) Publisher passes a Placement ID and elects to store the RampID envelope in a cookie. +1) Publisher passes a Placement ID and elects to store the RampID envelope in a first-party cookie. {% highlight javascript %} pbjs.setConfig({ @@ -47,8 +47,8 @@ pbjs.setConfig({ userIds: [{ name: "identityLink", params: { - pid: '999', // Set your Placement ID here - notUse3P: true/false // If you want to generate and use a RampID based on a LiveRamp 3p cookie (from a previous authentication) until ATS can generate a new RampID, set this property to false + pid: "999", // Set your Placement ID here + notUse3P: false }, storage: { type: "cookie", @@ -70,8 +70,8 @@ pbjs.setConfig({ userIds: [{ name: "identityLink", params: { - pid: '999', // Set your Placement ID here - notUse3P: true/false // If you want to generate and use a RampID based on a LiveRamp 3p cookie (from a previous authentication) until ATS can generate a new RampID, set this property to false + pid: "999", // Set your Placement ID here + notUse3P: false }, storage: { type: "html5", From 8379e5cfd1e53a7f972b68850486306c6a2f5093 Mon Sep 17 00:00:00 2001 From: Yuriy Velichko Date: Fri, 10 Feb 2023 19:36:46 +0200 Subject: [PATCH 028/762] Mobile: various clarification info (#4351) * android: add warning to check the Android SDK version on build from source * TCF: add warnings about prioritization of TCF signals * typo fix * typo fix --------- Co-authored-by: Chris Huie --- .../pbm-api/android/code-integration-android.md | 7 +++++++ .../pbm-api/android/pbm-targeting-params-android.md | 12 ++++++++++++ prebid-mobile/pbm-api/ios/pbm-targeting-ios.md | 12 ++++++++++++ 3 files changed, 31 insertions(+) diff --git a/prebid-mobile/pbm-api/android/code-integration-android.md b/prebid-mobile/pbm-api/android/code-integration-android.md index 052e024b..17679958 100644 --- a/prebid-mobile/pbm-api/android/code-integration-android.md +++ b/prebid-mobile/pbm-api/android/code-integration-android.md @@ -56,6 +56,13 @@ scripts/buildPrebidMobile.sh This will output the PrebidMobile framework for Android. +{% capture warning_note %} +If you see errors while building the Prebid Mobile SDK or Demo Applications, make sure that the needed Android SDK version is set up on your machine. Check the gradle build configs for the project and applications for details about the current required version. + +{% endcapture %} +{% include /alerts/alert_warning.html content=warning_note %} + + ## Initialize SDK {% capture warning_note %} diff --git a/prebid-mobile/pbm-api/android/pbm-targeting-params-android.md b/prebid-mobile/pbm-api/android/pbm-targeting-params-android.md index b955f62c..651e7163 100755 --- a/prebid-mobile/pbm-api/android/pbm-targeting-params-android.md +++ b/prebid-mobile/pbm-api/android/pbm-targeting-params-android.md @@ -23,6 +23,18 @@ Prebid SDK doesn't modify values for IAB-defined keys in the `SharedPreferences` The values provided via targeting API will be included in the bid request according to the `TCF v2` framework. +{% capture warning_note %} + +Since the SDK API has priority over CMP values, using the API blocks the CMP signals. Use a single way to provide the TCF signals. + +If you need to use an API way, ensure that all the following properties are set in the app code. + +If you need to use a CMP way, ensure that you don't set any of the following API properties. + + +{% endcapture %} +{% include /alerts/alert_warning.html content=warning_note %} + ### Subject To GPDR {:.no_toc} diff --git a/prebid-mobile/pbm-api/ios/pbm-targeting-ios.md b/prebid-mobile/pbm-api/ios/pbm-targeting-ios.md index 9ac25b30..5e3261ff 100644 --- a/prebid-mobile/pbm-api/ios/pbm-targeting-ios.md +++ b/prebid-mobile/pbm-api/ios/pbm-targeting-ios.md @@ -27,6 +27,18 @@ Prebid SDK doesn't modify values for IAB-defined keys in the `UserDefaults`. Ins The values provided via targeting API will be included in the bid request according to the `TCF v2` framework. +{% capture warning_note %} + +Since the SDK API has priority over CMP values, using the API blocks the CMP signals. Use a single way to provide the TCF signals. + +If you need to use an API way, ensure that all the following properties are set in the app code. + +If you need to use a CMP way, ensure that you don't set any of the following API properties. + + +{% endcapture %} +{% include /alerts/alert_warning.html content=warning_note %} + ### Subject To GPDR ``` From e03e42e02e29451fdea0f06dce7880a8ebfaad25 Mon Sep 17 00:00:00 2001 From: Muki Seiler Date: Fri, 10 Feb 2023 18:37:23 +0100 Subject: [PATCH 029/762] Add new google analytics v4 tag (#4347) --- _includes/footer.html | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/_includes/footer.html b/_includes/footer.html index 7e04247f..c734d23e 100644 --- a/_includes/footer.html +++ b/_includes/footer.html @@ -12,14 +12,18 @@ - - + + From 61ef51822c82ac7959e586022aa88d5a18b8d155 Mon Sep 17 00:00:00 2001 From: Chris Huie Date: Sat, 11 Feb 2023 14:25:01 -0700 Subject: [PATCH 030/762] Remove Prebid 1.0 Page (#4354) --- dev-docs/prebid-1.0-API.md | 278 ------------------------------------- 1 file changed, 278 deletions(-) delete mode 100644 dev-docs/prebid-1.0-API.md diff --git a/dev-docs/prebid-1.0-API.md b/dev-docs/prebid-1.0-API.md deleted file mode 100644 index d8a7b8a4..00000000 --- a/dev-docs/prebid-1.0-API.md +++ /dev/null @@ -1,278 +0,0 @@ ---- -layout: page_v2 -title: Prebid 1.0 Publisher API Changes -description: Description of the changes to the publisher facing API for Prebid 1.0 -top_nav_section: dev_docs -nav_section: reference - -sidebarType: 1 ---- - - - -# Prebid 1.0 Publisher API Changes -{:.no_toc} - -This document describes the changes to the Publisher API for Prebid.js version 1.0. - -* TOC -{:toc} - -## Removed Functions and Variables - -The following functions and variables were removed as of 1.0: - -- All `pbjs._*` variables, including: - - `pbjs._winningBids` - - `pbjs._bidsReceived` - - `pbjs._bidsRequested` - - `pbjs._adUnitCodes` - - `pbjs._adsReceived` - - `pbjs.cbTimeout` -- `pbjs.addCallback` and `pbjs.removeCallback` in favor of the [onEvent API](/dev-docs/publisher-api-reference/onEvent.html) -- `pbjs.allBidsAvailable` -- `pbjs.buildMasterVideoTagFromAdserverTag` in favor of [`pbjs.adServers.dfp.buildVideoUrl`](/dev-docs/publisher-api-reference/adServers.dfp.buildVideoUrl.html) -- `adUnit.sizeMapping` in favor of [`pbjs.setConfig({sizeConfig:[ ... ]})`]({{site.baseurl}}/dev-docs/prebid-1.0-API.html#size-mapping-changes) - -Other methods were removed as part of the [new `setConfig` API](/dev-docs/publisher-api-reference/setConfig.html) - for details, see [the section below describing the new `pbjs.setConfig` API](#pbjs.setConfig). - -{: .alert.alert-success :} -For a complete list of methods that were removed, see the [Publisher API Reference]({{site.baseurl}}/dev-docs/publisher-api-reference.html). - - - -## Legacy APIs replaced by `pbjs.setConfig` - -For 1.0, the following APIs were removed in favor of a generic "options" param object passed to [`pbjs.setConfig`](/dev-docs/publisher-api-reference/setConfig.html): - -- `pbjs.bidderTimeout` - use `pbjs.setConfig({bidderTimeout})` instead -- `pbjs.logging` - use `pbjs.setConfig({debug})` instead -- `pbjs.publisherDomain` - use `pbjs.setConfig({publisherDomain})` instead -- `pbjs.setPriceGranularity` - use `pbjs.setConfig({priceGranularity})` instead -- `pbjs.enableSendAllBids`- use `pbjs.setConfig({enableSendAllBids})` instead. Now defaults to `true`. -- `pbjs.setBidderSequence` - use `pbjs.setConfig({bidderSequence})` instead -- `pbjs.setS2SConfig` - use `pbjs.setConfig({s2sConfig})` instead - -### `pbjs.setConfig` Example -{:.no_toc} - -{: .alert.alert-warning :} -The input to `pbjs.setConfig` must be JSON (no JavaScript functions are allowed). - -{% highlight js %} - -pbjs.setConfig({ - currency: { - "adServerCurrency": "JPY", - "conversionRateFile": "" - }, - debug: true, // Previously `logging` - s2sConfig: { ... }, - priceGranularity: "medium", - enableSendAllBids: false, // Default will be `true` as of 1.0 - bidderSequence: "random", // Default is random - bidderTimeout: 700, // Default for all requests. - publisherDomain: "abc.com", // Used for SafeFrame creative. - pageOptions: { ... }, - cache: {url: ""} -}); - -{% endhighlight %} - -## No More Default Endpoints - -In Prebid 0.x there were defaults for the Prebid Server endpoints and the video cache URL. With 1.0, these defaults have been removed to be vendor neutral, so all publisher pages must define them via `pbjs.setConfig()`. The same functionality as 0.x may be achieved as shown below: - -{% highlight js %} - -pbjs.setConfig({ - cache: {url: "https://prebid.adnxs.com/pbc/v1/cache"}, - s2sConfig: { - ... - endpoint: "https://prebid.adnxs.com/pbs/v1/openrtb2/auction", - syncEndpoint: "https://prebid.adnxs.com/pbs/v1/cookie_sync", - ... - } -}); - -{% endhighlight %} - -## Size Mapping Changes - -The previous [`sizeMapping` functionality]({{site.baseurl}}/dev-docs/examples/size-mapping.html) was removed and replaced by a `sizeConfig` parameter to the `pbjs.setConfig` method that provides a more powerful way to describe types of devices and -screens. - -If `sizeConfig` is passed to `pbjs.setConfig`: - -- Before `requestBids` sends bids requests to adapters, it will evaluate and pick the appropriate label(s) based on the `sizeConfig.mediaQuery` and device properties and then filter the `adUnit.bids` based on the `labels` defined (by dropping those ad units that don't match the label definition). - - - The `sizeConfig.mediaQuery` property allows media queries in the form described [here](https://developer.mozilla.org/en-US/docs/Web/CSS/Media_Queries/Using_media_queries). They are tested using the [`window.matchMedia` API](https://developer.mozilla.org/en-US/docs/Web/API/Window/matchMedia). - -- If a label conditional (e.g. labelAny) doesn’t exist on an ad unit, it is automatically included in all requests for bids. - -- If multiple rules match, the sizes will be filtered to the intersection of all matching rules' `sizeConfig.sizesSupported` arrays. - -- The `adUnit.sizes` selected will be filtered based on the `sizesSupported` property of the matched `sizeConfig`. So the `adUnit.sizes` is a subset of the sizes defined from the resulting intersection of `sizesSupported` sizes and `adUnit.sizes`. - -### `sizeConfig` Example -{:.no_toc} - -To set size configuration rules, you can pass `sizeConfig` into `pbjs.setConfig` as follows: - -{% highlight js %} - -pbjs.setConfig({ - sizeConfig: [{ - 'mediaQuery': '(min-width: 1200px)', - 'sizesSupported': [ - [970, 90], - [728, 90], - [300, 250] - ], - 'labels': ['desktop'] - }, { - 'mediaQuery': '(min-width: 768px) and (max-width: 1199px)', - 'sizesSupported': [ - [728, 90], - [300, 250] - ], - 'labels': ['tablet', 'phone'] - }, { - 'mediaQuery': '(min-width: 0px)', - 'sizesSupported': [ - [300, 250], - [300, 100] - ], - 'labels': ['phone'] - }] -}); - -{% endhighlight %} - -### Labels -{:.no_toc} - -Labels can now be specified as a property on either an `adUnit` or on `adUnit.bids[]`. The presence of a label will disable the adUnit or bidder unless a sizeConfig rule has matched and enabled the label or the label has been enabled manually by passing them into through requestBids: `pbjs.requestBids({labels:[]})`. - -Labels may be targeted in the AdUnit structure by two conditional operators: `labelAny` and `labelAll`. - -With the `labelAny` operator, just one label has to match for the condition to be true. In the example below, either A or B can be defined in the label array to activate the bid or ad unit: -{% highlight bash %} -labelAny: ["A", "B"] -{% endhighlight %} - -With the `labelAll` conditional, every element of the target array must match an element of the label array in -order for the condition to be true. In the example below, both A and B must be defined in the label array to activate the bid or ad unit: -{% highlight bash %} -labelAll: ["A", "B"] -{% endhighlight %} - -{: .alert.alert-warning :} -Only one conditional may be specified on a given AdUnit or bid -- if both `labelAny` and `labelAll` are specified, only the first one will be utilized and an error will be logged to the console. It is allowable for an AdUnit to have one condition and a bid to have another. - -{: .alert.alert-warning :} -If either `labelAny` or `labelAll` values is an empty array, it evaluates to `true`. - - -Defining labels on the adUnit looks like the following: - -{% highlight js %} - -pbjs.addAdUnits([{ - code: "ad-slot-1", - mediaTypes: { - banner: { - sizes: [ - [970, 90], - [728, 90], - [300, 250], - [300, 100] - ] - } - }, - labelAny: ["visitor-uk"] - /* The full set of bids, not all of which are relevant on all devices */ - bids: [{ - bidder: "pulsepoint", - /* Labels flag this bid as relevant only on these screen sizes. */ - labelAny: ["desktop", "tablet"], - params: { - "cf": "728X90", - "cp": 123456, - "ct": 123456 - } - }, - { - bidder: "pulsepoint", - labelAny: ["desktop", "phone"], - params: { - "cf": "300x250", - "cp": 123456, - "ct": 123456 - } - }, - { - bidder: "sovrn", - labelAny: ["desktop", "tablet"], - params: { - "tagid": "123456" - } - }, - { - bidder: "sovrn", - labelAny: ["phone"], - params: { - "tagid": "111111" - } - } - ] -}]); - -{% endhighlight %} - -See [Conditional Ad Units]({{site.baseurl}}/dev-docs/conditional-ad-units.html) for additional use cases around labels. - - -### Manual Label Configuration -{:.no_toc} - -If an adUnit and/or adUnit.bids[] bidder has labels defined, they will be disabled by default. Manually setting active labels through `pbjs.requestBids()` will enable the selected adUnits and/or bidders. - -You can manually turn on labels using the following code: - -{% highlight js %} - -pbjs.requestBids({ - labels: ['visitor-uk'] -}); - -{% endhighlight %} - -## Ad Unit Changes - -The `mediaType` attribute has been removed in favor of a `mediaTypes` object. This object accepts multiple properties (i.e. `video`, `banner`, `native` etc) with an optional key-value pair object nested inside, e.g.: - -{% highlight js %} - -adUnit = { - "code": "unique_code_for_placement" - "mediaTypes": { // New field to replace `mediaType`. Defaults to `banner` if not specified. - video: { - context: 'outstream', - playerSize: [600, 480] - }, - banner: { - sizes: [300, 250], - ...options - }, - native: { ...options } - }, - labelAny: ["desktop", "mobile"] - bids: { ... } // Same as existing definition with addition of `label` attribute. -} - -{% endhighlight %} - -## Further Reading - -+ [Publisher API Reference]({{site.baseurl}}/dev-docs/publisher-api-reference.html) From 15f725a25d639caf2da843d09149e0ee3b4dcd22 Mon Sep 17 00:00:00 2001 From: bretg Date: Mon, 13 Feb 2023 09:18:10 -0500 Subject: [PATCH 031/762] PBS auction endpoint: ortb 2.6, seatnonbid (#4295) * PBS auction endpoint: ortb 2.6, sendnonbid * added tmax * Adding ID/TID updates * review comments * formatting moved pseudo-code out of 2.6 table into section below * Update pbs-endpoint-auction.md --- .../openrtb2/pbs-endpoint-auction.md | 146 ++++++++++++++++-- 1 file changed, 133 insertions(+), 13 deletions(-) diff --git a/prebid-server/endpoints/openrtb2/pbs-endpoint-auction.md b/prebid-server/endpoints/openrtb2/pbs-endpoint-auction.md index 9d30996b..e290067c 100644 --- a/prebid-server/endpoints/openrtb2/pbs-endpoint-auction.md +++ b/prebid-server/endpoints/openrtb2/pbs-endpoint-auction.md @@ -124,12 +124,73 @@ The auction config must then be used by the client. See the Prebid.js [Fledge fo ### OpenRTB Fields -Prebid Server accepts all OpenRTB 2.5 fields and passes them in the request to all bid and analytics adapters. Some fields are processed by Prebid Server in the following ways: +Prebid Server accepts all OpenRTB 2.5 fields and passes them in the request to all bid and analytics adapters. Some ORTB 2.6 fields are supported. Here are the fields with special processing: -#### Currency +{: .table .table-bordered .table-striped } +| ORTB Field | Version | Notes | +| --- | --- | --- | +| id | 2.5 | See below | +| source.tid | 2.5 | See below | +| imp[].id | 2.5 | See below | +| imp[].ext.tid | 2.x | See below | +| cur | 2.5 | Only the first array element is taken to be the "Ad Server Currency" for purposes of [currency conversion](/prebid-server/features/pbs-currency.html). | +| exp | 2.5 | See the [expiration](#expiration) section below | +| tmax | 2.5 | See the [timeout](#timeout) section below | +| device.lmt | 2.5 | See special processing for iOS apps defined in [issue 1699](https://github.com/prebid/prebid-server/issues/1699) | +| regs.gdpr | 2.6 | Bidders supporting 2.5 only: downgraded to regs.ext.gdpr | +| regs.us_privacy | 2.6 | Bidders supporting 2.5 only: downgraded to regs.ext.us_privacy | +| user.consent | 2.6 | Bidders supporting 2.5 only: downgraded to user.ext.consent | +| imp.rwdd | 2.6 | Bidders supporting 2.5 only: downgraded to imp.ext.prebid.is_rewarded_inventory | +| user.eids | 2.6 | Bidders supporting 2.5 only: downgraded to user.ext.eids | +| source.schain | 2.6 | Bidders supporting 2.5 only: downgraded to source.ext.schain | +| wlangb, {content, device}.langb, cattax, {site, app, publisher, content, producer}.cattax, ssai, {app, site}.content.{network, channel}, {app, content, site, user}.kwarray, device.sua | 2.6 | Bidders supporting 2.5 only: these fields are removed | +| {video, audio}.{rqddurs, maxseq, poddur, podid, podseq, mincpmpersec, slotinpod} | 2.6 | Bidders supporting 2.5 only: these fields are removed | +| regs.gpp | 2.6-202211 | Bidders supporting 2.5 only: this field is removed | +| regs.gpp_sid | 2.6-202211 | Bidders supporting 2.5 only: this field is removed | +| dooh | 2.6-202211 | not yet supported by PBS | +| imp.qty | 2.6-202211 | (PBS-Go only so far) Bidders supporting 2.5 only: this field is removed | +| imp.dt | 2.6-202211 | (PBS-Go only so far) Bidders supporting 2.5 only: this field is removed | + +#### IDs + +Prebid Server has the ability to fill in key IDs in the request. + +##### request.id + +``` +if host config generate_request_id (Go) / generate-storedrequest-bidrequest-id (Java) is true + if $.id is not set, generate a random value + if the storedrequest is from AMP or from ext.prebid.storedrequest, then replace any existing $.id with a random value +if $.id contains "{{UUID}}", replace that macro with a random value +``` -The `cur` field is read and the first element of the array is taken to be the -"Ad Server Currency" for purposes of [currency conversion](/prebid-server/features/pbs-currency.html). +##### request.source.tid + +``` +if source.tid is not set: + set source.tid to a random UUID +if host config auto_gen_source_tid (Go) / generate-storedrequest-bidrequest-id (Java) is true + if the storedrequest is from AMP or from a top-level stored request (ext.prebid.storedrequest), then replace any existing $.source.tid with a random value +if $.source.tid contains "{{UUID}}", replace that macro with a random value +``` + +##### request.imp[].id + +``` +if host config generate-storedrequest-bidrequest-id config is true + if any $.imp[].id is missing, set it to a random 16-digit string. (Note: this wasn't in issue 1507) + if the storedrequest is from AMP **or** from a top-level stored request (ext.prebid.storedrequest), confirm that all $.imp[].id fields in the request are different. If not different, re-number them all starting from "1". +``` + +##### request.imp[].ext.tid + +``` +if imp[n].ext.tid is not set: + set imp[n].ext.tid to a randomly generated UUID + if host config generate-storedrequest-bidrequest-id config is true + if the storedrequest is from AMP or from ext.prebid.storedrequest, then replace any existing $.imp[n].ext.tid with a random value +if $.imp[n].ext.tid contains "{{UUID}}", replace that macro with a random value +``` #### Expiration @@ -162,15 +223,36 @@ How long an item is stored in Prebid Cache is determined by this hunt path: 4. account config: {banner,video}-cache-ttl 5. global config: cache.{banner,video}-ttl-seconds -#### Privacy fields +#### Timeout + +The OpenRTB 2.5 `imp[].exp` field defines how long Prebid Server has to process the request +before the client will stop waiting. + +This field is used in different ways by PBS-Go and PBS-Java: + +##### PBS-Go + +1. if tmax is not specified or is 0, use the host configured default value (auction_timeout_ms.default) +1. if tmax is over the host defined max, cap it to the host defined max (auction_timeout_ms.max) + +##### PBS-Java -Prebid Server reads the OpenRTB privacy fields: +Core concepts: -- regs.coppa -- regs.ext.gdpr -- regs.ext.us_privacy -- user.ext.consent -- device.lmt +- request_tmax: what the incoming ORTB request defines as tmax (as milliseconds) +- biddertmax_max: controls that upstream doesn't tell us ridiculous values. In milliseconds. (configuration auction.biddertmax.max) +- biddertmax_min: it's not worth calling bidders and give them less time than this number of milliseconds (configuration (auction.biddertmax.min). Note: we recommend this value be at least 150 ms) +- biddertmax_percent: a lower number means more buffer for network delay. Host companies should set this to a lower value in regions where the network connections are slower. (configuration auction.biddertmax.percent) +- tmax_upstream_response_time: the amount of time (in ms) that PBS needs to respond to the original caller (configuration auction.tmax-upstream-response-time) +- processing_time: PBS calculation for how long it's been since the start of the request up to the point where the bidders are called +- bidder_tmax: this is what PBS-core tells the bidders they have to respond. The conceptual formula is: capped(request_tmax)*biddertmax_percent - processing_time - tmax_upstream_response_time ==> must be at least the configured min +- enforced_tmax: this is long PBS-core actually gives the bidders: capped(request_tmax)- processing_time - tmax_upstream_response_time ==> cannot be lower than bidder_tmax + +The full formulas: + +bidder_tmax=max(calculated_tmax, biddertmax_min)=max((min(request_tmax,biddertmax_max)*biddertmax_percent)-processing_time - tmax_upstream_response_time, biddertmax_min) + +enforced_tmax=max(calculated_enforcement,bidder_tmax)=max(min(request_tmax,biddertmax_max)-processing_time - tmax_upstream_response_time , bidder_tmax) ### OpenRTB Extensions @@ -1436,6 +1518,42 @@ This contains the request after the resolution of stored requests and implicit i `response.seatbid[].bid[].ext.origbidcpm` and `response.seatbid[].bid[].ext.origbidcur` will contain the original bid price/currency from the bidder. The value in seatbid[].bid[].price may be converted for currency and adjusted with a [bid adjustment factor](/prebid-server/endpoints/openrtb2/pbs-endpoint-auction.html#bid-adjustments). +##### Seat Non-Bid + +{: .alert.alert-info :} +PBS-Java only + +Prebid Server supports an ORTB extension that allows callers to get more information about bidders that may have had a chance to bid but did not. Eventually the system will support a fine-grained set of codes describing why a given bidder didn't bid on a particular impression, but for now we're phasing in the necessary internal infrastructure. + +To enable the additional output, set `ext.prebid.returnallbidstatus: true`. + +Here's a sample response: +``` +{ + ... + "ext": { + "seatnonbid": [ + { + "seat": "rubiconAlias", + "nonbid": [ + { + "impid": "test-div", + "statuscode": 0 + } + ] + } + } +} +``` + +The codes currently returned: + +{: .table .table-bordered .table-striped } +| Code | | Meaning | Platform | Notes | +| --- | --- | --- | --- | +| 0 | General No Bid | Java | The bidder had a chance to bid, and either declined to bid, returned an error, or the response was removed. | + + ### OpenRTB Ambiguities This section describes the ways in which Prebid Server **implements** OpenRTB spec ambiguous parts. @@ -1511,8 +1629,9 @@ The Prebid SDK version comes from: | imp[].ext.prebid.storedauctionresponse | PBS-Core skips the auction and uses the response in the DB instead, see [stored responses](/prebid-server/endpoints/openrtb2/pbs-endpoint-auction.html#stored-responses). | object | no | | imp[].ext.prebid.storedbidresponse | PBS-Core calls the adapter with the response in the DB instead of actually running the auction,see [stored responses](/prebid-server/endpoints/openrtb2/pbs-endpoint-auction.html#stored-responses). | object | no | | imp[].ext.prebid.storedrequest.id | Look up the defined stored request and merge the DB contents with this imp, see [stored requests](/prebid-server/endpoints/openrtb2/pbs-endpoint-auction.html#stored-requests). | object | no (yes with [issue 2292](https://github.com/prebid/prebid-server/issues/2292) | -| imp[].ext.prebid.is_rewarded_inventory | Passed through to bid adapters, see [rewarded video](/prebid-server/endpoints/openrtb2/pbs-endpoint-auction.html#rewarded-video). | integer | yes | +| imp[].ext.prebid.is_rewarded_inventory | (deprecated) Passed through to bid adapters, see [rewarded video](/prebid-server/endpoints/openrtb2/pbs-endpoint-auction.html#rewarded-video). (use imp.rwdd in ORTB 2.6) | integer | yes | | imp[].ext.prebid.passthrough | Allows an application to pass a value through to the response, see [request passthrough](#request-passthrough). | object | no | +| imp.ext.prebid.adunitcode | Prebid.js adunit code | string | yes | | app.ext.source | Defined by Prebid SDK.
ex: `"prebid-mobile"` | string | yes | | app.ext.version | Defined by Prebid SDK,
ex: `"1.6"` | string | yes | | device.ext.prebid.interstitial | PBS-core will adjust the sizes on a request for interstitials,see [interstitial support](/prebid-server/endpoints/openrtb2/pbs-endpoint-auction.html#interstitial-support). | object | yes | @@ -1543,7 +1662,7 @@ The Prebid SDK version comes from: | ext.prebid.server | additional Prebid Server metadata | object | yes | | ext.prebid.pbs.endpoint | additional Prebid Server metadata | string | yes | | ext.prebid.floors | PBS floors data | object | no | -| imp.ext.prebid.adunitcode | Prebid.js adunit code | string | yes | +| ext.prebid.returnallbidstatus | If true, PBS returns [ext.seatnonbid](#seat-non-bid) with details about bidders that didn't bid. | boolean | no | | imp.ext.ae | If 1, signals bid adapters that Fledge auction config is accepted on the response. (ae stands for auction environment) | integer | yes | | app.ext.prebid.source | The client that created this ORTB. Normally "prebid-mobile" | string | yes | | app.ext.prebid.version | The version of the client that created this ORTB. e.g. "1.1" | string | yes | @@ -1569,6 +1688,7 @@ The Prebid SDK version comes from: | ext.errors.BIDDER | Debug Mode: errors from the named bidder | object | | ext.responsetimemillisv.BIDDER | Debug Mode: how long the named bidder took to respond with a bid. | integer | | ext.prebid.passthrough | Copy of request ext.prebid.passthrough, see [passthrough](#request-passthrough). | object| +| ext.seatnonbid | Details on which bidders did not bid on each imp. See [seatnonbid]()#seat-non-bid| object| | ext.prebid.fledge.auctionconfigs | Bidder-supplied [Fledge](https://github.com/google/ads-privacy/tree/master/proposals/fledge-multiple-seller-testing) responses. | array of objects | ### Further Reading From ef6bb161a3cfb38fba4cfd2405c7b72d838d642a Mon Sep 17 00:00:00 2001 From: nouchy <33549554+nouchy@users.noreply.github.com> Date: Mon, 13 Feb 2023 20:36:10 +0100 Subject: [PATCH 032/762] Seller Defined Audience Support for Sirdata RTD Module (#4293) * Create sirdataRtdProvider.md New Sirdata RTD Segmentation Module documentation * Update cmp-best-practices.md Added guidelines for Sirdata CMP * Update sirdataRtdProvider.html Add information for Seller Defined Audience * Update sirdataRtdProvider.md (Module Name) --- dev-docs/modules/sirdataRtdProvider.md | 68 +++++++++++++++++++++----- 1 file changed, 55 insertions(+), 13 deletions(-) diff --git a/dev-docs/modules/sirdataRtdProvider.md b/dev-docs/modules/sirdataRtdProvider.md index 68a07237..0be81718 100644 --- a/dev-docs/modules/sirdataRtdProvider.md +++ b/dev-docs/modules/sirdataRtdProvider.md @@ -7,11 +7,7 @@ page_type: module module_type: rtd module_code : sirdataRtdProvider enable_download : true -vendor_specific: true -sidebarType : 1 ---- - -# Sirdata RTD Segmentation Module +# Sirdata RTD/SDA Module {:.no_toc} * TOC @@ -27,6 +23,8 @@ User's country and choice management are included in the module, so it's 100% co ORTB2 compliant and FPD support for Prebid versions < 4.29 +Now supports Seller Defined Audience ! + Please contact prebid@sirdata.com for more information. ## Publisher Usage @@ -93,6 +91,10 @@ pbjs.setConfig( bidder: 'ix', sizeLimit: 1200 //specific to Index Exchange, contextualMinRelevancyScore: 50, //Min score to filter contextual category for curation in the bidder (0-100 scale) + },{ + bidder: 'smartadserver' + },{ + bidder: 'proxistore' }] } } @@ -135,14 +137,54 @@ Please see the following example, which provides a function to modify bids for a ``` data Object format for usage in this kind of function : { - "segments":[111111,222222], - "contextual_categories":{"333333":100}, - "shared_taxonomy":{ - "27446":{ //CurationId - "segments":[444444,555555], - "contextual_categories":{"666666":100} - } - } + "segments": [ + 111111, + 222222 + ], + "segtaxid": null, + "cattaxid": null, + "contextual_categories": { + "333333": 100 + }, + "shared_taxonomy": { + "27440": { + "segments": [ + 444444, + 555555 + ], + "segtaxid": 552, + "cattaxid": 553, + "contextual_categories": { + "666666": 100 + } + } + }, + "global_taxonomy": { + "9998": { + "segments": [ + 123, + 234 + ], + "segtaxid": 4, + "cattaxid": 7, + "contextual_categories": { + "345": 100, + "456": 100 + } + }, + "9999": { + "segments": [ + 12345, + 23456 + ], + "segtaxid": 550, + "cattaxid": 551, + "contextual_categories": { + "34567": 100, + "45678": 100 + } + } + } } ``` From 5cfff1b956b8d4c254e47b8ae514ea9742e23bc1 Mon Sep 17 00:00:00 2001 From: Alexander Pykhteyev Date: Tue, 14 Feb 2023 02:37:27 +0700 Subject: [PATCH 033/762] Add custom targeting fields, rename iionads title to iion (#4288) Co-authored-by: apykhteyev --- dev-docs/bidders/iionads.md | 9 +++++++-- dev-docs/bidders/limelightDigital.md | 5 +++++ 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/dev-docs/bidders/iionads.md b/dev-docs/bidders/iionads.md index 162d0d8c..06d40284 100644 --- a/dev-docs/bidders/iionads.md +++ b/dev-docs/bidders/iionads.md @@ -1,7 +1,7 @@ --- layout: bidder -title: iionads -description: iionads Bidder Adaptor +title: Iion +description: Iion Bidder Adaptor biddercode: iionads pbjs: true pbs: false @@ -30,3 +30,8 @@ sidebarType: 1 | `adUnitId` | required | Ad Unit Id will be generated on iionads Platform. | 0 | `integer` | | `adUnitType` | required | Type of Ad Unit (`'video'`, `'banner'`) | `'banner'` | `string` | | `publisherId` | optional | Publisher ID | `'12345'` | `string` | +| `custom1` | optional | Custom targeting field 1 | `'custom1'` | `string` | +| `custom2` | optional | Custom targeting field 2 | `'custom2'` | `string` | +| `custom3` | optional | Custom targeting field 3 | `'custom3'` | `string` | +| `custom4` | optional | Custom targeting field 4 | `'custom4'` | `string` | +| `custom5` | optional | Custom targeting field 5 | `'custom5'` | `string` | diff --git a/dev-docs/bidders/limelightDigital.md b/dev-docs/bidders/limelightDigital.md index 4e48d48d..3dac7f69 100644 --- a/dev-docs/bidders/limelightDigital.md +++ b/dev-docs/bidders/limelightDigital.md @@ -29,3 +29,8 @@ sidebarType: 1 | `adUnitId` | required | Ad Unit Id will be generated on Limelight Digital Platform. | 0 | `integer` | | `adUnitType` | required | Type of Ad Unit (`'video'`, `'banner'`) | `'banner'` | `string` | | `publisherId` | optional | Publisher ID | `'12345'` | `string` | +| `custom1` | optional | Custom targeting field 1 | `'custom1'` | `string` | +| `custom2` | optional | Custom targeting field 2 | `'custom2'` | `string` | +| `custom3` | optional | Custom targeting field 3 | `'custom3'` | `string` | +| `custom4` | optional | Custom targeting field 4 | `'custom4'` | `string` | +| `custom5` | optional | Custom targeting field 5 | `'custom5'` | `string` | From 755666e0714bf675cdfa300ae55739cdde41c9f3 Mon Sep 17 00:00:00 2001 From: jsnellbaker <31102355+jsnellbaker@users.noreply.github.com> Date: Mon, 13 Feb 2023 14:42:49 -0500 Subject: [PATCH 034/762] appnexus bid params - underscore format update (#4336) * appnexus bid params - underscore format update * typo --------- Co-authored-by: Chris Huie --- dev-docs/bidders/appnexus.md | 27 ++++++++++++++++----------- 1 file changed, 16 insertions(+), 11 deletions(-) diff --git a/dev-docs/bidders/appnexus.md b/dev-docs/bidders/appnexus.md index b3571cfe..17d048b8 100644 --- a/dev-docs/bidders/appnexus.md +++ b/dev-docs/bidders/appnexus.md @@ -49,27 +49,32 @@ All AppNexus (Xandr) placements included in a single call to `requestBids` must #### Bid Params +{: .alert.alert-danger :} +Starting with Prebid.js version 7.36.0, an update was made to the `appnexusBidAdapter.js` file to support bid params in a lower-case underscore format (eg `invCode` to `inv_code`) similar to how the params are formatted for the Prebid Server AppNexus bidder. This change was implemented to streamline publisher setups for both projects instead of maintaining separate versions of the same params depending on what setup is used. +To avoid breaking changes, the old 'camelCase' format is still currently supported for all AppNexus bid params in the `appnexusBidAdapter.js` file. If you are using an older version of Prebid.js, you will need to continue to use the older 'camelCase' format as appropriate. +The table below will reflect both formats, though it's recommended to use the lower-case underscore format where possible going forward (assuming you're using a compatible version of Prebid.js). + {: .table .table-bordered .table-striped } | Name | Scope | Description | Example | Type | |---------------------|----------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|-------------------------------------------------------|------------------| -| `placement_id` (PBS) or `placementId` (PBJS) | required | The placement ID from AppNexus. You may identify a placement using the `invCode` and `member` instead of a placement ID. This parameter can be either a `string` or `integer` for Prebid.js, however `integer` is preferred. Legacy code can retain the `string` value. **Prebid Server requires an integer value.** | `234234` | `integer` | +| `placement_id` (PBS+PBJS) or `placementId` (PBJS) | required | The placement ID from AppNexus. You may identify a placement using the `invCode` and `member` instead of a placement ID. This parameter can be either a `string` or `integer` for Prebid.js, however `integer` is preferred. Legacy code can retain the `string` value. **Prebid Server requires an integer value.** | `234234` | `integer` | | `member` | optional | The member ID from AppNexus. Must be used with `invCode`. | `'12345'` | `string` | -| `invCode` | optional | The inventory code from AppNexus. Must be used with `member`. | `'abc123'` | `string` | -| `publisherId` | optional | The publisher ID from AppNexus. It is used by the AppNexus end point to identify the publisher when placement id is not provided and `invCode` goes wrong. The `publisherId` parameter can be either a `string` or `integer` for Prebid.js, however `integer` is preferred. | `12345` | `integer` | +| `invCode` or `inv_code` | optional | The inventory code from AppNexus. Must be used with `member`. | `'abc123'` | `string` | +| `publisherId` or `publisher_id` | optional | The publisher ID from AppNexus. It is used by the AppNexus end point to identify the publisher when placement id is not provided and `invCode` goes wrong. The `publisherId` parameter can be either a `string` or `integer` for Prebid.js, however `integer` is preferred. | `12345` | `integer` | | `frameworks` | optional | Array of integers listing API frameworks for Banner supported by the publisher. | `integer` | | `user` | optional | Object that specifies information about an external user. See [User Object](#appnexus-user-object) for details. | `user: { age: 25, gender: 0, dnt: true}` | `object` | -| `allowSmallerSizes` | optional | If `true`, ads smaller than the values in your ad unit's `sizes` array will be allowed to serve. Defaults to `false`. | `true` | `boolean` | -| `usePaymentRule` (PBJS) or `use_pmt_rule` (PBS) | optional | If `true`, Appnexus will return net price to Prebid.js after publisher payment rules have been applied. | `true` | `boolean` | +| `allowSmallerSizes` or `allow_smaller_sizes` | optional | If `true`, ads smaller than the values in your ad unit's `sizes` array will be allowed to serve. Defaults to `false`. | `true` | `boolean` | +| `usePaymentRule` (PBJS) or `use_pmt_rule` (PBS+PBJS) | optional | If `true`, Appnexus will return net price to Prebid.js after publisher payment rules have been applied. | `true` | `boolean` | | `keywords` | optional | A set of key-value pairs applied to all ad slots on the page. Mapped to [buy-side segment targeting](https://monetize.xandr.com/docs/segment-targeting) (login required). A maximum of 100 key/value pairs can be defined at the page level. Each tag can have up to 100 additional key/value pairs defined. Values can be empty. See [Passing Keys Without Values](#appnexus-no-value) below for examples. If you want to pass keywords for all adUnits, see [Auction Level Keywords](#appnexus-auction-keywords) for an example. Note that to use keyword with the Prebid Server adapter, that feature must be enabled for your account by an AppNexus account manager. | `keywords: { genre: ['rock', 'pop'] }` | `object` | | `video` | optional | Object containing video targeting parameters. See [Video Object](#appnexus-video-object) for details. | `video: { playback_method: ['auto_play_sound_off'] }` | `object` | | `app` | optional | Object containing mobile app parameters. See the [App Object](#appnexus-app-object) for details. | `app : { id: 'app-id'}` | `object` | | `reserve` | optional | Sets a floor price for the bid that is returned. If floors have been configured in the AppNexus Console, those settings will override what is configured here unless 'Reserve Price Override' is checked. See [Xandr docs](https://docs.xandr.com/bundle/monetize_monetize-standard/page/topics/create-a-floor-rule.html) | `0.90` | `float` | | `position` | optional | Identify the placement as above or below the fold. Allowed values: Unknown: `unknown`; Above the fold: `above`; Below the fold: `below` | `'above'` | `string` | -| `trafficSourceCode` | optional | Specifies the third-party source of this impression. | `'my_traffic_source'` | `string` | -| `supplyType` | optional | Indicates the type of supply for this placement. Possible values are `web`, `mobile_web`, `mobile_app` | `'web'` | `string` | -| `pubClick` | optional | Specifies a publisher-supplied URL for third-party click tracking. This is just a placeholder into which the publisher can insert their own click tracker. This parameter should be used for an unencoded tracker. This parameter is expected to be the last parameter in the URL. Please note that the click tracker placed in this parameter will only fire if the creative winning the auction is using AppNexus click tracking properly. | `'http://click.adserver.com/'` | `string` | -| `extInvCode` | optional | Specifies predefined value passed on the query string that can be used in reporting. The value must be entered into the system before it is logged. | `'10039'` | `string` | -| `externalImpId` | optional | Specifies the unique identifier of an externally generated auction. | `'bacbab02626452b097f6030b3c89ac05'` | `string` | +| `trafficSourceCode` or `traffic_source_code` | optional | Specifies the third-party source of this impression. | `'my_traffic_source'` | `string` | +| `supplyType` or `supply_type` | optional | Indicates the type of supply for this placement. Possible values are `web`, `mobile_web`, `mobile_app` | `'web'` | `string` | +| `pubClick` or `pub_click` | optional | Specifies a publisher-supplied URL for third-party click tracking. This is just a placeholder into which the publisher can insert their own click tracker. This parameter should be used for an unencoded tracker. This parameter is expected to be the last parameter in the URL. Please note that the click tracker placed in this parameter will only fire if the creative winning the auction is using AppNexus click tracking properly. | `'http://click.adserver.com/'` | `string` | +| `extInvCode` or `ext_inv_code` | optional | Specifies predefined value passed on the query string that can be used in reporting. The value must be entered into the system before it is logged. | `'10039'` | `string` | +| `externalImpId` or `external_imp_id` | optional | Specifies the unique identifier of an externally generated auction. | `'bacbab02626452b097f6030b3c89ac05'` | `string` | | `generate_ad_pod_id` | optional | Signal to AppNexus to split impressions by ad pod and add unique ad pod id to each request. Specific to long form video endpoint only. Supported by Prebid Server, not Prebid JS. | `true` | `boolean` |
@@ -96,7 +101,7 @@ All AppNexus (Xandr) placements included in a single call to `requestBids` must | Name | Description | Example | Type | |-------------------|---------------------------------------------------------------------------------------------------------------------------------|--------------------------------------------------------------------------|------------------| | `age` | The age of the user. | `35` | `integer` | -| `externalUid` | Specifies a string that corresponds to an external user ID for this user. | `'1234567890abcdefg'` | `string` | +| `externalUid` or `external_uid` | Specifies a string that corresponds to an external user ID for this user. | `'1234567890abcdefg'` | `string` | | `segments` | Specifies the segments to which the user belongs. | `[1, 2]` | `Array` | | `gender` | Specifies the gender of the user. Allowed values: Unknown: `0`; Male: `1`; Female: `2` | `1` | `integer` | | `dnt` | Do not track flag. Indicates if tracking cookies should be disabled for this auction | `true` | `boolean` | From 15c50526f2243363fd39efe7c9a9b1f010e6e00c Mon Sep 17 00:00:00 2001 From: dalmenarDevST <116064809+dalmenarDevST@users.noreply.github.com> Date: Mon, 13 Feb 2023 20:43:51 +0100 Subject: [PATCH 035/762] [SeedTag] add gpp support (#4271) --- dev-docs/bidders/seedtag.md | 1 + 1 file changed, 1 insertion(+) diff --git a/dev-docs/bidders/seedtag.md b/dev-docs/bidders/seedtag.md index 6364c998..df8c0477 100644 --- a/dev-docs/bidders/seedtag.md +++ b/dev-docs/bidders/seedtag.md @@ -12,6 +12,7 @@ media_types: banner, video biddercode: seedtag coppa_supported: true sidebarType: 1 +gpp_supported: true --- ### Note From 7c62fbe7a8e0145a64ca67b7638d34bec66fe66a Mon Sep 17 00:00:00 2001 From: Gino <53079123+Skylinar@users.noreply.github.com> Date: Mon, 13 Feb 2023 20:44:42 +0100 Subject: [PATCH 036/762] smartx Bid Adapter: add support for sitekey (#4265) * initial commit * adjustments * adjustments * adjustments * typo, further adjustments * removed userIds and schain support * Added optionals to outstream and made formatting * Update smartx.md minor edits for clarification and readability. * adjusted outstream_options * remove outstream_function, added pbjs_version_notes * bugfix outstream options for default outstream renderer configuration * refactor descriptions and adding "visibilityThreshold" * Add schain support * add support for sitekey to smartxBidAdapter --------- Co-authored-by: Gino Co-authored-by: Jean Stemp <38964447+jeanstemp@users.noreply.github.com> Co-authored-by: smartclip-adtech <65160328+smartclip-adtech@users.noreply.github.com> --- dev-docs/bidders/smartx.md | 1 + 1 file changed, 1 insertion(+) diff --git a/dev-docs/bidders/smartx.md b/dev-docs/bidders/smartx.md index a2d978ed..678ae6cd 100644 --- a/dev-docs/bidders/smartx.md +++ b/dev-docs/bidders/smartx.md @@ -35,6 +35,7 @@ Please reach out to your smartclip business contact for any questions and assist | `price_floor` | optional | Set the current channel price floor in real time. | `10` | `integer` | | `min_duration` | optional | Minimum video ad duration in seconds | `15` | `integer` | | `max_duration` | optional | Maximum video ad duration in seconds | `60` | `integer` | +| `sitekey` | optional | Sitekey provided by smartclip. | `'foo.bar.baz'` | `string` | From 9319f685f0415f09404b881bb143909d51dac1dc Mon Sep 17 00:00:00 2001 From: "Adserver.Online" <61009237+adserver-online@users.noreply.github.com> Date: Mon, 13 Feb 2023 21:50:55 +0200 Subject: [PATCH 037/762] Aso Bid Adapter: add bcmint alias (#4245) Co-authored-by: dev --- dev-docs/bidders/bcmint.md | 42 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 42 insertions(+) create mode 100644 dev-docs/bidders/bcmint.md diff --git a/dev-docs/bidders/bcmint.md b/dev-docs/bidders/bcmint.md new file mode 100644 index 00000000..7ee2d1dc --- /dev/null +++ b/dev-docs/bidders/bcmint.md @@ -0,0 +1,42 @@ +--- +layout: bidder +title: BCM International +description: BCM International Bid Adapter +biddercode: bcmint +gdpr_supported: true +usp_supported: true +media_types: video +safeframes_ok: true +deals_supported: false +pbjs: true +pbs: false +floors_supported: true +schain_supported: true +multiformat_supported: will-bid-on-one +userIds: all +sidebarType: 1 +--- +### Note: + +The BCM International adapter requires approval and setup. Please reach out to contact@bcm.ltd or visit us at [bcm.ltd](https://bcm.ltd) for more details. + +### Bid Params + +{: .table .table-bordered .table-striped } +| Name | Scope | Description | Example | Type | +|---------------|----------|------------------|-----------------------------|-----------| +| `server` | required | Server endpoint | `https://srv.datacygnal.io` | `String` | +| `zone` | required | Zone ID | `73815` | `Integer` | + +#### Video Caching + +Note that the BCM International adapter expects a client-side Prebid Cache to be enabled for video bidding. + +```js +pbjs.setConfig({ + usePrebidCache: true, + cache: { + url: 'https://prebid.adnxs.com/pbc/v1/cache' + } +}); +``` From 1385fca94d901fe168200559d03a7e79f4de02eb Mon Sep 17 00:00:00 2001 From: Denis Logachov Date: Mon, 13 Feb 2023 21:56:26 +0200 Subject: [PATCH 038/762] Create bidbuddy.md (#4234) --- dev-docs/bidders/bidbuddy.md | 34 ++++++++++++++++++++++++++++++++++ 1 file changed, 34 insertions(+) create mode 100644 dev-docs/bidders/bidbuddy.md diff --git a/dev-docs/bidders/bidbuddy.md b/dev-docs/bidders/bidbuddy.md new file mode 100644 index 00000000..1f06e216 --- /dev/null +++ b/dev-docs/bidders/bidbuddy.md @@ -0,0 +1,34 @@ +--- +layout: bidder +title: Bidbuddy +description: Bidbuddy Bidder Adaptor +biddercode: bidbuddy +pbjs: true +pbs: false +media_types: banner, native, video +gdpr_supported: true +usp_supported: true +coppa_supported: true +pbs_app_supported: true +schain_supported: true +userIds: all +fpd_supported: true +prebid_member: false +ortb_blocking_supported: true +multiformat_supported: will-bid-on-one +floors_supported: true +aliasCode: adkernel +sidebarType: 1 +--- + +### Note: + +The Bidbuddy bidding adapter requires setup and approval before implementation. Please reach out to for more details. + +### Bid Params + +{: .table .table-bordered .table-striped } +| Name | Scope | Description | Example | Type | +|----------|----------|-----------------------|---------------------------|----------| +| `host` | required | RTB host | `'cpm.bidbuddy.co.in'` | `string` | +| `zoneId` | required | Zone Id | 30164 | `integer` | From 32e4197b53150430462471f6461fb6937eb5ab31 Mon Sep 17 00:00:00 2001 From: Tomasz Kogut Date: Mon, 13 Feb 2023 21:01:03 +0100 Subject: [PATCH 039/762] Add docs for Scattered bid adapter (#4181) * Add docs for Scattered bid adaptor * Add info about gvl_id --- dev-docs/bidders/scattered.md | 49 +++++++++++++++++++++++++++++++++++ 1 file changed, 49 insertions(+) create mode 100644 dev-docs/bidders/scattered.md diff --git a/dev-docs/bidders/scattered.md b/dev-docs/bidders/scattered.md new file mode 100644 index 00000000..657b532c --- /dev/null +++ b/dev-docs/bidders/scattered.md @@ -0,0 +1,49 @@ +--- +layout: bidder +title: Scattered +description: Scattered Prebid Bidder Adaptor +biddercode: scattered +media_types: banner +coppa_supported: false +gdpr_supported: true +usp_supported: false +prebid_member: false +pbjs: true +pbs: false +schain_supported: false +userIds: none +gvl_id: 1179 +floors_supported: false +fpd_supported: false +deals_supported: false +multiformat_supported: will-bid-on-one +ortb_blocking_supported: false +safeframes_ok: false +sidebarType: 1 +--- + +### Bid params + +{: .table .table-bordered .table-striped } +| Name | Scope | Description | Example | Type | +| -------------- | -------- | ------------- | --------------- | --------- | +| `bidderDomain` | required | Bidder domain | `"Leaderboard"` | `string` | +| `test` | optional | Is test bid | 0 | `integer` | + + +### OpenRTB request config + +OpenRTB bid request `app`, `site`, `device` properties configured using prebid config. + +``` javascript +pbjs.setConfig({ + ortb2: { + site: { + id: '876', + publisher: { + domain: 'publisher1.eu' + } + } + } +}); +``` From ade272bf5ac304cf8db2c6274f2b4ef906d44a30 Mon Sep 17 00:00:00 2001 From: Andrea Tumbarello Date: Mon, 13 Feb 2023 21:13:10 +0100 Subject: [PATCH 040/762] AIDEM Bidder Adapter: Updated Banner/Video AdUnit examples and GDPR TCF Support feature (#4280) * AIDEM Bid Adapter dev-docs * title to uppercase * Added publisherId as required bidder param * Header levels pushed down by 1 * added "sidebarType: 1" to header data * Added placementId * fixed tables layout * Updated Banner/Video AdUnit examples and GDPR TCF Support feature * placementId is now a required parameter added optional rateLimit parameter * Restored placementId in an optional parameter --------- Co-authored-by: Giovanni Sollazzo Co-authored-by: darkstar Co-authored-by: AndreaC <67786179+darkstarac@users.noreply.github.com> --- dev-docs/bidders/aidem.md | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/dev-docs/bidders/aidem.md b/dev-docs/bidders/aidem.md index 346e929e..736af07e 100644 --- a/dev-docs/bidders/aidem.md +++ b/dev-docs/bidders/aidem.md @@ -3,7 +3,7 @@ layout: bidder title: AIDEM description: AIDEM Bidder Adapter biddercode: aidem -gdpr_supported: false +gdpr_supported: true gvl_id: none usp_supported: true coppa_supported: false @@ -36,6 +36,7 @@ This module is GDPR and CCPA compliant, and no 3rd party userIds are allowed. | `siteId` | required | Unique site ID | `'ABCDEF'` | `String` | | `publisherId` | required | Unique publisher ID | `'FEDCBA'` | `String` | | `placementId` | optional | Unique publisher tag ID | `'ABCDEF'` | `String` | +| `rateLimit` | optional | Limit the volume sent to AIDEM. Must be between 0 and 1 | `0.6` | `Number` | #### Banner Bid Params @@ -91,7 +92,8 @@ var adUnits = [{ bids: [{ bidder: 'aidem', params: { - siteId: 'prebid-test-site', + siteId: 'prebid-test-siteId', + publisherId: 'prebid-test-publisherId', }, }] }]; @@ -114,7 +116,8 @@ var adUnits = [{ bids: [{ bidder: 'aidem', params: { - siteId: 'prebid-test-site', + siteId: 'prebid-test-siteId', + publisherId: 'prebid-test-publisherId', }, }] }]; From 5a7e6519d1f1cb80b7376162be1d33cb1413ef59 Mon Sep 17 00:00:00 2001 From: Alexandru Date: Mon, 13 Feb 2023 22:20:28 +0200 Subject: [PATCH 041/762] BrightcomSSP bid adapter: add new bidder page (#4267) * BrightcomSSP: add new bidder page * BrightcomSSP: update title to correct one --- dev-docs/bidders/brightcomssp.md | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) create mode 100644 dev-docs/bidders/brightcomssp.md diff --git a/dev-docs/bidders/brightcomssp.md b/dev-docs/bidders/brightcomssp.md new file mode 100644 index 00000000..9c5b76df --- /dev/null +++ b/dev-docs/bidders/brightcomssp.md @@ -0,0 +1,28 @@ +--- +layout: bidder +title: Brightcom SSP +description: Prebid Brightcom SSP Bidder Adaptor +top_nav_section: dev_docs +nav_section: reference +pbjs: true +biddercode: bcmssp +gdpr_supported: true +usp_supported: true +coppa_supported: true +schain_supported: true +sidebarType: 1 +gvl_id: 883 +--- + +### Note: + +The Brightcom SSP bidder adapter requires setup and approval from the Brightcom team. Please reach out to your account manager for more information and to start using it. + +### Bid params + +{: .table .table-bordered .table-striped } + +| Name | Scope | Description | Example | Type | +| ---- | ----- | ----------- | ------- | ---- | +| `publisherId` | required | The publisher ID from Brightcom | `2141020` | `integer` | +| `bidFloor` | optional | The minimum bid value desired | `1.23` | `float` | From 318581c8c7300fe6af5a099a14d45a1abd3a6433 Mon Sep 17 00:00:00 2001 From: moquity <33487117+moquity@users.noreply.github.com> Date: Mon, 13 Feb 2023 23:07:42 +0200 Subject: [PATCH 042/762] Feature/neuwo rtd provider (#4244) * NeuwoRtdProvider dev-docs for website, pt.1 * feature/neuwoRTDProvider: when in rome, ... * feature/neuwoRTDProvider: fix file capitalization, check field values --- dev-docs/modules/neuwoRtdProvider.md | 48 ++++++++++++++++++++++++++++ 1 file changed, 48 insertions(+) create mode 100644 dev-docs/modules/neuwoRtdProvider.md diff --git a/dev-docs/modules/neuwoRtdProvider.md b/dev-docs/modules/neuwoRtdProvider.md new file mode 100644 index 00000000..402bf289 --- /dev/null +++ b/dev-docs/modules/neuwoRtdProvider.md @@ -0,0 +1,48 @@ +--- +layout: page_v2 +title: Neuwo Real-Time Data Module +display_name: Neuwo Real-Time Data Module +description: Enrich bids using neuwo.ai +page_type: module +module_type: rtd +module_code : neuwoRtdProvider +enable_download : true +sidebarType : 1 +--- + +# Neuwo Real-Time Data Module + +## Overview +Neuwo Real-Time Data Module allows you to enrich bids using neuwo.ai for content taxonomy. + +## Configuration + +| Name | Scope | Description | Example | Type | +|------------|----------|----------------------------------------|---------------|----------| +| `name` | required | Handle of the module used in real-time data providers; for this, use 'NeuwoRTDModule' | 'NeuwoRTDModule' | static | +| `params.publicToken` | required | Your neuwo.ai public token | `neu23-te45-idkf-44aa` | `string` | + +```javascript + +const neuwoDataProvider = { + name: 'NeuwoRTDModule', + params: { + publicToken: '' + } +} +pbjs.setConfig({realTimeData: { dataProviders: [ neuwoDataProvider ]}}) + +``` + +## Installation + +### Step 1: Install Prebid.js + +- Option 1: Use Prebid [Download](/download.html) page to build the Prebid.js package + - Include Neuwo Real-Time Data Module + +- Option 2: Include `neuwoRtdProvider` in build: `gulp build --modules=rtdModule,neuwoRtdProvider,...` + +### Step 2: Set configuration + +Enable Neuwo Real-Time Data Module using `pbjs.setConfig` in a related Javascript context. Command example is provided in Configuration section. \ No newline at end of file From 8c8bf1590d83f77c9fac26d7a291a8039e395926 Mon Sep 17 00:00:00 2001 From: WlsLogan <77974248+WlsLogan@users.noreply.github.com> Date: Tue, 14 Feb 2023 11:51:42 +0200 Subject: [PATCH 043/762] Logan Bid Adapter: updating removed adapter (#4238) * add docs * Update logan.md * fix * updates --------- Co-authored-by: Aiholkin --- dev-docs/bidders/logan.md | 1 + 1 file changed, 1 insertion(+) diff --git a/dev-docs/bidders/logan.md b/dev-docs/bidders/logan.md index 83698525..dabd33ac 100644 --- a/dev-docs/bidders/logan.md +++ b/dev-docs/bidders/logan.md @@ -8,6 +8,7 @@ schain_supported: true media_types: banner, video, native gdpr: true pbjs: true +pbs: true sidebarType: 1 --- From de9c2ae78f6f51ebf34f0812313ceb1deba089e2 Mon Sep 17 00:00:00 2001 From: Mark Kuhar Date: Tue, 14 Feb 2023 11:17:49 +0100 Subject: [PATCH 044/762] added video example (#4263) --- dev-docs/bidders/outbrain.md | 40 +++++++++++++++++++++++++++++++++++- 1 file changed, 39 insertions(+), 1 deletion(-) diff --git a/dev-docs/bidders/outbrain.md b/dev-docs/bidders/outbrain.md index 8ddb8354..3adaf10b 100644 --- a/dev-docs/bidders/outbrain.md +++ b/dev-docs/bidders/outbrain.md @@ -7,7 +7,7 @@ gdpr_supported: true gvl_id: 164 usp_supported: true coppa_supported: true -media_types: banner, native +media_types: banner, native, video safeframes_ok: true pbjs: true pbs: true @@ -165,3 +165,41 @@ var adUnits = [ }] ]; ``` + +#### Video example +``` +var adUnits = [ + code: '/19968336/prebid_video_example_1', + mediaTypes: { + video: { + context: "outstream", + playerSize: [[640, 480]], + mimes: ['video/mp4'], + protocols: [1, 2, 3, 4, 5, 6, 7, 8], + playbackmethod: [1], + skip: 1, + api: [2], + minbitrate: 1000, + maxbitrate: 3000, + minduration: 3, + maxduration: 10, + startdelay: 2, + placement: 4, + linearity: 1 + }, + }, + bids: [{ + bidder: 'outbrain', + params: { + publisher: { + id: '2706', + name: 'Publishers Name', + domain: 'publisher.com' + }, + tagid: 'tag-id', + bcat: ['IAB1-1'], + badv: ['example.com'] + } + }] +]; +``` From 6233b2a30fbe3e1256a3b28a4d3c83fc4d00e5aa Mon Sep 17 00:00:00 2001 From: Espen <2290914+espen-j@users.noreply.github.com> Date: Tue, 14 Feb 2023 11:55:00 +0100 Subject: [PATCH 045/762] CWire: Introduce prebid server adapter (#4242) * C-Wire: Remove video format * C-Wire: Add prebid-server support (c-wire/prebid#1) * C-Wire: Remove unsupported uid2Id * C-Wire: Update docs (c-wire/prebid#3) * C-Wire: Add debug flag (c-wire/prebid#3) --- dev-docs/bidders/cwire.md | 29 ++++++++++++++++++++--------- 1 file changed, 20 insertions(+), 9 deletions(-) diff --git a/dev-docs/bidders/cwire.md b/dev-docs/bidders/cwire.md index a703e628..2e1e568d 100644 --- a/dev-docs/bidders/cwire.md +++ b/dev-docs/bidders/cwire.md @@ -3,23 +3,34 @@ layout: bidder title: C-WIRE description: C-WIRE Prebid Bidder Adapter pbjs: true +pbs: true biddercode: cwire gdpr_supported: false usp_supported: false schain_supported: false -userIds: uid2Id +userIds: none enable_download: true -media_types: banner, video +media_types: banner sidebarType: 1 --- +--- ### Bid Params {: .table .table-bordered .table-striped } -| Name | Scope | Description | Example | Type | -|---------------|----------|-----------------------|-----------|-----------| -| `pageId` | required | C-WIRE page id | `2453` | `integer` | -| `placementId` | required | C-WIRE placement id | `113244` | `integer` | -| `cwcreative` | required | C-WIRE creative id to force | `42` | `integer` | -| `refgroups` | required | C-WIRE group name to force | `'test-user'` | `string` | -| `cwapikey` | required | C-WIRE API key for integration testing | `'xxx-yyy-some-uuid'` | `string` | +| Name | Scope | Description | Example | Type | +|---------------|:--------:|:-------------------:|:--------:|:---------:| +| `pageId` | required | C-WIRE page id | `2453` | `integer` | +| `placementId` | required | C-WIRE placement id | `113244` | `integer` | + +### URL parameters + +Additionally, the following parameters can be passed by URL parameters for testing. + +{: .table .table-bordered .table-striped } +| Name | Scope | Description | Example | Type | +|--------------|:--------:|:--------------------------------:|:-------------------------------:|:--------:| +| `cwcreative` | optional | C-WIRE creative id to force | `&cwcreative=1234` | `string` | +| `cwgroups` | optional | C-WIRE group name to force | `&cwgroups=test-group` | `string` | +| `cwfeatures` | optional | Comma separated list of features | `&cwfeatures=feature1,feature2` | `string` | +| `cwdebug` | optional | Debug flag | `&cwdebug=true` | `string` | From 0a454e19fff98ca177375ccc5547c51945f8fbc7 Mon Sep 17 00:00:00 2001 From: KiviAds <117356365+KiviAds@users.noreply.github.com> Date: Tue, 14 Feb 2023 13:01:21 +0200 Subject: [PATCH 046/762] New Adapter: Kivi (#4126) * init new adapter * updates * updates * Update kiviads.md Added some header data to make sure the page work correctly with the new navigation. --------- Co-authored-by: Jean Stemp <38964447+jeanstemp@users.noreply.github.com> --- dev-docs/bidders/kiviads.md | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) create mode 100644 dev-docs/bidders/kiviads.md diff --git a/dev-docs/bidders/kiviads.md b/dev-docs/bidders/kiviads.md new file mode 100644 index 00000000..d1c23feb --- /dev/null +++ b/dev-docs/bidders/kiviads.md @@ -0,0 +1,30 @@ +--- +layout: bidder +title: Kivi +description: Prebid Kivi Bidder Adapter +biddercode: kiviads +media_types: banner, video, native +pbjs: false +pbs: true +safeframes_ok: true +floors_supported: true +fpd_supported: false +multiformat_supported: will-not-bid +ortb_blocking_supported: partial +pbs_app_supported: true +gdpr_supported: true +usp_supported: true +coppa_supported: true +deals_supported: false +schain_supported: true +dchain_supported: false +sidebarType: 1 +--- + +### Bid Params + +{: .table .table-bordered .table-striped } +| Name | Scope | Description | Example | Type | +|---------------|----------|-----------------------|-----------|-----------| +| `placementId` | optional | Placement Id | `'0'` | `'string'` | +| `endpointId` | optional | Endpoint Id | `'0'` | `'string'` | From a9ec7ff900840157e1af1fb2258ddf6f9cd464ed Mon Sep 17 00:00:00 2001 From: Soniya Prasad <54229442+SoniyaMG@users.noreply.github.com> Date: Tue, 14 Feb 2023 12:22:49 +0100 Subject: [PATCH 047/762] New Adapter: Definemedia (#4264) * DEFINE MEDIA GmbH Adapter Documentation * Adding markdown document for Define Media adapter --------- Co-authored-by: Dennis Co-authored-by: soniyamg --- dev-docs/bidders/definemedia.md | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) create mode 100644 dev-docs/bidders/definemedia.md diff --git a/dev-docs/bidders/definemedia.md b/dev-docs/bidders/definemedia.md new file mode 100644 index 00000000..51488e6a --- /dev/null +++ b/dev-docs/bidders/definemedia.md @@ -0,0 +1,25 @@ +--- +layout: bidder +title: DEFINE MEDIA +description: Prebid DEFINE MEDIA Bidder Adapter +biddercode: definemedia +gdpr_supported: true +gvl_id: 440 +media_types: banner, native +pbjs: false +pbs: true +pbs_app_supported: false +prebid_member: false +--- + +### Registration + +Please reach out to our account management team to get started. Contact information is available under [a link](https://definemedia.de). + +### Bid Params + +{: .table .table-bordered .table-striped } +| Name | Scope | Description | Example | Type | +|---------------|----------|--------------|-----------|----------| +| `mandantId ` | required | Mandant ID | `5` | `integer`| +| `adslotId` | optional | Adslot ID | `199` | `integer`| \ No newline at end of file From 0955d604b66def7a1ce1eb1c10177592020eae78 Mon Sep 17 00:00:00 2001 From: Sacha <35510349+thebraveio@users.noreply.github.com> Date: Tue, 14 Feb 2023 14:33:22 +0300 Subject: [PATCH 048/762] Added pbs support (#4039) --- dev-docs/bidders/brave.md | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/dev-docs/bidders/brave.md b/dev-docs/bidders/brave.md index 50d1a433..15a75ce4 100644 --- a/dev-docs/bidders/brave.md +++ b/dev-docs/bidders/brave.md @@ -11,7 +11,14 @@ media_types: banner, video, native safeframes_ok: true deals_supported: true pbjs: true -pbs: false +pbs: true +gvl_id: 869 +floors_supported: true +pbs_app_supported: true +fpd_supported: false +dchain_supported: false +deals_supported: true +ortb_blocking_supported: true sidebarType: 1 --- @@ -21,7 +28,6 @@ The Brave Header Bidding adapter requires setup and approval from the Brave team ### Bid Params -{: .table .table-bordered .table-striped } | Name | Scope | Description | Example | Type | |---------------|----------|-------------------------------|-------------------------------------|-----------| | `placementId` | required | Brave's platform placement id | `'to0QI2aPgkbBZq6vgf0oHitouZduz0qw'` | `string` | From 5a25a3f01e702f718b4dd7555c0510ee2773aa19 Mon Sep 17 00:00:00 2001 From: Jose Cabal-Ugaz <6942011+josecu@users.noreply.github.com> Date: Tue, 14 Feb 2023 06:39:52 -0500 Subject: [PATCH 049/762] Fix code example for getBidRequestData in add-rtb-submodule (#4269) --- dev-docs/add-rtd-submodule.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dev-docs/add-rtd-submodule.md b/dev-docs/add-rtd-submodule.md index da83ba96..7ac56b2a 100644 --- a/dev-docs/add-rtd-submodule.md +++ b/dev-docs/add-rtd-submodule.md @@ -211,7 +211,7 @@ at the time `requestBids` is called, and RTD submodules that wish to modify it a export const subModuleObj = { name: 'ExampleRTDModule2', init: init, - setBidRequestsData: alterBidRequests + getBidRequestData: alterBidRequests }; function init(config, userConsent) { From 0fc0eea013bb92cab2115ed654b70c0b553f1c27 Mon Sep 17 00:00:00 2001 From: preved-medved Date: Tue, 14 Feb 2023 11:51:45 +0000 Subject: [PATCH 050/762] Add example how to integrate smartytech bidder (#4305) * Add dev documentation for smartytech adapter * Add exaples for video and banner integration * add description about multiformat support --- dev-docs/bidders/smartytech.md | 45 +++++++++++++++++++++++++++++++++- 1 file changed, 44 insertions(+), 1 deletion(-) diff --git a/dev-docs/bidders/smartytech.md b/dev-docs/bidders/smartytech.md index 78976b40..f0215760 100644 --- a/dev-docs/bidders/smartytech.md +++ b/dev-docs/bidders/smartytech.md @@ -4,7 +4,8 @@ title: SmartyTech description: Prebid SmartyTech Bidder Adaptor pbjs: true biddercode: smartytech -media_types: banner +media_types: banner, video +multiformat_supported: will-bid-on-one sidebarType: 1 --- @@ -14,3 +15,45 @@ sidebarType: 1 | Name | Scope | Description | Example | Type | |--------------|----------|--------------|---------|-----------| | `endpointId` | required | Endpoint ID. | `14` | `integer` | + + +### Sample Banner Ad Unit Example +``` +var adUnits = [{ + code: '/123123123/prebidjs-banner', + mediaTypes: { + banner: { + sizes: [ + [300, 301], + [300, 250] + ] + } + }, + bids: [{ + bidder: 'smartytech', + params: { + endpointId: 14 + } + }] +}]; +``` + +### Sample Video Ad Unit Example +``` +var videoAdUnit = { + code: '/123123123/video-vast-banner', + mediaTypes: { + video: { + context: 'instream', + playerSize: [640, 480], + mimes: ['video/mp4'], + } + }, + bids: [{ + bidder: 'smartytech', + params: { + endpointId: 14 + } + }] +}; +``` From d1457c30f048560e5acb97e359c9a86bd8a23d2d Mon Sep 17 00:00:00 2001 From: ahmadlob <109217988+ahmadlob@users.noreply.github.com> Date: Tue, 14 Feb 2023 14:36:58 +0200 Subject: [PATCH 051/762] Taboola Bid Adapter : support native in prebid server (#4329) * support-native-prebid-server * support-native-prebid-server --- dev-docs/bidders/taboola.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/dev-docs/bidders/taboola.md b/dev-docs/bidders/taboola.md index 056f319e..2cbfdcdc 100644 --- a/dev-docs/bidders/taboola.md +++ b/dev-docs/bidders/taboola.md @@ -25,6 +25,7 @@ sidebarType: 1 ### Note - Supports `display` format. +- Supports `native` format only in the Prebid Sever. - Uses `OpenRTB` standard. ### Registration @@ -105,3 +106,8 @@ Notes: }] }]; ``` + +### Native - Prebid Server Adapter + +Currently, supporting native and multi-format (banner and native mixed) requests in the prebid server adapter only. + From bbc1c5e01cdbd290a7a7327e8a5501ef68591268 Mon Sep 17 00:00:00 2001 From: Muki Seiler Date: Tue, 14 Feb 2023 15:24:35 +0100 Subject: [PATCH 052/762] Document floor support for adapters that have it (#4366) --- dev-docs/bidders/nextroll.md | 1 + dev-docs/bidders/onetag.md | 2 +- dev-docs/bidders/sonobi.md | 1 + 3 files changed, 3 insertions(+), 1 deletion(-) diff --git a/dev-docs/bidders/nextroll.md b/dev-docs/bidders/nextroll.md index 45757fa3..e54a643c 100644 --- a/dev-docs/bidders/nextroll.md +++ b/dev-docs/bidders/nextroll.md @@ -6,6 +6,7 @@ pbjs: true biddercode: nextroll media_types: display, native gdpr_supported: false +floors_supported: true usp_supported: true prebid_member: true sidebarType: 1 diff --git a/dev-docs/bidders/onetag.md b/dev-docs/bidders/onetag.md index 2251a1e4..6d8285da 100644 --- a/dev-docs/bidders/onetag.md +++ b/dev-docs/bidders/onetag.md @@ -12,7 +12,7 @@ gvl_id: 241 usp_supported: true userIds: britepoolId, criteo, id5Id, identityLink, liveIntentId, netId, parrableId, pubCommonId, unifiedId schain_supported: true -getFloor: true +floors_supported: true sidebarType: 1 --- diff --git a/dev-docs/bidders/sonobi.md b/dev-docs/bidders/sonobi.md index 7b3cbd3f..2c23637c 100644 --- a/dev-docs/bidders/sonobi.md +++ b/dev-docs/bidders/sonobi.md @@ -12,6 +12,7 @@ usp_supported: true coppa_supported: true schain_supported: true pbs_app_supported: true +floors_supported: true sidebarType: 1 --- From 54018b552e544a10c33463e065ba013e6de7f967 Mon Sep 17 00:00:00 2001 From: Ho Chia Leung Date: Tue, 14 Feb 2023 15:53:34 +0100 Subject: [PATCH 053/762] Corrected the custom parameters from "pb_hb" to "hb_pb" (#4334) * Update huaweiads.md add gdpr and coppa support * no message * Update pbs-database.md replaced `%RESPONSE_ID_LIST%` with `%ID_LIST%` * Update huaweiads.md * parameter is different between Go and Java * changed the custom parameters from "pb_hb" to "hb_pb" * attach adView to the view group --------- Co-authored-by: Ho Chia Leung Co-authored-by: bretg --- .../modules/rendering/max-ad-unit-setup.png | Bin 228464 -> 30139 bytes .../rendering/android-sdk-integration-max.md | 1 + 2 files changed, 1 insertion(+) diff --git a/assets/images/prebid-mobile/modules/rendering/max-ad-unit-setup.png b/assets/images/prebid-mobile/modules/rendering/max-ad-unit-setup.png index 36510051478ddd136a1513a98ee4f1a172360630..c8976389f03c6e24e1ef4e646c985d8ed87b0570 100644 GIT binary patch literal 30139 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

gs$|&RPaL^b%j-j{&yAyffzn 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�d_2z72_ITxGw79X$zSqB_xsKTc2Sy>JonDbfSlh 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 LaIEx*cl`eVRwg33 diff --git a/prebid-mobile/modules/rendering/android-sdk-integration-max.md b/prebid-mobile/modules/rendering/android-sdk-integration-max.md index 0c45d656..dbda51a5 100644 --- a/prebid-mobile/modules/rendering/android-sdk-integration-max.md +++ b/prebid-mobile/modules/rendering/android-sdk-integration-max.md @@ -58,6 +58,7 @@ Integration example: // 1. Create MaxAdView adView = MaxAdView(adUnitId, requireContext()) adView?.setListener(createListener()) +adWrapperView.addView(adView) // 2. Create MaxMediationBannerUtils val mediationUtils = MaxMediationBannerUtils(adView) From 59334546fdc2f136e98bd32e79e1ae560e8d396b Mon Sep 17 00:00:00 2001 From: nouchy <33549554+nouchy@users.noreply.github.com> Date: Wed, 15 Feb 2023 14:14:25 +0100 Subject: [PATCH 054/762] Broken page header (#4368) Broken page header fix --- dev-docs/modules/sirdataRtdProvider.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/dev-docs/modules/sirdataRtdProvider.md b/dev-docs/modules/sirdataRtdProvider.md index 0be81718..10e1d134 100644 --- a/dev-docs/modules/sirdataRtdProvider.md +++ b/dev-docs/modules/sirdataRtdProvider.md @@ -7,6 +7,10 @@ page_type: module module_type: rtd module_code : sirdataRtdProvider enable_download : true +vendor_specific: true +sidebarType : 1 +--- + # Sirdata RTD/SDA Module {:.no_toc} From ffdec11a9a7fef030ce877f4321429c9ee506ccd Mon Sep 17 00:00:00 2001 From: bretg Date: Wed, 15 Feb 2023 13:35:58 -0500 Subject: [PATCH 055/762] updating onetrust cookie banner (#4369) --- _includes/head--common.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/_includes/head--common.html b/_includes/head--common.html index 04ec6bbc..1d827321 100644 --- a/_includes/head--common.html +++ b/_includes/head--common.html @@ -16,7 +16,7 @@ {% if jekyll.environment == "production" %} - + From 566fa23672c193543e60f4f63787922424785f4e Mon Sep 17 00:00:00 2001 From: Yuriy Velichko Date: Thu, 16 Feb 2023 17:50:53 +0200 Subject: [PATCH 056/762] Mobile add test ad unit configs (#4373) * prepare the tables with description of test configs * add note --- .../android/code-integration-android.md | 22 ++++++++++++++++ .../pbm-api/ios/code-integration-ios.md | 25 +++++++++++++++++++ 2 files changed, 47 insertions(+) diff --git a/prebid-mobile/pbm-api/android/code-integration-android.md b/prebid-mobile/pbm-api/android/code-integration-android.md index 17679958..63c19f75 100644 --- a/prebid-mobile/pbm-api/android/code-integration-android.md +++ b/prebid-mobile/pbm-api/android/code-integration-android.md @@ -278,3 +278,25 @@ Follow the corresponding guide to integrate Prebid Mobile: - [GAM using Rendering API](../../modules/rendering/android-sdk-integration-gam.html) - [AdMob](../../modules/rendering/android-sdk-integration-admob) - [AppLovin MAX](../../modules/rendering/android-sdk-integration-max.html) + +### Test configs + +In the table below, you can find Prebid's test IDs that are used in the Demo Applications and that you can utilize for SDK integration validation. + +{: .table .table-bordered .table-striped } + +| Config ID | Ad Format | Description | +| -------------------- | ---------------- | ---------------------- | +|`https://prebid-server-test-j.prebid.org/openrtb2/auction` | **Custom Prebid Server Host**|A PBS instance that is dedicated to testing purposes.| +|`0689a263-318d-448b-a3d4-b02e8a709d9d`| **Stored Request ID**|The test account ID on the test server.| +|`imp-prebid-banner-320-50`|**HTML Banner**|Returns a stored response that contains a Banner 320x50 winning bid.| +|`imp-prebid-display-interstitial-320-480`|**HTML Interstitial**|Returns a stored response that contains a Interstitial 320x480 winning bid.| +|`imp-prebid-video-outstream-original-api`|**Outstream Video** (Original API)|Returns a stored response that contains a Video 320x50 winning bid.| +|`imp-prebid-video-outstream`|**Outstream Video** (Rendering API)|Returns a stored response that contains a Video 320x50 winning bid.| +|`imp-prebid-video-interstitial-320-480-original-api`|**Video Interstitial** (Original API)|Returns a stored response that contains a Video Interstitial 320x480 winning bid.| +|`imp-prebid-video-interstitial-320-480`|**Video Interstitial** (Rendering API)|Returns a stored response that contains a Video Interstitial 320x480 winning bid.| +|`imp-prebid-video-rewarded-320-480-original-api`|**Rewarded Video** (Original API)|Returns a stored response that contains a Rewarded Video 320x480 winning bid.| +|`imp-prebid-video-rewarded-320-480`|**Rewarded Video** (Original API)|Returns a stored response that contains a Rewarded Video 320x480 winning bid.| +|`sample_video_response`|**Instream Video**|Returns a stored response that contains a Video 320x480 winning bid. Note: on Android we have an [issue](https://github.com/prebid/prebid-mobile-android/issues/517) with Instream Video demo example. When it is fixed the config id will be updated to the new one.| +|`imp-prebid-banner-native-styles`|**Native Styles**|Returns a stored response that contains a Native winning bid.| +|`imp-prebid-banner-native-styles`|**In-App Native**|Returns a stored response that contains a Native winning bid.| diff --git a/prebid-mobile/pbm-api/ios/code-integration-ios.md b/prebid-mobile/pbm-api/ios/code-integration-ios.md index ec6f62c4..14afbaa9 100644 --- a/prebid-mobile/pbm-api/ios/code-integration-ios.md +++ b/prebid-mobile/pbm-api/ios/code-integration-ios.md @@ -254,3 +254,28 @@ Follow the corresponding guide to integrate Prebid Mobile: - [AdMob](../../modules/rendering/ios-sdk-integration-gam.html) - [AppLovin MAX](../../modules/rendering/ios-sdk-integration-max.html) + +### Test configs + +In the table below, you can find Prebid's test IDs that are used in the Demo Applications and that you can utilize for SDK integration validation. + +{: .table .table-bordered .table-striped } + +| Config ID | Ad Format | Description | +| -------------------- | ---------------- | ---------------------- | +|`https://prebid-server-test-j.prebid.org/openrtb2/auction` | **Custom Prebid Server Host**|A PBS instance that is dedicated to testing purposes.| +|`0689a263-318d-448b-a3d4-b02e8a709d9d`| **Stored Request ID**|The test account ID on the test server.| +|`imp-prebid-banner-320-50`|**HTML Banner**|Returns a stored response that contains a Banner 320x50 winning bid.| +|`imp-prebid-display-interstitial-320-480`|**HTML Interstitial**|Returns a stored response that contains a Interstitial 320x480 winning bid.| +|`imp-prebid-video-outstream-original-api`|**Outstream Video** (Original API)|Returns a stored response that contains a Video 320x50 winning bid.| +|`imp-prebid-video-outstream`|**Outstream Video** (Rendering API)|Returns a stored response that contains a Video 320x50 winning bid.| +|`imp-prebid-video-interstitial-320-480-original-api`|**Video Interstitial** (Original API)|Returns a stored response that contains a Video Interstitial 320x480 winning bid.| +|`imp-prebid-video-interstitial-320-480`|**Video Interstitial** (Rendering API)|Returns a stored response that contains a Video Interstitial 320x480 winning bid.| +|`imp-prebid-video-rewarded-320-480-original-api`|**Rewarded Video** (Original API)|Returns a stored response that contains a Rewarded Video 320x480 winning bid.| +|`imp-prebid-video-rewarded-320-480`|**Rewarded Video** (Original API)|Returns a stored response that contains a Rewarded Video 320x480 winning bid.| +|`imp-prebid-video-interstitial-320-480`|**Instream Video**|Returns a stored response that contains a Video 320x480 winning bid.| +|`imp-prebid-banner-native-styles`|**Native Styles**|Returns a stored response that contains a Native winning bid.| +|`imp-prebid-banner-native-styles`|**In-App Native**|Returns a stored response that contains a Native winning bid.| + + + From 312ff2d66ad4f3517fc21c024b09049c18327a4d Mon Sep 17 00:00:00 2001 From: bretg Date: Thu, 16 Feb 2023 11:46:55 -0500 Subject: [PATCH 057/762] cookie consent optanon no longer works (#4374) --- _layouts/example.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/_layouts/example.html b/_layouts/example.html index c86ea1d5..efbb0461 100644 --- a/_layouts/example.html +++ b/_layouts/example.html @@ -99,7 +99,7 @@

Further Reading

{% include footer.html %} From e914d46ae94db20937f6e3739b4e1714a7339901 Mon Sep 17 00:00:00 2001 From: bretg Date: Thu, 16 Feb 2023 13:27:39 -0500 Subject: [PATCH 058/762] can't call onetrust until loaded (#4375) --- _layouts/example.html | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/_layouts/example.html b/_layouts/example.html index efbb0461..50c6697f 100644 --- a/_layouts/example.html +++ b/_layouts/example.html @@ -61,7 +61,7 @@

About this example:

- {% include footer.html %} From b54d5fa56bc4d4efd793808699d4dcac12740bf8 Mon Sep 17 00:00:00 2001 From: bretg Date: Thu, 16 Feb 2023 14:19:23 -0500 Subject: [PATCH 059/762] Update guide.md --- guide.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/guide.md b/guide.md index b914330d..f102b184 100644 --- a/guide.md +++ b/guide.md @@ -304,7 +304,7 @@ We use Algolia for site search. Prebid websites don't set their own cookies, but vendor products we use do. So we use the OneTrust CookiePro library to pop up a cookie banner. If the user hasn't consented to setting cookies, they will find reduced functionality on the site -- they won't be able to view JSFiddle examples or example videos. -This is implemented with the [OptAnon](https://community.cookiepro.com/s/article/UUID-730ad441-6c4d-7877-7f85-36f1e801e8ca?language=en_US) library. See layout/example.md for how the OptAnon.InsertHtml function is used. +This is implemented with the [OneTrust](https://community.cookiepro.com/s/article/UUID-730ad441-6c4d-7877-7f85-36f1e801e8ca?language=en_US) library. See layout/example.md for how the OneTrust.InsertHtml function is used. The last argument to that function is the "group id", which declares what kind of cookies this vendor script is going to set. Here's how OneTrust defines the groups: From 4d3851f7bcf943cc9ec45bf00b233e9d13509ac9 Mon Sep 17 00:00:00 2001 From: msmeza Date: Fri, 17 Feb 2023 14:49:48 +0100 Subject: [PATCH 060/762] Updated Livewrapped Bid Adapter documentation (#4365) We just added support for the Price Floors Module (). We also became Prebid members. --- dev-docs/bidders/livewrapped.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/dev-docs/bidders/livewrapped.md b/dev-docs/bidders/livewrapped.md index cf58f805..221c4184 100644 --- a/dev-docs/bidders/livewrapped.md +++ b/dev-docs/bidders/livewrapped.md @@ -6,12 +6,14 @@ biddercode: livewrapped pbjs: true media_types: banner, video, native gdpr_supported: true +prebid_member: true userIds: all schain_supported: true gvl_id: 919 usp_supported: true coppa_supported: true safeframes_ok: true +floors_supported: true sidebarType: 1 --- From fc062f72449a4d71e941ba41937f8d69977fcbdd Mon Sep 17 00:00:00 2001 From: Ho Chia Leung Date: Thu, 23 Feb 2023 14:12:39 +0100 Subject: [PATCH 061/762] Gam creative missing value (#4340) * Update huaweiads.md add gdpr and coppa support * no message * Update pbs-database.md replaced `%RESPONSE_ID_LIST%` with `%ID_LIST%` * Update huaweiads.md * parameter is different between Go and Java * changed the custom parameters from "pb_hb" to "hb_pb" * attach adView to the view group * added the value for the dispatchAppEvent function --------- Co-authored-by: Ho Chia Leung Co-authored-by: bretg --- adops/mobile-rendering-gam-line-item-setup.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/adops/mobile-rendering-gam-line-item-setup.md b/adops/mobile-rendering-gam-line-item-setup.md index 8d076a35..74a9ab5c 100644 --- a/adops/mobile-rendering-gam-line-item-setup.md +++ b/adops/mobile-rendering-gam-line-item-setup.md @@ -54,7 +54,7 @@ If GAM Event Handler receives the `PrebidAppEvent` event it will render the winn ``` html - + ``` Pipeline Screenshot From 0a57e439ab6a5394e4323e4b84dbec52a1926eaa Mon Sep 17 00:00:00 2001 From: Demetrio Girardi Date: Thu, 23 Feb 2023 06:07:13 -0800 Subject: [PATCH 062/762] PBJS: Document `adUnit.bids[].ortb2Imp` and `module` (#4376) --- dev-docs/adunit-reference.md | 73 ++++++++++++++++++++++++++++++-- dev-docs/modules/prebidServer.md | 3 ++ 2 files changed, 73 insertions(+), 3 deletions(-) diff --git a/dev-docs/adunit-reference.md b/dev-docs/adunit-reference.md index 7464ca1a..0aeba72d 100644 --- a/dev-docs/adunit-reference.md +++ b/dev-docs/adunit-reference.md @@ -36,7 +36,7 @@ See the table below for the list of properties on the ad unit. For example ad u | `mediaTypes` | Optional | Object | Defines one or more media types that can serve into the ad unit. For a list of properties, see [`adUnit.mediaTypes`](#adUnit.mediaTypes) below. | | `labelAny` | Optional | Array[String] | Used for [conditional ads][conditionalAds]. Works with `sizeConfig` argument to [pbjs.setConfig][configureResponsive]. | | `labelAll` | Optional | Array[String] | Used for [conditional ads][conditionalAds]. Works with `sizeConfig` argument to [pbjs.setConfig][configureResponsive]. | -| `ortb2Imp` | Optional | Object | ortb2Imp is used to signal OpenRTB Imp objects at the adUnit grain. Similar to the global ortb2 field used for [global first party data configuration](/dev-docs/publisher-api-reference/setConfig.html#setConfig-fpd), but specific to this adunit. The ortb2Imp object currently supports [first party data](#adUnit-fpd-example) including the [Prebid Ad Slot](/features/pbAdSlot.html) and the [interstitial](#adUnit-interstitial-example) signal. | +| `ortb2Imp` | Optional | Object | ortb2Imp is used to signal OpenRTB Imp objects at the adUnit grain. Similar to the global ortb2 field used for [global first party data configuration](/dev-docs/publisher-api-reference/setConfig.html#setConfig-fpd), but specific to this adunit.| | `ttlBuffer` | Optional | Number | TTL buffer override for this adUnit. See [setConfig({ttlBuffer})](/dev-docs/publisher-api-reference/setConfig.html#setConfig-ttlBuffer) | | `renderer` | Optional | Object | Custom renderer, typically used for [outstream video](/dev-docs/show-outstream-video-ads.html) | | `video` | Optional | Object | Used to link an Ad Unit to the [Video Module][videoModule]. For allowed params see the [adUnit.video reference](#adUnit-video). | @@ -47,15 +47,17 @@ See the table below for the list of properties on the ad unit. For example ad u See the table below for the list of properties in the `bids` array of the ad unit. For example ad units, see the [Examples](#adUnit-examples) below. -Note that `bids` is optional only for [Prebid Server stored impressions](/dev-docs/modules/prebidServer.html#stored-imp), and required in all other cases. +Note that `bids` is optional only for [Prebid Server stored impressions](#stored-imp), and required in all other cases. {: .table .table-bordered .table-striped } | Name | Scope | Type | Description | |------------+----------+---------------+------------------------------------------------------------------------------------------------------------------------------------------| -| `bidder` | Required | String | Unique code identifying the bidder. For bidder codes, see the [bidder param reference]({{site.baseurl}}/dev-docs/bidders.html). | +| `bidder` | Optional | String | Unique code identifying the bidder. For bidder codes, see the [bidder param reference]({{site.baseurl}}/dev-docs/bidders.html). | +| `module` | Optional | String | Module code - for requesting bids from modules that are not bid adapters. See [Prebid Server stored impressions](#stored-imp). | | `params` | Required | Object | Bid request parameters for a given bidder. For allowed params, see the [bidder param reference]({{site.baseurl}}/dev-docs/bidders.html). | | `labelAny` | Optional | Array[String] | Used for [conditional ads][conditionalAds]. Works with `sizeConfig` argument to [pbjs.setConfig][configureResponsive]. | | `labelAll` | Optional | Array[String] | Used for [conditional ads][conditionalAds]. Works with `sizeConfig` argument to [pbjs.setConfig][configureResponsive]. | +| `ortb2Imp` | Optional | Object | OpenRTB first-party data specific to this bidder. This is merged with, and takes precedence over, `adUnit.ortb2Imp`.| | `renderer` | Optional | Object | Custom renderer. Takes precedence over `adUnit.renderer`, but applies only to this bidder. | @@ -605,6 +607,71 @@ pbjs.addAdUnits({ For more information on Interstitial ads, reference the [Interstitial feature page](/features/InterstitialAds.html). + + +### Prebid Server stored impressions + +When using [PBS stored impressions](/dev-docs/modules/prebidServer.html#stored-imp), `bids` is not required: + +```javascript +pbjs.addAdUnits({ + code: "test-div", + ortb2Imp: { + ext: { + prebid: { + storedrequest: { + id: 'stored-request-id' + } + } + } + } +}) +``` + +To use stored impressions together with client-side bidders - or stored impressions from other instances of Prebid Server - use `bids[].module`: + +```javascript +pbjs.addAdUnits({ + code: "test-div", + bids: [ + { + module: "pbsBidAdapter", + params: { + configName: "server-1" + }, + ortb2Imp: { + ext: { + prebid: { + storedrequest: { + id: 'stored-request-server-1' + } + } + } + } + }, + { + module: "pbsBidAdapter", + params: { + configName: "server-2" + }, + ortb2Imp: { + ext: { + prebid: { + storedrequest: { + id: 'stored-request-server-2' + } + } + } + } + }, + { + bidder: 'client-bidder', + // ... + } + ] +}); +``` + ## Related Topics + [Publisher API Reference](/dev-docs/publisher-api-reference) diff --git a/dev-docs/modules/prebidServer.md b/dev-docs/modules/prebidServer.md index 3ed47eee..c8e9b96e 100644 --- a/dev-docs/modules/prebidServer.md +++ b/dev-docs/modules/prebidServer.md @@ -45,12 +45,14 @@ The same bidder cannot be set in both configs. For example: pbjs.setConfig({ s2sConfig: [ { + name: "pbs-appnexus", accountId: '12345', bidders: ['appnexus','pubmatic'], defaultVendor: 'appnexus', timeout: 300, }, { + name: "pbs-rubicon", accountId: '678910', bidders: ['rubicon'], defaultVendor: 'rubicon', @@ -65,6 +67,7 @@ There are many configuration options for s2sConfig: | Attribute | Scope | Type | Description | |------------+---------+---------+---------------------------------------------------------------| | `accountId` | Required | String | Your Prebid Server account ID. This is obtained from whoever's hosting your Prebid Server. | +| `name` | Optional | String | A handle for this configuration, used to reference a specific server (when multiple are present) from [ad unit configuration](/dev-docs/adunit-reference.html#stored-imp) | | `bidders` | Optional | Array of Strings | Which bidders auctions should take place on the server side | | `allowUnknownBidderCodes` | Optional | Boolean | Allow Prebid Server to bid on behalf of bidders that are not explicitly listed in the adUnit. See important [note](#allowUnknownBidderCodes) below. Defaults to `false`. | | `defaultVendor` | Optional | String | Automatically includes all following options in the config with vendor's default values. Individual properties can be overridden by including them in the config along with this setting. See the Additional Notes below for more information. | From bf3f47befd6cbc97c9e9c6962e57cf168fae6901 Mon Sep 17 00:00:00 2001 From: Bugxyb Date: Thu, 23 Feb 2023 23:16:56 +0800 Subject: [PATCH 063/762] add EUC endpoint for Algorix (#4378) Co-authored-by: Bugxyb --- dev-docs/bidders/algorix.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/dev-docs/bidders/algorix.md b/dev-docs/bidders/algorix.md index 7de42639..a70e0909 100644 --- a/dev-docs/bidders/algorix.md +++ b/dev-docs/bidders/algorix.md @@ -29,9 +29,9 @@ AlgoriX adapter requires setup and approval from the AlgoriX team, even for exis | `token` | required | Token | `'028bca2d3b5c4f0ba155fa34864b0c4d'` | `string` | | `placementId` | optional | Placement Id | `'123456'` | `string` | | `appId` | optional | App Id | `'asdasdasd'` | `string` | -| `region` | optional | Server Region | `'APAC' or 'USE'` | `string` | +| `region` | optional | Server Region | `'APAC', 'USE', 'EUC'` | `string` | Note: * Prebid Server adapter only checks for and uses first imp bid params. All other imp bid params are ignored. * placementId and appId will be generated on AlgoriX Platform. -* region is optional param, which determine the AlgoriX server. APAC for SG endpoint, USE for US endpoint, Other for Global endpoint. +* region is optional param, which determine the AlgoriX server. APAC for SG endpoint, USE for US endpoint, EUC for EU endpoint, Other for Global endpoint. From 59c984fb14c5f0839a1c8a8a0161c73bec8c2b7c Mon Sep 17 00:00:00 2001 From: optidigital-prebid <124287395+optidigital-prebid@users.noreply.github.com> Date: Thu, 23 Feb 2023 16:37:17 +0100 Subject: [PATCH 064/762] New Adapter: Optidigital (#4327) * add Optidigital adapter * update doc --------- Co-authored-by: Dawid W --- dev-docs/bidders/optidigital.md | 73 +++++++++++++++++++++++++++++++++ 1 file changed, 73 insertions(+) create mode 100644 dev-docs/bidders/optidigital.md diff --git a/dev-docs/bidders/optidigital.md b/dev-docs/bidders/optidigital.md new file mode 100644 index 00000000..e8f1d911 --- /dev/null +++ b/dev-docs/bidders/optidigital.md @@ -0,0 +1,73 @@ +--- +layout: bidder +title: Optidigital +description: Prebid Optidigital Bidder Adapter +biddercode: optidigital +pbjs: true +floors_supported: true +tcf2_supported: true +usp_supported: true +schain_supported: true +ortb_blocking_supported: true +safeframes_ok: true +media_types: banner +gvl_id: 915 +sidebarType: 1 +--- + +### Bid Params + +{: .table .table-bordered .table-striped } +| Name | Scope | Description | Example | Type | +|----------------|----------|------------------------------------------------|--------------------------|--------------------| +| `publisherId` | required | Unique id of the publisher | `'p1234'` | `string` | +| `placementId` | required | Identifier for specific ad placement or ad tag | `'Billboard_Top'` | `string` | +| `divId` | optional | Id of the div containing the ad slot | `'Billboard_Top_3c5425'` | `string` | +| `pageTemplate` | optional | Page template name of the current page | `'home'` | `string` | +| `badv` | optional | Blocked advertiser domains | `['example.com']` | `array of strings` | +| `bcat` | optional | Blocked advertiser categories | `['IAB1-1', 'IAB1-2']` | `array of strings` | +| `bapp` | optional | Blocked advertiser mobile app bundles | `['com.blocked']` | `array of strings` | +| `battr` | optional | Blocked creative attributes | `[1, 2]` | `array of integers`| + + +### Note: + +The Optidigital Bidding adapter requires setup before beginning. Please contact us at prebid@optidigital.com. +The following test parameters can be used to verify that the Optidigital adapter is working properly. This example includes an test publisherId and placementId that would return the test creative. + +### AdUnits configuration example +``` + var adUnits = [{ + code: 'your-slot_1-div', // use exactly the same code as your slot div id. + mediaTypes: { + banner: { + sizes: [[300,600]] + } + }, + bids: [{ + bidder: 'optidigital', + params: { + publisherId: 'test', + placementId: 'Billboard_Top', + divId: 'Billboard_Top_3c5425', // optional parameter + pageTemplate: 'home', // optional parameter + badv: ['example.com'], // optional parameter + bcat: ['IAB1-1', 'IAB1-2'], // optional parameter + bapp: ['com.blocked'], // optional parameter + battr: [1, 2] // optional parameter + } + }] + }]; +``` + +### UserSync example + +``` +pbjs.setConfig({ + userSync: { + iframeEnabled: true, + syncEnabled: true, + syncDelay: 3000 + } +}); +``` \ No newline at end of file From cb4e8a6c273e68dae651d26d5a133b639b2c0ddc Mon Sep 17 00:00:00 2001 From: bretg Date: Thu, 23 Feb 2023 10:44:22 -0500 Subject: [PATCH 065/762] dead link fixes (#4385) --- _data/dropdown_v2.yml | 2 +- _data/sidebar.yml | 16 ---------------- adops/mobile-rendering-admob-line-item-setup.md | 2 +- adops/mobile-rendering-gam-line-item-setup.md | 4 ++-- adops/mobile-rendering-max-line-item-setup.md | 2 +- .../integrate-with-the-prebid-analytics-api.md | 2 +- dev-docs/modules/genericAnalyticsAdapter.md | 2 +- .../publisher-api-reference/bidderSettings.md | 2 +- .../pbm-api/ios/code-integration-ios.md | 4 ++-- 9 files changed, 10 insertions(+), 26 deletions(-) diff --git a/_data/dropdown_v2.yml b/_data/dropdown_v2.yml index 268f618b..6c0629e1 100644 --- a/_data/dropdown_v2.yml +++ b/_data/dropdown_v2.yml @@ -312,7 +312,7 @@ sectionId: 3 sectionName: Download title: Prebid Mobile - link: /prebid-mobile/download.html + link: /prebid-mobile/prebid-mobile-download.html needsDivider: 0 isHeader: 0 isSubSectionStart: 1 diff --git a/_data/sidebar.yml b/_data/sidebar.yml index 864ce4bd..9b848261 100644 --- a/_data/sidebar.yml +++ b/_data/sidebar.yml @@ -367,14 +367,6 @@ sectionTitle: subgroup: 3 -- sbSecId: 1 - title: Prebid 1.0 Publisher API Changes - link: /dev-docs/prebid-1.0-API.html - isHeader: 0 - isSectionHeader: 0 - sectionTitle: - subgroup: 3 - - sbSecId: 1 title: Adding an Adapter link: @@ -1027,14 +1019,6 @@ sectionTitle: subgroup: 2 -- sbSecId: 3 - title: 'Setting up Long-Form Video in GAM' - link: /adops/setting-up-prebid-ott-video-in-gam.html - isHeader: 0 - isSectionHeader: 0 - sectionTitle: - subgroup: 2 - - sbSecId: 3 title: "Setting up Order for Mobile Rendering API" link: /adops/mobile-rendering-gam-line-item-setup.html diff --git a/adops/mobile-rendering-admob-line-item-setup.md b/adops/mobile-rendering-admob-line-item-setup.md index df204565..5c2d4e73 100644 --- a/adops/mobile-rendering-admob-line-item-setup.md +++ b/adops/mobile-rendering-admob-line-item-setup.md @@ -3,7 +3,7 @@ layout: page_v2 title: Prebid Mobile Rendering Modules description: Prebid Mobile Rendering Modules architecture -sidebarType: 2 +sidebarType: 3 --- diff --git a/adops/mobile-rendering-gam-line-item-setup.md b/adops/mobile-rendering-gam-line-item-setup.md index 74a9ab5c..062acf03 100644 --- a/adops/mobile-rendering-gam-line-item-setup.md +++ b/adops/mobile-rendering-gam-line-item-setup.md @@ -3,7 +3,7 @@ layout: page_v2 title: Prebid Mobile Rendering GAM Line Item Setup description: Prebid Mobile Rendering Modules GAM line item setup -sidebarType: 2 +sidebarType: 3 --- @@ -203,4 +203,4 @@ p { padding: 4px; } ``` ---> \ No newline at end of file +--> diff --git a/adops/mobile-rendering-max-line-item-setup.md b/adops/mobile-rendering-max-line-item-setup.md index 259314a4..d2d3c48a 100644 --- a/adops/mobile-rendering-max-line-item-setup.md +++ b/adops/mobile-rendering-max-line-item-setup.md @@ -3,7 +3,7 @@ layout: page_v2 title: Prebid Mobile Rendering Modules description: Prebid Mobile Rendering Modules architecture -sidebarType: 2 +sidebarType: 3 --- diff --git a/dev-docs/integrate-with-the-prebid-analytics-api.md b/dev-docs/integrate-with-the-prebid-analytics-api.md index 78311d54..a433dfc4 100644 --- a/dev-docs/integrate-with-the-prebid-analytics-api.md +++ b/dev-docs/integrate-with-the-prebid-analytics-api.md @@ -75,7 +75,7 @@ Analytics adapter for Example.com. Contact prebid@example.com for information. 2. Create an analytics adapter to listen for [Prebid events](/dev-docs/publisher-api-reference/onEvent.html) and call the analytics library or server. See the existing *AnalyticsAdapter.js files in the repo under [modules](https://github.com/prebid/Prebid.js/tree/master/modules). -3. There are two types of analytics adapters. The example here focuses on the 'endpoint' type. See [AnalyticsAdapter.js](https://github.com/prebid/Prebid.js/blob/master/src/AnalyticsAdapter.js) for more info on the 'bundle' type. +3. There are two types of analytics adapters. The example here focuses on the 'endpoint' type. See [AnalyticsAdapter.js](https://github.com/prebid/Prebid.js/blob/master/libraries/analyticsAdapter/AnalyticsAdapter.js) for more info on the 'bundle' type. * endpoint - Calls the specified URL on analytics events. Doesn't require a global context. * bundle - An advanced option expecting a global context. diff --git a/dev-docs/modules/genericAnalyticsAdapter.md b/dev-docs/modules/genericAnalyticsAdapter.md index a243b63e..a29f7236 100644 --- a/dev-docs/modules/genericAnalyticsAdapter.md +++ b/dev-docs/modules/genericAnalyticsAdapter.md @@ -227,4 +227,4 @@ pbjs.enableAnalytics({ ### See also -[Prebid.js events](/dev-docs/publisher-api-reference/getEvents.md) +[Prebid.js events](/dev-docs/publisher-api-reference/getEvents.html) diff --git a/dev-docs/publisher-api-reference/bidderSettings.md b/dev-docs/publisher-api-reference/bidderSettings.md index 59ee2f39..d7d9e8c3 100644 --- a/dev-docs/publisher-api-reference/bidderSettings.md +++ b/dev-docs/publisher-api-reference/bidderSettings.md @@ -217,7 +217,7 @@ In the above example, the AOL bidder will inherit from "standard" adserverTarget ##### 2.3. inverseCpmAdjustment -When using [price floors](dev-docs/modules/floors.html), Prebid attempts to calculate the inverse of `bidCpmAdjustment`, so that the floor values it requests from SSPs take into account how the bid will be adjusted. +When using [price floors](/dev-docs/modules/floors.html), Prebid attempts to calculate the inverse of `bidCpmAdjustment`, so that the floor values it requests from SSPs take into account how the bid will be adjusted. For example, if the adjustment is `bidCpm * .85` as above, floors are adjusted by `bidFloor * 1 / .85`. The automatically derived inverse function is correct only when `bidCpmAdjustment` is a simple multiplication. If it isn't, the inverse should also be provided through `inverseCpmAdjustment`. For example: diff --git a/prebid-mobile/pbm-api/ios/code-integration-ios.md b/prebid-mobile/pbm-api/ios/code-integration-ios.md index 14afbaa9..a5114a59 100644 --- a/prebid-mobile/pbm-api/ios/code-integration-ios.md +++ b/prebid-mobile/pbm-api/ios/code-integration-ios.md @@ -11,7 +11,7 @@ sidebarType: 2 # Integration for iOS {:.no_toc} -Get started with Prebid Mobile by creating a [Prebid Server account]({{site.github.url}}/prebid-mobile/prebid-mobile-getting-started.html). Once your account is set up include the Prebid Mobile SDK in your app by either using dependencies managers or by [cloning the repo](https://github.com/prebid/prebid-mobile-ios) and using our included script to build the SDK. +Get started with Prebid Mobile by creating a [Prebid Server account](/prebid-mobile/prebid-mobile-getting-started.html). Once your account is set up include the Prebid Mobile SDK in your app by either using dependencies managers or by [cloning the repo](https://github.com/prebid/prebid-mobile-ios) and using our included script to build the SDK. * TOC {:toc} @@ -90,7 +90,7 @@ This will output the PrebidMobile.framework. ## Initialize SDK -Once you have a [Prebid Server]((/prebid-mobile/prebid-mobile-getting-started.html)), you will add 'account' info to the Prebid Mobile. For example, if you're using the AppNexus Prebid Server: +Once you have a [Prebid Server](/prebid-mobile/prebid-mobile-getting-started.html), you will add 'account' info to the Prebid Mobile. For example, if you're using the AppNexus Prebid Server: ``` Prebid.shared.prebidServerAccountId = "YOUR_ACCOUNT_ID" From 7936b3a3dc6c213b027780f42b28d5299559f370 Mon Sep 17 00:00:00 2001 From: Andrew Date: Thu, 23 Feb 2023 08:36:01 -0800 Subject: [PATCH 066/762] Remove broken linkedin link (#4386) Co-authored-by: Andrew Fowler --- _layouts/home.html | 1 - 1 file changed, 1 deletion(-) diff --git a/_layouts/home.html b/_layouts/home.html index 30db9fa9..4738f798 100644 --- a/_layouts/home.html +++ b/_layouts/home.html @@ -155,7 +155,6 @@

Subscribe for Updates

From 4495b5f714d60c0e4bf07c26b6721760c4eb8c7e Mon Sep 17 00:00:00 2001 From: Chris Huie Date: Thu, 23 Feb 2023 12:07:25 -0700 Subject: [PATCH 067/762] Update kueezrtb.md (#4361) --- dev-docs/bidders/kueezrtb.md | 1 + 1 file changed, 1 insertion(+) diff --git a/dev-docs/bidders/kueezrtb.md b/dev-docs/bidders/kueezrtb.md index f63a4576..2ef4bc25 100644 --- a/dev-docs/bidders/kueezrtb.md +++ b/dev-docs/bidders/kueezrtb.md @@ -9,6 +9,7 @@ gdpr_supported: true usp_supported: true coppa_supported: false schain_supported: true +gpp_supported: true floors_supported: true media_types: banner, video prebid_member: false From f3f628dd32703936009c1282094964778ed24dfa Mon Sep 17 00:00:00 2001 From: bretg Date: Thu, 23 Feb 2023 18:36:28 -0500 Subject: [PATCH 068/762] amp-iframe sync update (#4388) --- dev-docs/show-prebid-ads-on-amp-pages.md | 27 +++++++----------------- 1 file changed, 8 insertions(+), 19 deletions(-) diff --git a/dev-docs/show-prebid-ads-on-amp-pages.md b/dev-docs/show-prebid-ads-on-amp-pages.md index 324d165e..48e0e0ed 100644 --- a/dev-docs/show-prebid-ads-on-amp-pages.md +++ b/dev-docs/show-prebid-ads-on-amp-pages.md @@ -222,15 +222,12 @@ Replace `MACRO` in the preceding example with the appropriate macro for the ad s To sync user IDs with Prebid Server, the `amp-iframe` below may be added to your AMP pages referring to `load-cookie.html` or if you're running an IAB-compliant AMP CMP you can use `load-cookie-with-consent.html`. -{% capture tipNote %} -The following examples include a transparent image as a placeholder which will allow you to place the example at the top within the HTML body. If this is not included the iFrame must be either 600px away from the top or not within the first 75% of the viewport when scrolled to the top – whichever is smaller. For more information on this, see [amp-iframe](https://amp.dev/documentation/components/amp-iframe/) -{% endcapture %} -{% include alerts/alert_tip.html content=tipNote %} +Note that AMP constrains syncing as described in the [amp-iframe](https://amp.dev/documentation/components/amp-iframe) documentation. You may only have *one* amp-iframe on your page that is small, e.g. 1x1. Many publishers already have some kind of analytics or tracking frame on their page, so they may find it difficult to manage this. Several hacks are possible, including building a 'frankenstein' script that combines all of your required tracking into one or tying the sync to an image that's large enough to be visible. -{% capture consentNote %} - The load-cookie-with-consent.html file has the same argument syntax as load-cookie.html. It's a different file because it's larger and depends on the existence of an AMP Consent Management Platform. Note that the `sandbox` parameter to the amp-iframe must include both "allow-scripts" and "allow-same-origin". -{% endcapture %} -{% include alerts/alert_tip.html content=consentNote %} +Notes: +- The following examples include a transparent image as a placeholder which will allow you to place the example at the top within the HTML body. If this is not included the iFrame must be either 600px away from the top or not within the first 75% of the viewport when scrolled to the top – whichever is smaller. For more information on this, see [amp-iframe](https://amp.dev/documentation/components/amp-iframe/) +- Note that the `sandbox` parameter to the amp-iframe must include both "allow-scripts" and "allow-same-origin". +- The load-cookie-with-consent.html file has the same argument syntax as load-cookie.html. It's a different file because it's larger and depends on the existence of an AMP Consent Management Platform. If you're using AppNexus' managed service, you would enter something like this: ```html @@ -267,16 +264,10 @@ Or you can specify a full URL to another Prebid Server location (including a QA See [manually initiating a sync](/prebid-server/developers/pbs-cookie-sync.html#manually-initiating-a-sync) for more information about the available parameters. -### AMP RTC and GDPR +### AMP RTC -The two Prebid Server RTC vendor strings 'prebidappnexuspsp' and 'prebidrubicon' -support passing GDPR consent to Prebid Server. - -The CONSENT_STRING macro will be populated if you've integrated with a CMP -that supports amp-consent v2 -- custom CMP integration. - -If you're using a custom RTC callout, here are the parameters that can be passed through the RTC string: -- tag_id +If you're using a custom RTC callout rather than one of the pre-defined [vendor callouts](https://github.com/ampproject/amphtml/blob/main/src/service/real-time-config/callout-vendors.js), here are the parameters that can be passed through the RTC string: +- tag_id (this correspondes to the Prebid Server stored request ID) - w=ATTR(width) - h=ATTR(height) - ow=ATTR(data-override-width) @@ -293,8 +284,6 @@ If you're using a custom RTC callout, here are the parameters that can be passed - gdpr_applies=CONSENT_METADATA(gdprApplies) - attl_consent=CONSENT_METADATA(additionalConsent) -See the entries in the [AMP vendors callout file](https://github.com/ampproject/amphtml/blob/main/src/service/real-time-config/callout-vendors.js). - ## Debugging Tips To review that Prebid on AMP is working properly the following aspects can be looked at: + Include `#development=1` to the URL to review AMP specifc debug messages in the browser console. From 2de93571f0af96bc2c243aa5b7fa7f8fdd8b4a4f Mon Sep 17 00:00:00 2001 From: moquity <33487117+moquity@users.noreply.github.com> Date: Fri, 24 Feb 2023 18:15:31 +0200 Subject: [PATCH 069/762] NeuwoRTDProvider: docs: Overview, apiUrl (#4380) * overview improved, added description for apiUrl config value * Changed advertiser to plural --- dev-docs/modules/neuwoRtdProvider.md | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-) diff --git a/dev-docs/modules/neuwoRtdProvider.md b/dev-docs/modules/neuwoRtdProvider.md index 402bf289..9718e874 100644 --- a/dev-docs/modules/neuwoRtdProvider.md +++ b/dev-docs/modules/neuwoRtdProvider.md @@ -13,25 +13,34 @@ sidebarType : 1 # Neuwo Real-Time Data Module ## Overview -Neuwo Real-Time Data Module allows you to enrich bids using neuwo.ai for content taxonomy. + +The Neuwo AI RTD module is an advanced AI solution for real-time data processing in the field of contextual targeting and advertising. With its cutting-edge algorithms, it allows advertisers to target their audiences with the highest level of precision based on context, while also delivering a seamless user experience. + +The module provides advertisers with valuable insights and real-time contextual bidding capabilities. Whether you're a seasoned advertising professional or just starting out, Neuwo AI RTD module is the ultimate tool for contextual targeting and advertising. + +The benefit of Neuwo AI RTD module is that it provides an alternative solution for advertisers to target their audiences and deliver relevant advertisements, as the widespread use of cookies for tracking and targeting is becoming increasingly limited. + +The RTD module uses cutting-edge algorithms to process real-time data, allowing advertisers to target their audiences based on contextual information, such as segments, IAB Tiers and brand safety. The RTD module is designed to be flexible and scalable, making it an ideal solution for advertisers looking to stay ahead of the curve in the post-cookie era. + +Generate your token at: [https://neuwo.ai/generatetoken/] ## Configuration | Name | Scope | Description | Example | Type | |------------|----------|----------------------------------------|---------------|----------| | `name` | required | Handle of the module used in real-time data providers; for this, use 'NeuwoRTDModule' | 'NeuwoRTDModule' | static | -| `params.publicToken` | required | Your neuwo.ai public token | `neu23-te45-idkf-44aa` | `string` | +| `params.publicToken` | required | Your neuwo.ai public token | `neu23-te45-idkf-44aa` (format example) | `string` | +| `params.apiUrl` | required | Your neuwo.ai API url | `https://some-api-url.neuwo.ai/a/b/c` (format example) | `string` | ```javascript - const neuwoDataProvider = { name: 'NeuwoRTDModule', params: { - publicToken: '' + publicToken: '', + apiUrl: '' } } pbjs.setConfig({realTimeData: { dataProviders: [ neuwoDataProvider ]}}) - ``` ## Installation From 95688c3ffd534c41756b952a4d658b0efeb0934c Mon Sep 17 00:00:00 2001 From: Ariel Bouskila <64743745+arielunruly@users.noreply.github.com> Date: Fri, 24 Feb 2023 19:26:48 +0200 Subject: [PATCH 070/762] Update unruly.md (#4381) adding siteid as backward compability for the dev-docs --- dev-docs/bidders/unruly.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/dev-docs/bidders/unruly.md b/dev-docs/bidders/unruly.md index 2e84759c..dc193c75 100644 --- a/dev-docs/bidders/unruly.md +++ b/dev-docs/bidders/unruly.md @@ -25,5 +25,6 @@ sidebarType: 1 {: .table .table-bordered .table-striped } | Name | Scope | Description | Example | Type | |--------------------|----------------|------------------------------------------------------------------------------------------------------------------------------|--------------------------------------------------|-----------| -| `siteId` | required | The site ID from Unruly. This will be provided to you by your Unruly account manager. | `123456` | `integer` | +| `siteId` | required | The site ID from Unruly. This will be provided to you by your Unruly account manager, this is prefered | `123456` | `integer` | +| `siteid` | deprecated | The site ID from Unruly. This will be provided to you by your Unruly account manager, this is backward compability | `123456` | `integer` | | `featureOverrides` | optional | This param is a generic object for configuring Unruly outstream demand. To run UNmissable, set ‘canRunUnmissable’ to true. | `"featureOverrides": {"canRunUnmissable": true}` | `object` | From 8bd1b25d8267c527cf81bdd48b4221b874b0ebf2 Mon Sep 17 00:00:00 2001 From: Matt Vanderpol Date: Fri, 24 Feb 2023 12:32:24 -0800 Subject: [PATCH 071/762] Search update (#4391) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Update to DocSearch v3 And use new index to keep search working as expected * Remove magnifying glass from interface We don’t need it since the DocSearch v3 UI provides one * Remove other unneeded styling * Fix button display on mobile * Regenerate CSS * Break cache on CSS --- _assets/sass/components/_search.scss | 35 ++-------------------------- _includes/body-end.html | 7 +++--- _includes/head--common.html | 4 ++-- assets/css/main-bundle.css | 2 +- 4 files changed, 9 insertions(+), 39 deletions(-) diff --git a/_assets/sass/components/_search.scss b/_assets/sass/components/_search.scss index 0909593a..f369c11c 100644 --- a/_assets/sass/components/_search.scss +++ b/_assets/sass/components/_search.scss @@ -5,40 +5,9 @@ } .c-search { - position: relative; - @include media('<=990px') { - float: left; - } - - &::after { - @include position(absolute, 50% 10px null null); - @include size(20px); - transform: translateY(-50%); - background: url(/assets/images/icons/search-icon2.svg); - background-size: cover; - content: ''; - } - - input[type="search"] { - @include padding(null 8px); - border: 1px solid rgba(0, 0, 0, 0.125); - max-width: 120px; - transition: max-width 200ms ease-in-out; - - &:hover, &:focus { - max-width: 200px; - outline: none; + .DocSearch-Button { + margin-left: 0; } - - /* clears the ‘X’ from Internet Explorer */ - &::-ms-clear { display: none; width : 0; height: 0; } - &::-ms-reveal { display: none; width : 0; height: 0; } - - /* clears the ‘X’ from Chrome */ - &::-webkit-search-decoration, - &::-webkit-search-cancel-button, - &::-webkit-search-results-button, - &::-webkit-search-results-decoration { display: none; } } } diff --git a/_includes/body-end.html b/_includes/body-end.html index 023416be..e8bcc5ed 100644 --- a/_includes/body-end.html +++ b/_includes/body-end.html @@ -1,8 +1,9 @@ - + - + diff --git a/assets/css/main-bundle.css b/assets/css/main-bundle.css index f9128d2e..7eeb5561 100644 --- a/assets/css/main-bundle.css +++ b/assets/css/main-bundle.css @@ -1 +1 @@ -.awesomplete [hidden]{display:none}.awesomplete .visually-hidden{position:absolute;clip:rect(0,0,0,0)}.awesomplete{display:inline-block;position:relative}.awesomplete>input{display:block}.awesomplete>ul{position:absolute;left:0;z-index:1;min-width:100%;box-sizing:border-box;list-style:none;padding:0;margin:0;background:#fff}.awesomplete>ul:empty{display:none}*,:after,:before{box-sizing:border-box}html{font-family:sans-serif;line-height:1.15;-webkit-text-size-adjust:100%;-webkit-tap-highlight-color:rgba(0,0,0,0)}article,aside,figcaption,figure,footer,header,hgroup,main,nav,section{display:block}body{margin:0;font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Helvetica Neue,Arial,Noto Sans,sans-serif,Apple Color Emoji,Segoe UI Emoji,Segoe UI Symbol,Noto Color Emoji;font-size:1rem;font-weight:400;color:#212529;text-align:left;background-color:#eceeef}[tabindex="-1"]:focus:not(:focus-visible){outline:0!important}hr{box-sizing:content-box;height:0;overflow:visible}h1,h2,h3,h4,h5,h6{margin-top:0;margin-bottom:.5rem}p{margin-top:0;margin-bottom:1rem}abbr[data-original-title],abbr[title]{text-decoration:underline;-webkit-text-decoration:underline dotted;text-decoration:underline dotted;cursor:help;border-bottom:0;-webkit-text-decoration-skip-ink:none;text-decoration-skip-ink:none}address{font-style:normal;line-height:inherit}address,dl,ol,ul{margin-bottom:1rem}dl,ol,ul{margin-top:0}ol ol,ol ul,ul ol,ul ul{margin-bottom:0}dt{font-weight:700}dd{margin-bottom:.5rem;margin-left:0}blockquote{margin:0 0 1rem}b,strong{font-weight:bolder}small{font-size:80%}sub,sup{position:relative;font-size:75%;line-height:0;vertical-align:baseline}sub{bottom:-.25em}sup{top:-.5em}a{color:#007bff;text-decoration:none;background-color:transparent}a:hover{color:#0056b3;text-decoration:underline}a:not([href]):not([class]),a:not([href]):not([class]):hover{color:inherit;text-decoration:none}code,kbd,pre,samp{font-family:SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,monospace;font-size:1em}pre{margin-top:0;margin-bottom:1rem;overflow:auto;-ms-overflow-style:scrollbar}figure{margin:0 0 1rem}img{border-style:none}img,svg{vertical-align:middle}svg{overflow:hidden}table{border-collapse:collapse}caption{padding-top:.75rem;padding-bottom:.75rem;color:#6c757d;text-align:left;caption-side:bottom}th{text-align:inherit;text-align:-webkit-match-parent}label{display:inline-block;margin-bottom:.5rem}button{border-radius:0}button:focus{outline:1px dotted;outline:5px auto -webkit-focus-ring-color}button,input,optgroup,select,textarea{margin:0;font-family:inherit;font-size:inherit;line-height:inherit}button,input{overflow:visible}button,select{text-transform:none}[role=button]{cursor:pointer}select{word-wrap:normal}[type=button],[type=reset],[type=submit],button{-webkit-appearance:button}[type=button]:not(:disabled),[type=reset]:not(:disabled),[type=submit]:not(:disabled),button:not(:disabled){cursor:pointer}[type=button]::-moz-focus-inner,[type=reset]::-moz-focus-inner,[type=submit]::-moz-focus-inner,button::-moz-focus-inner{padding:0;border-style:none}input[type=checkbox],input[type=radio]{box-sizing:border-box;padding:0}textarea{overflow:auto;resize:vertical}fieldset{min-width:0;padding:0;margin:0;border:0}legend{display:block;width:100%;max-width:100%;padding:0;margin-bottom:.5rem;font-size:1.5rem;line-height:inherit;color:inherit;white-space:normal}progress{vertical-align:baseline}[type=number]::-webkit-inner-spin-button,[type=number]::-webkit-outer-spin-button{height:auto}[type=search]{outline-offset:-2px;-webkit-appearance:none}[type=search]::-webkit-search-decoration{-webkit-appearance:none}::-webkit-file-upload-button{font:inherit;-webkit-appearance:button}output{display:inline-block}summary{display:list-item;cursor:pointer}template{display:none}[hidden]{display:none!important}.container,.container-fluid,.container-lg,.container-md,.container-sm,.container-xl{width:100%;padding-right:10px;padding-left:10px;margin-right:auto;margin-left:auto}@media (min-width:576px){.container,.container-sm{max-width:540px}}@media (min-width:768px){.container,.container-md,.container-sm{max-width:720px}}@media (min-width:992px){.container,.container-lg,.container-md,.container-sm{max-width:960px}}@media (min-width:1200px){.container,.container-lg,.container-md,.container-sm,.container-xl{max-width:1200px}}.row{display:flex;flex-wrap:wrap;margin-right:-10px;margin-left:-10px}.no-gutters{margin-right:0;margin-left:0}.no-gutters>.col,.no-gutters>[class*=col-]{padding-right:0;padding-left:0}.col,.col-1,.col-2,.col-3,.col-4,.col-5,.col-6,.col-7,.col-8,.col-9,.col-10,.col-11,.col-12,.col-auto,.col-lg,.col-lg-1,.col-lg-2,.col-lg-3,.col-lg-4,.col-lg-5,.col-lg-6,.col-lg-7,.col-lg-8,.col-lg-9,.col-lg-10,.col-lg-11,.col-lg-12,.col-lg-auto,.col-md,.col-md-1,.col-md-2,.col-md-3,.col-md-4,.col-md-5,.col-md-6,.col-md-7,.col-md-8,.col-md-9,.col-md-10,.col-md-11,.col-md-12,.col-md-auto,.col-sm,.col-sm-1,.col-sm-2,.col-sm-3,.col-sm-4,.col-sm-5,.col-sm-6,.col-sm-7,.col-sm-8,.col-sm-9,.col-sm-10,.col-sm-11,.col-sm-12,.col-sm-auto,.col-xl,.col-xl-1,.col-xl-2,.col-xl-3,.col-xl-4,.col-xl-5,.col-xl-6,.col-xl-7,.col-xl-8,.col-xl-9,.col-xl-10,.col-xl-11,.col-xl-12,.col-xl-auto{position:relative;width:100%;padding-right:10px;padding-left:10px}.col{flex-basis:0;flex-grow:1;max-width:100%}.row-cols-1>*{flex:0 0 100%;max-width:100%}.row-cols-2>*{flex:0 0 50%;max-width:50%}.row-cols-3>*{flex:0 0 33.3333333333%;max-width:33.3333333333%}.row-cols-4>*{flex:0 0 25%;max-width:25%}.row-cols-5>*{flex:0 0 20%;max-width:20%}.row-cols-6>*{flex:0 0 16.6666666667%;max-width:16.6666666667%}.col-auto{flex:0 0 auto;width:auto;max-width:100%}.col-1{flex:0 0 8.3333333333%;max-width:8.3333333333%}.col-2{flex:0 0 16.6666666667%;max-width:16.6666666667%}.col-3{flex:0 0 25%;max-width:25%}.col-4{flex:0 0 33.3333333333%;max-width:33.3333333333%}.col-5{flex:0 0 41.6666666667%;max-width:41.6666666667%}.col-6{flex:0 0 50%;max-width:50%}.col-7{flex:0 0 58.3333333333%;max-width:58.3333333333%}.col-8{flex:0 0 66.6666666667%;max-width:66.6666666667%}.col-9{flex:0 0 75%;max-width:75%}.col-10{flex:0 0 83.3333333333%;max-width:83.3333333333%}.col-11{flex:0 0 91.6666666667%;max-width:91.6666666667%}.col-12{flex:0 0 100%;max-width:100%}.order-first{order:-1}.order-last{order:13}.order-0{order:0}.order-1{order:1}.order-2{order:2}.order-3{order:3}.order-4{order:4}.order-5{order:5}.order-6{order:6}.order-7{order:7}.order-8{order:8}.order-9{order:9}.order-10{order:10}.order-11{order:11}.order-12{order:12}.offset-1{margin-left:8.3333333333%}.offset-2{margin-left:16.6666666667%}.offset-3{margin-left:25%}.offset-4{margin-left:33.3333333333%}.offset-5{margin-left:41.6666666667%}.offset-6{margin-left:50%}.offset-7{margin-left:58.3333333333%}.offset-8{margin-left:66.6666666667%}.offset-9{margin-left:75%}.offset-10{margin-left:83.3333333333%}.offset-11{margin-left:91.6666666667%}@media (min-width:576px){.col-sm{flex-basis:0;flex-grow:1;max-width:100%}.row-cols-sm-1>*{flex:0 0 100%;max-width:100%}.row-cols-sm-2>*{flex:0 0 50%;max-width:50%}.row-cols-sm-3>*{flex:0 0 33.3333333333%;max-width:33.3333333333%}.row-cols-sm-4>*{flex:0 0 25%;max-width:25%}.row-cols-sm-5>*{flex:0 0 20%;max-width:20%}.row-cols-sm-6>*{flex:0 0 16.6666666667%;max-width:16.6666666667%}.col-sm-auto{flex:0 0 auto;width:auto;max-width:100%}.col-sm-1{flex:0 0 8.3333333333%;max-width:8.3333333333%}.col-sm-2{flex:0 0 16.6666666667%;max-width:16.6666666667%}.col-sm-3{flex:0 0 25%;max-width:25%}.col-sm-4{flex:0 0 33.3333333333%;max-width:33.3333333333%}.col-sm-5{flex:0 0 41.6666666667%;max-width:41.6666666667%}.col-sm-6{flex:0 0 50%;max-width:50%}.col-sm-7{flex:0 0 58.3333333333%;max-width:58.3333333333%}.col-sm-8{flex:0 0 66.6666666667%;max-width:66.6666666667%}.col-sm-9{flex:0 0 75%;max-width:75%}.col-sm-10{flex:0 0 83.3333333333%;max-width:83.3333333333%}.col-sm-11{flex:0 0 91.6666666667%;max-width:91.6666666667%}.col-sm-12{flex:0 0 100%;max-width:100%}.order-sm-first{order:-1}.order-sm-last{order:13}.order-sm-0{order:0}.order-sm-1{order:1}.order-sm-2{order:2}.order-sm-3{order:3}.order-sm-4{order:4}.order-sm-5{order:5}.order-sm-6{order:6}.order-sm-7{order:7}.order-sm-8{order:8}.order-sm-9{order:9}.order-sm-10{order:10}.order-sm-11{order:11}.order-sm-12{order:12}.offset-sm-0{margin-left:0}.offset-sm-1{margin-left:8.3333333333%}.offset-sm-2{margin-left:16.6666666667%}.offset-sm-3{margin-left:25%}.offset-sm-4{margin-left:33.3333333333%}.offset-sm-5{margin-left:41.6666666667%}.offset-sm-6{margin-left:50%}.offset-sm-7{margin-left:58.3333333333%}.offset-sm-8{margin-left:66.6666666667%}.offset-sm-9{margin-left:75%}.offset-sm-10{margin-left:83.3333333333%}.offset-sm-11{margin-left:91.6666666667%}}@media (min-width:768px){.col-md{flex-basis:0;flex-grow:1;max-width:100%}.row-cols-md-1>*{flex:0 0 100%;max-width:100%}.row-cols-md-2>*{flex:0 0 50%;max-width:50%}.row-cols-md-3>*{flex:0 0 33.3333333333%;max-width:33.3333333333%}.row-cols-md-4>*{flex:0 0 25%;max-width:25%}.row-cols-md-5>*{flex:0 0 20%;max-width:20%}.row-cols-md-6>*{flex:0 0 16.6666666667%;max-width:16.6666666667%}.col-md-auto{flex:0 0 auto;width:auto;max-width:100%}.col-md-1{flex:0 0 8.3333333333%;max-width:8.3333333333%}.col-md-2{flex:0 0 16.6666666667%;max-width:16.6666666667%}.col-md-3{flex:0 0 25%;max-width:25%}.col-md-4{flex:0 0 33.3333333333%;max-width:33.3333333333%}.col-md-5{flex:0 0 41.6666666667%;max-width:41.6666666667%}.col-md-6{flex:0 0 50%;max-width:50%}.col-md-7{flex:0 0 58.3333333333%;max-width:58.3333333333%}.col-md-8{flex:0 0 66.6666666667%;max-width:66.6666666667%}.col-md-9{flex:0 0 75%;max-width:75%}.col-md-10{flex:0 0 83.3333333333%;max-width:83.3333333333%}.col-md-11{flex:0 0 91.6666666667%;max-width:91.6666666667%}.col-md-12{flex:0 0 100%;max-width:100%}.order-md-first{order:-1}.order-md-last{order:13}.order-md-0{order:0}.order-md-1{order:1}.order-md-2{order:2}.order-md-3{order:3}.order-md-4{order:4}.order-md-5{order:5}.order-md-6{order:6}.order-md-7{order:7}.order-md-8{order:8}.order-md-9{order:9}.order-md-10{order:10}.order-md-11{order:11}.order-md-12{order:12}.offset-md-0{margin-left:0}.offset-md-1{margin-left:8.3333333333%}.offset-md-2{margin-left:16.6666666667%}.offset-md-3{margin-left:25%}.offset-md-4{margin-left:33.3333333333%}.offset-md-5{margin-left:41.6666666667%}.offset-md-6{margin-left:50%}.offset-md-7{margin-left:58.3333333333%}.offset-md-8{margin-left:66.6666666667%}.offset-md-9{margin-left:75%}.offset-md-10{margin-left:83.3333333333%}.offset-md-11{margin-left:91.6666666667%}}@media (min-width:992px){.col-lg{flex-basis:0;flex-grow:1;max-width:100%}.row-cols-lg-1>*{flex:0 0 100%;max-width:100%}.row-cols-lg-2>*{flex:0 0 50%;max-width:50%}.row-cols-lg-3>*{flex:0 0 33.3333333333%;max-width:33.3333333333%}.row-cols-lg-4>*{flex:0 0 25%;max-width:25%}.row-cols-lg-5>*{flex:0 0 20%;max-width:20%}.row-cols-lg-6>*{flex:0 0 16.6666666667%;max-width:16.6666666667%}.col-lg-auto{flex:0 0 auto;width:auto;max-width:100%}.col-lg-1{flex:0 0 8.3333333333%;max-width:8.3333333333%}.col-lg-2{flex:0 0 16.6666666667%;max-width:16.6666666667%}.col-lg-3{flex:0 0 25%;max-width:25%}.col-lg-4{flex:0 0 33.3333333333%;max-width:33.3333333333%}.col-lg-5{flex:0 0 41.6666666667%;max-width:41.6666666667%}.col-lg-6{flex:0 0 50%;max-width:50%}.col-lg-7{flex:0 0 58.3333333333%;max-width:58.3333333333%}.col-lg-8{flex:0 0 66.6666666667%;max-width:66.6666666667%}.col-lg-9{flex:0 0 75%;max-width:75%}.col-lg-10{flex:0 0 83.3333333333%;max-width:83.3333333333%}.col-lg-11{flex:0 0 91.6666666667%;max-width:91.6666666667%}.col-lg-12{flex:0 0 100%;max-width:100%}.order-lg-first{order:-1}.order-lg-last{order:13}.order-lg-0{order:0}.order-lg-1{order:1}.order-lg-2{order:2}.order-lg-3{order:3}.order-lg-4{order:4}.order-lg-5{order:5}.order-lg-6{order:6}.order-lg-7{order:7}.order-lg-8{order:8}.order-lg-9{order:9}.order-lg-10{order:10}.order-lg-11{order:11}.order-lg-12{order:12}.offset-lg-0{margin-left:0}.offset-lg-1{margin-left:8.3333333333%}.offset-lg-2{margin-left:16.6666666667%}.offset-lg-3{margin-left:25%}.offset-lg-4{margin-left:33.3333333333%}.offset-lg-5{margin-left:41.6666666667%}.offset-lg-6{margin-left:50%}.offset-lg-7{margin-left:58.3333333333%}.offset-lg-8{margin-left:66.6666666667%}.offset-lg-9{margin-left:75%}.offset-lg-10{margin-left:83.3333333333%}.offset-lg-11{margin-left:91.6666666667%}}@media (min-width:1200px){.col-xl{flex-basis:0;flex-grow:1;max-width:100%}.row-cols-xl-1>*{flex:0 0 100%;max-width:100%}.row-cols-xl-2>*{flex:0 0 50%;max-width:50%}.row-cols-xl-3>*{flex:0 0 33.3333333333%;max-width:33.3333333333%}.row-cols-xl-4>*{flex:0 0 25%;max-width:25%}.row-cols-xl-5>*{flex:0 0 20%;max-width:20%}.row-cols-xl-6>*{flex:0 0 16.6666666667%;max-width:16.6666666667%}.col-xl-auto{flex:0 0 auto;width:auto;max-width:100%}.col-xl-1{flex:0 0 8.3333333333%;max-width:8.3333333333%}.col-xl-2{flex:0 0 16.6666666667%;max-width:16.6666666667%}.col-xl-3{flex:0 0 25%;max-width:25%}.col-xl-4{flex:0 0 33.3333333333%;max-width:33.3333333333%}.col-xl-5{flex:0 0 41.6666666667%;max-width:41.6666666667%}.col-xl-6{flex:0 0 50%;max-width:50%}.col-xl-7{flex:0 0 58.3333333333%;max-width:58.3333333333%}.col-xl-8{flex:0 0 66.6666666667%;max-width:66.6666666667%}.col-xl-9{flex:0 0 75%;max-width:75%}.col-xl-10{flex:0 0 83.3333333333%;max-width:83.3333333333%}.col-xl-11{flex:0 0 91.6666666667%;max-width:91.6666666667%}.col-xl-12{flex:0 0 100%;max-width:100%}.order-xl-first{order:-1}.order-xl-last{order:13}.order-xl-0{order:0}.order-xl-1{order:1}.order-xl-2{order:2}.order-xl-3{order:3}.order-xl-4{order:4}.order-xl-5{order:5}.order-xl-6{order:6}.order-xl-7{order:7}.order-xl-8{order:8}.order-xl-9{order:9}.order-xl-10{order:10}.order-xl-11{order:11}.order-xl-12{order:12}.offset-xl-0{margin-left:0}.offset-xl-1{margin-left:8.3333333333%}.offset-xl-2{margin-left:16.6666666667%}.offset-xl-3{margin-left:25%}.offset-xl-4{margin-left:33.3333333333%}.offset-xl-5{margin-left:41.6666666667%}.offset-xl-6{margin-left:50%}.offset-xl-7{margin-left:58.3333333333%}.offset-xl-8{margin-left:66.6666666667%}.offset-xl-9{margin-left:75%}.offset-xl-10{margin-left:83.3333333333%}.offset-xl-11{margin-left:91.6666666667%}}.btn{display:inline-block;font-weight:400;color:#212529;text-align:center;vertical-align:middle;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;background-color:transparent;border:1px solid transparent;padding:.375rem .75rem;font-size:1rem;line-height:1.5;border-radius:.25rem;transition:color .15s ease-in-out,background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out}@media (prefers-reduced-motion:reduce){.btn{transition:none}}.btn:hover{color:#212529;text-decoration:none}.btn.focus,.btn:focus{outline:0;box-shadow:0 0 0 .2rem rgba(0,123,255,.25)}.btn.disabled,.btn:disabled{opacity:.65}.btn:not(:disabled):not(.disabled){cursor:pointer}a.btn.disabled,fieldset:disabled a.btn{pointer-events:none}.btn-primary{color:#fff;background-color:#007bff;border-color:#007bff}.btn-primary.focus,.btn-primary:focus,.btn-primary:hover{color:#fff;background-color:#0069d9;border-color:#0062cc}.btn-primary.focus,.btn-primary:focus{box-shadow:0 0 0 .2rem rgba(38,143,255,.5)}.btn-primary.disabled,.btn-primary:disabled{color:#fff;background-color:#007bff;border-color:#007bff}.btn-primary:not(:disabled):not(.disabled).active,.btn-primary:not(:disabled):not(.disabled):active,.show>.btn-primary.dropdown-toggle{color:#fff;background-color:#0062cc;border-color:#005cbf}.btn-primary:not(:disabled):not(.disabled).active:focus,.btn-primary:not(:disabled):not(.disabled):active:focus,.show>.btn-primary.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(38,143,255,.5)}.btn-secondary{color:#fff;background-color:#6c757d;border-color:#6c757d}.btn-secondary.focus,.btn-secondary:focus,.btn-secondary:hover{color:#fff;background-color:#5a6268;border-color:#545b62}.btn-secondary.focus,.btn-secondary:focus{box-shadow:0 0 0 .2rem rgba(130,138,145,.5)}.btn-secondary.disabled,.btn-secondary:disabled{color:#fff;background-color:#6c757d;border-color:#6c757d}.btn-secondary:not(:disabled):not(.disabled).active,.btn-secondary:not(:disabled):not(.disabled):active,.show>.btn-secondary.dropdown-toggle{color:#fff;background-color:#545b62;border-color:#4e555b}.btn-secondary:not(:disabled):not(.disabled).active:focus,.btn-secondary:not(:disabled):not(.disabled):active:focus,.show>.btn-secondary.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(130,138,145,.5)}.btn-success{color:#fff;background-color:#28a745;border-color:#28a745}.btn-success.focus,.btn-success:focus,.btn-success:hover{color:#fff;background-color:#218838;border-color:#1e7e34}.btn-success.focus,.btn-success:focus{box-shadow:0 0 0 .2rem rgba(72,180,97,.5)}.btn-success.disabled,.btn-success:disabled{color:#fff;background-color:#28a745;border-color:#28a745}.btn-success:not(:disabled):not(.disabled).active,.btn-success:not(:disabled):not(.disabled):active,.show>.btn-success.dropdown-toggle{color:#fff;background-color:#1e7e34;border-color:#1c7430}.btn-success:not(:disabled):not(.disabled).active:focus,.btn-success:not(:disabled):not(.disabled):active:focus,.show>.btn-success.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(72,180,97,.5)}.btn-info{color:#fff;background-color:#17a2b8;border-color:#17a2b8}.btn-info.focus,.btn-info:focus,.btn-info:hover{color:#fff;background-color:#138496;border-color:#117a8b}.btn-info.focus,.btn-info:focus{box-shadow:0 0 0 .2rem rgba(58,176,195,.5)}.btn-info.disabled,.btn-info:disabled{color:#fff;background-color:#17a2b8;border-color:#17a2b8}.btn-info:not(:disabled):not(.disabled).active,.btn-info:not(:disabled):not(.disabled):active,.show>.btn-info.dropdown-toggle{color:#fff;background-color:#117a8b;border-color:#10707f}.btn-info:not(:disabled):not(.disabled).active:focus,.btn-info:not(:disabled):not(.disabled):active:focus,.show>.btn-info.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(58,176,195,.5)}.btn-warning{color:#212529;background-color:#ffc107;border-color:#ffc107}.btn-warning.focus,.btn-warning:focus,.btn-warning:hover{color:#212529;background-color:#e0a800;border-color:#d39e00}.btn-warning.focus,.btn-warning:focus{box-shadow:0 0 0 .2rem rgba(222,170,12,.5)}.btn-warning.disabled,.btn-warning:disabled{color:#212529;background-color:#ffc107;border-color:#ffc107}.btn-warning:not(:disabled):not(.disabled).active,.btn-warning:not(:disabled):not(.disabled):active,.show>.btn-warning.dropdown-toggle{color:#212529;background-color:#d39e00;border-color:#c69500}.btn-warning:not(:disabled):not(.disabled).active:focus,.btn-warning:not(:disabled):not(.disabled):active:focus,.show>.btn-warning.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(222,170,12,.5)}.btn-danger{color:#fff;background-color:#dc3545;border-color:#dc3545}.btn-danger.focus,.btn-danger:focus,.btn-danger:hover{color:#fff;background-color:#c82333;border-color:#bd2130}.btn-danger.focus,.btn-danger:focus{box-shadow:0 0 0 .2rem rgba(225,83,97,.5)}.btn-danger.disabled,.btn-danger:disabled{color:#fff;background-color:#dc3545;border-color:#dc3545}.btn-danger:not(:disabled):not(.disabled).active,.btn-danger:not(:disabled):not(.disabled):active,.show>.btn-danger.dropdown-toggle{color:#fff;background-color:#bd2130;border-color:#b21f2d}.btn-danger:not(:disabled):not(.disabled).active:focus,.btn-danger:not(:disabled):not(.disabled):active:focus,.show>.btn-danger.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(225,83,97,.5)}.btn-light{color:#212529;background-color:#f8f9fa;border-color:#f8f9fa}.btn-light.focus,.btn-light:focus,.btn-light:hover{color:#212529;background-color:#e2e6ea;border-color:#dae0e5}.btn-light.focus,.btn-light:focus{box-shadow:0 0 0 .2rem rgba(216,217,219,.5)}.btn-light.disabled,.btn-light:disabled{color:#212529;background-color:#f8f9fa;border-color:#f8f9fa}.btn-light:not(:disabled):not(.disabled).active,.btn-light:not(:disabled):not(.disabled):active,.show>.btn-light.dropdown-toggle{color:#212529;background-color:#dae0e5;border-color:#d3d9df}.btn-light:not(:disabled):not(.disabled).active:focus,.btn-light:not(:disabled):not(.disabled):active:focus,.show>.btn-light.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(216,217,219,.5)}.btn-dark{color:#fff;background-color:#343a40;border-color:#343a40}.btn-dark.focus,.btn-dark:focus,.btn-dark:hover{color:#fff;background-color:#23272b;border-color:#1d2124}.btn-dark.focus,.btn-dark:focus{box-shadow:0 0 0 .2rem rgba(82,88,93,.5)}.btn-dark.disabled,.btn-dark:disabled{color:#fff;background-color:#343a40;border-color:#343a40}.btn-dark:not(:disabled):not(.disabled).active,.btn-dark:not(:disabled):not(.disabled):active,.show>.btn-dark.dropdown-toggle{color:#fff;background-color:#1d2124;border-color:#171a1d}.btn-dark:not(:disabled):not(.disabled).active:focus,.btn-dark:not(:disabled):not(.disabled):active:focus,.show>.btn-dark.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(82,88,93,.5)}.btn-outline-primary{color:#007bff;border-color:#007bff}.btn-outline-primary:hover{color:#fff;background-color:#007bff;border-color:#007bff}.btn-outline-primary.focus,.btn-outline-primary:focus{box-shadow:0 0 0 .2rem rgba(0,123,255,.5)}.btn-outline-primary.disabled,.btn-outline-primary:disabled{color:#007bff;background-color:transparent}.btn-outline-primary:not(:disabled):not(.disabled).active,.btn-outline-primary:not(:disabled):not(.disabled):active,.show>.btn-outline-primary.dropdown-toggle{color:#fff;background-color:#007bff;border-color:#007bff}.btn-outline-primary:not(:disabled):not(.disabled).active:focus,.btn-outline-primary:not(:disabled):not(.disabled):active:focus,.show>.btn-outline-primary.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(0,123,255,.5)}.btn-outline-secondary{color:#6c757d;border-color:#6c757d}.btn-outline-secondary:hover{color:#fff;background-color:#6c757d;border-color:#6c757d}.btn-outline-secondary.focus,.btn-outline-secondary:focus{box-shadow:0 0 0 .2rem rgba(108,117,125,.5)}.btn-outline-secondary.disabled,.btn-outline-secondary:disabled{color:#6c757d;background-color:transparent}.btn-outline-secondary:not(:disabled):not(.disabled).active,.btn-outline-secondary:not(:disabled):not(.disabled):active,.show>.btn-outline-secondary.dropdown-toggle{color:#fff;background-color:#6c757d;border-color:#6c757d}.btn-outline-secondary:not(:disabled):not(.disabled).active:focus,.btn-outline-secondary:not(:disabled):not(.disabled):active:focus,.show>.btn-outline-secondary.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(108,117,125,.5)}.btn-outline-success{color:#28a745;border-color:#28a745}.btn-outline-success:hover{color:#fff;background-color:#28a745;border-color:#28a745}.btn-outline-success.focus,.btn-outline-success:focus{box-shadow:0 0 0 .2rem rgba(40,167,69,.5)}.btn-outline-success.disabled,.btn-outline-success:disabled{color:#28a745;background-color:transparent}.btn-outline-success:not(:disabled):not(.disabled).active,.btn-outline-success:not(:disabled):not(.disabled):active,.show>.btn-outline-success.dropdown-toggle{color:#fff;background-color:#28a745;border-color:#28a745}.btn-outline-success:not(:disabled):not(.disabled).active:focus,.btn-outline-success:not(:disabled):not(.disabled):active:focus,.show>.btn-outline-success.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(40,167,69,.5)}.btn-outline-info{color:#17a2b8;border-color:#17a2b8}.btn-outline-info:hover{color:#fff;background-color:#17a2b8;border-color:#17a2b8}.btn-outline-info.focus,.btn-outline-info:focus{box-shadow:0 0 0 .2rem rgba(23,162,184,.5)}.btn-outline-info.disabled,.btn-outline-info:disabled{color:#17a2b8;background-color:transparent}.btn-outline-info:not(:disabled):not(.disabled).active,.btn-outline-info:not(:disabled):not(.disabled):active,.show>.btn-outline-info.dropdown-toggle{color:#fff;background-color:#17a2b8;border-color:#17a2b8}.btn-outline-info:not(:disabled):not(.disabled).active:focus,.btn-outline-info:not(:disabled):not(.disabled):active:focus,.show>.btn-outline-info.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(23,162,184,.5)}.btn-outline-warning{color:#ffc107;border-color:#ffc107}.btn-outline-warning:hover{color:#212529;background-color:#ffc107;border-color:#ffc107}.btn-outline-warning.focus,.btn-outline-warning:focus{box-shadow:0 0 0 .2rem rgba(255,193,7,.5)}.btn-outline-warning.disabled,.btn-outline-warning:disabled{color:#ffc107;background-color:transparent}.btn-outline-warning:not(:disabled):not(.disabled).active,.btn-outline-warning:not(:disabled):not(.disabled):active,.show>.btn-outline-warning.dropdown-toggle{color:#212529;background-color:#ffc107;border-color:#ffc107}.btn-outline-warning:not(:disabled):not(.disabled).active:focus,.btn-outline-warning:not(:disabled):not(.disabled):active:focus,.show>.btn-outline-warning.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(255,193,7,.5)}.btn-outline-danger{color:#dc3545;border-color:#dc3545}.btn-outline-danger:hover{color:#fff;background-color:#dc3545;border-color:#dc3545}.btn-outline-danger.focus,.btn-outline-danger:focus{box-shadow:0 0 0 .2rem rgba(220,53,69,.5)}.btn-outline-danger.disabled,.btn-outline-danger:disabled{color:#dc3545;background-color:transparent}.btn-outline-danger:not(:disabled):not(.disabled).active,.btn-outline-danger:not(:disabled):not(.disabled):active,.show>.btn-outline-danger.dropdown-toggle{color:#fff;background-color:#dc3545;border-color:#dc3545}.btn-outline-danger:not(:disabled):not(.disabled).active:focus,.btn-outline-danger:not(:disabled):not(.disabled):active:focus,.show>.btn-outline-danger.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(220,53,69,.5)}.btn-outline-light{color:#f8f9fa;border-color:#f8f9fa}.btn-outline-light:hover{color:#212529;background-color:#f8f9fa;border-color:#f8f9fa}.btn-outline-light.focus,.btn-outline-light:focus{box-shadow:0 0 0 .2rem rgba(248,249,250,.5)}.btn-outline-light.disabled,.btn-outline-light:disabled{color:#f8f9fa;background-color:transparent}.btn-outline-light:not(:disabled):not(.disabled).active,.btn-outline-light:not(:disabled):not(.disabled):active,.show>.btn-outline-light.dropdown-toggle{color:#212529;background-color:#f8f9fa;border-color:#f8f9fa}.btn-outline-light:not(:disabled):not(.disabled).active:focus,.btn-outline-light:not(:disabled):not(.disabled):active:focus,.show>.btn-outline-light.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(248,249,250,.5)}.btn-outline-dark{color:#343a40;border-color:#343a40}.btn-outline-dark:hover{color:#fff;background-color:#343a40;border-color:#343a40}.btn-outline-dark.focus,.btn-outline-dark:focus{box-shadow:0 0 0 .2rem rgba(52,58,64,.5)}.btn-outline-dark.disabled,.btn-outline-dark:disabled{color:#343a40;background-color:transparent}.btn-outline-dark:not(:disabled):not(.disabled).active,.btn-outline-dark:not(:disabled):not(.disabled):active,.show>.btn-outline-dark.dropdown-toggle{color:#fff;background-color:#343a40;border-color:#343a40}.btn-outline-dark:not(:disabled):not(.disabled).active:focus,.btn-outline-dark:not(:disabled):not(.disabled):active:focus,.show>.btn-outline-dark.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(52,58,64,.5)}.btn-link{font-weight:400;color:#007bff;text-decoration:none}.btn-link:hover{color:#0056b3}.btn-link.focus,.btn-link:focus,.btn-link:hover{text-decoration:underline}.btn-link.disabled,.btn-link:disabled{color:#6c757d;pointer-events:none}.btn-lg{padding:.5rem 1rem;font-size:1.25rem;line-height:1.5;border-radius:.3rem}.btn-sm{padding:.25rem .5rem;font-size:.875rem;line-height:1.5;border-radius:.2rem}.btn-block{display:block;width:100%}.btn-block+.btn-block{margin-top:.5rem}input[type=button].btn-block,input[type=reset].btn-block,input[type=submit].btn-block{width:100%}.fade{transition:opacity .15s linear}@media (prefers-reduced-motion:reduce){.fade{transition:none}}.fade:not(.show){opacity:0}.collapse:not(.show){display:none}.collapsing{position:relative;height:0;overflow:hidden;transition:height .35s ease}@media (prefers-reduced-motion:reduce){.collapsing{transition:none}}.dropdown,.dropleft,.dropright,.dropup{position:relative}.dropdown-toggle{white-space:nowrap}.dropdown-toggle:after{display:inline-block;margin-left:.255em;vertical-align:.255em;content:"";border-top:.3em solid;border-right:.3em solid transparent;border-bottom:0;border-left:.3em solid transparent}.dropdown-toggle:empty:after{margin-left:0}.dropdown-menu{position:absolute;top:100%;left:0;z-index:1000;display:none;float:left;min-width:10rem;padding:24px 0;margin:0;font-size:1rem;color:#212529;text-align:left;list-style:none;background-color:#fff;background-clip:padding-box;border:0 solid rgba(0,0,0,.15);border-radius:0}.dropdown-menu-left{right:auto;left:0}.dropdown-menu-right{right:0;left:auto}@media (min-width:576px){.dropdown-menu-sm-left{right:auto;left:0}.dropdown-menu-sm-right{right:0;left:auto}}@media (min-width:768px){.dropdown-menu-md-left{right:auto;left:0}.dropdown-menu-md-right{right:0;left:auto}}@media (min-width:992px){.dropdown-menu-lg-left{right:auto;left:0}.dropdown-menu-lg-right{right:0;left:auto}}@media (min-width:1200px){.dropdown-menu-xl-left{right:auto;left:0}.dropdown-menu-xl-right{right:0;left:auto}}.dropup .dropdown-menu{top:auto;bottom:100%;margin-top:0;margin-bottom:0}.dropup .dropdown-toggle:after{display:inline-block;margin-left:.255em;vertical-align:.255em;content:"";border-top:0;border-right:.3em solid transparent;border-bottom:.3em solid;border-left:.3em solid transparent}.dropup .dropdown-toggle:empty:after{margin-left:0}.dropright .dropdown-menu{top:0;right:auto;left:100%;margin-top:0;margin-left:0}.dropright .dropdown-toggle:after{display:inline-block;margin-left:.255em;vertical-align:.255em;content:"";border-top:.3em solid transparent;border-right:0;border-bottom:.3em solid transparent;border-left:.3em solid}.dropright .dropdown-toggle:empty:after{margin-left:0}.dropright .dropdown-toggle:after{vertical-align:0}.dropleft .dropdown-menu{top:0;right:100%;left:auto;margin-top:0;margin-right:0}.dropleft .dropdown-toggle:after{display:inline-block;margin-left:.255em;vertical-align:.255em;content:"";display:none}.dropleft .dropdown-toggle:before{display:inline-block;margin-right:.255em;vertical-align:.255em;content:"";border-top:.3em solid transparent;border-right:.3em solid;border-bottom:.3em solid transparent}.dropleft .dropdown-toggle:empty:after{margin-left:0}.dropleft .dropdown-toggle:before{vertical-align:0}.dropdown-menu[x-placement^=bottom],.dropdown-menu[x-placement^=left],.dropdown-menu[x-placement^=right],.dropdown-menu[x-placement^=top]{right:auto;bottom:auto}.dropdown-divider{height:0;margin:.5rem 0;overflow:hidden;border-top:1px solid #e9ecef}.dropdown-item{display:block;width:100%;padding:.25rem 1.5rem;clear:both;font-weight:400;color:#797f90;text-align:inherit;white-space:nowrap;background-color:transparent;border:0}.dropdown-item:focus,.dropdown-item:hover{color:#ff6f00;text-decoration:none;background-color:transparent}.dropdown-item.active,.dropdown-item:active{color:#fff;text-decoration:none;background-color:#007bff}.dropdown-item.disabled,.dropdown-item:disabled{color:#6c757d;pointer-events:none;background-color:transparent}.dropdown-menu.show{display:block}.dropdown-header{display:block;padding:24px 1.5rem;margin-bottom:0;font-size:.875rem;color:#6c757d;white-space:nowrap}.dropdown-item-text{display:block;padding:.25rem 1.5rem;color:#797f90}.navbar{position:relative;padding:0 1rem}.navbar,.navbar .container,.navbar .container-fluid,.navbar .container-lg,.navbar .container-md,.navbar .container-sm,.navbar .container-xl{display:flex;flex-wrap:wrap;align-items:center;justify-content:space-between}.navbar-brand{display:inline-block;padding-top:-.1875rem;padding-bottom:-.1875rem;margin-right:1rem;font-size:1.25rem;line-height:inherit;white-space:nowrap}.navbar-brand:focus,.navbar-brand:hover{text-decoration:none}.navbar-nav{display:flex;flex-direction:column;padding-left:0;margin-bottom:0;list-style:none}.navbar-nav .nav-link{padding-right:0;padding-left:0}.navbar-nav .dropdown-menu{position:static;float:none}.navbar-text{display:inline-block;padding-top:0;padding-bottom:0}.navbar-collapse{flex-basis:100%;flex-grow:1;align-items:center}.navbar-toggler{padding:.25rem .75rem;font-size:1.25rem;line-height:1;background-color:transparent;border:1px solid transparent;border-radius:.25rem}.navbar-toggler:focus,.navbar-toggler:hover{text-decoration:none}.navbar-toggler-icon{display:inline-block;width:1.5em;height:1.5em;vertical-align:middle;content:"";background:no-repeat 50%;background-size:100% 100%}@media (max-width:575.98px){.navbar-expand-sm>.container,.navbar-expand-sm>.container-fluid,.navbar-expand-sm>.container-lg,.navbar-expand-sm>.container-md,.navbar-expand-sm>.container-sm,.navbar-expand-sm>.container-xl{padding-right:0;padding-left:0}}@media (min-width:576px){.navbar-expand-sm{flex-flow:row nowrap;justify-content:flex-start}.navbar-expand-sm .navbar-nav{flex-direction:row}.navbar-expand-sm .navbar-nav .dropdown-menu{position:absolute}.navbar-expand-sm .navbar-nav .nav-link{padding-right:0;padding-left:0}.navbar-expand-sm>.container,.navbar-expand-sm>.container-fluid,.navbar-expand-sm>.container-lg,.navbar-expand-sm>.container-md,.navbar-expand-sm>.container-sm,.navbar-expand-sm>.container-xl{flex-wrap:nowrap}.navbar-expand-sm .navbar-collapse{display:flex!important;flex-basis:auto}.navbar-expand-sm .navbar-toggler{display:none}}@media (max-width:767.98px){.navbar-expand-md>.container,.navbar-expand-md>.container-fluid,.navbar-expand-md>.container-lg,.navbar-expand-md>.container-md,.navbar-expand-md>.container-sm,.navbar-expand-md>.container-xl{padding-right:0;padding-left:0}}@media (min-width:768px){.navbar-expand-md{flex-flow:row nowrap;justify-content:flex-start}.navbar-expand-md .navbar-nav{flex-direction:row}.navbar-expand-md .navbar-nav .dropdown-menu{position:absolute}.navbar-expand-md .navbar-nav .nav-link{padding-right:0;padding-left:0}.navbar-expand-md>.container,.navbar-expand-md>.container-fluid,.navbar-expand-md>.container-lg,.navbar-expand-md>.container-md,.navbar-expand-md>.container-sm,.navbar-expand-md>.container-xl{flex-wrap:nowrap}.navbar-expand-md .navbar-collapse{display:flex!important;flex-basis:auto}.navbar-expand-md .navbar-toggler{display:none}}@media (max-width:991.98px){.navbar-expand-lg>.container,.navbar-expand-lg>.container-fluid,.navbar-expand-lg>.container-lg,.navbar-expand-lg>.container-md,.navbar-expand-lg>.container-sm,.navbar-expand-lg>.container-xl{padding-right:0;padding-left:0}}@media (min-width:992px){.navbar-expand-lg{flex-flow:row nowrap;justify-content:flex-start}.navbar-expand-lg .navbar-nav{flex-direction:row}.navbar-expand-lg .navbar-nav .dropdown-menu{position:absolute}.navbar-expand-lg .navbar-nav .nav-link{padding-right:0;padding-left:0}.navbar-expand-lg>.container,.navbar-expand-lg>.container-fluid,.navbar-expand-lg>.container-lg,.navbar-expand-lg>.container-md,.navbar-expand-lg>.container-sm,.navbar-expand-lg>.container-xl{flex-wrap:nowrap}.navbar-expand-lg .navbar-collapse{display:flex!important;flex-basis:auto}.navbar-expand-lg .navbar-toggler{display:none}}@media (max-width:1199.98px){.navbar-expand-xl>.container,.navbar-expand-xl>.container-fluid,.navbar-expand-xl>.container-lg,.navbar-expand-xl>.container-md,.navbar-expand-xl>.container-sm,.navbar-expand-xl>.container-xl{padding-right:0;padding-left:0}}@media (min-width:1200px){.navbar-expand-xl{flex-flow:row nowrap;justify-content:flex-start}.navbar-expand-xl .navbar-nav{flex-direction:row}.navbar-expand-xl .navbar-nav .dropdown-menu{position:absolute}.navbar-expand-xl .navbar-nav .nav-link{padding-right:0;padding-left:0}.navbar-expand-xl>.container,.navbar-expand-xl>.container-fluid,.navbar-expand-xl>.container-lg,.navbar-expand-xl>.container-md,.navbar-expand-xl>.container-sm,.navbar-expand-xl>.container-xl{flex-wrap:nowrap}.navbar-expand-xl .navbar-collapse{display:flex!important;flex-basis:auto}.navbar-expand-xl .navbar-toggler{display:none}}.navbar-expand{flex-flow:row nowrap;justify-content:flex-start}.navbar-expand>.container,.navbar-expand>.container-fluid,.navbar-expand>.container-lg,.navbar-expand>.container-md,.navbar-expand>.container-sm,.navbar-expand>.container-xl{padding-right:0;padding-left:0}.navbar-expand .navbar-nav{flex-direction:row}.navbar-expand .navbar-nav .dropdown-menu{position:absolute}.navbar-expand .navbar-nav .nav-link{padding-right:0;padding-left:0}.navbar-expand>.container,.navbar-expand>.container-fluid,.navbar-expand>.container-lg,.navbar-expand>.container-md,.navbar-expand>.container-sm,.navbar-expand>.container-xl{flex-wrap:nowrap}.navbar-expand .navbar-collapse{display:flex!important;flex-basis:auto}.navbar-expand .navbar-toggler{display:none}.navbar-light .navbar-brand,.navbar-light .navbar-brand:focus,.navbar-light .navbar-brand:hover{color:rgba(0,0,0,.9)}.navbar-light .navbar-nav .nav-link{color:rgba(0,0,0,.5)}.navbar-light .navbar-nav .nav-link:focus,.navbar-light .navbar-nav .nav-link:hover{color:rgba(0,0,0,.7)}.navbar-light .navbar-nav .nav-link.disabled{color:rgba(0,0,0,.3)}.navbar-light .navbar-nav .active>.nav-link,.navbar-light .navbar-nav .nav-link.active,.navbar-light .navbar-nav .nav-link.show,.navbar-light .navbar-nav .show>.nav-link{color:rgba(0,0,0,.9)}.navbar-light .navbar-toggler{color:rgba(0,0,0,.5);border-color:rgba(0,0,0,.1)}.navbar-light .navbar-toggler-icon{background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='30' height='30'%3E%3Cpath stroke='rgba(0, 0, 0, 0.5)' stroke-linecap='round' stroke-miterlimit='10' stroke-width='2' d='M4 7h22M4 15h22M4 23h22'/%3E%3C/svg%3E")}.navbar-light .navbar-text{color:rgba(0,0,0,.5)}.navbar-light .navbar-text a,.navbar-light .navbar-text a:focus,.navbar-light .navbar-text a:hover{color:rgba(0,0,0,.9)}.navbar-dark .navbar-brand,.navbar-dark .navbar-brand:focus,.navbar-dark .navbar-brand:hover{color:#fff}.navbar-dark .navbar-nav .nav-link{color:hsla(0,0%,100%,.7)}.navbar-dark .navbar-nav .nav-link:focus,.navbar-dark .navbar-nav .nav-link:hover{color:hsla(0,0%,100%,.75)}.navbar-dark .navbar-nav .nav-link.disabled{color:hsla(0,0%,100%,.25)}.navbar-dark .navbar-nav .active>.nav-link,.navbar-dark .navbar-nav .nav-link.active,.navbar-dark .navbar-nav .nav-link.show,.navbar-dark .navbar-nav .show>.nav-link{color:#fff}.navbar-dark .navbar-toggler{color:hsla(0,0%,100%,.7);border-color:hsla(0,0%,100%,.1)}.navbar-dark .navbar-toggler-icon{background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='30' height='30'%3E%3Cpath stroke='rgba(255, 255, 255, 0.7)' stroke-linecap='round' stroke-miterlimit='10' stroke-width='2' d='M4 7h22M4 15h22M4 23h22'/%3E%3C/svg%3E")}.navbar-dark .navbar-text{color:hsla(0,0%,100%,.7)}.navbar-dark .navbar-text a,.navbar-dark .navbar-text a:focus,.navbar-dark .navbar-text a:hover{color:#fff}.nav{display:flex;flex-wrap:wrap;padding-left:0;margin-bottom:0;list-style:none}.nav-link{display:block;padding:0 1rem}.nav-link:focus,.nav-link:hover{text-decoration:none}.nav-link.disabled{color:#6c757d;pointer-events:none;cursor:default}.nav-tabs{border-bottom:1px solid #dee2e6}.nav-tabs .nav-item{margin-bottom:-1px}.nav-tabs .nav-link{border:1px solid transparent;border-top-left-radius:.25rem;border-top-right-radius:.25rem}.nav-tabs .nav-link:focus,.nav-tabs .nav-link:hover{border-color:#e9ecef #e9ecef #dee2e6}.nav-tabs .nav-link.disabled{color:#6c757d;background-color:transparent;border-color:transparent}.nav-tabs .nav-item.show .nav-link,.nav-tabs .nav-link.active{color:#495057;background-color:#eceeef;border-color:#dee2e6 #dee2e6 #eceeef}.nav-tabs .dropdown-menu{margin-top:-1px;border-top-left-radius:0;border-top-right-radius:0}.nav-pills .nav-link{border-radius:.25rem}.nav-pills .nav-link.active,.nav-pills .show>.nav-link{color:#fff;background-color:#007bff}.nav-fill .nav-item,.nav-fill>.nav-link{flex:1 1 auto;text-align:center}.nav-justified .nav-item,.nav-justified>.nav-link{flex-basis:0;flex-grow:1;text-align:center}.tab-content>.tab-pane{display:none}.tab-content>.active{display:block}.pbTable,.table{width:100%;margin-bottom:1rem;color:#797f90}.pbTable td,.pbTable th,.table td,.table th{padding:.75rem;vertical-align:top;border-top:1px solid #dddfe3}.pbTable thead th,.table thead th{vertical-align:bottom;border-bottom:2px solid #dddfe3}.pbTable tbody+tbody,.table tbody+tbody{border-top:2px solid #dddfe3}.table-sm td,.table-sm th{padding:.3rem}.pbTable,.pbTable td,.pbTable th,.table-bordered,.table-bordered td,.table-bordered th{border:1px solid #dddfe3}.pbTable thead td,.pbTable thead th,.table-bordered thead td,.table-bordered thead th{border-bottom-width:2px}.table-borderless tbody+tbody,.table-borderless td,.table-borderless th,.table-borderless thead th{border:0}.pbTable tbody tr:nth-of-type(odd),.table-striped tbody tr:nth-of-type(odd){background-color:#f8f9f9}.table-hover tbody tr:hover{color:#797f90;background-color:rgba(0,0,0,.075)}.table-primary,.table-primary>td,.table-primary>th{background-color:#b8daff}.table-primary tbody+tbody,.table-primary td,.table-primary th,.table-primary thead th{border-color:#7abaff}.table-hover .table-primary:hover,.table-hover .table-primary:hover>td,.table-hover .table-primary:hover>th{background-color:#9fcdff}.table-secondary,.table-secondary>td,.table-secondary>th{background-color:#d6d8db}.table-secondary tbody+tbody,.table-secondary td,.table-secondary th,.table-secondary thead th{border-color:#b3b7bb}.table-hover .table-secondary:hover,.table-hover .table-secondary:hover>td,.table-hover .table-secondary:hover>th{background-color:#c8cbcf}.table-success,.table-success>td,.table-success>th{background-color:#c3e6cb}.table-success tbody+tbody,.table-success td,.table-success th,.table-success thead th{border-color:#8fd19e}.table-hover .table-success:hover,.table-hover .table-success:hover>td,.table-hover .table-success:hover>th{background-color:#b1dfbb}.table-info,.table-info>td,.table-info>th{background-color:#bee5eb}.table-info tbody+tbody,.table-info td,.table-info th,.table-info thead th{border-color:#86cfda}.table-hover .table-info:hover,.table-hover .table-info:hover>td,.table-hover .table-info:hover>th{background-color:#abdde5}.table-warning,.table-warning>td,.table-warning>th{background-color:#ffeeba}.table-warning tbody+tbody,.table-warning td,.table-warning th,.table-warning thead th{border-color:#ffdf7e}.table-hover .table-warning:hover,.table-hover .table-warning:hover>td,.table-hover .table-warning:hover>th{background-color:#ffe8a1}.table-danger,.table-danger>td,.table-danger>th{background-color:#f5c6cb}.table-danger tbody+tbody,.table-danger td,.table-danger th,.table-danger thead th{border-color:#ed969e}.table-hover .table-danger:hover,.table-hover .table-danger:hover>td,.table-hover .table-danger:hover>th{background-color:#f1b0b7}.table-light,.table-light>td,.table-light>th{background-color:#fdfdfe}.table-light tbody+tbody,.table-light td,.table-light th,.table-light thead th{border-color:#fbfcfc}.table-hover .table-light:hover,.table-hover .table-light:hover>td,.table-hover .table-light:hover>th{background-color:#ececf6}.table-dark,.table-dark>td,.table-dark>th{background-color:#c6c8ca}.table-dark tbody+tbody,.table-dark td,.table-dark th,.table-dark thead th{border-color:#95999c}.table-hover .table-dark:hover,.table-hover .table-dark:hover>td,.table-hover .table-dark:hover>th{background-color:#b9bbbe}.table-active,.table-active>td,.table-active>th,.table-hover .table-active:hover,.table-hover .table-active:hover>td,.table-hover .table-active:hover>th{background-color:rgba(0,0,0,.075)}.pbTable .thead-dark th,.table .thead-dark th{color:#fff;background-color:#343a40;border-color:#454d55}.pbTable .thead-light th,.table .thead-light th{color:#495057;background-color:#e9ecef;border-color:#dddfe3}.table-dark{color:#fff;background-color:#343a40}.table-dark td,.table-dark th,.table-dark thead th{border-color:#454d55}.table-dark.pbTable,.table-dark.table-bordered{border:0}.table-dark.pbTable tbody tr:nth-of-type(odd),.table-dark.table-striped tbody tr:nth-of-type(odd){background-color:hsla(0,0%,100%,.05)}.table-dark.table-hover tbody tr:hover{color:#fff;background-color:hsla(0,0%,100%,.075)}@media (max-width:575.98px){.table-responsive-sm{display:block;width:100%;overflow-x:auto;-webkit-overflow-scrolling:touch}.table-responsive-sm>.pbTable,.table-responsive-sm>.table-bordered{border:0}}@media (max-width:767.98px){.table-responsive-md{display:block;width:100%;overflow-x:auto;-webkit-overflow-scrolling:touch}.table-responsive-md>.pbTable,.table-responsive-md>.table-bordered{border:0}}@media (max-width:991.98px){.table-responsive-lg{display:block;width:100%;overflow-x:auto;-webkit-overflow-scrolling:touch}.table-responsive-lg>.pbTable,.table-responsive-lg>.table-bordered{border:0}}@media (max-width:1199.98px){.table-responsive-xl{display:block;width:100%;overflow-x:auto;-webkit-overflow-scrolling:touch}.table-responsive-xl>.pbTable,.table-responsive-xl>.table-bordered{border:0}}.table-responsive{display:block;width:100%;overflow-x:auto;-webkit-overflow-scrolling:touch}.table-responsive>.pbTable,.table-responsive>.table-bordered{border:0}.card{position:relative;display:flex;flex-direction:column;min-width:0;word-wrap:break-word;background-color:#fff;background-clip:border-box;border:1px solid rgba(0,0,0,.125);border-radius:0}.card>hr{margin-right:0;margin-left:0}.card>.list-group{border-top:inherit;border-bottom:inherit}.card>.list-group:first-child{border-top-width:0;border-top-left-radius:0;border-top-right-radius:0}.card>.list-group:last-child{border-bottom-width:0;border-bottom-right-radius:0;border-bottom-left-radius:0}.card>.card-header+.list-group,.card>.list-group+.card-footer{border-top:0}.card-body{flex:1 1 auto;min-height:1px;padding:30px}.card-title{margin-bottom:.75rem}.card-subtitle{margin-top:-.375rem}.card-subtitle,.card-text:last-child{margin-bottom:0}.card-link:hover{text-decoration:none}.card-link+.card-link{margin-left:30px}.card-header{padding:.75rem 30px;margin-bottom:0;background-color:rgba(0,0,0,.03);border-bottom:1px solid rgba(0,0,0,.125)}.card-header:first-child{border-radius:0 0 0 0}.card-footer{padding:.75rem 30px;background-color:rgba(0,0,0,.03);border-top:1px solid rgba(0,0,0,.125)}.card-footer:last-child{border-radius:0 0 0 0}.card-header-tabs{margin-bottom:-.75rem;border-bottom:0}.card-header-pills,.card-header-tabs{margin-right:-15px;margin-left:-15px}.card-img-overlay{position:absolute;top:0;right:0;bottom:0;left:0;padding:1.25rem;border-radius:0}.card-img,.card-img-bottom,.card-img-top{flex-shrink:0;width:100%}.card-img,.card-img-top{border-top-left-radius:0;border-top-right-radius:0}.card-img,.card-img-bottom{border-bottom-right-radius:0;border-bottom-left-radius:0}.card-deck .card{margin-bottom:10px}@media (min-width:576px){.card-deck{display:flex;flex-flow:row wrap;margin-right:-10px;margin-left:-10px}.card-deck .card{flex:1 0 0%;margin-right:10px;margin-bottom:0;margin-left:10px}}.card-group>.card{margin-bottom:10px}@media (min-width:576px){.card-group{display:flex;flex-flow:row wrap}.card-group>.card{flex:1 0 0%;margin-bottom:0}.card-group>.card+.card{margin-left:0;border-left:0}.card-group>.card:not(:last-child){border-top-right-radius:0;border-bottom-right-radius:0}.card-group>.card:not(:last-child) .card-header,.card-group>.card:not(:last-child) .card-img-top{border-top-right-radius:0}.card-group>.card:not(:last-child) .card-footer,.card-group>.card:not(:last-child) .card-img-bottom{border-bottom-right-radius:0}.card-group>.card:not(:first-child){border-top-left-radius:0;border-bottom-left-radius:0}.card-group>.card:not(:first-child) .card-header,.card-group>.card:not(:first-child) .card-img-top{border-top-left-radius:0}.card-group>.card:not(:first-child) .card-footer,.card-group>.card:not(:first-child) .card-img-bottom{border-bottom-left-radius:0}}.card-columns .card{margin-bottom:.75rem}@media (min-width:576px){.card-columns{-moz-column-count:3;column-count:3;-moz-column-gap:1.25rem;column-gap:1.25rem;orphans:1;widows:1}.card-columns .card{display:inline-block;width:100%}}.accordion{overflow-anchor:none}.accordion>.card{overflow:hidden}.accordion>.card:not(:last-of-type){border-bottom:0;border-bottom-right-radius:0;border-bottom-left-radius:0}.accordion>.card:not(:first-of-type){border-top-left-radius:0;border-top-right-radius:0}.accordion>.card>.card-header{border-radius:0;margin-bottom:-1px}code{font-size:87.5%;color:#e83e8c;word-wrap:break-word}a>code{color:inherit}kbd{padding:.2rem .4rem;font-size:87.5%;color:#fff;background-color:#212529;border-radius:.2rem}kbd kbd{padding:0;font-size:100%;font-weight:700}pre{display:block;font-size:87.5%;color:#212529}pre code{font-size:inherit;color:inherit;word-break:normal}.pre-scrollable{max-height:340px;overflow-y:scroll}.alert,.pb-alert{position:relative;padding:.75rem 1.25rem;margin-bottom:1rem;border:1px solid transparent;border-radius:.25rem}.alert-heading{color:inherit}.alert-link{font-weight:700}.alert-dismissible{padding-right:4rem}.alert-dismissible .close{position:absolute;top:0;right:0;z-index:2;padding:.75rem 1.25rem;color:inherit}.alert-primary{color:#004085;background-color:#cce5ff;border-color:#b8daff}.alert-primary hr{border-top-color:#9fcdff}.alert-primary .alert-link{color:#002752}.alert-secondary{color:#383d41;background-color:#e2e3e5;border-color:#d6d8db}.alert-secondary hr{border-top-color:#c8cbcf}.alert-secondary .alert-link{color:#202326}.alert-success{color:#155724;background-color:#d4edda;border-color:#c3e6cb}.alert-success hr{border-top-color:#b1dfbb}.alert-success .alert-link{color:#0b2e13}.alert-info,.pb-alert-tip{color:#0c5460;background-color:#d1ecf1;border-color:#bee5eb}.alert-info hr,.pb-alert-tip hr{border-top-color:#abdde5}.alert-info .alert-link,.pb-alert-tip .alert-link{color:#062c33}.alert-warning,.pb-alert-warning{color:#856404;background-color:#fff3cd;border-color:#ffeeba}.alert-warning hr,.pb-alert-warning hr{border-top-color:#ffe8a1}.alert-warning .alert-link,.pb-alert-warning .alert-link{color:#533f03}.alert-danger,.pb-alert-important{color:#721c24;background-color:#f8d7da;border-color:#f5c6cb}.alert-danger hr,.pb-alert-important hr{border-top-color:#f1b0b7}.alert-danger .alert-link,.pb-alert-important .alert-link{color:#491217}.alert-light{color:#818182;background-color:#fefefe;border-color:#fdfdfe}.alert-light hr{border-top-color:#ececf6}.alert-light .alert-link{color:#686868}.alert-dark{color:#1b1e21;background-color:#d6d8d9;border-color:#c6c8ca}.alert-dark hr{border-top-color:#b9bbbe}.alert-dark .alert-link{color:#040505}.modal-open{overflow:hidden}.modal-open .modal{overflow-x:hidden;overflow-y:auto}.modal{position:fixed;top:0;left:0;z-index:1050;display:none;width:100%;height:100%;overflow:hidden;outline:0}.modal-dialog{position:relative;width:auto;margin:.5rem;pointer-events:none}.modal.fade .modal-dialog{transition:transform .3s ease-out;transform:translateY(-50px)}@media (prefers-reduced-motion:reduce){.modal.fade .modal-dialog{transition:none}}.modal.show .modal-dialog{transform:none}.modal.modal-static .modal-dialog{transform:scale(1.02)}.modal-dialog-scrollable{display:flex;max-height:calc(100% - 1rem)}.modal-dialog-scrollable .modal-content{max-height:calc(100vh - 1rem);overflow:hidden}.modal-dialog-scrollable .modal-footer,.modal-dialog-scrollable .modal-header{flex-shrink:0}.modal-dialog-scrollable .modal-body{overflow-y:auto}.modal-dialog-centered{display:flex;align-items:center;min-height:calc(100% - 1rem)}.modal-dialog-centered:before{display:block;height:calc(100vh - 1rem);height:-webkit-min-content;height:-moz-min-content;height:min-content;content:""}.modal-dialog-centered.modal-dialog-scrollable{flex-direction:column;justify-content:center;height:100%}.modal-dialog-centered.modal-dialog-scrollable .modal-content{max-height:none}.modal-dialog-centered.modal-dialog-scrollable:before{content:none}.modal-content{position:relative;display:flex;flex-direction:column;width:100%;pointer-events:auto;background-color:#fff;background-clip:padding-box;border:1px solid rgba(0,0,0,.2);border-radius:.3rem;outline:0}.modal-backdrop{position:fixed;top:0;left:0;z-index:1040;width:100vw;height:100vh;background-color:#000}.modal-backdrop.fade{opacity:0}.modal-backdrop.show{opacity:.5}.modal-header{display:flex;align-items:flex-start;justify-content:space-between;padding:1rem;border-bottom:1px solid #dee2e6;border-top-left-radius:calc(.3rem - 1px);border-top-right-radius:calc(.3rem - 1px)}.modal-header .close{padding:1rem;margin:-1rem -1rem -1rem auto}.modal-title{margin-bottom:0;line-height:1.5}.modal-body{position:relative;flex:1 1 auto;padding:1rem}.modal-footer{display:flex;flex-wrap:wrap;align-items:center;justify-content:flex-end;padding:.75rem;border-top:1px solid #dee2e6;border-bottom-right-radius:calc(.3rem - 1px);border-bottom-left-radius:calc(.3rem - 1px)}.modal-footer>*{margin:.25rem}.modal-scrollbar-measure{position:absolute;top:-9999px;width:50px;height:50px;overflow:scroll}@media (min-width:576px){.modal-dialog{max-width:500px;margin:1.75rem auto}.modal-dialog-scrollable{max-height:calc(100% - 3.5rem)}.modal-dialog-scrollable .modal-content{max-height:calc(100vh - 3.5rem)}.modal-dialog-centered{min-height:calc(100% - 3.5rem)}.modal-dialog-centered:before{height:calc(100vh - 3.5rem);height:-webkit-min-content;height:-moz-min-content;height:min-content}.modal-sm{max-width:300px}}@media (min-width:992px){.modal-lg,.modal-xl{max-width:800px}}@media (min-width:1200px){.modal-xl{max-width:1140px}}.align-baseline{vertical-align:baseline!important}.align-top{vertical-align:top!important}.align-middle{vertical-align:middle!important}.align-bottom{vertical-align:bottom!important}.align-text-bottom{vertical-align:text-bottom!important}.align-text-top{vertical-align:text-top!important}.bg-primary{background-color:#007bff!important}a.bg-primary:focus,a.bg-primary:hover,button.bg-primary:focus,button.bg-primary:hover{background-color:#0062cc!important}.bg-secondary{background-color:#6c757d!important}a.bg-secondary:focus,a.bg-secondary:hover,button.bg-secondary:focus,button.bg-secondary:hover{background-color:#545b62!important}.bg-success{background-color:#28a745!important}a.bg-success:focus,a.bg-success:hover,button.bg-success:focus,button.bg-success:hover{background-color:#1e7e34!important}.bg-info{background-color:#17a2b8!important}a.bg-info:focus,a.bg-info:hover,button.bg-info:focus,button.bg-info:hover{background-color:#117a8b!important}.bg-warning{background-color:#ffc107!important}a.bg-warning:focus,a.bg-warning:hover,button.bg-warning:focus,button.bg-warning:hover{background-color:#d39e00!important}.bg-danger{background-color:#dc3545!important}a.bg-danger:focus,a.bg-danger:hover,button.bg-danger:focus,button.bg-danger:hover{background-color:#bd2130!important}.bg-light{background-color:#f8f9fa!important}a.bg-light:focus,a.bg-light:hover,button.bg-light:focus,button.bg-light:hover{background-color:#dae0e5!important}.bg-dark{background-color:#343a40!important}a.bg-dark:focus,a.bg-dark:hover,button.bg-dark:focus,button.bg-dark:hover{background-color:#1d2124!important}.bg-white{background-color:#fff!important}.bg-transparent{background-color:transparent!important}.border{border:1px solid #dee2e6!important}.border-top{border-top:1px solid #dee2e6!important}.border-right{border-right:1px solid #dee2e6!important}.border-bottom{border-bottom:1px solid #dee2e6!important}.border-left{border-left:1px solid #dee2e6!important}.border-0{border:0!important}.border-top-0{border-top:0!important}.border-right-0{border-right:0!important}.border-bottom-0{border-bottom:0!important}.border-left-0{border-left:0!important}.border-primary{border-color:#007bff!important}.border-secondary{border-color:#6c757d!important}.border-success{border-color:#28a745!important}.border-info{border-color:#17a2b8!important}.border-warning{border-color:#ffc107!important}.border-danger{border-color:#dc3545!important}.border-light{border-color:#f8f9fa!important}.border-dark{border-color:#343a40!important}.border-white{border-color:#fff!important}.rounded-sm{border-radius:.2rem!important}.rounded{border-radius:.25rem!important}.rounded-top{border-top-left-radius:.25rem!important}.rounded-right,.rounded-top{border-top-right-radius:.25rem!important}.rounded-bottom,.rounded-right{border-bottom-right-radius:.25rem!important}.rounded-bottom,.rounded-left{border-bottom-left-radius:.25rem!important}.rounded-left{border-top-left-radius:.25rem!important}.rounded-lg{border-radius:.3rem!important}.rounded-circle{border-radius:50%!important}.rounded-pill{border-radius:50rem!important}.rounded-0{border-radius:0!important}.clearfix:after{display:block;clear:both;content:""}.d-none{display:none!important}.d-inline{display:inline!important}.d-inline-block{display:inline-block!important}.d-block{display:block!important}.d-table{display:table!important}.d-table-row{display:table-row!important}.d-table-cell{display:table-cell!important}.d-flex{display:flex!important}.d-inline-flex{display:inline-flex!important}@media (min-width:576px){.d-sm-none{display:none!important}.d-sm-inline{display:inline!important}.d-sm-inline-block{display:inline-block!important}.d-sm-block{display:block!important}.d-sm-table{display:table!important}.d-sm-table-row{display:table-row!important}.d-sm-table-cell{display:table-cell!important}.d-sm-flex{display:flex!important}.d-sm-inline-flex{display:inline-flex!important}}@media (min-width:768px){.d-md-none{display:none!important}.d-md-inline{display:inline!important}.d-md-inline-block{display:inline-block!important}.d-md-block{display:block!important}.d-md-table{display:table!important}.d-md-table-row{display:table-row!important}.d-md-table-cell{display:table-cell!important}.d-md-flex{display:flex!important}.d-md-inline-flex{display:inline-flex!important}}@media (min-width:992px){.d-lg-none{display:none!important}.d-lg-inline{display:inline!important}.d-lg-inline-block{display:inline-block!important}.d-lg-block{display:block!important}.d-lg-table{display:table!important}.d-lg-table-row{display:table-row!important}.d-lg-table-cell{display:table-cell!important}.d-lg-flex{display:flex!important}.d-lg-inline-flex{display:inline-flex!important}}@media (min-width:1200px){.d-xl-none{display:none!important}.d-xl-inline{display:inline!important}.d-xl-inline-block{display:inline-block!important}.d-xl-block{display:block!important}.d-xl-table{display:table!important}.d-xl-table-row{display:table-row!important}.d-xl-table-cell{display:table-cell!important}.d-xl-flex{display:flex!important}.d-xl-inline-flex{display:inline-flex!important}}@media print{.d-print-none{display:none!important}.d-print-inline{display:inline!important}.d-print-inline-block{display:inline-block!important}.d-print-block{display:block!important}.d-print-table{display:table!important}.d-print-table-row{display:table-row!important}.d-print-table-cell{display:table-cell!important}.d-print-flex{display:flex!important}.d-print-inline-flex{display:inline-flex!important}}.embed-responsive{position:relative;display:block;width:100%;padding:0;overflow:hidden}.embed-responsive:before{display:block;content:""}.embed-responsive .embed-responsive-item,.embed-responsive embed,.embed-responsive iframe,.embed-responsive object,.embed-responsive video{position:absolute;top:0;bottom:0;left:0;width:100%;height:100%;border:0}.embed-responsive-21by9:before{padding-top:42.8571428571%}.embed-responsive-16by9:before{padding-top:56.25%}.embed-responsive-4by3:before{padding-top:75%}.embed-responsive-1by1:before{padding-top:100%}.flex-row{flex-direction:row!important}.flex-column{flex-direction:column!important}.flex-row-reverse{flex-direction:row-reverse!important}.flex-column-reverse{flex-direction:column-reverse!important}.flex-wrap{flex-wrap:wrap!important}.flex-nowrap{flex-wrap:nowrap!important}.flex-wrap-reverse{flex-wrap:wrap-reverse!important}.flex-fill{flex:1 1 auto!important}.flex-grow-0{flex-grow:0!important}.flex-grow-1{flex-grow:1!important}.flex-shrink-0{flex-shrink:0!important}.flex-shrink-1{flex-shrink:1!important}.justify-content-start{justify-content:flex-start!important}.justify-content-end{justify-content:flex-end!important}.justify-content-center{justify-content:center!important}.justify-content-between{justify-content:space-between!important}.justify-content-around{justify-content:space-around!important}.align-items-start{align-items:flex-start!important}.align-items-end{align-items:flex-end!important}.align-items-center{align-items:center!important}.align-items-baseline{align-items:baseline!important}.align-items-stretch{align-items:stretch!important}.align-content-start{align-content:flex-start!important}.align-content-end{align-content:flex-end!important}.align-content-center{align-content:center!important}.align-content-between{align-content:space-between!important}.align-content-around{align-content:space-around!important}.align-content-stretch{align-content:stretch!important}.align-self-auto{align-self:auto!important}.align-self-start{align-self:flex-start!important}.align-self-end{align-self:flex-end!important}.align-self-center{align-self:center!important}.align-self-baseline{align-self:baseline!important}.align-self-stretch{align-self:stretch!important}@media (min-width:576px){.flex-sm-row{flex-direction:row!important}.flex-sm-column{flex-direction:column!important}.flex-sm-row-reverse{flex-direction:row-reverse!important}.flex-sm-column-reverse{flex-direction:column-reverse!important}.flex-sm-wrap{flex-wrap:wrap!important}.flex-sm-nowrap{flex-wrap:nowrap!important}.flex-sm-wrap-reverse{flex-wrap:wrap-reverse!important}.flex-sm-fill{flex:1 1 auto!important}.flex-sm-grow-0{flex-grow:0!important}.flex-sm-grow-1{flex-grow:1!important}.flex-sm-shrink-0{flex-shrink:0!important}.flex-sm-shrink-1{flex-shrink:1!important}.justify-content-sm-start{justify-content:flex-start!important}.justify-content-sm-end{justify-content:flex-end!important}.justify-content-sm-center{justify-content:center!important}.justify-content-sm-between{justify-content:space-between!important}.justify-content-sm-around{justify-content:space-around!important}.align-items-sm-start{align-items:flex-start!important}.align-items-sm-end{align-items:flex-end!important}.align-items-sm-center{align-items:center!important}.align-items-sm-baseline{align-items:baseline!important}.align-items-sm-stretch{align-items:stretch!important}.align-content-sm-start{align-content:flex-start!important}.align-content-sm-end{align-content:flex-end!important}.align-content-sm-center{align-content:center!important}.align-content-sm-between{align-content:space-between!important}.align-content-sm-around{align-content:space-around!important}.align-content-sm-stretch{align-content:stretch!important}.align-self-sm-auto{align-self:auto!important}.align-self-sm-start{align-self:flex-start!important}.align-self-sm-end{align-self:flex-end!important}.align-self-sm-center{align-self:center!important}.align-self-sm-baseline{align-self:baseline!important}.align-self-sm-stretch{align-self:stretch!important}}@media (min-width:768px){.flex-md-row{flex-direction:row!important}.flex-md-column{flex-direction:column!important}.flex-md-row-reverse{flex-direction:row-reverse!important}.flex-md-column-reverse{flex-direction:column-reverse!important}.flex-md-wrap{flex-wrap:wrap!important}.flex-md-nowrap{flex-wrap:nowrap!important}.flex-md-wrap-reverse{flex-wrap:wrap-reverse!important}.flex-md-fill{flex:1 1 auto!important}.flex-md-grow-0{flex-grow:0!important}.flex-md-grow-1{flex-grow:1!important}.flex-md-shrink-0{flex-shrink:0!important}.flex-md-shrink-1{flex-shrink:1!important}.justify-content-md-start{justify-content:flex-start!important}.justify-content-md-end{justify-content:flex-end!important}.justify-content-md-center{justify-content:center!important}.justify-content-md-between{justify-content:space-between!important}.justify-content-md-around{justify-content:space-around!important}.align-items-md-start{align-items:flex-start!important}.align-items-md-end{align-items:flex-end!important}.align-items-md-center{align-items:center!important}.align-items-md-baseline{align-items:baseline!important}.align-items-md-stretch{align-items:stretch!important}.align-content-md-start{align-content:flex-start!important}.align-content-md-end{align-content:flex-end!important}.align-content-md-center{align-content:center!important}.align-content-md-between{align-content:space-between!important}.align-content-md-around{align-content:space-around!important}.align-content-md-stretch{align-content:stretch!important}.align-self-md-auto{align-self:auto!important}.align-self-md-start{align-self:flex-start!important}.align-self-md-end{align-self:flex-end!important}.align-self-md-center{align-self:center!important}.align-self-md-baseline{align-self:baseline!important}.align-self-md-stretch{align-self:stretch!important}}@media (min-width:992px){.flex-lg-row{flex-direction:row!important}.flex-lg-column{flex-direction:column!important}.flex-lg-row-reverse{flex-direction:row-reverse!important}.flex-lg-column-reverse{flex-direction:column-reverse!important}.flex-lg-wrap{flex-wrap:wrap!important}.flex-lg-nowrap{flex-wrap:nowrap!important}.flex-lg-wrap-reverse{flex-wrap:wrap-reverse!important}.flex-lg-fill{flex:1 1 auto!important}.flex-lg-grow-0{flex-grow:0!important}.flex-lg-grow-1{flex-grow:1!important}.flex-lg-shrink-0{flex-shrink:0!important}.flex-lg-shrink-1{flex-shrink:1!important}.justify-content-lg-start{justify-content:flex-start!important}.justify-content-lg-end{justify-content:flex-end!important}.justify-content-lg-center{justify-content:center!important}.justify-content-lg-between{justify-content:space-between!important}.justify-content-lg-around{justify-content:space-around!important}.align-items-lg-start{align-items:flex-start!important}.align-items-lg-end{align-items:flex-end!important}.align-items-lg-center{align-items:center!important}.align-items-lg-baseline{align-items:baseline!important}.align-items-lg-stretch{align-items:stretch!important}.align-content-lg-start{align-content:flex-start!important}.align-content-lg-end{align-content:flex-end!important}.align-content-lg-center{align-content:center!important}.align-content-lg-between{align-content:space-between!important}.align-content-lg-around{align-content:space-around!important}.align-content-lg-stretch{align-content:stretch!important}.align-self-lg-auto{align-self:auto!important}.align-self-lg-start{align-self:flex-start!important}.align-self-lg-end{align-self:flex-end!important}.align-self-lg-center{align-self:center!important}.align-self-lg-baseline{align-self:baseline!important}.align-self-lg-stretch{align-self:stretch!important}}@media (min-width:1200px){.flex-xl-row{flex-direction:row!important}.flex-xl-column{flex-direction:column!important}.flex-xl-row-reverse{flex-direction:row-reverse!important}.flex-xl-column-reverse{flex-direction:column-reverse!important}.flex-xl-wrap{flex-wrap:wrap!important}.flex-xl-nowrap{flex-wrap:nowrap!important}.flex-xl-wrap-reverse{flex-wrap:wrap-reverse!important}.flex-xl-fill{flex:1 1 auto!important}.flex-xl-grow-0{flex-grow:0!important}.flex-xl-grow-1{flex-grow:1!important}.flex-xl-shrink-0{flex-shrink:0!important}.flex-xl-shrink-1{flex-shrink:1!important}.justify-content-xl-start{justify-content:flex-start!important}.justify-content-xl-end{justify-content:flex-end!important}.justify-content-xl-center{justify-content:center!important}.justify-content-xl-between{justify-content:space-between!important}.justify-content-xl-around{justify-content:space-around!important}.align-items-xl-start{align-items:flex-start!important}.align-items-xl-end{align-items:flex-end!important}.align-items-xl-center{align-items:center!important}.align-items-xl-baseline{align-items:baseline!important}.align-items-xl-stretch{align-items:stretch!important}.align-content-xl-start{align-content:flex-start!important}.align-content-xl-end{align-content:flex-end!important}.align-content-xl-center{align-content:center!important}.align-content-xl-between{align-content:space-between!important}.align-content-xl-around{align-content:space-around!important}.align-content-xl-stretch{align-content:stretch!important}.align-self-xl-auto{align-self:auto!important}.align-self-xl-start{align-self:flex-start!important}.align-self-xl-end{align-self:flex-end!important}.align-self-xl-center{align-self:center!important}.align-self-xl-baseline{align-self:baseline!important}.align-self-xl-stretch{align-self:stretch!important}}.float-left{float:left!important}.float-right{float:right!important}.float-none{float:none!important}@media (min-width:576px){.float-sm-left{float:left!important}.float-sm-right{float:right!important}.float-sm-none{float:none!important}}@media (min-width:768px){.float-md-left{float:left!important}.float-md-right{float:right!important}.float-md-none{float:none!important}}@media (min-width:992px){.float-lg-left{float:left!important}.float-lg-right{float:right!important}.float-lg-none{float:none!important}}@media (min-width:1200px){.float-xl-left{float:left!important}.float-xl-right{float:right!important}.float-xl-none{float:none!important}}.user-select-all{-webkit-user-select:all!important;-moz-user-select:all!important;-ms-user-select:all!important;user-select:all!important}.user-select-auto{-webkit-user-select:auto!important;-moz-user-select:auto!important;-ms-user-select:auto!important;user-select:auto!important}.user-select-none{-webkit-user-select:none!important;-moz-user-select:none!important;-ms-user-select:none!important;user-select:none!important}.overflow-auto{overflow:auto!important}.overflow-hidden{overflow:hidden!important}.position-static{position:static!important}.position-relative{position:relative!important}.position-absolute{position:absolute!important}.position-fixed{position:fixed!important}.position-sticky{position:-webkit-sticky!important;position:sticky!important}.fixed-top{top:0}.fixed-bottom,.fixed-top{position:fixed;right:0;left:0;z-index:1030}.fixed-bottom{bottom:0}@supports ((position:-webkit-sticky) or (position:sticky)){.sticky-top{position:-webkit-sticky;position:sticky;top:0;z-index:1020}}.sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border:0}.sr-only-focusable:active,.sr-only-focusable:focus{position:static;width:auto;height:auto;overflow:visible;clip:auto;white-space:normal}.shadow-sm{box-shadow:0 .125rem .25rem rgba(0,0,0,.075)!important}.shadow{box-shadow:0 .5rem 1rem rgba(0,0,0,.15)!important}.shadow-lg{box-shadow:0 1rem 3rem rgba(0,0,0,.175)!important}.shadow-none{box-shadow:none!important}.w-25{width:25%!important}.w-50{width:50%!important}.w-75{width:75%!important}.w-100{width:100%!important}.w-auto{width:auto!important}.h-25{height:25%!important}.h-50{height:50%!important}.h-75{height:75%!important}.h-100{height:100%!important}.h-auto{height:auto!important}.mw-100{max-width:100%!important}.mh-100{max-height:100%!important}.min-vw-100{min-width:100vw!important}.min-vh-100{min-height:100vh!important}.vw-100{width:100vw!important}.vh-100{height:100vh!important}.m-0{margin:0!important}.mt-0,.my-0{margin-top:0!important}.mr-0,.mx-0{margin-right:0!important}.mb-0,.my-0{margin-bottom:0!important}.ml-0,.mx-0{margin-left:0!important}.m-1{margin:.25rem!important}.mt-1,.my-1{margin-top:.25rem!important}.mr-1,.mx-1{margin-right:.25rem!important}.mb-1,.my-1{margin-bottom:.25rem!important}.ml-1,.mx-1{margin-left:.25rem!important}.m-2{margin:.5rem!important}.mt-2,.my-2{margin-top:.5rem!important}.mr-2,.mx-2{margin-right:.5rem!important}.mb-2,.my-2{margin-bottom:.5rem!important}.ml-2,.mx-2{margin-left:.5rem!important}.m-3{margin:1rem!important}.mt-3,.my-3{margin-top:1rem!important}.mr-3,.mx-3{margin-right:1rem!important}.mb-3,.my-3{margin-bottom:1rem!important}.ml-3,.mx-3{margin-left:1rem!important}.m-4{margin:1.5rem!important}.mt-4,.my-4{margin-top:1.5rem!important}.mr-4,.mx-4{margin-right:1.5rem!important}.mb-4,.my-4{margin-bottom:1.5rem!important}.ml-4,.mx-4{margin-left:1.5rem!important}.m-5{margin:3rem!important}.mt-5,.my-5{margin-top:3rem!important}.mr-5,.mx-5{margin-right:3rem!important}.mb-5,.my-5{margin-bottom:3rem!important}.ml-5,.mx-5{margin-left:3rem!important}.m-6{margin:3.75rem!important}.mt-6,.my-6{margin-top:3.75rem!important}.mr-6,.mx-6{margin-right:3.75rem!important}.mb-6,.my-6{margin-bottom:3.75rem!important}.ml-6,.mx-6{margin-left:3.75rem!important}.m-7{margin:4.5rem!important}.mt-7,.my-7{margin-top:4.5rem!important}.mr-7,.mx-7{margin-right:4.5rem!important}.mb-7,.my-7{margin-bottom:4.5rem!important}.ml-7,.mx-7{margin-left:4.5rem!important}.m-8{margin:5rem!important}.mt-8,.my-8{margin-top:5rem!important}.mr-8,.mx-8{margin-right:5rem!important}.mb-8,.my-8{margin-bottom:5rem!important}.ml-8,.mx-8{margin-left:5rem!important}.p-0{padding:0!important}.pt-0,.py-0{padding-top:0!important}.pr-0,.px-0{padding-right:0!important}.pb-0,.py-0{padding-bottom:0!important}.pl-0,.px-0{padding-left:0!important}.p-1{padding:.25rem!important}.pt-1,.py-1{padding-top:.25rem!important}.pr-1,.px-1{padding-right:.25rem!important}.pb-1,.py-1{padding-bottom:.25rem!important}.pl-1,.px-1{padding-left:.25rem!important}.p-2{padding:.5rem!important}.pt-2,.py-2{padding-top:.5rem!important}.pr-2,.px-2{padding-right:.5rem!important}.pb-2,.py-2{padding-bottom:.5rem!important}.pl-2,.px-2{padding-left:.5rem!important}.p-3{padding:1rem!important}.pt-3,.py-3{padding-top:1rem!important}.pr-3,.px-3{padding-right:1rem!important}.pb-3,.py-3{padding-bottom:1rem!important}.pl-3,.px-3{padding-left:1rem!important}.p-4{padding:1.5rem!important}.pt-4,.py-4{padding-top:1.5rem!important}.pr-4,.px-4{padding-right:1.5rem!important}.pb-4,.py-4{padding-bottom:1.5rem!important}.pl-4,.px-4{padding-left:1.5rem!important}.p-5{padding:3rem!important}.pt-5,.py-5{padding-top:3rem!important}.pr-5,.px-5{padding-right:3rem!important}.pb-5,.py-5{padding-bottom:3rem!important}.pl-5,.px-5{padding-left:3rem!important}.p-6{padding:3.75rem!important}.pt-6,.py-6{padding-top:3.75rem!important}.pr-6,.px-6{padding-right:3.75rem!important}.pb-6,.py-6{padding-bottom:3.75rem!important}.pl-6,.px-6{padding-left:3.75rem!important}.p-7{padding:4.5rem!important}.pt-7,.py-7{padding-top:4.5rem!important}.pr-7,.px-7{padding-right:4.5rem!important}.pb-7,.py-7{padding-bottom:4.5rem!important}.pl-7,.px-7{padding-left:4.5rem!important}.p-8{padding:5rem!important}.pt-8,.py-8{padding-top:5rem!important}.pr-8,.px-8{padding-right:5rem!important}.pb-8,.py-8{padding-bottom:5rem!important}.pl-8,.px-8{padding-left:5rem!important}.m-n1{margin:-.25rem!important}.mt-n1,.my-n1{margin-top:-.25rem!important}.mr-n1,.mx-n1{margin-right:-.25rem!important}.mb-n1,.my-n1{margin-bottom:-.25rem!important}.ml-n1,.mx-n1{margin-left:-.25rem!important}.m-n2{margin:-.5rem!important}.mt-n2,.my-n2{margin-top:-.5rem!important}.mr-n2,.mx-n2{margin-right:-.5rem!important}.mb-n2,.my-n2{margin-bottom:-.5rem!important}.ml-n2,.mx-n2{margin-left:-.5rem!important}.m-n3{margin:-1rem!important}.mt-n3,.my-n3{margin-top:-1rem!important}.mr-n3,.mx-n3{margin-right:-1rem!important}.mb-n3,.my-n3{margin-bottom:-1rem!important}.ml-n3,.mx-n3{margin-left:-1rem!important}.m-n4{margin:-1.5rem!important}.mt-n4,.my-n4{margin-top:-1.5rem!important}.mr-n4,.mx-n4{margin-right:-1.5rem!important}.mb-n4,.my-n4{margin-bottom:-1.5rem!important}.ml-n4,.mx-n4{margin-left:-1.5rem!important}.m-n5{margin:-3rem!important}.mt-n5,.my-n5{margin-top:-3rem!important}.mr-n5,.mx-n5{margin-right:-3rem!important}.mb-n5,.my-n5{margin-bottom:-3rem!important}.ml-n5,.mx-n5{margin-left:-3rem!important}.m-n6{margin:-3.75rem!important}.mt-n6,.my-n6{margin-top:-3.75rem!important}.mr-n6,.mx-n6{margin-right:-3.75rem!important}.mb-n6,.my-n6{margin-bottom:-3.75rem!important}.ml-n6,.mx-n6{margin-left:-3.75rem!important}.m-n7{margin:-4.5rem!important}.mt-n7,.my-n7{margin-top:-4.5rem!important}.mr-n7,.mx-n7{margin-right:-4.5rem!important}.mb-n7,.my-n7{margin-bottom:-4.5rem!important}.ml-n7,.mx-n7{margin-left:-4.5rem!important}.m-n8{margin:-5rem!important}.mt-n8,.my-n8{margin-top:-5rem!important}.mr-n8,.mx-n8{margin-right:-5rem!important}.mb-n8,.my-n8{margin-bottom:-5rem!important}.ml-n8,.mx-n8{margin-left:-5rem!important}.m-auto{margin:auto!important}.mt-auto,.my-auto{margin-top:auto!important}.mr-auto,.mx-auto{margin-right:auto!important}.mb-auto,.my-auto{margin-bottom:auto!important}.ml-auto,.mx-auto{margin-left:auto!important}@media (min-width:576px){.m-sm-0{margin:0!important}.mt-sm-0,.my-sm-0{margin-top:0!important}.mr-sm-0,.mx-sm-0{margin-right:0!important}.mb-sm-0,.my-sm-0{margin-bottom:0!important}.ml-sm-0,.mx-sm-0{margin-left:0!important}.m-sm-1{margin:.25rem!important}.mt-sm-1,.my-sm-1{margin-top:.25rem!important}.mr-sm-1,.mx-sm-1{margin-right:.25rem!important}.mb-sm-1,.my-sm-1{margin-bottom:.25rem!important}.ml-sm-1,.mx-sm-1{margin-left:.25rem!important}.m-sm-2{margin:.5rem!important}.mt-sm-2,.my-sm-2{margin-top:.5rem!important}.mr-sm-2,.mx-sm-2{margin-right:.5rem!important}.mb-sm-2,.my-sm-2{margin-bottom:.5rem!important}.ml-sm-2,.mx-sm-2{margin-left:.5rem!important}.m-sm-3{margin:1rem!important}.mt-sm-3,.my-sm-3{margin-top:1rem!important}.mr-sm-3,.mx-sm-3{margin-right:1rem!important}.mb-sm-3,.my-sm-3{margin-bottom:1rem!important}.ml-sm-3,.mx-sm-3{margin-left:1rem!important}.m-sm-4{margin:1.5rem!important}.mt-sm-4,.my-sm-4{margin-top:1.5rem!important}.mr-sm-4,.mx-sm-4{margin-right:1.5rem!important}.mb-sm-4,.my-sm-4{margin-bottom:1.5rem!important}.ml-sm-4,.mx-sm-4{margin-left:1.5rem!important}.m-sm-5{margin:3rem!important}.mt-sm-5,.my-sm-5{margin-top:3rem!important}.mr-sm-5,.mx-sm-5{margin-right:3rem!important}.mb-sm-5,.my-sm-5{margin-bottom:3rem!important}.ml-sm-5,.mx-sm-5{margin-left:3rem!important}.m-sm-6{margin:3.75rem!important}.mt-sm-6,.my-sm-6{margin-top:3.75rem!important}.mr-sm-6,.mx-sm-6{margin-right:3.75rem!important}.mb-sm-6,.my-sm-6{margin-bottom:3.75rem!important}.ml-sm-6,.mx-sm-6{margin-left:3.75rem!important}.m-sm-7{margin:4.5rem!important}.mt-sm-7,.my-sm-7{margin-top:4.5rem!important}.mr-sm-7,.mx-sm-7{margin-right:4.5rem!important}.mb-sm-7,.my-sm-7{margin-bottom:4.5rem!important}.ml-sm-7,.mx-sm-7{margin-left:4.5rem!important}.m-sm-8{margin:5rem!important}.mt-sm-8,.my-sm-8{margin-top:5rem!important}.mr-sm-8,.mx-sm-8{margin-right:5rem!important}.mb-sm-8,.my-sm-8{margin-bottom:5rem!important}.ml-sm-8,.mx-sm-8{margin-left:5rem!important}.p-sm-0{padding:0!important}.pt-sm-0,.py-sm-0{padding-top:0!important}.pr-sm-0,.px-sm-0{padding-right:0!important}.pb-sm-0,.py-sm-0{padding-bottom:0!important}.pl-sm-0,.px-sm-0{padding-left:0!important}.p-sm-1{padding:.25rem!important}.pt-sm-1,.py-sm-1{padding-top:.25rem!important}.pr-sm-1,.px-sm-1{padding-right:.25rem!important}.pb-sm-1,.py-sm-1{padding-bottom:.25rem!important}.pl-sm-1,.px-sm-1{padding-left:.25rem!important}.p-sm-2{padding:.5rem!important}.pt-sm-2,.py-sm-2{padding-top:.5rem!important}.pr-sm-2,.px-sm-2{padding-right:.5rem!important}.pb-sm-2,.py-sm-2{padding-bottom:.5rem!important}.pl-sm-2,.px-sm-2{padding-left:.5rem!important}.p-sm-3{padding:1rem!important}.pt-sm-3,.py-sm-3{padding-top:1rem!important}.pr-sm-3,.px-sm-3{padding-right:1rem!important}.pb-sm-3,.py-sm-3{padding-bottom:1rem!important}.pl-sm-3,.px-sm-3{padding-left:1rem!important}.p-sm-4{padding:1.5rem!important}.pt-sm-4,.py-sm-4{padding-top:1.5rem!important}.pr-sm-4,.px-sm-4{padding-right:1.5rem!important}.pb-sm-4,.py-sm-4{padding-bottom:1.5rem!important}.pl-sm-4,.px-sm-4{padding-left:1.5rem!important}.p-sm-5{padding:3rem!important}.pt-sm-5,.py-sm-5{padding-top:3rem!important}.pr-sm-5,.px-sm-5{padding-right:3rem!important}.pb-sm-5,.py-sm-5{padding-bottom:3rem!important}.pl-sm-5,.px-sm-5{padding-left:3rem!important}.p-sm-6{padding:3.75rem!important}.pt-sm-6,.py-sm-6{padding-top:3.75rem!important}.pr-sm-6,.px-sm-6{padding-right:3.75rem!important}.pb-sm-6,.py-sm-6{padding-bottom:3.75rem!important}.pl-sm-6,.px-sm-6{padding-left:3.75rem!important}.p-sm-7{padding:4.5rem!important}.pt-sm-7,.py-sm-7{padding-top:4.5rem!important}.pr-sm-7,.px-sm-7{padding-right:4.5rem!important}.pb-sm-7,.py-sm-7{padding-bottom:4.5rem!important}.pl-sm-7,.px-sm-7{padding-left:4.5rem!important}.p-sm-8{padding:5rem!important}.pt-sm-8,.py-sm-8{padding-top:5rem!important}.pr-sm-8,.px-sm-8{padding-right:5rem!important}.pb-sm-8,.py-sm-8{padding-bottom:5rem!important}.pl-sm-8,.px-sm-8{padding-left:5rem!important}.m-sm-n1{margin:-.25rem!important}.mt-sm-n1,.my-sm-n1{margin-top:-.25rem!important}.mr-sm-n1,.mx-sm-n1{margin-right:-.25rem!important}.mb-sm-n1,.my-sm-n1{margin-bottom:-.25rem!important}.ml-sm-n1,.mx-sm-n1{margin-left:-.25rem!important}.m-sm-n2{margin:-.5rem!important}.mt-sm-n2,.my-sm-n2{margin-top:-.5rem!important}.mr-sm-n2,.mx-sm-n2{margin-right:-.5rem!important}.mb-sm-n2,.my-sm-n2{margin-bottom:-.5rem!important}.ml-sm-n2,.mx-sm-n2{margin-left:-.5rem!important}.m-sm-n3{margin:-1rem!important}.mt-sm-n3,.my-sm-n3{margin-top:-1rem!important}.mr-sm-n3,.mx-sm-n3{margin-right:-1rem!important}.mb-sm-n3,.my-sm-n3{margin-bottom:-1rem!important}.ml-sm-n3,.mx-sm-n3{margin-left:-1rem!important}.m-sm-n4{margin:-1.5rem!important}.mt-sm-n4,.my-sm-n4{margin-top:-1.5rem!important}.mr-sm-n4,.mx-sm-n4{margin-right:-1.5rem!important}.mb-sm-n4,.my-sm-n4{margin-bottom:-1.5rem!important}.ml-sm-n4,.mx-sm-n4{margin-left:-1.5rem!important}.m-sm-n5{margin:-3rem!important}.mt-sm-n5,.my-sm-n5{margin-top:-3rem!important}.mr-sm-n5,.mx-sm-n5{margin-right:-3rem!important}.mb-sm-n5,.my-sm-n5{margin-bottom:-3rem!important}.ml-sm-n5,.mx-sm-n5{margin-left:-3rem!important}.m-sm-n6{margin:-3.75rem!important}.mt-sm-n6,.my-sm-n6{margin-top:-3.75rem!important}.mr-sm-n6,.mx-sm-n6{margin-right:-3.75rem!important}.mb-sm-n6,.my-sm-n6{margin-bottom:-3.75rem!important}.ml-sm-n6,.mx-sm-n6{margin-left:-3.75rem!important}.m-sm-n7{margin:-4.5rem!important}.mt-sm-n7,.my-sm-n7{margin-top:-4.5rem!important}.mr-sm-n7,.mx-sm-n7{margin-right:-4.5rem!important}.mb-sm-n7,.my-sm-n7{margin-bottom:-4.5rem!important}.ml-sm-n7,.mx-sm-n7{margin-left:-4.5rem!important}.m-sm-n8{margin:-5rem!important}.mt-sm-n8,.my-sm-n8{margin-top:-5rem!important}.mr-sm-n8,.mx-sm-n8{margin-right:-5rem!important}.mb-sm-n8,.my-sm-n8{margin-bottom:-5rem!important}.ml-sm-n8,.mx-sm-n8{margin-left:-5rem!important}.m-sm-auto{margin:auto!important}.mt-sm-auto,.my-sm-auto{margin-top:auto!important}.mr-sm-auto,.mx-sm-auto{margin-right:auto!important}.mb-sm-auto,.my-sm-auto{margin-bottom:auto!important}.ml-sm-auto,.mx-sm-auto{margin-left:auto!important}}@media (min-width:768px){.m-md-0{margin:0!important}.mt-md-0,.my-md-0{margin-top:0!important}.mr-md-0,.mx-md-0{margin-right:0!important}.mb-md-0,.my-md-0{margin-bottom:0!important}.ml-md-0,.mx-md-0{margin-left:0!important}.m-md-1{margin:.25rem!important}.mt-md-1,.my-md-1{margin-top:.25rem!important}.mr-md-1,.mx-md-1{margin-right:.25rem!important}.mb-md-1,.my-md-1{margin-bottom:.25rem!important}.ml-md-1,.mx-md-1{margin-left:.25rem!important}.m-md-2{margin:.5rem!important}.mt-md-2,.my-md-2{margin-top:.5rem!important}.mr-md-2,.mx-md-2{margin-right:.5rem!important}.mb-md-2,.my-md-2{margin-bottom:.5rem!important}.ml-md-2,.mx-md-2{margin-left:.5rem!important}.m-md-3{margin:1rem!important}.mt-md-3,.my-md-3{margin-top:1rem!important}.mr-md-3,.mx-md-3{margin-right:1rem!important}.mb-md-3,.my-md-3{margin-bottom:1rem!important}.ml-md-3,.mx-md-3{margin-left:1rem!important}.m-md-4{margin:1.5rem!important}.mt-md-4,.my-md-4{margin-top:1.5rem!important}.mr-md-4,.mx-md-4{margin-right:1.5rem!important}.mb-md-4,.my-md-4{margin-bottom:1.5rem!important}.ml-md-4,.mx-md-4{margin-left:1.5rem!important}.m-md-5{margin:3rem!important}.mt-md-5,.my-md-5{margin-top:3rem!important}.mr-md-5,.mx-md-5{margin-right:3rem!important}.mb-md-5,.my-md-5{margin-bottom:3rem!important}.ml-md-5,.mx-md-5{margin-left:3rem!important}.m-md-6{margin:3.75rem!important}.mt-md-6,.my-md-6{margin-top:3.75rem!important}.mr-md-6,.mx-md-6{margin-right:3.75rem!important}.mb-md-6,.my-md-6{margin-bottom:3.75rem!important}.ml-md-6,.mx-md-6{margin-left:3.75rem!important}.m-md-7{margin:4.5rem!important}.mt-md-7,.my-md-7{margin-top:4.5rem!important}.mr-md-7,.mx-md-7{margin-right:4.5rem!important}.mb-md-7,.my-md-7{margin-bottom:4.5rem!important}.ml-md-7,.mx-md-7{margin-left:4.5rem!important}.m-md-8{margin:5rem!important}.mt-md-8,.my-md-8{margin-top:5rem!important}.mr-md-8,.mx-md-8{margin-right:5rem!important}.mb-md-8,.my-md-8{margin-bottom:5rem!important}.ml-md-8,.mx-md-8{margin-left:5rem!important}.p-md-0{padding:0!important}.pt-md-0,.py-md-0{padding-top:0!important}.pr-md-0,.px-md-0{padding-right:0!important}.pb-md-0,.py-md-0{padding-bottom:0!important}.pl-md-0,.px-md-0{padding-left:0!important}.p-md-1{padding:.25rem!important}.pt-md-1,.py-md-1{padding-top:.25rem!important}.pr-md-1,.px-md-1{padding-right:.25rem!important}.pb-md-1,.py-md-1{padding-bottom:.25rem!important}.pl-md-1,.px-md-1{padding-left:.25rem!important}.p-md-2{padding:.5rem!important}.pt-md-2,.py-md-2{padding-top:.5rem!important}.pr-md-2,.px-md-2{padding-right:.5rem!important}.pb-md-2,.py-md-2{padding-bottom:.5rem!important}.pl-md-2,.px-md-2{padding-left:.5rem!important}.p-md-3{padding:1rem!important}.pt-md-3,.py-md-3{padding-top:1rem!important}.pr-md-3,.px-md-3{padding-right:1rem!important}.pb-md-3,.py-md-3{padding-bottom:1rem!important}.pl-md-3,.px-md-3{padding-left:1rem!important}.p-md-4{padding:1.5rem!important}.pt-md-4,.py-md-4{padding-top:1.5rem!important}.pr-md-4,.px-md-4{padding-right:1.5rem!important}.pb-md-4,.py-md-4{padding-bottom:1.5rem!important}.pl-md-4,.px-md-4{padding-left:1.5rem!important}.p-md-5{padding:3rem!important}.pt-md-5,.py-md-5{padding-top:3rem!important}.pr-md-5,.px-md-5{padding-right:3rem!important}.pb-md-5,.py-md-5{padding-bottom:3rem!important}.pl-md-5,.px-md-5{padding-left:3rem!important}.p-md-6{padding:3.75rem!important}.pt-md-6,.py-md-6{padding-top:3.75rem!important}.pr-md-6,.px-md-6{padding-right:3.75rem!important}.pb-md-6,.py-md-6{padding-bottom:3.75rem!important}.pl-md-6,.px-md-6{padding-left:3.75rem!important}.p-md-7{padding:4.5rem!important}.pt-md-7,.py-md-7{padding-top:4.5rem!important}.pr-md-7,.px-md-7{padding-right:4.5rem!important}.pb-md-7,.py-md-7{padding-bottom:4.5rem!important}.pl-md-7,.px-md-7{padding-left:4.5rem!important}.p-md-8{padding:5rem!important}.pt-md-8,.py-md-8{padding-top:5rem!important}.pr-md-8,.px-md-8{padding-right:5rem!important}.pb-md-8,.py-md-8{padding-bottom:5rem!important}.pl-md-8,.px-md-8{padding-left:5rem!important}.m-md-n1{margin:-.25rem!important}.mt-md-n1,.my-md-n1{margin-top:-.25rem!important}.mr-md-n1,.mx-md-n1{margin-right:-.25rem!important}.mb-md-n1,.my-md-n1{margin-bottom:-.25rem!important}.ml-md-n1,.mx-md-n1{margin-left:-.25rem!important}.m-md-n2{margin:-.5rem!important}.mt-md-n2,.my-md-n2{margin-top:-.5rem!important}.mr-md-n2,.mx-md-n2{margin-right:-.5rem!important}.mb-md-n2,.my-md-n2{margin-bottom:-.5rem!important}.ml-md-n2,.mx-md-n2{margin-left:-.5rem!important}.m-md-n3{margin:-1rem!important}.mt-md-n3,.my-md-n3{margin-top:-1rem!important}.mr-md-n3,.mx-md-n3{margin-right:-1rem!important}.mb-md-n3,.my-md-n3{margin-bottom:-1rem!important}.ml-md-n3,.mx-md-n3{margin-left:-1rem!important}.m-md-n4{margin:-1.5rem!important}.mt-md-n4,.my-md-n4{margin-top:-1.5rem!important}.mr-md-n4,.mx-md-n4{margin-right:-1.5rem!important}.mb-md-n4,.my-md-n4{margin-bottom:-1.5rem!important}.ml-md-n4,.mx-md-n4{margin-left:-1.5rem!important}.m-md-n5{margin:-3rem!important}.mt-md-n5,.my-md-n5{margin-top:-3rem!important}.mr-md-n5,.mx-md-n5{margin-right:-3rem!important}.mb-md-n5,.my-md-n5{margin-bottom:-3rem!important}.ml-md-n5,.mx-md-n5{margin-left:-3rem!important}.m-md-n6{margin:-3.75rem!important}.mt-md-n6,.my-md-n6{margin-top:-3.75rem!important}.mr-md-n6,.mx-md-n6{margin-right:-3.75rem!important}.mb-md-n6,.my-md-n6{margin-bottom:-3.75rem!important}.ml-md-n6,.mx-md-n6{margin-left:-3.75rem!important}.m-md-n7{margin:-4.5rem!important}.mt-md-n7,.my-md-n7{margin-top:-4.5rem!important}.mr-md-n7,.mx-md-n7{margin-right:-4.5rem!important}.mb-md-n7,.my-md-n7{margin-bottom:-4.5rem!important}.ml-md-n7,.mx-md-n7{margin-left:-4.5rem!important}.m-md-n8{margin:-5rem!important}.mt-md-n8,.my-md-n8{margin-top:-5rem!important}.mr-md-n8,.mx-md-n8{margin-right:-5rem!important}.mb-md-n8,.my-md-n8{margin-bottom:-5rem!important}.ml-md-n8,.mx-md-n8{margin-left:-5rem!important}.m-md-auto{margin:auto!important}.mt-md-auto,.my-md-auto{margin-top:auto!important}.mr-md-auto,.mx-md-auto{margin-right:auto!important}.mb-md-auto,.my-md-auto{margin-bottom:auto!important}.ml-md-auto,.mx-md-auto{margin-left:auto!important}}@media (min-width:992px){.m-lg-0{margin:0!important}.mt-lg-0,.my-lg-0{margin-top:0!important}.mr-lg-0,.mx-lg-0{margin-right:0!important}.mb-lg-0,.my-lg-0{margin-bottom:0!important}.ml-lg-0,.mx-lg-0{margin-left:0!important}.m-lg-1{margin:.25rem!important}.mt-lg-1,.my-lg-1{margin-top:.25rem!important}.mr-lg-1,.mx-lg-1{margin-right:.25rem!important}.mb-lg-1,.my-lg-1{margin-bottom:.25rem!important}.ml-lg-1,.mx-lg-1{margin-left:.25rem!important}.m-lg-2{margin:.5rem!important}.mt-lg-2,.my-lg-2{margin-top:.5rem!important}.mr-lg-2,.mx-lg-2{margin-right:.5rem!important}.mb-lg-2,.my-lg-2{margin-bottom:.5rem!important}.ml-lg-2,.mx-lg-2{margin-left:.5rem!important}.m-lg-3{margin:1rem!important}.mt-lg-3,.my-lg-3{margin-top:1rem!important}.mr-lg-3,.mx-lg-3{margin-right:1rem!important}.mb-lg-3,.my-lg-3{margin-bottom:1rem!important}.ml-lg-3,.mx-lg-3{margin-left:1rem!important}.m-lg-4{margin:1.5rem!important}.mt-lg-4,.my-lg-4{margin-top:1.5rem!important}.mr-lg-4,.mx-lg-4{margin-right:1.5rem!important}.mb-lg-4,.my-lg-4{margin-bottom:1.5rem!important}.ml-lg-4,.mx-lg-4{margin-left:1.5rem!important}.m-lg-5{margin:3rem!important}.mt-lg-5,.my-lg-5{margin-top:3rem!important}.mr-lg-5,.mx-lg-5{margin-right:3rem!important}.mb-lg-5,.my-lg-5{margin-bottom:3rem!important}.ml-lg-5,.mx-lg-5{margin-left:3rem!important}.m-lg-6{margin:3.75rem!important}.mt-lg-6,.my-lg-6{margin-top:3.75rem!important}.mr-lg-6,.mx-lg-6{margin-right:3.75rem!important}.mb-lg-6,.my-lg-6{margin-bottom:3.75rem!important}.ml-lg-6,.mx-lg-6{margin-left:3.75rem!important}.m-lg-7{margin:4.5rem!important}.mt-lg-7,.my-lg-7{margin-top:4.5rem!important}.mr-lg-7,.mx-lg-7{margin-right:4.5rem!important}.mb-lg-7,.my-lg-7{margin-bottom:4.5rem!important}.ml-lg-7,.mx-lg-7{margin-left:4.5rem!important}.m-lg-8{margin:5rem!important}.mt-lg-8,.my-lg-8{margin-top:5rem!important}.mr-lg-8,.mx-lg-8{margin-right:5rem!important}.mb-lg-8,.my-lg-8{margin-bottom:5rem!important}.ml-lg-8,.mx-lg-8{margin-left:5rem!important}.p-lg-0{padding:0!important}.pt-lg-0,.py-lg-0{padding-top:0!important}.pr-lg-0,.px-lg-0{padding-right:0!important}.pb-lg-0,.py-lg-0{padding-bottom:0!important}.pl-lg-0,.px-lg-0{padding-left:0!important}.p-lg-1{padding:.25rem!important}.pt-lg-1,.py-lg-1{padding-top:.25rem!important}.pr-lg-1,.px-lg-1{padding-right:.25rem!important}.pb-lg-1,.py-lg-1{padding-bottom:.25rem!important}.pl-lg-1,.px-lg-1{padding-left:.25rem!important}.p-lg-2{padding:.5rem!important}.pt-lg-2,.py-lg-2{padding-top:.5rem!important}.pr-lg-2,.px-lg-2{padding-right:.5rem!important}.pb-lg-2,.py-lg-2{padding-bottom:.5rem!important}.pl-lg-2,.px-lg-2{padding-left:.5rem!important}.p-lg-3{padding:1rem!important}.pt-lg-3,.py-lg-3{padding-top:1rem!important}.pr-lg-3,.px-lg-3{padding-right:1rem!important}.pb-lg-3,.py-lg-3{padding-bottom:1rem!important}.pl-lg-3,.px-lg-3{padding-left:1rem!important}.p-lg-4{padding:1.5rem!important}.pt-lg-4,.py-lg-4{padding-top:1.5rem!important}.pr-lg-4,.px-lg-4{padding-right:1.5rem!important}.pb-lg-4,.py-lg-4{padding-bottom:1.5rem!important}.pl-lg-4,.px-lg-4{padding-left:1.5rem!important}.p-lg-5{padding:3rem!important}.pt-lg-5,.py-lg-5{padding-top:3rem!important}.pr-lg-5,.px-lg-5{padding-right:3rem!important}.pb-lg-5,.py-lg-5{padding-bottom:3rem!important}.pl-lg-5,.px-lg-5{padding-left:3rem!important}.p-lg-6{padding:3.75rem!important}.pt-lg-6,.py-lg-6{padding-top:3.75rem!important}.pr-lg-6,.px-lg-6{padding-right:3.75rem!important}.pb-lg-6,.py-lg-6{padding-bottom:3.75rem!important}.pl-lg-6,.px-lg-6{padding-left:3.75rem!important}.p-lg-7{padding:4.5rem!important}.pt-lg-7,.py-lg-7{padding-top:4.5rem!important}.pr-lg-7,.px-lg-7{padding-right:4.5rem!important}.pb-lg-7,.py-lg-7{padding-bottom:4.5rem!important}.pl-lg-7,.px-lg-7{padding-left:4.5rem!important}.p-lg-8{padding:5rem!important}.pt-lg-8,.py-lg-8{padding-top:5rem!important}.pr-lg-8,.px-lg-8{padding-right:5rem!important}.pb-lg-8,.py-lg-8{padding-bottom:5rem!important}.pl-lg-8,.px-lg-8{padding-left:5rem!important}.m-lg-n1{margin:-.25rem!important}.mt-lg-n1,.my-lg-n1{margin-top:-.25rem!important}.mr-lg-n1,.mx-lg-n1{margin-right:-.25rem!important}.mb-lg-n1,.my-lg-n1{margin-bottom:-.25rem!important}.ml-lg-n1,.mx-lg-n1{margin-left:-.25rem!important}.m-lg-n2{margin:-.5rem!important}.mt-lg-n2,.my-lg-n2{margin-top:-.5rem!important}.mr-lg-n2,.mx-lg-n2{margin-right:-.5rem!important}.mb-lg-n2,.my-lg-n2{margin-bottom:-.5rem!important}.ml-lg-n2,.mx-lg-n2{margin-left:-.5rem!important}.m-lg-n3{margin:-1rem!important}.mt-lg-n3,.my-lg-n3{margin-top:-1rem!important}.mr-lg-n3,.mx-lg-n3{margin-right:-1rem!important}.mb-lg-n3,.my-lg-n3{margin-bottom:-1rem!important}.ml-lg-n3,.mx-lg-n3{margin-left:-1rem!important}.m-lg-n4{margin:-1.5rem!important}.mt-lg-n4,.my-lg-n4{margin-top:-1.5rem!important}.mr-lg-n4,.mx-lg-n4{margin-right:-1.5rem!important}.mb-lg-n4,.my-lg-n4{margin-bottom:-1.5rem!important}.ml-lg-n4,.mx-lg-n4{margin-left:-1.5rem!important}.m-lg-n5{margin:-3rem!important}.mt-lg-n5,.my-lg-n5{margin-top:-3rem!important}.mr-lg-n5,.mx-lg-n5{margin-right:-3rem!important}.mb-lg-n5,.my-lg-n5{margin-bottom:-3rem!important}.ml-lg-n5,.mx-lg-n5{margin-left:-3rem!important}.m-lg-n6{margin:-3.75rem!important}.mt-lg-n6,.my-lg-n6{margin-top:-3.75rem!important}.mr-lg-n6,.mx-lg-n6{margin-right:-3.75rem!important}.mb-lg-n6,.my-lg-n6{margin-bottom:-3.75rem!important}.ml-lg-n6,.mx-lg-n6{margin-left:-3.75rem!important}.m-lg-n7{margin:-4.5rem!important}.mt-lg-n7,.my-lg-n7{margin-top:-4.5rem!important}.mr-lg-n7,.mx-lg-n7{margin-right:-4.5rem!important}.mb-lg-n7,.my-lg-n7{margin-bottom:-4.5rem!important}.ml-lg-n7,.mx-lg-n7{margin-left:-4.5rem!important}.m-lg-n8{margin:-5rem!important}.mt-lg-n8,.my-lg-n8{margin-top:-5rem!important}.mr-lg-n8,.mx-lg-n8{margin-right:-5rem!important}.mb-lg-n8,.my-lg-n8{margin-bottom:-5rem!important}.ml-lg-n8,.mx-lg-n8{margin-left:-5rem!important}.m-lg-auto{margin:auto!important}.mt-lg-auto,.my-lg-auto{margin-top:auto!important}.mr-lg-auto,.mx-lg-auto{margin-right:auto!important}.mb-lg-auto,.my-lg-auto{margin-bottom:auto!important}.ml-lg-auto,.mx-lg-auto{margin-left:auto!important}}@media (min-width:1200px){.m-xl-0{margin:0!important}.mt-xl-0,.my-xl-0{margin-top:0!important}.mr-xl-0,.mx-xl-0{margin-right:0!important}.mb-xl-0,.my-xl-0{margin-bottom:0!important}.ml-xl-0,.mx-xl-0{margin-left:0!important}.m-xl-1{margin:.25rem!important}.mt-xl-1,.my-xl-1{margin-top:.25rem!important}.mr-xl-1,.mx-xl-1{margin-right:.25rem!important}.mb-xl-1,.my-xl-1{margin-bottom:.25rem!important}.ml-xl-1,.mx-xl-1{margin-left:.25rem!important}.m-xl-2{margin:.5rem!important}.mt-xl-2,.my-xl-2{margin-top:.5rem!important}.mr-xl-2,.mx-xl-2{margin-right:.5rem!important}.mb-xl-2,.my-xl-2{margin-bottom:.5rem!important}.ml-xl-2,.mx-xl-2{margin-left:.5rem!important}.m-xl-3{margin:1rem!important}.mt-xl-3,.my-xl-3{margin-top:1rem!important}.mr-xl-3,.mx-xl-3{margin-right:1rem!important}.mb-xl-3,.my-xl-3{margin-bottom:1rem!important}.ml-xl-3,.mx-xl-3{margin-left:1rem!important}.m-xl-4{margin:1.5rem!important}.mt-xl-4,.my-xl-4{margin-top:1.5rem!important}.mr-xl-4,.mx-xl-4{margin-right:1.5rem!important}.mb-xl-4,.my-xl-4{margin-bottom:1.5rem!important}.ml-xl-4,.mx-xl-4{margin-left:1.5rem!important}.m-xl-5{margin:3rem!important}.mt-xl-5,.my-xl-5{margin-top:3rem!important}.mr-xl-5,.mx-xl-5{margin-right:3rem!important}.mb-xl-5,.my-xl-5{margin-bottom:3rem!important}.ml-xl-5,.mx-xl-5{margin-left:3rem!important}.m-xl-6{margin:3.75rem!important}.mt-xl-6,.my-xl-6{margin-top:3.75rem!important}.mr-xl-6,.mx-xl-6{margin-right:3.75rem!important}.mb-xl-6,.my-xl-6{margin-bottom:3.75rem!important}.ml-xl-6,.mx-xl-6{margin-left:3.75rem!important}.m-xl-7{margin:4.5rem!important}.mt-xl-7,.my-xl-7{margin-top:4.5rem!important}.mr-xl-7,.mx-xl-7{margin-right:4.5rem!important}.mb-xl-7,.my-xl-7{margin-bottom:4.5rem!important}.ml-xl-7,.mx-xl-7{margin-left:4.5rem!important}.m-xl-8{margin:5rem!important}.mt-xl-8,.my-xl-8{margin-top:5rem!important}.mr-xl-8,.mx-xl-8{margin-right:5rem!important}.mb-xl-8,.my-xl-8{margin-bottom:5rem!important}.ml-xl-8,.mx-xl-8{margin-left:5rem!important}.p-xl-0{padding:0!important}.pt-xl-0,.py-xl-0{padding-top:0!important}.pr-xl-0,.px-xl-0{padding-right:0!important}.pb-xl-0,.py-xl-0{padding-bottom:0!important}.pl-xl-0,.px-xl-0{padding-left:0!important}.p-xl-1{padding:.25rem!important}.pt-xl-1,.py-xl-1{padding-top:.25rem!important}.pr-xl-1,.px-xl-1{padding-right:.25rem!important}.pb-xl-1,.py-xl-1{padding-bottom:.25rem!important}.pl-xl-1,.px-xl-1{padding-left:.25rem!important}.p-xl-2{padding:.5rem!important}.pt-xl-2,.py-xl-2{padding-top:.5rem!important}.pr-xl-2,.px-xl-2{padding-right:.5rem!important}.pb-xl-2,.py-xl-2{padding-bottom:.5rem!important}.pl-xl-2,.px-xl-2{padding-left:.5rem!important}.p-xl-3{padding:1rem!important}.pt-xl-3,.py-xl-3{padding-top:1rem!important}.pr-xl-3,.px-xl-3{padding-right:1rem!important}.pb-xl-3,.py-xl-3{padding-bottom:1rem!important}.pl-xl-3,.px-xl-3{padding-left:1rem!important}.p-xl-4{padding:1.5rem!important}.pt-xl-4,.py-xl-4{padding-top:1.5rem!important}.pr-xl-4,.px-xl-4{padding-right:1.5rem!important}.pb-xl-4,.py-xl-4{padding-bottom:1.5rem!important}.pl-xl-4,.px-xl-4{padding-left:1.5rem!important}.p-xl-5{padding:3rem!important}.pt-xl-5,.py-xl-5{padding-top:3rem!important}.pr-xl-5,.px-xl-5{padding-right:3rem!important}.pb-xl-5,.py-xl-5{padding-bottom:3rem!important}.pl-xl-5,.px-xl-5{padding-left:3rem!important}.p-xl-6{padding:3.75rem!important}.pt-xl-6,.py-xl-6{padding-top:3.75rem!important}.pr-xl-6,.px-xl-6{padding-right:3.75rem!important}.pb-xl-6,.py-xl-6{padding-bottom:3.75rem!important}.pl-xl-6,.px-xl-6{padding-left:3.75rem!important}.p-xl-7{padding:4.5rem!important}.pt-xl-7,.py-xl-7{padding-top:4.5rem!important}.pr-xl-7,.px-xl-7{padding-right:4.5rem!important}.pb-xl-7,.py-xl-7{padding-bottom:4.5rem!important}.pl-xl-7,.px-xl-7{padding-left:4.5rem!important}.p-xl-8{padding:5rem!important}.pt-xl-8,.py-xl-8{padding-top:5rem!important}.pr-xl-8,.px-xl-8{padding-right:5rem!important}.pb-xl-8,.py-xl-8{padding-bottom:5rem!important}.pl-xl-8,.px-xl-8{padding-left:5rem!important}.m-xl-n1{margin:-.25rem!important}.mt-xl-n1,.my-xl-n1{margin-top:-.25rem!important}.mr-xl-n1,.mx-xl-n1{margin-right:-.25rem!important}.mb-xl-n1,.my-xl-n1{margin-bottom:-.25rem!important}.ml-xl-n1,.mx-xl-n1{margin-left:-.25rem!important}.m-xl-n2{margin:-.5rem!important}.mt-xl-n2,.my-xl-n2{margin-top:-.5rem!important}.mr-xl-n2,.mx-xl-n2{margin-right:-.5rem!important}.mb-xl-n2,.my-xl-n2{margin-bottom:-.5rem!important}.ml-xl-n2,.mx-xl-n2{margin-left:-.5rem!important}.m-xl-n3{margin:-1rem!important}.mt-xl-n3,.my-xl-n3{margin-top:-1rem!important}.mr-xl-n3,.mx-xl-n3{margin-right:-1rem!important}.mb-xl-n3,.my-xl-n3{margin-bottom:-1rem!important}.ml-xl-n3,.mx-xl-n3{margin-left:-1rem!important}.m-xl-n4{margin:-1.5rem!important}.mt-xl-n4,.my-xl-n4{margin-top:-1.5rem!important}.mr-xl-n4,.mx-xl-n4{margin-right:-1.5rem!important}.mb-xl-n4,.my-xl-n4{margin-bottom:-1.5rem!important}.ml-xl-n4,.mx-xl-n4{margin-left:-1.5rem!important}.m-xl-n5{margin:-3rem!important}.mt-xl-n5,.my-xl-n5{margin-top:-3rem!important}.mr-xl-n5,.mx-xl-n5{margin-right:-3rem!important}.mb-xl-n5,.my-xl-n5{margin-bottom:-3rem!important}.ml-xl-n5,.mx-xl-n5{margin-left:-3rem!important}.m-xl-n6{margin:-3.75rem!important}.mt-xl-n6,.my-xl-n6{margin-top:-3.75rem!important}.mr-xl-n6,.mx-xl-n6{margin-right:-3.75rem!important}.mb-xl-n6,.my-xl-n6{margin-bottom:-3.75rem!important}.ml-xl-n6,.mx-xl-n6{margin-left:-3.75rem!important}.m-xl-n7{margin:-4.5rem!important}.mt-xl-n7,.my-xl-n7{margin-top:-4.5rem!important}.mr-xl-n7,.mx-xl-n7{margin-right:-4.5rem!important}.mb-xl-n7,.my-xl-n7{margin-bottom:-4.5rem!important}.ml-xl-n7,.mx-xl-n7{margin-left:-4.5rem!important}.m-xl-n8{margin:-5rem!important}.mt-xl-n8,.my-xl-n8{margin-top:-5rem!important}.mr-xl-n8,.mx-xl-n8{margin-right:-5rem!important}.mb-xl-n8,.my-xl-n8{margin-bottom:-5rem!important}.ml-xl-n8,.mx-xl-n8{margin-left:-5rem!important}.m-xl-auto{margin:auto!important}.mt-xl-auto,.my-xl-auto{margin-top:auto!important}.mr-xl-auto,.mx-xl-auto{margin-right:auto!important}.mb-xl-auto,.my-xl-auto{margin-bottom:auto!important}.ml-xl-auto,.mx-xl-auto{margin-left:auto!important}}.stretched-link:after{position:absolute;top:0;right:0;bottom:0;left:0;z-index:1;pointer-events:auto;content:"";background-color:transparent}.text-monospace{font-family:SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,monospace!important}.text-justify{text-align:justify!important}.text-wrap{white-space:normal!important}.text-nowrap{white-space:nowrap!important}.text-truncate{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.text-left{text-align:left!important}.text-right{text-align:right!important}.text-center{text-align:center!important}@media (min-width:576px){.text-sm-left{text-align:left!important}.text-sm-right{text-align:right!important}.text-sm-center{text-align:center!important}}@media (min-width:768px){.text-md-left{text-align:left!important}.text-md-right{text-align:right!important}.text-md-center{text-align:center!important}}@media (min-width:992px){.text-lg-left{text-align:left!important}.text-lg-right{text-align:right!important}.text-lg-center{text-align:center!important}}@media (min-width:1200px){.text-xl-left{text-align:left!important}.text-xl-right{text-align:right!important}.text-xl-center{text-align:center!important}}.text-lowercase{text-transform:lowercase!important}.text-uppercase{text-transform:uppercase!important}.text-capitalize{text-transform:capitalize!important}.font-weight-light{font-weight:300!important}.font-weight-lighter{font-weight:lighter!important}.font-weight-normal{font-weight:400!important}.font-weight-bold{font-weight:700!important}.font-weight-bolder{font-weight:bolder!important}.font-italic{font-style:italic!important}.text-white{color:#fff!important}.text-primary{color:#007bff!important}a.text-primary:focus,a.text-primary:hover{color:#0056b3!important}.text-secondary{color:#6c757d!important}a.text-secondary:focus,a.text-secondary:hover{color:#494f54!important}.text-success{color:#28a745!important}a.text-success:focus,a.text-success:hover{color:#19692c!important}.text-info{color:#17a2b8!important}a.text-info:focus,a.text-info:hover{color:#0f6674!important}.text-warning{color:#ffc107!important}a.text-warning:focus,a.text-warning:hover{color:#ba8b00!important}.text-danger{color:#dc3545!important}a.text-danger:focus,a.text-danger:hover{color:#a71d2a!important}.text-light{color:#f8f9fa!important}a.text-light:focus,a.text-light:hover{color:#cbd3da!important}.text-dark{color:#343a40!important}a.text-dark:focus,a.text-dark:hover{color:#121416!important}.text-body{color:#212529!important}.text-muted{color:#6c757d!important}.text-black-50{color:rgba(0,0,0,.5)!important}.text-white-50{color:hsla(0,0%,100%,.5)!important}.text-hide{font:0/0 a;color:transparent;text-shadow:none;background-color:transparent;border:0}.text-decoration-none{text-decoration:none!important}.text-break{word-break:break-word!important;word-wrap:break-word!important}.text-reset{color:inherit!important}.visible{visibility:visible!important}.invisible{visibility:hidden!important}.awesomplete>ul{background:#333;padding:0!important}.awesomplete>ul>li{padding:10px 15px;border-bottom:1px solid #707070;color:#efefef;font-size:17px}.awesomplete>ul>li:last-child{border-bottom:0}.awesomplete>ul>li[aria-selected=true]{background-color:#ff6f00}.awesomplete>ul>li:before{content:none!important}img{max-width:100%}div{min-width:0}body{color:#797f90;font-family:Arial,sans-serif;font-size:18px;line-height:1.5}@media (min-width:768px){body{font-size:18px}}.html__font-loaded--primary body{font-family:Open Sans,Arial,sans-serif}a{color:#ff6f00;text-decoration:underline}.h1,.h2,.h3,.h4,.h5,.h6,h1,h2,h3,h4,h5,h6{font-weight:600;color:#333}.typography-white .h1,.typography-white .h2,.typography-white .h3,.typography-white .h4,.typography-white .h5,.typography-white .h6,.typography-white h1,.typography-white h2,.typography-white h3,.typography-white h4,.typography-white h5,.typography-white h6{color:#fff}.h1.no-margin-top,.h2.no-margin-top,.h3.no-margin-top,.h4.no-margin-top,.h5.no-margin-top,.h6.no-margin-top,.no-margin-top .h1,.no-margin-top .h2,.no-margin-top .h3,.no-margin-top .h4,.no-margin-top .h5,.no-margin-top .h6,.no-margin-top h1,.no-margin-top h2,.no-margin-top h3,.no-margin-top h4,.no-margin-top h5,.no-margin-top h6,h1.no-margin-top,h2.no-margin-top,h3.no-margin-top,h4.no-margin-top,h5.no-margin-top,h6.no-margin-top{margin-top:0!important}.h1,h1{font-size:12vw;line-height:1.2}@media (min-width:410px){.h1,h1{font-size:42px}}@media (min-width:767px){.h1,h1{font-size:50px}}.h2,h2{font-size:36px;line-height:1.1}@media (min-width:768px){.h2,h2{font-size:40px}}.h3,h3{font-size:26px;line-height:1.1}@media (min-width:768px){.h3,h3{font-size:30px}}.h4,h4{font-size:22px}h5{font-size:20px}h6{font-size:18px}.pb-header .navbar{background:#333}@media (max-width:991px){.pb-header .navbar{padding-top:10px;padding-bottom:10px}}.pb-header .navbar-brand>img{display:block;max-width:140px;max-height:25px}.pb-header .dropdown-toggle:after{content:none}.pb-header .nav-item{padding-top:5px;padding-bottom:5px;margin-right:32px}.pb-header .nav-item:last-of-type{margin-right:0}@media (min-width:992px){.pb-header .nav-item{padding-top:34px;padding-bottom:24px}}.pb-header .nav-link{font-size:16px;text-decoration:none}@media (min-width:992px){.pb-header .nav-link[aria-expanded=true]:after{position:absolute;bottom:0;left:50%;height:0;width:0;border-color:transparent transparent #fff;border-style:solid;border-width:0 5.5px 8px;transform:translateX(-50%) translateY(0);z-index:5;content:""}}.pb-header .dropdown-menu{box-shadow:10px 10px 30px rgba(0,0,0,.16);-moz-column-rule:1px solid #dddfe3;column-rule:1px solid #dddfe3;padding:10px 0}@media (min-width:992px){.pb-header .dropdown-menu{padding:24px 0}.pb-header .dropdown-menu--product{-moz-columns:3;column-count:3;left:50%;transform:translateX(-50%)}.pb-header .dropdown-menu--support{-moz-columns:2;column-count:2;left:50%;transform:translateX(-50%)}.pb-header .dropdown-menu--resources{right:0;left:auto}.pb-header .dropdown-menu .dropdown-section{-moz-column-break-inside:avoid;break-inside:avoid-column}}.pb-header .dropdown-item{font-size:15px;text-decoration:none}.pb-header .dropdown-item--heading{font-weight:600;color:#333}.pb-header .dropdown-item--heading:hover{color:#ff6f00}@media (max-width:991px){.sidebar{margin-bottom:20px}}.sidebar a{text-decoration:none}.sidebar .navbar-toggler{color:rgba(0,0,0,.5);border-color:rgba(0,0,0,.1)}.sidebar .navbar-toggler-icon{background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='30' height='30'%3E%3Cpath stroke='rgba(0, 0, 0, 0.5)' stroke-linecap='round' stroke-miterlimit='10' stroke-width='2' d='M4 7h22M4 15h22M4 23h22'/%3E%3C/svg%3E")}.sidebar .collapse.is-active,.sidebar .list-group-item{display:block}.sidebar .list-group-item--level-0{position:relative;padding:9px 12px 11px 14px;border-top:1px solid #dddfe3;color:#797f90;font-size:20px}.sidebar .list-group-item--level-0:after{position:absolute;top:50%;right:12px;height:8px;width:15px;transform:translateY(-50%);background:url(/assets/images/icons/down-carrot-0.svg) no-repeat 0 0;content:""}.sidebar .list-group-item--level-0:last-of-type{border-bottom:1px solid #dddfe3}.sidebar .list-group-item--level-0>.pb-section-title{display:inline-block;padding-right:20px}.sidebar .list-group-item--level-0.is-active{background-color:#333;color:#fff}.sidebar .list-group-item--level-0.is-active:after{background-image:url(/assets/images/icons/up-carrot-0.svg)}.sidebar .list-group-item--level-0.is-active+.sidebar-submenu+.list-group-item{border-top:0}.sidebar .list-group-item--level-1{padding:8px 14px 9px;background-color:hsla(0,0%,100%,.25);border-bottom:1px solid #dddfe3;color:#797f90;font-size:18px}.sidebar .list-group-item--level-1.is-active{position:relative;color:#ff6f00}.sidebar .list-group-item--level-1.is-active:after{position:absolute;top:50%;right:15px;height:5px;width:10px;transform:translateY(-50%);background-image:url(/assets/images/icons/up-carrot-1.svg);background-repeat:no-repeat;background-position:0 0;content:""}.sidebar .list-group-item--level-1.is-active>.pb-section-subtitle{display:inline-block;padding-right:15px}.sidebar .list-group-item--level-1.is-active+.sidebar-submenu{background-color:hsla(0,0%,100%,.25)}.sidebar .list-group-item--level-1>.menu-collapsed.pb-nav-item.is-active{color:#ff6f00}.sidebar .list-group-item--level-2{padding:11px 14px 4px;background-color:hsla(0,0%,100%,.5);color:#797f90;font-size:15px}.sidebar .list-group-item--level-2:last-child{padding-bottom:11px;border-bottom:1px solid #dddfe3}.sidebar .list-group-item--level-2.is-active{color:#ff6f00}.sidebar .list-group-item--level-2>.pb-nav-item--title{display:block;margin-bottom:-8px;padding-bottom:5px;border-bottom:1px solid #999;color:#333}.pb-footer{padding-top:50px;padding-bottom:30px;background:#fff;font-size:12px;line-height:1.2}.banner--medium .card{background:none;border-color:hsla(0,0%,100%,.8)}.card-media{display:flex;justify-content:center;align-items:center}.card-deck--products .card-media{min-height:96px;margin-top:6px}.card-deck--products .card-title{margin-top:30px}.card-deck--md .card{margin-bottom:10px}@media (min-width:768px){.card-deck--md{display:flex;flex-flow:row wrap;margin-right:-10px;margin-left:-10px}.card-deck--md .card{flex:1 0 0%;margin-right:10px;margin-bottom:0;margin-left:10px}}.card-deck--formats .card{margin-bottom:10px;z-index:2}.card-deck--formats .card-body{display:flex;flex-flow:column-reverse;justify-content:space-around}.card-deck--formats .card-title{font-weight:600;margin-top:24px;margin-bottom:0;font-size:22px;line-height:1.2;color:#1ba9e1;text-decoration:none}.card-deck--formats .card-title:hover{color:#fff;z-index:2}.card-deck--formats .card-title:hover:before{position:absolute;top:0;right:0;bottom:0;left:0;z-index:-1;background-color:#ff6f00;content:""}.card-deck--formats .card-title:hover+.card-media{cursor:pointer;pointer-events:none}.card-deck--formats .card-title:hover+.card-media path{stroke:#fff}.card-deck--formats .card-title:hover+.card-media path[fill="#ff6f00"]{fill:#fff}.card-deck--formats .card-title+.card-media{position:relative;z-index:2}@media (min-width:576px){.card-deck--formats{display:flex;flex-flow:row wrap;justify-content:center;margin-right:-10px;margin-left:-10px}.card-deck--formats .card{flex:1 0 0%;min-width:180px;max-width:200px;margin-right:10px;margin-bottom:20px;margin-left:10px}}.banner--medium .card-deck .card{z-index:2}.banner--medium .card-deck .card-body{display:flex;flex-flow:column;justify-content:space-around}.banner--medium .card-deck .card-title{margin-top:24px;margin-bottom:0}.banner--medium .card-deck .card-title a{color:#fff;font-size:26px;text-decoration:none}.banner--medium .card-deck .card-title a:before{position:absolute;top:0;right:0;bottom:0;left:0;background-color:#ff6f00;opacity:0;z-index:-1;content:""}.banner--medium .card-deck .card-title a:hover:before{opacity:1}.banner{padding-top:4rem;padding-bottom:5.5rem}.banner--medium{background:#7e8c97;color:#fff}.banner--light{background:#fff;padding-bottom:0}.banner--light hr{margin-top:30px;border:0;border-top:1px solid rgba(221,223,227,.49);background:none}.btn-outline-brand{color:#1ba9e1;font-weight:700;padding:18px 32px 15px;border-color:#dddfe3;font-size:18px;text-decoration:none}.btn-outline-brand:hover{color:#fff;background-color:#1ba9e1;border-color:#1ba9e1}.btn-outline-brand.focus,.btn-outline-brand:focus{box-shadow:0 0 0 .2rem rgba(27,169,225,.5)}.btn-outline-brand.disabled,.btn-outline-brand:disabled{color:#1ba9e1;background-color:transparent}.btn-outline-brand:not(:disabled):not(.disabled).active,.btn-outline-brand:not(:disabled):not(.disabled):active,.show>.btn-outline-brand.dropdown-toggle{color:#fff;background-color:#1ba9e1;border-color:#1ba9e1}.btn-outline-brand:not(:disabled):not(.disabled).active:focus,.btn-outline-brand:not(:disabled):not(.disabled):active:focus,.show>.btn-outline-brand.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(27,169,225,.5)}@media (min-width:992px){.btn-outline-brand{padding-right:68px;padding-left:68px}}.pb-lg-img{width:70%;height:70%}.row>.wrapper{display:flex;flex-wrap:wrap;margin-right:-10px;margin-left:-10px}@media (min-width:992px){.pb-docs-container>.row>.col-lg-3.sidebar{flex:0 0 22%;max-width:22%}.pb-docs-container>.row>.col-lg-3.sidebar+.col-lg-9{flex:0 0 78%;max-width:78%}}.pb-docs-container+.pb-footer{margin-top:180px}.pb-content{padding:22px 30px;border:1px solid #dddfe3;background-color:#fff;font-size:19px;line-height:1.5789473684}.pb-content>.pb-content{margin:0;padding:0;border:none}.pb-content h1{margin-bottom:20px;padding-bottom:14px;border-bottom:1px solid #dddfe3;font-size:46.379px}.pb-content h2{margin-top:35px;margin-bottom:16px;font-size:37.107px}.pb-content h3{margin-top:28px;font-size:29.697px}.pb-content h4{margin-top:20px;font-size:23.75px}.pb-content h5{margin-top:16px;font-size:19px;font-style:italic}.pb-content ul{padding-left:20px;list-style:none}.pb-content ul li:not(.ui-tab){position:relative}.pb-content ul li:not(.ui-tab):before{position:absolute;top:10px;left:-20px;height:7px;width:7px;border:1px solid #707070;border-radius:50%;background:#333;content:""}.pb-content table.pbTable,.pb-content table.table{font-size:16px;line-height:1.75}.pb-content table.pbTable th,.pb-content table.table th{padding-top:9px;padding-bottom:9px;font-weight:600}.pb-content table.pbTable td,.pb-content table.pbTable th,.pb-content table.table td,.pb-content table.table th{padding-right:15px;padding-left:15px}.pb-content .pb-code-hl-wrap{width:100%}.pb-content .highlight,.pb-content .pb-code-hl{margin-top:20px;margin-bottom:20px;padding:20px 22px;border:1px solid #dddfe3;background:#f8f9f9;font-size:16px}.pb-content .highlight pre,.pb-content .pb-code-hl pre{margin-top:0;margin-bottom:0;padding:0;border:0;background:none}.pb-docs-container{margin-top:20px}@media (min-width:992px){.pb-docs-container{margin-top:65px}}.pb-alert{margin-top:10px}.center-image{margin:0 auto;display:block}.social-media{display:flex;align-items:center}@media (min-width:992px){.social-media{justify-content:flex-end;margin-top:100px}}.social-media a,.social-media h5{margin-right:22px;margin-bottom:0}.social-media h5{font-size:18px}.social-media a:last-child{margin-right:0}table.pbTable,table.table{background:#fff}.pbTable thead td,.pbTable thead th,.table-bordered thead td,.table-bordered thead th{border-bottom-width:1px}.download-form{margin-bottom:20px}.download-form>.row{flex-flow:column}.download-form .adapters{display:flex;flex-flow:row wrap}.download-form__modal,.modal-backdrop.fade{opacity:0}.pb-content .autocomplete-filter{padding:10px 15px;border:1px solid #b3c1cc;background-color:rgba(236,243,245,.35)}.pb-content .autocomplete-filter:focus{outline:none}.pb-content .c-bidder-list-group h4{color:#797f90;font-size:19px;font-weight:700}.pb-content .c-bidder-list{padding-left:0;-moz-columns:2;column-count:2}.pb-content .c-bidder-list li{padding-bottom:5px}.pb-content .c-bidder-list li:before{content:none!important}.pb-content .c-bidder-list a{text-decoration:none}.algolia-autocomplete .algolia-docsearch-suggestion--category-header{display:none!important}.c-search{position:relative}@media (max-width:990px){.c-search{float:left}}.c-search:after{position:absolute;top:50%;right:10px;height:20px;width:20px;transform:translateY(-50%);background:url(/assets/images/icons/search-icon2.svg);background-size:cover;content:""}.c-search input[type=search]{padding-right:8px;padding-left:8px;border:1px solid rgba(0,0,0,.125);max-width:120px;transition:max-width .2s ease-in-out}.c-search input[type=search]:focus,.c-search input[type=search]:hover{max-width:200px;outline:none}.c-search input[type=search]::-ms-clear,.c-search input[type=search]::-ms-reveal{display:none;width:0;height:0}.c-search input[type=search]::-webkit-search-cancel-button,.c-search input[type=search]::-webkit-search-decoration,.c-search input[type=search]::-webkit-search-results-button,.c-search input[type=search]::-webkit-search-results-decoration{display:none}.pb-homepage .h1,.pb-homepage h1{font-size:12vw;margin-bottom:.75rem}@media (min-width:768px){.pb-homepage .h1,.pb-homepage h1{font-size:40px}}.error404{width:100%;height:100%;text-align:center}.error404 h1{color:red;font-size:60px;font-weight:700} \ No newline at end of file +.awesomplete [hidden]{display:none}.awesomplete .visually-hidden{position:absolute;clip:rect(0,0,0,0)}.awesomplete{display:inline-block;position:relative}.awesomplete>input{display:block}.awesomplete>ul{position:absolute;left:0;z-index:1;min-width:100%;box-sizing:border-box;list-style:none;padding:0;margin:0;background:#fff}.awesomplete>ul:empty{display:none}*,:after,:before{box-sizing:border-box}html{font-family:sans-serif;line-height:1.15;-webkit-text-size-adjust:100%;-webkit-tap-highlight-color:rgba(0,0,0,0)}article,aside,figcaption,figure,footer,header,hgroup,main,nav,section{display:block}body{margin:0;font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Helvetica Neue,Arial,Noto Sans,sans-serif,Apple Color Emoji,Segoe UI Emoji,Segoe UI Symbol,Noto Color Emoji;font-size:1rem;font-weight:400;color:#212529;text-align:left;background-color:#eceeef}[tabindex="-1"]:focus:not(:focus-visible){outline:0!important}hr{box-sizing:content-box;height:0;overflow:visible}h1,h2,h3,h4,h5,h6{margin-top:0;margin-bottom:.5rem}p{margin-top:0;margin-bottom:1rem}abbr[data-original-title],abbr[title]{text-decoration:underline;-webkit-text-decoration:underline dotted;text-decoration:underline dotted;cursor:help;border-bottom:0;-webkit-text-decoration-skip-ink:none;text-decoration-skip-ink:none}address{font-style:normal;line-height:inherit}address,dl,ol,ul{margin-bottom:1rem}dl,ol,ul{margin-top:0}ol ol,ol ul,ul ol,ul ul{margin-bottom:0}dt{font-weight:700}dd{margin-bottom:.5rem;margin-left:0}blockquote{margin:0 0 1rem}b,strong{font-weight:bolder}small{font-size:80%}sub,sup{position:relative;font-size:75%;line-height:0;vertical-align:baseline}sub{bottom:-.25em}sup{top:-.5em}a{color:#007bff;text-decoration:none;background-color:transparent}a:hover{color:#0056b3;text-decoration:underline}a:not([href]):not([class]),a:not([href]):not([class]):hover{color:inherit;text-decoration:none}code,kbd,pre,samp{font-family:SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,monospace;font-size:1em}pre{margin-top:0;margin-bottom:1rem;overflow:auto;-ms-overflow-style:scrollbar}figure{margin:0 0 1rem}img{border-style:none}img,svg{vertical-align:middle}svg{overflow:hidden}table{border-collapse:collapse}caption{padding-top:.75rem;padding-bottom:.75rem;color:#6c757d;text-align:left;caption-side:bottom}th{text-align:inherit;text-align:-webkit-match-parent}label{display:inline-block;margin-bottom:.5rem}button{border-radius:0}button:focus{outline:1px dotted;outline:5px auto -webkit-focus-ring-color}button,input,optgroup,select,textarea{margin:0;font-family:inherit;font-size:inherit;line-height:inherit}button,input{overflow:visible}button,select{text-transform:none}[role=button]{cursor:pointer}select{word-wrap:normal}[type=button],[type=reset],[type=submit],button{-webkit-appearance:button}[type=button]:not(:disabled),[type=reset]:not(:disabled),[type=submit]:not(:disabled),button:not(:disabled){cursor:pointer}[type=button]::-moz-focus-inner,[type=reset]::-moz-focus-inner,[type=submit]::-moz-focus-inner,button::-moz-focus-inner{padding:0;border-style:none}input[type=checkbox],input[type=radio]{box-sizing:border-box;padding:0}textarea{overflow:auto;resize:vertical}fieldset{min-width:0;padding:0;margin:0;border:0}legend{display:block;width:100%;max-width:100%;padding:0;margin-bottom:.5rem;font-size:1.5rem;line-height:inherit;color:inherit;white-space:normal}progress{vertical-align:baseline}[type=number]::-webkit-inner-spin-button,[type=number]::-webkit-outer-spin-button{height:auto}[type=search]{outline-offset:-2px;-webkit-appearance:none}[type=search]::-webkit-search-decoration{-webkit-appearance:none}::-webkit-file-upload-button{font:inherit;-webkit-appearance:button}output{display:inline-block}summary{display:list-item;cursor:pointer}template{display:none}[hidden]{display:none!important}.container,.container-fluid,.container-lg,.container-md,.container-sm,.container-xl{width:100%;padding-right:10px;padding-left:10px;margin-right:auto;margin-left:auto}@media (min-width:576px){.container,.container-sm{max-width:540px}}@media (min-width:768px){.container,.container-md,.container-sm{max-width:720px}}@media (min-width:992px){.container,.container-lg,.container-md,.container-sm{max-width:960px}}@media (min-width:1200px){.container,.container-lg,.container-md,.container-sm,.container-xl{max-width:1200px}}.row{display:flex;flex-wrap:wrap;margin-right:-10px;margin-left:-10px}.no-gutters{margin-right:0;margin-left:0}.no-gutters>.col,.no-gutters>[class*=col-]{padding-right:0;padding-left:0}.col,.col-1,.col-2,.col-3,.col-4,.col-5,.col-6,.col-7,.col-8,.col-9,.col-10,.col-11,.col-12,.col-auto,.col-lg,.col-lg-1,.col-lg-2,.col-lg-3,.col-lg-4,.col-lg-5,.col-lg-6,.col-lg-7,.col-lg-8,.col-lg-9,.col-lg-10,.col-lg-11,.col-lg-12,.col-lg-auto,.col-md,.col-md-1,.col-md-2,.col-md-3,.col-md-4,.col-md-5,.col-md-6,.col-md-7,.col-md-8,.col-md-9,.col-md-10,.col-md-11,.col-md-12,.col-md-auto,.col-sm,.col-sm-1,.col-sm-2,.col-sm-3,.col-sm-4,.col-sm-5,.col-sm-6,.col-sm-7,.col-sm-8,.col-sm-9,.col-sm-10,.col-sm-11,.col-sm-12,.col-sm-auto,.col-xl,.col-xl-1,.col-xl-2,.col-xl-3,.col-xl-4,.col-xl-5,.col-xl-6,.col-xl-7,.col-xl-8,.col-xl-9,.col-xl-10,.col-xl-11,.col-xl-12,.col-xl-auto{position:relative;width:100%;padding-right:10px;padding-left:10px}.col{flex-basis:0;flex-grow:1;max-width:100%}.row-cols-1>*{flex:0 0 100%;max-width:100%}.row-cols-2>*{flex:0 0 50%;max-width:50%}.row-cols-3>*{flex:0 0 33.3333333333%;max-width:33.3333333333%}.row-cols-4>*{flex:0 0 25%;max-width:25%}.row-cols-5>*{flex:0 0 20%;max-width:20%}.row-cols-6>*{flex:0 0 16.6666666667%;max-width:16.6666666667%}.col-auto{flex:0 0 auto;width:auto;max-width:100%}.col-1{flex:0 0 8.3333333333%;max-width:8.3333333333%}.col-2{flex:0 0 16.6666666667%;max-width:16.6666666667%}.col-3{flex:0 0 25%;max-width:25%}.col-4{flex:0 0 33.3333333333%;max-width:33.3333333333%}.col-5{flex:0 0 41.6666666667%;max-width:41.6666666667%}.col-6{flex:0 0 50%;max-width:50%}.col-7{flex:0 0 58.3333333333%;max-width:58.3333333333%}.col-8{flex:0 0 66.6666666667%;max-width:66.6666666667%}.col-9{flex:0 0 75%;max-width:75%}.col-10{flex:0 0 83.3333333333%;max-width:83.3333333333%}.col-11{flex:0 0 91.6666666667%;max-width:91.6666666667%}.col-12{flex:0 0 100%;max-width:100%}.order-first{order:-1}.order-last{order:13}.order-0{order:0}.order-1{order:1}.order-2{order:2}.order-3{order:3}.order-4{order:4}.order-5{order:5}.order-6{order:6}.order-7{order:7}.order-8{order:8}.order-9{order:9}.order-10{order:10}.order-11{order:11}.order-12{order:12}.offset-1{margin-left:8.3333333333%}.offset-2{margin-left:16.6666666667%}.offset-3{margin-left:25%}.offset-4{margin-left:33.3333333333%}.offset-5{margin-left:41.6666666667%}.offset-6{margin-left:50%}.offset-7{margin-left:58.3333333333%}.offset-8{margin-left:66.6666666667%}.offset-9{margin-left:75%}.offset-10{margin-left:83.3333333333%}.offset-11{margin-left:91.6666666667%}@media (min-width:576px){.col-sm{flex-basis:0;flex-grow:1;max-width:100%}.row-cols-sm-1>*{flex:0 0 100%;max-width:100%}.row-cols-sm-2>*{flex:0 0 50%;max-width:50%}.row-cols-sm-3>*{flex:0 0 33.3333333333%;max-width:33.3333333333%}.row-cols-sm-4>*{flex:0 0 25%;max-width:25%}.row-cols-sm-5>*{flex:0 0 20%;max-width:20%}.row-cols-sm-6>*{flex:0 0 16.6666666667%;max-width:16.6666666667%}.col-sm-auto{flex:0 0 auto;width:auto;max-width:100%}.col-sm-1{flex:0 0 8.3333333333%;max-width:8.3333333333%}.col-sm-2{flex:0 0 16.6666666667%;max-width:16.6666666667%}.col-sm-3{flex:0 0 25%;max-width:25%}.col-sm-4{flex:0 0 33.3333333333%;max-width:33.3333333333%}.col-sm-5{flex:0 0 41.6666666667%;max-width:41.6666666667%}.col-sm-6{flex:0 0 50%;max-width:50%}.col-sm-7{flex:0 0 58.3333333333%;max-width:58.3333333333%}.col-sm-8{flex:0 0 66.6666666667%;max-width:66.6666666667%}.col-sm-9{flex:0 0 75%;max-width:75%}.col-sm-10{flex:0 0 83.3333333333%;max-width:83.3333333333%}.col-sm-11{flex:0 0 91.6666666667%;max-width:91.6666666667%}.col-sm-12{flex:0 0 100%;max-width:100%}.order-sm-first{order:-1}.order-sm-last{order:13}.order-sm-0{order:0}.order-sm-1{order:1}.order-sm-2{order:2}.order-sm-3{order:3}.order-sm-4{order:4}.order-sm-5{order:5}.order-sm-6{order:6}.order-sm-7{order:7}.order-sm-8{order:8}.order-sm-9{order:9}.order-sm-10{order:10}.order-sm-11{order:11}.order-sm-12{order:12}.offset-sm-0{margin-left:0}.offset-sm-1{margin-left:8.3333333333%}.offset-sm-2{margin-left:16.6666666667%}.offset-sm-3{margin-left:25%}.offset-sm-4{margin-left:33.3333333333%}.offset-sm-5{margin-left:41.6666666667%}.offset-sm-6{margin-left:50%}.offset-sm-7{margin-left:58.3333333333%}.offset-sm-8{margin-left:66.6666666667%}.offset-sm-9{margin-left:75%}.offset-sm-10{margin-left:83.3333333333%}.offset-sm-11{margin-left:91.6666666667%}}@media (min-width:768px){.col-md{flex-basis:0;flex-grow:1;max-width:100%}.row-cols-md-1>*{flex:0 0 100%;max-width:100%}.row-cols-md-2>*{flex:0 0 50%;max-width:50%}.row-cols-md-3>*{flex:0 0 33.3333333333%;max-width:33.3333333333%}.row-cols-md-4>*{flex:0 0 25%;max-width:25%}.row-cols-md-5>*{flex:0 0 20%;max-width:20%}.row-cols-md-6>*{flex:0 0 16.6666666667%;max-width:16.6666666667%}.col-md-auto{flex:0 0 auto;width:auto;max-width:100%}.col-md-1{flex:0 0 8.3333333333%;max-width:8.3333333333%}.col-md-2{flex:0 0 16.6666666667%;max-width:16.6666666667%}.col-md-3{flex:0 0 25%;max-width:25%}.col-md-4{flex:0 0 33.3333333333%;max-width:33.3333333333%}.col-md-5{flex:0 0 41.6666666667%;max-width:41.6666666667%}.col-md-6{flex:0 0 50%;max-width:50%}.col-md-7{flex:0 0 58.3333333333%;max-width:58.3333333333%}.col-md-8{flex:0 0 66.6666666667%;max-width:66.6666666667%}.col-md-9{flex:0 0 75%;max-width:75%}.col-md-10{flex:0 0 83.3333333333%;max-width:83.3333333333%}.col-md-11{flex:0 0 91.6666666667%;max-width:91.6666666667%}.col-md-12{flex:0 0 100%;max-width:100%}.order-md-first{order:-1}.order-md-last{order:13}.order-md-0{order:0}.order-md-1{order:1}.order-md-2{order:2}.order-md-3{order:3}.order-md-4{order:4}.order-md-5{order:5}.order-md-6{order:6}.order-md-7{order:7}.order-md-8{order:8}.order-md-9{order:9}.order-md-10{order:10}.order-md-11{order:11}.order-md-12{order:12}.offset-md-0{margin-left:0}.offset-md-1{margin-left:8.3333333333%}.offset-md-2{margin-left:16.6666666667%}.offset-md-3{margin-left:25%}.offset-md-4{margin-left:33.3333333333%}.offset-md-5{margin-left:41.6666666667%}.offset-md-6{margin-left:50%}.offset-md-7{margin-left:58.3333333333%}.offset-md-8{margin-left:66.6666666667%}.offset-md-9{margin-left:75%}.offset-md-10{margin-left:83.3333333333%}.offset-md-11{margin-left:91.6666666667%}}@media (min-width:992px){.col-lg{flex-basis:0;flex-grow:1;max-width:100%}.row-cols-lg-1>*{flex:0 0 100%;max-width:100%}.row-cols-lg-2>*{flex:0 0 50%;max-width:50%}.row-cols-lg-3>*{flex:0 0 33.3333333333%;max-width:33.3333333333%}.row-cols-lg-4>*{flex:0 0 25%;max-width:25%}.row-cols-lg-5>*{flex:0 0 20%;max-width:20%}.row-cols-lg-6>*{flex:0 0 16.6666666667%;max-width:16.6666666667%}.col-lg-auto{flex:0 0 auto;width:auto;max-width:100%}.col-lg-1{flex:0 0 8.3333333333%;max-width:8.3333333333%}.col-lg-2{flex:0 0 16.6666666667%;max-width:16.6666666667%}.col-lg-3{flex:0 0 25%;max-width:25%}.col-lg-4{flex:0 0 33.3333333333%;max-width:33.3333333333%}.col-lg-5{flex:0 0 41.6666666667%;max-width:41.6666666667%}.col-lg-6{flex:0 0 50%;max-width:50%}.col-lg-7{flex:0 0 58.3333333333%;max-width:58.3333333333%}.col-lg-8{flex:0 0 66.6666666667%;max-width:66.6666666667%}.col-lg-9{flex:0 0 75%;max-width:75%}.col-lg-10{flex:0 0 83.3333333333%;max-width:83.3333333333%}.col-lg-11{flex:0 0 91.6666666667%;max-width:91.6666666667%}.col-lg-12{flex:0 0 100%;max-width:100%}.order-lg-first{order:-1}.order-lg-last{order:13}.order-lg-0{order:0}.order-lg-1{order:1}.order-lg-2{order:2}.order-lg-3{order:3}.order-lg-4{order:4}.order-lg-5{order:5}.order-lg-6{order:6}.order-lg-7{order:7}.order-lg-8{order:8}.order-lg-9{order:9}.order-lg-10{order:10}.order-lg-11{order:11}.order-lg-12{order:12}.offset-lg-0{margin-left:0}.offset-lg-1{margin-left:8.3333333333%}.offset-lg-2{margin-left:16.6666666667%}.offset-lg-3{margin-left:25%}.offset-lg-4{margin-left:33.3333333333%}.offset-lg-5{margin-left:41.6666666667%}.offset-lg-6{margin-left:50%}.offset-lg-7{margin-left:58.3333333333%}.offset-lg-8{margin-left:66.6666666667%}.offset-lg-9{margin-left:75%}.offset-lg-10{margin-left:83.3333333333%}.offset-lg-11{margin-left:91.6666666667%}}@media (min-width:1200px){.col-xl{flex-basis:0;flex-grow:1;max-width:100%}.row-cols-xl-1>*{flex:0 0 100%;max-width:100%}.row-cols-xl-2>*{flex:0 0 50%;max-width:50%}.row-cols-xl-3>*{flex:0 0 33.3333333333%;max-width:33.3333333333%}.row-cols-xl-4>*{flex:0 0 25%;max-width:25%}.row-cols-xl-5>*{flex:0 0 20%;max-width:20%}.row-cols-xl-6>*{flex:0 0 16.6666666667%;max-width:16.6666666667%}.col-xl-auto{flex:0 0 auto;width:auto;max-width:100%}.col-xl-1{flex:0 0 8.3333333333%;max-width:8.3333333333%}.col-xl-2{flex:0 0 16.6666666667%;max-width:16.6666666667%}.col-xl-3{flex:0 0 25%;max-width:25%}.col-xl-4{flex:0 0 33.3333333333%;max-width:33.3333333333%}.col-xl-5{flex:0 0 41.6666666667%;max-width:41.6666666667%}.col-xl-6{flex:0 0 50%;max-width:50%}.col-xl-7{flex:0 0 58.3333333333%;max-width:58.3333333333%}.col-xl-8{flex:0 0 66.6666666667%;max-width:66.6666666667%}.col-xl-9{flex:0 0 75%;max-width:75%}.col-xl-10{flex:0 0 83.3333333333%;max-width:83.3333333333%}.col-xl-11{flex:0 0 91.6666666667%;max-width:91.6666666667%}.col-xl-12{flex:0 0 100%;max-width:100%}.order-xl-first{order:-1}.order-xl-last{order:13}.order-xl-0{order:0}.order-xl-1{order:1}.order-xl-2{order:2}.order-xl-3{order:3}.order-xl-4{order:4}.order-xl-5{order:5}.order-xl-6{order:6}.order-xl-7{order:7}.order-xl-8{order:8}.order-xl-9{order:9}.order-xl-10{order:10}.order-xl-11{order:11}.order-xl-12{order:12}.offset-xl-0{margin-left:0}.offset-xl-1{margin-left:8.3333333333%}.offset-xl-2{margin-left:16.6666666667%}.offset-xl-3{margin-left:25%}.offset-xl-4{margin-left:33.3333333333%}.offset-xl-5{margin-left:41.6666666667%}.offset-xl-6{margin-left:50%}.offset-xl-7{margin-left:58.3333333333%}.offset-xl-8{margin-left:66.6666666667%}.offset-xl-9{margin-left:75%}.offset-xl-10{margin-left:83.3333333333%}.offset-xl-11{margin-left:91.6666666667%}}.btn{display:inline-block;font-weight:400;color:#212529;text-align:center;vertical-align:middle;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;background-color:transparent;border:1px solid transparent;padding:.375rem .75rem;font-size:1rem;line-height:1.5;border-radius:.25rem;transition:color .15s ease-in-out,background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out}@media (prefers-reduced-motion:reduce){.btn{transition:none}}.btn:hover{color:#212529;text-decoration:none}.btn.focus,.btn:focus{outline:0;box-shadow:0 0 0 .2rem rgba(0,123,255,.25)}.btn.disabled,.btn:disabled{opacity:.65}.btn:not(:disabled):not(.disabled){cursor:pointer}a.btn.disabled,fieldset:disabled a.btn{pointer-events:none}.btn-primary{color:#fff;background-color:#007bff;border-color:#007bff}.btn-primary.focus,.btn-primary:focus,.btn-primary:hover{color:#fff;background-color:#0069d9;border-color:#0062cc}.btn-primary.focus,.btn-primary:focus{box-shadow:0 0 0 .2rem rgba(38,143,255,.5)}.btn-primary.disabled,.btn-primary:disabled{color:#fff;background-color:#007bff;border-color:#007bff}.btn-primary:not(:disabled):not(.disabled).active,.btn-primary:not(:disabled):not(.disabled):active,.show>.btn-primary.dropdown-toggle{color:#fff;background-color:#0062cc;border-color:#005cbf}.btn-primary:not(:disabled):not(.disabled).active:focus,.btn-primary:not(:disabled):not(.disabled):active:focus,.show>.btn-primary.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(38,143,255,.5)}.btn-secondary{color:#fff;background-color:#6c757d;border-color:#6c757d}.btn-secondary.focus,.btn-secondary:focus,.btn-secondary:hover{color:#fff;background-color:#5a6268;border-color:#545b62}.btn-secondary.focus,.btn-secondary:focus{box-shadow:0 0 0 .2rem rgba(130,138,145,.5)}.btn-secondary.disabled,.btn-secondary:disabled{color:#fff;background-color:#6c757d;border-color:#6c757d}.btn-secondary:not(:disabled):not(.disabled).active,.btn-secondary:not(:disabled):not(.disabled):active,.show>.btn-secondary.dropdown-toggle{color:#fff;background-color:#545b62;border-color:#4e555b}.btn-secondary:not(:disabled):not(.disabled).active:focus,.btn-secondary:not(:disabled):not(.disabled):active:focus,.show>.btn-secondary.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(130,138,145,.5)}.btn-success{color:#fff;background-color:#28a745;border-color:#28a745}.btn-success.focus,.btn-success:focus,.btn-success:hover{color:#fff;background-color:#218838;border-color:#1e7e34}.btn-success.focus,.btn-success:focus{box-shadow:0 0 0 .2rem rgba(72,180,97,.5)}.btn-success.disabled,.btn-success:disabled{color:#fff;background-color:#28a745;border-color:#28a745}.btn-success:not(:disabled):not(.disabled).active,.btn-success:not(:disabled):not(.disabled):active,.show>.btn-success.dropdown-toggle{color:#fff;background-color:#1e7e34;border-color:#1c7430}.btn-success:not(:disabled):not(.disabled).active:focus,.btn-success:not(:disabled):not(.disabled):active:focus,.show>.btn-success.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(72,180,97,.5)}.btn-info{color:#fff;background-color:#17a2b8;border-color:#17a2b8}.btn-info.focus,.btn-info:focus,.btn-info:hover{color:#fff;background-color:#138496;border-color:#117a8b}.btn-info.focus,.btn-info:focus{box-shadow:0 0 0 .2rem rgba(58,176,195,.5)}.btn-info.disabled,.btn-info:disabled{color:#fff;background-color:#17a2b8;border-color:#17a2b8}.btn-info:not(:disabled):not(.disabled).active,.btn-info:not(:disabled):not(.disabled):active,.show>.btn-info.dropdown-toggle{color:#fff;background-color:#117a8b;border-color:#10707f}.btn-info:not(:disabled):not(.disabled).active:focus,.btn-info:not(:disabled):not(.disabled):active:focus,.show>.btn-info.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(58,176,195,.5)}.btn-warning{color:#212529;background-color:#ffc107;border-color:#ffc107}.btn-warning.focus,.btn-warning:focus,.btn-warning:hover{color:#212529;background-color:#e0a800;border-color:#d39e00}.btn-warning.focus,.btn-warning:focus{box-shadow:0 0 0 .2rem rgba(222,170,12,.5)}.btn-warning.disabled,.btn-warning:disabled{color:#212529;background-color:#ffc107;border-color:#ffc107}.btn-warning:not(:disabled):not(.disabled).active,.btn-warning:not(:disabled):not(.disabled):active,.show>.btn-warning.dropdown-toggle{color:#212529;background-color:#d39e00;border-color:#c69500}.btn-warning:not(:disabled):not(.disabled).active:focus,.btn-warning:not(:disabled):not(.disabled):active:focus,.show>.btn-warning.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(222,170,12,.5)}.btn-danger{color:#fff;background-color:#dc3545;border-color:#dc3545}.btn-danger.focus,.btn-danger:focus,.btn-danger:hover{color:#fff;background-color:#c82333;border-color:#bd2130}.btn-danger.focus,.btn-danger:focus{box-shadow:0 0 0 .2rem rgba(225,83,97,.5)}.btn-danger.disabled,.btn-danger:disabled{color:#fff;background-color:#dc3545;border-color:#dc3545}.btn-danger:not(:disabled):not(.disabled).active,.btn-danger:not(:disabled):not(.disabled):active,.show>.btn-danger.dropdown-toggle{color:#fff;background-color:#bd2130;border-color:#b21f2d}.btn-danger:not(:disabled):not(.disabled).active:focus,.btn-danger:not(:disabled):not(.disabled):active:focus,.show>.btn-danger.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(225,83,97,.5)}.btn-light{color:#212529;background-color:#f8f9fa;border-color:#f8f9fa}.btn-light.focus,.btn-light:focus,.btn-light:hover{color:#212529;background-color:#e2e6ea;border-color:#dae0e5}.btn-light.focus,.btn-light:focus{box-shadow:0 0 0 .2rem rgba(216,217,219,.5)}.btn-light.disabled,.btn-light:disabled{color:#212529;background-color:#f8f9fa;border-color:#f8f9fa}.btn-light:not(:disabled):not(.disabled).active,.btn-light:not(:disabled):not(.disabled):active,.show>.btn-light.dropdown-toggle{color:#212529;background-color:#dae0e5;border-color:#d3d9df}.btn-light:not(:disabled):not(.disabled).active:focus,.btn-light:not(:disabled):not(.disabled):active:focus,.show>.btn-light.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(216,217,219,.5)}.btn-dark{color:#fff;background-color:#343a40;border-color:#343a40}.btn-dark.focus,.btn-dark:focus,.btn-dark:hover{color:#fff;background-color:#23272b;border-color:#1d2124}.btn-dark.focus,.btn-dark:focus{box-shadow:0 0 0 .2rem rgba(82,88,93,.5)}.btn-dark.disabled,.btn-dark:disabled{color:#fff;background-color:#343a40;border-color:#343a40}.btn-dark:not(:disabled):not(.disabled).active,.btn-dark:not(:disabled):not(.disabled):active,.show>.btn-dark.dropdown-toggle{color:#fff;background-color:#1d2124;border-color:#171a1d}.btn-dark:not(:disabled):not(.disabled).active:focus,.btn-dark:not(:disabled):not(.disabled):active:focus,.show>.btn-dark.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(82,88,93,.5)}.btn-outline-primary{color:#007bff;border-color:#007bff}.btn-outline-primary:hover{color:#fff;background-color:#007bff;border-color:#007bff}.btn-outline-primary.focus,.btn-outline-primary:focus{box-shadow:0 0 0 .2rem rgba(0,123,255,.5)}.btn-outline-primary.disabled,.btn-outline-primary:disabled{color:#007bff;background-color:transparent}.btn-outline-primary:not(:disabled):not(.disabled).active,.btn-outline-primary:not(:disabled):not(.disabled):active,.show>.btn-outline-primary.dropdown-toggle{color:#fff;background-color:#007bff;border-color:#007bff}.btn-outline-primary:not(:disabled):not(.disabled).active:focus,.btn-outline-primary:not(:disabled):not(.disabled):active:focus,.show>.btn-outline-primary.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(0,123,255,.5)}.btn-outline-secondary{color:#6c757d;border-color:#6c757d}.btn-outline-secondary:hover{color:#fff;background-color:#6c757d;border-color:#6c757d}.btn-outline-secondary.focus,.btn-outline-secondary:focus{box-shadow:0 0 0 .2rem rgba(108,117,125,.5)}.btn-outline-secondary.disabled,.btn-outline-secondary:disabled{color:#6c757d;background-color:transparent}.btn-outline-secondary:not(:disabled):not(.disabled).active,.btn-outline-secondary:not(:disabled):not(.disabled):active,.show>.btn-outline-secondary.dropdown-toggle{color:#fff;background-color:#6c757d;border-color:#6c757d}.btn-outline-secondary:not(:disabled):not(.disabled).active:focus,.btn-outline-secondary:not(:disabled):not(.disabled):active:focus,.show>.btn-outline-secondary.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(108,117,125,.5)}.btn-outline-success{color:#28a745;border-color:#28a745}.btn-outline-success:hover{color:#fff;background-color:#28a745;border-color:#28a745}.btn-outline-success.focus,.btn-outline-success:focus{box-shadow:0 0 0 .2rem rgba(40,167,69,.5)}.btn-outline-success.disabled,.btn-outline-success:disabled{color:#28a745;background-color:transparent}.btn-outline-success:not(:disabled):not(.disabled).active,.btn-outline-success:not(:disabled):not(.disabled):active,.show>.btn-outline-success.dropdown-toggle{color:#fff;background-color:#28a745;border-color:#28a745}.btn-outline-success:not(:disabled):not(.disabled).active:focus,.btn-outline-success:not(:disabled):not(.disabled):active:focus,.show>.btn-outline-success.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(40,167,69,.5)}.btn-outline-info{color:#17a2b8;border-color:#17a2b8}.btn-outline-info:hover{color:#fff;background-color:#17a2b8;border-color:#17a2b8}.btn-outline-info.focus,.btn-outline-info:focus{box-shadow:0 0 0 .2rem rgba(23,162,184,.5)}.btn-outline-info.disabled,.btn-outline-info:disabled{color:#17a2b8;background-color:transparent}.btn-outline-info:not(:disabled):not(.disabled).active,.btn-outline-info:not(:disabled):not(.disabled):active,.show>.btn-outline-info.dropdown-toggle{color:#fff;background-color:#17a2b8;border-color:#17a2b8}.btn-outline-info:not(:disabled):not(.disabled).active:focus,.btn-outline-info:not(:disabled):not(.disabled):active:focus,.show>.btn-outline-info.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(23,162,184,.5)}.btn-outline-warning{color:#ffc107;border-color:#ffc107}.btn-outline-warning:hover{color:#212529;background-color:#ffc107;border-color:#ffc107}.btn-outline-warning.focus,.btn-outline-warning:focus{box-shadow:0 0 0 .2rem rgba(255,193,7,.5)}.btn-outline-warning.disabled,.btn-outline-warning:disabled{color:#ffc107;background-color:transparent}.btn-outline-warning:not(:disabled):not(.disabled).active,.btn-outline-warning:not(:disabled):not(.disabled):active,.show>.btn-outline-warning.dropdown-toggle{color:#212529;background-color:#ffc107;border-color:#ffc107}.btn-outline-warning:not(:disabled):not(.disabled).active:focus,.btn-outline-warning:not(:disabled):not(.disabled):active:focus,.show>.btn-outline-warning.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(255,193,7,.5)}.btn-outline-danger{color:#dc3545;border-color:#dc3545}.btn-outline-danger:hover{color:#fff;background-color:#dc3545;border-color:#dc3545}.btn-outline-danger.focus,.btn-outline-danger:focus{box-shadow:0 0 0 .2rem rgba(220,53,69,.5)}.btn-outline-danger.disabled,.btn-outline-danger:disabled{color:#dc3545;background-color:transparent}.btn-outline-danger:not(:disabled):not(.disabled).active,.btn-outline-danger:not(:disabled):not(.disabled):active,.show>.btn-outline-danger.dropdown-toggle{color:#fff;background-color:#dc3545;border-color:#dc3545}.btn-outline-danger:not(:disabled):not(.disabled).active:focus,.btn-outline-danger:not(:disabled):not(.disabled):active:focus,.show>.btn-outline-danger.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(220,53,69,.5)}.btn-outline-light{color:#f8f9fa;border-color:#f8f9fa}.btn-outline-light:hover{color:#212529;background-color:#f8f9fa;border-color:#f8f9fa}.btn-outline-light.focus,.btn-outline-light:focus{box-shadow:0 0 0 .2rem rgba(248,249,250,.5)}.btn-outline-light.disabled,.btn-outline-light:disabled{color:#f8f9fa;background-color:transparent}.btn-outline-light:not(:disabled):not(.disabled).active,.btn-outline-light:not(:disabled):not(.disabled):active,.show>.btn-outline-light.dropdown-toggle{color:#212529;background-color:#f8f9fa;border-color:#f8f9fa}.btn-outline-light:not(:disabled):not(.disabled).active:focus,.btn-outline-light:not(:disabled):not(.disabled):active:focus,.show>.btn-outline-light.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(248,249,250,.5)}.btn-outline-dark{color:#343a40;border-color:#343a40}.btn-outline-dark:hover{color:#fff;background-color:#343a40;border-color:#343a40}.btn-outline-dark.focus,.btn-outline-dark:focus{box-shadow:0 0 0 .2rem rgba(52,58,64,.5)}.btn-outline-dark.disabled,.btn-outline-dark:disabled{color:#343a40;background-color:transparent}.btn-outline-dark:not(:disabled):not(.disabled).active,.btn-outline-dark:not(:disabled):not(.disabled):active,.show>.btn-outline-dark.dropdown-toggle{color:#fff;background-color:#343a40;border-color:#343a40}.btn-outline-dark:not(:disabled):not(.disabled).active:focus,.btn-outline-dark:not(:disabled):not(.disabled):active:focus,.show>.btn-outline-dark.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(52,58,64,.5)}.btn-link{font-weight:400;color:#007bff;text-decoration:none}.btn-link:hover{color:#0056b3}.btn-link.focus,.btn-link:focus,.btn-link:hover{text-decoration:underline}.btn-link.disabled,.btn-link:disabled{color:#6c757d;pointer-events:none}.btn-lg{padding:.5rem 1rem;font-size:1.25rem;line-height:1.5;border-radius:.3rem}.btn-sm{padding:.25rem .5rem;font-size:.875rem;line-height:1.5;border-radius:.2rem}.btn-block{display:block;width:100%}.btn-block+.btn-block{margin-top:.5rem}input[type=button].btn-block,input[type=reset].btn-block,input[type=submit].btn-block{width:100%}.fade{transition:opacity .15s linear}@media (prefers-reduced-motion:reduce){.fade{transition:none}}.fade:not(.show){opacity:0}.collapse:not(.show){display:none}.collapsing{position:relative;height:0;overflow:hidden;transition:height .35s ease}@media (prefers-reduced-motion:reduce){.collapsing{transition:none}}.dropdown,.dropleft,.dropright,.dropup{position:relative}.dropdown-toggle{white-space:nowrap}.dropdown-toggle:after{display:inline-block;margin-left:.255em;vertical-align:.255em;content:"";border-top:.3em solid;border-right:.3em solid transparent;border-bottom:0;border-left:.3em solid transparent}.dropdown-toggle:empty:after{margin-left:0}.dropdown-menu{position:absolute;top:100%;left:0;z-index:1000;display:none;float:left;min-width:10rem;padding:24px 0;margin:0;font-size:1rem;color:#212529;text-align:left;list-style:none;background-color:#fff;background-clip:padding-box;border:0 solid rgba(0,0,0,.15);border-radius:0}.dropdown-menu-left{right:auto;left:0}.dropdown-menu-right{right:0;left:auto}@media (min-width:576px){.dropdown-menu-sm-left{right:auto;left:0}.dropdown-menu-sm-right{right:0;left:auto}}@media (min-width:768px){.dropdown-menu-md-left{right:auto;left:0}.dropdown-menu-md-right{right:0;left:auto}}@media (min-width:992px){.dropdown-menu-lg-left{right:auto;left:0}.dropdown-menu-lg-right{right:0;left:auto}}@media (min-width:1200px){.dropdown-menu-xl-left{right:auto;left:0}.dropdown-menu-xl-right{right:0;left:auto}}.dropup .dropdown-menu{top:auto;bottom:100%;margin-top:0;margin-bottom:0}.dropup .dropdown-toggle:after{display:inline-block;margin-left:.255em;vertical-align:.255em;content:"";border-top:0;border-right:.3em solid transparent;border-bottom:.3em solid;border-left:.3em solid transparent}.dropup .dropdown-toggle:empty:after{margin-left:0}.dropright .dropdown-menu{top:0;right:auto;left:100%;margin-top:0;margin-left:0}.dropright .dropdown-toggle:after{display:inline-block;margin-left:.255em;vertical-align:.255em;content:"";border-top:.3em solid transparent;border-right:0;border-bottom:.3em solid transparent;border-left:.3em solid}.dropright .dropdown-toggle:empty:after{margin-left:0}.dropright .dropdown-toggle:after{vertical-align:0}.dropleft .dropdown-menu{top:0;right:100%;left:auto;margin-top:0;margin-right:0}.dropleft .dropdown-toggle:after{display:inline-block;margin-left:.255em;vertical-align:.255em;content:"";display:none}.dropleft .dropdown-toggle:before{display:inline-block;margin-right:.255em;vertical-align:.255em;content:"";border-top:.3em solid transparent;border-right:.3em solid;border-bottom:.3em solid transparent}.dropleft .dropdown-toggle:empty:after{margin-left:0}.dropleft .dropdown-toggle:before{vertical-align:0}.dropdown-menu[x-placement^=bottom],.dropdown-menu[x-placement^=left],.dropdown-menu[x-placement^=right],.dropdown-menu[x-placement^=top]{right:auto;bottom:auto}.dropdown-divider{height:0;margin:.5rem 0;overflow:hidden;border-top:1px solid #e9ecef}.dropdown-item{display:block;width:100%;padding:.25rem 1.5rem;clear:both;font-weight:400;color:#797f90;text-align:inherit;white-space:nowrap;background-color:transparent;border:0}.dropdown-item:focus,.dropdown-item:hover{color:#ff6f00;text-decoration:none;background-color:transparent}.dropdown-item.active,.dropdown-item:active{color:#fff;text-decoration:none;background-color:#007bff}.dropdown-item.disabled,.dropdown-item:disabled{color:#6c757d;pointer-events:none;background-color:transparent}.dropdown-menu.show{display:block}.dropdown-header{display:block;padding:24px 1.5rem;margin-bottom:0;font-size:.875rem;color:#6c757d;white-space:nowrap}.dropdown-item-text{display:block;padding:.25rem 1.5rem;color:#797f90}.navbar{position:relative;padding:0 1rem}.navbar,.navbar .container,.navbar .container-fluid,.navbar .container-lg,.navbar .container-md,.navbar .container-sm,.navbar .container-xl{display:flex;flex-wrap:wrap;align-items:center;justify-content:space-between}.navbar-brand{display:inline-block;padding-top:-.1875rem;padding-bottom:-.1875rem;margin-right:1rem;font-size:1.25rem;line-height:inherit;white-space:nowrap}.navbar-brand:focus,.navbar-brand:hover{text-decoration:none}.navbar-nav{display:flex;flex-direction:column;padding-left:0;margin-bottom:0;list-style:none}.navbar-nav .nav-link{padding-right:0;padding-left:0}.navbar-nav .dropdown-menu{position:static;float:none}.navbar-text{display:inline-block;padding-top:0;padding-bottom:0}.navbar-collapse{flex-basis:100%;flex-grow:1;align-items:center}.navbar-toggler{padding:.25rem .75rem;font-size:1.25rem;line-height:1;background-color:transparent;border:1px solid transparent;border-radius:.25rem}.navbar-toggler:focus,.navbar-toggler:hover{text-decoration:none}.navbar-toggler-icon{display:inline-block;width:1.5em;height:1.5em;vertical-align:middle;content:"";background:no-repeat 50%;background-size:100% 100%}@media (max-width:575.98px){.navbar-expand-sm>.container,.navbar-expand-sm>.container-fluid,.navbar-expand-sm>.container-lg,.navbar-expand-sm>.container-md,.navbar-expand-sm>.container-sm,.navbar-expand-sm>.container-xl{padding-right:0;padding-left:0}}@media (min-width:576px){.navbar-expand-sm{flex-flow:row nowrap;justify-content:flex-start}.navbar-expand-sm .navbar-nav{flex-direction:row}.navbar-expand-sm .navbar-nav .dropdown-menu{position:absolute}.navbar-expand-sm .navbar-nav .nav-link{padding-right:0;padding-left:0}.navbar-expand-sm>.container,.navbar-expand-sm>.container-fluid,.navbar-expand-sm>.container-lg,.navbar-expand-sm>.container-md,.navbar-expand-sm>.container-sm,.navbar-expand-sm>.container-xl{flex-wrap:nowrap}.navbar-expand-sm .navbar-collapse{display:flex!important;flex-basis:auto}.navbar-expand-sm .navbar-toggler{display:none}}@media (max-width:767.98px){.navbar-expand-md>.container,.navbar-expand-md>.container-fluid,.navbar-expand-md>.container-lg,.navbar-expand-md>.container-md,.navbar-expand-md>.container-sm,.navbar-expand-md>.container-xl{padding-right:0;padding-left:0}}@media (min-width:768px){.navbar-expand-md{flex-flow:row nowrap;justify-content:flex-start}.navbar-expand-md .navbar-nav{flex-direction:row}.navbar-expand-md .navbar-nav .dropdown-menu{position:absolute}.navbar-expand-md .navbar-nav .nav-link{padding-right:0;padding-left:0}.navbar-expand-md>.container,.navbar-expand-md>.container-fluid,.navbar-expand-md>.container-lg,.navbar-expand-md>.container-md,.navbar-expand-md>.container-sm,.navbar-expand-md>.container-xl{flex-wrap:nowrap}.navbar-expand-md .navbar-collapse{display:flex!important;flex-basis:auto}.navbar-expand-md .navbar-toggler{display:none}}@media (max-width:991.98px){.navbar-expand-lg>.container,.navbar-expand-lg>.container-fluid,.navbar-expand-lg>.container-lg,.navbar-expand-lg>.container-md,.navbar-expand-lg>.container-sm,.navbar-expand-lg>.container-xl{padding-right:0;padding-left:0}}@media (min-width:992px){.navbar-expand-lg{flex-flow:row nowrap;justify-content:flex-start}.navbar-expand-lg .navbar-nav{flex-direction:row}.navbar-expand-lg .navbar-nav .dropdown-menu{position:absolute}.navbar-expand-lg .navbar-nav .nav-link{padding-right:0;padding-left:0}.navbar-expand-lg>.container,.navbar-expand-lg>.container-fluid,.navbar-expand-lg>.container-lg,.navbar-expand-lg>.container-md,.navbar-expand-lg>.container-sm,.navbar-expand-lg>.container-xl{flex-wrap:nowrap}.navbar-expand-lg .navbar-collapse{display:flex!important;flex-basis:auto}.navbar-expand-lg .navbar-toggler{display:none}}@media (max-width:1199.98px){.navbar-expand-xl>.container,.navbar-expand-xl>.container-fluid,.navbar-expand-xl>.container-lg,.navbar-expand-xl>.container-md,.navbar-expand-xl>.container-sm,.navbar-expand-xl>.container-xl{padding-right:0;padding-left:0}}@media (min-width:1200px){.navbar-expand-xl{flex-flow:row nowrap;justify-content:flex-start}.navbar-expand-xl .navbar-nav{flex-direction:row}.navbar-expand-xl .navbar-nav .dropdown-menu{position:absolute}.navbar-expand-xl .navbar-nav .nav-link{padding-right:0;padding-left:0}.navbar-expand-xl>.container,.navbar-expand-xl>.container-fluid,.navbar-expand-xl>.container-lg,.navbar-expand-xl>.container-md,.navbar-expand-xl>.container-sm,.navbar-expand-xl>.container-xl{flex-wrap:nowrap}.navbar-expand-xl .navbar-collapse{display:flex!important;flex-basis:auto}.navbar-expand-xl .navbar-toggler{display:none}}.navbar-expand{flex-flow:row nowrap;justify-content:flex-start}.navbar-expand>.container,.navbar-expand>.container-fluid,.navbar-expand>.container-lg,.navbar-expand>.container-md,.navbar-expand>.container-sm,.navbar-expand>.container-xl{padding-right:0;padding-left:0}.navbar-expand .navbar-nav{flex-direction:row}.navbar-expand .navbar-nav .dropdown-menu{position:absolute}.navbar-expand .navbar-nav .nav-link{padding-right:0;padding-left:0}.navbar-expand>.container,.navbar-expand>.container-fluid,.navbar-expand>.container-lg,.navbar-expand>.container-md,.navbar-expand>.container-sm,.navbar-expand>.container-xl{flex-wrap:nowrap}.navbar-expand .navbar-collapse{display:flex!important;flex-basis:auto}.navbar-expand .navbar-toggler{display:none}.navbar-light .navbar-brand,.navbar-light .navbar-brand:focus,.navbar-light .navbar-brand:hover{color:rgba(0,0,0,.9)}.navbar-light .navbar-nav .nav-link{color:rgba(0,0,0,.5)}.navbar-light .navbar-nav .nav-link:focus,.navbar-light .navbar-nav .nav-link:hover{color:rgba(0,0,0,.7)}.navbar-light .navbar-nav .nav-link.disabled{color:rgba(0,0,0,.3)}.navbar-light .navbar-nav .active>.nav-link,.navbar-light .navbar-nav .nav-link.active,.navbar-light .navbar-nav .nav-link.show,.navbar-light .navbar-nav .show>.nav-link{color:rgba(0,0,0,.9)}.navbar-light .navbar-toggler{color:rgba(0,0,0,.5);border-color:rgba(0,0,0,.1)}.navbar-light .navbar-toggler-icon{background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='30' height='30'%3E%3Cpath stroke='rgba(0, 0, 0, 0.5)' stroke-linecap='round' stroke-miterlimit='10' stroke-width='2' d='M4 7h22M4 15h22M4 23h22'/%3E%3C/svg%3E")}.navbar-light .navbar-text{color:rgba(0,0,0,.5)}.navbar-light .navbar-text a,.navbar-light .navbar-text a:focus,.navbar-light .navbar-text a:hover{color:rgba(0,0,0,.9)}.navbar-dark .navbar-brand,.navbar-dark .navbar-brand:focus,.navbar-dark .navbar-brand:hover{color:#fff}.navbar-dark .navbar-nav .nav-link{color:hsla(0,0%,100%,.7)}.navbar-dark .navbar-nav .nav-link:focus,.navbar-dark .navbar-nav .nav-link:hover{color:hsla(0,0%,100%,.75)}.navbar-dark .navbar-nav .nav-link.disabled{color:hsla(0,0%,100%,.25)}.navbar-dark .navbar-nav .active>.nav-link,.navbar-dark .navbar-nav .nav-link.active,.navbar-dark .navbar-nav .nav-link.show,.navbar-dark .navbar-nav .show>.nav-link{color:#fff}.navbar-dark .navbar-toggler{color:hsla(0,0%,100%,.7);border-color:hsla(0,0%,100%,.1)}.navbar-dark .navbar-toggler-icon{background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='30' height='30'%3E%3Cpath stroke='rgba(255, 255, 255, 0.7)' stroke-linecap='round' stroke-miterlimit='10' stroke-width='2' d='M4 7h22M4 15h22M4 23h22'/%3E%3C/svg%3E")}.navbar-dark .navbar-text{color:hsla(0,0%,100%,.7)}.navbar-dark .navbar-text a,.navbar-dark .navbar-text a:focus,.navbar-dark .navbar-text a:hover{color:#fff}.nav{display:flex;flex-wrap:wrap;padding-left:0;margin-bottom:0;list-style:none}.nav-link{display:block;padding:0 1rem}.nav-link:focus,.nav-link:hover{text-decoration:none}.nav-link.disabled{color:#6c757d;pointer-events:none;cursor:default}.nav-tabs{border-bottom:1px solid #dee2e6}.nav-tabs .nav-item{margin-bottom:-1px}.nav-tabs .nav-link{border:1px solid transparent;border-top-left-radius:.25rem;border-top-right-radius:.25rem}.nav-tabs .nav-link:focus,.nav-tabs .nav-link:hover{border-color:#e9ecef #e9ecef #dee2e6}.nav-tabs .nav-link.disabled{color:#6c757d;background-color:transparent;border-color:transparent}.nav-tabs .nav-item.show .nav-link,.nav-tabs .nav-link.active{color:#495057;background-color:#eceeef;border-color:#dee2e6 #dee2e6 #eceeef}.nav-tabs .dropdown-menu{margin-top:-1px;border-top-left-radius:0;border-top-right-radius:0}.nav-pills .nav-link{border-radius:.25rem}.nav-pills .nav-link.active,.nav-pills .show>.nav-link{color:#fff;background-color:#007bff}.nav-fill .nav-item,.nav-fill>.nav-link{flex:1 1 auto;text-align:center}.nav-justified .nav-item,.nav-justified>.nav-link{flex-basis:0;flex-grow:1;text-align:center}.tab-content>.tab-pane{display:none}.tab-content>.active{display:block}.pbTable,.table{width:100%;margin-bottom:1rem;color:#797f90}.pbTable td,.pbTable th,.table td,.table th{padding:.75rem;vertical-align:top;border-top:1px solid #dddfe3}.pbTable thead th,.table thead th{vertical-align:bottom;border-bottom:2px solid #dddfe3}.pbTable tbody+tbody,.table tbody+tbody{border-top:2px solid #dddfe3}.table-sm td,.table-sm th{padding:.3rem}.pbTable,.pbTable td,.pbTable th,.table-bordered,.table-bordered td,.table-bordered th{border:1px solid #dddfe3}.pbTable thead td,.pbTable thead th,.table-bordered thead td,.table-bordered thead th{border-bottom-width:2px}.table-borderless tbody+tbody,.table-borderless td,.table-borderless th,.table-borderless thead th{border:0}.pbTable tbody tr:nth-of-type(odd),.table-striped tbody tr:nth-of-type(odd){background-color:#f8f9f9}.table-hover tbody tr:hover{color:#797f90;background-color:rgba(0,0,0,.075)}.table-primary,.table-primary>td,.table-primary>th{background-color:#b8daff}.table-primary tbody+tbody,.table-primary td,.table-primary th,.table-primary thead th{border-color:#7abaff}.table-hover .table-primary:hover,.table-hover .table-primary:hover>td,.table-hover .table-primary:hover>th{background-color:#9fcdff}.table-secondary,.table-secondary>td,.table-secondary>th{background-color:#d6d8db}.table-secondary tbody+tbody,.table-secondary td,.table-secondary th,.table-secondary thead th{border-color:#b3b7bb}.table-hover .table-secondary:hover,.table-hover .table-secondary:hover>td,.table-hover .table-secondary:hover>th{background-color:#c8cbcf}.table-success,.table-success>td,.table-success>th{background-color:#c3e6cb}.table-success tbody+tbody,.table-success td,.table-success th,.table-success thead th{border-color:#8fd19e}.table-hover .table-success:hover,.table-hover .table-success:hover>td,.table-hover .table-success:hover>th{background-color:#b1dfbb}.table-info,.table-info>td,.table-info>th{background-color:#bee5eb}.table-info tbody+tbody,.table-info td,.table-info th,.table-info thead th{border-color:#86cfda}.table-hover .table-info:hover,.table-hover .table-info:hover>td,.table-hover .table-info:hover>th{background-color:#abdde5}.table-warning,.table-warning>td,.table-warning>th{background-color:#ffeeba}.table-warning tbody+tbody,.table-warning td,.table-warning th,.table-warning thead th{border-color:#ffdf7e}.table-hover .table-warning:hover,.table-hover .table-warning:hover>td,.table-hover .table-warning:hover>th{background-color:#ffe8a1}.table-danger,.table-danger>td,.table-danger>th{background-color:#f5c6cb}.table-danger tbody+tbody,.table-danger td,.table-danger th,.table-danger thead th{border-color:#ed969e}.table-hover .table-danger:hover,.table-hover .table-danger:hover>td,.table-hover .table-danger:hover>th{background-color:#f1b0b7}.table-light,.table-light>td,.table-light>th{background-color:#fdfdfe}.table-light tbody+tbody,.table-light td,.table-light th,.table-light thead th{border-color:#fbfcfc}.table-hover .table-light:hover,.table-hover .table-light:hover>td,.table-hover .table-light:hover>th{background-color:#ececf6}.table-dark,.table-dark>td,.table-dark>th{background-color:#c6c8ca}.table-dark tbody+tbody,.table-dark td,.table-dark th,.table-dark thead th{border-color:#95999c}.table-hover .table-dark:hover,.table-hover .table-dark:hover>td,.table-hover .table-dark:hover>th{background-color:#b9bbbe}.table-active,.table-active>td,.table-active>th,.table-hover .table-active:hover,.table-hover .table-active:hover>td,.table-hover .table-active:hover>th{background-color:rgba(0,0,0,.075)}.pbTable .thead-dark th,.table .thead-dark th{color:#fff;background-color:#343a40;border-color:#454d55}.pbTable .thead-light th,.table .thead-light th{color:#495057;background-color:#e9ecef;border-color:#dddfe3}.table-dark{color:#fff;background-color:#343a40}.table-dark td,.table-dark th,.table-dark thead th{border-color:#454d55}.table-dark.pbTable,.table-dark.table-bordered{border:0}.table-dark.pbTable tbody tr:nth-of-type(odd),.table-dark.table-striped tbody tr:nth-of-type(odd){background-color:hsla(0,0%,100%,.05)}.table-dark.table-hover tbody tr:hover{color:#fff;background-color:hsla(0,0%,100%,.075)}@media (max-width:575.98px){.table-responsive-sm{display:block;width:100%;overflow-x:auto;-webkit-overflow-scrolling:touch}.table-responsive-sm>.pbTable,.table-responsive-sm>.table-bordered{border:0}}@media (max-width:767.98px){.table-responsive-md{display:block;width:100%;overflow-x:auto;-webkit-overflow-scrolling:touch}.table-responsive-md>.pbTable,.table-responsive-md>.table-bordered{border:0}}@media (max-width:991.98px){.table-responsive-lg{display:block;width:100%;overflow-x:auto;-webkit-overflow-scrolling:touch}.table-responsive-lg>.pbTable,.table-responsive-lg>.table-bordered{border:0}}@media (max-width:1199.98px){.table-responsive-xl{display:block;width:100%;overflow-x:auto;-webkit-overflow-scrolling:touch}.table-responsive-xl>.pbTable,.table-responsive-xl>.table-bordered{border:0}}.table-responsive{display:block;width:100%;overflow-x:auto;-webkit-overflow-scrolling:touch}.table-responsive>.pbTable,.table-responsive>.table-bordered{border:0}.card{position:relative;display:flex;flex-direction:column;min-width:0;word-wrap:break-word;background-color:#fff;background-clip:border-box;border:1px solid rgba(0,0,0,.125);border-radius:0}.card>hr{margin-right:0;margin-left:0}.card>.list-group{border-top:inherit;border-bottom:inherit}.card>.list-group:first-child{border-top-width:0;border-top-left-radius:0;border-top-right-radius:0}.card>.list-group:last-child{border-bottom-width:0;border-bottom-right-radius:0;border-bottom-left-radius:0}.card>.card-header+.list-group,.card>.list-group+.card-footer{border-top:0}.card-body{flex:1 1 auto;min-height:1px;padding:30px}.card-title{margin-bottom:.75rem}.card-subtitle{margin-top:-.375rem}.card-subtitle,.card-text:last-child{margin-bottom:0}.card-link:hover{text-decoration:none}.card-link+.card-link{margin-left:30px}.card-header{padding:.75rem 30px;margin-bottom:0;background-color:rgba(0,0,0,.03);border-bottom:1px solid rgba(0,0,0,.125)}.card-header:first-child{border-radius:0 0 0 0}.card-footer{padding:.75rem 30px;background-color:rgba(0,0,0,.03);border-top:1px solid rgba(0,0,0,.125)}.card-footer:last-child{border-radius:0 0 0 0}.card-header-tabs{margin-bottom:-.75rem;border-bottom:0}.card-header-pills,.card-header-tabs{margin-right:-15px;margin-left:-15px}.card-img-overlay{position:absolute;top:0;right:0;bottom:0;left:0;padding:1.25rem;border-radius:0}.card-img,.card-img-bottom,.card-img-top{flex-shrink:0;width:100%}.card-img,.card-img-top{border-top-left-radius:0;border-top-right-radius:0}.card-img,.card-img-bottom{border-bottom-right-radius:0;border-bottom-left-radius:0}.card-deck .card{margin-bottom:10px}@media (min-width:576px){.card-deck{display:flex;flex-flow:row wrap;margin-right:-10px;margin-left:-10px}.card-deck .card{flex:1 0 0%;margin-right:10px;margin-bottom:0;margin-left:10px}}.card-group>.card{margin-bottom:10px}@media (min-width:576px){.card-group{display:flex;flex-flow:row wrap}.card-group>.card{flex:1 0 0%;margin-bottom:0}.card-group>.card+.card{margin-left:0;border-left:0}.card-group>.card:not(:last-child){border-top-right-radius:0;border-bottom-right-radius:0}.card-group>.card:not(:last-child) .card-header,.card-group>.card:not(:last-child) .card-img-top{border-top-right-radius:0}.card-group>.card:not(:last-child) .card-footer,.card-group>.card:not(:last-child) .card-img-bottom{border-bottom-right-radius:0}.card-group>.card:not(:first-child){border-top-left-radius:0;border-bottom-left-radius:0}.card-group>.card:not(:first-child) .card-header,.card-group>.card:not(:first-child) .card-img-top{border-top-left-radius:0}.card-group>.card:not(:first-child) .card-footer,.card-group>.card:not(:first-child) .card-img-bottom{border-bottom-left-radius:0}}.card-columns .card{margin-bottom:.75rem}@media (min-width:576px){.card-columns{-moz-column-count:3;column-count:3;-moz-column-gap:1.25rem;column-gap:1.25rem;orphans:1;widows:1}.card-columns .card{display:inline-block;width:100%}}.accordion{overflow-anchor:none}.accordion>.card{overflow:hidden}.accordion>.card:not(:last-of-type){border-bottom:0;border-bottom-right-radius:0;border-bottom-left-radius:0}.accordion>.card:not(:first-of-type){border-top-left-radius:0;border-top-right-radius:0}.accordion>.card>.card-header{border-radius:0;margin-bottom:-1px}code{font-size:87.5%;color:#e83e8c;word-wrap:break-word}a>code{color:inherit}kbd{padding:.2rem .4rem;font-size:87.5%;color:#fff;background-color:#212529;border-radius:.2rem}kbd kbd{padding:0;font-size:100%;font-weight:700}pre{display:block;font-size:87.5%;color:#212529}pre code{font-size:inherit;color:inherit;word-break:normal}.pre-scrollable{max-height:340px;overflow-y:scroll}.alert,.pb-alert{position:relative;padding:.75rem 1.25rem;margin-bottom:1rem;border:1px solid transparent;border-radius:.25rem}.alert-heading{color:inherit}.alert-link{font-weight:700}.alert-dismissible{padding-right:4rem}.alert-dismissible .close{position:absolute;top:0;right:0;z-index:2;padding:.75rem 1.25rem;color:inherit}.alert-primary{color:#004085;background-color:#cce5ff;border-color:#b8daff}.alert-primary hr{border-top-color:#9fcdff}.alert-primary .alert-link{color:#002752}.alert-secondary{color:#383d41;background-color:#e2e3e5;border-color:#d6d8db}.alert-secondary hr{border-top-color:#c8cbcf}.alert-secondary .alert-link{color:#202326}.alert-success{color:#155724;background-color:#d4edda;border-color:#c3e6cb}.alert-success hr{border-top-color:#b1dfbb}.alert-success .alert-link{color:#0b2e13}.alert-info,.pb-alert-tip{color:#0c5460;background-color:#d1ecf1;border-color:#bee5eb}.alert-info hr,.pb-alert-tip hr{border-top-color:#abdde5}.alert-info .alert-link,.pb-alert-tip .alert-link{color:#062c33}.alert-warning,.pb-alert-warning{color:#856404;background-color:#fff3cd;border-color:#ffeeba}.alert-warning hr,.pb-alert-warning hr{border-top-color:#ffe8a1}.alert-warning .alert-link,.pb-alert-warning .alert-link{color:#533f03}.alert-danger,.pb-alert-important{color:#721c24;background-color:#f8d7da;border-color:#f5c6cb}.alert-danger hr,.pb-alert-important hr{border-top-color:#f1b0b7}.alert-danger .alert-link,.pb-alert-important .alert-link{color:#491217}.alert-light{color:#818182;background-color:#fefefe;border-color:#fdfdfe}.alert-light hr{border-top-color:#ececf6}.alert-light .alert-link{color:#686868}.alert-dark{color:#1b1e21;background-color:#d6d8d9;border-color:#c6c8ca}.alert-dark hr{border-top-color:#b9bbbe}.alert-dark .alert-link{color:#040505}.modal-open{overflow:hidden}.modal-open .modal{overflow-x:hidden;overflow-y:auto}.modal{position:fixed;top:0;left:0;z-index:1050;display:none;width:100%;height:100%;overflow:hidden;outline:0}.modal-dialog{position:relative;width:auto;margin:.5rem;pointer-events:none}.modal.fade .modal-dialog{transition:transform .3s ease-out;transform:translateY(-50px)}@media (prefers-reduced-motion:reduce){.modal.fade .modal-dialog{transition:none}}.modal.show .modal-dialog{transform:none}.modal.modal-static .modal-dialog{transform:scale(1.02)}.modal-dialog-scrollable{display:flex;max-height:calc(100% - 1rem)}.modal-dialog-scrollable .modal-content{max-height:calc(100vh - 1rem);overflow:hidden}.modal-dialog-scrollable .modal-footer,.modal-dialog-scrollable .modal-header{flex-shrink:0}.modal-dialog-scrollable .modal-body{overflow-y:auto}.modal-dialog-centered{display:flex;align-items:center;min-height:calc(100% - 1rem)}.modal-dialog-centered:before{display:block;height:calc(100vh - 1rem);height:-webkit-min-content;height:-moz-min-content;height:min-content;content:""}.modal-dialog-centered.modal-dialog-scrollable{flex-direction:column;justify-content:center;height:100%}.modal-dialog-centered.modal-dialog-scrollable .modal-content{max-height:none}.modal-dialog-centered.modal-dialog-scrollable:before{content:none}.modal-content{position:relative;display:flex;flex-direction:column;width:100%;pointer-events:auto;background-color:#fff;background-clip:padding-box;border:1px solid rgba(0,0,0,.2);border-radius:.3rem;outline:0}.modal-backdrop{position:fixed;top:0;left:0;z-index:1040;width:100vw;height:100vh;background-color:#000}.modal-backdrop.fade{opacity:0}.modal-backdrop.show{opacity:.5}.modal-header{display:flex;align-items:flex-start;justify-content:space-between;padding:1rem;border-bottom:1px solid #dee2e6;border-top-left-radius:calc(.3rem - 1px);border-top-right-radius:calc(.3rem - 1px)}.modal-header .close{padding:1rem;margin:-1rem -1rem -1rem auto}.modal-title{margin-bottom:0;line-height:1.5}.modal-body{position:relative;flex:1 1 auto;padding:1rem}.modal-footer{display:flex;flex-wrap:wrap;align-items:center;justify-content:flex-end;padding:.75rem;border-top:1px solid #dee2e6;border-bottom-right-radius:calc(.3rem - 1px);border-bottom-left-radius:calc(.3rem - 1px)}.modal-footer>*{margin:.25rem}.modal-scrollbar-measure{position:absolute;top:-9999px;width:50px;height:50px;overflow:scroll}@media (min-width:576px){.modal-dialog{max-width:500px;margin:1.75rem auto}.modal-dialog-scrollable{max-height:calc(100% - 3.5rem)}.modal-dialog-scrollable .modal-content{max-height:calc(100vh - 3.5rem)}.modal-dialog-centered{min-height:calc(100% - 3.5rem)}.modal-dialog-centered:before{height:calc(100vh - 3.5rem);height:-webkit-min-content;height:-moz-min-content;height:min-content}.modal-sm{max-width:300px}}@media (min-width:992px){.modal-lg,.modal-xl{max-width:800px}}@media (min-width:1200px){.modal-xl{max-width:1140px}}.align-baseline{vertical-align:baseline!important}.align-top{vertical-align:top!important}.align-middle{vertical-align:middle!important}.align-bottom{vertical-align:bottom!important}.align-text-bottom{vertical-align:text-bottom!important}.align-text-top{vertical-align:text-top!important}.bg-primary{background-color:#007bff!important}a.bg-primary:focus,a.bg-primary:hover,button.bg-primary:focus,button.bg-primary:hover{background-color:#0062cc!important}.bg-secondary{background-color:#6c757d!important}a.bg-secondary:focus,a.bg-secondary:hover,button.bg-secondary:focus,button.bg-secondary:hover{background-color:#545b62!important}.bg-success{background-color:#28a745!important}a.bg-success:focus,a.bg-success:hover,button.bg-success:focus,button.bg-success:hover{background-color:#1e7e34!important}.bg-info{background-color:#17a2b8!important}a.bg-info:focus,a.bg-info:hover,button.bg-info:focus,button.bg-info:hover{background-color:#117a8b!important}.bg-warning{background-color:#ffc107!important}a.bg-warning:focus,a.bg-warning:hover,button.bg-warning:focus,button.bg-warning:hover{background-color:#d39e00!important}.bg-danger{background-color:#dc3545!important}a.bg-danger:focus,a.bg-danger:hover,button.bg-danger:focus,button.bg-danger:hover{background-color:#bd2130!important}.bg-light{background-color:#f8f9fa!important}a.bg-light:focus,a.bg-light:hover,button.bg-light:focus,button.bg-light:hover{background-color:#dae0e5!important}.bg-dark{background-color:#343a40!important}a.bg-dark:focus,a.bg-dark:hover,button.bg-dark:focus,button.bg-dark:hover{background-color:#1d2124!important}.bg-white{background-color:#fff!important}.bg-transparent{background-color:transparent!important}.border{border:1px solid #dee2e6!important}.border-top{border-top:1px solid #dee2e6!important}.border-right{border-right:1px solid #dee2e6!important}.border-bottom{border-bottom:1px solid #dee2e6!important}.border-left{border-left:1px solid #dee2e6!important}.border-0{border:0!important}.border-top-0{border-top:0!important}.border-right-0{border-right:0!important}.border-bottom-0{border-bottom:0!important}.border-left-0{border-left:0!important}.border-primary{border-color:#007bff!important}.border-secondary{border-color:#6c757d!important}.border-success{border-color:#28a745!important}.border-info{border-color:#17a2b8!important}.border-warning{border-color:#ffc107!important}.border-danger{border-color:#dc3545!important}.border-light{border-color:#f8f9fa!important}.border-dark{border-color:#343a40!important}.border-white{border-color:#fff!important}.rounded-sm{border-radius:.2rem!important}.rounded{border-radius:.25rem!important}.rounded-top{border-top-left-radius:.25rem!important}.rounded-right,.rounded-top{border-top-right-radius:.25rem!important}.rounded-bottom,.rounded-right{border-bottom-right-radius:.25rem!important}.rounded-bottom,.rounded-left{border-bottom-left-radius:.25rem!important}.rounded-left{border-top-left-radius:.25rem!important}.rounded-lg{border-radius:.3rem!important}.rounded-circle{border-radius:50%!important}.rounded-pill{border-radius:50rem!important}.rounded-0{border-radius:0!important}.clearfix:after{display:block;clear:both;content:""}.d-none{display:none!important}.d-inline{display:inline!important}.d-inline-block{display:inline-block!important}.d-block{display:block!important}.d-table{display:table!important}.d-table-row{display:table-row!important}.d-table-cell{display:table-cell!important}.d-flex{display:flex!important}.d-inline-flex{display:inline-flex!important}@media (min-width:576px){.d-sm-none{display:none!important}.d-sm-inline{display:inline!important}.d-sm-inline-block{display:inline-block!important}.d-sm-block{display:block!important}.d-sm-table{display:table!important}.d-sm-table-row{display:table-row!important}.d-sm-table-cell{display:table-cell!important}.d-sm-flex{display:flex!important}.d-sm-inline-flex{display:inline-flex!important}}@media (min-width:768px){.d-md-none{display:none!important}.d-md-inline{display:inline!important}.d-md-inline-block{display:inline-block!important}.d-md-block{display:block!important}.d-md-table{display:table!important}.d-md-table-row{display:table-row!important}.d-md-table-cell{display:table-cell!important}.d-md-flex{display:flex!important}.d-md-inline-flex{display:inline-flex!important}}@media (min-width:992px){.d-lg-none{display:none!important}.d-lg-inline{display:inline!important}.d-lg-inline-block{display:inline-block!important}.d-lg-block{display:block!important}.d-lg-table{display:table!important}.d-lg-table-row{display:table-row!important}.d-lg-table-cell{display:table-cell!important}.d-lg-flex{display:flex!important}.d-lg-inline-flex{display:inline-flex!important}}@media (min-width:1200px){.d-xl-none{display:none!important}.d-xl-inline{display:inline!important}.d-xl-inline-block{display:inline-block!important}.d-xl-block{display:block!important}.d-xl-table{display:table!important}.d-xl-table-row{display:table-row!important}.d-xl-table-cell{display:table-cell!important}.d-xl-flex{display:flex!important}.d-xl-inline-flex{display:inline-flex!important}}@media print{.d-print-none{display:none!important}.d-print-inline{display:inline!important}.d-print-inline-block{display:inline-block!important}.d-print-block{display:block!important}.d-print-table{display:table!important}.d-print-table-row{display:table-row!important}.d-print-table-cell{display:table-cell!important}.d-print-flex{display:flex!important}.d-print-inline-flex{display:inline-flex!important}}.embed-responsive{position:relative;display:block;width:100%;padding:0;overflow:hidden}.embed-responsive:before{display:block;content:""}.embed-responsive .embed-responsive-item,.embed-responsive embed,.embed-responsive iframe,.embed-responsive object,.embed-responsive video{position:absolute;top:0;bottom:0;left:0;width:100%;height:100%;border:0}.embed-responsive-21by9:before{padding-top:42.8571428571%}.embed-responsive-16by9:before{padding-top:56.25%}.embed-responsive-4by3:before{padding-top:75%}.embed-responsive-1by1:before{padding-top:100%}.flex-row{flex-direction:row!important}.flex-column{flex-direction:column!important}.flex-row-reverse{flex-direction:row-reverse!important}.flex-column-reverse{flex-direction:column-reverse!important}.flex-wrap{flex-wrap:wrap!important}.flex-nowrap{flex-wrap:nowrap!important}.flex-wrap-reverse{flex-wrap:wrap-reverse!important}.flex-fill{flex:1 1 auto!important}.flex-grow-0{flex-grow:0!important}.flex-grow-1{flex-grow:1!important}.flex-shrink-0{flex-shrink:0!important}.flex-shrink-1{flex-shrink:1!important}.justify-content-start{justify-content:flex-start!important}.justify-content-end{justify-content:flex-end!important}.justify-content-center{justify-content:center!important}.justify-content-between{justify-content:space-between!important}.justify-content-around{justify-content:space-around!important}.align-items-start{align-items:flex-start!important}.align-items-end{align-items:flex-end!important}.align-items-center{align-items:center!important}.align-items-baseline{align-items:baseline!important}.align-items-stretch{align-items:stretch!important}.align-content-start{align-content:flex-start!important}.align-content-end{align-content:flex-end!important}.align-content-center{align-content:center!important}.align-content-between{align-content:space-between!important}.align-content-around{align-content:space-around!important}.align-content-stretch{align-content:stretch!important}.align-self-auto{align-self:auto!important}.align-self-start{align-self:flex-start!important}.align-self-end{align-self:flex-end!important}.align-self-center{align-self:center!important}.align-self-baseline{align-self:baseline!important}.align-self-stretch{align-self:stretch!important}@media (min-width:576px){.flex-sm-row{flex-direction:row!important}.flex-sm-column{flex-direction:column!important}.flex-sm-row-reverse{flex-direction:row-reverse!important}.flex-sm-column-reverse{flex-direction:column-reverse!important}.flex-sm-wrap{flex-wrap:wrap!important}.flex-sm-nowrap{flex-wrap:nowrap!important}.flex-sm-wrap-reverse{flex-wrap:wrap-reverse!important}.flex-sm-fill{flex:1 1 auto!important}.flex-sm-grow-0{flex-grow:0!important}.flex-sm-grow-1{flex-grow:1!important}.flex-sm-shrink-0{flex-shrink:0!important}.flex-sm-shrink-1{flex-shrink:1!important}.justify-content-sm-start{justify-content:flex-start!important}.justify-content-sm-end{justify-content:flex-end!important}.justify-content-sm-center{justify-content:center!important}.justify-content-sm-between{justify-content:space-between!important}.justify-content-sm-around{justify-content:space-around!important}.align-items-sm-start{align-items:flex-start!important}.align-items-sm-end{align-items:flex-end!important}.align-items-sm-center{align-items:center!important}.align-items-sm-baseline{align-items:baseline!important}.align-items-sm-stretch{align-items:stretch!important}.align-content-sm-start{align-content:flex-start!important}.align-content-sm-end{align-content:flex-end!important}.align-content-sm-center{align-content:center!important}.align-content-sm-between{align-content:space-between!important}.align-content-sm-around{align-content:space-around!important}.align-content-sm-stretch{align-content:stretch!important}.align-self-sm-auto{align-self:auto!important}.align-self-sm-start{align-self:flex-start!important}.align-self-sm-end{align-self:flex-end!important}.align-self-sm-center{align-self:center!important}.align-self-sm-baseline{align-self:baseline!important}.align-self-sm-stretch{align-self:stretch!important}}@media (min-width:768px){.flex-md-row{flex-direction:row!important}.flex-md-column{flex-direction:column!important}.flex-md-row-reverse{flex-direction:row-reverse!important}.flex-md-column-reverse{flex-direction:column-reverse!important}.flex-md-wrap{flex-wrap:wrap!important}.flex-md-nowrap{flex-wrap:nowrap!important}.flex-md-wrap-reverse{flex-wrap:wrap-reverse!important}.flex-md-fill{flex:1 1 auto!important}.flex-md-grow-0{flex-grow:0!important}.flex-md-grow-1{flex-grow:1!important}.flex-md-shrink-0{flex-shrink:0!important}.flex-md-shrink-1{flex-shrink:1!important}.justify-content-md-start{justify-content:flex-start!important}.justify-content-md-end{justify-content:flex-end!important}.justify-content-md-center{justify-content:center!important}.justify-content-md-between{justify-content:space-between!important}.justify-content-md-around{justify-content:space-around!important}.align-items-md-start{align-items:flex-start!important}.align-items-md-end{align-items:flex-end!important}.align-items-md-center{align-items:center!important}.align-items-md-baseline{align-items:baseline!important}.align-items-md-stretch{align-items:stretch!important}.align-content-md-start{align-content:flex-start!important}.align-content-md-end{align-content:flex-end!important}.align-content-md-center{align-content:center!important}.align-content-md-between{align-content:space-between!important}.align-content-md-around{align-content:space-around!important}.align-content-md-stretch{align-content:stretch!important}.align-self-md-auto{align-self:auto!important}.align-self-md-start{align-self:flex-start!important}.align-self-md-end{align-self:flex-end!important}.align-self-md-center{align-self:center!important}.align-self-md-baseline{align-self:baseline!important}.align-self-md-stretch{align-self:stretch!important}}@media (min-width:992px){.flex-lg-row{flex-direction:row!important}.flex-lg-column{flex-direction:column!important}.flex-lg-row-reverse{flex-direction:row-reverse!important}.flex-lg-column-reverse{flex-direction:column-reverse!important}.flex-lg-wrap{flex-wrap:wrap!important}.flex-lg-nowrap{flex-wrap:nowrap!important}.flex-lg-wrap-reverse{flex-wrap:wrap-reverse!important}.flex-lg-fill{flex:1 1 auto!important}.flex-lg-grow-0{flex-grow:0!important}.flex-lg-grow-1{flex-grow:1!important}.flex-lg-shrink-0{flex-shrink:0!important}.flex-lg-shrink-1{flex-shrink:1!important}.justify-content-lg-start{justify-content:flex-start!important}.justify-content-lg-end{justify-content:flex-end!important}.justify-content-lg-center{justify-content:center!important}.justify-content-lg-between{justify-content:space-between!important}.justify-content-lg-around{justify-content:space-around!important}.align-items-lg-start{align-items:flex-start!important}.align-items-lg-end{align-items:flex-end!important}.align-items-lg-center{align-items:center!important}.align-items-lg-baseline{align-items:baseline!important}.align-items-lg-stretch{align-items:stretch!important}.align-content-lg-start{align-content:flex-start!important}.align-content-lg-end{align-content:flex-end!important}.align-content-lg-center{align-content:center!important}.align-content-lg-between{align-content:space-between!important}.align-content-lg-around{align-content:space-around!important}.align-content-lg-stretch{align-content:stretch!important}.align-self-lg-auto{align-self:auto!important}.align-self-lg-start{align-self:flex-start!important}.align-self-lg-end{align-self:flex-end!important}.align-self-lg-center{align-self:center!important}.align-self-lg-baseline{align-self:baseline!important}.align-self-lg-stretch{align-self:stretch!important}}@media (min-width:1200px){.flex-xl-row{flex-direction:row!important}.flex-xl-column{flex-direction:column!important}.flex-xl-row-reverse{flex-direction:row-reverse!important}.flex-xl-column-reverse{flex-direction:column-reverse!important}.flex-xl-wrap{flex-wrap:wrap!important}.flex-xl-nowrap{flex-wrap:nowrap!important}.flex-xl-wrap-reverse{flex-wrap:wrap-reverse!important}.flex-xl-fill{flex:1 1 auto!important}.flex-xl-grow-0{flex-grow:0!important}.flex-xl-grow-1{flex-grow:1!important}.flex-xl-shrink-0{flex-shrink:0!important}.flex-xl-shrink-1{flex-shrink:1!important}.justify-content-xl-start{justify-content:flex-start!important}.justify-content-xl-end{justify-content:flex-end!important}.justify-content-xl-center{justify-content:center!important}.justify-content-xl-between{justify-content:space-between!important}.justify-content-xl-around{justify-content:space-around!important}.align-items-xl-start{align-items:flex-start!important}.align-items-xl-end{align-items:flex-end!important}.align-items-xl-center{align-items:center!important}.align-items-xl-baseline{align-items:baseline!important}.align-items-xl-stretch{align-items:stretch!important}.align-content-xl-start{align-content:flex-start!important}.align-content-xl-end{align-content:flex-end!important}.align-content-xl-center{align-content:center!important}.align-content-xl-between{align-content:space-between!important}.align-content-xl-around{align-content:space-around!important}.align-content-xl-stretch{align-content:stretch!important}.align-self-xl-auto{align-self:auto!important}.align-self-xl-start{align-self:flex-start!important}.align-self-xl-end{align-self:flex-end!important}.align-self-xl-center{align-self:center!important}.align-self-xl-baseline{align-self:baseline!important}.align-self-xl-stretch{align-self:stretch!important}}.float-left{float:left!important}.float-right{float:right!important}.float-none{float:none!important}@media (min-width:576px){.float-sm-left{float:left!important}.float-sm-right{float:right!important}.float-sm-none{float:none!important}}@media (min-width:768px){.float-md-left{float:left!important}.float-md-right{float:right!important}.float-md-none{float:none!important}}@media (min-width:992px){.float-lg-left{float:left!important}.float-lg-right{float:right!important}.float-lg-none{float:none!important}}@media (min-width:1200px){.float-xl-left{float:left!important}.float-xl-right{float:right!important}.float-xl-none{float:none!important}}.user-select-all{-webkit-user-select:all!important;-moz-user-select:all!important;-ms-user-select:all!important;user-select:all!important}.user-select-auto{-webkit-user-select:auto!important;-moz-user-select:auto!important;-ms-user-select:auto!important;user-select:auto!important}.user-select-none{-webkit-user-select:none!important;-moz-user-select:none!important;-ms-user-select:none!important;user-select:none!important}.overflow-auto{overflow:auto!important}.overflow-hidden{overflow:hidden!important}.position-static{position:static!important}.position-relative{position:relative!important}.position-absolute{position:absolute!important}.position-fixed{position:fixed!important}.position-sticky{position:-webkit-sticky!important;position:sticky!important}.fixed-top{top:0}.fixed-bottom,.fixed-top{position:fixed;right:0;left:0;z-index:1030}.fixed-bottom{bottom:0}@supports ((position:-webkit-sticky) or (position:sticky)){.sticky-top{position:-webkit-sticky;position:sticky;top:0;z-index:1020}}.sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border:0}.sr-only-focusable:active,.sr-only-focusable:focus{position:static;width:auto;height:auto;overflow:visible;clip:auto;white-space:normal}.shadow-sm{box-shadow:0 .125rem .25rem rgba(0,0,0,.075)!important}.shadow{box-shadow:0 .5rem 1rem rgba(0,0,0,.15)!important}.shadow-lg{box-shadow:0 1rem 3rem rgba(0,0,0,.175)!important}.shadow-none{box-shadow:none!important}.w-25{width:25%!important}.w-50{width:50%!important}.w-75{width:75%!important}.w-100{width:100%!important}.w-auto{width:auto!important}.h-25{height:25%!important}.h-50{height:50%!important}.h-75{height:75%!important}.h-100{height:100%!important}.h-auto{height:auto!important}.mw-100{max-width:100%!important}.mh-100{max-height:100%!important}.min-vw-100{min-width:100vw!important}.min-vh-100{min-height:100vh!important}.vw-100{width:100vw!important}.vh-100{height:100vh!important}.m-0{margin:0!important}.mt-0,.my-0{margin-top:0!important}.mr-0,.mx-0{margin-right:0!important}.mb-0,.my-0{margin-bottom:0!important}.ml-0,.mx-0{margin-left:0!important}.m-1{margin:.25rem!important}.mt-1,.my-1{margin-top:.25rem!important}.mr-1,.mx-1{margin-right:.25rem!important}.mb-1,.my-1{margin-bottom:.25rem!important}.ml-1,.mx-1{margin-left:.25rem!important}.m-2{margin:.5rem!important}.mt-2,.my-2{margin-top:.5rem!important}.mr-2,.mx-2{margin-right:.5rem!important}.mb-2,.my-2{margin-bottom:.5rem!important}.ml-2,.mx-2{margin-left:.5rem!important}.m-3{margin:1rem!important}.mt-3,.my-3{margin-top:1rem!important}.mr-3,.mx-3{margin-right:1rem!important}.mb-3,.my-3{margin-bottom:1rem!important}.ml-3,.mx-3{margin-left:1rem!important}.m-4{margin:1.5rem!important}.mt-4,.my-4{margin-top:1.5rem!important}.mr-4,.mx-4{margin-right:1.5rem!important}.mb-4,.my-4{margin-bottom:1.5rem!important}.ml-4,.mx-4{margin-left:1.5rem!important}.m-5{margin:3rem!important}.mt-5,.my-5{margin-top:3rem!important}.mr-5,.mx-5{margin-right:3rem!important}.mb-5,.my-5{margin-bottom:3rem!important}.ml-5,.mx-5{margin-left:3rem!important}.m-6{margin:3.75rem!important}.mt-6,.my-6{margin-top:3.75rem!important}.mr-6,.mx-6{margin-right:3.75rem!important}.mb-6,.my-6{margin-bottom:3.75rem!important}.ml-6,.mx-6{margin-left:3.75rem!important}.m-7{margin:4.5rem!important}.mt-7,.my-7{margin-top:4.5rem!important}.mr-7,.mx-7{margin-right:4.5rem!important}.mb-7,.my-7{margin-bottom:4.5rem!important}.ml-7,.mx-7{margin-left:4.5rem!important}.m-8{margin:5rem!important}.mt-8,.my-8{margin-top:5rem!important}.mr-8,.mx-8{margin-right:5rem!important}.mb-8,.my-8{margin-bottom:5rem!important}.ml-8,.mx-8{margin-left:5rem!important}.p-0{padding:0!important}.pt-0,.py-0{padding-top:0!important}.pr-0,.px-0{padding-right:0!important}.pb-0,.py-0{padding-bottom:0!important}.pl-0,.px-0{padding-left:0!important}.p-1{padding:.25rem!important}.pt-1,.py-1{padding-top:.25rem!important}.pr-1,.px-1{padding-right:.25rem!important}.pb-1,.py-1{padding-bottom:.25rem!important}.pl-1,.px-1{padding-left:.25rem!important}.p-2{padding:.5rem!important}.pt-2,.py-2{padding-top:.5rem!important}.pr-2,.px-2{padding-right:.5rem!important}.pb-2,.py-2{padding-bottom:.5rem!important}.pl-2,.px-2{padding-left:.5rem!important}.p-3{padding:1rem!important}.pt-3,.py-3{padding-top:1rem!important}.pr-3,.px-3{padding-right:1rem!important}.pb-3,.py-3{padding-bottom:1rem!important}.pl-3,.px-3{padding-left:1rem!important}.p-4{padding:1.5rem!important}.pt-4,.py-4{padding-top:1.5rem!important}.pr-4,.px-4{padding-right:1.5rem!important}.pb-4,.py-4{padding-bottom:1.5rem!important}.pl-4,.px-4{padding-left:1.5rem!important}.p-5{padding:3rem!important}.pt-5,.py-5{padding-top:3rem!important}.pr-5,.px-5{padding-right:3rem!important}.pb-5,.py-5{padding-bottom:3rem!important}.pl-5,.px-5{padding-left:3rem!important}.p-6{padding:3.75rem!important}.pt-6,.py-6{padding-top:3.75rem!important}.pr-6,.px-6{padding-right:3.75rem!important}.pb-6,.py-6{padding-bottom:3.75rem!important}.pl-6,.px-6{padding-left:3.75rem!important}.p-7{padding:4.5rem!important}.pt-7,.py-7{padding-top:4.5rem!important}.pr-7,.px-7{padding-right:4.5rem!important}.pb-7,.py-7{padding-bottom:4.5rem!important}.pl-7,.px-7{padding-left:4.5rem!important}.p-8{padding:5rem!important}.pt-8,.py-8{padding-top:5rem!important}.pr-8,.px-8{padding-right:5rem!important}.pb-8,.py-8{padding-bottom:5rem!important}.pl-8,.px-8{padding-left:5rem!important}.m-n1{margin:-.25rem!important}.mt-n1,.my-n1{margin-top:-.25rem!important}.mr-n1,.mx-n1{margin-right:-.25rem!important}.mb-n1,.my-n1{margin-bottom:-.25rem!important}.ml-n1,.mx-n1{margin-left:-.25rem!important}.m-n2{margin:-.5rem!important}.mt-n2,.my-n2{margin-top:-.5rem!important}.mr-n2,.mx-n2{margin-right:-.5rem!important}.mb-n2,.my-n2{margin-bottom:-.5rem!important}.ml-n2,.mx-n2{margin-left:-.5rem!important}.m-n3{margin:-1rem!important}.mt-n3,.my-n3{margin-top:-1rem!important}.mr-n3,.mx-n3{margin-right:-1rem!important}.mb-n3,.my-n3{margin-bottom:-1rem!important}.ml-n3,.mx-n3{margin-left:-1rem!important}.m-n4{margin:-1.5rem!important}.mt-n4,.my-n4{margin-top:-1.5rem!important}.mr-n4,.mx-n4{margin-right:-1.5rem!important}.mb-n4,.my-n4{margin-bottom:-1.5rem!important}.ml-n4,.mx-n4{margin-left:-1.5rem!important}.m-n5{margin:-3rem!important}.mt-n5,.my-n5{margin-top:-3rem!important}.mr-n5,.mx-n5{margin-right:-3rem!important}.mb-n5,.my-n5{margin-bottom:-3rem!important}.ml-n5,.mx-n5{margin-left:-3rem!important}.m-n6{margin:-3.75rem!important}.mt-n6,.my-n6{margin-top:-3.75rem!important}.mr-n6,.mx-n6{margin-right:-3.75rem!important}.mb-n6,.my-n6{margin-bottom:-3.75rem!important}.ml-n6,.mx-n6{margin-left:-3.75rem!important}.m-n7{margin:-4.5rem!important}.mt-n7,.my-n7{margin-top:-4.5rem!important}.mr-n7,.mx-n7{margin-right:-4.5rem!important}.mb-n7,.my-n7{margin-bottom:-4.5rem!important}.ml-n7,.mx-n7{margin-left:-4.5rem!important}.m-n8{margin:-5rem!important}.mt-n8,.my-n8{margin-top:-5rem!important}.mr-n8,.mx-n8{margin-right:-5rem!important}.mb-n8,.my-n8{margin-bottom:-5rem!important}.ml-n8,.mx-n8{margin-left:-5rem!important}.m-auto{margin:auto!important}.mt-auto,.my-auto{margin-top:auto!important}.mr-auto,.mx-auto{margin-right:auto!important}.mb-auto,.my-auto{margin-bottom:auto!important}.ml-auto,.mx-auto{margin-left:auto!important}@media (min-width:576px){.m-sm-0{margin:0!important}.mt-sm-0,.my-sm-0{margin-top:0!important}.mr-sm-0,.mx-sm-0{margin-right:0!important}.mb-sm-0,.my-sm-0{margin-bottom:0!important}.ml-sm-0,.mx-sm-0{margin-left:0!important}.m-sm-1{margin:.25rem!important}.mt-sm-1,.my-sm-1{margin-top:.25rem!important}.mr-sm-1,.mx-sm-1{margin-right:.25rem!important}.mb-sm-1,.my-sm-1{margin-bottom:.25rem!important}.ml-sm-1,.mx-sm-1{margin-left:.25rem!important}.m-sm-2{margin:.5rem!important}.mt-sm-2,.my-sm-2{margin-top:.5rem!important}.mr-sm-2,.mx-sm-2{margin-right:.5rem!important}.mb-sm-2,.my-sm-2{margin-bottom:.5rem!important}.ml-sm-2,.mx-sm-2{margin-left:.5rem!important}.m-sm-3{margin:1rem!important}.mt-sm-3,.my-sm-3{margin-top:1rem!important}.mr-sm-3,.mx-sm-3{margin-right:1rem!important}.mb-sm-3,.my-sm-3{margin-bottom:1rem!important}.ml-sm-3,.mx-sm-3{margin-left:1rem!important}.m-sm-4{margin:1.5rem!important}.mt-sm-4,.my-sm-4{margin-top:1.5rem!important}.mr-sm-4,.mx-sm-4{margin-right:1.5rem!important}.mb-sm-4,.my-sm-4{margin-bottom:1.5rem!important}.ml-sm-4,.mx-sm-4{margin-left:1.5rem!important}.m-sm-5{margin:3rem!important}.mt-sm-5,.my-sm-5{margin-top:3rem!important}.mr-sm-5,.mx-sm-5{margin-right:3rem!important}.mb-sm-5,.my-sm-5{margin-bottom:3rem!important}.ml-sm-5,.mx-sm-5{margin-left:3rem!important}.m-sm-6{margin:3.75rem!important}.mt-sm-6,.my-sm-6{margin-top:3.75rem!important}.mr-sm-6,.mx-sm-6{margin-right:3.75rem!important}.mb-sm-6,.my-sm-6{margin-bottom:3.75rem!important}.ml-sm-6,.mx-sm-6{margin-left:3.75rem!important}.m-sm-7{margin:4.5rem!important}.mt-sm-7,.my-sm-7{margin-top:4.5rem!important}.mr-sm-7,.mx-sm-7{margin-right:4.5rem!important}.mb-sm-7,.my-sm-7{margin-bottom:4.5rem!important}.ml-sm-7,.mx-sm-7{margin-left:4.5rem!important}.m-sm-8{margin:5rem!important}.mt-sm-8,.my-sm-8{margin-top:5rem!important}.mr-sm-8,.mx-sm-8{margin-right:5rem!important}.mb-sm-8,.my-sm-8{margin-bottom:5rem!important}.ml-sm-8,.mx-sm-8{margin-left:5rem!important}.p-sm-0{padding:0!important}.pt-sm-0,.py-sm-0{padding-top:0!important}.pr-sm-0,.px-sm-0{padding-right:0!important}.pb-sm-0,.py-sm-0{padding-bottom:0!important}.pl-sm-0,.px-sm-0{padding-left:0!important}.p-sm-1{padding:.25rem!important}.pt-sm-1,.py-sm-1{padding-top:.25rem!important}.pr-sm-1,.px-sm-1{padding-right:.25rem!important}.pb-sm-1,.py-sm-1{padding-bottom:.25rem!important}.pl-sm-1,.px-sm-1{padding-left:.25rem!important}.p-sm-2{padding:.5rem!important}.pt-sm-2,.py-sm-2{padding-top:.5rem!important}.pr-sm-2,.px-sm-2{padding-right:.5rem!important}.pb-sm-2,.py-sm-2{padding-bottom:.5rem!important}.pl-sm-2,.px-sm-2{padding-left:.5rem!important}.p-sm-3{padding:1rem!important}.pt-sm-3,.py-sm-3{padding-top:1rem!important}.pr-sm-3,.px-sm-3{padding-right:1rem!important}.pb-sm-3,.py-sm-3{padding-bottom:1rem!important}.pl-sm-3,.px-sm-3{padding-left:1rem!important}.p-sm-4{padding:1.5rem!important}.pt-sm-4,.py-sm-4{padding-top:1.5rem!important}.pr-sm-4,.px-sm-4{padding-right:1.5rem!important}.pb-sm-4,.py-sm-4{padding-bottom:1.5rem!important}.pl-sm-4,.px-sm-4{padding-left:1.5rem!important}.p-sm-5{padding:3rem!important}.pt-sm-5,.py-sm-5{padding-top:3rem!important}.pr-sm-5,.px-sm-5{padding-right:3rem!important}.pb-sm-5,.py-sm-5{padding-bottom:3rem!important}.pl-sm-5,.px-sm-5{padding-left:3rem!important}.p-sm-6{padding:3.75rem!important}.pt-sm-6,.py-sm-6{padding-top:3.75rem!important}.pr-sm-6,.px-sm-6{padding-right:3.75rem!important}.pb-sm-6,.py-sm-6{padding-bottom:3.75rem!important}.pl-sm-6,.px-sm-6{padding-left:3.75rem!important}.p-sm-7{padding:4.5rem!important}.pt-sm-7,.py-sm-7{padding-top:4.5rem!important}.pr-sm-7,.px-sm-7{padding-right:4.5rem!important}.pb-sm-7,.py-sm-7{padding-bottom:4.5rem!important}.pl-sm-7,.px-sm-7{padding-left:4.5rem!important}.p-sm-8{padding:5rem!important}.pt-sm-8,.py-sm-8{padding-top:5rem!important}.pr-sm-8,.px-sm-8{padding-right:5rem!important}.pb-sm-8,.py-sm-8{padding-bottom:5rem!important}.pl-sm-8,.px-sm-8{padding-left:5rem!important}.m-sm-n1{margin:-.25rem!important}.mt-sm-n1,.my-sm-n1{margin-top:-.25rem!important}.mr-sm-n1,.mx-sm-n1{margin-right:-.25rem!important}.mb-sm-n1,.my-sm-n1{margin-bottom:-.25rem!important}.ml-sm-n1,.mx-sm-n1{margin-left:-.25rem!important}.m-sm-n2{margin:-.5rem!important}.mt-sm-n2,.my-sm-n2{margin-top:-.5rem!important}.mr-sm-n2,.mx-sm-n2{margin-right:-.5rem!important}.mb-sm-n2,.my-sm-n2{margin-bottom:-.5rem!important}.ml-sm-n2,.mx-sm-n2{margin-left:-.5rem!important}.m-sm-n3{margin:-1rem!important}.mt-sm-n3,.my-sm-n3{margin-top:-1rem!important}.mr-sm-n3,.mx-sm-n3{margin-right:-1rem!important}.mb-sm-n3,.my-sm-n3{margin-bottom:-1rem!important}.ml-sm-n3,.mx-sm-n3{margin-left:-1rem!important}.m-sm-n4{margin:-1.5rem!important}.mt-sm-n4,.my-sm-n4{margin-top:-1.5rem!important}.mr-sm-n4,.mx-sm-n4{margin-right:-1.5rem!important}.mb-sm-n4,.my-sm-n4{margin-bottom:-1.5rem!important}.ml-sm-n4,.mx-sm-n4{margin-left:-1.5rem!important}.m-sm-n5{margin:-3rem!important}.mt-sm-n5,.my-sm-n5{margin-top:-3rem!important}.mr-sm-n5,.mx-sm-n5{margin-right:-3rem!important}.mb-sm-n5,.my-sm-n5{margin-bottom:-3rem!important}.ml-sm-n5,.mx-sm-n5{margin-left:-3rem!important}.m-sm-n6{margin:-3.75rem!important}.mt-sm-n6,.my-sm-n6{margin-top:-3.75rem!important}.mr-sm-n6,.mx-sm-n6{margin-right:-3.75rem!important}.mb-sm-n6,.my-sm-n6{margin-bottom:-3.75rem!important}.ml-sm-n6,.mx-sm-n6{margin-left:-3.75rem!important}.m-sm-n7{margin:-4.5rem!important}.mt-sm-n7,.my-sm-n7{margin-top:-4.5rem!important}.mr-sm-n7,.mx-sm-n7{margin-right:-4.5rem!important}.mb-sm-n7,.my-sm-n7{margin-bottom:-4.5rem!important}.ml-sm-n7,.mx-sm-n7{margin-left:-4.5rem!important}.m-sm-n8{margin:-5rem!important}.mt-sm-n8,.my-sm-n8{margin-top:-5rem!important}.mr-sm-n8,.mx-sm-n8{margin-right:-5rem!important}.mb-sm-n8,.my-sm-n8{margin-bottom:-5rem!important}.ml-sm-n8,.mx-sm-n8{margin-left:-5rem!important}.m-sm-auto{margin:auto!important}.mt-sm-auto,.my-sm-auto{margin-top:auto!important}.mr-sm-auto,.mx-sm-auto{margin-right:auto!important}.mb-sm-auto,.my-sm-auto{margin-bottom:auto!important}.ml-sm-auto,.mx-sm-auto{margin-left:auto!important}}@media (min-width:768px){.m-md-0{margin:0!important}.mt-md-0,.my-md-0{margin-top:0!important}.mr-md-0,.mx-md-0{margin-right:0!important}.mb-md-0,.my-md-0{margin-bottom:0!important}.ml-md-0,.mx-md-0{margin-left:0!important}.m-md-1{margin:.25rem!important}.mt-md-1,.my-md-1{margin-top:.25rem!important}.mr-md-1,.mx-md-1{margin-right:.25rem!important}.mb-md-1,.my-md-1{margin-bottom:.25rem!important}.ml-md-1,.mx-md-1{margin-left:.25rem!important}.m-md-2{margin:.5rem!important}.mt-md-2,.my-md-2{margin-top:.5rem!important}.mr-md-2,.mx-md-2{margin-right:.5rem!important}.mb-md-2,.my-md-2{margin-bottom:.5rem!important}.ml-md-2,.mx-md-2{margin-left:.5rem!important}.m-md-3{margin:1rem!important}.mt-md-3,.my-md-3{margin-top:1rem!important}.mr-md-3,.mx-md-3{margin-right:1rem!important}.mb-md-3,.my-md-3{margin-bottom:1rem!important}.ml-md-3,.mx-md-3{margin-left:1rem!important}.m-md-4{margin:1.5rem!important}.mt-md-4,.my-md-4{margin-top:1.5rem!important}.mr-md-4,.mx-md-4{margin-right:1.5rem!important}.mb-md-4,.my-md-4{margin-bottom:1.5rem!important}.ml-md-4,.mx-md-4{margin-left:1.5rem!important}.m-md-5{margin:3rem!important}.mt-md-5,.my-md-5{margin-top:3rem!important}.mr-md-5,.mx-md-5{margin-right:3rem!important}.mb-md-5,.my-md-5{margin-bottom:3rem!important}.ml-md-5,.mx-md-5{margin-left:3rem!important}.m-md-6{margin:3.75rem!important}.mt-md-6,.my-md-6{margin-top:3.75rem!important}.mr-md-6,.mx-md-6{margin-right:3.75rem!important}.mb-md-6,.my-md-6{margin-bottom:3.75rem!important}.ml-md-6,.mx-md-6{margin-left:3.75rem!important}.m-md-7{margin:4.5rem!important}.mt-md-7,.my-md-7{margin-top:4.5rem!important}.mr-md-7,.mx-md-7{margin-right:4.5rem!important}.mb-md-7,.my-md-7{margin-bottom:4.5rem!important}.ml-md-7,.mx-md-7{margin-left:4.5rem!important}.m-md-8{margin:5rem!important}.mt-md-8,.my-md-8{margin-top:5rem!important}.mr-md-8,.mx-md-8{margin-right:5rem!important}.mb-md-8,.my-md-8{margin-bottom:5rem!important}.ml-md-8,.mx-md-8{margin-left:5rem!important}.p-md-0{padding:0!important}.pt-md-0,.py-md-0{padding-top:0!important}.pr-md-0,.px-md-0{padding-right:0!important}.pb-md-0,.py-md-0{padding-bottom:0!important}.pl-md-0,.px-md-0{padding-left:0!important}.p-md-1{padding:.25rem!important}.pt-md-1,.py-md-1{padding-top:.25rem!important}.pr-md-1,.px-md-1{padding-right:.25rem!important}.pb-md-1,.py-md-1{padding-bottom:.25rem!important}.pl-md-1,.px-md-1{padding-left:.25rem!important}.p-md-2{padding:.5rem!important}.pt-md-2,.py-md-2{padding-top:.5rem!important}.pr-md-2,.px-md-2{padding-right:.5rem!important}.pb-md-2,.py-md-2{padding-bottom:.5rem!important}.pl-md-2,.px-md-2{padding-left:.5rem!important}.p-md-3{padding:1rem!important}.pt-md-3,.py-md-3{padding-top:1rem!important}.pr-md-3,.px-md-3{padding-right:1rem!important}.pb-md-3,.py-md-3{padding-bottom:1rem!important}.pl-md-3,.px-md-3{padding-left:1rem!important}.p-md-4{padding:1.5rem!important}.pt-md-4,.py-md-4{padding-top:1.5rem!important}.pr-md-4,.px-md-4{padding-right:1.5rem!important}.pb-md-4,.py-md-4{padding-bottom:1.5rem!important}.pl-md-4,.px-md-4{padding-left:1.5rem!important}.p-md-5{padding:3rem!important}.pt-md-5,.py-md-5{padding-top:3rem!important}.pr-md-5,.px-md-5{padding-right:3rem!important}.pb-md-5,.py-md-5{padding-bottom:3rem!important}.pl-md-5,.px-md-5{padding-left:3rem!important}.p-md-6{padding:3.75rem!important}.pt-md-6,.py-md-6{padding-top:3.75rem!important}.pr-md-6,.px-md-6{padding-right:3.75rem!important}.pb-md-6,.py-md-6{padding-bottom:3.75rem!important}.pl-md-6,.px-md-6{padding-left:3.75rem!important}.p-md-7{padding:4.5rem!important}.pt-md-7,.py-md-7{padding-top:4.5rem!important}.pr-md-7,.px-md-7{padding-right:4.5rem!important}.pb-md-7,.py-md-7{padding-bottom:4.5rem!important}.pl-md-7,.px-md-7{padding-left:4.5rem!important}.p-md-8{padding:5rem!important}.pt-md-8,.py-md-8{padding-top:5rem!important}.pr-md-8,.px-md-8{padding-right:5rem!important}.pb-md-8,.py-md-8{padding-bottom:5rem!important}.pl-md-8,.px-md-8{padding-left:5rem!important}.m-md-n1{margin:-.25rem!important}.mt-md-n1,.my-md-n1{margin-top:-.25rem!important}.mr-md-n1,.mx-md-n1{margin-right:-.25rem!important}.mb-md-n1,.my-md-n1{margin-bottom:-.25rem!important}.ml-md-n1,.mx-md-n1{margin-left:-.25rem!important}.m-md-n2{margin:-.5rem!important}.mt-md-n2,.my-md-n2{margin-top:-.5rem!important}.mr-md-n2,.mx-md-n2{margin-right:-.5rem!important}.mb-md-n2,.my-md-n2{margin-bottom:-.5rem!important}.ml-md-n2,.mx-md-n2{margin-left:-.5rem!important}.m-md-n3{margin:-1rem!important}.mt-md-n3,.my-md-n3{margin-top:-1rem!important}.mr-md-n3,.mx-md-n3{margin-right:-1rem!important}.mb-md-n3,.my-md-n3{margin-bottom:-1rem!important}.ml-md-n3,.mx-md-n3{margin-left:-1rem!important}.m-md-n4{margin:-1.5rem!important}.mt-md-n4,.my-md-n4{margin-top:-1.5rem!important}.mr-md-n4,.mx-md-n4{margin-right:-1.5rem!important}.mb-md-n4,.my-md-n4{margin-bottom:-1.5rem!important}.ml-md-n4,.mx-md-n4{margin-left:-1.5rem!important}.m-md-n5{margin:-3rem!important}.mt-md-n5,.my-md-n5{margin-top:-3rem!important}.mr-md-n5,.mx-md-n5{margin-right:-3rem!important}.mb-md-n5,.my-md-n5{margin-bottom:-3rem!important}.ml-md-n5,.mx-md-n5{margin-left:-3rem!important}.m-md-n6{margin:-3.75rem!important}.mt-md-n6,.my-md-n6{margin-top:-3.75rem!important}.mr-md-n6,.mx-md-n6{margin-right:-3.75rem!important}.mb-md-n6,.my-md-n6{margin-bottom:-3.75rem!important}.ml-md-n6,.mx-md-n6{margin-left:-3.75rem!important}.m-md-n7{margin:-4.5rem!important}.mt-md-n7,.my-md-n7{margin-top:-4.5rem!important}.mr-md-n7,.mx-md-n7{margin-right:-4.5rem!important}.mb-md-n7,.my-md-n7{margin-bottom:-4.5rem!important}.ml-md-n7,.mx-md-n7{margin-left:-4.5rem!important}.m-md-n8{margin:-5rem!important}.mt-md-n8,.my-md-n8{margin-top:-5rem!important}.mr-md-n8,.mx-md-n8{margin-right:-5rem!important}.mb-md-n8,.my-md-n8{margin-bottom:-5rem!important}.ml-md-n8,.mx-md-n8{margin-left:-5rem!important}.m-md-auto{margin:auto!important}.mt-md-auto,.my-md-auto{margin-top:auto!important}.mr-md-auto,.mx-md-auto{margin-right:auto!important}.mb-md-auto,.my-md-auto{margin-bottom:auto!important}.ml-md-auto,.mx-md-auto{margin-left:auto!important}}@media (min-width:992px){.m-lg-0{margin:0!important}.mt-lg-0,.my-lg-0{margin-top:0!important}.mr-lg-0,.mx-lg-0{margin-right:0!important}.mb-lg-0,.my-lg-0{margin-bottom:0!important}.ml-lg-0,.mx-lg-0{margin-left:0!important}.m-lg-1{margin:.25rem!important}.mt-lg-1,.my-lg-1{margin-top:.25rem!important}.mr-lg-1,.mx-lg-1{margin-right:.25rem!important}.mb-lg-1,.my-lg-1{margin-bottom:.25rem!important}.ml-lg-1,.mx-lg-1{margin-left:.25rem!important}.m-lg-2{margin:.5rem!important}.mt-lg-2,.my-lg-2{margin-top:.5rem!important}.mr-lg-2,.mx-lg-2{margin-right:.5rem!important}.mb-lg-2,.my-lg-2{margin-bottom:.5rem!important}.ml-lg-2,.mx-lg-2{margin-left:.5rem!important}.m-lg-3{margin:1rem!important}.mt-lg-3,.my-lg-3{margin-top:1rem!important}.mr-lg-3,.mx-lg-3{margin-right:1rem!important}.mb-lg-3,.my-lg-3{margin-bottom:1rem!important}.ml-lg-3,.mx-lg-3{margin-left:1rem!important}.m-lg-4{margin:1.5rem!important}.mt-lg-4,.my-lg-4{margin-top:1.5rem!important}.mr-lg-4,.mx-lg-4{margin-right:1.5rem!important}.mb-lg-4,.my-lg-4{margin-bottom:1.5rem!important}.ml-lg-4,.mx-lg-4{margin-left:1.5rem!important}.m-lg-5{margin:3rem!important}.mt-lg-5,.my-lg-5{margin-top:3rem!important}.mr-lg-5,.mx-lg-5{margin-right:3rem!important}.mb-lg-5,.my-lg-5{margin-bottom:3rem!important}.ml-lg-5,.mx-lg-5{margin-left:3rem!important}.m-lg-6{margin:3.75rem!important}.mt-lg-6,.my-lg-6{margin-top:3.75rem!important}.mr-lg-6,.mx-lg-6{margin-right:3.75rem!important}.mb-lg-6,.my-lg-6{margin-bottom:3.75rem!important}.ml-lg-6,.mx-lg-6{margin-left:3.75rem!important}.m-lg-7{margin:4.5rem!important}.mt-lg-7,.my-lg-7{margin-top:4.5rem!important}.mr-lg-7,.mx-lg-7{margin-right:4.5rem!important}.mb-lg-7,.my-lg-7{margin-bottom:4.5rem!important}.ml-lg-7,.mx-lg-7{margin-left:4.5rem!important}.m-lg-8{margin:5rem!important}.mt-lg-8,.my-lg-8{margin-top:5rem!important}.mr-lg-8,.mx-lg-8{margin-right:5rem!important}.mb-lg-8,.my-lg-8{margin-bottom:5rem!important}.ml-lg-8,.mx-lg-8{margin-left:5rem!important}.p-lg-0{padding:0!important}.pt-lg-0,.py-lg-0{padding-top:0!important}.pr-lg-0,.px-lg-0{padding-right:0!important}.pb-lg-0,.py-lg-0{padding-bottom:0!important}.pl-lg-0,.px-lg-0{padding-left:0!important}.p-lg-1{padding:.25rem!important}.pt-lg-1,.py-lg-1{padding-top:.25rem!important}.pr-lg-1,.px-lg-1{padding-right:.25rem!important}.pb-lg-1,.py-lg-1{padding-bottom:.25rem!important}.pl-lg-1,.px-lg-1{padding-left:.25rem!important}.p-lg-2{padding:.5rem!important}.pt-lg-2,.py-lg-2{padding-top:.5rem!important}.pr-lg-2,.px-lg-2{padding-right:.5rem!important}.pb-lg-2,.py-lg-2{padding-bottom:.5rem!important}.pl-lg-2,.px-lg-2{padding-left:.5rem!important}.p-lg-3{padding:1rem!important}.pt-lg-3,.py-lg-3{padding-top:1rem!important}.pr-lg-3,.px-lg-3{padding-right:1rem!important}.pb-lg-3,.py-lg-3{padding-bottom:1rem!important}.pl-lg-3,.px-lg-3{padding-left:1rem!important}.p-lg-4{padding:1.5rem!important}.pt-lg-4,.py-lg-4{padding-top:1.5rem!important}.pr-lg-4,.px-lg-4{padding-right:1.5rem!important}.pb-lg-4,.py-lg-4{padding-bottom:1.5rem!important}.pl-lg-4,.px-lg-4{padding-left:1.5rem!important}.p-lg-5{padding:3rem!important}.pt-lg-5,.py-lg-5{padding-top:3rem!important}.pr-lg-5,.px-lg-5{padding-right:3rem!important}.pb-lg-5,.py-lg-5{padding-bottom:3rem!important}.pl-lg-5,.px-lg-5{padding-left:3rem!important}.p-lg-6{padding:3.75rem!important}.pt-lg-6,.py-lg-6{padding-top:3.75rem!important}.pr-lg-6,.px-lg-6{padding-right:3.75rem!important}.pb-lg-6,.py-lg-6{padding-bottom:3.75rem!important}.pl-lg-6,.px-lg-6{padding-left:3.75rem!important}.p-lg-7{padding:4.5rem!important}.pt-lg-7,.py-lg-7{padding-top:4.5rem!important}.pr-lg-7,.px-lg-7{padding-right:4.5rem!important}.pb-lg-7,.py-lg-7{padding-bottom:4.5rem!important}.pl-lg-7,.px-lg-7{padding-left:4.5rem!important}.p-lg-8{padding:5rem!important}.pt-lg-8,.py-lg-8{padding-top:5rem!important}.pr-lg-8,.px-lg-8{padding-right:5rem!important}.pb-lg-8,.py-lg-8{padding-bottom:5rem!important}.pl-lg-8,.px-lg-8{padding-left:5rem!important}.m-lg-n1{margin:-.25rem!important}.mt-lg-n1,.my-lg-n1{margin-top:-.25rem!important}.mr-lg-n1,.mx-lg-n1{margin-right:-.25rem!important}.mb-lg-n1,.my-lg-n1{margin-bottom:-.25rem!important}.ml-lg-n1,.mx-lg-n1{margin-left:-.25rem!important}.m-lg-n2{margin:-.5rem!important}.mt-lg-n2,.my-lg-n2{margin-top:-.5rem!important}.mr-lg-n2,.mx-lg-n2{margin-right:-.5rem!important}.mb-lg-n2,.my-lg-n2{margin-bottom:-.5rem!important}.ml-lg-n2,.mx-lg-n2{margin-left:-.5rem!important}.m-lg-n3{margin:-1rem!important}.mt-lg-n3,.my-lg-n3{margin-top:-1rem!important}.mr-lg-n3,.mx-lg-n3{margin-right:-1rem!important}.mb-lg-n3,.my-lg-n3{margin-bottom:-1rem!important}.ml-lg-n3,.mx-lg-n3{margin-left:-1rem!important}.m-lg-n4{margin:-1.5rem!important}.mt-lg-n4,.my-lg-n4{margin-top:-1.5rem!important}.mr-lg-n4,.mx-lg-n4{margin-right:-1.5rem!important}.mb-lg-n4,.my-lg-n4{margin-bottom:-1.5rem!important}.ml-lg-n4,.mx-lg-n4{margin-left:-1.5rem!important}.m-lg-n5{margin:-3rem!important}.mt-lg-n5,.my-lg-n5{margin-top:-3rem!important}.mr-lg-n5,.mx-lg-n5{margin-right:-3rem!important}.mb-lg-n5,.my-lg-n5{margin-bottom:-3rem!important}.ml-lg-n5,.mx-lg-n5{margin-left:-3rem!important}.m-lg-n6{margin:-3.75rem!important}.mt-lg-n6,.my-lg-n6{margin-top:-3.75rem!important}.mr-lg-n6,.mx-lg-n6{margin-right:-3.75rem!important}.mb-lg-n6,.my-lg-n6{margin-bottom:-3.75rem!important}.ml-lg-n6,.mx-lg-n6{margin-left:-3.75rem!important}.m-lg-n7{margin:-4.5rem!important}.mt-lg-n7,.my-lg-n7{margin-top:-4.5rem!important}.mr-lg-n7,.mx-lg-n7{margin-right:-4.5rem!important}.mb-lg-n7,.my-lg-n7{margin-bottom:-4.5rem!important}.ml-lg-n7,.mx-lg-n7{margin-left:-4.5rem!important}.m-lg-n8{margin:-5rem!important}.mt-lg-n8,.my-lg-n8{margin-top:-5rem!important}.mr-lg-n8,.mx-lg-n8{margin-right:-5rem!important}.mb-lg-n8,.my-lg-n8{margin-bottom:-5rem!important}.ml-lg-n8,.mx-lg-n8{margin-left:-5rem!important}.m-lg-auto{margin:auto!important}.mt-lg-auto,.my-lg-auto{margin-top:auto!important}.mr-lg-auto,.mx-lg-auto{margin-right:auto!important}.mb-lg-auto,.my-lg-auto{margin-bottom:auto!important}.ml-lg-auto,.mx-lg-auto{margin-left:auto!important}}@media (min-width:1200px){.m-xl-0{margin:0!important}.mt-xl-0,.my-xl-0{margin-top:0!important}.mr-xl-0,.mx-xl-0{margin-right:0!important}.mb-xl-0,.my-xl-0{margin-bottom:0!important}.ml-xl-0,.mx-xl-0{margin-left:0!important}.m-xl-1{margin:.25rem!important}.mt-xl-1,.my-xl-1{margin-top:.25rem!important}.mr-xl-1,.mx-xl-1{margin-right:.25rem!important}.mb-xl-1,.my-xl-1{margin-bottom:.25rem!important}.ml-xl-1,.mx-xl-1{margin-left:.25rem!important}.m-xl-2{margin:.5rem!important}.mt-xl-2,.my-xl-2{margin-top:.5rem!important}.mr-xl-2,.mx-xl-2{margin-right:.5rem!important}.mb-xl-2,.my-xl-2{margin-bottom:.5rem!important}.ml-xl-2,.mx-xl-2{margin-left:.5rem!important}.m-xl-3{margin:1rem!important}.mt-xl-3,.my-xl-3{margin-top:1rem!important}.mr-xl-3,.mx-xl-3{margin-right:1rem!important}.mb-xl-3,.my-xl-3{margin-bottom:1rem!important}.ml-xl-3,.mx-xl-3{margin-left:1rem!important}.m-xl-4{margin:1.5rem!important}.mt-xl-4,.my-xl-4{margin-top:1.5rem!important}.mr-xl-4,.mx-xl-4{margin-right:1.5rem!important}.mb-xl-4,.my-xl-4{margin-bottom:1.5rem!important}.ml-xl-4,.mx-xl-4{margin-left:1.5rem!important}.m-xl-5{margin:3rem!important}.mt-xl-5,.my-xl-5{margin-top:3rem!important}.mr-xl-5,.mx-xl-5{margin-right:3rem!important}.mb-xl-5,.my-xl-5{margin-bottom:3rem!important}.ml-xl-5,.mx-xl-5{margin-left:3rem!important}.m-xl-6{margin:3.75rem!important}.mt-xl-6,.my-xl-6{margin-top:3.75rem!important}.mr-xl-6,.mx-xl-6{margin-right:3.75rem!important}.mb-xl-6,.my-xl-6{margin-bottom:3.75rem!important}.ml-xl-6,.mx-xl-6{margin-left:3.75rem!important}.m-xl-7{margin:4.5rem!important}.mt-xl-7,.my-xl-7{margin-top:4.5rem!important}.mr-xl-7,.mx-xl-7{margin-right:4.5rem!important}.mb-xl-7,.my-xl-7{margin-bottom:4.5rem!important}.ml-xl-7,.mx-xl-7{margin-left:4.5rem!important}.m-xl-8{margin:5rem!important}.mt-xl-8,.my-xl-8{margin-top:5rem!important}.mr-xl-8,.mx-xl-8{margin-right:5rem!important}.mb-xl-8,.my-xl-8{margin-bottom:5rem!important}.ml-xl-8,.mx-xl-8{margin-left:5rem!important}.p-xl-0{padding:0!important}.pt-xl-0,.py-xl-0{padding-top:0!important}.pr-xl-0,.px-xl-0{padding-right:0!important}.pb-xl-0,.py-xl-0{padding-bottom:0!important}.pl-xl-0,.px-xl-0{padding-left:0!important}.p-xl-1{padding:.25rem!important}.pt-xl-1,.py-xl-1{padding-top:.25rem!important}.pr-xl-1,.px-xl-1{padding-right:.25rem!important}.pb-xl-1,.py-xl-1{padding-bottom:.25rem!important}.pl-xl-1,.px-xl-1{padding-left:.25rem!important}.p-xl-2{padding:.5rem!important}.pt-xl-2,.py-xl-2{padding-top:.5rem!important}.pr-xl-2,.px-xl-2{padding-right:.5rem!important}.pb-xl-2,.py-xl-2{padding-bottom:.5rem!important}.pl-xl-2,.px-xl-2{padding-left:.5rem!important}.p-xl-3{padding:1rem!important}.pt-xl-3,.py-xl-3{padding-top:1rem!important}.pr-xl-3,.px-xl-3{padding-right:1rem!important}.pb-xl-3,.py-xl-3{padding-bottom:1rem!important}.pl-xl-3,.px-xl-3{padding-left:1rem!important}.p-xl-4{padding:1.5rem!important}.pt-xl-4,.py-xl-4{padding-top:1.5rem!important}.pr-xl-4,.px-xl-4{padding-right:1.5rem!important}.pb-xl-4,.py-xl-4{padding-bottom:1.5rem!important}.pl-xl-4,.px-xl-4{padding-left:1.5rem!important}.p-xl-5{padding:3rem!important}.pt-xl-5,.py-xl-5{padding-top:3rem!important}.pr-xl-5,.px-xl-5{padding-right:3rem!important}.pb-xl-5,.py-xl-5{padding-bottom:3rem!important}.pl-xl-5,.px-xl-5{padding-left:3rem!important}.p-xl-6{padding:3.75rem!important}.pt-xl-6,.py-xl-6{padding-top:3.75rem!important}.pr-xl-6,.px-xl-6{padding-right:3.75rem!important}.pb-xl-6,.py-xl-6{padding-bottom:3.75rem!important}.pl-xl-6,.px-xl-6{padding-left:3.75rem!important}.p-xl-7{padding:4.5rem!important}.pt-xl-7,.py-xl-7{padding-top:4.5rem!important}.pr-xl-7,.px-xl-7{padding-right:4.5rem!important}.pb-xl-7,.py-xl-7{padding-bottom:4.5rem!important}.pl-xl-7,.px-xl-7{padding-left:4.5rem!important}.p-xl-8{padding:5rem!important}.pt-xl-8,.py-xl-8{padding-top:5rem!important}.pr-xl-8,.px-xl-8{padding-right:5rem!important}.pb-xl-8,.py-xl-8{padding-bottom:5rem!important}.pl-xl-8,.px-xl-8{padding-left:5rem!important}.m-xl-n1{margin:-.25rem!important}.mt-xl-n1,.my-xl-n1{margin-top:-.25rem!important}.mr-xl-n1,.mx-xl-n1{margin-right:-.25rem!important}.mb-xl-n1,.my-xl-n1{margin-bottom:-.25rem!important}.ml-xl-n1,.mx-xl-n1{margin-left:-.25rem!important}.m-xl-n2{margin:-.5rem!important}.mt-xl-n2,.my-xl-n2{margin-top:-.5rem!important}.mr-xl-n2,.mx-xl-n2{margin-right:-.5rem!important}.mb-xl-n2,.my-xl-n2{margin-bottom:-.5rem!important}.ml-xl-n2,.mx-xl-n2{margin-left:-.5rem!important}.m-xl-n3{margin:-1rem!important}.mt-xl-n3,.my-xl-n3{margin-top:-1rem!important}.mr-xl-n3,.mx-xl-n3{margin-right:-1rem!important}.mb-xl-n3,.my-xl-n3{margin-bottom:-1rem!important}.ml-xl-n3,.mx-xl-n3{margin-left:-1rem!important}.m-xl-n4{margin:-1.5rem!important}.mt-xl-n4,.my-xl-n4{margin-top:-1.5rem!important}.mr-xl-n4,.mx-xl-n4{margin-right:-1.5rem!important}.mb-xl-n4,.my-xl-n4{margin-bottom:-1.5rem!important}.ml-xl-n4,.mx-xl-n4{margin-left:-1.5rem!important}.m-xl-n5{margin:-3rem!important}.mt-xl-n5,.my-xl-n5{margin-top:-3rem!important}.mr-xl-n5,.mx-xl-n5{margin-right:-3rem!important}.mb-xl-n5,.my-xl-n5{margin-bottom:-3rem!important}.ml-xl-n5,.mx-xl-n5{margin-left:-3rem!important}.m-xl-n6{margin:-3.75rem!important}.mt-xl-n6,.my-xl-n6{margin-top:-3.75rem!important}.mr-xl-n6,.mx-xl-n6{margin-right:-3.75rem!important}.mb-xl-n6,.my-xl-n6{margin-bottom:-3.75rem!important}.ml-xl-n6,.mx-xl-n6{margin-left:-3.75rem!important}.m-xl-n7{margin:-4.5rem!important}.mt-xl-n7,.my-xl-n7{margin-top:-4.5rem!important}.mr-xl-n7,.mx-xl-n7{margin-right:-4.5rem!important}.mb-xl-n7,.my-xl-n7{margin-bottom:-4.5rem!important}.ml-xl-n7,.mx-xl-n7{margin-left:-4.5rem!important}.m-xl-n8{margin:-5rem!important}.mt-xl-n8,.my-xl-n8{margin-top:-5rem!important}.mr-xl-n8,.mx-xl-n8{margin-right:-5rem!important}.mb-xl-n8,.my-xl-n8{margin-bottom:-5rem!important}.ml-xl-n8,.mx-xl-n8{margin-left:-5rem!important}.m-xl-auto{margin:auto!important}.mt-xl-auto,.my-xl-auto{margin-top:auto!important}.mr-xl-auto,.mx-xl-auto{margin-right:auto!important}.mb-xl-auto,.my-xl-auto{margin-bottom:auto!important}.ml-xl-auto,.mx-xl-auto{margin-left:auto!important}}.stretched-link:after{position:absolute;top:0;right:0;bottom:0;left:0;z-index:1;pointer-events:auto;content:"";background-color:transparent}.text-monospace{font-family:SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,monospace!important}.text-justify{text-align:justify!important}.text-wrap{white-space:normal!important}.text-nowrap{white-space:nowrap!important}.text-truncate{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.text-left{text-align:left!important}.text-right{text-align:right!important}.text-center{text-align:center!important}@media (min-width:576px){.text-sm-left{text-align:left!important}.text-sm-right{text-align:right!important}.text-sm-center{text-align:center!important}}@media (min-width:768px){.text-md-left{text-align:left!important}.text-md-right{text-align:right!important}.text-md-center{text-align:center!important}}@media (min-width:992px){.text-lg-left{text-align:left!important}.text-lg-right{text-align:right!important}.text-lg-center{text-align:center!important}}@media (min-width:1200px){.text-xl-left{text-align:left!important}.text-xl-right{text-align:right!important}.text-xl-center{text-align:center!important}}.text-lowercase{text-transform:lowercase!important}.text-uppercase{text-transform:uppercase!important}.text-capitalize{text-transform:capitalize!important}.font-weight-light{font-weight:300!important}.font-weight-lighter{font-weight:lighter!important}.font-weight-normal{font-weight:400!important}.font-weight-bold{font-weight:700!important}.font-weight-bolder{font-weight:bolder!important}.font-italic{font-style:italic!important}.text-white{color:#fff!important}.text-primary{color:#007bff!important}a.text-primary:focus,a.text-primary:hover{color:#0056b3!important}.text-secondary{color:#6c757d!important}a.text-secondary:focus,a.text-secondary:hover{color:#494f54!important}.text-success{color:#28a745!important}a.text-success:focus,a.text-success:hover{color:#19692c!important}.text-info{color:#17a2b8!important}a.text-info:focus,a.text-info:hover{color:#0f6674!important}.text-warning{color:#ffc107!important}a.text-warning:focus,a.text-warning:hover{color:#ba8b00!important}.text-danger{color:#dc3545!important}a.text-danger:focus,a.text-danger:hover{color:#a71d2a!important}.text-light{color:#f8f9fa!important}a.text-light:focus,a.text-light:hover{color:#cbd3da!important}.text-dark{color:#343a40!important}a.text-dark:focus,a.text-dark:hover{color:#121416!important}.text-body{color:#212529!important}.text-muted{color:#6c757d!important}.text-black-50{color:rgba(0,0,0,.5)!important}.text-white-50{color:hsla(0,0%,100%,.5)!important}.text-hide{font:0/0 a;color:transparent;text-shadow:none;background-color:transparent;border:0}.text-decoration-none{text-decoration:none!important}.text-break{word-break:break-word!important;word-wrap:break-word!important}.text-reset{color:inherit!important}.visible{visibility:visible!important}.invisible{visibility:hidden!important}.awesomplete>ul{background:#333;padding:0!important}.awesomplete>ul>li{padding:10px 15px;border-bottom:1px solid #707070;color:#efefef;font-size:17px}.awesomplete>ul>li:last-child{border-bottom:0}.awesomplete>ul>li[aria-selected=true]{background-color:#ff6f00}.awesomplete>ul>li:before{content:none!important}img{max-width:100%}div{min-width:0}body{color:#797f90;font-family:Arial,sans-serif;font-size:18px;line-height:1.5}@media (min-width:768px){body{font-size:18px}}.html__font-loaded--primary body{font-family:Open Sans,Arial,sans-serif}a{color:#ff6f00;text-decoration:underline}.h1,.h2,.h3,.h4,.h5,.h6,h1,h2,h3,h4,h5,h6{font-weight:600;color:#333}.typography-white .h1,.typography-white .h2,.typography-white .h3,.typography-white .h4,.typography-white .h5,.typography-white .h6,.typography-white h1,.typography-white h2,.typography-white h3,.typography-white h4,.typography-white h5,.typography-white h6{color:#fff}.h1.no-margin-top,.h2.no-margin-top,.h3.no-margin-top,.h4.no-margin-top,.h5.no-margin-top,.h6.no-margin-top,.no-margin-top .h1,.no-margin-top .h2,.no-margin-top .h3,.no-margin-top .h4,.no-margin-top .h5,.no-margin-top .h6,.no-margin-top h1,.no-margin-top h2,.no-margin-top h3,.no-margin-top h4,.no-margin-top h5,.no-margin-top h6,h1.no-margin-top,h2.no-margin-top,h3.no-margin-top,h4.no-margin-top,h5.no-margin-top,h6.no-margin-top{margin-top:0!important}.h1,h1{font-size:12vw;line-height:1.2}@media (min-width:410px){.h1,h1{font-size:42px}}@media (min-width:767px){.h1,h1{font-size:50px}}.h2,h2{font-size:36px;line-height:1.1}@media (min-width:768px){.h2,h2{font-size:40px}}.h3,h3{font-size:26px;line-height:1.1}@media (min-width:768px){.h3,h3{font-size:30px}}.h4,h4{font-size:22px}h5{font-size:20px}h6{font-size:18px}.pb-header .navbar{background:#333}@media (max-width:991px){.pb-header .navbar{padding-top:10px;padding-bottom:10px}}.pb-header .navbar-brand>img{display:block;max-width:140px;max-height:25px}.pb-header .dropdown-toggle:after{content:none}.pb-header .nav-item{padding-top:5px;padding-bottom:5px;margin-right:32px}.pb-header .nav-item:last-of-type{margin-right:0}@media (min-width:992px){.pb-header .nav-item{padding-top:34px;padding-bottom:24px}}.pb-header .nav-link{font-size:16px;text-decoration:none}@media (min-width:992px){.pb-header .nav-link[aria-expanded=true]:after{position:absolute;bottom:0;left:50%;height:0;width:0;border-color:transparent transparent #fff;border-style:solid;border-width:0 5.5px 8px;transform:translateX(-50%) translateY(0);z-index:5;content:""}}.pb-header .dropdown-menu{box-shadow:10px 10px 30px rgba(0,0,0,.16);-moz-column-rule:1px solid #dddfe3;column-rule:1px solid #dddfe3;padding:10px 0}@media (min-width:992px){.pb-header .dropdown-menu{padding:24px 0}.pb-header .dropdown-menu--product{-moz-columns:3;column-count:3;left:50%;transform:translateX(-50%)}.pb-header .dropdown-menu--support{-moz-columns:2;column-count:2;left:50%;transform:translateX(-50%)}.pb-header .dropdown-menu--resources{right:0;left:auto}.pb-header .dropdown-menu .dropdown-section{-moz-column-break-inside:avoid;break-inside:avoid-column}}.pb-header .dropdown-item{font-size:15px;text-decoration:none}.pb-header .dropdown-item--heading{font-weight:600;color:#333}.pb-header .dropdown-item--heading:hover{color:#ff6f00}@media (max-width:991px){.sidebar{margin-bottom:20px}}.sidebar a{text-decoration:none}.sidebar .navbar-toggler{color:rgba(0,0,0,.5);border-color:rgba(0,0,0,.1)}.sidebar .navbar-toggler-icon{background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='30' height='30'%3E%3Cpath stroke='rgba(0, 0, 0, 0.5)' stroke-linecap='round' stroke-miterlimit='10' stroke-width='2' d='M4 7h22M4 15h22M4 23h22'/%3E%3C/svg%3E")}.sidebar .collapse.is-active,.sidebar .list-group-item{display:block}.sidebar .list-group-item--level-0{position:relative;padding:9px 12px 11px 14px;border-top:1px solid #dddfe3;color:#797f90;font-size:20px}.sidebar .list-group-item--level-0:after{position:absolute;top:50%;right:12px;height:8px;width:15px;transform:translateY(-50%);background:url(/assets/images/icons/down-carrot-0.svg) no-repeat 0 0;content:""}.sidebar .list-group-item--level-0:last-of-type{border-bottom:1px solid #dddfe3}.sidebar .list-group-item--level-0>.pb-section-title{display:inline-block;padding-right:20px}.sidebar .list-group-item--level-0.is-active{background-color:#333;color:#fff}.sidebar .list-group-item--level-0.is-active:after{background-image:url(/assets/images/icons/up-carrot-0.svg)}.sidebar .list-group-item--level-0.is-active+.sidebar-submenu+.list-group-item{border-top:0}.sidebar .list-group-item--level-1{padding:8px 14px 9px;background-color:hsla(0,0%,100%,.25);border-bottom:1px solid #dddfe3;color:#797f90;font-size:18px}.sidebar .list-group-item--level-1.is-active{position:relative;color:#ff6f00}.sidebar .list-group-item--level-1.is-active:after{position:absolute;top:50%;right:15px;height:5px;width:10px;transform:translateY(-50%);background-image:url(/assets/images/icons/up-carrot-1.svg);background-repeat:no-repeat;background-position:0 0;content:""}.sidebar .list-group-item--level-1.is-active>.pb-section-subtitle{display:inline-block;padding-right:15px}.sidebar .list-group-item--level-1.is-active+.sidebar-submenu{background-color:hsla(0,0%,100%,.25)}.sidebar .list-group-item--level-1>.menu-collapsed.pb-nav-item.is-active{color:#ff6f00}.sidebar .list-group-item--level-2{padding:11px 14px 4px;background-color:hsla(0,0%,100%,.5);color:#797f90;font-size:15px}.sidebar .list-group-item--level-2:last-child{padding-bottom:11px;border-bottom:1px solid #dddfe3}.sidebar .list-group-item--level-2.is-active{color:#ff6f00}.sidebar .list-group-item--level-2>.pb-nav-item--title{display:block;margin-bottom:-8px;padding-bottom:5px;border-bottom:1px solid #999;color:#333}.pb-footer{padding-top:50px;padding-bottom:30px;background:#fff;font-size:12px;line-height:1.2}.banner--medium .card{background:none;border-color:hsla(0,0%,100%,.8)}.card-media{display:flex;justify-content:center;align-items:center}.card-deck--products .card-media{min-height:96px;margin-top:6px}.card-deck--products .card-title{margin-top:30px}.card-deck--md .card{margin-bottom:10px}@media (min-width:768px){.card-deck--md{display:flex;flex-flow:row wrap;margin-right:-10px;margin-left:-10px}.card-deck--md .card{flex:1 0 0%;margin-right:10px;margin-bottom:0;margin-left:10px}}.card-deck--formats .card{margin-bottom:10px;z-index:2}.card-deck--formats .card-body{display:flex;flex-flow:column-reverse;justify-content:space-around}.card-deck--formats .card-title{font-weight:600;margin-top:24px;margin-bottom:0;font-size:22px;line-height:1.2;color:#1ba9e1;text-decoration:none}.card-deck--formats .card-title:hover{color:#fff;z-index:2}.card-deck--formats .card-title:hover:before{position:absolute;top:0;right:0;bottom:0;left:0;z-index:-1;background-color:#ff6f00;content:""}.card-deck--formats .card-title:hover+.card-media{cursor:pointer;pointer-events:none}.card-deck--formats .card-title:hover+.card-media path{stroke:#fff}.card-deck--formats .card-title:hover+.card-media path[fill="#ff6f00"]{fill:#fff}.card-deck--formats .card-title+.card-media{position:relative;z-index:2}@media (min-width:576px){.card-deck--formats{display:flex;flex-flow:row wrap;justify-content:center;margin-right:-10px;margin-left:-10px}.card-deck--formats .card{flex:1 0 0%;min-width:180px;max-width:200px;margin-right:10px;margin-bottom:20px;margin-left:10px}}.banner--medium .card-deck .card{z-index:2}.banner--medium .card-deck .card-body{display:flex;flex-flow:column;justify-content:space-around}.banner--medium .card-deck .card-title{margin-top:24px;margin-bottom:0}.banner--medium .card-deck .card-title a{color:#fff;font-size:26px;text-decoration:none}.banner--medium .card-deck .card-title a:before{position:absolute;top:0;right:0;bottom:0;left:0;background-color:#ff6f00;opacity:0;z-index:-1;content:""}.banner--medium .card-deck .card-title a:hover:before{opacity:1}.banner{padding-top:4rem;padding-bottom:5.5rem}.banner--medium{background:#7e8c97;color:#fff}.banner--light{background:#fff;padding-bottom:0}.banner--light hr{margin-top:30px;border:0;border-top:1px solid rgba(221,223,227,.49);background:none}.btn-outline-brand{color:#1ba9e1;font-weight:700;padding:18px 32px 15px;border-color:#dddfe3;font-size:18px;text-decoration:none}.btn-outline-brand:hover{color:#fff;background-color:#1ba9e1;border-color:#1ba9e1}.btn-outline-brand.focus,.btn-outline-brand:focus{box-shadow:0 0 0 .2rem rgba(27,169,225,.5)}.btn-outline-brand.disabled,.btn-outline-brand:disabled{color:#1ba9e1;background-color:transparent}.btn-outline-brand:not(:disabled):not(.disabled).active,.btn-outline-brand:not(:disabled):not(.disabled):active,.show>.btn-outline-brand.dropdown-toggle{color:#fff;background-color:#1ba9e1;border-color:#1ba9e1}.btn-outline-brand:not(:disabled):not(.disabled).active:focus,.btn-outline-brand:not(:disabled):not(.disabled):active:focus,.show>.btn-outline-brand.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(27,169,225,.5)}@media (min-width:992px){.btn-outline-brand{padding-right:68px;padding-left:68px}}.pb-lg-img{width:70%;height:70%}.row>.wrapper{display:flex;flex-wrap:wrap;margin-right:-10px;margin-left:-10px}@media (min-width:992px){.pb-docs-container>.row>.col-lg-3.sidebar{flex:0 0 22%;max-width:22%}.pb-docs-container>.row>.col-lg-3.sidebar+.col-lg-9{flex:0 0 78%;max-width:78%}}.pb-docs-container+.pb-footer{margin-top:180px}.pb-content{padding:22px 30px;border:1px solid #dddfe3;background-color:#fff;font-size:19px;line-height:1.5789473684}.pb-content>.pb-content{margin:0;padding:0;border:none}.pb-content h1{margin-bottom:20px;padding-bottom:14px;border-bottom:1px solid #dddfe3;font-size:46.379px}.pb-content h2{margin-top:35px;margin-bottom:16px;font-size:37.107px}.pb-content h3{margin-top:28px;font-size:29.697px}.pb-content h4{margin-top:20px;font-size:23.75px}.pb-content h5{margin-top:16px;font-size:19px;font-style:italic}.pb-content ul{padding-left:20px;list-style:none}.pb-content ul li:not(.ui-tab){position:relative}.pb-content ul li:not(.ui-tab):before{position:absolute;top:10px;left:-20px;height:7px;width:7px;border:1px solid #707070;border-radius:50%;background:#333;content:""}.pb-content table.pbTable,.pb-content table.table{font-size:16px;line-height:1.75}.pb-content table.pbTable th,.pb-content table.table th{padding-top:9px;padding-bottom:9px;font-weight:600}.pb-content table.pbTable td,.pb-content table.pbTable th,.pb-content table.table td,.pb-content table.table th{padding-right:15px;padding-left:15px}.pb-content .pb-code-hl-wrap{width:100%}.pb-content .highlight,.pb-content .pb-code-hl{margin-top:20px;margin-bottom:20px;padding:20px 22px;border:1px solid #dddfe3;background:#f8f9f9;font-size:16px}.pb-content .highlight pre,.pb-content .pb-code-hl pre{margin-top:0;margin-bottom:0;padding:0;border:0;background:none}.pb-docs-container{margin-top:20px}@media (min-width:992px){.pb-docs-container{margin-top:65px}}.pb-alert{margin-top:10px}.center-image{margin:0 auto;display:block}.social-media{display:flex;align-items:center}@media (min-width:992px){.social-media{justify-content:flex-end;margin-top:100px}}.social-media a,.social-media h5{margin-right:22px;margin-bottom:0}.social-media h5{font-size:18px}.social-media a:last-child{margin-right:0}table.pbTable,table.table{background:#fff}.pbTable thead td,.pbTable thead th,.table-bordered thead td,.table-bordered thead th{border-bottom-width:1px}.download-form{margin-bottom:20px}.download-form>.row{flex-flow:column}.download-form .adapters{display:flex;flex-flow:row wrap}.download-form__modal,.modal-backdrop.fade{opacity:0}.pb-content .autocomplete-filter{padding:10px 15px;border:1px solid #b3c1cc;background-color:rgba(236,243,245,.35)}.pb-content .autocomplete-filter:focus{outline:none}.pb-content .c-bidder-list-group h4{color:#797f90;font-size:19px;font-weight:700}.pb-content .c-bidder-list{padding-left:0;-moz-columns:2;column-count:2}.pb-content .c-bidder-list li{padding-bottom:5px}.pb-content .c-bidder-list li:before{content:none!important}.pb-content .c-bidder-list a{text-decoration:none}.algolia-autocomplete .algolia-docsearch-suggestion--category-header{display:none!important}@media (max-width:990px){.c-search .DocSearch-Button{margin-left:0}}.pb-homepage .h1,.pb-homepage h1{font-size:12vw;margin-bottom:.75rem}@media (min-width:768px){.pb-homepage .h1,.pb-homepage h1{font-size:40px}}.error404{width:100%;height:100%;text-align:center}.error404 h1{color:red;font-size:60px;font-weight:700} \ No newline at end of file From 1e80c607f3eea21944ce2d1f869d51a359ffae97 Mon Sep 17 00:00:00 2001 From: Olivier Date: Sat, 25 Feb 2023 18:57:30 +0100 Subject: [PATCH 072/762] Adagio: add user-sync config recommends (#4379) Co-authored-by: G15N --- dev-docs/bidders/adagio.md | 22 +++++++++++++++++++++- 1 file changed, 21 insertions(+), 1 deletion(-) diff --git a/dev-docs/bidders/adagio.md b/dev-docs/bidders/adagio.md index d3a19b3e..ea0ff9f9 100644 --- a/dev-docs/bidders/adagio.md +++ b/dev-docs/bidders/adagio.md @@ -21,7 +21,27 @@ sidebarType: 1 The Adagio bidder adapter requires setup and approval from the Adagio team. Please reach out to [contact@adagio.io](mailto:contact@adagio.io) for more information. -### Bidder Settings +### Configuration + +#### User Sync + +Adagio strongly recommends enabling user syncing through iFrames. This functionality improves DSP user match rates and increases the bid rate and bid price. Make sure to call `pbjs.setConfig()` only once. This configuration is optional in Prebid, but required by Adagio. + +```js +// https://docs.prebid.org/dev-docs/publisher-api-reference/setConfig.html#setConfig-Configure-User-Syncing +pbjs.setConfig({ + userSync: { + filterSettings: { + iframe: { + bidders: ['adagio'], + filter: 'include' + } + } + } +}); +``` + +#### Bidder Settings The Adagio bid adapter uses browser local storage. Since Prebid.js 7.x, the access to it must be explicitly set. From 60f38b940e8562f19a8242e3636dfc675bd0569f Mon Sep 17 00:00:00 2001 From: Ruslan S <15067216+Enigo@users.noreply.github.com> Date: Sun, 26 Feb 2023 03:39:37 +0800 Subject: [PATCH 073/762] Update smaato.md to indicate gpp support (#4371) --- dev-docs/bidders/smaato.md | 1 + 1 file changed, 1 insertion(+) diff --git a/dev-docs/bidders/smaato.md b/dev-docs/bidders/smaato.md index 5bd1e7d4..eb7a6667 100644 --- a/dev-docs/bidders/smaato.md +++ b/dev-docs/bidders/smaato.md @@ -7,6 +7,7 @@ gdpr_supported: true gvl_id: 82 usp_supported: true coppa_supported: true +gpp_supported: true media_types: banner, video, native userId: criteo, pubCommonId, unifiedId pbjs: true From 8847511d52f35469bac4c54497f7331187608234 Mon Sep 17 00:00:00 2001 From: Gammelin Guillaume Date: Sat, 25 Feb 2023 20:57:39 +0100 Subject: [PATCH 074/762] Adagio: update doc video params (#4367) --- dev-docs/bidders/adagio.md | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/dev-docs/bidders/adagio.md b/dev-docs/bidders/adagio.md index ea0ff9f9..5a56d69f 100644 --- a/dev-docs/bidders/adagio.md +++ b/dev-docs/bidders/adagio.md @@ -60,25 +60,25 @@ pbjs.bidderSettings = { {: .table .table-bordered .table-striped } -| Name | Scope | Description | Example | Type | -|--------------------|--------------------|----------------------------------------------------------------------------------------------------------------------|-----------------|-----------| -| `organizationId` | required | Id of the Organization. Handed out by Adagio. | `'1010'` | `string` | -| `site` | required | Name of the site. Handed out by Adagio.
- max length: 50 | `'mysite-com'` | `string` | -| `placement`* | required | Refers to the placement of an adunit in a page.
Must not contain any information about the type of device.
- max length: 30
- max distinctives values: 10 | `'ban_atf'` | `string` | -| `adUnitElementId` | required | Refers to the adunit html attribute id in a page. | `'gpt-ban-atf'` | `string` | -| `pagetype`* | highly recommended | Describes what kind of content will be present in the page.
- max length: 30
- max distinctives values: 50 | `'article'` | `string` | -| `category`* | recommended | Category of the content displayed in the page.
- max length: 30
- max distinctives values: 50 | `'sport'` | `string` | -| `video` | optional | OpenRTB 2.5 video options object.
All options will override ones defined in mediaTypes.video | `{skip: 1, playbackmethod: [6]}` | `object` | -| `native` | optional | Partial OpenRTB Native 1.2 request object. Supported fields are:
- context
-plcmttype | `{context: 1, plcmttype: 2}` | `object` | +| Name | Scope | Description | Example | Type | +| ----------------- | ------------------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------ | -------- | +| `organizationId` | required | Id of the Organization. Handed out by Adagio. | `'1010'` | `string` | +| `site` | required | Name of the site. Handed out by Adagio.
- max length: 50 | `'mysite-com'` | `string` | +| `placement`* | required | Refers to the placement of an adunit in a page.
Must not contain any information about the type of device.
- max length: 30
- max distinctives values: 10 | `'ban_atf'` | `string` | +| `adUnitElementId` | required | Refers to the adunit html attribute id in a page. | `'gpt-ban-atf'` | `string` | +| `pagetype`* | highly recommended | Describes what kind of content will be present in the page.
- max length: 30
- max distinctives values: 50 | `'article'` | `string` | +| `category`* | recommended | Category of the content displayed in the page.
- max length: 30
- max distinctives values: 50 | `'sport'` | `string` | +| `video` | optional | OpenRTB video options object. All options will override ones defined in mediaTypes video.
Mandatory:
- api (your video player must at least support the value 2 and/or 7)
Highly recommended:
- playbackmethod | `{api: [2, 7], playbackmethod: [6], skip: 1, startdelay: 0}` | +| `native` | optional | Partial OpenRTB Native 1.2 request object. Supported fields are:
- context
- plcmttype | `{context: 1, plcmttype: 2}` | `object` | *These parameters will have its accentuated characters converted to their non-accentuated version: `é` => `e` ### Native Custom assets -| Name | description | -|--------------|-------------------------------------| -| `adagio_bvw` | Url to handle Measure beacon | +| Name | description | +| ------------ | ---------------------------- | +| `adagio_bvw` | Url to handle Measure beacon | ### First Party Data From 6f328a9a51e6056a1c263ba6865b14e574fe2e7a Mon Sep 17 00:00:00 2001 From: admediadev <124867578+admediadev@users.noreply.github.com> Date: Sun, 26 Feb 2023 22:38:50 +0530 Subject: [PATCH 075/762] Admedia Adapter Doc (#4346) Co-authored-by: kapil_arora --- dev-docs/bidders/admedia.md | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) create mode 100644 dev-docs/bidders/admedia.md diff --git a/dev-docs/bidders/admedia.md b/dev-docs/bidders/admedia.md new file mode 100644 index 00000000..03553c40 --- /dev/null +++ b/dev-docs/bidders/admedia.md @@ -0,0 +1,19 @@ +--- +layout: bidder +title: admedia +description: Prebid admedia Bidder Adaptor +pbjs: true +biddercode: admedia +media_types: banner +sidebarType: 1 +--- + + +### Bid Params + +{: .table .table-bordered .table-striped } +| Name | Scope | Description | Example | Type | +|-----------------|----------|--------------------------|--------------|----------| +| `placementId` | required | The placement ID provided by admedia | `'1234567'` | `string` | +| `aid` | required | The aid provided by admedia | `'1234'` | `string` | +| `referrrInfo` | required | The referring page url to be sent by the publisher | `'https://test.com/abc'` | `string` | From 37f77f2e50b12928837c79bfab658ffc3aac921b Mon Sep 17 00:00:00 2001 From: Aaron Price <67345931+AaronColbyPrice@users.noreply.github.com> Date: Sun, 26 Feb 2023 11:44:12 -0800 Subject: [PATCH 076/762] ups_update_analytics_docs: adding documentation for new error logging feature and added column to document default values (#4364) --- dev-docs/analytics/epsilon.md | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/dev-docs/analytics/epsilon.md b/dev-docs/analytics/epsilon.md index 91b233ba..032ddc1b 100644 --- a/dev-docs/analytics/epsilon.md +++ b/dev-docs/analytics/epsilon.md @@ -20,10 +20,11 @@ publishersupport@epsilon.com for more information. #### Analytics Options {: .table .table-bordered .table-striped } -| Name | Scope | Description | Example | Type | -|-------------|---------|--------------------|-----------------------------------------------------------------------------------------------------------------------------|-------------------------------------------------------------------------------------|------------------| -| site_id | required | Epsilon site id for the site that will track prebid usage. | 1234 | integer | -| cnvr_sampling | optional | Sample rate for analytics data. Value should be between 0 and 1 (inclusive), 0 == never sample, 1 == always sample, 0.5 == send analytics 50% of the time. | 0.5 | float | +| Name | Scope | Description | Example | Default |Type | +| ---------- | -------- | --------------------------------------------------------------------------- | -------------- | -------- |-------- | +| site_id | required | Epsilon site id for the site that will track prebid usage. | 1234 | n/a | integer | +| cnvr_sampling | optional | Sample rate for analytics data. Value should be between 0 and 1 (inclusive), 0 == never sample, 1 == always sample, 0.5 == send analytics 50% of the time. | 0.5 | 1 | float | +| send_error_data | optional | Adds extra analytics that tracks script runtime errors, bad data and bidders | true | false | boolean | ### Example Configuration @@ -35,7 +36,8 @@ publishersupport@epsilon.com for more information. provider: 'conversant', options: { site_id: 108060, - cnvr_sampling: 0.5 + cnvr_sampling: 0.5, + send_error_data: true } } ); From cc0fdc36532f203db1c4a1172bc79c20d83dadea Mon Sep 17 00:00:00 2001 From: Andrew Date: Mon, 27 Feb 2023 17:48:18 -0800 Subject: [PATCH 077/762] Video docs updates (#4360) * Remove broken Akamai instream example. * Remove broken Ooyala instream examples. * Remove additional files from removed players. * Remove dead code. * Wrap video example in Optanon. * Finish adplayer pro optanon wrapping. * Remove broken video server examples. * Wrap Instream Brid in Optanon * Wrap Instream Brightcove in Optanon * Remove all outdated video examples. * Add onetrust promise. * Complete JW instream platform Onetrust example. * Complete JW instream hosted Onetrust example. * Complete videoJS instream Onetrust example. * Complete Outstream BasicIMA Onetrust example. * Complete Outstream Google Ad Manager Onetrust example. * Complete Outstream No Server Onetrust example. * Complete Outstream specifiy renderer Onetrust example. * Complete Lonform Freewheel Onetrust example. * Additional cleanup. * Update InsertHTML implementation * Update function calls to new OneTrust API --------- Co-authored-by: Andrew Fowler --- _data/sidebar.yml | 172 ------- _includes/head--common.html | 17 +- _includes/video/pb-is-app.html | 4 +- _includes/video/pb-is-bc.html | 2 +- _includes/video/pb-is-br.html | 6 +- _includes/video/pb-is-jw01.html | 6 +- _includes/video/pb-is-jw02.html | 112 +++-- _includes/video/pb-is-ol.html | 122 ----- _includes/video/pb-is-vjs.html | 112 ++--- _includes/video/pb-lf-fw.html | 13 +- _includes/video/pb-os-dfp.html | 13 +- _includes/video/pb-os-nas-renderer.html | 2 +- _includes/video/pb-os-nas.html | 4 +- _includes/video/pbs-oy.html | 127 ------ _layouts/video_sample.html | 39 +- dev-docs/show-video-with-a-dfp-video-tag.md | 10 - .../flowplayer/pb-cp-flowplayer.html | 276 ------------ .../crossplayer/jwplayer/pb-cp-jwplayer.html | 235 ---------- .../crossplayer/kaltura/pb-cp-kaltura.html | 281 ------------ .../crossplayer/videojs/pb-cp-videojs.html | 299 ------------- examples/video/index.md | 13 +- .../adplayerpro/pb-ve-adplayerpro.html | 157 ------- examples/video/instream/akamai/pb-ve-amp.html | 252 ----------- examples/video/instream/brid/pb-ve-brid.html | 190 -------- .../instream/brightcove/pb-ve-brightcove.html | 298 ------------- .../instream/flowplayer/pb-ve-flowplayer.html | 193 -------- .../jwplayer/pb-ve-jwplayer-hosted.html | 310 ++++++------- .../jwplayer/pb-ve-jwplayer-platform.html | 319 ++++++------- .../video/instream/kaltura/pb-ve-kaltura.html | 286 ------------ .../video/instream/ooyala/pb-ve-ooyala.html | 352 --------------- .../video/instream/radiant/pb-ve-radiant.html | 326 -------------- .../video/instream/videojs/pb-ve-videojs.html | 419 +++++++++--------- .../video/long-form/pb-ve-lf-freewheel.html | 210 ++++----- examples/video/outstream/basic-ima.html | 77 ++-- .../video/outstream/pb-ve-outstream-dfp.html | 261 +++++------ ...-outstream-no-server-specify-renderer.html | 240 +++++----- .../outstream/pb-ve-outstream-no-server.html | 163 +++---- examples/video/server/brid/pbs-ve-brid.html | 182 -------- .../jwplayer/pbs-ve-jwplayer-hosted.html | 206 --------- .../jwplayer/pbs-ve-jwplayer-platform.html | 202 --------- .../video/server/kaltura/pbs-ve-kaltura.html | 299 ------------- .../video/server/ooyala/pbs-ve-ooyala.html | 369 --------------- .../video/server/radiant/pbs-ve-radiant.html | 341 -------------- .../video/server/videojs/pbs-ve-videojs.html | 282 ------------ prebid-video/video-integrating-solo.md | 16 - 45 files changed, 1183 insertions(+), 6632 deletions(-) delete mode 100644 _includes/video/pb-is-ol.html delete mode 100644 _includes/video/pbs-oy.html delete mode 100644 examples/video/crossplayer/flowplayer/pb-cp-flowplayer.html delete mode 100644 examples/video/crossplayer/jwplayer/pb-cp-jwplayer.html delete mode 100644 examples/video/crossplayer/kaltura/pb-cp-kaltura.html delete mode 100644 examples/video/crossplayer/videojs/pb-cp-videojs.html delete mode 100644 examples/video/instream/adplayerpro/pb-ve-adplayerpro.html delete mode 100644 examples/video/instream/akamai/pb-ve-amp.html delete mode 100644 examples/video/instream/brid/pb-ve-brid.html delete mode 100644 examples/video/instream/brightcove/pb-ve-brightcove.html delete mode 100644 examples/video/instream/flowplayer/pb-ve-flowplayer.html delete mode 100644 examples/video/instream/kaltura/pb-ve-kaltura.html delete mode 100644 examples/video/instream/ooyala/pb-ve-ooyala.html delete mode 100644 examples/video/instream/radiant/pb-ve-radiant.html delete mode 100644 examples/video/server/brid/pbs-ve-brid.html delete mode 100644 examples/video/server/jwplayer/pbs-ve-jwplayer-hosted.html delete mode 100644 examples/video/server/jwplayer/pbs-ve-jwplayer-platform.html delete mode 100644 examples/video/server/kaltura/pbs-ve-kaltura.html delete mode 100644 examples/video/server/ooyala/pbs-ve-ooyala.html delete mode 100644 examples/video/server/radiant/pbs-ve-radiant.html delete mode 100644 examples/video/server/videojs/pbs-ve-videojs.html diff --git a/_data/sidebar.yml b/_data/sidebar.yml index 9b848261..36a5830d 100644 --- a/_data/sidebar.yml +++ b/_data/sidebar.yml @@ -1275,47 +1275,6 @@ sectionTitle: subgroup: 2 -- sbSecId: 4 - title: 'Akamai AMP' - link: /examples/video/instream/akamai/pb-ve-amp.html - isHeader: 0 - isSectionHeader: 0 - sectionTitle: - subgroup: 2 - -- sbSecId: 4 - title: 'AdPlayer.Pro' - link: /examples/video/instream/adplayerpro/pb-ve-adplayerpro.html - isHeader: 0 - isSectionHeader: 0 - sectionTitle: - subgroup: 2 - -- sbSecId: 4 - title: 'Brid' - link: /examples/video/instream/brid/pb-ve-brid.html - isHeader: 0 - isSectionHeader: 0 - sectionTitle: - subgroup: 2 - -- sbSecId: 4 - title: 'Brightcove' - link: /examples/video/instream/brightcove/pb-ve-brightcove.html - isHeader: 0 - isSectionHeader: 0 - sectionTitle: - subgroup: 2 - -- sbSecId: 4 - title: 'Flowplayer' - link: /examples/video/instream/flowplayer/pb-ve-flowplayer.html - Item: 1 - isHeader: 0 - isSectionHeader: 0 - sectionTitle: - subgroup: 2 - - sbSecId: 4 title: 'JW Player (Platform)' link: /examples/video/instream/jwplayer/pb-ve-jwplayer-platform.html @@ -1332,30 +1291,6 @@ sectionTitle: subgroup: 2 -- sbSecId: 4 - title: 'Kaltura' - link: /examples/video/instream/kaltura/pb-ve-kaltura.html - isHeader: 0 - isSectionHeader: 0 - sectionTitle: - subgroup: 2 - -- sbSecId: 4 - title: 'Ooyala' - link: /examples/video/instream/ooyala/pb-ve-ooyala.html - isHeader: 0 - isSectionHeader: 0 - sectionTitle: - subgroup: 2 - -- sbSecId: 4 - title: 'Radiant' - link: /examples/video/instream/radiant/pb-ve-radiant.html - isHeader: 0 - isSectionHeader: 0 - sectionTitle: - subgroup: 2 - - sbSecId: 4 title: 'VideoJS' link: /examples/video/instream/videojs/pb-ve-videojs.html @@ -1364,112 +1299,6 @@ sectionTitle: subgroup: 2 -- sbSecId: 4 - title: "Prebid Server" - link: - isHeader: 0 - isSectionHeader: 0 - isCatHeader: 1 - sectionTitle: - subgroup: 2 - -- sbSecId: 4 - title: 'Brid' - link: /examples/video/server/brid/pbs-ve-brid.html - isHeader: 0 - isSectionHeader: 0 - sectionTitle: - subgroup: 2 - -- sbSecId: 4 - title: 'JW Player (Platform)' - link: /examples/video/server/jwplayer/pbs-ve-jwplayer-platform.html - isHeader: 0 - isSectionHeader: 0 - sectionTitle: - subgroup: 2 - -- sbSecId: 4 - title: 'JW Player (Self-Hosted)' - link: /examples/video/server/jwplayer/pbs-ve-jwplayer-hosted.html - isHeader: 0 - isSectionHeader: 0 - sectionTitle: - subgroup: 2 - -- sbSecId: 4 - title: 'Kaltura' - link: /examples/video/server/kaltura/pbs-ve-kaltura.html - isHeader: 0 - isSectionHeader: 0 - sectionTitle: - subgroup: 2 - -- sbSecId: 4 - title: 'Ooyala' - link: /examples/video/server/ooyala/pbs-ve-ooyala.html - isHeader: 0 - isSectionHeader: 0 - sectionTitle: - subgroup: 2 - -- sbSecId: 4 - title: 'Radiant' - link: /examples/video/server/radiant/pbs-ve-radiant.html - isHeader: 0 - isSectionHeader: 0 - sectionTitle: - subgroup: 2 - -- sbSecId: 4 - title: 'VideoJS' - link: /examples/video/server/videojs/pbs-ve-videojs.html - isHeader: 0 - isSectionHeader: 0 - sectionTitle: - subgroup: 2 - -- sbSecId: 4 - title: "Cross Player" - link: - isHeader: 0 - isSectionHeader: 0 - isCatHeader: 1 - sectionTitle: - subgroup: 2 - -- sbSecId: 4 - title: 'Flowplayer' - link: /examples/video/crossplayer/flowplayer/pb-cp-flowplayer.html - isHeader: 0 - isSectionHeader: 0 - sectionTitle: - subgroup: 2 - -- sbSecId: 4 - title: 'JW Player' - link: /examples/video/crossplayer/jwplayer/pb-cp-jwplayer.html - isHeader: 0 - isSectionHeader: 0 - sectionTitle: - subgroup: 2 - -- sbSecId: 4 - title: 'Kaltura' - link: /examples/video/crossplayer/kaltura/pb-cp-kaltura.html - isHeader: 0 - isSectionHeader: 0 - sectionTitle: - subgroup: 2 - -- sbSecId: 4 - title: 'VideoJS' - link: /examples/video/crossplayer/videojs/pb-cp-videojs.html - isHeader: 0 - isSectionHeader: 0 - sectionTitle: - subgroup: 2 - - sbSecId: 4 title: "Outstream" link: @@ -1528,7 +1357,6 @@ sectionTitle: subgroup: 2 - #--------------Prebid Server--------------| - sbSecId: 5 diff --git a/_includes/head--common.html b/_includes/head--common.html index cb2c4178..d40cf33b 100644 --- a/_includes/head--common.html +++ b/_includes/head--common.html @@ -15,12 +15,17 @@ {% endif %} {% if jekyll.environment == "production" %} - - - - + + + + {% endif %} diff --git a/_includes/video/pb-is-app.html b/_includes/video/pb-is-app.html index 0d7c2854..f7634cd8 100644 --- a/_includes/video/pb-is-app.html +++ b/_includes/video/pb-is-app.html @@ -7,8 +7,10 @@ - + - - + - - - - - - // define invokeVideoPlayer in advance in case we get the bids back from prebid before the entire page loads - var tempTag = false; - var invokeVideoPlayer = function(url) { - tempTag = url; - } - var videoAdUnit = { - code: 'video1', - mediaTypes: { - video: { - context: 'instream', - playerSize: [640, 480], - mimes: ['video/mp4'], - protocols: [1, 2, 3, 4, 5, 6, 7, 8], - playbackmethod: [2], - skip: 1 - } - }, - bids: [{ - bidder: 'appnexus', - params: { - placementId: 13232361 // Add your own placement id here - } - }] - }; + diff --git a/_includes/video/pb-is-ol.html b/_includes/video/pb-is-ol.html deleted file mode 100644 index 4535432c..00000000 --- a/_includes/video/pb-is-ol.html +++ /dev/null @@ -1,122 +0,0 @@ - - - - -{% include head--common.html %} - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/_includes/video/pb-is-vjs.html b/_includes/video/pb-is-vjs.html index 0eefc25f..f75dff52 100644 --- a/_includes/video/pb-is-vjs.html +++ b/_includes/video/pb-is-vjs.html @@ -10,66 +10,74 @@ - - - - + - /* Prebid video ad unit */ + diff --git a/_includes/video/pb-lf-fw.html b/_includes/video/pb-lf-fw.html index 1381371a..4b27564b 100644 --- a/_includes/video/pb-lf-fw.html +++ b/_includes/video/pb-lf-fw.html @@ -8,15 +8,18 @@ - - - - + - + @@ -49,6 +58,7 @@ }); function initAdserver() { + window.gptLoaded.then(() => { if (pbjs.initAdserverSet) return; pbjs.initAdserverSet = true; googletag.cmd.push(function() { @@ -57,6 +67,7 @@ googletag.pubads().refresh(); }); }); + }); } setTimeout(function() { diff --git a/_includes/video/pb-os-nas-renderer.html b/_includes/video/pb-os-nas-renderer.html index 35a8a624..1c9137ee 100644 --- a/_includes/video/pb-os-nas-renderer.html +++ b/_includes/video/pb-os-nas-renderer.html @@ -6,7 +6,7 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/_layouts/video_sample.html b/_layouts/video_sample.html index d2cf058f..e46677cc 100644 --- a/_layouts/video_sample.html +++ b/_layouts/video_sample.html @@ -1,23 +1,7 @@ -{% if page.videoType == "pb-is-br" %} - {% include /video/pb-is-br.html %} -{% elsif page.videoType == "pb-is-amp" %} - {% include /video/pb-is-amp.html %} -{% elsif page.videoType == "pb-is-app" %} - {% include /video/pb-is-app.html %} -{% elsif page.videoType == "pb-is-bc" %} - {% include /video/pb-is-bc.html %} -{% elsif page.videoType == "pb-is-fp" %} - {% include /video/pb-is-fp.html %} -{% elsif page.videoType == "pb-is-jw01" %} +{% if page.videoType == "pb-is-jw01" %} {% include /video/pb-is-jw01.html %} {% elsif page.videoType == "pb-is-jw02" %} {% include /video/pb-is-jw02.html %} -{% elsif page.videoType == "pb-is-kl" %} - {% include /video/pb-is-kl.html %} -{% elsif page.videoType == "pb-is-ol" %} - {% include /video/pb-is-ol.html %} -{% elsif page.videoType == "pb-is-rd" %} - {% include /video/pb-is-rd.html %} {% elsif page.videoType == "pb-is-sb" %} {% include /video/pb-is-sb.html %} {% elsif page.videoType == "pb-is-vjs" %} @@ -30,8 +14,6 @@ {% include /video/pbs-jw02.html %} {% elsif page.videoType == "pbs-kl" %} {% include /video/pbs-kl.html %} -{% elsif page.videoType == "pbs-oy" %} - {% include /video/pbs-oy.html %} {% elsif page.videoType == "pbs-rd" %} {% include /video/pbs-rd.html %} {% elsif page.videoType == "pbs-vjs" %} @@ -50,14 +32,6 @@ {% include /video/pb-os-basic-ima.html %} {% elsif page.videoType == "pb-lf-fw" %} {% include /video/pb-lf-fw.html %} -{% elsif page.videoType == "pb-cp-fp" %} - {% include /video/pb-cp-fp.html %} -{% elsif page.videoType == "pb-cp-jw" %} - {% include /video/pb-cp-jw.html %} -{% elsif page.videoType == "pb-cp-kl" %} - {% include /video/pb-cp-kl.html %} -{% elsif page.videoType == "pb-cp-vjs" %} - {% include /video/pb-cp-vjs.html %} {% endif %} @@ -102,16 +76,5 @@ {% endif %} {% endif %} - - diff --git a/dev-docs/show-video-with-a-dfp-video-tag.md b/dev-docs/show-video-with-a-dfp-video-tag.md index a2a724cc..37abf718 100644 --- a/dev-docs/show-video-with-a-dfp-video-tag.md +++ b/dev-docs/show-video-with-a-dfp-video-tag.md @@ -206,16 +206,6 @@ Below, find links to end-to-end "working examples" integrating Prebid.js demand + [VideoJS]({{site.github.url}}/examples/video/instream/videojs/pb-ve-videojs.html) + [Instream and Banner Mixed](/dev-docs/examples/instream-banner-mix.html) -### Using Prebid Server Video - -+ [Brid]({{site.baseurl}}/examples/video/server/brid/pbs-ve-brid.html) -+ [JW Player - Platform]({{site.baseurl}}/examples/video/server/jwplayer/pbs-ve-jwplayer-platform.html) -+ [JW Player - Hosted]({{site.baseurl}}/examples/video/server/jwplayer/pbs-ve-jwplayer-hosted.html) -+ [Kaltura]({{site.baseurl}}/examples/video/server/kaltura/pbs-ve-kaltura.html) -+ [Ooyala]({{site.baseurl}}/examples/video/server/ooyala/pbs-ve-ooyala.html) -+ [VideoJS]({{site.baseurl}}/examples/video/server/videojs/pbs-ve-videojs.html) - - ## Related Topics + [Setting up Prebid Video in Google Ad Manager]({{site.baseurl}}/adops/setting-up-prebid-video-in-dfp.html) diff --git a/examples/video/crossplayer/flowplayer/pb-cp-flowplayer.html b/examples/video/crossplayer/flowplayer/pb-cp-flowplayer.html deleted file mode 100644 index 7b18799b..00000000 --- a/examples/video/crossplayer/flowplayer/pb-cp-flowplayer.html +++ /dev/null @@ -1,276 +0,0 @@ ---- -layout: video_sample -title: Prebid Video | Instream Example with Flowplayer -description: An example of an instream pre-roll ad using Cross-Player Prebid Communication Component and Flowplayer. -videoType: pb-cp-fp -isVideo: true -sidebarType: 4 ---- - - - -
-
-
-

{{ page.title }}

-

{{page.description }}

-
- - -
-

Important: - This example uses a test version of Prebid.js hosted on our CDN that is not recommended for production use. It includes all available adapters. Production implementations should build from source or customize the build using the Download page to make sure only the necessary bidder adapters are included.

-
- - -
- -
-
- -

The button will be enabled only during ads

-
- -
- -
- -
- - - - -
-

Warning: - Do not forget to exchange the placementId in the code examples with your own placementId!

-

- To allow the Cross-Player plugin to load your custom build of Prebid.js ensure that the option key `prebidPath` is set to the custom build's location. If `prebidPath` is not set, the plugin will point to `//cdn.jsdelivr.net/npm/prebid.js@latest/dist/not-for-prod/prebid.js`.

-
- -

Place this code in the page header.

-
-
-
-<link rel="stylesheet" href="//cdn.flowplayer.com/releases/native/stable/style/flowplayer.css">
-<script src="//cdn.flowplayer.com/releases/native/stable/flowplayer.min.js"></script>
-<script src="//cdn.flowplayer.com/releases/native/stable/plugins/ads.min.js"></script>
-<script src="//imasdk.googleapis.com/js/sdkloader/ima3.js"></script>
-
-<style>
-        #player {
-            max-width: 40em;
-            width: 100%;
-            float: left;
-        }
-
-        #controls {
-            float: left;
-            padding: 1em;
-        }
-    </style>
-
-<script type="text/javascript">
-  var options = {
-    biddersSpec: {
-      code: 'video1',
-      sizes: [640,480],
-      mediaTypes: {
-        video: {
-                context: 'instream',
-                playerSize: [640, 480],
-                mimes: ['video/mp4'],
-                protocols: [1, 2, 3, 4, 5, 6, 7, 8],
-                playbackmethod: [2],
-                skip: 1
-        }
-      },
-      bids: [
-        {
-          bidder: 'appnexus',
-          params: {
-              placementId: '13232361'  // Add your own placement id here 
- } - } - } - ] - }, - prebidConfigOptions: { - cache: { - url: 'https://prebid.adnxs.com/pbc/v1/cache' - } - }, - dfpParameters: { - params: { - iu: '/19968336/prebid_cache_video_adunit', - cust_params: { - section: "blog", - anotherKey: "anotherValue" - }, - output: "vast" - } - }, - }; - function doHeaderBidding() { - window.prebidPluginCP.doPrebid(options); - } - -</script> -<script src="//acdn.adnxs.com/video/plugins/cp/PrebidPluginCP.min.js" onload="doHeaderBidding()"></script> -
-
- -

Place this code in the page body.

-
- -
-
-<div id="player"></div>
-<!--video player div-->
-<div id="player"></div>
-<div id="controls">
-    <button id="ad-toggle" disabled>
-        Toggle ad playback
-    </button>
-    <p>The button will be enabled only during ads</p>
-</div>
-
-<script type="text/javascript">
-var messageId = 100;
-var asyncTag = function() {
-  var message = {
-    command: 'PPCP:prebidRequest',
-    messageId: ++messageId
-  };
-  return new Promise(function(resolve) {
-    var listener = function(event) {
-      if (event && event.data) {
-        var data = {};
-        try {
-            data = JSON.parse(event.data);
-        } catch (error) { }
-        if (data.command === 'PPCP:prebidResponse' && data.messageId === messageId) {
-          window.removeEventListener('message', listener);
-          if (data.url && data.url != 'failed') {
-            resolve(data.url);
-          }
-          else {
-            resolve(null);
-          }
-        }
-      }
-    };
-    window.addEventListener('message', listener);
-    top.postMessage(JSON.stringify(message), '*');
-    setTimeout(function() {
-      window.removeEventListener('message', listener);
-      resolve(null);
-    }, 2000);
-  })
-}
-
-
-var player = flowplayer('#player', {
-src: "//edge.flowplayer.org/drive.mp4",
-title: "Flowplayer demo",
-description: "Demo showing ads",
-autoplay: true,
-ima: {
-  ads: [
-    {"time":0,"adTag":asyncTag}
-  ]
-},
-token:"eyJraWQiOiJZSVI0VVJZODA2TGoiLCJ0eXAiOiJKV1QiLCJhbGciOiJFUzI1NiJ9.eyJjIjoie1wiYWNsXCI6NixcImlkXCI6XCJZSVI0VVJZODA2TGpcIn0iLCJpc3MiOiJGbG93cGxheWVyIn0.YUoY8b2vl1Z15PikwgYeWQ8Cp85C-TvtmwIJ_UFxpfAYYH8yiiUrhmd3SaY_qb3AvVDz45xVV6R9wizYl-NRGQ"
-})
-
-var btn = document.querySelector('#ad-toggle');
-
-btn.addEventListener('click', function() {
-if (player.ads.adPlaying) player.ads.pause();
-else player.ads.resume();
-})
-
-function toggleDisabled(disabled) {
-return function() { btn.disabled = disabled }
-}
-
-player.ads.on(flowplayer.AdEvents.AD_STARTED, toggleDisabled(false));
-player.ads.on(flowplayer.AdEvents.AD_COMPLETED, toggleDisabled(true));
-player.ads.on(flowplayer.AdEvents.AD_SKIPPED, toggleDisabled(true));
-
-</script>
-      
-
- -
-
- - - - - - diff --git a/examples/video/crossplayer/jwplayer/pb-cp-jwplayer.html b/examples/video/crossplayer/jwplayer/pb-cp-jwplayer.html deleted file mode 100644 index 6f741b1e..00000000 --- a/examples/video/crossplayer/jwplayer/pb-cp-jwplayer.html +++ /dev/null @@ -1,235 +0,0 @@ ---- -layout: video_sample -title: Prebid Video | Instream Example with JW Player (Platform) -description: An example of an instream pre-roll ad using Cross-Player Prebid Communication Component and JW Player (Platform). -videoType: pb-cp-jw -isVideo: true -sidebarType: 4 ---- - - - -
-
-
-

{{ page.title }}

-

{{page.description }}

-
- - -
-

Important: - This example uses a test version of Prebid.js hosted on our CDN that is not recommended for production use. It includes all available adapters. Production implementations should build from source or customize the build using the Download page to make sure only the necessary bidder adapters are included.

-
- - -
- - - - -
-

Warning: - Do not forget to exchange the placementId in the code examples with your own placementId!

-

- To allow the Cross-Player plugin to load your custom build of Prebid.js ensure that the option key `prebidPath` is set to the custom build's location. If `prebidPath` is not set, the plugin will point to `//cdn.jsdelivr.net/npm/prebid.js@latest/dist/not-for-prod/prebid.js`.

-
- -

Place this code in the page header.

-
-
-
-<script type="text/javascript">
-var options = {
-  biddersSpec: {
-    code: 'video1',
-    sizes: [640,480],
-    mediaTypes: {
-      video: {
-  context: 'instream',
-  playerSize: [640, 480],
-  mimes: ['video/mp4'],
-  protocols: [1, 2, 3, 4, 5, 6, 7, 8],
-  playbackmethod: [2],
-  skip: 1
-      }
-    },
-    bids: [
-      {
-        bidder: 'appnexus',
-        params: {
-          placementId: '13232361'  // Add your own placement id here
- } - } - ] - }, - prebidConfigOptions: { - cache: { - url: 'https://prebid.adnxs.com/pbc/v1/cache' - } - }, - dfpParameters: { - params: { - iu: '/19968336/prebid_cache_video_adunit', - cust_params: { - section: "blog", - anotherKey: "anotherValue" - }, - output: "vast" - } - }, -}; -function doHeaderBidding() { - window.prebidPluginCP.doPrebid(options); -} - -</script> -<script src="//acdn.adnxs.com/video/plugins/cp/PrebidPluginCP.min.js" onload="doHeaderBidding()"></script> -
-
- -

Place this code in the page body.

-
- -
-  
-  <div id="myElement1"></div>
-
-  <!-- This line loads a player without loading any video content -->
-  <!-- Replace this with the correct url for your player -->
-  <script src="YOUR_JW_URL"></script>
-  <script>
-      // we initialize our player instance, specifying the div to load it into
-      var playerInstance = jwplayer('myElement1');
-
-      function invokeVideoPlayer(url) {
-          // this calls setup on the player we initialized
-          // this will use the settings defined in the player we loaded above unless you override them here
-          playerInstance.setup({
-              "file": "https://vjs.zencdn.net/v/oceans.mp4",
-              // or "file" could be replaced with "playlist" and a URL
-              // from your JW Platform account in either json or rss format.
-              "width": 640,
-              "height": 480,
-              // we enable vast advertising for this player
-              "advertising": {
-                  "client": "vast",
-                  // url is the vast tag url that we passed in when we called invokeVideoPlayer in the header
-                  "tag": url
-              },
-          });
-      }
-
-      var messageId = 100;
-      var getVastUrl = function() {
-        var message = {
-          command: 'PPCP:prebidRequest',
-          messageId: ++messageId
-        };
-        return new Promise(function(resolve) {
-          var listener = function(event) {
-            if (event && event.data) {
-              var data = {};
-              try {
-                data = JSON.parse(event.data);
-              } catch (error) { }
-              if (data.command === 'PPCP:prebidResponse' && data.messageId === messageId) {
-                window.removeEventListener('message', listener);
-                if (data.url && data.url != 'failed') {
-                  resolve(data.url);
-                }
-                else {
-                  resolve(null);
-                }
-              }
-            }
-          };
-          window.addEventListener('message', listener);
-          top.postMessage(JSON.stringify(message), '*');
-          setTimeout(function() {
-            window.removeEventListener('message', listener);
-            resolve(null);
-          }, 2000);
-        })
-      };
-
-      getVastUrl().then(function(url) {
-        invokeVideoPlayer(url);
-      })
-      .catch(function() {
-        invokeVideoPlayer(null);
-      });
-  </script>
-      
-
- -
-
- - - - - - - - - diff --git a/examples/video/crossplayer/kaltura/pb-cp-kaltura.html b/examples/video/crossplayer/kaltura/pb-cp-kaltura.html deleted file mode 100644 index 6aac173d..00000000 --- a/examples/video/crossplayer/kaltura/pb-cp-kaltura.html +++ /dev/null @@ -1,281 +0,0 @@ ---- -layout: video_sample -title: Prebid Video | Instream Example with Kaltura -description: An example of an instream pre-roll ad using Cross-Player Prebid Communication Component and Kaltura. -videoType: pb-cp-kl -isVideo: true -sidebarType: 4 ---- - - - -
-
-
-

{{ page.title }}

-

{{page.description }}

-
- - -
-

Important: - This example uses a test version of Prebid.js hosted on our CDN that is not recommended for production use. It includes all available adapters. Production implementations should build from source or customize the build using the Download page to make sure only the necessary bidder adapters are included.

-
- - -
- - - - -
-

Warning: - Do not forget to exchange the placementId in the code examples with your own placementId!

-

- To allow the Cross-Player plugin to load your custom build of Prebid.js ensure that the option key `prebidPath` is set to the custom build's location. If `prebidPath` is not set, the plugin will point to `//cdn.jsdelivr.net/npm/prebid.js@latest/dist/not-for-prod/prebid.js`.

-
- -
-

Place this code in the page header.

-
-
-<script type="text/javascript">
-var options = {
-  biddersSpec: {
-    code: 'video1',
-    sizes: [640,480],
-    mediaTypes: {
-      video: {
-	context: 'instream',
-	playerSize: [640, 480],
-	mimes: ['video/mp4'],
-	protocols: [1, 2, 3, 4, 5, 6, 7, 8],
-	playbackmethod: [2],
-	skip: 1
-      }
-    },
-    bids: [
-      {
-        bidder: 'appnexus',
-        params: {
-          placementId: '13232361'  // Add your own placement id here
- } - } - ] - }, - prebidConfigOptions: { - cache: { - url: 'https://prebid.adnxs.com/pbc/v1/cache' - } - }, - dfpParameters: { - params: { - iu: '/19968336/prebid_cache_video_adunit', - cust_params: { - section: "blog", - anotherKey: "anotherValue" - }, - output: "vast" - } - }, -}; -function doHeaderBidding() { - window.prebidPluginCP.doPrebid(options); -} - -</script> -<script src="//acdn.adnxs.com/video/plugins/cp/PrebidPluginCP.min.js" onload="doHeaderBidding()"></script> -
- -
- - -
-

Place this code in the page body.

-
-
-<div id="myPlayer" style="width:640px; height:480px;"></div>
-<!-- INCLUDE KALTURA PLAYER SCRIPT
-
-Add the script for your Kaltura player. This will be part of
-the code you will copy-paste from Kaltura. -->
-
-<script src="https://cdnapi.kaltura.com/p/2222001/sp/222200100/embedIframeJs/uiconf_id/37440401/partner_id/2222001"></script>
-
-    <script type="text/javascript">
-     invokeVideoPlayer = function(url) {
-
-       /* EMBED KALTURA PLAYER
-
-         Call `kWidget.embed()` and pass in a JSON object of your
-         player settings. Most of this JSON object will be part of
-         the code you will copy paste from Kaltura.
-
-         Documentation for kWidget available here:
-         https://player.kaltura.com/docs/kwidget */
-
-         kWidget.embed({
-             "targetId": "myPlayer",
-             "wid": "_2222001",
-             "uiconf_id": 37440401,
-
-             /* ADD VAST SETTINGS TO THE PLAYER SETTINGS
-
-                 Inside `flashVars`, add another key called `"vast"` and
-                 pass in a JSON object with:
-
-                 - the position where you want your ad to play
-
-                 - the URL of the ad (which in this case will be the `url`
-                 we got back from Prebid) */
-
-             "flashvars": {
-                 "streamerType": "auto",
-                 "vast": {
-                     "plugin": true,
-                     "prerollUrl": url,
-                 }
-             },
-             "entry_id": "1_k4eka7er",
-
-             /* ADD A READY CALLBACK AND GET A REFERENCE TO THE PLAYER
-
-                 Add a ready callback to the player settings. This allows
-                 us to get a reference to the player (stored in the
-                 variable `kdp`) in order to interact with it later. */
-
-             readyCallback: function(playerId) {
-                 console.log("Kaltura player " + playerId + " is ready.");
-             }
-           });
-       }
-       var messageId = 100;
-       var getVastUrl = function() {
-         var message = {
-           command: 'PPCP:prebidRequest',
-           messageId: ++messageId
-         };
-         return new Promise(function(resolve) {
-           var listener = function(event) {
-             if (event && event.data) {
-               var data = {};
-               try {
-                   data = JSON.parse(event.data);
-               } catch (error) { }
-               if (data.command === 'PPCP:prebidResponse' && data.messageId === messageId) {
-                 window.removeEventListener('message', listener);
-                 if (data.url && data.url != 'failed') {
-                   resolve(data.url);
-                 }
-                 else {
-                   resolve(null);
-                 }
-               }
-             }
-           };
-           window.addEventListener('message', listener);
-           top.postMessage(JSON.stringify(message), '*');
-           setTimeout(function() {
-             window.removeEventListener('message', listener);
-             resolve(null);
-           }, 2000);
-         })
-       };
-
-       getVastUrl().then(function(url) {
-         invokeVideoPlayer(url);
-       })
-       .catch(function() {
-         invokeVideoPlayer(null);
-       });
-   </script>
-
-
- -
-
- - - - - - - - - diff --git a/examples/video/crossplayer/videojs/pb-cp-videojs.html b/examples/video/crossplayer/videojs/pb-cp-videojs.html deleted file mode 100644 index e180a1df..00000000 --- a/examples/video/crossplayer/videojs/pb-cp-videojs.html +++ /dev/null @@ -1,299 +0,0 @@ ---- -layout: video_sample -title: Prebid Video | Instream Example with VideoJS -description: An example of an instream pre-roll ad using Cross-Player Prebid Communication Component and VideoJS. -videoType: pb-cp-vjs -isVideo: true -sidebarType: 4 ---- - - - -
-
-
-

{{ page.title }}

-

{{page.description }}

-
- - -
-

Important: - This example uses a test version of Prebid.js hosted on our CDN that is not recommended for production use. It includes all available adapters. Production implementations should build from source or customize the build using the Download page to make sure only the necessary bidder adapters are included.

-
- - -
- - - - - -
-

Warning: - Do not forget to exchange the placementId in the code examples with your own placementId!

-

- To allow the Cross-Player plugin to load your custom build of Prebid.js ensure that the option key `prebidPath` is set to the custom build's location. If `prebidPath` is not set, the plugin will point to `//cdn.jsdelivr.net/npm/prebid.js@latest/dist/not-for-prod/prebid.js`.

-
- -

Place this code in the page header.

-
-
-
-<!-- use recent version of videojs to ensure proper functioning with the iOS devices -->
-<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/video.js/6.4.0/video-js.css">
-<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/video.js/6.4.0/video.js"></script>
-<!-- videojs-vast-vpaid -->
-<link href="https://cdnjs.cloudflare.com/ajax/libs/videojs-vast-vpaid/2.0.2/videojs.vast.vpaid.min.css" rel="stylesheet">
-<script src="https://cdnjs.cloudflare.com/ajax/libs/videojs-vast-vpaid/2.0.2/videojs_5.vast.vpaid.min.js"></script>
-
-<script type="text/javascript">
-  var options = {
-    biddersSpec: {
-      code: 'video1',
-      sizes: [640,480],
-      mediaTypes: {
-        video: {
-    context: 'instream',
-    playerSize: [640, 480],
-    mimes: ['video/mp4'],
-    protocols: [1, 2, 3, 4, 5, 6, 7, 8],
-    playbackmethod: [2],
-    skip: 1
-        }
-      },
-      bids: [
-        {
-          bidder: 'appnexus',
-          params: {
-            placementId: '13232361'  // Add your own placement id here
- } - } - ] - }, - prebidConfigOptions: { - cache: { - url: 'https://prebid.adnxs.com/pbc/v1/cache' - } - }, - dfpParameters: { - params: { - iu: '/19968336/prebid_cache_video_adunit', - cust_params: { - section: "blog", - anotherKey: "anotherValue" - }, - output: "vast" - } - }, - }; - function doHeaderBidding() { - window.prebidPluginCP.doPrebid(options); - } - -</script> -<script src="//acdn.adnxs.com/video/plugins/cp/PrebidPluginCP.min.js" onload="doHeaderBidding()"></script> - -
-
- -

Place this code in the page body.

-
- -
-
-<div class="example-video-container">
-<video id="vid1" class="video-js vjs-default-skin vjs-big-play-centered" controls data-setup='{}' width='640' height='480'>
-  <source src="https://vjs.zencdn.net/v/oceans.mp4" type='video/mp4'/>
-  <source src="https://vjs.zencdn.net/v/oceans.webm" type='video/webm'/>
-  <source src="https://vjs.zencdn.net/v/oceans.ogv" type='video/ogg'/>
-</video>
-</div>
-<script>
-var page_load_time;
-
-page_load_time = new Date().getTime() - performance.timing.navigationStart;
-console.log(page_load_time + "ms -- Player loading!");
-
-var vid1 = videojs('vid1');
-
-page_load_time = new Date().getTime() - performance.timing.navigationStart;
-console.log(page_load_time + "ms -- Player loaded!");
-
-function invokeVideoPlayer(url) {
-
-  page_load_time = new Date().getTime() - performance.timing.navigationStart;
-  console.log(page_load_time + "ms -- Prebid VAST url = " + url);
-
-  /* Access the player instance by calling `videojs()` and passing
-    in the player's ID. Add a `ready` listener to make sure the
-    player is ready before interacting with it. */
-
-  videojs("vid1").ready(function() {
-
-      page_load_time = new Date().getTime() - performance.timing.navigationStart;
-      console.log(page_load_time + "ms -- Player is ready!");
-
-      /* PASS SETTINGS TO VAST PLUGIN
-
-        Pass in a JSON object to the player's `vastClient` (defined
-        by the VAST/VPAID plugin we're using). The requires an
-        `adTagUrl`, which will be the URL returned by Prebid. You
-        can view all the options available for the `vastClient`
-        here:
-
-        https://github.com/MailOnline/videojs-vast-vpaid#options */
-
-      var player = this;
-      var vastAd = player.vastClient({
-          adTagUrl: url,
-          playAdAlways: true,
-          verbosity: 4,
-          vpaidFlashLoaderPath: "https://github.com/MailOnline/videojs-vast-vpaid/blob/RELEASE/bin/VPAIDFlash.swf?raw=true",
-          autoplay: true
-      });
-
-      page_load_time = new Date().getTime() - performance.timing.navigationStart;
-      console.log(page_load_time + "ms -- Prebid VAST tag inserted!");
-
-      player.muted(true);
-      player.play();
-
-      page_load_time = new Date().getTime() - performance.timing.navigationStart;
-      console.log(page_load_time + "ms -- invokeVideoPlayer complete!");
-
-  });
-}
-var messageId = 100;
-var getVastUrl = function() {
-var message = {
-  command: 'PPCP:prebidRequest',
-  messageId: ++messageId
-};
-return new Promise(function(resolve) {
-  var listener = function(event) {
-    if (event && event.data) {
-      var data = {};
-      try {
-          data = JSON.parse(event.data);
-      } catch (error) { }
-      if (data.command === 'PPCP:prebidResponse' && data.messageId === messageId) {
-        window.removeEventListener('message', listener);
-        if (data.url && data.url != 'failed') {
-          resolve(data.url);
-        }
-        else {
-          resolve(null);
-        }
-      }
-    }
-  };
-  window.addEventListener('message', listener);
-  top.postMessage(JSON.stringify(message), '*');
-  setTimeout(function() {
-    window.removeEventListener('message', listener);
-    resolve(null);
-  }, 2000);
-})
-};
-
-getVastUrl().then(function(url) {
-  invokeVideoPlayer(url);
-})
-.catch(function() {
-  invokeVideoPlayer(null);
-});
-
-</script>
-      
-
- -
-
- - - - -
diff --git a/examples/video/index.md b/examples/video/index.md index 434817b5..4faadf49 100644 --- a/examples/video/index.md +++ b/examples/video/index.md @@ -1,7 +1,7 @@ --- layout: page_v2 title: Prebid Video Examples -description: This section provides examples of instream, outstream, server and long-form videos with Prebid.js. +description: This section provides examples of instream, outstream and long-form videos with Prebid.js. sidebarType: 4 --- @@ -19,28 +19,17 @@ The following examples are available: ## Instream - - [Brid](/examples/video/server/brid/pbs-ve-brid.html) - [Brightcove](/examples/video/instream/brightcove/pb-ve-brightcove.html) - [Flowplayer](/examples/video/instream/flowplayer/pb-ve-flowplayer.html) - [JW Player](/examples/video/instream/jwplayer/pb-ve-jwplayer-platform.html) - [JW Player (Self-Hosted)](/examples/video/instream/jwplayer/pb-ve-jwplayer-hosted.html) - [Kaltura](/examples/video/instream/kaltura/pb-ve-kaltura.html) - - [Ooyala](/examples/video/instream/ooyala/pb-ve-ooyala.html) - [VideoJS](/examples/video/instream/videojs/pb-ve-videojs.html) ## Instream and Banner Mixed Page - [Instream/Banner Mixed](/dev-docs/examples/instream-banner-mix.html) -## Server - - - [Brid](/examples/video/server/brid/pbs-ve-brid.html) - - [JW Player](/examples/video/server/jwplayer/pbs-ve-jwplayer-platform.html) - - [JW Player (Self-Hosted)](/examples/video/server/jwplayer/pbs-ve-jwplayer-hosted.html) - - [Kaltura](/examples/video/server/kaltura/pbs-ve-kaltura.html) - - [Ooyala](/examples/video/server/ooyala/pbs-ve-ooyala.html) - - [VideoJS](/examples/video/server/videojs/pbs-ve-videojs.html) - ## Outstream - [Google Ad Manager](/examples/video/outstream/pb-ve-outstream-dfp.html) diff --git a/examples/video/instream/adplayerpro/pb-ve-adplayerpro.html b/examples/video/instream/adplayerpro/pb-ve-adplayerpro.html deleted file mode 100644 index 54aa70a9..00000000 --- a/examples/video/instream/adplayerpro/pb-ve-adplayerpro.html +++ /dev/null @@ -1,157 +0,0 @@ ---- -layout: video_sample -title: Prebid Video | Instream Example with AdPlayer.Pro Player -description: An example of an instream pre-roll ad using Prebid.js and AdPlayer.Pro player. -videoType: pb-is-app -isVideo: true -sidebarType: 4 ---- - - - -
-
-
-

{{ page.title }}

-

{{page.description }}

-
- - -
-

Important: - This example uses a test version of Prebid.js hosted on our CDN that is not recommended for production use. It includes all available adapters. Production implementations should build from source or customize the build using the Download page to make sure only the necessary bidder adapters are included.

-
- - -
- - - - -
-

Warning: - Do not forget to exchange the placementId in the code examples with your own placementId!

-
- -

Place this code in the page header.

-
-
-
-<script async src="//cdn.jsdelivr.net/npm/prebid.js@latest/dist/not-for-prod/prebid.js"></script>
-<script type="text/javascript" src="https://static.adplayer.pro/player/demo.js"></script> -<script> - var pbjs = pbjs || {}; - pbjs.que = pbjs.que || []; - - // define invokeVideoPlayer in advance in case we get the bids back from prebid before the entire page loads
- var tempTag = false; - var invokeVideoPlayer = function(url) { - tempTag = url; - } - - var videoAdUnit = { - code: 'video1', - mediaTypes: { - video: { - context: 'instream', - playerSize: [640, 480], - mimes: ['video/mp4'], - protocols: [1, 2, 3, 4, 5, 6, 7, 8], - playbackmethod: [2], - skip: 1 - } - }, - bids: [{ - bidder: 'appnexus', - params: { - placementId: 13232361 // Add your own placement id here
- } - }] - }; - - pbjs.que.push(function() { - pbjs.addAdUnits(videoAdUnit); // add your ad units to the bid request
- pbjs.setConfig({ - debug: true, - cache: { - url: 'https://prebid.adnxs.com/pbc/v1/cache' - } - }); - - pbjs.requestBids({ - bidsBackHandler: function(bids) { - var videoUrl = pbjs.adServers.dfp.buildVideoUrl({ - adUnit: videoAdUnit, - params: { - iu: '/19968336/prebid_cache_video_adunit', - cust_params: { - section: 'blog', - anotherKey: 'anotherValue' - }, - output: 'vast' - } - }); - invokeVideoPlayer(videoUrl); - } - }); - }); - -</script> -
-
- -

Place this code in the page body.

-
- -
-<!--player div-->
-<div id="playerContainerADP" style="width:640px; height:480px;"></div>
-<script type="text/javascript">
-  invokeVideoPlayer = function(url) {
-        AdPlayerPro('playerContainerADP').setup({
-          "file": "https://static.adplayer.pro/video/640.mp4",
-          "width": 640,
-          "height": 480,
-          "autoStart": true,
-          "muted": true,
-          "advertising": {
-            "tag": url
-          }
-        });
-  };
-
-  if (tempTag) {
-    invokeVideoPlayer(tempTag);
-    tempTag = false;
-  }
-  </script>
-      
-
- -
-
- - - -
- - - diff --git a/examples/video/instream/akamai/pb-ve-amp.html b/examples/video/instream/akamai/pb-ve-amp.html deleted file mode 100644 index 26444f81..00000000 --- a/examples/video/instream/akamai/pb-ve-amp.html +++ /dev/null @@ -1,252 +0,0 @@ ---- -layout: video_sample -title: Prebid Video | Instream Example with Akamai Adaptive Media Player (AMP) -description: An example of an instream pre roll ad with Akamai AMP and Prebid.js. Akamai AMP also provides a built-in prebid plugin - wich simplifies and integrates the common prebid.js bidding workflow without extra efforts. -videoType: pb-is-amp -isVideo: true -sidebarType: 4 ---- - -
-
-
-

{{ page.title }}

-

{{page.description }}

-
- - -
-

Important: - This example uses a test version of Prebid.js hosted on our CDN that is not recommended for production - use. It includes all available adapters. Production implementations should build from source or - customize the build using the Download page to make sure only the necessary bidder adapters are - included.

-
- -
-
-
- - - - -
-

Warning: - Do not forget to exchange the placementId in the code examples with your own placementId!

-
- -

Place this code in the page header.

-
-
-<script async src="//cdn.jsdelivr.net/npm/prebid.js@latest/dist/not-for-prod/prebid.js"></script>
-<script type="text/javascript" src="https://amp.akamaized.net/hosted/1.x/player?apikey=sample"></script> -<script> - var pbjs = pbjs || {}; - pbjs.que = pbjs.que || []; - var tempTag = false; - var invokeVideoPlayer = function(url) { - tempTag = url; - } - - var videoAdUnit = { - code: 'video1', - mediaTypes: { - video: { - context: 'instream', - playerSize: [640, 480], - mimes: ['video/mp4'], - protocols: [1, 2, 3, 4, 5, 6, 7, 8], - playbackmethod: [2], - skip: 1 - } - }, - bids: [{ - bidder: 'appnexus', - params: { - placementId: 13232361 /* Add own placement id */ - } - }] - }; - - pbjs.que.push(function() { - pbjs.addAdUnits(videoAdUnit); - pbjs.setConfig({ - debug: true, - cache: { - url: 'https://prebid.adnxs.com/pbc/v1/cache' - } - }); - - pbjs.requestBids({ - bidsBackHandler: function(bids) { - var videoUrl = pbjs.adServers.dfp.buildVideoUrl({ - adUnit: videoAdUnit, - params: { - iu: '/19968336/prebid_cache_video_adunit', - cust_params: { - section: 'blog', - anotherKey: 'anotherValue' - }, - output: 'vast' - } - }); - invokeVideoPlayer(videoUrl); - } - }); - }); - -</script> -
- -
- - -
-

Place this code in the page body.

-
-<!--player container-->
-<div style="width:604px; height:341px;">
-    <div id="akamai-player" </div>
-</div>
-<script type="text/javascript">
-  invokeVideoPlayer = function(url) {
-    var config = {
-        plugins: {
-            ima: {
-                resources: [
-                    { src: "//imasdk.googleapis.com/js/sdkloader/ima3.js", type: "text/javascript", async: true },
-                    { src: "${paths.plugins}ima/Ima.min.js", type: "text/javascript", async: true }
-                ],
-                adTagUrl: url
-            }
-        },
-        autoplay: 'muted',
-        media: {
-            src: "https://mdtp-a.akamaihd.net/customers/akamai/video/VfE.mp4"
-        }
-    }
-
-    akamai.amp.AMP.create('#akamai-player', config)
-  };
-
-  if (tempTag) {
-    invokeVideoPlayer(tempTag);
-    tempTag = false;
-  }
-  </script>
-            
-
-
- -

Using Prebid Plugin for AMP

-

As an alternative an adUnit can be passed within the built-int prebid plugin for AMP. The prebid bid request will be handled by prebid plugin automatically just before the ad request takes place.

-

The plugin can be implemented by providing a prebid object to the player config as follows

-
-
-    <head>
-        <script type="text/javascript" src="https://amp.akamaized.net/hosted/1.x/player?apikey=sample"></script>
-    </head>
-    <body>
-        <!--player container-->
-         <div style="width:604px; height:341px;">
-            <div id="akamai-player"/div> </div>
-        </div>
-        <script type="text/javascript">
-        var config = {
-            plugins: {
-              prebid: {
-                adServer: {
-                  name: "dfp"
-                },
-                resources: [
-                  { src: "https://cdn.jsdelivr.net/npm/prebid.js@latest/dist/not-for-prod/prebid.js", type: "text/javascript", async: true },
-                  { src: "${paths.plugins}prebid/Prebid.min.js", type: "text/javascript", async: true }
-                ],
-                adUnits: {
-                  code: "video-1",
-                  mediaTypes: {
-                    video: {
-                      playerSize: [640, 480],
-                      context: 'instream',
-                      mimes: ['video/mp4'],
-                      protocols: [1, 2, 3, 4, 5, 6, 7, 8],
-                      playbackmethod: [2]
-                    }
-                  },
-                  bids: [
-                    {
-                      bidder: "appnexus",
-                      params: {
-                        placementId: 13232361 /* Test placementId not for prod */
-                      }
-                    }
-                  ]
-                },
-                options: {
-                  cache: {
-                    url: "https://prebid.adnxs.com/pbc/v1/cache"
-                  },
-                  enableSendAllBids: true
-                }
-              },
-              ima: {
-                resources: [
-                  { src: "//imasdk.googleapis.com/js/sdkloader/ima3.js", type: "text/javascript", async: true },
-                  { src: "${paths.plugins}ima/Ima.min.js", type: "text/javascript", async: true }
-                ],
-                adTagUrl: {
-                  params: {
-                    sz: "640x480",
-                    iu: "/19968336/prebid_cache_video_adunit",
-                    output: "vast",
-                    correlator: "#{now}"
-                  }
-                }
-              }
-            },
-            autoplay: 'muted',
-            media: {
-                src: "https://mdtp-a.akamaihd.net/customers/akamai/video/VfE.mp4"
-            }
-          };
-
-        akamai.amp.AMP.create('#akamai-player', config)
-      </script>
-    </body>
-      
-
-
- - - - - diff --git a/examples/video/instream/brid/pb-ve-brid.html b/examples/video/instream/brid/pb-ve-brid.html deleted file mode 100644 index 9b719ea9..00000000 --- a/examples/video/instream/brid/pb-ve-brid.html +++ /dev/null @@ -1,190 +0,0 @@ ---- -layout: video_sample -title: Prebid Video | Instream Example with Brid Player -description: An example of an instream pre-roll ad using Prebid.js and Brid player. -videoType: pb-is-br -isVideo: true -sidebarType: 4 ---- - - -
-
-
-

{{ page.title }}

-

{{page.description }}

-
- - -
-

Important: - This example uses a test version of Prebid.js hosted on our CDN that is not recommended for production use. It includes all available adapters. Production implementations should build from source or customize the build using the Download page to make sure only the necessary bidder adapters are included.

-
- - -
- - - - -
-

Warning: - Do not forget to exchange the placementId in the code examples with your own placementId!

-
- -

Place this code in the page header.

-
-
-
-<script async src="//cdn.jsdelivr.net/npm/prebid.js@latest/dist/not-for-prod/prebid.js"></script>
-<script type="text/javascript" src="//services.brid.tv/player/build/brid.min.js"></script> -<script> - var pbjs = pbjs || {}; - pbjs.que = pbjs.que || []; - - // define invokeVideoPlayer in advance in case we get the bids back from prebid before the entire page loads
- var tempTag = false; - var invokeVideoPlayer = function(url){ - tempTag = url; - } - - /* - Prebid Video adUnit - */ - - var videoAdUnit = { - code: 'video1', - sizes: [640,480], - mediaTypes: { - video: { - context: 'instream', - playerSize: [640, 480], - mimes: ['video/mp4'], - protocols: [1, 2, 3, 4, 5, 6, 7, 8], - playbackmethod: [2], - skip: 1 - } - }, - bids: [ - { - bidder: 'appnexusAst', - params: { - placementId: '13232361' // Add your own placement id here
- } - } - ] - }; - - pbjs.que.push(function(){ - // add your ad units to the bid request
- pbjs.addAdUnits(videoAdUnit); - - pbjs.setConfig({ - usePrebidCache: true, - cache: { - url: 'https://prebid.adnxs.com/pbc/v1/cache' - } - }); - - pbjs.requestBids({ - bidsBackHandler: function(bids) { - var videoUrl = pbjs.adServers.dfp.buildVideoUrl({ - adUnit: videoAdUnit, - params: { - iu: '/19968336/prebid_cache_video_adunit', - cust_params: { - section: "blog", - anotherKey: "anotherValue" - }, - output: "vast" - } - }); - invokeVideoPlayer(videoUrl); - } - }); - }); - - pbjs.bidderSettings = - { - standard: { - adserverTargeting: [ - { - key: "hb_bidder", - val: function (bidResponse) { - return bidResponse.bidderCode; - } - }, { - key: "hb_adid", - val: function (bidResponse) { - return bidResponse.adId; - } - }, { - key: "hb_pb", - val: function (bidResponse) { - return "10.00"; - } - }, { - key: "hb_size", - val: function (bidResponse) { - return bidResponse.size; - - } - } - ] - } - }; - -</script> -
- -
- -

Place this code in the page body.

-
- -
-
-<div id="myDiv" class="brid" style="width:640px; height:360;"></div>
-
-<script type="text/javascript">
-  invokeVideoPlayer = function(url) {
-  $bp("myDiv", {"id":"17041","width":"640","height":"360","video":"400684",
-  "Ad": [
-          {
-              "mobile": url, // Array of url's will get called in succession
-              "desktop": null, // Array of url's will get called in succession
-              "adType": "0", // Type 0 for pre roll
-              "adTimeType": "s",
-              "overlayStartAt": null,
-              "overlayDuration": null,
-              "cuepoints": null
-          }
-      ]
-  });
-  }
-  </script>
-      
-
-
-
- - - - - diff --git a/examples/video/instream/brightcove/pb-ve-brightcove.html b/examples/video/instream/brightcove/pb-ve-brightcove.html deleted file mode 100644 index 202b1f90..00000000 --- a/examples/video/instream/brightcove/pb-ve-brightcove.html +++ /dev/null @@ -1,298 +0,0 @@ ---- -layout: video_sample -title: Prebid Video | Instream Example with Brightcove Player -description: An example of an instream pre-roll ad using Prebid.js and Brightcove player. -videoType: pb-is-bc -isVideo: true -sidebarType: 4 ---- - - - -
-
-
-

{{ page.title }}

-

{{page.description }}

-
- - -
-

Important: - This example uses a test version of Prebid.js hosted on our CDN that is not recommended for production use. It includes all available adapters. Production implementations should build from source or customize the build using the Download page to make sure only the necessary bidder adapters are included.

-
- - -
- -
- - - - -
-

Warning: - Do not forget to exchange the placementId in the code examples with your own placementId!

-
- -

Place this code in the page header.

-
-
-
-<script async src="//cdn.jsdelivr.net/npm/prebid.js@latest/dist/not-for-prod/prebid.js"></script>
-<!--brightcove & prebid js code--> -<script> - var pbjs = pbjs || {}; - pbjs.que = pbjs.que || []; - iosDevice = !!navigator.platform.match(/iPhone|iPod|iPad/); - - /* PRE-DEFINE `invokeVideoPlayer` - - Because we have no way of knowing when all the bids will be - returned from Prebid we can't be sure that the browser will - reach the point where `invokeVideoPlayer` is defined before - `bidsBackHandler` fires and tries to call it. - - To prevent an "`invokeVideoPlayer` not defined" error, we - pre-define it before we make the call to Prebid, and redefine - it later on with the code to create the player and play the - ad. - - In this first version, it simply stores the winning VAST to - use later. */ - - var tempTag = false; - var invokeVideoPlayer = function(url) { - tempTag = url; - } - - var videoAdUnit = { - code: 'video1', - mediaTypes: { - video: { - context: 'instream', - playerSize: [640, 480], - mimes: ['video/mp4'], - protocols: [1, 2, 3, 4, 5, 6, 7, 8], - playbackmethod: [2], - skip: 1 - } - }, - bids: [{ - bidder: 'appnexus', - params: { - placementId: iosDevice ? 13239390 : 13232361 // Add your own placement id here. - } - }] - }; - - pbjs.que.push(function() { - pbjs.addAdUnits(videoAdUnit); - pbjs.setConfig({ - debug: true, - cache: { - url: 'https://prebid.adnxs.com/pbc/v1/cache' - } - }); - pbjs.requestBids({ - bidsBackHandler: function(bids) { - var videoUrl = pbjs.adServers.dfp.buildVideoUrl({ - adUnit: videoAdUnit, - params: { - iu: '/19968336/prebid_cache_video_adunit', - cust_params: { - section: 'blog', - anotherKey: 'anotherValue' - }, - output: 'vast' - } - }); - invokeVideoPlayer(videoUrl); - } - }); - }); - -</script> -
-
- -

Place this code in the page body.

-
- -
-
-<!-- INCLUDE PLAYER AND IMA3 PLUGIN SCRIPTS
-
-First, include the player script from Brightcove. This will
-also be part of the embed code provided by Video Cloud. Then
-include the ima3 plugin script.
-
-Since we are not configuring the plugin in Video Cloud, we
-need to include this script on the page.  -->
-
-<script src="//players.brightcove.net/5530036758001/HJMTvh2YZ_default/index.min.js"></script>
-<script src="//players.brightcove.net/videojs-ima3/2/videojs.ima3.min.js"></script>
-
-<script type="text/JavaScript">
-
-    // REDEFINE `invokeVideoPlayer`
- function invokeVideoPlayer(url) { - - // USE `bc()` TO REFERENCE VIDEO PLAYER, PASS OPTIONS INTO IMA3 PLUGIN
- bc("myVideo").ima3({ - serverUrl: url, - debug: true, - timeout: 5000, - ima3SdkSettings: { - "disableCustomPlaybackForIOS10Plus": true - }, - adTechOrder: [ - "html5", - "flash" - ], - }); - - // ADD A `ready` LISTENER AND INTERACT WITH THE PLAYER   - - // Call `videojs()` and pass in the ID of the video element to   - // get a reference to the player. Call `.ready` on the player   - // to set up the event listener, and place any code that will   - // interact with the player inside the callback (such as   - // loading media files, logging events for the player or ads).
- - videojs("myVideo").ready(function() { - var myPlayer = this; - - // LOAD THE MEDIA FILE   - - // Once we know the player is ready and we have our prebid ad   - // ready, load the content video from Brightcove Studio.   - - // Replace this ID with the ID with one of your own media file IDs   - // which can be found in your Brightcove Studio account.
- - myPlayer.catalog.getVideo("5530880848001", function(error, video){ - myPlayer.catalog.load(video); - if(error) { - console.log("There was an error retrieving the media file: " + error); - } - }); - - myPlayer.on("ima3error", function() { - console.log("There was an ima3 error."); - }); - }); - }; - - // ACCOUNT FOR PAGE SPEED   - - // If prebid returned bids before the browser reached the end of   - // the page, the first version of `invokeVideoPlayer` will have   - // been called from `bidsBackHandler` so the winning vast tag   - // will be stored in `tempTag`.   - - // If that's the case, we want to call the 'real' version of   - // `invokeVideoPlayer` with the stored url to create the player   - // and play the ad.   - - // If `tempTag` is not defined, that means the browser reached   - // the end of the page before the bids came back from prebid,   - // meaning the 'real' version of `invokeVideoPlayer` was already   - // called.
- - if (tempTag) { - invokeVideoPlayer(tempTag); - tempTag = false; - } - </script> -
-
-
-
- - - - - - - - - diff --git a/examples/video/instream/flowplayer/pb-ve-flowplayer.html b/examples/video/instream/flowplayer/pb-ve-flowplayer.html deleted file mode 100644 index a7d4dd17..00000000 --- a/examples/video/instream/flowplayer/pb-ve-flowplayer.html +++ /dev/null @@ -1,193 +0,0 @@ ---- -layout: video_sample -title: Prebid Video | Instream Example with Flowplayer -description: An example of an instream pre-roll ad using Prebid.js and Flowplayer. -videoType: pb-is-fp -isVideo: true -sidebarType: 4 ---- - - - -
-
-
-

{{ page.title }}

-

{{page.description }}

-
- - -
-

Important: - This example uses a test version of Prebid.js hosted on our CDN that is not recommended for production use. It includes all available adapters. Production implementations should build from source or customize the build using the Download page to make sure only the necessary bidder adapters are included.

-
- - - -
- -
- -
- - - - -
-

Warning: - Do not forget to exchange the placementId in the code examples with your own placementId!

-
- -

Place this code in the page header.

-
-
-
-<script async src="//cdn.jsdelivr.net/npm/prebid.js@latest/dist/not-for-prod/prebid.js"></script>
-<link rel="stylesheet" href="//cdn.flowplayer.com/releases/native/3/stable/style/flowplayer.css">
-<script src="//cdn.flowplayer.com/releases/native/3/stable/flowplayer.min.js"></script>
-<script src="//cdn.flowplayer.com/releases/native/3/stable/plugins/ads.min.js"></script>
-<script src="//imasdk.googleapis.com/js/sdkloader/ima3.js"></script>
-<style>
-    #player {
-        max-width: 40em;
-        width: 100%;
-        float: left;
-    }
-
-</style>
-<script>
-  var pbjs = pbjs || {};
-  pbjs.que = pbjs.que || [];
-
-  const BIDDER1_PROVIDER = 'appnexus';
-  const BIDDER1_PLACEMENT_ID = '13232361';
-
-  // The ad tag in Flowplayer can be actual ad tag or promise to an ad tag.  
-  // We return the ad tag if it is available before the player is ready to play  
-  // Otherwise the player waits for 2 secs for tag to be available.
- var adtag = null - var timeout = 2000 - window.prebid_fetcher = function() { - if (adtag) return Promise.resolve(adtag) - - return new Promise(function (resolve) { - setTimeout(function() { - resolve(adtag) - }, timeout) - }) - } - - /* - Prebid Video adUnit - */ - - var videoAdUnit = { - code: 'video1', - sizes: [640,480], - mediaTypes: { - video: { - context: 'instream', - playerSize: [640, 480], - mimes: ['video/mp4'], - protocols: [1, 2, 3, 4, 5, 6, 7, 8], - playbackmethod: [2], - skip: 1 - } - }, - bids: [ - { - bidder: BIDDER1_PROVIDER, - params: { - placementId: BIDDER1_PLACEMENT_ID - } - } - ] - }; - - pbjs.que.push(function(){ - pbjs.addAdUnits(videoAdUnit); // add your ad units to the bid request
- - pbjs.setConfig({ - debug: true, - cache: { - url: 'https://prebid.adnxs.com/pbc/v1/cache' - } - }); - - pbjs.requestBids({ - bidsBackHandler: function(bids) { - var videoUrl = pbjs.adServers.dfp.buildVideoUrl({ - adUnit: videoAdUnit, - params: { - iu: '/19968336/prebid_cache_video_adunit', - cust_params: { - section: "blog", - anotherKey: "anotherValue" - }, - output: "vast" - } - }); - adtag = videoUrl; - } - }); - }); - -</script> -
-
- -

Place this code in the page body.

-
- -
-
-<div id="player"></div>
-<!--video player div-->
-<div id="player"></div>
-<div id="controls">
-    <button id="ad-toggle" disabled>
-        Toggle ad playback
-    </button>
-    <p>The button will be enabled only during ads</p>
-</div>
-
-<script type="text/javascript">
-  var player = flowplayer('#player', {
-    src: "//edge.flowplayer.org/drive.mp4",
-    title: "Flowplayer demo",
-    description: "Demo showing ads",
-    ima: {
-      ads: [{
-        time: 0, // preroll
-        adTag: 'flowplayer://prebid_fetcher' // this will try to call window.prebid_fetcher
-      ]
-    },
-    token:"eyJraWQiOiJZSVI0VVJZODA2TGoiLCJ0eXAiOiJKV1QiLCJhbGciOiJFUzI1NiJ9.eyJjIjoie1wiYWNsXCI6NixcImlkXCI6XCJZSVI0VVJZODA2TGpcIn0iLCJpc3MiOiJGbG93cGxheWVyIn0.YUoY8b2vl1Z15PikwgYeWQ8Cp85C-TvtmwIJ_UFxpfAYYH8yiiUrhmd3SaY_qb3AvVDz45xVV6R9wizYl-NRGQ"
-  })
-
-</script>
-      
-
-
-
- - - - - - diff --git a/examples/video/instream/jwplayer/pb-ve-jwplayer-hosted.html b/examples/video/instream/jwplayer/pb-ve-jwplayer-hosted.html index b880a48e..9b5f0875 100644 --- a/examples/video/instream/jwplayer/pb-ve-jwplayer-hosted.html +++ b/examples/video/instream/jwplayer/pb-ve-jwplayer-hosted.html @@ -7,8 +7,6 @@ sidebarType: 4 --- - -
@@ -16,163 +14,173 @@

{{ page.title }}

{{page.description }}

- -
-

Important: - This example uses a test version of Prebid.js hosted on our CDN that is not recommended for production use. It includes all available adapters. Production implementations should build from source or customize the build using the Download page to make sure only the necessary bidder adapters are included.

-
- - -
- - - - -
-

Warning: - Do not forget to exchange the placementId in the code examples with your own placementId!

-
- -

Place this code in the page header.

-
-
-
-
-<script async src="//cdn.jsdelivr.net/npm/prebid.js@latest/dist/not-for-prod/prebid.js"></script>
-<script type="text/javascript" src="https://ssl.p.jwpcdn.com/player/v/7.2.4/jwplayer.js"></script>
-<script type="text/javascript">
-  jwplayer.key = "YOUR_JW_PLAYER_KEY"; //Test Key - replace this with your own valid JWPlayer license key
-</script> -<script> - var pbjs = pbjs || {}; - pbjs.que = pbjs.que || []; - - // define invokeVideoPlayer in advance in case we get the bids back from prebid before the entire page loads
- var tempTag = false; - var invokeVideoPlayer = function(url) { - tempTag = url; - } - - var videoAdUnit = { - code: 'video1', - mediaTypes: { - video: { - context: 'instream', - playerSize: [640, 480], - mimes: ['video/mp4'], - protocols: [1, 2, 3, 4, 5, 6, 7, 8], - playbackmethod: [2], - skip: 1 - } - }, - bids: [{ - bidder: 'appnexus', - params: { - placementId: 13232361 // Add your own placement id here
- } - }] - }; - - pbjs.que.push(function() { - pbjs.addAdUnits(videoAdUnit); // add your ad units to the bid request
- pbjs.setConfig({ - debug: true, - cache: { - url: 'https://prebid.adnxs.com/pbc/v1/cache' - } - }); - - pbjs.requestBids({ - bidsBackHandler: function(bids) { - var videoUrl = pbjs.adServers.dfp.buildVideoUrl({ - adUnit: videoAdUnit, - params: { - iu: '/19968336/prebid_cache_video_adunit', - cust_params: { - section: 'blog', - anotherKey: 'anotherValue' - }, - output: 'vast' - } - }); - invokeVideoPlayer(videoUrl); - } - }); - }); - -</script> -
+
+

(Sorry, video code examples aren't available with your cookie privacy settings.)

+

Cookie Settings


-

Place this code in the page body.

-
- - -
-
-
-<!--player div-->
-<div id="playerContainerJW" style='width:640px; height:480px; border:1px solid black;'></div>
-<script>
-  var jwPlayerInstance = jwplayer("playerContainerJW");
-
-  invokeVideoPlayer = function(url) {
-      jwPlayerInstance.setup({
-          "file": "https://vjs.zencdn.net/v/oceans.mp4",
-          "width": 640,
-          "height": 480,
-          "autostart": true,
-          "mute": false,
-          "advertising": {
-              client: "vast",
-          }
-      });
-
-      jwPlayerInstance.on('beforePlay', function() {
-          jwPlayerInstance.playAd(url);
+    
 	
- diff --git a/examples/video/instream/jwplayer/pb-ve-jwplayer-platform.html b/examples/video/instream/jwplayer/pb-ve-jwplayer-platform.html index e2116360..26fb0faa 100644 --- a/examples/video/instream/jwplayer/pb-ve-jwplayer-platform.html +++ b/examples/video/instream/jwplayer/pb-ve-jwplayer-platform.html @@ -16,168 +16,171 @@

{{ page.title }}

{{page.description }}

- -
-

Important: - This example uses a test version of Prebid.js hosted on our CDN that is not recommended for production use. It includes all available adapters. Production implementations should build from source or customize the build using the Download page to make sure only the necessary bidder adapters are included.

-
- - -
- - - - -
- -

Warning: - Do not forget to exchange the placementId in the code examples with your own placementId!

-
- -

Place this code in the page header.

-
-
-
-<!--Prebid.js and video player code-->
-<script async src="//cdn.jsdelivr.net/npm/prebid.js@latest/dist/not-for-prod/prebid.js"></script>
-<script>
-    var pbjs = pbjs || {};
-    pbjs.que = pbjs.que || [];
-
-    // define invokeVideoPlayer in advance in case we get the bids back from prebid before the entire page loads
- var tempTag = false; - var invokeVideoPlayer = function(url) { - tempTag = url; - } - - var videoAdUnit = { - code: 'video1', - mediaTypes: { - video: { - context: 'instream', - playerSize: [640, 480], - mimes: ['video/mp4'], - protocols: [1, 2, 3, 4, 5, 6, 7, 8], - playbackmethod: [2], - skip: 1 - } - }, - bids: [{ - bidder: 'appnexus', - params: { - placementId: 13232361 //put your placement id here
- } - }] - }; - - pbjs.que.push(function() { - //put your adunits here
- pbjs.addAdUnits(videoAdUnit); - - pbjs.setConfig({ - debug: true, - cache: { - url: 'https://prebid.adnxs.com/pbc/v1/cache' - } - }); - - pbjs.requestBids({ - bidsBackHandler: function(bids) { - var videoUrl = pbjs.adServers.dfp.buildVideoUrl({ - adUnit: videoAdUnit, - params: { - iu: '/19968336/prebid_cache_video_adunit', - cust_params: { - section: 'blog', - anotherKey: 'anotherValue' - }, - output: 'vast' - } - }); - invokeVideoPlayer(videoUrl); - } - }); - }); - -</script> -
-
- -

Place this code in the page body.

-
- -
-  
-<div id="myElement1"></div>
-
-<!-- Replace this with the correct url for your player -->
-<script src="YOUR_JW_URL"></script>
-<script>
-    // we initialize our player instance, specifying the div to load it into
- var playerInstance = jwplayer('myElement1'); - - function invokeVideoPlayer(url) { - // this calls setup on the player we initialized   - // this will use the settings defined in the player we loaded above unless you override them here
- playerInstance.setup({ - "file": "https://vjs.zencdn.net/v/oceans.mp4", - // or "file" could be replaced with "playlist" and a URL - // from your JW Platform account in either json or rss format. - "width": 640, - "height": 480, - // we enable vast advertising for this player
- "advertising": { - "client": "vast", - // url is the vast tag url that we passed in when we called invokeVideoPlayer in the header
- "tag": url - }, - }); - } - - if (tempTag) { - invokeVideoPlayer(tempTag); - tempTag = false; - } - -</script> - -
-
+
+

(Sorry, video code examples aren't available with your cookie privacy settings.)

+

Cookie Settings


+
+ +
- - - - + - - + diff --git a/examples/video/instream/kaltura/pb-ve-kaltura.html b/examples/video/instream/kaltura/pb-ve-kaltura.html deleted file mode 100644 index a5ce5347..00000000 --- a/examples/video/instream/kaltura/pb-ve-kaltura.html +++ /dev/null @@ -1,286 +0,0 @@ ---- -layout: video_sample -title: Prebid Video | Instream Example with Kaltura -description: An example of an instream pre-roll ad using Prebid.js and Kaltura. -videoType: pb-is-kl -isVideo: true -sidebarType: 4 ---- - - - -
-
-
-

{{ page.title }}

-

{{page.description }}

-
- - -
-

Important: - This example uses a test version of Prebid.js hosted on our CDN that is not recommended for production use. It includes all available adapters. Production implementations should build from source or customize the build using the Download page to make sure only the necessary bidder adapters are included.

-
- - -
- - - - -
-

Warning: - Do not forget to exchange the placementId in the code examples with your own placementId!

-
- -
-

Place this code in the page header.

-
-
-<script>
-    var pbjs = pbjs || {};
-    pbjs.que = pbjs.que || [];
-
-    /* PRE-DEFINE `invokeVideoPlayer`
-
-    Because we have no way of knowing when all the bids will be
-    returned from Prebid we can't be sure that the browser will
-    reach the point where `invokeVideoPlayer` is defined before
-    `bidsBackHandler` fires and tries to call it.
-
-    To prevent an "`invokeVideoPlayer` not defined" error, we
-    pre-define it before we make the call to Prebid, and redefine
-    it later on with the code to create the player and play the
-    ad.
-
-    In this first version it simply stores the winning VAST to use
-    later. */
-
-    var tempTag = false;
-    var invokeVideoPlayer = function(url) {
-        tempTag = url;
-    }
-
-    var videoAdUnit = {
-        code: 'video1',
-        mediaTypes: {
-            video: {
-                context: 'instream',
-                playerSize: [640, 480],
-                mimes: ['video/mp4'],
-                protocols: [1, 2, 3, 4, 5, 6, 7, 8],
-                playbackmethod: [2],
-                skip: 1
-            }
-        },
-        bids: [{
-            bidder: 'appnexus',
-            params: {
-                placementId: 13232361  // Add your own placement ID here
- } - }] - }; - - pbjs.que.push(function() { - pbjs.addAdUnits(videoAdUnit); // add your ad units to the bid request
- - pbjs.setConfig({ - debug: true, - cache: { - url: 'https://prebid.adnxs.com/pbc/v1/cache' - } - }); - - pbjs.requestBids({ - bidsBackHandler: function(bids) { - var videoUrl = pbjs.adServers.dfp.buildVideoUrl({ - adUnit: videoAdUnit, - params: { - iu: '/19968336/prebid_cache_video_adunit', - cust_params: { - section: 'blog', - anotherKey: 'anotherValue' - }, - output: 'vast' - } - }); - invokeVideoPlayer(videoUrl); - } - }); - }); - -</script> -
- -
- - -
-

Place this code in the page body.

-
-
-<div id="myPlayer" style="width:640px; height:480px;"></div>
-<!-- INCLUDE KALTURA PLAYER SCRIPT
-
- Add the script for your Kaltura player. This will be part of
- the code you will copy-paste from Kaltura. -->
-
-<script src="https://cdnapi.kaltura.com/p/2222001/sp/222200100/embedIframeJs/uiconf_id/37440401/partner_id/2222001"></script>
-
-<script>
-    invokeVideoPlayer = function(url) {
-
-        /* EMBED KALTURA PLAYER
-
-           Call `kWidget.embed()` and pass in a JSON object of your
-           player settings. Most of this JSON object will be part of
-           the code you will copy paste from Kaltura.
-
-           Documentation for kWidget available here:
-           https://player.kaltura.com/docs/kwidget */
-
-        kWidget.embed({
-            "targetId": "myPlayer",
-            "wid": "_2222001",
-            "uiconf_id": 37440401,
-
-            /* ADD VAST SETTINGS TO THE PLAYER SETTINGS
-
-               Inside `flashVars`, add another key called `"vast"` and
-               pass in a JSON object with:
-
-               - the position where you want your ad to play
-
-               - the URL of the ad (which in this case will be the `url`
-               we got back from Prebid) */
-
-            "flashvars": {
-                "streamerType": "auto",
-                "vast": {
-                    "plugin": true,
-                    "prerollUrl": url,
-                }
-            },
-            "entry_id": "1_k4eka7er",
-
-            /* ADD A READY CALLBACK AND GET A REFERENCE TO THE PLAYER
-
-               Add a ready callback to the player settings. This allows
-               us to get a reference to the player (stored in the
-               variable `kdp`) in order to interact with it later. */
-
-            readyCallback: function(playerId) {
-                console.log("Kaltura player " + playerId + " is ready.");
-            }
-        });
-    }
-
-    /* ACCOUNT FOR PAGE SPEED
-
-       If Prebid returned bids before the browser reached the end of
-       the page, the first version of `invokeVideoPlayer` will have
-       been called from `bidsBackHandler` so the winning VAST tag
-       will be stored in the `tempTag` variable.
-
-       If that's the case, we want to call the 'real' version of
-       `invokeVideoPlayer` with the stored URL to create the player
-       and play the ad.
-
-       If `tempTag` is not defined, that means the browser reached
-       the end of the page before the bids came back from Prebid,
-       meaning the 'real' version of `invokeVideoPlayer` was already
-       called. */
-
-    if (tempTag) {
-        invokeVideoPlayer(tempTag);
-        tempTag = false;
-    }
-
-</script>  
-
-
- -
-
- - - - - - - - - - diff --git a/examples/video/instream/ooyala/pb-ve-ooyala.html b/examples/video/instream/ooyala/pb-ve-ooyala.html deleted file mode 100644 index 605ed7fe..00000000 --- a/examples/video/instream/ooyala/pb-ve-ooyala.html +++ /dev/null @@ -1,352 +0,0 @@ ---- -layout: video_sample -title: Prebid Video | Instream Example with Ooyala player -description: An example of an instream pre-roll ad using Prebid.js and Ooyala player . -videoType: pb-is-ol -isVideo: true -sidebarType: 4 ---- - - - -
-
-
-

{{ page.title }}

-

{{page.description }}

-
- - -
-

Important: - This example uses a test version of Prebid.js hosted on our CDN that is not recommended for production use. It includes all available adapters. Production implementations should build from source or customize the build using the Download page to make sure only the necessary bidder adapters are included.

-
- - -
- - - - -
-

Warning: - Do not forget to exchange the placementId in the code examples with your own placementId!

-
- -

Place this code in the page header.

-
-
-
-<script async src="//cdn.jsdelivr.net/npm/prebid.js@latest/dist/not-for-prod/prebid.js"></script>
-<!-- LOAD OOYALA PLUGINS
-
- Load the Ooyala player scripts you plan to use.
-
- You must load the core player script, the scripts for
- whatever video formats you want to support, and the scripts
- for the ad manager you want to use.
-
- The scripts themselves and a guide for choosing which ones
- you need can be found here:
-
- https://help.ooyala.com/video-platform/documentation/concepts/pbv4_plugins.html
--->
-
-<!-- CORE PLAYER REQUIRED -->
-<script src="//player.ooyala.com/static/v4/production/latest/core.min.js"></script>
-
-<!-- VIDEO PLUGINS -->
-<script src="//player.ooyala.com/static/v4/production/latest/video-plugin/main_html5.min.js"></script>
-<script src="//player.ooyala.com/static/v4/production/latest/video-plugin/bit_wrapper.min.js"></script>
-<script src="//player.ooyala.com/static/v4/production/latest/video-plugin/osmf_flash.min.js"></script>
-
-<!-- HTML5 SKIN -->
-<script src="//player.ooyala.com/static/v4/production/latest/skin-plugin/html5-skin.min.js"></script>
-
-<!-- SKIN ASSET -->
-<link rel="stylesheet" href="//player.ooyala.com/static/v4/production/latest/skin-plugin/html5-skin.min.css" />
-
-<!-- IMA PLUGIN -->
-<script src="//player.ooyala.com/static/v4/production/latest/ad-plugin/google_ima.js"></script>
-<script>
-    var pbjs = pbjs || {};
-    pbjs.que = pbjs.que || [];
-    iosDevice = !!navigator.platform.match(/iPhone|iPod|iPad/);
-    console.log("|||| Start of prebid: " + performance.now());
-
-    /* PRE-DEFINE `invokeVideoPlayer`
-
-       Because we have no way of knowing when all the bids will be
-       returned from prebid we can't be sure that the browser will
-       reach the point where `invokeVideoPlayer` is defined before
-       bidsBackHandler fires and tries to call it.
-
-       To prevent a `invokeVideoPlayer not defined` error, we
-       pre-define it before we make the call to prebid, and redefine
-       it later on with the code to create the player and play the
-       ad. In this first version it simply stores the winning VAST to
-       use later.  */
-
-    var tempTag = false;
-    var invokeVideoPlayer = function(url) {
-        tempTag = url;
-    }
-
-    var videoAdUnit = {
-        code: 'video1',
-        mediaTypes: {
-            video: {
-    context: 'instream',
-    playerSize: [640, 480],
-    mimes: ['video/mp4'],
-    protocols: [1, 2, 3, 4, 5, 6, 7, 8],
-    playbackmethod: [2],
-    skip: 1
-            }
-        },
-        bids: [{
-            bidder: 'appnexus',
-            params: {
-                placementId: iosDevice ? 13239390 : 13232361 // Add your own placement id here.
-            }
-        }]
-    };
-
-    pbjs.que.push(function() {
-        pbjs.addAdUnits(videoAdUnit); // add your ad units to the bid request
- - /* Use the Prebid Cache - required for video ads */ - - pbjs.setConfig({ - debug: true, - cache: { - url: 'https://prebid.adnxs.com/pbc/v1/cache' - } - }); - - pbjs.requestBids({ - bidsBackHandler: function(bids) { - - /* Build the DFP video URL */ - - var videoUrl = pbjs.adServers.dfp.buildVideoUrl({ - adUnit: videoAdUnit, - params: { - iu: '/19968336/prebid_cache_video_adunit', - cust_params: { - section: 'blog', - anotherKey: 'anotherValue' - }, - output: 'vast' - } - }); - invokeVideoPlayer(videoUrl); - } - }); - }); - -</script> -
- -

Place this code in the page body.

-
- -
-
-<script>
-    var invokeVideoPlayer = function(url) {
-        console.log("invoking video player with url " + url);
-
-        /* DEFINE PLAYER SETTINGS
-
-           Define the settings you want for your player in a JSON
-           object. These lines will be part of the embed code you
-           copy-paste from Ooyala Backlot, we just need to add the ad
-           parameters.  */
-
-        var playerParam = {
-            'pcode': 'lsbWkyOjtI6LOjmlqk2o5I-TsWRA',
-            'playerBrandingId': '45b8294c6ad14265b2b47586c911cb07',
-            'debug': true,
-            'autoplay': true,
-            'initialVolume': 0.0,
-            'skin': {
-                'config': '//player.ooyala.com/static/v4/stable/4.6.9/skin-plugin/skin.json',
-                'inline': {
-                    'adScreen': {
-                        'showAdMarquee': true,
-                        'showAdCountDown': true,
-                        'showControlBar': true,
-                        'useGoogleAdUI': true
-                    }
-                }
-            },
-
-            /* ADD THE AD PARAMETERS TO THE PLAYER SETTINGS
-
-               Create a new JSON object in the player parameters. The key
-               should be the ad manager you're using (in our case we're
-               using the Google IMA ads manager, so the key is
-               `"google-ima-ads-manager"`). The IMA ads manager requires
-               an ad set (which we've named `"all_ads"`).
-
-               For more information see the Ooyala docs:
-
-               https://help.ooyala.com/video-platform/concepts/pbv4_ads_dev_google_ima.html:
-
-               Make sure the ad parameters are properly formatted JSON.
-             */
-            "google-ima-ads-manager": {
-                "all_ads": [{
-                    "position": "0",
-                    "position_type": "t",
-                    "tag_url": url
-                }],
-                'showAdControls': true
-            }
-        };
-
-        /* INITIALIZE THE PLAYER
-
-           Use the `OO.ready()` event to make sure that all the
-           necessary Ooyala plugins have loaded before attempting to
-           create the player. Once it has, call `create()` and pass
-           in:
-
-           - the div you're creating the player in
-
-           - the ID of the content video
-
-           - the player settings we created above */
-
-        OO.ready(function() {
-            console.log("OO is ready, invoking");
-            console.dir(playerParam);
-            window.pp = OO.Player.create('container', 'ltcG54NzE6Bxk08Mqs1_KMcQZDN7lH8N', playerParam);
-        });
-    }
-
-    /* ACCOUNT FOR PAGE SPEED
-
-       If Prebid returned bids before the browser reached the end of
-       the page, the first version of `invokeVideoPlayer` will have
-       been called from `bidsBackHandler`, so the winning VAST tag will
-       be stored in `tempTag`.
-
-       If that's the case, we want to call the "real" version of
-       `invokeVideoPlayer` with the stored URL to create the player and
-       play the ad.
-
-       If `tempTag` is not defined, that means the browser reached the
-       end of the page before the bids came back from Prebid, meaning
-       the "real" version of `invokeVideoPlayer` was already called.
-     */
-
-    if (tempTag) {
-        invokeVideoPlayer(tempTag);
-        tempTag = false;
-    }
-
-</script>
-      
-
-
-
- - - - diff --git a/examples/video/instream/radiant/pb-ve-radiant.html b/examples/video/instream/radiant/pb-ve-radiant.html deleted file mode 100644 index ddfa9b9d..00000000 --- a/examples/video/instream/radiant/pb-ve-radiant.html +++ /dev/null @@ -1,326 +0,0 @@ ---- -layout: video_sample -title: Prebid Video | Instream Example with Radiant Media Player -description: An example of an instream pre-roll ad using Prebid.js and Radiant Media Player . -videoType: pb-is-rd -isVideo: true -sidebarType: 4 ---- - -
-
-
-

{{ page.title }}

-

{{page.description }}

-
- - -
-

Important: - This example uses a test version of Prebid.js hosted on our CDN that is not recommended for production use. It includes all available adapters. Production implementations should build from source or customize the build using the Download page to make sure only the necessary bidder adapters are included.

-
- - -
- - - - -
-

Warning: - Do not forget to exchange the placementId in the code examples with your own placementId!

-
- -

Place this code in the page header.

-
-
-
-<!--production version of prebid.js-->
-<script async src="//cdn.jsdelivr.net/npm/prebid.js@latest/dist/not-for-prod/prebid.js"></script>
-
-<!-- Radiant Media Player core library - debug browser console mode (use rmp.min.js for production) -->
-<script src="https://cdn.radiantmediatechs.com/rmp/5.5.6/js/rmp.debug.js"></script>
-      
-
- - -

Place this code in the page body.

-
- -
-
-<script>
-  /* our app where we run player
-     our app variables */
-  var pbApp = {};
-  pbApp.playerSetup = false;
-  pbApp.prebidTempTag = false;
-  pbApp.debug = true;
-  /* in case pre-bidding takes too long or fails we provide a playerSetupTimeout and fallbackAdTagUrl
-     to insure player setup happens - this is optional */
-  pbApp.playerSetupTimeout = 5000;
-  pbApp.fallbackAdTagUrl = 'https://www.radiantmediaplayer.com/vast/tags/inline-linear-1.xml';
-  /* no console - no logs */
-  if (typeof window.console === 'undefined' || typeof window.console.log === 'undefined' || typeof window.console.dir === 'undefined') {
-    pbApp.debug = false;
-  }
-
-  /* invokeVideoPlayer may not be defined when bidsBackHandler runs
-     we pre-defined it here so as to capture the returned adTagUrl to be passed to the player */
-  pbApp.invokeVideoPlayer = function (adTagUrl) {
-    pbApp.prebidTempTag = adTagUrl;
-  };
-
-  /* prebid.js variables */
-  var pbjs;
-  pbjs = pbjs || {};
-  pbjs.que = pbjs.que || [];
-
-  /* Prebid video ad unit
-     This is a working example but you must use your own settings/bidders for production
-     More docs at https://prebid.org/prebid-video/video-overview.html */
-  var videoAdUnit = {
-    code: 'video1',
-    mediaTypes: {
-      video: {
-        context: 'instream',
-        playerSize: [640, 480],
-        mimes: ['video/mp4'],
-        protocols: [1, 2, 3, 4, 5, 6, 7, 8],
-        playbackmethod: [2],
-        skip: 1
-      }
-    },
-    bids: [{
-      bidder: 'appnexus',
-      params: {
-        placementId: 13232361
-      }
-    }]
-  };
-
-  pbjs.que.push(function () {
-    pbjs.addAdUnits(videoAdUnit);
-
-    pbjs.setConfig({
-      debug: true,
-      cache: {
-        url: 'https://prebid.adnxs.com/pbc/v1/cache'
-      }
-    });
-
-    pbjs.requestBids({
-      bidsBackHandler: function (bids) {
-        if (pbApp.debug) {
-          window.console.dir(bids);
-        }
-        var videoUrl = pbjs.adServers.dfp.buildVideoUrl({
-          adUnit: videoAdUnit,
-          params: {
-            iu: '/19968336/prebid_cache_video_adunit',
-            cust_params: {
-              section: 'blog',
-              anotherKey: 'anotherValue'
-            },
-            output: 'vast'
-          }
-        });
-        pbApp.invokeVideoPlayer(videoUrl);
-      }
-    });
-  });
-
-  /* here we re-define invokeVideoPlayer with Radiant Media Player set-up */
-  pbApp.invokeVideoPlayer = function (adTagUrl) {
-    if (pbApp.playerSetup) {
-      return;
-    }
-    pbApp.playerSetup = true;
-    if (pbApp.debug) {
-      window.console.log('invokeVideoPlayer with Prebid VAST url = ' + adTagUrl);
-    }
-    var src = {
-      mp4: [
-        'https://www.rmp-streaming.com/media/bbb-360p.mp4'
-      ]
-    };
-    var settings = {
-      licenseKey: 'Kl8lZ292K3N6MmVvZD9yb201ZGFzaXMzMGRiMEElXyo=',
-      src: src,
-      width: 640,
-      height: 360,
-      /*we enabled ads for our player
-       note that we requested a winning bid for skippable auto_play_sound_off so player starts muted autoplay*/
-      ads: true,
-      autoplay: true,
-      muted: true,
-      // we use Google IMA in this demo, but you can use rmp-vast as well depending on your requirements
- adParser: 'ima', - // since we may request a skippable ads we set adDisableCustomPlaybackForIOS10Plus: true to allow rendering of skippable ads on iOS
- adDisableCustomPlaybackForIOS10Plus: true, - // here is our winner VAST adTagUrl
- adTagUrl: adTagUrl, - poster: 'https://www.radiantmediaplayer.com/images/poster-rmp-showcase.jpg' - }; - var elementID = 'rmpPlayer'; - var rmp = new RadiantMP(elementID); - rmp.init(settings); - - }; - - /* in case we already have a winning bid let's use the returned adTagUrl to run player */ - if (pbApp.prebidTempTag) { - pbApp.invokeVideoPlayer(pbApp.prebidTempTag); - pbApp.prebidTempTag = false; - } - - /* in case something went wrong (latency, network errors, bid issues ...) and we have no winning bid we still need to run the player - this is done after pbApp.playerSetupTimeout ms and we use fallbackAdTagUrl as adTagUrl to pass to the player */ - setTimeout(function () { - if (pbApp.playerSetup) { - return; - } - pbApp.invokeVideoPlayer(pbApp.fallbackAdTagUrl); - }, pbApp.playerSetupTimeout); - </script> -
-
-
-
- - - - diff --git a/examples/video/instream/videojs/pb-ve-videojs.html b/examples/video/instream/videojs/pb-ve-videojs.html index c99dc178..c3be4fd6 100644 --- a/examples/video/instream/videojs/pb-ve-videojs.html +++ b/examples/video/instream/videojs/pb-ve-videojs.html @@ -16,231 +16,246 @@

{{ page.title }}

{{page.description }}

- -
-

Important: - This example uses a test version of Prebid.js hosted on our CDN that is not recommended for production use. It includes all available adapters. Production implementations should build from source or customize the build using the Download page to make sure only the necessary bidder adapters are included.

-
- - -
- +
+

(Sorry, video code examples aren't available with your cookie privacy settings.)

+

Cookie Settings


- - - -
-

Warning: - Do not forget to exchange the placementId in the code examples with your own placementId!

-
- -

Place this code in the page header.

-
-
-
-<script async src="//cdn.jsdelivr.net/npm/prebid.js@latest/dist/not-for-prod/prebid.js"></script>
-<!-- use recent version of videojs to ensure proper functioning with the iOS devices -->
-<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/video.js/6.4.0/video-js.css">
-<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/video.js/6.4.0/video.js"></script>
-<!-- videojs-vast-vpaid -->
-<link href="https://cdnjs.cloudflare.com/ajax/libs/videojs-vast-vpaid/2.0.2/videojs.vast.vpaid.min.css" rel="stylesheet">
-<script src="https://cdnjs.cloudflare.com/ajax/libs/videojs-vast-vpaid/2.0.2/videojs_5.vast.vpaid.min.js"></script>
-
-<script>
-    var pbjs = pbjs || {};
-    pbjs.que = pbjs.que || [];
-
-
-    /* Prebid video ad unit */
-
-    var videoAdUnit = {
-        code: 'video1',
-        mediaTypes: {
-            video: {
-                context: 'instream',
-                playerSize: [640, 480],
-                mimes: ['video/mp4'],
-                protocols: [1, 2, 3, 4, 5, 6, 7, 8],
-                playbackmethod: [2],
-                skip: 1
-            }
-        },
-        bids: [{
-            bidder: 'appnexus',
-            params: {
-                placementId: 13232361
-            }
-        }]
-    };
-
-    pbjs.que.push(function() {
-        pbjs.addAdUnits(videoAdUnit);
-
-        pbjs.setConfig({
-            debug: true,
-            cache: {
-                url: 'https://prebid.adnxs.com/pbc/v1/cache'
-            }
-        });
-
-        pbjs.requestBids({
-            bidsBackHandler: function(bids) {
-                var videoUrl = pbjs.adServers.dfp.buildVideoUrl({
-                    adUnit: videoAdUnit,
-                    params: {
-                        iu: '/19968336/prebid_cache_video_adunit',
-                        cust_params: {
-                            section: 'blog',
-                            anotherKey: 'anotherValue'
-                        },
-                        output: 'vast'
-                    }
-                });
-                invokeVideoPlayer(videoUrl);
-            }
-        });
-    });
-
-</script>
-      
-
- -

Place this code in the page body.

-
- -
-
-<div class="example-video-container">
-  <video id="vid1" class="video-js vjs-default-skin vjs-big-play-centered" controls data-setup='{}' width='640' height='480'>
-    <source src="https://vjs.zencdn.net/v/oceans.mp4" type='video/mp4'/>
-    <source src="https://vjs.zencdn.net/v/oceans.webm" type='video/webm'/>
-    <source src="https://vjs.zencdn.net/v/oceans.ogv" type='video/ogg'/>
-  </video>
-</div>
-
-
-<script>
-    var page_load_time;
-
-    page_load_time = new Date().getTime() - performance.timing.navigationStart;
-    console.log(page_load_time + "ms -- Player loading!");
-
-    var vid1 = videojs('vid1');
-
-    page_load_time = new Date().getTime() - performance.timing.navigationStart;
-    console.log(page_load_time + "ms -- Player loaded!");
-
-    function invokeVideoPlayer(url) {
-
-        page_load_time = new Date().getTime() - performance.timing.navigationStart;
-        console.log(page_load_time + "ms -- Prebid VAST url = " + url);
-
-        /* Access the player instance by calling `videojs()` and passing
-           in the player's ID. Add a `ready` listener to make sure the
-           player is ready before interacting with it. */
-
-        videojs("vid1").ready(function() {
-
-            page_load_time = new Date().getTime() - performance.timing.navigationStart;
-            console.log(page_load_time + "ms -- Player is ready!");
-
-            /* PASS SETTINGS TO VAST PLUGIN
-
-               Pass in a JSON object to the player's `vastClient` (defined
-               by the VAST/VPAID plugin we're using). The requires an
-               `adTagUrl`, which will be the URL returned by Prebid. You
-               can view all the options available for the `vastClient`
-               here:
-
-               https://github.com/MailOnline/videojs-vast-vpaid#options */
-
-            var player = this;
-            var vastAd = player.vastClient({
-                adTagUrl: url,
-                playAdAlways: true,
-                verbosity: 4,
-                vpaidFlashLoaderPath: "https://github.com/MailOnline/videojs-vast-vpaid/blob/RELEASE/bin/VPAIDFlash.swf?raw=true",
-                autoplay: true
-            });
-
-            page_load_time = new Date().getTime() - performance.timing.navigationStart;
-            console.log(page_load_time + "ms -- Prebid VAST tag inserted!");
-
-            player.muted(true);
-            player.play();
-
-            page_load_time = new Date().getTime() - performance.timing.navigationStart;
-            console.log(page_load_time + "ms -- invokeVideoPlayer complete!");
-
-        });
-    }
-
-</script>
-      
-
+
diff --git a/examples/video/long-form/pb-ve-lf-freewheel.html b/examples/video/long-form/pb-ve-lf-freewheel.html index 3b1958aa..d82bf5b3 100644 --- a/examples/video/long-form/pb-ve-lf-freewheel.html +++ b/examples/video/long-form/pb-ve-lf-freewheel.html @@ -13,127 +13,105 @@

{{ page.title }}

{{page.description }}

- - -
-

Important: - This example uses a test version of Prebid.js hosted on our CDN that is not recommended for production use. It includes all available adapters. Production implementations should build from source or customize the build using the Download page to make sure only the necessary bidder adapters are included.

-
- - - - -
-
-
- - - -
-
-
- -
-
-
-
-
Ad:
- - -
-
-
-
+ +
+

(Sorry, video code examples aren't available with your cookie privacy settings.)

+

Cookie Settings


+
+ +
- - - - - - - - + diff --git a/examples/video/outstream/basic-ima.html b/examples/video/outstream/basic-ima.html index df6b7ff9..0d012a81 100644 --- a/examples/video/outstream/basic-ima.html +++ b/examples/video/outstream/basic-ima.html @@ -36,30 +36,39 @@

{{ page.title }}

{{ page.description }}

- -
-

Important: - This example uses a test version of Prebid.js hosted on our CDN that is not recommended for production use. It includes all available adapters. Production implementations should build from source or customize the build using the Download page to make sure only the necessary bidder adapters are included.

-
- - -
-

Warning: - Do not forget to exchange the placementId in the code examples with your own placementId!

-
-
- -
-
+
+

(Sorry, video code examples aren't available with your cookie privacy settings.)

+

Cookie Settings


+
-
-
-

-           
-
+ @@ -126,18 +135,24 @@

{{ page.title }}

pbjs.que.push(() => { pbjs.addAdUnits(videoAdUnit); - pbjs.requestBids({ - bidsBackHandler: (bids) => { - const highestCpmBids = pbjs.getHighestCpmBids('adContainer'); - pbjs.renderAd(document, highestCpmBids[0].adId); - } + window.onetrustLoaded.then(() => { + pbjs.requestBids({ + bidsBackHandler: (bids) => { + const highestCpmBids = pbjs.getHighestCpmBids('adContainer'); + pbjs.renderAd(document, highestCpmBids[0].adId); + } + }); }); }); diff --git a/examples/video/outstream/pb-ve-outstream-dfp.html b/examples/video/outstream/pb-ve-outstream-dfp.html index 45a1230d..60a99d48 100644 --- a/examples/video/outstream/pb-ve-outstream-dfp.html +++ b/examples/video/outstream/pb-ve-outstream-dfp.html @@ -15,131 +15,144 @@

{{ page.title }}

{{page.description }}

- - -
-

Important: - This example uses a test version of Prebid.js hosted on our CDN that is not recommended for production use. It includes all available adapters. Production implementations should build from source or customize the build using the Download page to make sure only the necessary bidder adapters are included.

-
- -
- -
-

Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.

-
- -
-

Prebid Outstream Video Ad

- -
- -
-

Sed ut perspiciatis unde omnis iste natus error sit voluptatem accusantium doloremque laudantium, totam rem aperiam, eaque ipsa quae ab illo inventore veritatis et quasi architecto beatae vitae dicta sunt explicabo. Nemo enim ipsam voluptatem quia voluptas sit aspernatur aut odit aut fugit, sed quia consequuntur magni dolores eos qui ratione voluptatem sequi nesciunt. Neque porro quisquam est, qui dolorem ipsum quia dolor sit amet, consectetur, adipisci velit, sed quia non numquam eius modi tempora incidunt ut labore et dolore magnam aliquam quaerat voluptatem. Ut enim ad minima veniam, quis nostrum exercitationem ullam corporis suscipit laboriosam, nisi ut aliquid ex ea commodi consequatur? Quis autem vel eum iure reprehenderit qui in ea voluptate velit esse quam nihil molestiae consequatur, vel illum qui dolorem eum fugiat quo voluptas nulla pariatur?

-
-
- - - - - -
-

Warning: - Do not forget to exchange the placementId in the code examples with your own placementId!

-
- -

Place this code in the page header.

-
-
-
-<script async src="//securepubads.g.doubleclick.net/tag/js/gpt.js"></script>
-
-<script>
-
-    var pbjs = pbjs || {};
-    pbjs.que = pbjs.que || [];
-
-    var googletag = googletag || {};
-    googletag.cmd = googletag.cmd || [];
-
-    var PREBID_TIMEOUT = 1000;
-
-    var adUnits = [{
-        code: 'video1',
-        mediaTypes: {
-            video: {
-                context: 'outstream',
-                playerSize: [640, 480],
-                mimes: ['video/mp4'],
-                protocols: [1, 2, 3, 4, 5, 6, 7, 8],
-                playbackmethod: [2],
-                skip: 1
-            }
-        },
-        bids: [
-            {
-                bidder: 'appnexus',
-                params: {
-                    placementId: 13232385
-                }
-            }
-        ]
-    }];
-
-    pbjs.que.push(function() {
-        pbjs.addAdUnits(adUnits);
-        pbjs.requestBids({
-            bidsBackHandler: initAdserver
-        });
-    });
-
-    function initAdserver() {
-        if (pbjs.initAdserverSet) return;
-        pbjs.initAdserverSet = true;
-        googletag.cmd.push(function() {
-            pbjs.que.push(function() {
-                pbjs.setTargetingForGPTAsync();
-                googletag.pubads().refresh();
-            });
-        });
-    }
-
-    setTimeout(function() {
-        initAdserver();
-    }, PREBID_TIMEOUT);
-
-    googletag.cmd.push(function() {
-        var slot1 = googletag.defineSlot('/19968336/prebid_outstream_adunit_1', [[1, 1]], 'video1').addService(googletag.pubads());
-        googletag.pubads().disableInitialLoad();
-        googletag.pubads().enableSingleRequest();
-        googletag.enableServices();
-    });
-
-</script>
-      
-
- - -

Place this code in the page body.

-
-
-
-<div id='video1'>
-    <p>Prebid Outstream Video Ad</p>
-    <script type='text/javascript'>
-        googletag.cmd.push(function() {
-            googletag.display('video1');
-        });
-
-    </script>
-</div>
-
-      
+ +
+

(Sorry, video code examples aren't available with your cookie privacy settings.)

+

Cookie Settings


+ +
diff --git a/examples/video/outstream/pb-ve-outstream-no-server-specify-renderer.html b/examples/video/outstream/pb-ve-outstream-no-server-specify-renderer.html index ab09e851..ffcff336 100644 --- a/examples/video/outstream/pb-ve-outstream-no-server-specify-renderer.html +++ b/examples/video/outstream/pb-ve-outstream-no-server-specify-renderer.html @@ -7,8 +7,6 @@ sidebarType: 4 --- - -
@@ -16,129 +14,141 @@

{{ page.title }}

{{page.description }}

- -
-

Important: - This example uses a test version of Prebid.js hosted on our CDN that is not recommended for production use. It includes all available adapters. Production implementations should build from source or customize the build using the Download page to make sure only the necessary bidder adapters are included.

+
+

(Sorry, video code examples aren't available with your cookie privacy settings.)

+

Cookie Settings


-
-
-

Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.

-
- -
-

Prebid Outstream Video Ad

-
- -
-

Sed ut perspiciatis unde omnis iste natus error sit voluptatem accusantium doloremque laudantium, totam rem aperiam, eaque ipsa quae ab illo inventore veritatis et quasi architecto beatae vitae dicta sunt explicabo. Nemo enim ipsam voluptatem quia voluptas sit aspernatur aut odit aut fugit, sed quia consequuntur magni dolores eos qui ratione voluptatem sequi nesciunt. Neque porro quisquam est, qui dolorem ipsum quia dolor sit amet, consectetur, adipisci velit, sed quia non numquam eius modi tempora incidunt ut labore et dolore magnam aliquam quaerat voluptatem. Ut enim ad minima veniam, quis nostrum exercitationem ullam corporis suscipit laboriosam, nisi ut aliquid ex ea commodi consequatur? Quis autem vel eum iure reprehenderit qui in ea voluptate velit esse quam nihil molestiae consequatur, vel illum qui dolorem eum fugiat quo voluptas nulla pariatur?

-
-
+
diff --git a/examples/video/outstream/pb-ve-outstream-no-server.html b/examples/video/outstream/pb-ve-outstream-no-server.html index 4b96f20e..eb5c183d 100644 --- a/examples/video/outstream/pb-ve-outstream-no-server.html +++ b/examples/video/outstream/pb-ve-outstream-no-server.html @@ -7,8 +7,6 @@ sidebarType: 4 --- - -
@@ -16,99 +14,106 @@

{{ page.title }}

{{page.description }}

- -
-

Important: - This example uses a test version of Prebid.js hosted on our CDN that is not recommended for production use. It includes all available adapters. Production implementations should build from source or customize the build using the Download page to make sure only the necessary bidder adapters are included.

-
+
+

(Sorry, video code examples aren't available with your cookie privacy settings.)

+

Cookie Settings


+
-
+
- -
-

Prebid Outstream Video Ad

-

- diff --git a/examples/video/server/brid/pbs-ve-brid.html b/examples/video/server/brid/pbs-ve-brid.html deleted file mode 100644 index 0590ef79..00000000 --- a/examples/video/server/brid/pbs-ve-brid.html +++ /dev/null @@ -1,182 +0,0 @@ ---- -layout: video_sample -title: Prebid Video | Prebid Server Example with Brid player -description: An example of a pre-roll ad using Prebid Server and Brid player. -videoType: pbs-br -isVideo: true -sidebarType: 4 ---- - - - -
-
-
-

{{ page.title }}

-

{{page.description }}

-
- - -
-

Important: - This example uses a test version of Prebid.js hosted on our CDN that is not recommended for production use. It includes all available adapters. Production implementations should build from source or customize the build using the Download page to make sure only the necessary bidder adapters are included.

-
- - -
- - - - -
-

Warning: - Do not forget to exchange the placementId in the code examples with your own placementId!

-
- -

Place this code in the page header.

-
-
-
-<script async src="//cdn.jsdelivr.net/npm/prebid.js@latest/dist/not-for-prod/prebid.js"></script>
-
-<script type="text/javascript" src="//services.brid.tv/player/build/brid.min.js"></script>
-<script>
-    var pbjs = pbjs || {};
-    pbjs.que = pbjs.que || [];
-
-    /* PRE-DEFINE `invokeVideoPlayer`
-
-    Because we have no way of knowing when all the bids will be
-    returned from Prebid we can't be sure that the browser will
-    reach the point where `invokeVideoPlayer` is defined before
-    `bidsBackHandler` fires and tries to call it.
-
-    To prevent an "`invokeVideoPlayer` not defined" error, we
-    pre-define it before we make the call to Prebid, and redefine
-    it later on with the code to create the player and play the
-    ad.
-
-    In this first version, it simply stores the winning VAST to
-    use later. */
-
-    var tempTag = false;
-    var invokeVideoPlayer = function(url) {
-        tempTag = url;
-    };
-
-    /* Prebid video ad unit */
-
-    var videoAdUnit = {
-        code: 'video1',
-        mediaTypes: {
-            video: {
-                context: 'instream',
-                playerSize: [640, 480],
-                mimes: ['video/mp4'],
-                protocols: [1, 2, 3, 4, 5, 6, 7, 8],
-                playbackmethod: [2],
-                skip: 1
-            }
-        },
-        bids: [{
-            bidder: 'appnexus',
-            params: {
-                placementId: 13232361 // Add your own placement id here
- } - }] - }; - - pbjs.que.push(function() { - - // configure prebid to use prebid cache and prebid server   - // make sure to add your own accountId to your s2sConfig object
- pbjs.setConfig({ - cache: { - url: 'https://prebid.adnxs.com/pbc/v1/cache' - }, - debug: true, - enableSendAllBids: true, - s2sConfig: { - endpoint: 'https://prebid.adnxs.com/pbs/v1/openrtb2/auction', - enabled: true, - accountId: 'c9d412ee-3cc6-4b66-9326-9f49d528f13e', - bidders: ['appnexus'] - } - }); - - pbjs.addAdUnits(videoAdUnit); // add your ad units to the bid request
- - pbjs.requestBids({ - bidsBackHandler: function(bids) { - console.log("got some bids"); - console.log(bids); - var videoUrl = pbjs.adServers.dfp.buildVideoUrl({ - adUnit: videoAdUnit, - params: { - iu: '/19968336/prebid_cache_video_adunit', - cust_params: { - section: 'blog', - anotherKey: 'anotherValue' - }, - output: 'vast' - } - }); - invokeVideoPlayer(videoUrl); - } - }); - }); - -</script> - -
-
- - -

Place this code in the page body.

-
-
-
-<div id="myDiv" class="brid" style="width:640px; height:360;"></div>
-
-<script type="text/javascript">
-  invokeVideoPlayer = function(url) {
-    $bp("myDiv", {"id":"17041","width":"640","height":"360","video":"400684",
-    "Ad": [
-            {
-                "mobile": url, // Array of url's will get called in succession
- "desktop": null, // Array of url's will get called in succession
- "adType": "0", // Type 0 for pre roll
- "adTimeType": "s", - "overlayStartAt": null, - "overlayDuration": null, - "cuepoints": null - } - ] - }); - } -</script> -
-
-
-
- - - - - diff --git a/examples/video/server/jwplayer/pbs-ve-jwplayer-hosted.html b/examples/video/server/jwplayer/pbs-ve-jwplayer-hosted.html deleted file mode 100644 index 37297406..00000000 --- a/examples/video/server/jwplayer/pbs-ve-jwplayer-hosted.html +++ /dev/null @@ -1,206 +0,0 @@ ---- -layout: video_sample -title: Prebid Video | Prebid Server Example with JW Player (Self-Hosted) -description: An example of a pre-roll ad using Prebid Server and JW Player (Hosted). -videoType: pbs-jw02 -isVideo: true -sidebarType: 4 ---- - - -
-
-
-

{{ page.title }}

-

{{page.description }}

-
- - -
-

Important: - This example uses a test version of Prebid.js hosted on our CDN that is not recommended for production use. It includes all available adapters. Production implementations should build from source or customize the build using the Download page to make sure only the necessary bidder adapters are included.

-
- - -
- - - - -
-

Warning: - Do not forget to exchange the placementId in the code examples with your own placementId!

-
- -

Place this code in the page header.

-
-
-  
-<script async src="//cdn.jsdelivr.net/npm/prebid.js@latest/dist/not-for-prod/prebid.js"></script>
-<script type="text/javascript" src="https://ssl.p.jwpcdn.com/player/v/8.0.5/jwplayer.js"></script>
-<script type="text/javascript">
-    jwplayer.key = "YOUR_JW_PLAYER_KEY"; //Test Key - replace this with your own valid JWPlayer license key
-</script> - -<script> - var pbjs = pbjs || {}; - pbjs.que = pbjs.que || []; - - /* PRE-DEFINE `invokeVideoPlayer` - - Because we have no way of knowing when all the bids will be - returned from Prebid we can't be sure that the browser will - reach the point where `invokeVideoPlayer` is defined before - `bidsBackHandler` fires and tries to call it. - - To prevent an "`invokeVideoPlayer` not defined" error, we - pre-define it before we make the call to Prebid, and redefine - it later on with the code to create the player and play the - ad. - - In this first version, it simply stores the winning VAST to - use later. */ - - var tempTag = false; - var invokeVideoPlayer = function(url) { - tempTag = url; - }; - - /* Prebid video ad unit */ - - var videoAdUnit = { - code: 'video1', - mediaTypes: { - video: { - context: 'instream', - playerSize: [640, 480], - mimes: ['video/mp4'], - protocols: [1, 2, 3, 4, 5, 6, 7, 8], - playbackmethod: [2], - skip: 1 - } - }, - bids: [{ - bidder: 'appnexus', - params: { - placementId: 13232361 // Add your own placement id here
- } - }] - }; - - pbjs.que.push(function() { - - // configure prebid to use prebid cache and prebid server
- // make sure to add your own accountId to your s2sConfig object
- pbjs.setConfig({ - cache: { - url: 'https://prebid.adnxs.com/pbc/v1/cache' - }, - debug: true, - enableSendAllBids: true, - s2sConfig: { - endpoint: 'https://prebid.adnxs.com/pbs/v1/openrtb2/auction', - enabled: true, - accountId: 'c9d412ee-3cc6-4b66-9326-9f49d528f13e', - bidders: ['appnexus'] - } - }); - - - pbjs.addAdUnits(videoAdUnit); // add your ad units to the bid request
- - pbjs.requestBids({ - bidsBackHandler: function(bids) { - console.log("got some bids"); - console.log(bids); - var videoUrl = pbjs.adServers.dfp.buildVideoUrl({ - adUnit: videoAdUnit, - params: { - iu: '/19968336/prebid_cache_video_adunit', - cust_params: { - section: 'blog', - anotherKey: 'anotherValue' - }, - output: 'vast' - } - }); - invokeVideoPlayer(videoUrl); - } - }); - }); - -</script> - -
- -
- -

Place this code in the page body.

-
- -
-
-<div id="playerContainerJW" style='width:640px; height:480px; border:1px solid black;'></div>
-
-<script>
-    var jwPlayerInstance = jwplayer("playerContainerJW");
-
-    invokeVideoPlayer = function(url) {
-        console.log("starting player with url " + url);
-        jwPlayerInstance.setup({
-
-           "file": "https://vjs.zencdn.net/v/oceans.mp4",
-            "width": 640,
-            "height": 480,
-            "autostart": true,
-            "mute": true,
-            "advertising": {
-                client: "vast",
-            }
-        });
-
-        jwPlayerInstance.on('beforePlay', function() {
-            jwPlayerInstance.playAd(url);
-        })
-    }
-
-    if (tempTag) {
-        invokeVideoPlayer(tempTag);
-        tempTag = false;
-    }
-
-</script>
-
-      
-
-
-
- - - - diff --git a/examples/video/server/jwplayer/pbs-ve-jwplayer-platform.html b/examples/video/server/jwplayer/pbs-ve-jwplayer-platform.html deleted file mode 100644 index 64567302..00000000 --- a/examples/video/server/jwplayer/pbs-ve-jwplayer-platform.html +++ /dev/null @@ -1,202 +0,0 @@ ---- -layout: video_sample -title: Prebid Video | Prebid Server Example with JW Player (Platform) -description: An example of a pre-roll ad using Prebid Server and JW Player (Platform). -videoType: pbs-jw01 -isVideo: true -sidebarType: 4 ---- - -
-
-
-

{{ page.title }}

-

{{page.description }}

-
- - -
-

Important: - This example uses a test version of Prebid.js hosted on our CDN that is not recommended for production use. It includes all available adapters. Production implementations should build from source or customize the build using the Download page to make sure only the necessary bidder adapters are included.

-
- - -
- - - - -
-

Warning: - Do not forget to exchange the placementId in the code examples with your own placementId!

-
- -

Place this code in the page header.

-
-
-
-      <script>
-      var pbjs = pbjs || {};
-      pbjs.que = pbjs.que || [];
-
-      /* PRE-DEFINE `invokeVideoPlayer`
-
-      Because we have no way of knowing when all the bids will be
-      returned from Prebid we can't be sure that the browser will
-      reach the point where `invokeVideoPlayer` is defined before
-      `bidsBackHandler` fires and tries to call it.
-
-      To prevent an "`invokeVideoPlayer` not defined" error, we
-      pre-define it before we make the call to Prebid, and redefine
-      it later on with the code to create the player and play the
-      ad.
-
-      In this first version, it simply stores the winning VAST to
-      use later. */
-
-      var tempTag = false;
-      var invokeVideoPlayer = function(url) {
-          tempTag = url;
-      };
-
-      var videoAdUnit = {
-          code: 'video1',
-          mediaTypes: {
-              video: {
-      context: 'instream',
-      playerSize: [640, 480],
-      mimes: ['video/mp4'],
-      protocols: [1, 2, 3, 4, 5, 6, 7, 8],
-      playbackmethod: [2],
-      skip: 1
-              }
-          },
-          bids: [{
-              bidder: 'appnexus',
-              params: {
-                  placementId: 13232361  // Add your own placement id here.
- } - }] - }; - - pbjs.que.push(function() { - - // configure prebid to use prebid cache and prebid server  - // make sure to add your own accountId to your s2sConfig object
- pbjs.setConfig({ - cache: { - url: 'https://prebid.adnxs.com/pbc/v1/cache' - }, - debug: true, - s2sConfig: { - endpoint: 'https://prebid.adnxs.com/pbs/v1/openrtb2/auction', - enabled: true, - accountId: 'c9d412ee-3cc6-4b66-9326-9f49d528f13e', - bidders: ['appnexus'] - } - }); - - pbjs.addAdUnits(videoAdUnit); // add your ad units to the bid request
- - pbjs.requestBids({ - bidsBackHandler: function(bids) { - - var videoUrl = pbjs.adServers.dfp.buildVideoUrl({ - adUnit: videoAdUnit, - params: { - iu: '/19968336/prebid_cache_video_adunit', - cust_params: { - section: 'blog', - anotherKey: 'anotherValue' - }, - output: 'vast' - } - }); - invokeVideoPlayer(videoUrl); - } - }); - }); - - </script> -
-
- -

Place this code in the page body.

-
- -
-
-<!-- This line loads a player without loading any video content -->
-<!-- Replace this with the correct url for your player -->
-<script src="YOUR_JW_URL"></script>
-<script>
-    // we initialize our player instance, specifying the div to load it into
- var playerInstance = jwplayer('myElement1'); - - function invokeVideoPlayer(url) { - // this calls setup on the player we initialized  - // this will use the settings defined in the player we loaded above unless you override them here
- playerInstance.setup({ - "file": "https://vjs.zencdn.net/v/oceans.mp4", - // or "file" could be replaced with "playlist" and a URL - // from your JW Platform account in either json or rss format. - "width": 640, - "height": 480, - "autostart": true, - "mute": true, - // we enable vast advertising for this player
- "advertising": { - "client": "vast", - // url is the vast tag url that we passed in when we called invokeVideoPlayer in the header
- "tag": url - } - }); - } - - if (tempTag) { - invokeVideoPlayer(tempTag); - tempTag = false; - } - -</script> -
-
-
-
- - - - - - - - diff --git a/examples/video/server/kaltura/pbs-ve-kaltura.html b/examples/video/server/kaltura/pbs-ve-kaltura.html deleted file mode 100644 index a6eecad0..00000000 --- a/examples/video/server/kaltura/pbs-ve-kaltura.html +++ /dev/null @@ -1,299 +0,0 @@ ---- -layout: video_sample -title: Prebid Video | Prebid Server Example with Kaltura -description: An example of a pre-roll ad using Prebid Server and Kaltura. -videoType: pbs-kl -isVideo: true -sidebarType: 4 ---- - - - -
-
-
-

{{ page.title }}

-

{{page.description }}

-
- - -
-

Important: - This example uses a test version of Prebid.js hosted on our CDN that is not recommended for production use. It includes all available adapters. Production implementations should build from source or customize the build using the Download page to make sure only the necessary bidder adapters are included.

-
- - -
- - - - -
-

Warning: - Do not forget to exchange the placementId in the code examples with your own placementId!

-
- -

Place this code in the page header.

-
-
-
-
-<script>
-    var pbjs = pbjs || {};
-    pbjs.que = pbjs.que || [];
-
-    /* PRE-DEFINE `invokeVideoPlayer`
-
-    Because we have no way of knowing when all the bids will be
-    returned from Prebid we can't be sure that the browser will
-    reach the point where `invokeVideoPlayer` is defined before
-    `bidsBackHandler` fires and tries to call it.
-
-    To prevent an "`invokeVideoPlayer` not defined" error, we
-    pre-define it before we make the call to Prebid, and redefine
-    it later on with the code to create the player and play the
-    ad.
-
-    In this first version, it simply stores the winning VAST to
-    use later. */
-
-    var tempTag = false;
-    var invokeVideoPlayer = function(url) {
-        tempTag = url;
-    };
-
-    /* Prebid video ad unit */
-
-    var videoAdUnit = {
-        code: 'video1',
-        mediaTypes: {
-            video: {
-                context: 'instream',
-                playerSize: [640, 480],
-                mimes: ['video/mp4'],
-                protocols: [1, 2, 3, 4, 5, 6, 7, 8],
-                playbackmethod: [2],
-                skip: 1
-            }
-        },
-        bids: [{
-            bidder: 'appnexus',
-            params: {
-                placementId: 13232361  // Add your own placement id here.
- } - }] - }; - - pbjs.que.push(function() { - - // configure prebid to use prebid cache and prebid server   - // make sure to add your own accountId to your s2sConfig object
- pbjs.setConfig({ - cache: { - url: 'https://prebid.adnxs.com/pbc/v1/cache' - }, - debug: true, - s2sConfig: { - endpoint: 'https://prebid.adnxs.com/pbs/v1/openrtb2/auction', - enabled: true, - accountId: 'c9d412ee-3cc6-4b66-9326-9f49d528f13e', - bidders: ['appnexus'] - } - }); - - pbjs.addAdUnits(videoAdUnit); // add your ad units to the bid request
- - pbjs.requestBids({ - bidsBackHandler: function(bids) { - - var videoUrl = pbjs.adServers.dfp.buildVideoUrl({ - adUnit: videoAdUnit, - params: { - iu: '/19968336/prebid_cache_video_adunit', - cust_params: { - section: 'blog', - anotherKey: 'anotherValue' - }, - output: 'vast' - } - }); - invokeVideoPlayer(videoUrl); - } - }); - }); - -</script> -
-
- -

Place this code in the page body.

-
- -
-
-<div id="myPlayer" style="width:640px; height:480px;"></div>
-
-<!-- INCLUDE KALTURA PLAYER SCRIPT
-
- Add the script for your Kaltura player. This will be part of
- the code you will copy-paste from Kaltura. -->
-
-<script src="https://cdnapi.kaltura.com/p/2222001/sp/222200100/embedIframeJs/uiconf_id/37440401/partner_id/2222001"></script>
-
-<script>
-    invokeVideoPlayer = function(url) {
-
-        /* EMBED KALTURA PLAYER
-
-        Call `kWidget.embed()` and pass in a JSON object of your
-        player settings. Most of this JSON object will be part of
-        the code you will copy paste from Kaltura.
-
-        Documentation for kWidget available here:
-        https://player.kaltura.com/docs/kwidget */
-
-        kWidget.embed({
-            "targetId": "myPlayer",
-            "wid": "_2222001",
-            "uiconf_id": 37440401,
-
-            /* ADD VAST SETTINGS TO THE PLAYER SETTINGS
-
-            Inside `flashVars`, add another key called `"vast"` and
-            pass in a JSON object with:
-
-            - the position where you want your ad to play
-
-            - the URL of the ad (which in this case will be the `url`
-            we got back from Prebid) */
-
-            "flashvars": {
-                "streamerType": "auto",
-                "vast": {
-                    "plugin": true,
-                    "prerollUrl": url,
-                }
-            },
-            "entry_id": "1_k4eka7er",
-
-            /* ADD A READY CALLBACK AND GET A REFERENCE TO THE PLAYER
-
-            Add a ready callback to the player settings. This allows
-            us to get a reference to the player (stored in the
-            variable `kdp`) in order to interact with it later. */
-
-            readyCallback: function(playerId) {
-                console.log("Kaltura player " + playerId + " is ready.");
-            }
-        });
-    };
-
-    /* ACCOUNT FOR PAGE SPEED
-
-    If Prebid returned bids before the browser reached the end of
-    the page, the first version of `invokeVideoPlayer` will have
-    been called from `bidsBackHandler` so the winning VAST tag
-    will be stored in the `tempTag` variable.
-
-    If that's the case, we want to call the 'real' version of
-    `invokeVideoPlayer` with the stored URL to create the player
-    and play the ad.
-
-    If `tempTag` is not defined, that means the browser reached
-    the end of the page before the bids came back from Prebid,
-    meaning the 'real' version of `invokeVideoPlayer` was already
-    called. */
-
-    if (tempTag) {
-        invokeVideoPlayer(tempTag);
-        tempTag = false;
-    }
-
-</script>
-      
-
-
-
- - - - - - - - - - - diff --git a/examples/video/server/ooyala/pbs-ve-ooyala.html b/examples/video/server/ooyala/pbs-ve-ooyala.html deleted file mode 100644 index 1f2a8b92..00000000 --- a/examples/video/server/ooyala/pbs-ve-ooyala.html +++ /dev/null @@ -1,369 +0,0 @@ ---- -layout: video_sample -title: Prebid Video | Prebid Server Example with Ooyala -description: An example of a pre-roll ad using Prebid Server and Ooyala. -videoType: pbs-oy -isVideo: true -sidebarType: 4 ---- - - - -
-
-
-

{{ page.title }}

-

{{page.description }}

-
- - -
-

Important: - This example uses a test version of Prebid.js hosted on our CDN that is not recommended for production use. It includes all available adapters. Production implementations should build from source or customize the build using the Download page to make sure only the necessary bidder adapters are included.

-
- - -
- - - - - -
-

Warning: - Do not forget to exchange the placementId in the code examples with your own placementId!

-
- -

Place this code in the page header.

-
-
-  
-
-<!-- LOAD OOYALA PLUGINS
-
- Load the Ooyala player scripts you plan to use.
-
- You must load the core player script, the scripts for
- whatever video formats you want to support, and the scripts
- for the ad manager you want to use.
-
- The scripts themselves and a guide for choosing which ones
- you need can be found here:
-
- https://help.ooyala.com/video-platform/documentation/concepts/pbv4_plugins.html
--->
-
-<!-- CORE PLAYER REQUIRED -->
-<script src="//player.ooyala.com/static/v4/production/latest/core.min.js"></script>
-
-<!-- VIDEO PLUGINS -->
-<script src="//player.ooyala.com/static/v4/production/latest/video-plugin/main_html5.min.js"></script>
-<script src="//player.ooyala.com/static/v4/production/latest/video-plugin/bit_wrapper.min.js"></script>
-<script src="//player.ooyala.com/static/v4/production/latest/video-plugin/osmf_flash.min.js"></script>
-
-<!-- HTML5 SKIN -->
-<script src="//player.ooyala.com/static/v4/production/latest/skin-plugin/html5-skin.min.js"></script>
-
-<!-- SKIN ASSET -->
-<link rel="stylesheet" href="//player.ooyala.com/static/v4/production/latest/skin-plugin/html5-skin.min.css" />
-
-<!-- IMA PLUGIN -->
-<script src="//player.ooyala.com/static/v4/production/latest/ad-plugin/google_ima.js"></script>
-<script>
-    var pbjs = pbjs || {};
-    pbjs.que = pbjs.que || [];
-
-    /* PRE-DEFINE `invokeVideoPlayer`
-
-    Because we have no way of knowing when all the bids will be
-    returned from Prebid we can't be sure that the browser will
-    reach the point where `invokeVideoPlayer` is defined before
-    `bidsBackHandler` fires and tries to call it.
-
-    To prevent an "`invokeVideoPlayer` not defined" error, we
-    pre-define it before we make the call to Prebid, and redefine
-    it later on with the code to create the player and play the
-    ad.
-
-    In this first version, it simply stores the winning VAST to
-    use later. */
-
-    var tempTag = false;
-    var invokeVideoPlayer = function(url) {
-        tempTag = url;
-    };
-
-    /* Prebid video ad unit */
-
-    var videoAdUnit = {
-        code: 'video1',
-        mediaTypes: {
-            video: {
-                context: 'instream',
-                playerSize: [640, 480],
-                mimes: ['video/mp4'],
-                protocols: [1, 2, 3, 4, 5, 6, 7, 8],
-                playbackmethod: [2],
-                skip: 1
-            }
-        },
-        bids: [{
-            bidder: 'appnexus',
-            params: {
-                placementId: 13232361  // Add your own placement id here.
- } - }] - }; - - pbjs.que.push(function() { - - // configure prebid to use prebid cache and prebid server   - // make sure to add your own accountId to your s2sConfig object
- pbjs.setConfig({ - cache: { - url: 'https://prebid.adnxs.com/pbc/v1/cache' - }, - debug: true, - s2sConfig: { - endpoint: 'https://prebid.adnxs.com/pbs/v1/openrtb2/auction', - enabled: true, - accountId: 'c9d412ee-3cc6-4b66-9326-9f49d528f13e', // replace this with your account id
- bidders: ['appnexus'] - } - }); - - // add your ad units to the bid request
- pbjs.addAdUnits(videoAdUnit); - - pbjs.requestBids({ - bidsBackHandler: function(bids) { - console.log(bids); - var videoUrl = pbjs.adServers.dfp.buildVideoUrl({ - adUnit: videoAdUnit, - params: { - iu: '/19968336/prebid_cache_video_adunit', - cust_params: { - section: 'blog', - anotherKey: 'anotherValue' - }, - output: 'vast' - } - }); - invokeVideoPlayer(videoUrl); - } - }); - }); - -</script> -
-
- -

Place this code in the page body.

-
- -
-
-<div id='container' style='width:640px;height:480px;'></div>
-
-<script>
-    var invokeVideoPlayer = function(url) {
-        console.log("invoking video player with url " + url);
-
-        /* DEFINE PLAYER SETTINGS
-
-        Define the settings you want for your player in a JSON
-        object. These lines will be part of the embed code you
-        copy-paste from Ooyala Backlot, we just need to add the ad
-        parameters.  */
-
-        var playerParam = {
-            'pcode': 'lsbWkyOjtI6LOjmlqk2o5I-TsWRA',
-            'playerBrandingId': '45b8294c6ad14265b2b47586c911cb07',
-            'debug': true,
-            'autoplay': true,
-            'initialVolume': 0.0,
-            'skin': {
-                'config': '//player.ooyala.com/static/v4/stable/4.6.9/skin-plugin/skin.json',
-                'inline': {
-                    'adScreen': {
-                        'showAdMarquee': true,
-                        'showAdCountDown': true,
-                        'showControlBar': true,
-                        'useGoogleAdUI': true
-                    }
-                }
-            },
-
-            /* ADD THE AD PARAMETERS TO THE PLAYER SETTINGS
-
-            Create a new JSON object in the player parameters. The key
-            should be the ad manager you're using (in our case we're
-            using the Google IMA ads manager, so the key is
-            `"google-ima-ads-manager"`). The IMA ads manager requires
-            an ad set (which we've named `"all_ads"`).
-
-            For more information see the Ooyala docs:
-
-            https://help.ooyala.com/video-platform/concepts/pbv4_ads_dev_google_ima.html:
-
-            Make sure the ad parameters are properly formatted JSON.
-            */
-            "google-ima-ads-manager": {
-                "all_ads": [{
-                    "position": "0",
-                    "position_type": "t",
-                    "tag_url": url
-                }],
-                'showAdControls': true
-            }
-        };
-
-        /* INITIALIZE THE PLAYER
-
-        Use the `OO.ready()` event to make sure that all the
-        necessary Ooyala plugins have loaded before attempting to
-        create the player. Once it has, call `create()` and pass
-        in:
-
-        - the div you're creating the player in
-
-        - the ID of the content video
-
-        - the player settings we created above */
-
-        OO.ready(function() {
-            console.log("OO is ready, invoking");
-            console.dir(playerParam);
-            window.pp = OO.Player.create('container', 'ltcG54NzE6Bxk08Mqs1_KMcQZDN7lH8N', playerParam);
-        });
-    };
-
-    /* ACCOUNT FOR PAGE SPEED
-
-    If Prebid returned bids before the browser reached the end of
-    the page, the first version of `invokeVideoPlayer` will have
-    been called from `bidsBackHandler`, so the winning VAST tag will
-    be stored in `tempTag`.
-
-    If that's the case, we want to call the "real" version of
-    `invokeVideoPlayer` with the stored URL to create the player and
-    play the ad.
-
-    If `tempTag` is not defined, that means the browser reached the
-    end of the page before the bids came back from Prebid, meaning
-    the "real" version of `invokeVideoPlayer` was already called.
-    */
-
-    if (tempTag) {
-        invokeVideoPlayer(tempTag);
-        tempTag = false;
-    }
-
-</script>
-
-      
-
-
-
- - - - - - - - diff --git a/examples/video/server/radiant/pbs-ve-radiant.html b/examples/video/server/radiant/pbs-ve-radiant.html deleted file mode 100644 index 8d89af40..00000000 --- a/examples/video/server/radiant/pbs-ve-radiant.html +++ /dev/null @@ -1,341 +0,0 @@ ---- -layout: video_sample -title: Prebid Video | Prebid Server Example with Radiant Media Player -description: An example of an instream pre-roll ad using Prebid Server and Radiant Media Player . -videoType: pbs-rd -isVideo: true -sidebarType: 4 ---- - -
-
-
-

{{ page.title }}

-

{{page.description }}

-
- - -
-

Important: - This example uses a test version of Prebid.js hosted on our CDN that is not recommended for production use. It includes all available adapters. Production implementations should build from source or customize the build using the Download page to make sure only the necessary bidder adapters are included.

-
- - -
- - - - -
-

Warning: - Do not forget to exchange the placementId in the code examples with your own placementId!

-
- -

Place this code in the page header.

-
-
-
-<!--production version of prebid.js-->
-<script async src="//cdn.jsdelivr.net/npm/prebid.js@latest/dist/not-for-prod/prebid.js"></script>
-
-<!-- Radiant Media Player core library - debug browser console mode (use rmp.min.js for production) -->
-<script src="https://cdn.radiantmediatechs.com/rmp/5.5.6/js/rmp.debug.js"></script>
-      
-
- - -
-

Place this code in the page body.

- -
-
-/* our app where we run player
-   our app variables */
-var pbApp = {};
-pbApp.playerSetup = false;
-pbApp.prebidTempTag = false;
-pbApp.debug = true;
-/* in case pre-bidding takes too long or fails we provide a playerSetupTimeout and fallbackAdTagUrl
-   to insure player setup happens - this is optional */
-pbApp.playerSetupTimeout = 5000;
-pbApp.fallbackAdTagUrl = 'https://www.radiantmediaplayer.com/vast/tags/inline-linear-1.xml';
-/* no console - no logs */
-if (typeof window.console === 'undefined' || typeof window.console.log === 'undefined' || typeof window.console.dir === 'undefined') {
-  pbApp.debug = false;
-}
-
-/* invokeVideoPlayer may not be defined when bidsBackHandler runs
-   we pre-defined it here so as to capture the returned adTagUrl to be passed to the player */
-pbApp.invokeVideoPlayer = function (adTagUrl) {
-  pbApp.prebidTempTag = adTagUrl;
-};
-
-/* prebid.js variables */
-var pbjs;
-pbjs = pbjs || {};
-pbjs.que = pbjs.que || [];
-
-/* Prebid video ad unit
-   This is a working example but you must use your own settings/bidders for production
-   More docs at https://prebid.org/prebid-video/video-overview.html */
-var videoAdUnit = {
-  code: 'video1',
-  mediaTypes: {
-    video: {
-  context: 'instream',
-  playerSize: [640, 480],
-  mimes: ['video/mp4'],
-  protocols: [1, 2, 3, 4, 5, 6, 7, 8],
-  playbackmethod: [2],
-  skip: 1
-    }
-  },
-  bids: [{
-    bidder: 'appnexus',
-    params: {
-      placementId: 13232361  // Add your own placement id here.
-    }
-  }]
-};
-
-pbjs.que.push(function () {
-  // configure prebid to use prebid cache and prebid server
-  // make sure to add your own accountId to your s2sConfig object
-  pbjs.setConfig({
-    cache: {
-      url: 'https://prebid.adnxs.com/pbc/v1/cache'
-    },
-    debug: true,
-    enableSendAllBids: true,
-    s2sConfig: {
-      endpoint: 'https://prebid.adnxs.com/pbs/v1/openrtb2/auction',
-      enabled: true,
-      accountId: 'c9d412ee-3cc6-4b66-9326-9f49d528f13e',
-      bidders: ['appnexus']
-    }
-  });
-
-  pbjs.addAdUnits(videoAdUnit); // add your ad units to the bid request
-
-  pbjs.requestBids({
-    bidsBackHandler: function (bids) {
-      if (pbApp.debug) {
-        window.console.dir(bids);
-      }
-      var videoUrl = pbjs.adServers.dfp.buildVideoUrl({
-        adUnit: videoAdUnit,
-        params: {
-          iu: '/19968336/prebid_cache_video_adunit',
-          cust_params: {
-            section: 'blog',
-            anotherKey: 'anotherValue'
-          },
-          output: 'vast'
-        }
-      });
-      pbApp.invokeVideoPlayer(videoUrl);
-    }
-  });
-});
-
-/* here we re-define invokeVideoPlayer with Radiant Media Player set-up */
-pbApp.invokeVideoPlayer = function (adTagUrl) {
-  if (pbApp.playerSetup) {
-    return;
-  }
-  pbApp.playerSetup = true;
-  if (pbApp.debug) {
-    window.console.log('invokeVideoPlayer with Prebid VAST url = ' + adTagUrl);
-  }
-  var src = {
-    mp4: [
-      'https://www.rmp-streaming.com/media/bbb-360p.mp4'
-    ]
-  };
-  var settings = {
-    licenseKey: 'Kl8lZ292K3N6MmVvZD9yb201ZGFzaXMzMGRiMEElXyo=',
-    src: src,
-    width: 640,
-    height: 360,
-    //*we enabled ads for our player
-    note that we requested a winning bid for skippable auto_play_sound_off so player starts muted autoplay*/
-    ads: true,
-    autoplay: true,
-    muted: true,
-    // we use Google IMA in this demo, but you can use rmp-vast as well depending on your requirements
- adParser: 'ima', - // since we may request a skippable ads we set adDisableCustomPlaybackForIOS10Plus: true to allow rendering of skippable ads on iOS
- adDisableCustomPlaybackForIOS10Plus: true, - // here is our winner VAST adTagUrl
- adTagUrl: adTagUrl, - poster: 'https://www.radiantmediaplayer.com/images/poster-rmp-showcase.jpg' - }; - var elementID = 'rmpPlayer'; - var rmp = new RadiantMP(elementID); - rmp.init(settings); - -}; - -/* in case we already have a winning bid let's use the returned adTagUrl to run player */ -if (pbApp.prebidTempTag) { - pbApp.invokeVideoPlayer(pbApp.prebidTempTag); - pbApp.prebidTempTag = false; -} - -/* in case something went wrong (latency, network errors, bid issues ...) and we have no winning bid we still need to run the player - this is done after pbApp.playerSetupTimeout ms and we use fallbackAdTagUrl as adTagUrl to pass to the player */ -setTimeout(function () { - if (pbApp.playerSetup) { - return; - } - pbApp.invokeVideoPlayer(pbApp.fallbackAdTagUrl); -}, pbApp.playerSetupTimeout); -
-
-
-
- - - - diff --git a/examples/video/server/videojs/pbs-ve-videojs.html b/examples/video/server/videojs/pbs-ve-videojs.html deleted file mode 100644 index 329ef45b..00000000 --- a/examples/video/server/videojs/pbs-ve-videojs.html +++ /dev/null @@ -1,282 +0,0 @@ ---- -layout: video_sample -title: Prebid Video | Prebid Server Example with VideoJS -description: An example of a pre-roll ad using Prebid Server and VideoJS. -videoType: pbs-vjs -isVideo: true -sidebarType: 4 ---- - - - -
-
-
-

{{ page.title }}

-

{{page.description }}

-
- - -
-

Important: - This example uses a test version of Prebid.js hosted on our CDN that is not recommended for production use. It includes all available adapters. Production implementations should build from source or customize the build using the Download page to make sure only the necessary bidder adapters are included.

-
- - -
- -
- - - - - -
-

Warning: - Do not forget to exchange the placementId in the code examples with your own placementId!

-
- -

Place this code in the page header.

-
-
-
-<!-- videojs -->
-<!-- use recent version of videojs to ensure proper functioning with the iOS devices -->
-<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/video.js/6.4.0/video-js.css">
-<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/video.js/6.4.0/video.js"></script>
-<!-- videojs-vast-vpaid -->
-<link href="https://cdnjs.cloudflare.com/ajax/libs/videojs-vast-vpaid/2.0.2/videojs.vast.vpaid.min.css" rel="stylesheet">
-<script src="https://cdnjs.cloudflare.com/ajax/libs/videojs-vast-vpaid/2.0.2/videojs_5.vast.vpaid.min.js"></script>
-
-<script>
-    var pbjs = pbjs || {};
-    pbjs.que = pbjs.que || [];
-
-    /* PRE-DEFINE `invokeVideoPlayer`
-
-    Because we have no way of knowing when all the bids will be
-    returned from Prebid we can't be sure that the browser will
-    reach the point where `invokeVideoPlayer` is defined before
-    `bidsBackHandler` fires and tries to call it.
-
-    To prevent an "`invokeVideoPlayer` not defined" error, we
-    pre-define it before we make the call to Prebid, and redefine
-    it later on with the code to create the player and play the
-    ad.
-
-    In this first version, it simply stores the winning VAST to
-    use later. */
-
-    var tempTag = false;
-    var invokeVideoPlayer = function(url) {
-        tempTag = url;
-    };
-
-    /* Prebid video ad unit */
-
-    var videoAdUnit = {
-        code: 'video1',
-        mediaTypes: {
-            video: {
-                context: 'instream',
-                playerSize: [640, 480],
-                mimes: ['video/mp4'],
-                protocols: [1, 2, 3, 4, 5, 6, 7, 8],
-                playbackmethod: [2],
-                skip: 1
-            }
-        },
-        bids: [{
-            bidder: 'appnexus',
-            params: {
-                placementId: 13232361  // Add your own placement id here.
-            }
-        }]
-    };
-
-    pbjs.que.push(function() {
-
-        // configure prebid to use prebid cache and prebid server  
-        // make sure to add your own accountId to your s2sConfig object 
- pbjs.setConfig({ - cache: { - url: 'https://prebid.adnxs.com/pbc/v1/cache' - }, - debug: true, - s2sConfig: { - endpoint: 'https://prebid.adnxs.com/pbs/v1/openrtb2/auction', - enabled: true, - accountId: 'c9d412ee-3cc6-4b66-9326-9f49d528f13e', // replace this with your account id
- bidders: ['appnexus'] - } - }); - - // add your ad units to the bid request
- pbjs.addAdUnits(videoAdUnit); - - pbjs.requestBids({ - bidsBackHandler: function(bids) { - var videoUrl = pbjs.adServers.dfp.buildVideoUrl({ - adUnit: videoAdUnit, - params: { - iu: '/19968336/prebid_cache_video_adunit', - cust_params: { - section: 'blog', - anotherKey: 'anotherValue' - }, - output: 'vast' - } - }); - invokeVideoPlayer(videoUrl); - } - }); - }); - -</script> -
-
- -

Place this code in the page body.

-
- -
-
-<div class="example-video-container">
-    <video id="vid1" class="video-js vjs-default-skin vjs-big-play-centered" controls data-setup='{}' width='640' height='480'>
-        <source src="https://vjs.zencdn.net/v/oceans.mp4" type='video/mp4'/>
-        <source src="https://vjs.zencdn.net/v/oceans.webm" type='video/webm'/>
-        <source src="https://vjs.zencdn.net/v/oceans.ogv" type='video/ogg'/>
-    </video>
-</div>
-
-<script>
-    var page_load_time;
-
-    page_load_time = new Date().getTime() - performance.timing.navigationStart;
-    console.log(page_load_time + "ms -- Player loading!");
-
-    var vid1 = videojs('vid1');
-
-    page_load_time = new Date().getTime() - performance.timing.navigationStart;
-    console.log(page_load_time + "ms -- Player loaded!");
-
-    function invokeVideoPlayer(url) {
-
-        page_load_time = new Date().getTime() - performance.timing.navigationStart;
-        console.log(page_load_time + "ms -- Prebid VAST url = " + url);
-
-        /* Access the player instance by calling `videojs()` and passing
-         in the player's ID. Add a `ready` listener to make sure the
-         player is ready before interacting with it. */
-
-        videojs("vid1").ready(function() {
-
-            page_load_time = new Date().getTime() - performance.timing.navigationStart;
-            console.log(page_load_time + "ms -- Player is ready!");
-
-            /* PASS SETTINGS TO VAST PLUGIN
-
-            Pass in a JSON object to the player's `vastClient` (defined
-            by the VAST/VPAID plugin we're using). The requires an
-            `adTagUrl`, which will be the URL returned by Prebid. You
-            can view all the options available for the `vastClient`
-            here:
-
-            https://github.com/MailOnline/videojs-vast-vpaid#options */
-
-            var player = this;
-            var vastAd = player.vastClient({
-                adTagUrl: url,
-                prerollTimeout: 500,
-                playAdAlways: true,
-                verbosity: 4,
-                vpaidFlashLoaderPath: "https://github.com/MailOnline/videojs-vast-vpaid/blob/RELEASE/bin/VPAIDFlash.swf?raw=true",
-                autoplay: true
-            });
-
-            page_load_time = new Date().getTime() - performance.timing.navigationStart;
-            console.log(page_load_time + "ms -- Prebid VAST tag inserted!");
-
-            player.muted(true);
-            player.play();
-
-            page_load_time = new Date().getTime() - performance.timing.navigationStart;
-            console.log(page_load_time + "ms -- invokeVideoPlayer complete!");
-
-        });
-    }
-
-</script>
-      
-
-
-
- - - - - - - - diff --git a/prebid-video/video-integrating-solo.md b/prebid-video/video-integrating-solo.md index 53cc498c..e69271e0 100644 --- a/prebid-video/video-integrating-solo.md +++ b/prebid-video/video-integrating-solo.md @@ -95,14 +95,8 @@ This section contains working examples of instream and outstream video ads for v ## Using client-side adapters ### Instream -+ [Akamai AMP]({{site.github.url}}/examples/video/instream/akamai/pb-ve-amp.html) -+ [Brid]({{site.github.url}}/examples/video/instream/brid/pb-ve-brid.html) -+ [Brightcove]({{site.github.url}}/examples/video/instream/brightcove/pb-ve-brightcove.html) -+ [Flowplayer]({{site.github.url}}/examples/video/instream/flowplayer/pb-ve-flowplayer.html) + [JWPlayer - Platform]({{site.github.url}}/examples/video/instream/jwplayer/pb-ve-jwplayer-platform.html) + [JWPlayer - Hosted]({{site.github.url}}/examples/video/instream/jwplayer/pb-ve-jwplayer-hosted.html) -+ [Kaltura]({{site.github.url}}/examples/video/instream/kaltura/pb-ve-kaltura.html) -+ [Ooyala]({{site.github.url}}/examples/video/instream/ooyala/pb-ve-ooyala.html) + [VideoJS]({{site.github.url}}/examples/video/instream/videojs/pb-ve-videojs.html) ### Outstream @@ -110,16 +104,6 @@ This section contains working examples of instream and outstream video ads for v + [Outstream with Google Ad Manager]({{site.github.url}}/examples/video/outstream/pb-ve-outstream-dfp.html) + [Outstream without an Ad Server]({{site.github.url}}/examples/video/outstream/pb-ve-outstream-no-server.html) -## Using Prebid Server - -+ [Brid]({{site.baseurl}}/examples/video/server/brid/pbs-ve-brid.html) -+ [JW Player - Platform]({{site.baseurl}}/examples/video/server/jwplayer/pbs-ve-jwplayer-platform.html) -+ [JW Player - Hosted]({{site.baseurl}}/examples/video/server/jwplayer/pbs-ve-jwplayer-hosted.html) -+ [Kaltura]({{site.baseurl}}/examples/video/server/kaltura/pbs-ve-kaltura.html) -+ [Ooyala]({{site.baseurl}}/examples/video/server/ooyala/pbs-ve-ooyala.html) -+ [VideoJS]({{site.baseurl}}/examples/video/server/videojs/pbs-ve-videojs.html) - - # Further Reading - [Prebid.js for Video Overview]({{site.github.url}}/prebid-video/video-overview.html) From 5bb755dc5fd5f95e76b8457fb9ea283111761a9a Mon Sep 17 00:00:00 2001 From: bretg Date: Tue, 28 Feb 2023 12:27:31 -0500 Subject: [PATCH 078/762] PBS auction endpoint update (#4396) added ext.prebid.analytics --- .../endpoints/openrtb2/pbs-endpoint-auction.md | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/prebid-server/endpoints/openrtb2/pbs-endpoint-auction.md b/prebid-server/endpoints/openrtb2/pbs-endpoint-auction.md index e290067c..adb9cd3f 100644 --- a/prebid-server/endpoints/openrtb2/pbs-endpoint-auction.md +++ b/prebid-server/endpoints/openrtb2/pbs-endpoint-auction.md @@ -1406,6 +1406,20 @@ PBS-core creates this block before sending to bid adapters. They receive additio             } ``` +##### Analytics Extension + +Some analytics adapters may support special flags that can be passed on ext.prebid.analytics. e.g. + +``` +ext.prebid: { + analytics: { + myanalyticsadapter: { + myflag: true + } + } +} +``` + #### OpenRTB Response Extensions ##### Bidder Response Times @@ -1663,6 +1677,7 @@ The Prebid SDK version comes from: | ext.prebid.pbs.endpoint | additional Prebid Server metadata | string | yes | | ext.prebid.floors | PBS floors data | object | no | | ext.prebid.returnallbidstatus | If true, PBS returns [ext.seatnonbid](#seat-non-bid) with details about bidders that didn't bid. | boolean | no | +| ext.prebid.analytics | Arguments that can be passed through to individual analytics adapters | object | no | | imp.ext.ae | If 1, signals bid adapters that Fledge auction config is accepted on the response. (ae stands for auction environment) | integer | yes | | app.ext.prebid.source | The client that created this ORTB. Normally "prebid-mobile" | string | yes | | app.ext.prebid.version | The version of the client that created this ORTB. e.g. "1.1" | string | yes | From e66c535164cbd16e399181af8d27eeda512ea5a8 Mon Sep 17 00:00:00 2001 From: Michele Nasti Date: Wed, 1 Mar 2023 20:38:58 +0100 Subject: [PATCH 079/762] Separate puc docs (#3645) * more details about ortb native * added a section for bid adapters * move paragraph up * wordsmithing * added link to ortb spec Co-authored-by: Muki Seiler * fixed link * Fix ad-unit-define creative link * fix native-implementation link * add clickUrlUnesc; add openrtb spec links * fixes * replace /dist/creative.js with hb_format.js replace native-render.js with native.js * put %%PATTERN:hb_format%% everywhere * fix examples that use renderAd in native * fix examples * mentioning hb_format directly * updated adops docs --------- Co-authored-by: Michele Nasti Co-authored-by: bretg Co-authored-by: Muki Seiler Co-authored-by: Filip Stamenkovic --- adops/adops-general-sbs.md | 3 +- adops/creative-considerations.md | 2 +- adops/gam-creative-banner-sbs.md | 6 ++-- adops/gam-native.md | 26 +++++++++-------- ...g-up-prebid-with-the-appnexus-ad-server.md | 2 +- dev-docs/show-prebid-ads-on-amp-pages.md | 4 +-- overview/prebid-universal-creative.md | 25 +++++++++++----- prebid/native-implementation.md | 29 ++++++++++--------- 8 files changed, 56 insertions(+), 41 deletions(-) diff --git a/adops/adops-general-sbs.md b/adops/adops-general-sbs.md index af21d97c..80ed48e5 100644 --- a/adops/adops-general-sbs.md +++ b/adops/adops-general-sbs.md @@ -131,7 +131,7 @@ We recommend using the [Prebid Universal Creative](/overview/prebid-universal-cr If you’re working with banner or outstream creatives, the HTML you’ll enter in the creatives will be similar to the following (utilizing whatever macro format is supported by your ad server): ``` - + + + + ``` @@ -164,7 +164,7 @@ p { The GAM creative is identical whether the template is defined in the AdUnit or the external render JavaScript. There are two key aspects of the native creative in this scenario: -1. Load the Prebid.js native rendering code. You can utilize the jsdelivr version of native-render.js or host your own copy. If you use the version hosted on jsdelivr, make sure to declare jsdelivr as an ad technology provider in GAM. Admin → EU User Consent → Declare ad technology providers +1. Load the Prebid.js native rendering code. You may utilize the jsdelivr version of native.js or host your own copy. If you use the version hosted on jsdelivr, make sure to declare jsdelivr as an ad technology provider in GAM. Admin → EU User Consent → Declare ad technology providers. 2. Invoke the Prebid.js native rendering function with an object containing the following attributes: - adid - Used to identify which Prebid.js creative holds the appropriate native assets. - pubUrl - The URL of the page, which is needed for the HTML postmessage call. @@ -172,19 +172,21 @@ The GAM creative is identical whether the template is defined in the AdUnit or t Example creative HTML: ``` - + ``` {: .alert.alert-warning :} -When using Send All Bids, use `pbNativeTagData.adId = "%%PATTERN:hb_adid_BIDDERCODE%%";` rather than `pbNativeTagData.adId = "%%PATTERN:hb_adid%%";` for each bidder’s creative, replacing `BIDDERCODE` with the actual bidder code, such as `%%PATTERN:hb_adid_BidderA%%`. +When using Send All Bids, use `ucTagData.adId = "%%PATTERN:hb_adid_BIDDERCODE%%";` rather than `ucTagData.adId = "%%PATTERN:hb_adid%%";` for each bidder’s creative, replacing `BIDDERCODE` with the actual bidder code, such as `%%PATTERN:hb_adid_BidderA%%`. The example CSS in the previous section applies here as well. @@ -202,7 +204,7 @@ Now that you've defined your native template you can create your native creative {:start="4"} 4. Under **Settings**, enter a **Name** for your creative. -5. Enter any value into the **Click-through URL** field; this value will be overwritten by the native asset values. Also, if you operate in Europe and are using the jsdelivr-hosted native-render.js, make sure you set jsdelivr as your ad technology provider. (See Step 6 below.) +5. Enter any value into the **Click-through URL** field; this value will be overwritten by the native asset values. Also, if you operate in Europe and are using the jsdelivr-hosted native.js, make sure you set jsdelivr as your ad technology provider. (See Step 6 below.) ![Native Creative](/assets/images/ad-ops/gam-sbs/gam-new-creative-part2.png){: .pb-md-img :} diff --git a/adops/setting-up-prebid-with-the-appnexus-ad-server.md b/adops/setting-up-prebid-with-the-appnexus-ad-server.md index 7f4bbd51..607b0aac 100644 --- a/adops/setting-up-prebid-with-the-appnexus-ad-server.md +++ b/adops/setting-up-prebid-with-the-appnexus-ad-server.md @@ -78,7 +78,7 @@ Follow the creative setup instructions in [Add Creatives](https://docs.xandr.com ![New creative]({{ site.github.url }}/assets/images/ad-ops/appnexus-setup/prebid-creative-appnexus.png) {: .pb-lg-img :} {% highlight html %} - + + + +``` + +This loads the PUC from the Prebid-maintained location. Your managed +service provider may have a different location. + +## Features of the PUC ### What the PUC does for Web iframe Banners/Outstream 1. Simply calls the Prebid.js renderAd function diff --git a/prebid/native-implementation.md b/prebid/native-implementation.md index 8eb4ca89..e0f9077e 100644 --- a/prebid/native-implementation.md +++ b/prebid/native-implementation.md @@ -66,7 +66,7 @@ This table summarizes how the 3 approaches work: | --- | --- |--- | --- | | Prebid.js | mediaTypes. native.sendTargetingKeys: false | sendTargetingKeys:false and mediaTypes.native.adTemplate contains ##macros## | sendTargetingKeys:false and mediaTypes.native.rendererUrl | | Ad Server Key Value Pairs | hb_adid | hb_adid | hb_adid | -| Ad Server | Native template loads native-render.js and calls renderNativeAd(). Uses Prebid ##macro## format. | Native creative loads native-render.js and calls renderNativeAd() with requestAllAssets: true | Native creative loads native-render.js and calls renderNativeAd(), with requestAllAssets:true | +| Ad Server | Native template loads native.js and calls renderNativeAd(). Uses Prebid ##macro## format. | Native creative loads native.js and calls renderNativeAd() with requestAllAssets: true | Native creative loads native.js and calls renderNativeAd(), with requestAllAssets:true | | Prebid Universal Creative | renderNativeAd resolves macros in the creative body and CSS. | renderNativeAd resolves ##macros## in adTemplate and CSS, appending the adTemplate to the creative body | renderNativeAd loads javascript from renderUrl, calls the renderAd function, appending the results to the creative body. | | Javascript rendering function | n/a | n/a | Receives the ortb response into `bid.ortb`, and the renderer is responsible for resolving any macro format and returning an HTML block. | @@ -184,7 +184,7 @@ Bid adapters will declare which custom assets they support in their documentatio {: .alert.alert-success :} -Note: The `native-render.js::renderNativeAd()` function must be called with `requestAllAssets: true`. +Note: The `native.js::renderNativeAd()` function must be called with `requestAllAssets: true`. In the native template, simply access the custom value with the normal Prebid `##macro##` format assuming `hb_native_asset_id_` as the prefix. For example, if your custom asset has `id: 7`: @@ -273,7 +273,7 @@ pbjs.addAdUnits({ There are three key aspects of the native template: 1. Build the creative with special Prebid.js macros, e.g. `##hb_native_asset_id_{id}##.` Note that macros can be placed in the body (HTML) and/or head (CSS) of the native creative. -2. Load the Prebid.js native rendering code. You may utilize the jsdelivr version of native-render.js or host your own copy. If you use the version hosted on jsdelivr, make sure any necessary ad server permissions are established. +2. Load the Prebid.js native rendering code. You may utilize the jsdelivr version of native.js or host your own copy. If you use the version hosted on jsdelivr, make sure any necessary ad server permissions are established. 3. Invoke the Prebid.js native rendering function with an object containing the following attributes: 1. adid - used to identify which Prebid.js creative holds the appropriate native assets 2. pubUrl - the URL of the page, which is needed for the HTML postmessage call @@ -289,7 +289,7 @@ Example creative HTML:
##hb_native_asset_id_3##
- + + + - - - {% endif %} + + + + diff --git a/_includes/video/pb-is-app.html b/_includes/video/pb-is-app.html index f7634cd8..3a48ac18 100644 --- a/_includes/video/pb-is-app.html +++ b/_includes/video/pb-is-app.html @@ -8,7 +8,10 @@ ### Downloading and Installing Prebid.js @@ -36,7 +38,9 @@ Optanon.InsertHtml('','vimeo2', null, {deleteSelectorContent: true}, 3); + window.onetrustLoaded.then(() => { + OneTrust.InsertHtml('', 'vimeo2', null, {deleteSelectorContent: true}, 'C0003'); + }) ### Ad Server Setup for Header Bidding @@ -47,7 +51,9 @@ Optanon.InsertHtml('','vimeo3', null, {deleteSelectorContent: true}, 3); + window.onetrustLoaded.then(() => { + OneTrust.InsertHtml('', 'vimeo3', null, {deleteSelectorContent: true}, 'C0003'); + }) ### Setup Google Ad Manager for Header Bidding @@ -58,7 +64,9 @@ Optanon.InsertHtml('','vimeo4', null, {deleteSelectorContent: true}, 3); + window.onetrustLoaded.then(() => { + OneTrust.InsertHtml('', 'vimeo4', null, {deleteSelectorContent: true}, 'C0003'); + }) ### Ad Units Array Setup @@ -69,7 +77,9 @@ Optanon.InsertHtml('','vimeo5', null, {deleteSelectorContent: true}, 3); + window.onetrustLoaded.then(() => { + OneTrust.InsertHtml('', 'vimeo5', null, {deleteSelectorContent: true}, 'C0003'); + }) ## Troubleshooting @@ -82,7 +92,9 @@ Optanon.InsertHtml('','vimeo6', null, {deleteSelectorContent: true}, 3); + window.onetrustLoaded.then(() => { + OneTrust.InsertHtml('', 'vimeo6', null, {deleteSelectorContent: true}, 'C0003'); + }) ### Troubleshooting Ad Server: Size and Inventory @@ -93,7 +105,9 @@ Optanon.InsertHtml('','vimeo7', null, {deleteSelectorContent: true}, 3); + window.onetrustLoaded.then(() => { + OneTrust.InsertHtml('', 'vimeo7', null, {deleteSelectorContent: true}, 'C0003'); + }) ### Troubleshooting Ad Server: Line Item Rate and Priority @@ -104,7 +118,9 @@ Optanon.InsertHtml('','vimeo8', null, {deleteSelectorContent: true}, 3); + window.onetrustLoaded.then(() => { + OneTrust.InsertHtml('', 'vimeo8', null, {deleteSelectorContent: true}, 'C0003'); + }) ### Troubleshooting Header Bidding Calls @@ -115,7 +131,9 @@ Optanon.InsertHtml('','vimeo9', null, {deleteSelectorContent: true}, 3); + window.onetrustLoaded.then(() => { + OneTrust.InsertHtml('', 'vimeo9', null, {deleteSelectorContent: true}, 'C0003'); + }) ## Prebid Video @@ -128,7 +146,9 @@ Optanon.InsertHtml('','vimeo10', null, {deleteSelectorContent: true}, 3); + window.onetrustLoaded.then(() => { + OneTrust.InsertHtml('', 'vimeo10', null, {deleteSelectorContent: true}, 'C0003'); + }) ### Prebid Video: Instream @@ -139,7 +159,9 @@ Optanon.InsertHtml('','vimeo11', null, {deleteSelectorContent: true}, 3); + window.onetrustLoaded.then(() => { + OneTrust.InsertHtml('', 'vimeo11', null, {deleteSelectorContent: true}, 'C0003'); + }) ### Prebid Video: Outstream @@ -150,7 +172,9 @@ Optanon.InsertHtml('','vimeo12', null, {deleteSelectorContent: true}, 3); + window.onetrustLoaded.then(() => { + OneTrust.InsertHtml('', 'vimeo12', null, {deleteSelectorContent: true}, 'C0003'); + }) diff --git a/videos/prebid-video.md b/videos/prebid-video.md index a72a458e..f6e1038c 100644 --- a/videos/prebid-video.md +++ b/videos/prebid-video.md @@ -21,7 +21,9 @@ sidebarType: 4 ## Prebid Video: Instream @@ -32,7 +34,9 @@ Optanon.InsertHtml('','vimeo2', null, {deleteSelectorContent: true}, 3); + window.onetrustLoaded.then(() => { + OneTrust.InsertHtml('', 'vimeo2', null, {deleteSelectorContent: true}, 'C0003'); + }) ## Prebid Video: Outstream @@ -43,6 +47,8 @@ Optanon.InsertHtml('','vimeo3', null, {deleteSelectorContent: true}, 3); + window.onetrustLoaded.then(() => { + OneTrust.InsertHtml('', 'vimeo3', null, {deleteSelectorContent: true}, 'C0003'); + }) diff --git a/videos/setup.md b/videos/setup.md index 45ee5444..60a39676 100644 --- a/videos/setup.md +++ b/videos/setup.md @@ -21,7 +21,9 @@ sidebarType: 1

Header Bidding from AppNexus on Vimeo.

@@ -34,7 +36,9 @@ Optanon.InsertHtml('', 'vimeo2', null, {deleteSelectorContent: true}, 3); + window.onetrustLoaded.then(() => { + OneTrust.InsertHtml('', 'vimeo2', null, {deleteSelectorContent: true}, 'C0003'); + })

Downloading and Installing Prebid.js from AppNexus on Vimeo.

@@ -47,7 +51,9 @@ Optanon.InsertHtml('', 'vimeo3', null, {deleteSelectorContent: true}, 3); + window.onetrustLoaded.then(() => { + OneTrust.InsertHtml('', 'vimeo3', null, {deleteSelectorContent: true}, 'C0003'); + }) ## Setup Google Ad Manager for Header Bidding @@ -58,7 +64,9 @@ Optanon.InsertHtml('', 'vimeo4', null, {deleteSelectorContent: true}, 3); + window.onetrustLoaded.then(() => { + OneTrust.InsertHtml('', 'vimeo4', null, {deleteSelectorContent: true}, 'C0003'); + })

Setup Google Ad Manager for Header Bidding from AppNexus on Vimeo.

@@ -71,7 +79,9 @@ Optanon.InsertHtml('', 'vimeo5', null, {deleteSelectorContent: true}, 3); + window.onetrustLoaded.then(() => { + OneTrust.InsertHtml('', 'vimeo5', null, {deleteSelectorContent: true}, 'C0003'); + }) diff --git a/videos/troubleshooting.md b/videos/troubleshooting.md index 495c8d61..d0c8dc15 100644 --- a/videos/troubleshooting.md +++ b/videos/troubleshooting.md @@ -21,7 +21,9 @@ sidebarType: 1

Troubleshooting Header Bidding Configuration from AppNexus on Vimeo.

@@ -34,7 +36,9 @@ Optanon.InsertHtml('','vimeo2', null, {deleteSelectorContent: true}, 3); + window.onetrustLoaded.then(() => { + OneTrust.InsertHtml('', 'vimeo2', null, {deleteSelectorContent: true}, 'C0003'); + }) ## Troubleshooting Ad Server: Line Item Rate and Priority @@ -45,7 +49,9 @@ Optanon.InsertHtml('','vimeo3', null, {deleteSelectorContent: true}, 3); + window.onetrustLoaded.then(() => { + OneTrust.InsertHtml('', 'vimeo3', null, {deleteSelectorContent: true}, 'C0003'); + }) ## Troubleshooting Header Bidding Calls @@ -56,7 +62,9 @@ Optanon.InsertHtml('','vimeo4', null, {deleteSelectorContent: true}, 3); + window.onetrustLoaded.then(() => { + OneTrust.InsertHtml('', 'vimeo4', null, {deleteSelectorContent: true}, 'C0003'); + }) From 1191909e85f3f210b6f3d64b921f7d7777fe660f Mon Sep 17 00:00:00 2001 From: Erik Hummel Date: Thu, 30 Mar 2023 13:05:05 -0400 Subject: [PATCH 129/762] Documentation updates for March 2023 (#4444) * Documentation updates for March 2023 * typo fix * Update dev-docs/modules/userid-submodules/lotame.md fix curly quotes to normal quotes. Co-authored-by: Muki Seiler --------- Co-authored-by: Erik Hummel Co-authored-by: Muki Seiler --- dev-docs/modules/userid-submodules/lotame.md | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) diff --git a/dev-docs/modules/userid-submodules/lotame.md b/dev-docs/modules/userid-submodules/lotame.md index d2ecd784..858140af 100644 --- a/dev-docs/modules/userid-submodules/lotame.md +++ b/dev-docs/modules/userid-submodules/lotame.md @@ -10,23 +10,20 @@ useridmodule: lotamePanoramaIdSystem Lotame’s Panorama ID module sends information from the request to its identity graph in order to successfully generate a Panorama ID. For more information on how the Panorama ID works, please visit [https://www.lotame.com/panorama/id/](https://www.lotame.com/panorama/id/). -**Ease of Implementation**: Deployment of the Lotame Panorama ID module has been optimized for ease by not requiring any registration to utilize. Simply add the generic module to start producing the Panorama ID across your inventory. - Lotame's privacy policy related to the Panorama ID and the collection of data and how data is used is available at [https://www.lotame.com/about-lotame/privacy/lotames-products-services-privacy-policy/](https://www.lotame.com/about-lotame/privacy/lotames-products-services-privacy-policy/). Consult with your legal counsel to determine the appropriate user disclosures with respect to use of the Lotame Panorama ID module. -If you have any questions about Panorama ID, please reach out by emailing [PanoramaID@lotame.com](mailto:PanoramaID@lotame.com). +If you have any questions about Panorama ID, please reach out by emailing [prebid@lotame.com](mailto:prebid@lotame.com). Add it to your Prebid.js package with: {: .alert.alert-info :} gulp build --modules=lotamePanoramaIdSystem -## Lotame Panorama ID Configuration +## Lotame Panorama ID Registration & Implementation -The Lotame Panorama ID module does not require any configuration parameters. It should work as-is provided that bidders use it in their adapters. +To get started, you will need to register with Lotame in order to receive your unique client ID for the userID module. You can [register here](https://www.cognitoforms.com/LotameSolutionsInc/PanoramaIDOfferingEnrollment) or contact [prebid@lotame.com](mailto:prebid@lotame.com) for any questions that you may have. -{: .alert.alert-info :} -NOTE: For optimal performance, the Lotame Panorama Id module should be called at every opportunity. It is best not to use `params.storage` with this module as the module has its own optimal caching mechanism. +Once you sign up, you will receive an email with your client ID and instructions for implementation. ## Lotame Panorama ID Example @@ -34,13 +31,21 @@ NOTE: For optimal performance, the Lotame Panorama Id module should be called at | Param under userSync.userIds[] | Scope | Type | Description | Example | | --- | --- | --- | --- | --- | | name | Required | String | The name of the module | "lotamePanoramaId" | +| params | Required | Object | Configuration options for the Lotame Panorama ID Module | | + | params.clientId | Required | String | The Lotame Client ID provided as part of your registration as noted above | "1001" | {% highlight javascript %} pbjs.setConfig({ userSync: { userIds: [{ name: "lotamePanoramaId", + params: { + clientId: "1001" + } }] } }); {% endhighlight %} + +{: .alert.alert-info :} +NOTE: For optimal performance, the Lotame Panorama Id module should be called at every opportunity. It is best not to use params.storage with this module as the module has its own optimal caching mechanism. From 1a3e54dcdbf9c8e7f7b71c0055047ae1fe8a6877 Mon Sep 17 00:00:00 2001 From: MartianTribe Date: Mon, 3 Apr 2023 11:46:29 -0400 Subject: [PATCH 130/762] Update kargo.md --- dev-docs/bidders/kargo.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/dev-docs/bidders/kargo.md b/dev-docs/bidders/kargo.md index 7b086652..8c9c5002 100644 --- a/dev-docs/bidders/kargo.md +++ b/dev-docs/bidders/kargo.md @@ -10,8 +10,8 @@ gdpr_supported: true userIds: unifiedId usp_supported: true coppa_supported: false -schain_supported: false -dchain_supported: false +schain_supported: true +dchain_supported: true safeframes_ok: false deals_supported: true floors_supported: true From 9f864e797e3974cad1d3a81b5a8d035394a3b9cd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Besse?= Date: Mon, 3 Apr 2023 21:54:26 +0200 Subject: [PATCH 131/762] Adagio: Add documentation for splitKeyword and dataLayer params (#4430) * Add documentation for the splitKeyword and dl params * Update param from `dl` to `dataLayer` - Improve description, fix example.. * Adagio: Update description for dataLayer param --- dev-docs/bidders/adagio.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/dev-docs/bidders/adagio.md b/dev-docs/bidders/adagio.md index 5a56d69f..b4ea493b 100644 --- a/dev-docs/bidders/adagio.md +++ b/dev-docs/bidders/adagio.md @@ -59,7 +59,6 @@ pbjs.bidderSettings = { **Important**: Adagio needs to collect attention data about the ads displayed on a page and must listen to some specifics ad-server events. Please refer to the [Adagio user guide](https://adagioio.notion.site/Adagio-Account-Setup-Guide-fbcd940649224cdfa10393d2f008792e) for details. {: .table .table-bordered .table-striped } - | Name | Scope | Description | Example | Type | | ----------------- | ------------------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------ | -------- | | `organizationId` | required | Id of the Organization. Handed out by Adagio. | `'1010'` | `string` | @@ -70,7 +69,8 @@ pbjs.bidderSettings = { | `category`* | recommended | Category of the content displayed in the page.
- max length: 30
- max distinctives values: 50 | `'sport'` | `string` | | `video` | optional | OpenRTB video options object. All options will override ones defined in mediaTypes video.
Mandatory:
- api (your video player must at least support the value 2 and/or 7)
Highly recommended:
- playbackmethod | `{api: [2, 7], playbackmethod: [6], skip: 1, startdelay: 0}` | | `native` | optional | Partial OpenRTB Native 1.2 request object. Supported fields are:
- context
- plcmttype | `{context: 1, plcmttype: 2}` | `object` | - +| `splitKeyword` | optional | Keyword that can later be used in a split rule targeting to trigger the rule (especially for Direct Seats AB testing) | `'splitrule-one'` | `string` | +| `dataLayer` | optional | A set of arbitrary key-value pairs. This can be used to configure mappings. The keys and values must be strings. | `{placement: 'my-placement', siteid: 'my-siteid'}` | `object` | *These parameters will have its accentuated characters converted to their non-accentuated version: `é` => `e` From 9f75e904e9631626659a0e25300c13d4309cac5e Mon Sep 17 00:00:00 2001 From: Bernhard Pickenbrock Date: Tue, 4 Apr 2023 15:05:27 +0200 Subject: [PATCH 132/762] Smaato: Adapters that accept geolocation data from bid parameters should also accept it from ortb2.(device|user).geo (#9676) (#4455) --- dev-docs/bidders/smaato.md | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/dev-docs/bidders/smaato.md b/dev-docs/bidders/smaato.md index eb7a6667..89e5054c 100644 --- a/dev-docs/bidders/smaato.md +++ b/dev-docs/bidders/smaato.md @@ -211,6 +211,8 @@ Publishers should use the `ortb2` method of setting First Party Data. The follow - ortb2.user.yob - ortb2.user.gender - ortb2.user.ext.eids +- ortb2.device.geo +- ortb2.device.ifa The IAB standard taxonomies are not supported. @@ -230,6 +232,13 @@ pbjs.setConfig({ keywords: "a,b", gender: "M", yob: 1984 + }, + device: { + ifa: "identifier", + geo: { + lat: 53.5488, + lon: 9.9872 + } } } }); From fb9936f421c022e36ed500a60d9435c7bc21596e Mon Sep 17 00:00:00 2001 From: Karim Mourra Date: Wed, 5 Apr 2023 13:16:16 -0300 Subject: [PATCH 133/762] [Video] Add example using Video Module with video.js (#4459) * adds examples for VM * builds * loads script tags * updates sidebar menu * removes jwplayer * updates displayed config to reflect programmatic one * requests bids based on onetrust --- _data/sidebar.yml | 8 + _includes/video/pb-vm-vjs.html | 27 ++ _layouts/video_sample.html | 2 + examples/video/index.md | 6 + .../videojs/video-module-videojs.html | 286 ++++++++++++++++++ 5 files changed, 329 insertions(+) create mode 100644 _includes/video/pb-vm-vjs.html create mode 100644 examples/video/instream/videoModule/videojs/video-module-videojs.html diff --git a/_data/sidebar.yml b/_data/sidebar.yml index b23317f0..8129f229 100644 --- a/_data/sidebar.yml +++ b/_data/sidebar.yml @@ -1275,6 +1275,14 @@ sectionTitle: subgroup: 2 +- sbSecId: 4 + title: 'Prebid Video Module: VideoJS' + link: /examples/video/instream/videoModule/videojs/video-module-videojs.html + isHeader: 0 + isSectionHeader: 0 + sectionTitle: + subgroup: 2 + - sbSecId: 4 title: 'JW Player (Platform)' link: /examples/video/instream/jwplayer/pb-ve-jwplayer-platform.html diff --git a/_includes/video/pb-vm-vjs.html b/_includes/video/pb-vm-vjs.html new file mode 100644 index 00000000..d9237849 --- /dev/null +++ b/_includes/video/pb-vm-vjs.html @@ -0,0 +1,27 @@ + + + + + {% include head--common.html %} + + + + + + + + + + + + + + diff --git a/_layouts/video_sample.html b/_layouts/video_sample.html index e46677cc..c62c9dad 100644 --- a/_layouts/video_sample.html +++ b/_layouts/video_sample.html @@ -6,6 +6,8 @@ {% include /video/pb-is-sb.html %} {% elsif page.videoType == "pb-is-vjs" %} {% include /video/pb-is-vjs.html %} +{% elsif page.videoType == "pb-vm-vjs" %} + {% include /video/pb-vm-vjs.html %} {% elsif page.videoType == "pbs-br" %} {% include /video/pbs-br.html %} {% elsif page.videoType == "pbs-jw01" %} diff --git a/examples/video/index.md b/examples/video/index.md index 4faadf49..67442d0e 100644 --- a/examples/video/index.md +++ b/examples/video/index.md @@ -17,6 +17,12 @@ sidebarType: 4 The following examples are available: +## Prebid Video Module: Instream + +- [VideoJS](/examples/video/instream/videoModule/videojs/video-module-videojs.html) + +## Prebid Video Module: Outstream + ## Instream - [Brightcove](/examples/video/instream/brightcove/pb-ve-brightcove.html) diff --git a/examples/video/instream/videoModule/videojs/video-module-videojs.html b/examples/video/instream/videoModule/videojs/video-module-videojs.html new file mode 100644 index 00000000..513ae2e5 --- /dev/null +++ b/examples/video/instream/videoModule/videojs/video-module-videojs.html @@ -0,0 +1,286 @@ +--- +layout: video_sample +title: Prebid Video Module | Instream Example with VideoJS Submodule +description: An example of an instream pre-roll ad using the Prebid.js Video Module and the VideoJS submodule. +videoType: pb-vm-vjs +isVideo: true +sidebarType: 4 +--- + + +
+
+
+

{{ page.title }}

+

{{page.description }}

+
+ +
+

(Sorry, video code examples aren't available with your cookie privacy settings.)

+

Cookie Settings


+
+ + +
+
+ +{% if jekyll.environment == "production" %} + +{% else %} + +{% endif %} + + + + From 5e28b9444cd8c0d67670c03f6de77bc54913d6b1 Mon Sep 17 00:00:00 2001 From: rajsidhunovatiq <79534312+rajsidhunovatiq@users.noreply.github.com> Date: Thu, 6 Apr 2023 18:12:54 +0100 Subject: [PATCH 134/762] update docs to make it easier for clients (#4452) --- dev-docs/modules/userid-submodules/novatiq.md | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/dev-docs/modules/userid-submodules/novatiq.md b/dev-docs/modules/userid-submodules/novatiq.md index 706e73e2..5d2cd2cd 100644 --- a/dev-docs/modules/userid-submodules/novatiq.md +++ b/dev-docs/modules/userid-submodules/novatiq.md @@ -23,14 +23,17 @@ pbjs.setConfig({ userSync: { userIds: [{ name: 'novatiq', + bidders: [ + `rubicon` + ], params: { // change to the Partner Number you received from Novatiq sourceid '1a3' } } }], - // 50ms maximum auction delay, applies to all userId modules - auctionDelay: 50 + // 1000ms maximum auction delay, applies to all userId modules + auctionDelay: 1000 } }); {% endhighlight %} @@ -42,7 +45,7 @@ pbjs.setConfig({ | --- | --- | --- | --- | --- | | name | Required | String | Module identification: `"novatiq"` | `"novatiq"` | | params | Required | Object | Configuration specifications for the Novatiq module. | | -| params.sourceid | Required | String | This is the Novatiq Partner Number obtained via Novatiq registration. | `1a3` | +| params.sourceid | Required (if applicable) | String | This is the Novatiq Partner Number obtained via Novatiq registration. | `1a3` | | params.useSharedId | Optional | Boolean | Use the sharedID module if it's activated. | `true` | | params.sharedIdName | Optional | String | Same as the SharedID "name" parameter
Defaults to "_pubcid" | `"demo_pubcid"` | | params.useCallbacks | Optional | Boolean | Use callbacks for custom integrations | `false` | @@ -72,6 +75,9 @@ pbjs.setConfig({ userIds: [ { name: 'novatiq', + bidders: [ + `rubicon` + ], params: { // change to the Partner Number you received from Novatiq sourceid '1a3', @@ -85,8 +91,8 @@ pbjs.setConfig({ } } }], - // 50ms maximum auction delay, applies to all userId modules - auctionDelay: 50 + // 1000ms maximum auction delay, applies to all userId modules + auctionDelay: 1000 } }); {% endhighlight %} From 5d3370bfe25eecf37be921b44d7bd71dfc046d67 Mon Sep 17 00:00:00 2001 From: asurovenko-zeta <80847074+asurovenko-zeta@users.noreply.github.com> Date: Mon, 10 Apr 2023 18:00:50 +0200 Subject: [PATCH 135/762] ZetaGlobalSsp adapter: tagid in doc (#4470) Co-authored-by: Surovenko Alexey --- dev-docs/bidders/zeta_global_ssp.md | 1 + 1 file changed, 1 insertion(+) diff --git a/dev-docs/bidders/zeta_global_ssp.md b/dev-docs/bidders/zeta_global_ssp.md index a56068b4..6acb845a 100644 --- a/dev-docs/bidders/zeta_global_ssp.md +++ b/dev-docs/bidders/zeta_global_ssp.md @@ -29,6 +29,7 @@ The Zeta Global SSP adapter requires setup and approval from the Zeta Global SSP |----------------------|----------|---------------------------------------------------------------------------------------------------------------------|--------------|-----------| | `sid` | required | Seller ID. The identifier associated with the seller or reseller account within the advertising system | `"sid123"` | `string` | | `shortname` | required | Publisher Name. The unique name associated with the seller or reseller account within the advertising system | `"pub_name"` | `string` | +| `tagid` | required | Identifier for specific ad placement or ad tag that was used to initiate the auction | `"123877"` | `string` | | `tags` | optional | The object containing set of Zeta's custom tags witch publisher have to supply | `tags: {}` | `object` | | `site` | optional | The object containing site data (See OpenRTB spec) | `site: {}` | `object` | | `app` | optional | The object containing app data (See OpenRTB spec) | `app: {}` | `object` | From f32dd2b435598447c05452973b13f73e98f330f5 Mon Sep 17 00:00:00 2001 From: Denis Logachov Date: Mon, 10 Apr 2023 20:01:19 +0300 Subject: [PATCH 136/762] Adkernel: documenting adliveconnect alias (#4451) * Adkernel: documenting adliveconnect alias * Update adlive.md * Rename adlive.md to adliveconnect.md --- dev-docs/bidders/adliveconnect.md | 34 +++++++++++++++++++++++++++++++ 1 file changed, 34 insertions(+) create mode 100644 dev-docs/bidders/adliveconnect.md diff --git a/dev-docs/bidders/adliveconnect.md b/dev-docs/bidders/adliveconnect.md new file mode 100644 index 00000000..fd730d84 --- /dev/null +++ b/dev-docs/bidders/adliveconnect.md @@ -0,0 +1,34 @@ +--- +layout: bidder +title: Adliveconnect +description: Adliveconnect Bidder Adaptor +biddercode: adliveconnect +pbjs: true +pbs: false +media_types: banner, native, video +gdpr_supported: true +usp_supported: true +coppa_supported: true +pbs_app_supported: false +schain_supported: true +userIds: all +fpd_supported: true +prebid_member: false +ortb_blocking_supported: true +multiformat_supported: will-bid-on-one +floors_supported: true +aliasCode: adkernel +sidebarType: 1 +--- + +### Note: + +The Adlive bidding adapter requires setup and approval before implementation. Please reach out to for more details. + +### Bid Params + +{: .table .table-bordered .table-striped } +| Name | Scope | Description | Example | Type | +|----------|----------|-----------------------|---------------------------|----------| +| `host` | required | RTB host | `'cpm.adlive.io'` | `string` | +| `zoneId` | required | Zone Id | 30164 | `integer` | From 0f087273b90caa5638100990eb27e95835efb442 Mon Sep 17 00:00:00 2001 From: Demetrio Girardi Date: Mon, 10 Apr 2023 10:23:36 -0700 Subject: [PATCH 137/762] PBJS: document new `storageAllowed` options (#4466) --- dev-docs/publisher-api-reference/bidderSettings.md | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/dev-docs/publisher-api-reference/bidderSettings.md b/dev-docs/publisher-api-reference/bidderSettings.md index d7d9e8c3..2da634a2 100644 --- a/dev-docs/publisher-api-reference/bidderSettings.md +++ b/dev-docs/publisher-api-reference/bidderSettings.md @@ -46,7 +46,7 @@ Some sample scenarios where publishers may wish to alter the default settings: | sendStandardTargeting | adapter-specific | 0.13.0 | true | If adapter-specific targeting is specified, can be used to suppress the standard targeting for that adapter. | | suppressEmptyKeys | standard or adapter-specific | 0.13.0 | false | If custom adserverTargeting functions are specified that may generate empty keys, this can be used to suppress them. | | allowZeroCpmBids | standard or adapter-specific | 6.2.0 | false | Would allow bids with a 0 CPM to be accepted by Prebid.js and could be passed to the ad server. | -| storageAllowed | standard or adapter-specific | 6.13.0 | true in 6.x, false after 7.0 | Allow use of cookies and local storage. | +| storageAllowed | standard or adapter-specific | 6.13.0 | true in 6.x, false after 7.0 | Allow use of cookies and/or local storage. | | allowAlternateBidderCodes | standard or adapter-specific | 6.23.0 | true in v6.x
false from v7.0| Allow adapters to bid with alternate bidder codes. | | allowedAlternateBidderCodes | standard or adapter-specific | 6.23.0 | n/a | Array of bidder codes for which an adapter can bid.
`undefined` or `['*']` will allow adapter to bid with any bidder code. | @@ -262,7 +262,12 @@ either specific bid adapter(s) or all bid adapters the permission for these bids ##### 2.7. storageAllowed -This flag defines if the bid adapter can access browser cookies and local storage. +This setting defines if the bid adapter can access browser cookies or local storage. Allowed values are: + + - an array containing either `'html5'`, `'cookie'` or both to allow specific storage methods (e.g. `['cookie']` enables cookies but not local storage) + - `true` to allow any storage method; + - `false` to disable all storage. +
Default value is `true` in version 6.x
Default value is `false` in version 7.x From 2d2d1f685569aea674a38d0b1d55ef1b68f8e7f3 Mon Sep 17 00:00:00 2001 From: Nisar Thadathil Date: Tue, 11 Apr 2023 00:02:47 +0530 Subject: [PATCH 138/762] Updated documentation for Vidoomy Schain support (#4465) --- dev-docs/bidders/vidoomy.md | 1 + 1 file changed, 1 insertion(+) diff --git a/dev-docs/bidders/vidoomy.md b/dev-docs/bidders/vidoomy.md index 39599b47..aba41d23 100644 --- a/dev-docs/bidders/vidoomy.md +++ b/dev-docs/bidders/vidoomy.md @@ -11,6 +11,7 @@ usp_supported: true coppa_supported: true pbs: true sidebarType: 1 +schain_supported: true --- ### Note: From d4a52676dd53b1b7a215873e56d2565bf377fb35 Mon Sep 17 00:00:00 2001 From: abermanov-zeta <95416296+abermanov-zeta@users.noreply.github.com> Date: Tue, 11 Apr 2023 16:53:03 +0200 Subject: [PATCH 139/762] Documentation: Zeta Global SSP Prebid Server Adapter. (#4464) --- dev-docs/bidders/zeta_global_ssp.md | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/dev-docs/bidders/zeta_global_ssp.md b/dev-docs/bidders/zeta_global_ssp.md index 6acb845a..f38f2430 100644 --- a/dev-docs/bidders/zeta_global_ssp.md +++ b/dev-docs/bidders/zeta_global_ssp.md @@ -1,11 +1,12 @@ --- layout: bidder -title: Zeta Global Ssp -description: Zeta Global Ssp Prebid Bidder Adapter +title: Zeta Global SSP +description: Zeta Global SSP Prebid Bidder Adapter pbjs: true +pbs: true biddercode: zeta_global_ssp deals_supported: false -media_types: banner +media_types: banner, video gdpr_supported: true usp_supported: true coppa_supported: true @@ -24,6 +25,8 @@ The Zeta Global SSP adapter requires setup and approval from the Zeta Global SSP ### Bid Params +#### Prebid.js Bid Params + {: .table .table-bordered .table-striped } | Name | Scope | Description | Example | Type | |----------------------|----------|---------------------------------------------------------------------------------------------------------------------|--------------|-----------| @@ -35,3 +38,9 @@ The Zeta Global SSP adapter requires setup and approval from the Zeta Global SSP | `app` | optional | The object containing app data (See OpenRTB spec) | `app: {}` | `object` | | `bidfloor` | optional | The minimum bid value desired | `0.2` | `float` | | `test` | optional | Flag which will induce a sample bid response when true; only set to true for testing purposes (1 = true, 0 = false) | `1` | `integer` | + + +#### Prebid Server Bid Params + +Prebid Server Adapter does not support any parameters. +You must get `sid` and `shortname` values from Zeta Global and use them instead of placeholders in the URL. From 5c5da95e504df5c38a0164872d5e746c38a6ab1b Mon Sep 17 00:00:00 2001 From: Jean-Baptiste Date: Tue, 11 Apr 2023 18:51:53 +0200 Subject: [PATCH 140/762] add greenbids analytics documentation (#4427) * add greenbids analytics documentation * fix typo and allow download --- dev-docs/analytics/greenbids.md | 33 +++++++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) create mode 100644 dev-docs/analytics/greenbids.md diff --git a/dev-docs/analytics/greenbids.md b/dev-docs/analytics/greenbids.md new file mode 100644 index 00000000..189726a3 --- /dev/null +++ b/dev-docs/analytics/greenbids.md @@ -0,0 +1,33 @@ +--- +layout: analytics +title: Greenbids +description: Greenbids Analytics Adapter +modulecode: greenbids +prebid_member: false +enable_download: true +--- + +#### Registration + +The Greenbids Analytics adapter requires setup and approval from the +Greenbids team. Please reach out to our team for more information [https://greenbids.ai](https://greenbids.ai). + +#### Analytics Options + +{: .table .table-bordered .table-striped } +| Name | Scope | Description | Example | Type | +|-------------|---------|--------------------|-----------------------------------------------------------------------------------------------------------------------------|-------------------------------------------------------------------------------------|------------------| +| pbuid | required | The Greenbids Publisher ID | greenbids-publisher-1 | string | +| sampling | optional | sampling factor [0-1] (a value of 0.1 will filter 90% of the traffic) | 0.5 | float | + +### Example Configuration + +``` + pbjs.enableAnalytics({ + provider: 'greenbids', + options: { + pbuid: "greenbids-publisher-1" // please contact Greenbids to get a pbuid for yourself + sampling: 1.0 + } + }); +``` From db6a0e70c955e3eaa3ede8309ec681d45728fb2b Mon Sep 17 00:00:00 2001 From: Patrick Loughrey Date: Tue, 11 Apr 2023 12:56:07 -0400 Subject: [PATCH 141/762] Triplelift: Update video parameters requirement (#4478) * TL-34447 Add GPP Support to Prebid.org * TL-27059: Added pDMP documentation * Update triplelift.md * Triplelift: Update video params --------- Co-authored-by: bretg --- dev-docs/bidders/triplelift.md | 1 + 1 file changed, 1 insertion(+) diff --git a/dev-docs/bidders/triplelift.md b/dev-docs/bidders/triplelift.md index a3e0a762..109444a6 100644 --- a/dev-docs/bidders/triplelift.md +++ b/dev-docs/bidders/triplelift.md @@ -70,6 +70,7 @@ See the [Ad Unit Reference](https://docs.prebid.org/dev-docs/adunit-reference.ht | Name | Scope | Description | Example | Type | |-----------------|------------------------------|--------------------------------------------------------------------------------------|---------------------------------------------|----------| | `adUnit.mediaTypes.video.placement` | required | Instream: 1; Outstream: 3, 4, 5. | `3` | `int` | +| `adUnit.mediaTypes.video.playerSize` | required | Video player dimensions or size in pixels | `[640, 480]` | `integer array` | From 59c97c65ddaa3fd753d6d696600a3b3f96ef67ab Mon Sep 17 00:00:00 2001 From: dzhang-criteo <87757739+dzhang-criteo@users.noreply.github.com> Date: Thu, 13 Apr 2023 15:43:52 +0200 Subject: [PATCH 142/762] Criteo: update doc (#4480) Specify support of GPP --- dev-docs/bidders/criteo.md | 1 + 1 file changed, 1 insertion(+) diff --git a/dev-docs/bidders/criteo.md b/dev-docs/bidders/criteo.md index 02509f03..c26f00e2 100644 --- a/dev-docs/bidders/criteo.md +++ b/dev-docs/bidders/criteo.md @@ -17,6 +17,7 @@ gvl_id: 91 coppa_supported: true multiformat_supported: will-bid-on-any sidebarType: 1 +gpp_supported: true --- ### Notes From a70d08e4287b52c9466a327ab4ffdad75779d1fd Mon Sep 17 00:00:00 2001 From: SmartyAdman <59048845+SmartyAdman@users.noreply.github.com> Date: Fri, 14 Apr 2023 00:27:50 +0300 Subject: [PATCH 143/762] Adman Adapter: text edit only (#4483) * Add adman dev doc * Change params Params required by new adapter setup * Edit docs Fix naming, use quotes around example * adding quotes to string param * Update adman.md * tcf2_supported: true * Update adman.md add usp support * Add api param for prebid servr adapter * updates for prebid 5.0, and support uid2 * add Lotame Panorama ID * add idx (UserID Module) * edit schain_support --------- Co-authored-by: minoru katogi Co-authored-by: ADman Media Co-authored-by: bretg Co-authored-by: Aiholkin --- dev-docs/bidders/adman.md | 1 + 1 file changed, 1 insertion(+) diff --git a/dev-docs/bidders/adman.md b/dev-docs/bidders/adman.md index 4bb430f0..55e07ac6 100644 --- a/dev-docs/bidders/adman.md +++ b/dev-docs/bidders/adman.md @@ -7,6 +7,7 @@ pbs: true biddercode: adman gdpr_supported: true usp_supported: true +schain_supported: true media_types: banner, video, native userIds: uid2, lotamePanoramaId, idx sidebarType: 1 From 16f228cf15c5dbb044de6d723b0c399c7c118090 Mon Sep 17 00:00:00 2001 From: Samuel Adu Date: Fri, 14 Apr 2023 14:13:44 +0100 Subject: [PATCH 144/762] Updated documentation for Yahoo ConnectID UserID module (#4456) Co-authored-by: slimkrazy --- dev-docs/modules/userid-submodules/yahoo.md | 94 +++++++++------------ 1 file changed, 38 insertions(+), 56 deletions(-) diff --git a/dev-docs/modules/userid-submodules/yahoo.md b/dev-docs/modules/userid-submodules/yahoo.md index f6e86cb9..706988b7 100644 --- a/dev-docs/modules/userid-submodules/yahoo.md +++ b/dev-docs/modules/userid-submodules/yahoo.md @@ -5,41 +5,30 @@ description: Yahoo ConnectID User ID sub-module useridmodule: connectIdSystem --- -Yahoo ConnectID is a person based ID and does not depend on 3rd party cookies. It enables ad tech platforms to recognize and match users consistently across the open web. Built on top of Yahoo’s robust and proprietary ID Graph it delivers a higher find rate of audiences on publishers’ sites user targeting that respects privacy. +Yahoo ConnectID is a person based ID and does not depend on 3rd party cookies. It enables ad tech platforms to recognize and match users consistently across the open web. Built on top of Yahoo's robust and proprietary ID Graph it delivers higher monetization while respecting user privacy via multiple controls. -## Honoring Privacy Choices - -Yahoo ConnectID provides multiple mechanisms for users to manage their privacy choices. Users can manage their choices via [ConnectID Control Portal](http://connectid.yahoo.com), on the [Yahoo Privacy Dashboard](https://legal.yahoo.com/us/en/yahoo/privacy/dashboard/index.html) and [NAI’s Audience Matched Opt Out page](https://optout.networkadvertising.org/optout/email). No further actions are required by Publishers as Yahoo will ensure that privacy choices selected by users via one of these methods are honored. We will automatically stop generating ConnectIDs for users who have opted-out. - -When desired, additional privacy control can be provided to your users. Within your privacy policy or website privacy settings, [Create an Easy Opt-in Opt-out Toggle](https://documentation.help.yahooinc.com/platform/SSP/Sellers/Integrate/Create-an-Easy-OptIn-Optout-Toggle.htm) for ConnectID. - -Finally, ConnectID follows all global privacy laws (such as the CCPA) and industry frameworks (such as NAI, DAA and IAB). Yahoo will auto-detect most privacy signals present on the page (including those set by prebid libraries) and not generate a ConnectID for users that have opted-out. +Add support for Yahoo ConnectID to your Prebid.js package using: +{: .alert.alert-info :} +gulp build --modules=userId,connectIdSystem ## Yahoo ConnectID Registration -A Yahoo supplied publisher specific pixel Id is required. Please reach out to your account manager for assistance with setup. - -Add support for Yahoo ConnectID to your Prebid.js package with: - -{: .alert.alert-info :} -gulp build --modules=userId,connectIdSystem +A Yahoo-supplied publisher-specific pixel ID is required. Reach out to [connectid.support@yahooinc.com](mailto:connectid.support@yahooinc.com) for assistance with setup. ## Yahoo ConnectID Configuration +Note: Parameters are case-sensitive. ConnectID is the proper name of our product, however, when used in code it is spelled as connect**I**d. Follow the example in the table below.
| Param under userSync.userIds[] | Scope | Type | Description | Example | | --- | --- | --- | --- | --- | -| name | Required | String | The name of this module. | `'connectId'` | +| name | Required | String | The name of this module. | `"connectId"` | | params | Required | Object | Container of all module params. || -| params.pixelId | Required | Number | The Yahoo supplied publisher specific pixel Id | `8976` | -| params.he | Optional | String | The SHA-256 hashed user email address. One of either the `he` parameter or the `puid` parameter must be supplied. |`'ed8ddbf5a171981db8ef938596ca297d5e3f84bcc280041c5880dba3baf9c1d4'`| -| params.puid | Optional | String | The publisher-supplied user identifier. One of either the `he` parameter or the `puid` parameter must be supplied. | `"P-975484817"` | -| storage | Required | Object | Defines where and for how long the results of the call to get a user ID will be stored. | | -| storage.type | Required | String | Defines where the resolved user ID will be stored (either `'cookie'` or `'html5'` localstorage).| `'html5'` | -| storage.name | Required | String | The name of the cookie or html5 localstorage where the resolved user ID will be stored. | `'connectId'` | -| storage.expires | Recommended | Integer | How long (in days) the user ID information will be stored. The recommended value is `15` | `15` | +| params.pixelId | Required | Number | +The Yahoo-supplied publisher-specific pixel ID. | `"0000"` | +| params.he | Optional | String | The SHA-256 hashed user email address which has been lowercased prior to hashing. Pass both `he` and `puid` params if present, otherwise pass either of the two that is available. |`"ed8ddbf5a171981db8ef938596ca297d5e3f84bcc280041c5880dba3baf9c1d4"`| +| params.puid | Optional | String | The publisher supplied user identifier such as a first-party cookie. Pass both `he` and `puid` params if present, otherwise pass either of the two that is available. | `"ab9iibf5a231ii1db8ef911596ca297d5e3f84biii00041c5880dba3baf9c1da"` | {: .table .table-bordered .table-striped }
@@ -47,19 +36,15 @@ gulp build --modules=userId,connectIdSystem ## Yahoo ConnectID Examples ``` -// [Sample #1]: Using a hashed email. +// [Sample #1]: Using a hashed email only. + pbjs.setConfig({ userSync: { userIds: [{ name: "connectId", params: { - pixelId: 8976, + pixelId: "0000", he: "ed8ddbf5a171981db8ef938596ca297d5e3f84bcc280041c5880dba3baf9c1d4" - }, - storage: { - type: "html5", - name: "connectId", - expires: 15 } }] } @@ -67,42 +52,39 @@ pbjs.setConfig({ ``` ``` -// [Sample #2]: Using a publisher-supplied user identifier. -pbjs.setConfig({ - userSync: { - userIds: [{ - name: "connectId", - params: { - pixelId: 8976, - puid: "P-975484817" - }, - storage: { - type: "html5", - name: "connectId", - expires: 15 - } - }] - } -}) -``` +// [Sample #2]: Using a hashed email and a publisher-supplied user identifier such as a first-party cookie. -``` -// [Sample #3]: Using a hashed email and a publisher-supplied user identifier. pbjs.setConfig({ userSync: { userIds: [{ name: "connectId", params: { - pixelId: 8976, + pixelId: "0000", he: "ed8ddbf5a171981db8ef938596ca297d5e3f84bcc280041c5880dba3baf9c1d4", - puid: "P-975484817" - }, - storage: { - type: "html5", - name: "connectId", - expires: 15 + puid: "ab9iibf5a231ii1db8ef911596ca297d5e3f84biii00041c580dba3baf9c1da" } }] } }) ``` + +## Honoring Privacy Choices + +Yahoo ConnectID provides multiple mechanisms for users to manage their privacy choices. Users can manage their choices via [ConnectID Control Portal](http://connectid.yahoo.com), on the [Yahoo Privacy Dashboard](https://legal.yahoo.com/us/en/yahoo/privacy/dashboard/index.html) and [NAI’s Audience Matched Opt Out page](https://optout.networkadvertising.org/optout/email). No further actions are required by Publishers as Yahoo will ensure that privacy choices selected by users via one of these methods are honored. We will automatically stop generating ConnectIDs for users who have opted-out. + +When desired, additional privacy control can be provided to your users. Within your privacy policy or website privacy settings, [Create an Easy Opt-in Opt-out Toggle](https://documentation.help.yahooinc.com/platform/SSP/Sellers/Integrate/Create-an-Easy-OptIn-Optout-Toggle.htm) for ConnectID. + +Finally, ConnectID follows all global privacy laws (such as the CCPA) and industry frameworks (such as NAI, DAA and IAB). Yahoo will auto-detect most privacy signals present on the page (including those set by Prebid libraries) and not generate a ConnectID for users that have opted-out. + +## Yahoo ConnectID Optional Parameters +Please note that the storage related parameters are optional. We recommend that you omit them, since ConnectID module is pre-configured with the most optimal storage parameters already. + +
+| Param under userSync.userIds[] | Scope | Type | Description | Example | +| --- | --- | --- | --- | --- | +| storage | Optional | Object | Defines where and for how long the results of the call to get a user ID will be stored. | | +| storage.type | Optional | String | Defines where the resolved user ID will be stored (either `'cookie'` or `'html5'` local storage).| `'cookie'` | +| storage.name | Optional | String | The name of the cookie or html5 local storage where the resolved user ID will be stored. | `'connectId'` | +| storage.expires | Optional | Integer | How long (in days) the user ID information will be stored. | `15` | +{: .table .table-bordered .table-striped } +
From f5cdf0cc7033458839265d26694958a6f6486124 Mon Sep 17 00:00:00 2001 From: Demetrio Girardi Date: Fri, 14 Apr 2023 06:25:05 -0700 Subject: [PATCH 145/762] PBJS: document new option for RTD submodules (#4467) --- dev-docs/add-rtd-submodule.md | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/dev-docs/add-rtd-submodule.md b/dev-docs/add-rtd-submodule.md index 7ac56b2a..b2c118c0 100644 --- a/dev-docs/add-rtd-submodule.md +++ b/dev-docs/add-rtd-submodule.md @@ -90,13 +90,14 @@ In order to let RTD-core know where to find the functions in your sub-module, cr | param name | type | Scope | Description | Params | | :------------ | :------------ | :------ | :------ | :------ | | name | string | required | must match the name provided by the publisher in the on-page config | n/a | -| init | function | required | defines the function that does any auction-level initialization required | config, userConsent | -| getTargetingData | function | optional | defines a function that provides ad server targeting data to RTD-core | adUnitArray, config, userConsent | -| getBidRequestData | function | optional | defines a function that provides bid request data to RTD-core | reqBidsConfigObj, callback, config, userConsent | -| onAuctionInitEvent | function | optional | listens to the AUCTION_INIT event and calls a sub-module function that lets it inspect and/or update the auction | auctionDetails, config, userConsent | -| onAuctionEndEvent | function |optional | listens to the AUCTION_END event and calls a sub-module function that lets it know when auction is done | auctionDetails, config, userConsent | -| onBidRequestEvent | function |optional | listens to the BID_REQUESTED event and calls a sub-module function that lets it know when a bid is about to be requested | bidRequest, config, userConsent | -| onBidResponseEvent | function |optional | listens to the BID_RESPONSE event and calls a sub-module function that lets it know when a bid response has been collected | bidResponse, config, userConsent | +| gvlid | number | optional | global vendor list ID for your submodule | n/a | +| init | function | required | defines the function that does any auction-level initialization required | config, userConsent | +| getTargetingData | function | optional | defines a function that provides ad server targeting data to RTD-core | adUnitArray, config, userConsent | +| getBidRequestData | function | optional | defines a function that provides bid request data to RTD-core | reqBidsConfigObj, callback, config, userConsent | +| onAuctionInitEvent | function | optional | listens to the AUCTION_INIT event and calls a sub-module function that lets it inspect and/or update the auction | auctionDetails, config, userConsent | +| onAuctionEndEvent | function |optional | listens to the AUCTION_END event and calls a sub-module function that lets it know when auction is done | auctionDetails, config, userConsent | +| onBidRequestEvent | function |optional | listens to the BID_REQUESTED event and calls a sub-module function that lets it know when a bid is about to be requested | bidRequest, config, userConsent | +| onBidResponseEvent | function |optional | listens to the BID_RESPONSE event and calls a sub-module function that lets it know when a bid response has been collected | bidResponse, config, userConsent | For example: {% highlight text %} From 43ddf51c6d8e192d48053ea356c94c5b4327f8bd Mon Sep 17 00:00:00 2001 From: Brett Bloxom <38990705+BrettBlox@users.noreply.github.com> Date: Fri, 14 Apr 2023 07:41:37 -0600 Subject: [PATCH 146/762] Updates documentation for concert gpp support (#2) (#4437) --- dev-docs/bidders/concert.md | 1 + 1 file changed, 1 insertion(+) diff --git a/dev-docs/bidders/concert.md b/dev-docs/bidders/concert.md index d9a45e87..79a6bdba 100644 --- a/dev-docs/bidders/concert.md +++ b/dev-docs/bidders/concert.md @@ -8,6 +8,7 @@ biddercode: concert media_types: banner gdpr_supported: true usp_supported: true +gpp_supported: true sidebarType: 1 --- From 986885a050610b6a188f444cd69a5d21c4a136b7 Mon Sep 17 00:00:00 2001 From: Patrick McCann Date: Fri, 14 Apr 2023 11:21:47 -0400 Subject: [PATCH 147/762] Update firstPartyData.md (#4468) --- features/firstPartyData.md | 28 +++++++++++++++++++++++++--- 1 file changed, 25 insertions(+), 3 deletions(-) diff --git a/features/firstPartyData.md b/features/firstPartyData.md index bcca76f2..02b8b2f1 100644 --- a/features/firstPartyData.md +++ b/features/firstPartyData.md @@ -75,15 +75,13 @@ pbjs.setConfig({ }] }, ext: { - data: { // fields that aren't part of openrtb 2.5 + data: { // fields that aren't part of openrtb 2.6 pageType: "article", category: "repair" } } }, user: { - yob: 1985, - gender: "m", keywords: "a,b", data: [{ name: "dataprovider.com", @@ -169,6 +167,30 @@ pbjs.addAdUnits({ }); {% endhighlight %} +Another case is [declaring rewarded](https://github.com/InteractiveAdvertisingBureau/openrtb2.x/blob/422eedb76e8730c89dcac75c7427c18cfa10e8c4/2.6.md?plain=1#L993). Here is how one might do that: + + +{% highlight js %} +pbjs.addAdUnits({ + code: "test-div-rewarded", + mediaTypes: { + banner: { + sizes: [[300,250]] + } + }, + ortb2Imp: { + rwdd: 1, + ext: { + data: { + pbadslot: "my-rewarded-rectangle", + adUnitSpecificAttribute: "123" + } + } + }, + ... +}); +{% endhighlight %} + You may also specify adUnit-specific transaction IDs using `ortb2Imp.ext.tid`, and Prebid will use them instead of generating random new ones. This is useful if you are auctioning the same slots through multiple header bidding libraries. Note: you must take care to not re-use the same transaction IDs across different ad units or auctions. Here's a simplified example passing a tid through the [requestBids](/dev-docs/publisher-api-reference/requestBids.html) function: {% highlight js %} From 56a37de05d24be7d64ffacd2e930213d44010f6d Mon Sep 17 00:00:00 2001 From: Gaudeamus Date: Fri, 14 Apr 2023 18:40:11 +0300 Subject: [PATCH 148/762] update mgid adapter adding support of user sync & ortb2 (#4463) Co-authored-by: gaudeamus --- dev-docs/bidders/mgid.md | 38 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 38 insertions(+) diff --git a/dev-docs/bidders/mgid.md b/dev-docs/bidders/mgid.md index 8f765879..d52a4baf 100644 --- a/dev-docs/bidders/mgid.md +++ b/dev-docs/bidders/mgid.md @@ -7,7 +7,11 @@ pbs: true biddercode: mgid media_types: banner,native gdpr_supported: true +usp_supported: true gvl_id: 358 +floors_supported: true +ortb_blocking_supported: partial +multiformat_supported: will-bid-on-any sidebarType: 1 --- @@ -17,6 +21,7 @@ sidebarType: 1 - [Description](#description) - [Bid params](#bid-params) - [Test Parameters](#test-parameters) +- [User Sync](#user-sync)
@@ -114,3 +119,36 @@ var adUnits = [{ }] }]; ``` + + + +### User Sync + +Mgid recommends UserSync configuration to be enabled. Without it, Mgid adapter will not be able to perform user syncs, which lowers match rate and reduces monetization. + +For Prebid.js v1.15.0 and later: + +```javascript +pbjs.setConfig({ + userSync: { + filterSettings: { + iframe: { + bidders: '*', // '*' represents all bidders + filter: 'include' + } + } + } +}); +``` + +For Prebid.js v1.14.0 and before: + +```javascript +pbjs.setConfig({ + userSync: { + iframeEnabled: true, + enabledBidders: ['mgid'] + }}); +``` + +Note: Combine the above configuration with any other UserSync configuration. Multiple setConfig() calls overwrite each other and only the last call for a given attribute will take effect. From 314a080fedf3aa2b4e691ab152bd06770eb290da Mon Sep 17 00:00:00 2001 From: Jason Quaccia Date: Fri, 14 Apr 2023 12:14:01 -0700 Subject: [PATCH 149/762] documentation for batch video cache requests (#4453) --- dev-docs/publisher-api-reference/setConfig.md | 21 +++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/dev-docs/publisher-api-reference/setConfig.md b/dev-docs/publisher-api-reference/setConfig.md index 916815fc..eadf9a5f 100644 --- a/dev-docs/publisher-api-reference/setConfig.md +++ b/dev-docs/publisher-api-reference/setConfig.md @@ -1204,6 +1204,8 @@ be retrieved. There are two different flows possible with Prebid.js around VAST | cache.timeout | no | number | Timeout (in milliseconds) for network requests to the cache | | cache.vasttrack | no | boolean | Passes additional data to the url, used for additional event tracking data. Defaults to `false`. | | cache.ignoreBidderCacheKey | no | boolean | If the bidder supplied their own cache key, setting this value to true adds a VAST wrapper around that URL, stores it in the cache defined by the `url` parameter, and replaces the original video cache key with the new one. This can dramatically simplify ad server setup because it means all VAST creatives reside behind a single URL. The tradeoff: this approach requires the video player to unwrap one extra level of VAST. Defaults to `false`. | +| cache.batchSize | no | number | Enables video cache requests to be batched by a specified amount (defaults to 1) instead of making a single request per each video. | +| cache.batchTimeout | no | number | Used in conjunction with `batchSize`, `batchTimeout` specifies how long to wait in milliseconds before sending a batch video cache request based on the value for `batchSize` (if present). A batch request will be made whether the `batchSize` amount was reached or the `batchTimeout` timer runs out. `batchTimeout` defaults to 0. | Here's an example of basic client-side caching. Substitute your Prebid Cache URL as needed: @@ -1250,6 +1252,25 @@ Setting the `vasttrack` parameter to `true` supplies the POST made to the `/vtra Prebid Server endpoint with a couple of additional parameters needed by the analytics system to join the event to the original auction request. +Optionally, `batchSize` and `batchTimeout` can be utlilized as illustrated with the example below: + +{% highlight js %} +pbjs.setConfig({ + cache: { + url: 'https://prebid.adnxs.com/pbc/v1/cache', + batchSize: 4, + batchTimeout: 50 + } +}); +{% endhighlight %} + +The example above states that a timer will be initialized and wait up to 50ms for 4 responses to have been collected and then will fire off one batch video cache request for all 4 responses. Note that the batch request will be made when the specified `batchSize` number is reached or with the number of responses that could be collected within the timeframe specified by the value for `batchTimeout`. + +If a batchSize is set to 2 and 5 video responses arrive (within the timeframe specified by `batchTimeout`), then three batch requests in total will be made: +1. Batch 1 will contain cache requests for 2 videos +2. Batch 2 will contain cache requests for 2 videos +3. Batch 3 will contain cache requests for 1 video + #### Instream tracking From 3d94d938b8c38499426854edb2fd92f94335d177 Mon Sep 17 00:00:00 2001 From: Elad Yosifon Date: Fri, 14 Apr 2023 23:02:43 +0300 Subject: [PATCH 150/762] Update KueezRTB and Kueez docs (#4461) * Update KueezRTB and Kueez docs * Update KueezRTB and Kueez docs --- dev-docs/bidders/kueez.md | 72 +++--------------------------------- dev-docs/bidders/kueezrtb.md | 40 +++++++++++++++++++- 2 files changed, 44 insertions(+), 68 deletions(-) diff --git a/dev-docs/bidders/kueez.md b/dev-docs/bidders/kueez.md index f782abee..033c9093 100644 --- a/dev-docs/bidders/kueez.md +++ b/dev-docs/bidders/kueez.md @@ -1,6 +1,6 @@ --- layout: bidder -title: Kueez +title: Kueez (Go To KueezRTB) description: Prebid Kueez Bidder Adapter multiformat_supported: will-bid-on-any pbjs: true @@ -15,69 +15,9 @@ fpd_supported: true sidebarType: 1 --- -### Note +### IMPORTANT NOTICE! +**TL;DR** +The `kueez` adapter is currently "on hold" in favor of `kueezrtb`. +Please contact your Account Manager/Executive for details. -The Kueez adapter requires setup and approval. Please reach out to prebid@kueez.com. - -### Bid Parameters - -#### Banner, Video - -{: .table .table-bordered .table-striped } -| Name | Scope | Type | Description | Example -| ---- | ----- | ---- | ----------- | ------- -| `org` | required | String | the organization Id provided by your Kueez representative | "test-org-id" -| `floorPrice` | optional | Number | Minimum price in USD. Misuse of this parameter can impact revenue | 1.5 -| `placementId` | optional | String | A unique placement identifier | "12345678" -| `testMode` | optional | Boolean | This activates the test mode | false - -## Example - ```javascript -var adUnits = [{ - code: 'banner-div', - mediaTypes: { - banner: { - sizes: [ - [300, 250], - [728, 90] - ] - } - }, - bids: [{ - bidder: 'kueez', - params: { - org: 'test-org-id', // Required - floorPrice: 1.2, // Optional - placementId: '12345678', // Optional - testMode: true // Optional - } - }] - }, - { - code: 'dfp-video-div', - sizes: [ - [640, 480] - ], - mediaTypes: { - video: { - playerSize: [ - [640, 480] - ], - context: 'instream' - } - }, - bids: [{ - bidder: 'kueez', - params: { - org: 'test-org-id', // Required - floorPrice: 1.50, // Optional - placementId: '12345678', // Optional - testMode: true // Optional - } - }] - } -]; -``` - -### Configuration -Kueez recommends setting UserSync by iframe for monetization. +Go To KueezRTB diff --git a/dev-docs/bidders/kueezrtb.md b/dev-docs/bidders/kueezrtb.md index 2ef4bc25..36e944d5 100644 --- a/dev-docs/bidders/kueezrtb.md +++ b/dev-docs/bidders/kueezrtb.md @@ -31,5 +31,41 @@ sidebarType: 1 |------------|----------|-------------------------------------------------------------------------------------------|------------------------------|----------| | `cId` | required | The connection ID from KueezRTB. | `'562524b21b1c1f08117fc7f9'` | `string` | | `pId` | required | The publisher ID from KueezRTB. | `'59ac17c192832d0011283fe3'` | `string` | -| `bidFloor` | required | The minimum bid value desired. KueezRTB will not respond with bids lower than this value. | `0.90` | `float` | -| `subDomain`| optional | Sets the server subdomain, default: 'exchange'. | `'exchange'` | `string` | +| `bidFloor` | optional | The minimum bid value desired. KueezRTB will not respond with bids lower than this value. | `0.90` | `float` | + + +## Example + ```javascript +var adUnits = [{ + code: 'banner-div', + mediaTypes: { + banner: { + sizes: [ + [300, 250], + [728, 90] + ] + } + }, + bids: [{ + bidder: 'kueezrtb', + params: { + cId: '562524b21b1c1f08117fc7f9', // Required - PROVIDED DURING SETUP... + pId: '59ac17c192832d0011283fe3', // Required - PROVIDED DURING SETUP... + bidFloor: 1.23 // Optional + } + }] + } +]; + +// configure pbjs to enable user syncing +pbjs.setConfig({ + userSync: { + filterSettings: { + iframe: { + bidders: 'kueezrtb', + filter: 'include' + } + } + } +}); +``` \ No newline at end of file From 94bfc23351d74319eccc0cb819ac67bf082042f1 Mon Sep 17 00:00:00 2001 From: brushmate Date: Sat, 15 Apr 2023 19:58:47 +0200 Subject: [PATCH 151/762] Update Yieldab docs (#4484) --- dev-docs/bidders/yieldlab.md | 84 +++++++++++++++++++++++++----------- 1 file changed, 58 insertions(+), 26 deletions(-) diff --git a/dev-docs/bidders/yieldlab.md b/dev-docs/bidders/yieldlab.md index f3335f61..0532c1b0 100644 --- a/dev-docs/bidders/yieldlab.md +++ b/dev-docs/bidders/yieldlab.md @@ -27,35 +27,67 @@ sidebarType: 1 ### Bid Params {: .table .table-bordered .table-striped } -| Name | Scope | Description | Example | Type | -|----------------|----------|---------------------------------------------------------------------------------------|---------------------------------------------|----------| -| `adslotId` | required | Yieldlab Adslot ID | `'12345'` | `string` | -| `supplyId` | required | Yieldlab Supply ID. Please reach out to your account management for more information. | `'12345'` | `string` | -| `targeting` | optional | Key-Value Targeting | `{ 'key1': 'value1', 'key2': 'value2' }` | `object` | -| `extId` | optional | External Id | `'abc'` | `string` | +| Name | Scope | Description | Example | Type | +|----------------|----------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|---------------------------------------------|----------| +| `adslotId` | required | Yieldlab Adslot ID | `'12345'` | `string` | +| `supplyId` | required | Yieldlab Supply ID. Please reach out to your account management for more information. | `'12345'` | `string` | +| `targeting` | optional | Key-Value Targeting | `{ 'key1': 'value1', 'key2': 'value2' }` | `object` | +| `extId` | optional | External Id | `'abc'` | `string` | | `iabContent` | optional | Object of content information, see [IAB Content Object](#iab_content) for details. It will override the content object passed in [First Party Data](https://docs.prebid.org/features/firstPartyData.html) | `{ 'id': 'foo', 'title': 'bar' }` | `object` | -| `customParams` | optional | Custom parameters to append to the query string of the bidding endpoint. | `{ 'param': 'value1', 'param2': 'value2' }` | `object` | +| `customParams` | optional | Custom parameters to append to the query string of the bidding endpoint. | `{ 'param': 'value1', 'param2': 'value2' }` | `object` | - + #### IAB Content Object -Yieldlab supports passing the IAB content object in correspond to the OpenRTB Specifications. -The following attributes are supported, and all of them are optional. +Yieldlab supports passing the IAB content object according to section *3.2.16* +of the [OpenRTB 2.6 specification][openrtb-spec]. The following attributes are +supported, and all of them are optional: -{: .table .table-bordered .table-striped } -| Name | Scope | Description | Example | Type | -|----------------|----------|-----------------------------------------------------------------------------------------------|---------------------------------------------|------------------| -| `id` | optional | Id uniquely identifying the content | `'12345'` | `string` | -| `episode` | optional | Episode number | `'42'` | `string` | -| `title` | optional | Content title | `'some title'` | `string` | -| `series` | optional | Content series | `'some series'` | `string` | -| `season` | optional | Content season | `'s1'` | `string` | -| `artist` | optional | Artist credited with the content | `'John Doe'` | `string` | -| `genre` | optional | Genre that best describes the content | `'some genre'` | `string` | -| `isrc` | optional | International Standard Recording Code conforming to ISO3901 | `'CC-XXX-YY-NNNNN'` | `string` | -| `url` | optional | URL of the content, for buy-side contextualization or review | `'https://yieldlab.com'` | `string` | -| `cat` | optional | Array of IAB content categories that describe the content producer | `['IAB1-1', 'IAB1-2']` | `Array` | -| `context` | optional | Type of content - 1: video, 2: game, 3: music, 4: application, 5: text, 6: other, 7: unknown | `'7'` | `string` | -| `keywords` | optional | Array of keywords describing the content | `['k1', 'k2', 'k3']` | `Array` | -| `live` | optional | 0 = not live, 1 = content is live | `'0'` | `string` | +* `id` +* `episode` +* `title` +* `series` +* `season` +* `artist` +* `genre` +* `album` +* `isrc` +* `producer` + * `id` + * `name` + * `cattax` + * `cat` + * `domain` +* `url` +* `cattax` +* `cat` +* `prodq` +* `context` +* `contentrating` +* `userrating` +* `qagmediarating` +* `keywords` +* `livestream` +* `sourcerelationship` +* `len` +* `language` +* `embeddable` +* `data` + * `id` + * `name` + * `segment` + * `id` + * `name` + * `value` + * `ext` +* `network` + * `id` + * `name` + * `domain` +* `channel` + * `id` + * `name` + * `domain` + +[openrtb-spec]: https://iabtechlab.com/wp-content/uploads/2022/04/OpenRTB-2-6_FINAL.pdf \ No newline at end of file From b5ff4e4c5872c5c3f524a86a36987d8f0c2cfb84 Mon Sep 17 00:00:00 2001 From: DridgerVE <33929311+DridgerVE@users.noreply.github.com> Date: Sat, 15 Apr 2023 21:03:04 +0300 Subject: [PATCH 152/762] Yandex adapter: add pbs support (#4479) --- dev-docs/bidders/yandex.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/dev-docs/bidders/yandex.md b/dev-docs/bidders/yandex.md index 9dac8bff..86ad047e 100644 --- a/dev-docs/bidders/yandex.md +++ b/dev-docs/bidders/yandex.md @@ -3,8 +3,9 @@ layout: bidder title: Yandex description: Prebid Yandex Bidder Adapter pbjs: true +pbs: true biddercode: yandex -media_types: banner +media_types: banner, native sidebarType: 1 --- From 3c8cf8cf159989fad11a28a39fb3edd12b625672 Mon Sep 17 00:00:00 2001 From: Viktor Dreiling <34981284+3link@users.noreply.github.com> Date: Sat, 15 Apr 2023 21:48:50 +0200 Subject: [PATCH 153/762] Add information about EIDS support for attributes resolved by LI's user id module (#4477) * Add information about EIDS support for attributes resolved by LI's user id module * Better describe the case of returning multiple ids * Improve example * Fix typo * Be more precise * Clean-up * Improve wording resolved vs. requested * Add section * Adjust section's title * Wording * Add an example * Remove duplication * Polish text --------- Co-authored-by: Viktor Dreiling --- .../modules/userid-submodules/liveintent.md | 55 ++++++++++++++++--- 1 file changed, 48 insertions(+), 7 deletions(-) diff --git a/dev-docs/modules/userid-submodules/liveintent.md b/dev-docs/modules/userid-submodules/liveintent.md index e06e309e..8f0cc8db 100644 --- a/dev-docs/modules/userid-submodules/liveintent.md +++ b/dev-docs/modules/userid-submodules/liveintent.md @@ -47,15 +47,56 @@ The first-party cookie generation and identity resolution functionality is provi The LiveIntent ID sub-module follows the standard Prebid.js initialization based on the GDPR consumer opt-out choices. With regard to CCPA, the LiveConnect JS receives a us_privacy string from the Prebid US Privacy Consent Management Module and respects opt-outs. -## Resolving uid2 +## Configuring requested attributes -Attributes other than the nonID can be requested using the requestedAttributesOverrides configuration option. +Attributes other than the nonID can be requested using the `requestedAttributesOverrides` configuration option. -One attribute that requires special mention here is 'uid2'. If this attribute is resolved by the id module -it will be exposed in the same format as from the Unified ID 2.0 userid module. If both the LiveIntent module -and the uid2 module manage to resolve an uid2, the one from the uid2 module will be used. -Enabling this option in addition to the uid2 module is an easy way to increase your uid2 resolution rates. -Example configuration to enable uid2 resolution: +For example, with the configuration below, the nonID as well as 'uid2', the 'medianet' id and the 'bidswitch' id will be requested: + +{% highlight javascript %} +pbjs.setConfig({ + userSync: { + userIds: [{ + "name": "liveIntentId", + "params": { + "publisherId": "12432415", + "requestedAttributesOverrides": {'uid2': true, 'medianet': true, 'bidswitch': true}, + }, + }] + } +}); +{% endhighlight %} + +### Multiple user ids + +The attributes 'uid2', 'medianet' or 'bidswitch' are treated specially by LiveIntent's user id sub-module. Each of these three attributes will result in a separate id returned by the sub-module. + +For example, in case 'uid2' is configured to be requested - additionally to the nonID - the `request.userId` object would look like this: + +{% highlight javascript %} +``` +{ + ... + "lipb" : { + "lipbid": "sample-nonid-value", + "segments": ["999"], + "uid2" : "sample-uid2-value" + }, + "uid2" : { + "id" : "sample-uid2-value" + } + ... +} +``` +{% endhighlight %} + +Note that 'uid2' is exposed as part of 'lipb' as well as separately as 'uid2'. 'medianet' and 'bidswitch' behave the same way. + +For the attributes 'lipbid' (nonID), 'uid2', 'medianet' and 'bidswitch' there is also support for their conversion into OpenRTB EIDS format. Please refer to [userId.md](../userId.md) for more information on conversion and [eids.md](https://github.com/prebid/Prebid.js/blob/master/modules/userId/eids.md) for output format examples. + +### Requesting uid2 + +An attribute that requires special mention here is 'uid2'. If this attribute is resolved by the id sub-module, it will be exposed in the same format as from the Unified ID 2.0 user id module. If both the LiveIntent module and the uid2 module manage to resolve an uid2, the one from the uid2 module will be used. Enabling this option in addition to the uid2 module is an easy way to increase your uid2 resolution rates. Example configuration to enable uid2 resolution: {% highlight javascript %} pbjs.setConfig({ From 5adc23ff0f33b6179f5c86ecca3f2481efd60f28 Mon Sep 17 00:00:00 2001 From: Sonali-More-Xandr <87759626+Sonali-More-Xandr@users.noreply.github.com> Date: Sun, 16 Apr 2023 01:27:12 +0530 Subject: [PATCH 154/762] remove oftmedia_server.md file (#4469) --- dev-docs/bidders/oftmedia_server.md | 26 -------------------------- 1 file changed, 26 deletions(-) delete mode 100644 dev-docs/bidders/oftmedia_server.md diff --git a/dev-docs/bidders/oftmedia_server.md b/dev-docs/bidders/oftmedia_server.md deleted file mode 100644 index 34dabd86..00000000 --- a/dev-docs/bidders/oftmedia_server.md +++ /dev/null @@ -1,26 +0,0 @@ ---- -layout: bidder -title: One Fifty Two Media Server -description: Prebid Server One Fifty Two Media Bidder Adaptor -pbjs: false -biddercode: oftmedia -aliasCode : adtelligent -gdpr_supported: true -coppa_supported: true -usp_supported: true -pbs: true -schain_supported: true -media_types: banner, video -prebid_member: true -userIds: britepoolId, criteo, id5Id, identityLink, liveIntentId, netId, parrableId, pubCommonId, unifiedId -safeframes_ok: true -gvl_id: 1111 -sidebarType: 1 ---- - -### Bid Params - -{: .table .table-bordered .table-striped } -| Name | Scope | Description | Example | Type | -|-------|----------|---------------------------------|----------|-----------| -| `aid` | required | The source ID from OftMedia. | `350975` | `integer` | From 43b7b7274bc93485a29be09ca9b1525e4e9c25b0 Mon Sep 17 00:00:00 2001 From: Eyvaz Ahmadzada <62054743+eyvazahmadzada@users.noreply.github.com> Date: Sun, 16 Apr 2023 00:39:46 +0400 Subject: [PATCH 155/762] IntentIQ: add analytics and update id submodule docs (#4450) * added: docs for intentIQ analytics adapter * update intentIQ ID system docs --- dev-docs/analytics/intentiq.md | 21 ++++ .../modules/userid-submodules/intentiq.md | 116 +++++++----------- 2 files changed, 65 insertions(+), 72 deletions(-) create mode 100644 dev-docs/analytics/intentiq.md diff --git a/dev-docs/analytics/intentiq.md b/dev-docs/analytics/intentiq.md new file mode 100644 index 00000000..a0e7b1cc --- /dev/null +++ b/dev-docs/analytics/intentiq.md @@ -0,0 +1,21 @@ +--- +layout: analytics +title: IntentIQ +description: IntentIQ Analytics Adapter +modulecode: intentiq +--- + +### Description + +By using this Intent IQ adapter, you will be able to obtain comprehensive analytics and metrics regarding the performance of the Intent IQ Unified ID module. This includes how the module impacts your revenue, CPMs, and fill rates related to bidders and domains. + +#### Intent IQ Universal ID Registration + +No registration for this module is required. + +#### Intent IQ Universal ID Configuration + +IMPORTANT: requires Intent IQ Universal ID module be installed and configured. [(How-To)](https://docs.prebid.org/dev-docs/modules/userid-submodules/intentiq.html) + +No additional configuration for this module is required. We will use the configuration provided for Intent IQ Universal IQ module. + diff --git a/dev-docs/modules/userid-submodules/intentiq.md b/dev-docs/modules/userid-submodules/intentiq.md index 4a99dc6f..6c7487b8 100644 --- a/dev-docs/modules/userid-submodules/intentiq.md +++ b/dev-docs/modules/userid-submodules/intentiq.md @@ -5,97 +5,68 @@ description: Intent IQ ID User ID sub-module useridmodule: intentIqIdSystem --- +# Intent IQ Universal ID module -Intent IQ’s universal ID with its unparalleled coverage of over 80% of ad inventory, protects publishers’ ability to rely on advertising as their main revenue source while preserving user privacy in a third party cookieless world. +By leveraging the Intent IQ identity graph, our module helps publishers, SSPs, and DSPs overcome the challenges of monetizing cookie-less inventory and preparing for a future without 3rd-party cookies. Our solution implements 1st-party data clustering and provides Intent IQ person IDs with over 90% coverage and unmatched accuracy in supported countries while remaining privacy-friendly and CCPA compliant. This results in increased CPMs, higher fill rates, and, ultimately, lifting overall revenue -The universal ID is an Intent IQ generated alphanumeric characters ID representing a person. This ID is not matched with personal information and remains anonymous to Intent IQ. +# All you need is a few basic steps to start using our solution. -Intent IQ universal ID enables partners - publishers, SSPs, DSPs, DMPs and advertisers to support, in a privacy-friendly way, and on a person level, core elements of the advertising business model - +## Registration -- Targeting across sites and devices -- Frequency capping -- Attribution measurement across sites and devices +Navigate to [our portal ](https://www.intentiq.com/) and contact our team for partner ID. +check our [documentation](https://pbmodule.documents.intentiq.com/) to get more information about our solution and how utilze it's full potential -Intent IQ's universal ID works across IP addresses and user-agent changes. - -Intent IQ's universal ID truly stands out in the coverage and accuracy it provides. Intent IQ's universal ID covers over 80% of ad inventory with 90% accuracy. By contrast, third-party cookies offer 56% coverage and log-in solutions offer coverage of less than 20%. +## Integration +{: .alert.alert-info :} +gulp build –modules=intentIqIdSystem -Add it to your Prebid.js package with: +We recommend including the Intent IQ Analytics adapter module for improved visibility -{: .alert.alert-info :} -gulp build --modules=intentIqIdSystem +## Configuration -## Intent IQ ID Registration +### Parameters -You can set up Intent IQ ID by contacting our operations team at [Intent IQ Contact Us](https://www.intentiq.com/contact-us) and getting your partner id. +Please find below list of parameters that could be used in configuring Intent IQ Universal ID module -The Intent IQ ID privacy is covered under the [Intent IQ Privacy Policy](https://www.intentiq.com/technology-privacy-policy). -## Intent IQ ID Configuration {: .table .table-bordered .table-striped } -| Param under userSync.userIds[] | Scope | Type | Description | Example | -| --- | --- | --- | --- | --- | -| name | Required | String | `"intentIqId"` | `"intentIqId"` | -| params | Required for IntentIqId | Object | Details for IntentIqId initialization. | | -| params.partner | Required | String | This is the partner ID value obtained from registering with IntentIQ. | `"1177538"` | -| params.pcid | Optional | String | This is the partner cookie ID, it is a dynamic value attached to the request. | `"g3hC52b"` | -| params.pai | Optional | String | This is the partner customer ID / advertiser ID, it is a dynamic value attached to the request. | `"advertiser1"` | - -{: .alert.alert-info :} -**NOTE:** The Intent IQ ID is encrypted with a key that changes every several hours. Demand partners utilize the latest key to decrypt the ID and use it. Therefore, to enable demand partners have an ID they can use, we highly recommend calling Intent IQ every 4 hours by setting storage.refreshInSeconds to 4 hours (4*3600 seconds) -## Intent IQ ID Examples +| Param under userSync.userIds[] | Scope | Type | Description | Example | +| ------------------------------ | -------- | ------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | --------------- | +| name | Required | String | The name of this module: "intentIqId" | `"intentIqId"` | +| params | Required | Object | Details for IntentIqId initialization. | | +| params.partner | Required | Number | This is the partner ID value obtained from registering with IntentIQ. | `1177538` | +| params.percentage | Required | Number | This a percentage value for our A/B testing group distribution. The values supposed to be in range of 0 to 100. We suggest to set it to 95 percent for optimal balance ofbetween prefromance and preceision. | `95` | +| params.pcid | Optional | String | This is the partner cookie ID, it is a dynamic value attached to the request. | `"g3hC52b"` | +| params.pai | Optional | String | This is the partner customer ID / advertiser ID, it is a dynamic value attached to the request. | `"advertiser1"` | -1) Publisher has a partner ID from Intent IQ and cookies. +### Configuration example -{: .alert.alert-warning :} {% highlight javascript %} pbjs.setConfig({ - userSync: { - userIds: [{ - name: "intentIqId", - params: { - partner: 123456 // valid partner id - }, - storage: { - type: "cookie", - name: "intentIqId", // create a cookie with this name - expires: 60, // cookie can last for 60 days - refreshInSeconds: 4*3600 // refresh ID every 4 hours to ensure it's fresh -} - }], - syncDelay: 3000 // 3 seconds after the first auction - } + userSync: { + userIds: [ + { + name: "intentIqId", + params: { + partner: 123456, // valid partner id + percentage: 95, + }, + storage: { + type: "html5", + name: "intentIqId", // set localstorage with this name + expires: 60, + refreshInSeconds: 4 * 3600, // refresh ID every 4 hours to ensure it's fresh + }, + }, + ], + syncDelay: 3000, + }, }); {% endhighlight %} -2) Publisher supports Intent IQ and HTML5 local storage. - -{% highlight javascript %} -pbjs.setConfig({ - userSync: { - userIds: [{ - name: "intentIqId", - params: { - partner: 123456 // valid partner id - }, - storage: { - type: "html5", - name: "intentIqId", // set localstorage with this name - expires: 60, - refreshInSeconds: 4*3600 // refresh ID every 4 hours to ensure it's fresh - } - }], - syncDelay: 3000 - } -}); -{% endhighlight %} - - -3) Publisher supports IntentIQ and HTML5 local storage with extra dynamic params such as 'pcid' and 'pai'. - {% highlight javascript %} pbjs.setConfig({ userSync: { @@ -103,8 +74,9 @@ pbjs.setConfig({ name: "intentIqId", params: { partner: 123456 // valid partner id - pcid: PCID_VARIABLE // string value, dynamically loaded into a variable before setting the configuration - pai: PAI_VARIABLE // string value, dynamically loaded into a variable before setting the configuration + pcid: PCID_VARIABLE, // string value, dynamically loaded into a variable before setting the configuration + pai: PAI_VARIABLE , // string value, dynamically loaded into a variable before setting the configuration + percentage: 95 }, storage: { type: "html5", @@ -115,4 +87,4 @@ pbjs.setConfig({ syncDelay: 3000 } }); -{% endhighlight %} +{% endhighlight %} \ No newline at end of file From 43962592228a51b7d9c4f5a94c73e1dc93b8585a Mon Sep 17 00:00:00 2001 From: JulieLorin Date: Sat, 15 Apr 2023 22:45:35 +0200 Subject: [PATCH 156/762] FPD Enrichment: use low entropy method by default to fetch user agent data (#4447) --- dev-docs/modules/enrichmentFpdModule.md | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/dev-docs/modules/enrichmentFpdModule.md b/dev-docs/modules/enrichmentFpdModule.md index 26f84e66..f86b80b5 100644 --- a/dev-docs/modules/enrichmentFpdModule.md +++ b/dev-docs/modules/enrichmentFpdModule.md @@ -55,7 +55,8 @@ At the beginning of each auction, this module merges a number of values into the ### User agent client hints -The module populates `device.sua` with UA client hints retrieved from `navigator.userAgentData`. By default, it asks for [every available high entropy hint](https://developer.mozilla.org/en-US/docs/Web/API/NavigatorUAData#returning_high_entropy_values); you may specify the list of hints with the `uaHints` option: + +The module populates `device.sua` with UA client hints retrieved from `navigator.userAgentData`. By default, it won't ask for any high entropy hint. You can specify the list of hints using the `uaHints` option with [any available high entropy hint](https://developer.mozilla.org/en-US/docs/Web/API/NavigatorUAData#returning_high_entropy_values): ```javascript pbjs.setConfig({ @@ -68,7 +69,7 @@ pbjs.setConfig({ }) ``` -If `uaHints` is set to an empty array, the module will not attempt to retrieve any high entropy hint and use only the available low-entropy values. +If `uaHints` is set to an empty array or is not set, the module will not attempt to retrieve any high entropy hint and use only the available low-entropy values. # Related Reading - [Prebid.js First Party Data feature](/features/firstPartyData.html) From f3bd494df043f3dbee8ff618f6614b4a28d10379 Mon Sep 17 00:00:00 2001 From: v-dridger <123445033+v-dridger@users.noreply.github.com> Date: Sat, 15 Apr 2023 23:49:57 +0300 Subject: [PATCH 157/762] Intertech: creating doc for new server adapter (#4446) * Intertech: creating doc for new server adapter * fix --- dev-docs/bidders/intertech.md | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) create mode 100644 dev-docs/bidders/intertech.md diff --git a/dev-docs/bidders/intertech.md b/dev-docs/bidders/intertech.md new file mode 100644 index 00000000..29512af6 --- /dev/null +++ b/dev-docs/bidders/intertech.md @@ -0,0 +1,20 @@ +--- +layout: bidder +title: intertech +description: Prebid Intertech Bidder Adapter +pbs: true +biddercode: intertech +media_types: banner, native +--- + +### Registration + +The Intertech Bidding adapter requires setup before beginning. Please contact us at [prebid@intertechsrvcs.com](mailto:prebid@intertechsrvcs.com). + +### Bid params + +{: .table .table-bordered .table-striped } +| Name | Scope | Description | Example | Type | +|---------------|----------|-------------------------|-----------|-----------| +| `pageId` | required | Page ID | `123456` | `Integer` | +| `impId` | required | Block ID | `12` | `Integer` | From b43585d4cea3d022bff3587fae4af5d611a08bb2 Mon Sep 17 00:00:00 2001 From: Aaron Price <67345931+AaronColbyPrice@users.noreply.github.com> Date: Sat, 15 Apr 2023 13:52:45 -0700 Subject: [PATCH 158/762] FixUrlLinkInBidderSearch: changing autocomplete list from using bidderCode as the new url to the page url. This matches the implementation on line 47 where the bidder is linked to page.url in the tag. This fixes a problem where a bidder rebrands as a new company and wants to update labelling but needs to keep an old bidder code for backward compatability (#4445) --- dev-docs/bidders.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dev-docs/bidders.md b/dev-docs/bidders.md index a52a8bee..c9e05a55 100644 --- a/dev-docs/bidders.md +++ b/dev-docs/bidders.md @@ -31,7 +31,7 @@ Publishers are advised to check with legal counsel before doing business with an
From 24a43f5c25524a875352ce1adf00586d69a429d3 Mon Sep 17 00:00:00 2001 From: ivs-mark <128337031+ivs-mark@users.noreply.github.com> Date: Sun, 16 Apr 2023 04:53:44 +0800 Subject: [PATCH 159/762] Add IVS bid adapter documentation (#4443) --- dev-docs/bidders/ivs.md | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) create mode 100644 dev-docs/bidders/ivs.md diff --git a/dev-docs/bidders/ivs.md b/dev-docs/bidders/ivs.md new file mode 100644 index 00000000..d79aa552 --- /dev/null +++ b/dev-docs/bidders/ivs.md @@ -0,0 +1,21 @@ +--- +layout: bidder +title: IVS Bidder Adapter +description: Prebid IVS Bidder Adapter +biddercode: ivs +media_types: video +floors_supported: true +pbjs: true +sidebarType: 1 +--- + +### Note: + +The IVS Bidding adapter requires setup before beginning. Please contact us at prebid@ivs.tv + +### Bid Params + +{: .table .table-bordered .table-striped } +| Name | Scope | Description | Example | Type | +|----------------|----------|----------------------------|-------------|-----------| +| `publisherId` | required | Unique id of the publisher | `'3001234'` | `string` | From 9f2ec1b885b65b9336f359e7681094d94ffddc01 Mon Sep 17 00:00:00 2001 From: jsnellbaker <31102355+jsnellbaker@users.noreply.github.com> Date: Sat, 15 Apr 2023 16:55:53 -0400 Subject: [PATCH 160/762] appnexus - change fpd flag (#4440) --- dev-docs/bidders/appnexus.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dev-docs/bidders/appnexus.md b/dev-docs/bidders/appnexus.md index 17d048b8..4eb2b4f7 100644 --- a/dev-docs/bidders/appnexus.md +++ b/dev-docs/bidders/appnexus.md @@ -12,7 +12,7 @@ coppa_supported: true usp_supported: true gpp_supported: true floors_supported: true -fpd_supported: true +fpd_supported: false pbjs: true pbjs_version_notes: please avoid using v7.15 and v7.16 pbs: true From 8c100a6c934858d50f576e85574d0a8bc03a71d9 Mon Sep 17 00:00:00 2001 From: Gena Date: Sat, 15 Apr 2023 23:57:59 +0300 Subject: [PATCH 161/762] 9Dots Media (#4436) --- dev-docs/bidders/9dotsmedia.md | 105 +++++++++++++++++++++++++++++++++ 1 file changed, 105 insertions(+) create mode 100644 dev-docs/bidders/9dotsmedia.md diff --git a/dev-docs/bidders/9dotsmedia.md b/dev-docs/bidders/9dotsmedia.md new file mode 100644 index 00000000..292163e9 --- /dev/null +++ b/dev-docs/bidders/9dotsmedia.md @@ -0,0 +1,105 @@ +--- +layout: bidder +title: 9Dots Media +description: 9Dots Media Bidder Adapter +biddercode: 9dotsmedia +aliasCode: adtelligent +media_types: video,banner +gdpr_supported: true +userIds: britepoolId, criteo, id5Id, identityLink, liveIntentId, netId, parrableId, pubCommonId, unifiedId +schain_supported: true +coppa_supported: true +usp_supported: true +safeframes_ok: true +prebid_member: true +pbjs: true +pbs: false +deals_supported: false +sidebarType: 1 +--- + +### Bid params + +{: .table .table-bordered .table-striped } +| Name | Scope | Description | Example | Type | +|-------|----------|---------------------------------|----------|-----------| +| `aid` | required | The source ID from 9Dots Media. | `12412` | `integer` | + +### Description +9Dots Media header bidding adapter connects with 9Dots Media demand sources in order to fetch bids. +This adapter provides a solution for accessing Video demand and display demand. + + +### Test Parameters +``` + var adUnits = [ + + // Video instream adUnit + { + code: 'test-div', + mediaTypes: { + video: { + context: 'instream', + playerSize: [640, 480] + } + }, + bids: [{ + bidder: '9dotsmedia', + params: { + aid: 472386 + } + }] + }, + + // Video outstream adUnit + { + code: 'test-div', + mediaTypes: { + video: { + context: 'outstream', + playerSize: [640, 480] + } + }, + bids: [{ + bidder: '9dotsmedia', + params: { + aid: 472386 + } + }] + }, + + // Video ADPOD adUnit + { + code: 'test-div', + sizes: [[640, 480]], + mediaTypes: { + video: { + context: 'adpod', + playerSize: [640, 480] + } + }, + bids: [{ + bidder: '9dotsmedia', + params: { + aid: 472386 + } + }] + }, + + // Banner adUnit + { + code: 'test-div', + mediaTypes:{ + banner:{ + sizes: [[300, 250]] + } + } + bids: [{ + bidder: '9dotsmedia', + params: { + aid: 529814 + } + }] + } + ]; +``` From bec269fc8dd3ab59df4008b34e7330e15bfea72c Mon Sep 17 00:00:00 2001 From: Paulius Imbrasas <880130+CremboC@users.noreply.github.com> Date: Sat, 15 Apr 2023 21:58:30 +0100 Subject: [PATCH 162/762] Update Permutive documentation (#4435) --- dev-docs/modules/permutiveRtdProvider.md | 93 ++++++++++++------------ 1 file changed, 47 insertions(+), 46 deletions(-) diff --git a/dev-docs/modules/permutiveRtdProvider.md b/dev-docs/modules/permutiveRtdProvider.md index 5370d054..27f9dc3e 100644 --- a/dev-docs/modules/permutiveRtdProvider.md +++ b/dev-docs/modules/permutiveRtdProvider.md @@ -15,7 +15,7 @@ sidebarType : 1 {:.no_toc} * TOC -{:toc} + {:toc} ## Prebid Config for Permutive RTD Module @@ -31,7 +31,7 @@ gulp build --modules=rtdModule,permutiveRtdProvider > Note that the global RTD module, `rtdModule`, is a prerequisite of the Permutive RTD module. -You then need to enable the Permutive RTD in your Prebid configuration, using the below format: +You then need to enable the Permutive RTD in your Prebid configuration. Below is an example of the format: ```javascript pbjs.setConfig({ @@ -63,20 +63,8 @@ as well as enabling settings for specific use cases mentioned above (e.g. acbidd | name | String | This should always be `permutive` | - | | waitForIt | Boolean | Should be `true` if there's an `auctionDelay` defined (optional) | `false` | | params | Object | | - | -| params.acBidders | String[] | An array of bidders which should receive Audience Connector cohorts. | `[]` | +| params.acBidders | String[] | An array of bidder codes to share cohorts with in certain versions of Prebid, see below | `[]` | | params.maxSegs | Integer | Maximum number of cohorts to be included in either the `permutive` or `p_standard` key-value. | `500` | -| params.transformations | Object[] | An array of configurations for ORTB2 user data transformations | | - -##### The `transformations` parameter - -This array contains configurations for transformations we'll apply to the Permutive object in the ORTB2 `user.data` array. The results of these transformations will be appended to the `user.data` array that's attached to ORTB2 bid requests. - -##### Supported transformations - -{: .table .table-bordered .table-striped } -| Name | ID | Config structure | Description | -| ---------------------- | -------------------- | ------------------------------------------------------- | ------------------------------------------------------------------------------------ | -| IAB taxonomies | iab | ```{ segtax: number, iabIds: Object}``` | Transform segment IDs from Permutive to IAB (note: alpha version, subject to change) | #### Context @@ -87,7 +75,7 @@ As Prebid utilizes TCF vendor consent, for the Permutive RTD module to load, Per #### Instructions -1. Publisher enables GDPR rules within Prebid. +1. Publisher enables rules within Prebid GDPR module 2. Label Permutive as an exception, as shown below. ```javascript [ @@ -110,29 +98,58 @@ Before making any updates to this configuration, please ensure that this approac ## Cohort Activation with Permutive RTD Module -### _Enabling Standard Cohorts_ - **Note**: Publishers must be enabled on the above Permutive RTD Submodule to enable Standard Cohorts. -The acbidders config in the Permutive RTD module allows publishers to determine which demand partners (SSPs) will receive standard cohorts via the user.data ortb2 object. Cohorts will be sent in the `p_standard` key-value. +### _Enabling Publisher Cohorts_ + +#### Standard Cohorts + +The Permutive RTD module sets Standard Cohort IDs as bidder-specific ortb2.user.data first-party data, following the Prebid ortb2 convention. Cohorts will be sent in the `p_standard` key-value. + +For Prebid versions below 7.29.0, populate the acbidders config in the Permutive RTD with an array of bidder codes with whom you wish to share Standard Cohorts with. You also need to permission the bidders by communicating the bidder list to the Permutive team at strategicpartnershipops@permutive.com. + +For Prebid versions 7.29.0 and above, do not populate bidder codes in acbidders for the purpose of sharing Standard Cohorts (Note: there may be other business needs that require you to populate acbidders for Prebid versions 7.29.0+, see Advertiser Cohorts below). To share Standard Cohorts with bidders in Prebid versions 7.29.0 and above, communicate the bidder list to the Permutive team at strategicpartnershipops@permutive.com. + +#### _Bidder Specific Requirements for Standard Cohorts_ +For PubMatic or OpenX: Please ensure you are using Prebid.js 7.13 (or later) +For Xandr: Please ensure you are using Prebid.js 7.29 (or later) +For Equativ: Please ensure you are using Prebid.js 7.26 (or later) + +#### Custom Cohorts + +The Permutive RTD module also supports passing any of the **Custom** Cohorts created in the dashboard to some SSP partners for targeting +e.g. setting up publisher deals. For these activations, cohort IDs are set in bidder-specific locations per ad unit (custom parameters). + +Currently, bidders with known support for custom cohort targeting are: + +- Xandr +- Magnite + +When enabling the respective Activation for a cohort in Permutive, this module will automatically attach that cohort ID to the bid request. +There is no need to enable individual bidders in the module configuration, it will automatically reflect which SSP integrations you have enabled in your Permutive dashboard. +Permutive cohorts will be sent in the permutive key-value. + -The Permutive RTD module sets standard cohort IDs as bidder-specific ortb2.user.data first-party data, following the Prebid ortb2 convention. +### _Enabling Advertiser Cohorts_ -There are **two** ways to assign which demand partner bidders (e.g. SSPs) will receive Standard Cohort information via the Audience Connector (acbidders) config: +If you are connecting to an Advertiser seat within Permutive to share Advertiser Cohorts, populate the acbidders config in the Permutive RTD with an array of bidder codes with whom you wish to share Advertiser Cohorts with. + +### _Managing acbidders_ + +If your business needs require you to populate acbidders with bidder codes based on the criteria above, there are **two** ways to manage it. #### Option 1 - Automated -New demand partner bidders may be added to the acbidders config directly within the Permutive Platform. +If you are using Prebid.js v7.13.0+, bidders may be added to or removed from the acbidders config directly within the Permutive Dashboard. **Permutive can do this on your behalf**. Simply contact your Permutive CSM with strategicpartnershipops@permutive.com on cc, indicating which bidders you would like added. -Or, a publisher may do this themselves within the UI using the below instructions. +Or, a publisher may do this themselves within the Permutive Dashboard using the below instructions. ##### Create Integration -In order to update acbidders via the Permutive dashboard, -it is necessary to first enable the prebid integration in the integrations page (settings). +In order to manage acbidders via the Permutive dashboard, it is necessary to first enable the Prebid integration via the integrations page (settings). ![Alt text](/assets/images/dev-docs/modules/permutiveRtdProvider-integration-create.png?raw=true "Permutive Prebid integration - create") @@ -142,33 +159,17 @@ Please see [this document](https://support.permutive.com/hc/en-us/articles/36001 ##### Update acbidders -The input for the “Data Provider config” is currently a multi-input free text. -A valid “bidder code” needs to be entered in order to enable Standard Cohorts to be passed to the desired partner. -The [prebid Bidders page](https://docs.prebid.org/dev-docs/bidders.html) contains instructions and a link to a list of possible bidder codes. +The input for the “Data Provider config” is a multi-input free text. A valid “bidder code” needs to be entered in order to enable Standard or Advertiser Cohorts to be passed to the desired partner. The [prebid Bidders page](https://docs.prebid.org/dev-docs/bidders.html) contains instructions and a link to a list of possible bidder codes. ![Alt text](/assets/images/dev-docs/modules/permutiveRtdProvider-integration-update.png?raw=true "Permutive Prebid integration - update") -Acbidders can be added or removed from the list using this feature, however, this will not impact any acbidders that have been applied using the manual method below. +Bidders can be added or removed from acbidders using this feature, however, this will not impact any bidders that have been applied using the manual method below. #### Option 2 - Manual -As a secondary option, new demand partner bidders may be added manually. +As a secondary option, bidders may be added manually. -To do so, a Publisher may define which bidders should receive Standard Cohorts by +To do so, define which bidders should receive Standard or Advertiser Cohorts by including the _bidder code_ of any bidder in the `acBidders` array. -**Note:** If a Publisher ever needs to remove a manually-added bidder, the bidder will also need to be removed manually. - -### _Enabling Custom Cohort IDs for Targeting_ - -Separately from Standard Cohorts - The Permutive RTD module also supports passing any of the **custom** cohorts created in the dashboard to some SSP partners for targeting -e.g. setting up publisher deals. For these activations, cohort IDs are set in bidder-specific locations per ad unit (custom parameters). - -Currently, bidders with known support for custom cohort targeting are: - -- Xandr -- Magnite - -When enabling the respective Activation for a cohort in Permutive, this module will automatically attach that cohort ID to the bid request. -There is no need to enable individual bidders in the module configuration, it will automatically reflect which SSP integrations you have enabled in your Permutive dashboard. -Permutive cohorts will be sent in the permutive key-value. +**Note:** If you ever need to remove a manually-added bidder, the bidder will also need to be removed manually. From 03e558bd2c259f9bc43e67ec35eac6fb94a4a403 Mon Sep 17 00:00:00 2001 From: Brian Schaaf Date: Sat, 15 Apr 2023 16:58:48 -0400 Subject: [PATCH 163/762] PubWise Support PBS (#4428) --- dev-docs/bidders/pwbid.md | 1 + 1 file changed, 1 insertion(+) diff --git a/dev-docs/bidders/pwbid.md b/dev-docs/bidders/pwbid.md index ec0361fb..ef32a00b 100644 --- a/dev-docs/bidders/pwbid.md +++ b/dev-docs/bidders/pwbid.md @@ -3,6 +3,7 @@ layout: bidder title: PubWise description: PubWise Bidder Adaptor pbjs: true +pbs: true biddercode: pwbid aliasCode: pubwise media_types: banner, native, video From 76e8da3a7461b4bb01108dc13b7292dd0d77abeb Mon Sep 17 00:00:00 2001 From: Vadim Mazzherin Date: Sun, 16 Apr 2023 03:00:08 +0600 Subject: [PATCH 164/762] ShowHeroes Bid Adapter: update documentation (#4422) * add ShowHeroes Adapter * removing longer-than-12 header happily we don't need that anymore * ShowHeroes Bid Adapter: update params * Delete showheroes.md * ShowHeroes bid adapter: update doc --------- Co-authored-by: bretg --- dev-docs/bidders/showheroes-bs.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/dev-docs/bidders/showheroes-bs.md b/dev-docs/bidders/showheroes-bs.md index 357cb5b5..8d84acbf 100644 --- a/dev-docs/bidders/showheroes-bs.md +++ b/dev-docs/bidders/showheroes-bs.md @@ -6,6 +6,8 @@ pbjs: true biddercode: showheroes-bs media_types: video, banner gdpr_supported: true +usp_supported: true +schain_supported: true sidebarType: 1 --- From 5e5b5197e9d311513eec06100a62db34eb5d59d4 Mon Sep 17 00:00:00 2001 From: Ilia Medvedev Date: Sun, 16 Apr 2023 01:00:38 +0400 Subject: [PATCH 165/762] New Adapter: Evolution Technologies (#4421) * New Adapter: Evolution Technologies * Rename evolutionTechnologies to evtech --- dev-docs/bidders/evtech.md | 30 ++++++++++++++++++++++++++++ dev-docs/bidders/iionads.md | 4 +++- dev-docs/bidders/limelightDigital.md | 4 +++- 3 files changed, 36 insertions(+), 2 deletions(-) create mode 100644 dev-docs/bidders/evtech.md diff --git a/dev-docs/bidders/evtech.md b/dev-docs/bidders/evtech.md new file mode 100644 index 00000000..d02b1ba2 --- /dev/null +++ b/dev-docs/bidders/evtech.md @@ -0,0 +1,30 @@ +--- +layout: bidder +title: Evolution Technologies +description: Evolution Technologies Bidder Adaptor +biddercode: evtech +pbjs: false +pbs: true +media_types: banner, video, audio, native +userIds: all +fpd_supported: false +gdpr_supported: true +usp_supported: true +coppa_supported: true +schain_supported: true +prebid_member: false +ortb_blocking_supported: true +multiformat_supported: will-bid-on-one +floors_supported: false +aliasCode: limelightDigital +sidebarType: 1 +--- + +### Bid Params + +{: .table .table-bordered .table-striped } + +| Name | Scope | Description | Example | Type | +|:--------------|:---------|:----------------------|:------------------|:----------| +| `host` | required | Ad network's RTB host | `'e-volution.ai'` | `string` | +| `publisherId` | required | Publisher ID | `12345` | `integer` | diff --git a/dev-docs/bidders/iionads.md b/dev-docs/bidders/iionads.md index cf6c28c0..3ca533cc 100644 --- a/dev-docs/bidders/iionads.md +++ b/dev-docs/bidders/iionads.md @@ -36,4 +36,6 @@ sidebarType: 1 | `custom4` | optional | Custom targeting field 4 | `'custom4'` | `string` | | `custom5` | optional | Custom targeting field 5 | `'custom5'` | `string` | -iionads server-side Prebid Server adapter supports `banner`, `video`, `audio`, `native` media types. But iionads client-side Prebid.js adapter supports only `banner` and `video` media types, doesn't support `audio` and `native`. +iionads server-side Prebid Server adapter requires only `publisherId` and `host` parameters. But iionads client-side Prebid.js adapter requires only `host`, `adUnitId`, `adUnitType`. + +iionads server-side Prebid Server adapter supports only `banner`, `video`, `audio`, `native` media types. But iionads client-side Prebid.js adapter supports only `banner` and `video` media types, doesn't support `audio` and `native`. diff --git a/dev-docs/bidders/limelightDigital.md b/dev-docs/bidders/limelightDigital.md index 2134f4d4..e3b8e3f0 100644 --- a/dev-docs/bidders/limelightDigital.md +++ b/dev-docs/bidders/limelightDigital.md @@ -35,4 +35,6 @@ sidebarType: 1 | `custom4` | optional | Custom targeting field 4 | `'custom4'` | `string` | | `custom5` | optional | Custom targeting field 5 | `'custom5'` | `string` | -Limelight Digital server-side Prebid Server adapter supports `banner`, `video`, `audio`, `native` media types. But Limelight Digital client-side Prebid.js adapter supports only `banner` and `video` media types, doesn't support `audio` and `native`. +Limelight Digital server-side Prebid Server adapter requires only `publisherId` and `host` parameters. But Limelight Digital client-side Prebid.js adapter requires only `host`, `adUnitId`, `adUnitType`. + +Limelight Digital server-side Prebid Server adapter supports only `banner`, `video`, `audio`, `native` media types. But Limelight Digital client-side Prebid.js adapter supports only `banner` and `video` media types, doesn't support `audio` and `native`. From 6b61017af76206a886bbbeee6aa79db8ee68f81a Mon Sep 17 00:00:00 2001 From: onlsol <48312668+onlsol@users.noreply.github.com> Date: Sat, 15 Apr 2023 23:01:11 +0200 Subject: [PATCH 166/762] DSPx docs update (#4417) * schain support * userIds support * multiformat support * bid params description --- dev-docs/bidders/dspx.md | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/dev-docs/bidders/dspx.md b/dev-docs/bidders/dspx.md index 074cd122..c60589d1 100644 --- a/dev-docs/bidders/dspx.md +++ b/dev-docs/bidders/dspx.md @@ -6,12 +6,15 @@ pbjs: true biddercode: dspx media_types: banner, video gdpr_supported: true -userIds: uid2, netId +schain_supported: true +userIds: uid2, netId, id5Id, sharedId +multiformat_supported: will-bid-on-one +gvl_id: 602 sidebarType: 1 --- ### Note: -The DSPx Bidder Adapter requires setup and approval from DSPx team. Please reach out to your account team or prebid@dspx.tv for more information. +The DSPx bidder adapter requires setup and approval from the DSPx team. Please reach out to prebid@dspx.tv for more information and start using it. ### Bid Params @@ -20,13 +23,13 @@ The DSPx Bidder Adapter requires setup and approval from DSPx team. Please reach | Name | Scope | Description | Example | Type | |---------------|----------|----------------------------------------------------------------------------|------------------------|-----------------| | `placement` | required | Placement ID from dspx. | `'101'` | `string` | -| `pfilter` | optional | Selection filter. E.g. floorprice (min_cpm_micros) | `{"floorprice": 1000000}`| `object` | +| `pfilter` | optional | Custom filter parameters. | `{"customxy": 1000000}`| `object` | | `bcat` | optional | List of Blocked Categories (IAB) - comma separated. | `'IAB2,IAB4'` | `string` | **Notice:** The creative type can be checked by the `type` property of `bidResponse` object. E.g.: ```js bidsBackHandler: function(bids) { - var contentType = bids[0].type // JS InSkin|JS Interscroller Type A|...; + var contentType = bids[0].type } ``` From cf8aeafe56917d3c3db65fbc564e63b24a2e7c6b Mon Sep 17 00:00:00 2001 From: beglobal2022 <120370005+beglobal2022@users.noreply.github.com> Date: Sun, 16 Apr 2023 02:32:35 +0530 Subject: [PATCH 167/762] Added document for bedigitech adaptor (#4394) Co-authored-by: yogesh.ingale1 --- dev-docs/bidders/bedigitech.md | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) create mode 100644 dev-docs/bidders/bedigitech.md diff --git a/dev-docs/bidders/bedigitech.md b/dev-docs/bidders/bedigitech.md new file mode 100644 index 00000000..383e42c3 --- /dev/null +++ b/dev-docs/bidders/bedigitech.md @@ -0,0 +1,23 @@ +--- +layout: bidder +title: BEdigitech +description: Prebid BEdigitech Bidder Adapter +pbjs: true +pbs: false +biddercode: bedigitech +gdpr_supported: false +usp_supported: false +media_types: banner, native +--- + +### Note: + +The BEdigitech Bidding adapter requires setup before beginning. Please contact us at yogesh@thebeglobal.com +Due to different integration API prebid.js and prebid-server api params are different + +### Prebid.JS Bid Params + +{: .table .table-bordered .table-striped } +| Name | Scope | Description | Example | Type | +|---------------|----------|-----------------------|-----------|-----------| +| `placementId` | required | bedigitech placement | `'1234'` | `'string'`| From 786122f545c408317e3c75ffd32ef62eed02aa48 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 17 Apr 2023 08:00:05 -0700 Subject: [PATCH 168/762] Bump ua-parser-js and browser-sync (#4486) Bumps [ua-parser-js](https://github.com/faisalman/ua-parser-js) to 1.0.35 and updates ancestor dependency [browser-sync](https://github.com/BrowserSync/browser-sync). These dependencies need to be updated together. Updates `ua-parser-js` from 1.0.2 to 1.0.35 - [Release notes](https://github.com/faisalman/ua-parser-js/releases) - [Changelog](https://github.com/faisalman/ua-parser-js/blob/master/changelog.md) - [Commits](https://github.com/faisalman/ua-parser-js/compare/1.0.2...1.0.35) Updates `browser-sync` from 2.27.11 to 2.29.1 - [Release notes](https://github.com/BrowserSync/browser-sync/releases) - [Changelog](https://github.com/BrowserSync/browser-sync/blob/master/CHANGELOG.md) - [Commits](https://github.com/BrowserSync/browser-sync/compare/v2.27.11...v2.29.1) --- updated-dependencies: - dependency-name: ua-parser-js dependency-type: indirect - dependency-name: browser-sync dependency-type: direct:development ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- package-lock.json | 590 +++++++++++++++++++++++++++++----------------- package.json | 2 +- 2 files changed, 374 insertions(+), 218 deletions(-) diff --git a/package-lock.json b/package-lock.json index fdd5679a..ac50a842 100644 --- a/package-lock.json +++ b/package-lock.json @@ -16,7 +16,7 @@ "popper.js": "^1.16.1" }, "devDependencies": { - "browser-sync": "^2.27.11", + "browser-sync": "^2.29.1", "browser-sync-webpack-plugin": "^2.0.1", "cross-env": "^7.0.2", "laravel-mix": "^5.0.7", @@ -2131,21 +2131,22 @@ "dev": true }, "node_modules/browser-sync": { - "version": "2.27.11", - "resolved": "https://registry.npmjs.org/browser-sync/-/browser-sync-2.27.11.tgz", - "integrity": "sha512-U5f9u97OYJH66T0MGWWzG9rOQTW6ZmDMj97vsmtqwNS03JAwdLVES8eel2lD3rvAqQCNAFqaJ74NMacBI57vJg==", + "version": "2.29.1", + "resolved": "https://registry.npmjs.org/browser-sync/-/browser-sync-2.29.1.tgz", + "integrity": "sha512-WXy9HMJVQaNUTPjmai330E2fnDA6W84l/vBILGkYu9yHXIpWw1gJYjdQWDfEhLFljYUHNTN9jM3GCej2T55m+g==", "dev": true, "dependencies": { - "browser-sync-client": "^2.27.11", - "browser-sync-ui": "^2.27.11", + "browser-sync-client": "^2.29.1", + "browser-sync-ui": "^2.29.1", "bs-recipes": "1.3.4", "bs-snippet-injector": "^2.0.1", + "chalk": "4.1.2", "chokidar": "^3.5.1", "connect": "3.6.6", "connect-history-api-fallback": "^1", "dev-ip": "^1.0.1", "easy-extender": "^2.3.4", - "eazy-logger": "3.1.0", + "eazy-logger": "^4.0.1", "etag": "^1.8.1", "fresh": "^0.5.2", "fs-extra": "3.0.1", @@ -2164,7 +2165,7 @@ "serve-static": "1.13.2", "server-destroy": "1.0.1", "socket.io": "^4.4.1", - "ua-parser-js": "1.0.2", + "ua-parser-js": "^1.0.33", "yargs": "^17.3.1" }, "bin": { @@ -2175,28 +2176,27 @@ } }, "node_modules/browser-sync-client": { - "version": "2.27.11", - "resolved": "https://registry.npmjs.org/browser-sync-client/-/browser-sync-client-2.27.11.tgz", - "integrity": "sha512-okMNfD2NasL/XD1/BclP3onXjhahisk3e/kTQ5HPDT/lLqdBqNDd6QFcjI5I1ak7na2hxKQSLjryql+7fp5gKQ==", + "version": "2.29.1", + "resolved": "https://registry.npmjs.org/browser-sync-client/-/browser-sync-client-2.29.1.tgz", + "integrity": "sha512-aESnjt3rU7CZpzjyqzhIC2UJ3MVhzRis7cPKkGbyYWDf/wnbxyRa3fFenF3Qx9061/guY3HHhD67uiTVV26DVg==", "dev": true, "dependencies": { "etag": "1.8.1", "fresh": "0.5.2", - "mitt": "^1.1.3", - "rxjs": "^5.5.6", - "typescript": "^4.6.2" + "mitt": "^1.1.3" }, "engines": { "node": ">=8.0.0" } }, "node_modules/browser-sync-ui": { - "version": "2.27.11", - "resolved": "https://registry.npmjs.org/browser-sync-ui/-/browser-sync-ui-2.27.11.tgz", - "integrity": "sha512-1T/Y8Pp1R68aUL7zVSFq0nxtr258xWd/nTasCAHX2M6EsGaswVOFtXsw3bKqsr35z+J+LfVfOdz1HFLYKxdgrA==", + "version": "2.29.1", + "resolved": "https://registry.npmjs.org/browser-sync-ui/-/browser-sync-ui-2.29.1.tgz", + "integrity": "sha512-MB7SAiUgVUrhipO2xyO1sheC9H0+LKXPQ3L1tQWcZ3AgizBnUNKAqDZPSwe4grNSa8o8ImSAwJp7lMS6XYy1Dw==", "dev": true, "dependencies": { "async-each-series": "0.1.1", + "chalk": "4.1.2", "connect-history-api-fallback": "^1", "immutable": "^3", "server-destroy": "1.0.1", @@ -2204,6 +2204,76 @@ "stream-throttle": "^0.1.3" } }, + "node_modules/browser-sync-ui/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/browser-sync-ui/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/browser-sync-ui/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/browser-sync-ui/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "node_modules/browser-sync-ui/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/browser-sync-ui/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/browser-sync-webpack-plugin": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/browser-sync-webpack-plugin/-/browser-sync-webpack-plugin-2.0.1.tgz", @@ -2271,6 +2341,22 @@ "node": ">=8" } }, + "node_modules/browser-sync/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, "node_modules/browser-sync/node_modules/chokidar": { "version": "3.5.3", "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.3.tgz", @@ -2394,6 +2480,15 @@ "node": ">= 6" } }, + "node_modules/browser-sync/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, "node_modules/browser-sync/node_modules/http-errors": { "version": "1.6.3", "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.6.3.tgz", @@ -2586,6 +2681,18 @@ "node": ">=8" } }, + "node_modules/browser-sync/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/browser-sync/node_modules/to-regex-range": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", @@ -4292,12 +4399,6 @@ "node": ">=4" } }, - "node_modules/dlv": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/dlv/-/dlv-1.1.3.tgz", - "integrity": "sha512-+HlytyjlPKnIG8XuRG8WvmBP8xs8P71y+SKKS6ZXWoEgLuePxtDoUEiH7WkdePWrQ5JBpE6aoVqfZfJUQkjXwA==", - "dev": true - }, "node_modules/dns-equal": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/dns-equal/-/dns-equal-1.0.0.tgz", @@ -4417,17 +4518,87 @@ } }, "node_modules/eazy-logger": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/eazy-logger/-/eazy-logger-3.1.0.tgz", - "integrity": "sha512-/snsn2JqBtUSSstEl4R0RKjkisGHAhvYj89i7r3ytNUKW12y178KDZwXLXIgwDqLW6E/VRMT9qfld7wvFae8bQ==", + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/eazy-logger/-/eazy-logger-4.0.1.tgz", + "integrity": "sha512-2GSFtnnC6U4IEKhEI7+PvdxrmjJ04mdsj3wHZTFiw0tUtG4HCWzTr13ZYTk8XOGnA1xQMaDljoBOYlk3D/MMSw==", "dev": true, "dependencies": { - "tfunk": "^4.0.0" + "chalk": "4.1.2" }, "engines": { "node": ">= 0.8.0" } }, + "node_modules/eazy-logger/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/eazy-logger/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/eazy-logger/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/eazy-logger/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "node_modules/eazy-logger/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/eazy-logger/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/ee-first": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", @@ -4516,22 +4687,22 @@ } }, "node_modules/engine.io-client": { - "version": "6.2.3", - "resolved": "https://registry.npmjs.org/engine.io-client/-/engine.io-client-6.2.3.tgz", - "integrity": "sha512-aXPtgF1JS3RuuKcpSrBtimSjYvrbhKW9froICH4s0F3XQWLxsKNxqzG39nnvQZQnva4CMvUK63T7shevxRyYHw==", + "version": "6.4.0", + "resolved": "https://registry.npmjs.org/engine.io-client/-/engine.io-client-6.4.0.tgz", + "integrity": "sha512-GyKPDyoEha+XZ7iEqam49vz6auPnNJ9ZBfy89f+rMMas8AuiMWOZ9PVzu8xb9ZC6rafUqiGHSCfu22ih66E+1g==", "dev": true, "dependencies": { "@socket.io/component-emitter": "~3.1.0", "debug": "~4.3.1", "engine.io-parser": "~5.0.3", - "ws": "~8.2.3", + "ws": "~8.11.0", "xmlhttprequest-ssl": "~2.0.0" } }, "node_modules/engine.io-client/node_modules/ws": { - "version": "8.2.3", - "resolved": "https://registry.npmjs.org/ws/-/ws-8.2.3.tgz", - "integrity": "sha512-wBuoj1BDpC6ZQ1B7DWQBYVLphPWkm8i9Y0/3YdHjHKHiohOJ1ws+3OccDWtH+PoC9DZD5WOTrJvNbWvjS6JWaA==", + "version": "8.11.0", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.11.0.tgz", + "integrity": "sha512-HPG3wQd9sNQoT9xHyNCXoDUa+Xw/VevmY9FoHyQ+g+rrMn4j6FB4np7Z0OhdTgjx6MgQLK7jwSy1YecU1+4Asg==", "dev": true, "engines": { "node": ">=10.0.0" @@ -9843,18 +10014,6 @@ "integrity": "sha1-pfE/957zt0D+MKqAP7CfmIBdR4I=", "dev": true }, - "node_modules/rxjs": { - "version": "5.5.12", - "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-5.5.12.tgz", - "integrity": "sha512-xx2itnL5sBbqeeiVgNPVuQQ1nC8Jp2WfNJhXWHmElW9YmrpS9UVnNzhP3EH3HFqexO5Tlp8GhYY+WEcqcVMvGw==", - "dev": true, - "dependencies": { - "symbol-observable": "1.0.1" - }, - "engines": { - "npm": ">=2.0.0" - } - }, "node_modules/safe-buffer": { "version": "5.1.2", "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", @@ -10464,14 +10623,14 @@ "dev": true }, "node_modules/socket.io-client": { - "version": "4.5.4", - "resolved": "https://registry.npmjs.org/socket.io-client/-/socket.io-client-4.5.4.tgz", - "integrity": "sha512-ZpKteoA06RzkD32IbqILZ+Cnst4xewU7ZYK12aS1mzHftFFjpoMz69IuhP/nL25pJfao/amoPI527KnuhFm01g==", + "version": "4.6.1", + "resolved": "https://registry.npmjs.org/socket.io-client/-/socket.io-client-4.6.1.tgz", + "integrity": "sha512-5UswCV6hpaRsNg5kkEHVcbBIXEYoVbMQaHJBXJCyEQ+CiFPV1NIOY0XOFWG4XR4GZcB8Kn6AsRs/9cy9TbqVMQ==", "dev": true, "dependencies": { "@socket.io/component-emitter": "~3.1.0", "debug": "~4.3.2", - "engine.io-client": "~6.2.3", + "engine.io-client": "~6.4.0", "socket.io-parser": "~4.2.1" }, "engines": { @@ -10955,15 +11114,6 @@ "node": ">=4.0.0" } }, - "node_modules/symbol-observable": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/symbol-observable/-/symbol-observable-1.0.1.tgz", - "integrity": "sha512-Kb3PrPYz4HanVF1LVGuAdW6LoVgIwjUYJGzFe7NDrBLCN4lsV/5J0MFurV+ygS4bRVwrCEt2c7MQ1R2a72oJDw==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/tapable": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/tapable/-/tapable-1.1.3.tgz", @@ -11138,50 +11288,6 @@ "node": ">=0.10.0" } }, - "node_modules/tfunk": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/tfunk/-/tfunk-4.0.0.tgz", - "integrity": "sha512-eJQ0dGfDIzWNiFNYFVjJ+Ezl/GmwHaFTBTjrtqNPW0S7cuVDBrZrmzUz6VkMeCR4DZFqhd4YtLwsw3i2wYHswQ==", - "dev": true, - "dependencies": { - "chalk": "^1.1.3", - "dlv": "^1.1.3" - } - }, - "node_modules/tfunk/node_modules/ansi-styles": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", - "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/tfunk/node_modules/chalk": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", - "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", - "dev": true, - "dependencies": { - "ansi-styles": "^2.2.1", - "escape-string-regexp": "^1.0.2", - "has-ansi": "^2.0.0", - "strip-ansi": "^3.0.0", - "supports-color": "^2.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/tfunk/node_modules/supports-color": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", - "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=", - "dev": true, - "engines": { - "node": ">=0.8.0" - } - }, "node_modules/through": { "version": "2.3.8", "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", @@ -11329,23 +11435,10 @@ "integrity": "sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c=", "dev": true }, - "node_modules/typescript": { - "version": "4.9.4", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.9.4.tgz", - "integrity": "sha512-Uz+dTXYzxXXbsFpM86Wh3dKCxrQqUcVMxwU54orwlJjOpO3ao8L7j5lH+dWfTwgCwIuM9GQ2kvVotzYJMXTBZg==", - "dev": true, - "bin": { - "tsc": "bin/tsc", - "tsserver": "bin/tsserver" - }, - "engines": { - "node": ">=4.2.0" - } - }, "node_modules/ua-parser-js": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/ua-parser-js/-/ua-parser-js-1.0.2.tgz", - "integrity": "sha512-00y/AXhx0/SsnI51fTc0rLRmafiGOM4/O+ny10Ps7f+j/b8p/ZY11ytMgznXkOVo4GQ+KwQG5UQLkLGirsACRg==", + "version": "1.0.35", + "resolved": "https://registry.npmjs.org/ua-parser-js/-/ua-parser-js-1.0.35.tgz", + "integrity": "sha512-fKnGuqmTBnIE+/KXSzCn4db8RTigUzw1AN0DmdU6hJovUTbYJKyqj+8Mt1c4VfRDnOVJnENmfYkIPZ946UrSAA==", "dev": true, "funding": [ { @@ -14706,21 +14799,22 @@ "dev": true }, "browser-sync": { - "version": "2.27.11", - "resolved": "https://registry.npmjs.org/browser-sync/-/browser-sync-2.27.11.tgz", - "integrity": "sha512-U5f9u97OYJH66T0MGWWzG9rOQTW6ZmDMj97vsmtqwNS03JAwdLVES8eel2lD3rvAqQCNAFqaJ74NMacBI57vJg==", + "version": "2.29.1", + "resolved": "https://registry.npmjs.org/browser-sync/-/browser-sync-2.29.1.tgz", + "integrity": "sha512-WXy9HMJVQaNUTPjmai330E2fnDA6W84l/vBILGkYu9yHXIpWw1gJYjdQWDfEhLFljYUHNTN9jM3GCej2T55m+g==", "dev": true, "requires": { - "browser-sync-client": "^2.27.11", - "browser-sync-ui": "^2.27.11", + "browser-sync-client": "^2.29.1", + "browser-sync-ui": "^2.29.1", "bs-recipes": "1.3.4", "bs-snippet-injector": "^2.0.1", + "chalk": "4.1.2", "chokidar": "^3.5.1", "connect": "3.6.6", "connect-history-api-fallback": "^1", "dev-ip": "^1.0.1", "easy-extender": "^2.3.4", - "eazy-logger": "3.1.0", + "eazy-logger": "^4.0.1", "etag": "^1.8.1", "fresh": "^0.5.2", "fs-extra": "3.0.1", @@ -14739,7 +14833,7 @@ "serve-static": "1.13.2", "server-destroy": "1.0.1", "socket.io": "^4.4.1", - "ua-parser-js": "1.0.2", + "ua-parser-js": "^1.0.33", "yargs": "^17.3.1" }, "dependencies": { @@ -14783,6 +14877,16 @@ "fill-range": "^7.0.1" } }, + "chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + }, "chokidar": { "version": "3.5.3", "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.3.tgz", @@ -14876,6 +14980,12 @@ "is-glob": "^4.0.1" } }, + "has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true + }, "http-errors": { "version": "1.6.3", "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.6.3.tgz", @@ -15029,6 +15139,15 @@ "ansi-regex": "^5.0.1" } }, + "supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "requires": { + "has-flag": "^4.0.0" + } + }, "to-regex-range": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", @@ -15079,30 +15198,80 @@ } }, "browser-sync-client": { - "version": "2.27.11", - "resolved": "https://registry.npmjs.org/browser-sync-client/-/browser-sync-client-2.27.11.tgz", - "integrity": "sha512-okMNfD2NasL/XD1/BclP3onXjhahisk3e/kTQ5HPDT/lLqdBqNDd6QFcjI5I1ak7na2hxKQSLjryql+7fp5gKQ==", + "version": "2.29.1", + "resolved": "https://registry.npmjs.org/browser-sync-client/-/browser-sync-client-2.29.1.tgz", + "integrity": "sha512-aESnjt3rU7CZpzjyqzhIC2UJ3MVhzRis7cPKkGbyYWDf/wnbxyRa3fFenF3Qx9061/guY3HHhD67uiTVV26DVg==", "dev": true, "requires": { "etag": "1.8.1", "fresh": "0.5.2", - "mitt": "^1.1.3", - "rxjs": "^5.5.6", - "typescript": "^4.6.2" + "mitt": "^1.1.3" } }, "browser-sync-ui": { - "version": "2.27.11", - "resolved": "https://registry.npmjs.org/browser-sync-ui/-/browser-sync-ui-2.27.11.tgz", - "integrity": "sha512-1T/Y8Pp1R68aUL7zVSFq0nxtr258xWd/nTasCAHX2M6EsGaswVOFtXsw3bKqsr35z+J+LfVfOdz1HFLYKxdgrA==", + "version": "2.29.1", + "resolved": "https://registry.npmjs.org/browser-sync-ui/-/browser-sync-ui-2.29.1.tgz", + "integrity": "sha512-MB7SAiUgVUrhipO2xyO1sheC9H0+LKXPQ3L1tQWcZ3AgizBnUNKAqDZPSwe4grNSa8o8ImSAwJp7lMS6XYy1Dw==", "dev": true, "requires": { "async-each-series": "0.1.1", + "chalk": "4.1.2", "connect-history-api-fallback": "^1", "immutable": "^3", "server-destroy": "1.0.1", "socket.io-client": "^4.4.1", "stream-throttle": "^0.1.3" + }, + "dependencies": { + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "requires": { + "color-convert": "^2.0.1" + } + }, + "chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true + }, + "supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "requires": { + "has-flag": "^4.0.0" + } + } } }, "browser-sync-webpack-plugin": { @@ -16486,12 +16655,6 @@ "path-type": "^3.0.0" } }, - "dlv": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/dlv/-/dlv-1.1.3.tgz", - "integrity": "sha512-+HlytyjlPKnIG8XuRG8WvmBP8xs8P71y+SKKS6ZXWoEgLuePxtDoUEiH7WkdePWrQ5JBpE6aoVqfZfJUQkjXwA==", - "dev": true - }, "dns-equal": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/dns-equal/-/dns-equal-1.0.0.tgz", @@ -16600,12 +16763,63 @@ } }, "eazy-logger": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/eazy-logger/-/eazy-logger-3.1.0.tgz", - "integrity": "sha512-/snsn2JqBtUSSstEl4R0RKjkisGHAhvYj89i7r3ytNUKW12y178KDZwXLXIgwDqLW6E/VRMT9qfld7wvFae8bQ==", + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/eazy-logger/-/eazy-logger-4.0.1.tgz", + "integrity": "sha512-2GSFtnnC6U4IEKhEI7+PvdxrmjJ04mdsj3wHZTFiw0tUtG4HCWzTr13ZYTk8XOGnA1xQMaDljoBOYlk3D/MMSw==", "dev": true, "requires": { - "tfunk": "^4.0.0" + "chalk": "4.1.2" + }, + "dependencies": { + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "requires": { + "color-convert": "^2.0.1" + } + }, + "chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true + }, + "supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "requires": { + "has-flag": "^4.0.0" + } + } } }, "ee-first": { @@ -16704,22 +16918,22 @@ } }, "engine.io-client": { - "version": "6.2.3", - "resolved": "https://registry.npmjs.org/engine.io-client/-/engine.io-client-6.2.3.tgz", - "integrity": "sha512-aXPtgF1JS3RuuKcpSrBtimSjYvrbhKW9froICH4s0F3XQWLxsKNxqzG39nnvQZQnva4CMvUK63T7shevxRyYHw==", + "version": "6.4.0", + "resolved": "https://registry.npmjs.org/engine.io-client/-/engine.io-client-6.4.0.tgz", + "integrity": "sha512-GyKPDyoEha+XZ7iEqam49vz6auPnNJ9ZBfy89f+rMMas8AuiMWOZ9PVzu8xb9ZC6rafUqiGHSCfu22ih66E+1g==", "dev": true, "requires": { "@socket.io/component-emitter": "~3.1.0", "debug": "~4.3.1", "engine.io-parser": "~5.0.3", - "ws": "~8.2.3", + "ws": "~8.11.0", "xmlhttprequest-ssl": "~2.0.0" }, "dependencies": { "ws": { - "version": "8.2.3", - "resolved": "https://registry.npmjs.org/ws/-/ws-8.2.3.tgz", - "integrity": "sha512-wBuoj1BDpC6ZQ1B7DWQBYVLphPWkm8i9Y0/3YdHjHKHiohOJ1ws+3OccDWtH+PoC9DZD5WOTrJvNbWvjS6JWaA==", + "version": "8.11.0", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.11.0.tgz", + "integrity": "sha512-HPG3wQd9sNQoT9xHyNCXoDUa+Xw/VevmY9FoHyQ+g+rrMn4j6FB4np7Z0OhdTgjx6MgQLK7jwSy1YecU1+4Asg==", "dev": true, "requires": {} } @@ -21090,15 +21304,6 @@ "integrity": "sha1-pfE/957zt0D+MKqAP7CfmIBdR4I=", "dev": true }, - "rxjs": { - "version": "5.5.12", - "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-5.5.12.tgz", - "integrity": "sha512-xx2itnL5sBbqeeiVgNPVuQQ1nC8Jp2WfNJhXWHmElW9YmrpS9UVnNzhP3EH3HFqexO5Tlp8GhYY+WEcqcVMvGw==", - "dev": true, - "requires": { - "symbol-observable": "1.0.1" - } - }, "safe-buffer": { "version": "5.1.2", "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", @@ -21620,14 +21825,14 @@ "dev": true }, "socket.io-client": { - "version": "4.5.4", - "resolved": "https://registry.npmjs.org/socket.io-client/-/socket.io-client-4.5.4.tgz", - "integrity": "sha512-ZpKteoA06RzkD32IbqILZ+Cnst4xewU7ZYK12aS1mzHftFFjpoMz69IuhP/nL25pJfao/amoPI527KnuhFm01g==", + "version": "4.6.1", + "resolved": "https://registry.npmjs.org/socket.io-client/-/socket.io-client-4.6.1.tgz", + "integrity": "sha512-5UswCV6hpaRsNg5kkEHVcbBIXEYoVbMQaHJBXJCyEQ+CiFPV1NIOY0XOFWG4XR4GZcB8Kn6AsRs/9cy9TbqVMQ==", "dev": true, "requires": { "@socket.io/component-emitter": "~3.1.0", "debug": "~4.3.2", - "engine.io-client": "~6.2.3", + "engine.io-client": "~6.4.0", "socket.io-parser": "~4.2.1" } }, @@ -22040,12 +22245,6 @@ "util.promisify": "~1.0.0" } }, - "symbol-observable": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/symbol-observable/-/symbol-observable-1.0.1.tgz", - "integrity": "sha512-Kb3PrPYz4HanVF1LVGuAdW6LoVgIwjUYJGzFe7NDrBLCN4lsV/5J0MFurV+ygS4bRVwrCEt2c7MQ1R2a72oJDw==", - "dev": true - }, "tapable": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/tapable/-/tapable-1.1.3.tgz", @@ -22176,43 +22375,6 @@ } } }, - "tfunk": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/tfunk/-/tfunk-4.0.0.tgz", - "integrity": "sha512-eJQ0dGfDIzWNiFNYFVjJ+Ezl/GmwHaFTBTjrtqNPW0S7cuVDBrZrmzUz6VkMeCR4DZFqhd4YtLwsw3i2wYHswQ==", - "dev": true, - "requires": { - "chalk": "^1.1.3", - "dlv": "^1.1.3" - }, - "dependencies": { - "ansi-styles": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", - "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=", - "dev": true - }, - "chalk": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", - "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", - "dev": true, - "requires": { - "ansi-styles": "^2.2.1", - "escape-string-regexp": "^1.0.2", - "has-ansi": "^2.0.0", - "strip-ansi": "^3.0.0", - "supports-color": "^2.0.0" - } - }, - "supports-color": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", - "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=", - "dev": true - } - } - }, "through": { "version": "2.3.8", "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", @@ -22338,16 +22500,10 @@ "integrity": "sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c=", "dev": true }, - "typescript": { - "version": "4.9.4", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.9.4.tgz", - "integrity": "sha512-Uz+dTXYzxXXbsFpM86Wh3dKCxrQqUcVMxwU54orwlJjOpO3ao8L7j5lH+dWfTwgCwIuM9GQ2kvVotzYJMXTBZg==", - "dev": true - }, "ua-parser-js": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/ua-parser-js/-/ua-parser-js-1.0.2.tgz", - "integrity": "sha512-00y/AXhx0/SsnI51fTc0rLRmafiGOM4/O+ny10Ps7f+j/b8p/ZY11ytMgznXkOVo4GQ+KwQG5UQLkLGirsACRg==", + "version": "1.0.35", + "resolved": "https://registry.npmjs.org/ua-parser-js/-/ua-parser-js-1.0.35.tgz", + "integrity": "sha512-fKnGuqmTBnIE+/KXSzCn4db8RTigUzw1AN0DmdU6hJovUTbYJKyqj+8Mt1c4VfRDnOVJnENmfYkIPZ946UrSAA==", "dev": true }, "uglify-js": { diff --git a/package.json b/package.json index 71ac66fa..3eb43407 100644 --- a/package.json +++ b/package.json @@ -26,7 +26,7 @@ }, "homepage": "https://github.com/AtreNet/prebid.github.io#readme", "devDependencies": { - "browser-sync": "^2.27.11", + "browser-sync": "^2.29.1", "browser-sync-webpack-plugin": "^2.0.1", "cross-env": "^7.0.2", "laravel-mix": "^5.0.7", From be0652695b857796fd46048f6ce9e5ac5ff56df6 Mon Sep 17 00:00:00 2001 From: ValeriiBarsuk <121865116+ValeriiBarsuk@users.noreply.github.com> Date: Mon, 17 Apr 2023 20:29:50 +0200 Subject: [PATCH 169/762] Updated PBS-database AMP, stored requests query (#4460) * Updated PBS-database AMP, stored requests query * Resolved remark * wordsmithing * updating to clarify top-level/imp-level --------- Co-authored-by: Valerii Barsuk Co-authored-by: bretg --- prebid-server/features/pbs-storedreqs-java.md | 23 ++++++++++-------- prebid-server/hosting/pbs-database.md | 24 +++++++++++-------- 2 files changed, 27 insertions(+), 20 deletions(-) diff --git a/prebid-server/features/pbs-storedreqs-java.md b/prebid-server/features/pbs-storedreqs-java.md index c3444295..d9249deb 100644 --- a/prebid-server/features/pbs-storedreqs-java.md +++ b/prebid-server/features/pbs-storedreqs-java.md @@ -14,8 +14,8 @@ title: Prebid Server | Features | Setting Up Stored Requests for Java ## Overview There are two different kinds of stored requests: -- **impression-level stored requests**: these are scoped to the contents of a single OpenRTB `imp` object -- **top-level stored requests**: these are scoped to the entire OpenRTB package, and is where you can place details in ext.prebid, tmax, site, etc. It is not recommended to place imp objects in this type of stored request. +- **impression-level stored requests**: these are scoped to the contents of a single OpenRTB `imp` object. Prebid Server defines these in imp[].ext.prebid.storedrequest. +- **top-level stored requests**: these are scoped to the entire OpenRTB package, and is where you can place details in ext.prebid, tmax, site, etc. It is not recommended to place imp objects in this type of stored request. Prebid Server defines these in ext.prebid.storedrequest. ## PBS-Java Stored Request Quickstart @@ -141,8 +141,8 @@ HTTP request properties will overwrite the Stored Request ones. ## Top-Level Stored Requests -So far, our examples have only used Stored Imp data. However, Stored Requests -are also allowed on the [BidRequest](https://www.iab.com/wp-content/uploads/2016/03/OpenRTB-API-Specification-Version-2-5-FINAL.pdf#page=15). +So far, our examples have only used impression-level data. However, Stored Requests +are also allowed at the top level at ext.prebid.storedrequest. These work exactly the same way, but support storing properties like timeouts and price granularity. For example, assume the following `stored-requests/{id}.json`: @@ -197,11 +197,13 @@ will produce the same auction as if the HTTP request had been: } ``` -Prebid Server does allow Stored BidRequests and Stored Imps in the same HTTP Request. -The Stored BidRequest will be applied first, and then the Stored Imps after. +Prebid Server does allow both top-level and impression-level stored requests in the same HTTP Request. +The top-level stored request will be applied first, and then the impression-level stored request. **Beware**: Stored Request data will not be applied recursively. -If a Stored BidRequest includes Imps with their own Stored Request IDs, then the data for those Stored Imps will not be resolved. +If a Stored BidRequest includes Imps with their own Stored Request IDs, then the data for the contained Stored Imps will not be resolved. + +**Note**: However, stored requests may contain [storedresponses](/prebid-server/endpoints/openrtb2/pbs-endpoint-auction.html#stored-responses). ## Alternate backends @@ -225,8 +227,8 @@ settings: ``` The select query columns of `stored-requests-query` and `amp-stored-requests-query` properties should correspond to the specific format: -- first column: account ID which is searched by. -- second column: ID of stored data item which is searched by. +- first column: account ID, which is used to make sure that storedrequests are unique to the account +- second column: ID of stored data item - third column: value of stored data item. - forth column: type of stored data item. Can be `request` for stored requests or `imp` for stored impressions. @@ -277,7 +279,7 @@ settings: dbname: database-name user: username password: password - stored-requests-query: SELECT accountId, reqid, requestData, 'request' as dataType FROM stored_requests WHERE reqid IN (%REQUEST_ID_LIST%) UNION ALL SELECT accountId, impid, impData, 'imp' as dataType FROM stored_imps WHERE impid IN (%IMP_ID_LIST%) + stored-requests-query: SELECT accountId, reqid, requestData, 'request' as dataType FROM stored_requests WHERE reqid IN (%REQUEST_ID_LIST%) UNION ALL SELECT accountId, impid, impData, 'imp' as dataType FROM stored_requests WHERE impid IN (%IMP_ID_LIST%) amp-stored-requests-query: SELECT accountId, reqid, requestData, 'request' as dataType FROM stored_requests WHERE reqid IN (%REQUEST_ID_LIST%) http: endpoint: http://stored-requests.prebid.com @@ -296,3 +298,4 @@ Refresh rate can be negative or zero - in such case the data will be fetched onc ## Related Reading - [Stored Responses](/prebid-server/endpoints/openrtb2/pbs-endpoint-auction.html#stored-responses) +- [Hosting a PBS database](/prebid-server/hosting/pbs-database.html) diff --git a/prebid-server/hosting/pbs-database.md b/prebid-server/hosting/pbs-database.md index 084e7e6c..4554dc56 100644 --- a/prebid-server/hosting/pbs-database.md +++ b/prebid-server/hosting/pbs-database.md @@ -57,20 +57,22 @@ The Stored Request query needs to return fields in this order: There are two parameters that can be passed into the query: -- %REQUEST_ID_LIST% : a comma-separated list of "top-level" stored request IDs -- %IMP_ID_LIST% : a comma-separated list of "impression-level" stored request IDs +- %REQUEST_ID_LIST% : a comma-separated list of "top-level" stored request IDs - these are the IDs in ext.prebid.storedrequest.id. +- %IMP_ID_LIST% : a comma-separated list of "impression-level" stored request IDs - these are the IDs in imp[].ext.prebid.storedrequest.id. This query is defined in settings.database.stored-requests-query. Example: ``` settings: database: type: mysql - stored-requests-query: SELECT uuid, config, 'request' as dataType FROM stored_requests WHERE uuid IN (%REQUEST_ID_LIST%) UNION ALL SELECT uuid, config, 'imp' as dataType FROM stored_requests WHERE uuid IN (%IMP_ID_LIST%) + stored-requests-query: SELECT accountId, reqid, storedData, 'request' as dataType FROM stored_requests WHERE reqid IN (%REQUEST_ID_LIST%) UNION ALL SELECT accountId, reqid, storedData, 'imp' as dataType FROM stored_requests WHERE reqid IN (%IMP_ID_LIST%) ``` This example assumes that the schema includes these fields: -- uuid is a string field that contains the stored request ID -- config is a JSON field that contains the body of the stored request +- accountId: account ID, which is used to make sure that storedrequests are unique to the account +- reqid: ID of stored data item +- storedData: value of stored data item +- 'request' or 'imp': type of stored data item. Again, you can name the fields however you'd like in your database, and the query can be arbitrarily complicated as long as it returns the fields in the order and types shown here. @@ -84,12 +86,14 @@ This query is defined in settings.database.amp-stored-requests-query. Example: settings: database: type: mysql - stored-requests-query: SELECT uuid, config, 'request' as dataType FROM stored_requests WHERE uuid IN (%REQUEST_ID_LIST%) + amp-stored-requests-query: SELECT accountId, reqid, storedData, 'request' as dataType FROM stored_requests WHERE reqid IN (%REQUEST_ID_LIST%) ``` This example assumes that the stored_requests schema includes these fields: -- uuid is a string field that contains the stored request ID -- config is a JSON field that contains the body of the stored request +- accountId: account ID, which is used to make sure that storedrequests are unique to the account +- reqid: ID of stored data item +- storedData: value of stored data item +- 'request': type of stored data item. Can be only be 'request' for AMP. Again, you can name the fields however you'd like in your database, and the query can be arbitrarily complicated as long as it returns the fields in the order and types shown here. @@ -105,8 +109,8 @@ The Stored Response query needs to return fields in this order: One parameter can be passed into the query, though at this point, the parameter differs between Go and Java: -- %RESPONSE_ID_LIST% (PBS-Java): a comma-separated list of stored response IDs -- %ID_LIST% (PBS-Go): a comma-separated list of stored response IDs +- %RESPONSE_ID_LIST% (PBS-Java): a comma-separated list of stored response IDs. These come from imp[].ext.prebid.storedbidresponse or imp[].ext.prebid.storedauctionresponse. +- %ID_LIST% (PBS-Go): a comma-separated list of stored response IDs. These come from imp[].ext.prebid.storedbidresponse or imp[].ext.prebid.storedauctionresponse. This query is defined in settings.database.stored-requests-query. Example: ``` From 763401e5ed5cb38177d832a0c14fa1c3ef27dcbf Mon Sep 17 00:00:00 2001 From: bretg Date: Tue, 18 Apr 2023 09:21:08 -0400 Subject: [PATCH 170/762] Floors enforcePBS default is true on the server side (#4489) --- dev-docs/modules/floors.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/dev-docs/modules/floors.md b/dev-docs/modules/floors.md index 12a7f182..30f41fde 100644 --- a/dev-docs/modules/floors.md +++ b/dev-docs/modules/floors.md @@ -293,7 +293,7 @@ a subset that will be merged under the 'data' object. | enforcement | object | Controls the enforcement behavior within the Price Floors Module.| - | | skipRate | integer | skipRate is a random function whose input value is any integer 0 through 100 to determine when to skip all floor logic, where 0 is always use floor data and 100 is always skip floor data. The use case is for publishers or floor providers to learn bid behavior when floors are applied or skipped. Analytics adapters will have access to model version (if defined) when skipped is true to signal the Price Floors Module is in floors mode. If skipRate is supplied in both the root level of the floors object and within the data object, the skipRate configuration within the data object shall prevail. | 0 | | enforcement.enforceJS | boolean | If set to true, the Price Floors Module will provide floors to bid adapters for bid request matched rules and suppress any bids not exceeding a matching floor. If set to false, the Price Floors Module will still provide floors for bid adapters, there will be no floor enforcement.| true | -| enforcement.enforcePBS | boolean | If set to true, the Price Floors Module will signal to Prebid Server to pass floors to it’s bid adapters and enforce floors. If set to false, the pbjs should still pass matched bid request floor data to PBS, however no enforcement will take place. | false | +| enforcement.enforcePBS | boolean | If set to true, the Price Floors Module will signal to Prebid Server to pass floors to it’s bid adapters and enforce floors. If set to false, the pbjs should still pass matched bid request floor data to PBS, however no enforcement will take place. | true | | enforcement.floorDeals | boolean | Enforce floors for deal bid requests. | false | | enforcement.bidAdjustment | boolean | If true, the Price Floors Module will use the bidAdjustment function to adjust the floor per bidder. If false (or no bidAdjustment function is provided), floors will not be adjusted. Note: Setting this parameter to false may have unexpected results, such as signaling a gross floor when expecting net or vice versa. | true | | endpoint | object | Prebid.js only: controls behavior for dynamically retrieving floors. | - | @@ -354,7 +354,7 @@ a subset that will be merged under the 'data' object. | location | string | Prebid Server only: this is a read-only field set by the Prebid-Server floors feature to let analytics adapters know where the floors data came from. Possible values are: 'request', 'fetch' or 'noData'. | n/a | | enforcement | object | Controls the enforcement behavior within the module.| - | | enforcement.enforceJS | boolean | If set to true, the module will provide floors to bid adapters for bid request matched rules and suppress any bids not exceeding a matching floor. If set to false, the module will still provide floors for bid adapters, but there will be no floor enforcement.| true | -| enforcement.enforcePBS | boolean | If set to true, the module will signal to Prebid Server to pass floors to it’s bid adapters and enforce floors. If set to false, Prebid.js should still pass matched bid request floor data to Prebid Server, however no enforcement will take place. | false | +| enforcement.enforcePBS | boolean | If set to true, the module will signal to Prebid Server to pass floors to it’s bid adapters and enforce floors. If set to false, Prebid.js should still pass matched bid request floor data to Prebid Server, however no enforcement will take place. | true | | enforcement.floorDeals | boolean | Enforce floors for deal bid requests. | false | | enforcement.bidAdjustment | boolean | If true, the module will use the bidAdjustment function to adjust the floor per bidder. If false (or no bidAdjustment function is provided), floors will not be adjusted. Note: Setting this parameter to false may have unexpected results, such as signaling a gross floor when expecting net or vice versa. | true | | enforcement.enforceRate | integer | Prebid Server only: Defines a percentage for how often bid response enforcement activity should take place given that the floors feature is active. If the floors feature is skipped due to skipRate, this has no affect. For every non-skipped auction, this percent of them should be enforced: i.e. bids discarded. This feature lets publishers ease into enforcement in case bidders aren't adhering to floor rules. | 100 | From 42c1c660b5ca5f5565d45a079548d116b2c56288 Mon Sep 17 00:00:00 2001 From: Yuriy Velichko Date: Tue, 18 Apr 2023 19:49:51 +0300 Subject: [PATCH 171/762] Mobile: Restore the description of Prebid SDK utilization with 3rd party ad server (#4363) * ios: restore the description of Prebid SDK utilization with 3rd party ad server * fix typo, update statement * android: restore the description of Prebid SDK utilization with 3rd party ad server * fix broken link --- .../rendering/android-sdk-integration-pb.md | 68 ++++++++++++++++-- .../rendering/ios-sdk-integration-pb.md | 71 ++++++++++++++++--- ...ndroid-sdk-integration-gam-original-api.md | 2 +- 3 files changed, 125 insertions(+), 16 deletions(-) diff --git a/prebid-mobile/modules/rendering/android-sdk-integration-pb.md b/prebid-mobile/modules/rendering/android-sdk-integration-pb.md index 0d6aab3d..64f053f5 100644 --- a/prebid-mobile/modules/rendering/android-sdk-integration-pb.md +++ b/prebid-mobile/modules/rendering/android-sdk-integration-pb.md @@ -7,19 +7,73 @@ sidebarType: 2 --- -# Custom Integration +# Custom Bidding Integration {:.no_toc} -## Overview of Rendering API +You can use Prebid SDK to monetize your app with a custom ad server or even without it. Use the `Transport API` to obtain the targeting keywords for following usage with the custom ad server. Use the `Rendering API` to display the winning bid without primary ad server and its SDK. + +* TOC +{:toc} + +## Transport API + +The default ad server for Prebid's Mobile SDK is GAM. The SDK can be expanded to include support for 3rd party ad servers through the fetchDemand function. This function returns the Prebid Server bidder key/values (targeting keys), which can then be passed to the ad server of choice. + +In this mode, the publisher will be responsible for the following actions: + +* Call fetchDemand with extended targetingDict callback +* Retrieve targeting keys from extended fetchDemand function +* Convert targeting keys into the format for your ad server +* Pass converted keys to your ad server +* Render ad with Prebid Universal Creative or custom renderer + +This approach is avaliable for the following ad formats: + +* Display Banner via `BannerAdUnit` +* Video Banner and Instream Video via `VideoAdUnit` +* Display Interstitial via `InterstitialAdUnit` +* Video Interstitial via `VideoInterstitialAdUnit` +* Rewarded Video via `RewardedVideoAdUnit` +* Native Styles via `NativeRequest` + +The basic integration steps for these ad units you can find at the page for integration using [Original API](/prebid-mobile/pbm-api/android/android-sdk-integration-gam-original-api.html). The diference is that you should use the `fetchDemand` function with following signature: + +``` kotlin +public void fetchDemand(@NonNull Object adObj, + @NonNull OnCompleteListener2 listener) { ... } + +public interface OnCompleteListener2 { + /** + * This method will be called when PrebidMobile finishes attaching keywords to unmodifiableMap. + * @param resultCode see {@link ResultCode} class definition for details + * @param unmodifiableMap a map of targeting Key/Value pairs + */ + @MainThread + void onComplete(ResultCode resultCode, + @Nullable Map unmodifiableMap); +} +``` + +Examples: + +``` kotlin +private fun loadRewardedVideo() { + adUnit?.fetchDemand { resultCode, unmodifiableMap -> + val keywords: Map = HashMap(unmodifiableMap) + + adServerObject.loadRewardedVideo(ADUNITID_REWARDED, keywords) + } +} +``` + +## Rendering API The integration and usage of the Rendering API is similar to any other Ad SDK. It sends the bid requests to the Prebid Server and renders the winning bid. ![Rendering with GAM as the Primary Ad Server](/assets/images/prebid-mobile/modules/rendering/Prebid-In-App-Bidding-Overview-Pure-Prebid.png) -* TOC -{:toc} -## Banner API +### Banner API Integration example: @@ -61,7 +115,7 @@ For **Banner Video** you will also need to specify the `bannerView.videoPlacemen bannerView.videoPlacementType = PlacementType.IN_BANNER // or any other available type ``` -## Interstitial API +### Interstitial API Integration example: @@ -115,7 +169,7 @@ override fun onAdLoaded(interstitialAdUnit: InterstitialAdUnit) { } ``` -## Rewarded API +### Rewarded API Integration example: diff --git a/prebid-mobile/modules/rendering/ios-sdk-integration-pb.md b/prebid-mobile/modules/rendering/ios-sdk-integration-pb.md index 18a6e1ad..cafc31fe 100644 --- a/prebid-mobile/modules/rendering/ios-sdk-integration-pb.md +++ b/prebid-mobile/modules/rendering/ios-sdk-integration-pb.md @@ -10,16 +10,71 @@ sidebarType: 2 # Custom Bidding Integration {:.no_toc} -## Mobile API - -The integration and usage of the Rendering API are similar to any other Ad SDK. It sends the bid requests to the Prebid Server and renders the winning bid. - -![In-App Bidding with Prebid](/assets/images/prebid-mobile/modules/rendering/Prebid-In-App-Bidding-Overview-Pure-Prebid.png) +You can use Prebid SDK to monetize your app with a custom ad server or even without it. Use the `Transport API` to obtain the targeting keywords for following usage with the custom ad server. Use the `Rendering API` to display the winning bid without primary ad server and its SDK. * TOC {:toc} -## Banner API +## Transport API + +The default ad server for Prebid's Mobile SDK is GAM. The SDK can be expanded to include support for 3rd party ad servers through the fetchDemand function. This function returns the Prebid Server bidder key/values (targeting keys), which can then be passed to the ad server of choice. + +In this mode, the publisher will be responsible for the following actions: + +* Call fetchDemand with extended targetingDict callback +* Retrieve targeting keys from extended fetchDemand function +* Convert targeting keys into the format for your ad server +* Pass converted keys to your ad server +* Render ad with Prebid Universal Creative or custom renderer + +This approach is avaliable for the following ad formats: + +* Display Banner via `BannerAdUnit` +* Video Banner and Instream Video via `VideoAdUnit` +* Display Interstitial via `InterstitialAdUnit` +* Video Interstitial via `VideoInterstitialAdUnit` +* Rewarded Video via `RewardedVideoAdUnit` +* Native Styles via `NativeRequest` + +The basic integration steps for these ad units you can find at the page for integration using [Original API](/prebid-mobile/pbm-api/ios/ios-sdk-integration-gam-original-api.html). The diference is that you should use the `fetchDemand` function with following signature: + +``` swift +dynamic public func fetchDemand( + completion: @escaping(_ result: ResultCode, + _ kvResultDict: [String : String]?) -> Void) +``` + +Examples: + +```swift +func loadBanner() { + + //adUnit is BannerAdUnit type + adUnit.fetchDemand { [weak self] (resultCode: ResultCode, targetingDict: [String : String]?) in + + self?.adServerRequest.customTargeting = targetingDict + self?.adServerBanner.load(self?.adServerRequest) + } +} + +func loadRewardedVideo() { + let adUnit = RewardedVideoAdUnit(configId: "1001-1") + adUnit.fetchDemand { [weak self] (resultCode: ResultCode, targetingDict: [String : String]?) in + + //Publisher should provide support for converting keys into format of 3rd party ad server and loading ads + let keywords = convertDictToAdServerKeywords(dict: targetingDict) + AdServerLoadAds.loadAd(withAdUnitID: "46d2ebb3ccd340b38580b5d3581c6434", keywords: keywords) + } +} +``` + +## Rendering API + +The Rendering API integration and usage are similar to any other Ad SDK. In this case, Prebid SDK sends the bid requests to the Prebid Server and renders the winning bid. + +![In-App Bidding with Prebid](/assets/images/prebid-mobile/modules/rendering/Prebid-In-App-Bidding-Overview-Pure-Prebid.png) + +### Banner API Integration example: @@ -61,7 +116,7 @@ For **Banner Video** you also need to specify the ad format: banner.adFormat = .video ``` -## Interstitial API +### Interstitial API Integration example: @@ -126,7 +181,7 @@ func interstitialDidReceiveAd(_ interstitial: InterstitialRenderingAdUnit) { } ``` -## Rewarded API +### Rewarded API Integration example: diff --git a/prebid-mobile/pbm-api/android/android-sdk-integration-gam-original-api.md b/prebid-mobile/pbm-api/android/android-sdk-integration-gam-original-api.md index 191cd922..cead15dc 100755 --- a/prebid-mobile/pbm-api/android/android-sdk-integration-gam-original-api.md +++ b/prebid-mobile/pbm-api/android/android-sdk-integration-gam-original-api.md @@ -994,7 +994,7 @@ If the `AdManagerAdRequest ` contains targeting keywords, the respective Prebid #### Step 4: Implement OnCustomFormatAdLoadedListener protocol {:.no_toc} -In order to capture the native ad response you will need to implement [OnCustomFormatAdLoadedListener](https://radeon-drivers.com/?_=%2Fandroid%2Freference%2Fcom%2Fgoogle%2Fandroid%2Fgms%2Fads%2Fnativead%2FNativeCustomFormatAd.OnCustomFormatAdLoadedListener%23UUlexhFFzSDzTfOQ54KBpjGsLVY524B1MgR06Ro%3D) protocol. +In order to capture the native ad response you will need to implement [OnCustomFormatAdLoadedListener](https://developers.google.com/android/reference/com/google/android/gms/ads/nativead/NativeCustomFormatAd.OnCustomFormatAdLoadedListener) protocol. You should use following Prebid function to determine whether the Prebid line item should be rendered: From a10d636ea60f41eb4ea02afc96a44954f754cd86 Mon Sep 17 00:00:00 2001 From: Jason Quaccia Date: Tue, 18 Apr 2023 11:36:50 -0700 Subject: [PATCH 172/762] enabling the pm analytics mod to be downloadable (#4494) PubMatic Analytics Adapter will be available on Download page. --- dev-docs/analytics/pubmatic.md | 1 - 1 file changed, 1 deletion(-) diff --git a/dev-docs/analytics/pubmatic.md b/dev-docs/analytics/pubmatic.md index 08a7e348..40d252b8 100644 --- a/dev-docs/analytics/pubmatic.md +++ b/dev-docs/analytics/pubmatic.md @@ -5,7 +5,6 @@ description: PubMatic Analytics Adapter modulecode: pubmatic prebid_member: true gvl_id: 76 -enable_download: false --- #### Registration From 0c74b29a52d49de77a4cf05adbbf049121732abd Mon Sep 17 00:00:00 2001 From: Yuriy Velichko Date: Tue, 18 Apr 2023 23:25:18 +0300 Subject: [PATCH 173/762] mobile: updates for sdk configuration flow (#4423) * mobile: updates for sdk configuration flow * doc: do not use test PBS URL in the public doc --- .../android/code-integration-android.md | 40 +++++++++----- .../pbm-api/ios/code-integration-ios.md | 55 +++++++++++++------ 2 files changed, 64 insertions(+), 31 deletions(-) diff --git a/prebid-mobile/pbm-api/android/code-integration-android.md b/prebid-mobile/pbm-api/android/code-integration-android.md index 63c19f75..8b4842ce 100644 --- a/prebid-mobile/pbm-api/android/code-integration-android.md +++ b/prebid-mobile/pbm-api/android/code-integration-android.md @@ -63,7 +63,9 @@ If you see errors while building the Prebid Mobile SDK or Demo Applications, mak {% include /alerts/alert_warning.html content=warning_note %} -## Initialize SDK +## Add SDK + +### Set Prebid Server {% capture warning_note %} All integration examples for Android are written in `Kotlin`. @@ -80,28 +82,40 @@ PrebidMobile.setPrebidServerAccountId(YOUR_ACCOUNT_ID) PrebidMobile.setPrebidServerHost(Host.APPNEXUS) ``` -If you have opted to host your own Prebid Server solution you will need to store the url to the server in your app. +If you have opted to host your own Prebid Server solution you will need to store the url to the server in your app. Make sure that your URL points to the [/openrtb2/auction](https://docs.prebid.org/prebid-server/endpoints/openrtb2/pbs-endpoint-auction.html) endpoint. + ``` -PrebidMobile.setPrebidServerHost(Host.createCustomHost("https://prebid-server-test-j.prebid.org/openrtb2/auction")) +PrebidMobile.setPrebidServerHost(Host.createCustomHost(PREBID_SERVER_AUCTION_ENDPOINT)) ``` -Once you set the account ID and the Prebid Server host, you should initialize the Prebid SDK. There are several options for how to do it. +### Initialize SDK -Use the following initialization for Prebid SDK: +Once you set the account ID and the Prebid Server host, you should initialize the Prebid SDK. Use the following initialization for Prebid SDK: ```kotlin -PrebidMobile.initializeSdk(applicationContext, object : SdkInitializationListener { - override fun onSdkInit() { - TODO("Not yet implemented") +PrebidMobile.initializeSdk(applicationContext) { status -> + if (status == InitializationStatus.SUCCEEDED) { + Log.d(TAG, "SDK initialized successfully!") + } else if (status == InitializationStatus.SERVER_STATUS_WARNING) { + Log.e(TAG, "Prebid Server status checking failed: $status\n${status.description}") } - - override fun onSdkFailedToInit(error: InitError?) { - TODO("Not yet implemented") + else { + Log.e(TAG, "SDK initialization error: $status\n${status.description}") } -}) +} ``` +During the initialization, SDK creates internal classes and performs the health check request to the [/status](https://docs.prebid.org/prebid-server/endpoints/pbs-endpoint-status.html) endpoint. If you use a custom PBS host you should provide a custom status endpoint as well: + +``` +PrebidMobile.setCustomStatusEndpoint(PREBID_SERVER_STATUS_ENDPOINT) +``` + +If something goes wrong with the request, the status of the initialization callback will be `SERVER_STATUS_WARNING`. It doesn't affect an SDK flow and just informs you about the health check result. + +### Check compatibility with your GMA SDK + If you integrate Prebid Mobile with GMA SDK, use the following method, which checks the compatibility of Prebid SDK with GMA SDK used in the app: ```kotlin @@ -182,7 +196,7 @@ Apply global settings with the `PrebidMobile` object. String containing the Prebid Server account ID. ```kotlin -PrebidMobile.setPrebidServerAccountId("123321") +PrebidMobile.setPrebidServerAccountId(YOUR_ACCOUNT_ID) var pbsAccountId = PrebidMobile.getPrebidServerAccountId() ``` diff --git a/prebid-mobile/pbm-api/ios/code-integration-ios.md b/prebid-mobile/pbm-api/ios/code-integration-ios.md index a5114a59..bc62c341 100644 --- a/prebid-mobile/pbm-api/ios/code-integration-ios.md +++ b/prebid-mobile/pbm-api/ios/code-integration-ios.md @@ -88,49 +88,68 @@ scripts/buildPrebidMobile.sh This will output the PrebidMobile.framework. -## Initialize SDK +## Add SDK + +### Set Prebid Server Once you have a [Prebid Server](/prebid-mobile/prebid-mobile-getting-started.html), you will add 'account' info to the Prebid Mobile. For example, if you're using the AppNexus Prebid Server: ``` -Prebid.shared.prebidServerAccountId = "YOUR_ACCOUNT_ID" +Prebid.shared.prebidServerAccountId = YOUR_ACCOUNT_ID Prebid.shared.prebidServerHost = .Appnexus ``` -If you have opted to host your own Prebid Server solution, you will need to store the URL to the server in your app. +If you have opted to host your own Prebid Server solution, you will need to store the URL to the server in your app. Make sure that your URL points to the [/openrtb2/auction](https://docs.prebid.org/prebid-server/endpoints/openrtb2/pbs-endpoint-auction.html) endpoint. ``` -try! Prebid.shared.setCustomPrebidServer(url: "https://prebid-server-test-j.prebid.org/openrtb2/auction") +try! Prebid.shared.setCustomPrebidServer(url: PREBID_SERVER_AUCTION_ENDPOINT) ``` This method throws an exception if the provided URL is invalid. +### Initialize SDK + Once you set the account ID and the Prebid Server host, you should initialize the Prebid SDK. There are several options for how to do it. -For the No Ad Server scenario, use the following initialization: +If you integrate Prebid Mobile with GMA SDK, use the following initializer, which checks the compatibility of Prebid SDK with GMA SDK used in the app: +``` swift +Prebid.initializeSDK(GADMobileAds.sharedInstance()) { status, error in + switch status { + case .succeeded: + print("Prebid SDK successfully initialized") + case .failed: + if let error = error { + print("An error occurred during Prebid SDK initialization: \(error.localizedDescription)") + } + case .serverStatusWarning: + if let error = error { + print("Prebid Server status checking failed: \(error.localizedDescription)") + } + default: + break + } +} ``` + +Check the log messages of the app. If the provided GMA SDK version is not verified for compatibility, the Prebid SDK informs about it. + +For the No Ad Server scenario, use the following initialization: + +``` swift Prebid.initializeSDK { status, error in - if let error = error { - print("Initialization Error: \(error.localizedDescription)") - return - } + // .... } ``` -If you integrate Prebid Mobile with GMA SDK, use the following initializer, which checks the compatibility of Prebid SDK with GMA SDK used in the app: - +During the initialization, SDK creates internal classes and performs the health check request to the [/status](https://docs.prebid.org/prebid-server/endpoints/pbs-endpoint-status.html) endpoint. If you use a custom PBS host you should provide a custom status endpoint as well: ``` -Prebid.initializeSDK(GADMobileAds.sharedInstance()) { status, error in - if let error = error { - print("Initialization Error: \(error.localizedDescription)") - return - } -} +Prebid.shared.customStatusEndpoint = PREBID_SERVER_STATUS_ENDPOINT ``` -Check the log messages of the app. If the provided GMA SDK version is not verified for compatibility, the Prebid SDK informs about it. +If something goes wrong with the request, the status of the initialization callback will be `.serverStatusWarning`. It doesn't affect an SDK flow and just informs you about the health check result. + ## Set Targeting Parameters From 2774b4e184588d73cbba01248f54161e7e4cf9da Mon Sep 17 00:00:00 2001 From: bretg Date: Wed, 19 Apr 2023 10:58:28 -0400 Subject: [PATCH 174/762] trustx: update PBS support (#4499) removing the PBS flag from the 'standalone' docs file, which was intended for PBJS only --- dev-docs/bidders/trustxstandalone.md | 1 - 1 file changed, 1 deletion(-) diff --git a/dev-docs/bidders/trustxstandalone.md b/dev-docs/bidders/trustxstandalone.md index 95197714..45c8797b 100644 --- a/dev-docs/bidders/trustxstandalone.md +++ b/dev-docs/bidders/trustxstandalone.md @@ -3,7 +3,6 @@ layout: bidder title: TrustX (standalone) description: Prebid TrustX Bidder Adaptor pbjs: true -pbs: true biddercode: trustx media_types: banner, video multiformat_supported: will-bid-on-any From 3f535608bce1dde3e3a6ba3ce7b97c86e935580c Mon Sep 17 00:00:00 2001 From: rimaburder-index <55195208+rimaburder-index@users.noreply.github.com> Date: Wed, 19 Apr 2023 11:15:43 -0400 Subject: [PATCH 175/762] Updated Index's PBS docs (#4492) Updated bid request limit note --- dev-docs/bidders/ix-server.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dev-docs/bidders/ix-server.md b/dev-docs/bidders/ix-server.md index ea75fe71..dbcd1baa 100644 --- a/dev-docs/bidders/ix-server.md +++ b/dev-docs/bidders/ix-server.md @@ -51,7 +51,7 @@ Publishers can use Prebid Server in any of the following ways with Index Exchang * In CTV apps and other long-form video environments, you (or the SSAI vendor) can make a call to Prebid Server using OpenRTB, and then Prebid Server uses our server-side adapter to call Index. For set up instructions, see [Call Index from CTV/long-form video environment](#set-up-instructions-to-call-index-through-prebid-server) section on this page. * In any other server-to-server OpenRTB environment, you can send OpenRTB bid requests to the Prebid Server host of your choice. For set up instructions, see [Call Index from any other server-to-server OpenRTB environment](#call-index-from-ortb) section on this page. -**Note about the bid request limit:** You can send up to 20 ad slots in a single bid request to Index. If a single bid request contains more than 20 ad slots, only the first 20 are accepted and the rest are ignored. +**Note about sending multiple ad slots in a single bid request:** Index accepts up to 100 valid ad slots in a single bid request. If a single bid request contains more than 100 ad slots (including invalid ad slots), only the first 100 valid ad slots are accepted and the rest are ignored. For example streaming TV media owners can signal multiple ad pods for long-form programming in a single request. From 7c321526ecd174051795cf5b2324c7924f99853d Mon Sep 17 00:00:00 2001 From: rimaburder-index <55195208+rimaburder-index@users.noreply.github.com> Date: Wed, 19 Apr 2023 11:16:57 -0400 Subject: [PATCH 176/762] updated Index's Prebid.js docs (#4491) Updated bid request limit, added AdUnit-specific data to the FPD module and rearranged the section. --- dev-docs/bidders/ix.md | 61 +++++++++++++++++++++++++----------------- 1 file changed, 37 insertions(+), 24 deletions(-) diff --git a/dev-docs/bidders/ix.md b/dev-docs/bidders/ix.md index 72997706..77ba5ff1 100644 --- a/dev-docs/bidders/ix.md +++ b/dev-docs/bidders/ix.md @@ -32,8 +32,9 @@ sidebarType: 1 - [Set up Prebid.js to call Index through Prebid Server (server-side adapter)](#set-up-prebidjs-to-call-index-through-prebid-server-server-side-adapter) - [Modules to include in your build process](#modules-to-include-in-your-build-process) - [Set up First Party Data (FPD)](#set-up-first-party-data-fpd) - - [Index bidder-specific FPD module](#index-bidder-specific-fpd-module) - - [Prebid FPD module](#prebid-fpd-module) + - [Global data](#prebid-fpd-module) + - [Index bidder-specific data](#index-bidder-specific-fpd-module) + - [AdUnit-specific data](#adunit-specific-data) - [Index's outstream video player](#indexs-outstream-video-player) - [Prebid Native configuration](#prebid-native-configuration) - [Bid request parameters](#bid-request-parameters) @@ -54,13 +55,13 @@ Publishers can use Prebid.js to call Index Exchange (Index) in any of the follow * **Call through our server-side adapter**: Prebid.js makes a call to Prebid Server and then Prebid Server uses our server-side adapter to call Index. This reduces workload on the browser. For configuration instructions, see the [Set up Prebid.js to call Index through Prebid Server (server-side adapter)](#server-side-adapter) on this page. **Notes:** -* **Bid request limit**: You can send up to 20 ad slots in a single bid request to Index. If a single bid request contains more than 20 ad slots, only the first 20 are accepted and the rest are ignored. +* **Send multiple ad slots in a single bid request**: Index accepts up to 100 valid ad slots in a single bid request. If a single bid request contains more than 100 ad slots (including invalid ad slots), only the first 100 valid ad slots are accepted and the rest are ignored. For example streaming TV media owners can signal multiple ad pods for long-form programming in a single request. * **How to view bid requests sent to Index:** * In your browser, open a new tab. * Open the **Developer tools**. * In **Developer tools**, click the **Network** tab. * In the **Network** tab, search for requests sent to `casalemedia.com/cygnus` (from version 6.28.0 and earlier) or `casalemedia.com/openrtb/pbjs` (from version 6.29.0 and later). These are the bid requests sent to Index. -* **Recommended Global Bidder settings:** For our adapter, Index recommends enabling local storage. As of Prebid.js 7.x, local storage access must be explicitly specified. By leveraging local storage, Index is able to take advantage of the latest features our exchange has to offer. For instructions on enabling local storage, see Prebid’s [pbjs.bidderSettings](https://docs.prebid.org/dev-docs/publisher-api-reference/bidderSettings.html) documentation. +* **Recommended Global Bidder settings:** For our adapter, Index recommends enabling local storage. As of Prebid.js 7.x, local storage access must be explicitly specified. By leveraging local storage, Index is able to take advantage of the latest features our exchange has to offer. For instructions on enabling local storage, see Prebid’s [pbjs.bidderSettings](https://docs.prebid.org/dev-docs/publisher-api-reference/bidderSettings.html) documentation.
Example: ```javascript pbjs.bidderSettings = { @@ -198,18 +199,34 @@ If you are using a JSON file to specify modules, add `ixBidAdapter` and `dfpAdSe ## Set up First Party Data (FPD) -You can set up FPD using the Index bidder-specific module (recommended) or the Prebid FPD module. +You can set up the Prebid.js FPD module using Global data, Index bidder-specific site data, or ad unit-specific data. Index supports deal targeting in all the three FPD types. -**Notes:** +
+ +### Global data -* Index does not support ad unit-specific FPD and `ortb2.imp`. -* To target deals with Index, you must use the Index bidder-specific FPD module. The Prebid FPD module does not support deals targeting. If you have any questions or need help setting up the configuration, contact your Index Representative. +Use this data type to allow all bid adapters to have access to first party data that might be useful in ad targeting. This is available from Prebid.js version 4.30 and above. + +To supply data that is accessible to all bidders, use the `[pbjs.setConfig()]` object as illustrated below. Use the `[setBidderConfig()]` function to supply bidder-specific data. For more information about the standard or more detailed examples, see Prebid's [First Party Data Feature](https://docs.prebid.org/features/firstPartyData.html) documentation. + +```javascript +pbjs.setConfig({ + ortb2: { + site: { + ... + }, + user: { + ... + } + } +}); +``` -### Index bidder-specific FPD module +### Index bidder-specific data -This module allows you to specify key-value pairs that will be included in your query string when targeting deals. For example, if a user visits a news page, you can pass that information by submitting a key-value pair for `category = news`. You can then create a deal in the Index UI and activate the deal only on pages that contain `category = news` as the key-value pair. +Use this data type to specify key-value pairs that will be included in your query string when targeting deals. For example, if a user visits a news page, you can pass that information by submitting a key-value pair for `category = news`. You can then create a deal in the Index UI and activate the deal only on pages that contain `category = news` as the key-value pair. To include the FPD in a bid request, in the `[pbjs.setConfig()]` object at the `ix` bidder level, provide the key-values in the `firstPartyData` parameter. Make sure that you set it before the `pbjs.requestBids` configuration. If you want to change the values, you can update the `pbjs.setConfig` once again. The change will be reflected in all future bid requests. @@ -224,26 +241,22 @@ To include the FPD in a bid request, in the `[pbjs.setConfig()]` object at the ` } }); ``` + +### AdUnit-specific data - - -### Prebid FPD module +Use this data type to specify key-value pairs at the ad unit level when targeting deals and apply it to all bidders. This is available from Prebid.js version 7.45 and above. To include the adUnit-specific data in a bid request, see Prebid's [Supplying AdUnit-Specific Data](https://docs.prebid.org/features/firstPartyData.html#supplying-adunit-specific-data) documentation. -This module allows all bid adapters to have access to first party data that might be useful in ad targeting. This is available from Prebid.js version 4.30 and above. -To supply data that is accessible to all bidders, use the `[pbjs.setConfig()]` object as illustrated below. Use the `[setBidderConfig()]` function to supply bidder-specific data. For more information about the standard or more detailed examples, see Prebid's [First Party Data Feature](https://docs.prebid.org/features/firstPartyData.html) documentation. ```javascript -pbjs.setConfig({ - ortb2: { - site: { - ... - }, - user: { - ... +ortb2Imp: { + ext: { + data: { + pbadslot: "homepage-top-rect", + adUnitSpecificAttribute: "123" } - } -}); + } + } ``` From c3feb1513f70e7957a3d380426a2adfb6cc6ed8a Mon Sep 17 00:00:00 2001 From: bretg Date: Wed, 19 Apr 2023 13:56:01 -0400 Subject: [PATCH 177/762] re-adding cleanmedianet (#4500) * re-adding cleanmedianet Per issue https://github.com/prebid/prebid.github.io/issues/4448 * Update cleanmedianet.md * Update cleanmedianet.md --- dev-docs/bidders/cleanmedianet.md | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) create mode 100644 dev-docs/bidders/cleanmedianet.md diff --git a/dev-docs/bidders/cleanmedianet.md b/dev-docs/bidders/cleanmedianet.md new file mode 100644 index 00000000..5b1d420d --- /dev/null +++ b/dev-docs/bidders/cleanmedianet.md @@ -0,0 +1,29 @@ +--- +layout: bidder +title: Clean Media Net +description: Clean Media Bidder Adapter +biddercode: cleanmedianet +pbjs: true +media_types: banner, video +gdpr_supported: false +usp_supported: true +coppa_supported: false +schain_supported: true +floors_supported: true +userIds: +prebid_member: false +safeframes_ok: true +deals_supported: false +pbs_app_supported: false +fpd_supported: false +ortb_blocking_supported: false +gvl_id: +multiformat_supported: will-bid-on-any +--- + +### Bid params + +{: .table .table-bordered .table-striped } +| Name | Scope | Description | Example | Type | +|-------------------+----------+--------------------------------------------------------+-------------------------+---------| +| `supplyPartnerId` | required | The supply account's ID in your Clean Media dashboard. | `"1253"`, `"1254"`, etc | string | From 8cbf858dd8632327be3b102352a86f074340153f Mon Sep 17 00:00:00 2001 From: Muki Seiler Date: Thu, 20 Apr 2023 10:01:27 +0200 Subject: [PATCH 178/762] Support consent mode for google analytics (#4441) * Support consent mode for google analytics * Use onetrustloaded global promise * Working consent for GA --- _includes/footer.html | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) diff --git a/_includes/footer.html b/_includes/footer.html index c734d23e..da9a3fb8 100644 --- a/_includes/footer.html +++ b/_includes/footer.html @@ -9,21 +9,33 @@
+ From fffa44d5b909313c6fb45ec25c83e19a89492a8b Mon Sep 17 00:00:00 2001 From: Muki Seiler Date: Thu, 20 Apr 2023 10:20:30 +0200 Subject: [PATCH 179/762] Revert "Support consent mode for google analytics (#4441)" (#4502) This reverts commit 8cbf858dd8632327be3b102352a86f074340153f. --- _includes/footer.html | 18 +++--------------- 1 file changed, 3 insertions(+), 15 deletions(-) diff --git a/_includes/footer.html b/_includes/footer.html index da9a3fb8..c734d23e 100644 --- a/_includes/footer.html +++ b/_includes/footer.html @@ -9,33 +9,21 @@ - From 9b5d29cae0b2e6d28e28ff29f9d69a5d534bf285 Mon Sep 17 00:00:00 2001 From: Muki Seiler Date: Thu, 20 Apr 2023 13:15:58 +0200 Subject: [PATCH 180/762] Respect consent for google analytics (#4503) * Support consent mode for google analytics * Use onetrustloaded global promise * Working consent for GA * Disable TCF2 support for gtag --- _includes/footer.html | 19 ++++++++++++++++--- 1 file changed, 16 insertions(+), 3 deletions(-) diff --git a/_includes/footer.html b/_includes/footer.html index c734d23e..79da5595 100644 --- a/_includes/footer.html +++ b/_includes/footer.html @@ -9,21 +9,34 @@ + From d7910a667af6546319b99065b792f26dab2677f7 Mon Sep 17 00:00:00 2001 From: Scott Kay Date: Fri, 21 Apr 2023 13:12:22 -0400 Subject: [PATCH 181/762] PBS-Go Feature Updates (#4507) --- dev-docs/modules/multibid.md | 2 +- prebid-server/developers/add-new-bidder-go.md | 2 +- prebid-server/endpoints/openrtb2/pbs-endpoint-auction.md | 6 ------ prebid-server/features/pbs-feature-idx.md | 8 ++++---- 4 files changed, 6 insertions(+), 12 deletions(-) diff --git a/dev-docs/modules/multibid.md b/dev-docs/modules/multibid.md index e9ae46f0..36b3b9cd 100644 --- a/dev-docs/modules/multibid.md +++ b/dev-docs/modules/multibid.md @@ -104,4 +104,4 @@ array returned from the `interpretResponse` function. ## Related Topics -- [MultiBid in the Prebid Server /openrtb2/auction endpoint](/prebid-server/endpoints/openrtb2/pbs-endpoint-auction.html#multibid-pbs-java-only) +- [MultiBid in the Prebid Server /openrtb2/auction endpoint](/prebid-server/endpoints/openrtb2/pbs-endpoint-auction.html#multibid) diff --git a/prebid-server/developers/add-new-bidder-go.md b/prebid-server/developers/add-new-bidder-go.md index b06bb3c8..f52a14e8 100644 --- a/prebid-server/developers/add-new-bidder-go.md +++ b/prebid-server/developers/add-new-bidder-go.md @@ -494,7 +494,7 @@ import ( "fmt" "net/http" - "github.com/prebid/openrtb/v17/openrtb2" + "github.com/prebid/openrtb/v19/openrtb2" "github.com/prebid/prebid-server/adapters" "github.com/prebid/prebid-server/config" "github.com/prebid/prebid-server/errortypes" diff --git a/prebid-server/endpoints/openrtb2/pbs-endpoint-auction.md b/prebid-server/endpoints/openrtb2/pbs-endpoint-auction.md index a886e362..412e9ebc 100644 --- a/prebid-server/endpoints/openrtb2/pbs-endpoint-auction.md +++ b/prebid-server/endpoints/openrtb2/pbs-endpoint-auction.md @@ -1140,9 +1140,6 @@ Each adapter must be coded to read the values from the ortb and pass it to their ##### Custom Targeting -{: .alert.alert-info :} -PBS-Java only - An OpenRTB extension, whether in the the original request or the [stored-request](/prebid-server/features/pbs-storedreqs.html), can customize the ad server targeting generated by PBS. The OpenRTB field is `ext.prebid.adservertargeting`. Here's an example: @@ -1203,9 +1200,6 @@ In order to pull AMP parameters out into targeting, Prebid Server places AMP que ##### MultiBid -{: .alert.alert-info :} -PBS-Java only - Allows a single bidder to bid more than once into an auction and have extra bids passed back to the client. diff --git a/prebid-server/features/pbs-feature-idx.md b/prebid-server/features/pbs-feature-idx.md index a202b3dd..e7b35b38 100644 --- a/prebid-server/features/pbs-feature-idx.md +++ b/prebid-server/features/pbs-feature-idx.md @@ -18,7 +18,7 @@ title: Prebid Server | Features | [AMP](/prebid-server/use-cases/pbs-amp.html) | Core | Reads and responds to the /openrtb2/amp endpoint | | | | Targeting | Core | Request can specify `includewinners` and `includebidderkeys`. These cause PBS to emit seatbid[].bid[].ext.prebid.targeting values. | | | | Targeting | Format | Request can specify `includeformat`, which causes PBS to emit hb_format along with other targeting values like hb_pb, etc. | | | -| Targeting | [Custom Targeting](/prebid-server/endpoints/openrtb2/pbs-endpoint-auction.html#custom-targeting) | Request can specify `ext.prebid.adservertargeting`, which causes PBS to emit custom targeting values. | | | +| Targeting | [Custom Targeting](/prebid-server/endpoints/openrtb2/pbs-endpoint-auction.html#custom-targeting) | Request can specify `ext.prebid.adservertargeting`, which causes PBS to emit custom targeting values. | | | | Request Params | Global Params | Publishers can specify [adapter-specific cross-impression attributes](/prebid-server/endpoints/openrtb2/pbs-endpoint-auction.html#global-bid-adapter-parameters). | | | | [Price Granularity](/prebid-server/endpoints/openrtb2/pbs-endpoint-auction.html#targeting) | Core | Request can define quantization rules. Bids are quantized before being added to ad server targeting. | | | | Price Granularity | Mediatype pricegranularity | Request can define different quantization rules for different mediatypes. Bids are quantized before being added to ad server targeting. | | | @@ -30,11 +30,11 @@ title: Prebid Server | Features | GDPR | Support for basicEnforcementVendors | Host companies can define bidders that don't require vendor consent but do require Purpose consent. | | | | GDPR | TCF 2 Geo-Fencing | If the incoming request contains device.geo.country, PBS will enforce the EEA if the request is flagged as being in GDPR scope. | | | | GDPR | TCF 2 Geo-Lookup | Can use a geographic lookup service to help determine whether the incoming request is in-scope for GDPR. | | | -| GDPR | TCF 2 channel exception | Can be configured to turn off GDPR checks for a specific account and a specific channel. e.g. Account 123 has a different legal basis for AMP. | | | +| GDPR | TCF 2 channel exception | Can be configured to turn off GDPR checks for a specific account and a specific channel. e.g. Account 123 has a different legal basis for AMP. | | | | [US Privacy](/prebid-server/features/pbs-privacy.html#ccpa--us-privacy) | USP core | Able to: read the US Privacy consent string (CCPA) and [take appropriate enforcement action](https://github.com/prebid/prebid-server/issues/1129). | | | | US Privacy | USP AMP support | Able to: read the US Privacy consent string from AMP requests and [take appropriate enforcement action](https://github.com/prebid/prebid-server/issues/1176). | | | | [GPP](/prebid-server/features/pbs-privacy.html#gpp) | GPP Passthrough | Global Privacy Platform parameters are passed through auction and usersync requests. | | | -| [GPP](/prebid-server/features/pbs-privacy.html#gpp) | GPP TCF2/USP Support | PBS reads the Global Privacy Platform string and pulls out TCF2/USP strings when appropriate. | | | +| [GPP](/prebid-server/features/pbs-privacy.html#gpp) | GPP TCF2/USP Support | PBS reads the Global Privacy Platform string and pulls out TCF2/USP strings when appropriate. | | | | COPPA | Core | Able to read the COPPA flag and [take appropriate enforcement action](https://github.com/prebid/prebid-server/issues/929). | | | | Global Privacy Control | Core | Passes the Sec-GPC header through to bidders. | | | | [Cache](/prebid-server/features/pbs-caching.html) | Bids core | Accepts the ext.prebid.cache.bids parameter, storing bid objects in PBC. | | | @@ -74,7 +74,7 @@ title: Prebid Server | Features | [Events](https://docs.google.com/document/d/1ry0X4C2EV-R0pMrm1IQk9BstxaT395UCl3KKqTGa5c8/edit#heading=h.7w5yevygp2gz) | Events | Ability to process the /event endpoint, place /event URLs in the OpenRTB response, and place /event URLs in VAST XML. | | | | Events | Events vasttrack endpoint | Ability to process the /vasttrack endpoint initated by Prebid.js, placing /event URLs in VAST XML. | | | | Events | Events BidID Generation | Some bidders don't generate unique enough BidIDs to join with auction events. This feature allows the host company to inject a PBS-generated BidID alongside the bidder-generated ID. | | | -| Auction | [MultiBid](/prebid-server/endpoints/openrtb2/pbs-endpoint-auction.html#multibid) | Allow named bidders to supply more than one response. | | | +| Auction | [MultiBid](/prebid-server/endpoints/openrtb2/pbs-endpoint-auction.html#multibid) | Allow named bidders to supply more than one response. | | | | Analytics | Analytics module support | Allows developers to plug in a [custom analytics adapter](/prebid-server/developers/pbs-build-an-analytics-adapter.html). | | | | Bid Response Validation | Validate secure markup | PBS can configurably reject bid responses that don't supply a secure creative when in a secure context. | | | | Bid Response Validation | Validate bid sizes | PBS can configurably reject bid responses with sizes that are bigger than the request dimensions. | | | From fbf381e8a347937161d807afb17a637a47e098f6 Mon Sep 17 00:00:00 2001 From: Scott Kay Date: Fri, 21 Apr 2023 13:13:08 -0400 Subject: [PATCH 182/762] Add PBS OpenRTB 2.6-202303 Fields (#4508) --- prebid-server/endpoints/openrtb2/pbs-endpoint-auction.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/prebid-server/endpoints/openrtb2/pbs-endpoint-auction.md b/prebid-server/endpoints/openrtb2/pbs-endpoint-auction.md index 412e9ebc..a6904a80 100644 --- a/prebid-server/endpoints/openrtb2/pbs-endpoint-auction.md +++ b/prebid-server/endpoints/openrtb2/pbs-endpoint-auction.md @@ -150,6 +150,8 @@ Prebid Server accepts all OpenRTB 2.x fields and passes them in the request to a | dooh | 2.6-202211 | not yet supported by PBS | | imp.qty | 2.6-202211 | (PBS-Go only so far) Bidders supporting 2.5 only: this field is removed | | imp.dt | 2.6-202211 | (PBS-Go only so far) Bidders supporting 2.5 only: this field is removed | +| imp.refresh | 2.6-202303 | (PBS-Go only so far) Bidders supporting 2.5 only: this field is removed | +| imp.video.plcmt | 2.6-202303 | (PBS-Go only so far) Bidders supporting 2.5 only: this field is removed | #### IDs From ef8919d2c2fca5d6289b183cd5a931f11521fd3d Mon Sep 17 00:00:00 2001 From: rimaburder-index <55195208+rimaburder-index@users.noreply.github.com> Date: Fri, 21 Apr 2023 13:16:18 -0400 Subject: [PATCH 183/762] Updated the version number for ad-unit FPD (#4509) Updated the version number for ad-unit FPD --- dev-docs/bidders/ix.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dev-docs/bidders/ix.md b/dev-docs/bidders/ix.md index 77ba5ff1..20679f04 100644 --- a/dev-docs/bidders/ix.md +++ b/dev-docs/bidders/ix.md @@ -245,7 +245,7 @@ To include the FPD in a bid request, in the `[pbjs.setConfig()]` object at the ` ### AdUnit-specific data -Use this data type to specify key-value pairs at the ad unit level when targeting deals and apply it to all bidders. This is available from Prebid.js version 7.45 and above. To include the adUnit-specific data in a bid request, see Prebid's [Supplying AdUnit-Specific Data](https://docs.prebid.org/features/firstPartyData.html#supplying-adunit-specific-data) documentation. +Use this data type to specify key-value pairs at the ad unit level when targeting deals and apply it to all bidders. This will be available from Prebid.js version 7.46 and above. To include the adUnit-specific data in a bid request, see Prebid's [Supplying AdUnit-Specific Data](https://docs.prebid.org/features/firstPartyData.html#supplying-adunit-specific-data) documentation. ```javascript From 0d500846ef9b9ddf807123b527349624382742c5 Mon Sep 17 00:00:00 2001 From: Demetrio Girardi Date: Fri, 21 Apr 2023 10:18:54 -0700 Subject: [PATCH 184/762] Remove duplicate listing of the `video.placement` option (#4488) --- dev-docs/adunit-reference.md | 1 - 1 file changed, 1 deletion(-) diff --git a/dev-docs/adunit-reference.md b/dev-docs/adunit-reference.md index 0aeba72d..93751c65 100644 --- a/dev-docs/adunit-reference.md +++ b/dev-docs/adunit-reference.md @@ -113,7 +113,6 @@ See [Prebid Native Implementation](/prebid/native-implementation.html) for detai | `w` | Recommended | Integer | Width of the video player in device independent pixels (DIPS)., see [OpenRTB 2.5 spec][openRTB]. | | `h` | Recommended | Integer | Height of the video player in device independent pixels (DIPS)., see [OpenRTB 2.5 spec][openRTB]. | | `startdelay` | Recommended | Integer | Indicates the start delay in seconds, see [OpenRTB 2.5 spec][openRTB]. | -| `placement` | Optional | Integer | Placement type for the impression, see [OpenRTB 2.5 spec][openRTB]. | | `linearity` | Optional | Integer | Indicates if the impression must be linear, nonlinear, etc, see [OpenRTB 2.5 spec][openRTB]. | | `skip` | Optional | Integer | Indicates if the player will allow the video to be skipped, where 0 = no, 1 = yes., see [OpenRTB 2.5 spec][openRTB]. | | `skipmin` | Optional | Integer | Videos of total duration greater than this number of seconds can be skippable; only applicable if the ad is skippable., see [OpenRTB 2.5 spec][openRTB]. | From 7d9e458f8206091c515f891eaf23eba4ac6a4c36 Mon Sep 17 00:00:00 2001 From: Valentin Petrovych <72038591+ValentinPostindustria@users.noreply.github.com> Date: Thu, 27 Apr 2023 18:12:16 +0300 Subject: [PATCH 185/762] Mobile SDK multiformat feature (#4476) * Update iOS documentation. * iOS documentation corrections. * Update Android documentation. * Android corrections. * iOS corrections. * Android ad unit formats renaming. * iOS AdFormat case renaming * doc: corrections for iOS * doc: corrections for Android --------- Co-authored-by: Olena Stepaniuk Co-authored-by: Yuriy Velichko --- .../android-sdk-customization-controls.md | 2 +- .../android-sdk-integration-admob.md | 4 +- .../rendering/android-sdk-integration-gam.md | 2 +- .../rendering/android-sdk-integration-max.md | 4 +- .../rendering/android-sdk-integration-pb.md | 2 +- .../rendering/ios-sdk-integration-admob.md | 10 +- .../rendering/ios-sdk-integration-gam.md | 8 +- .../rendering/ios-sdk-integration-max.md | 10 +- .../rendering/ios-sdk-integration-pb.md | 14 +- ...ndroid-sdk-integration-gam-original-api.md | 194 +++++++-- .../ios-sdk-integration-gam-original-api.md | 367 ++++++++++++++---- 11 files changed, 472 insertions(+), 145 deletions(-) diff --git a/prebid-mobile/modules/rendering/android-sdk-customization-controls.md b/prebid-mobile/modules/rendering/android-sdk-customization-controls.md index e0588663..14051a97 100644 --- a/prebid-mobile/modules/rendering/android-sdk-customization-controls.md +++ b/prebid-mobile/modules/rendering/android-sdk-customization-controls.md @@ -166,7 +166,7 @@ The code sample: adUnit = MediationInterstitialAdUnit( activity, configId, - EnumSet.of(AdUnitFormat.DISPLAY), + EnumSet.of(AdUnitFormat.BANNER), mediationUtils ) diff --git a/prebid-mobile/modules/rendering/android-sdk-integration-admob.md b/prebid-mobile/modules/rendering/android-sdk-integration-admob.md index 80d90545..9fd9b965 100644 --- a/prebid-mobile/modules/rendering/android-sdk-integration-admob.md +++ b/prebid-mobile/modules/rendering/android-sdk-integration-admob.md @@ -138,7 +138,7 @@ val mediationUtils = AdMobInterstitialMediationUtils(extras) adUnit = MediationInterstitialAdUnit( activity, configId, - AdUnitFormat.DISPLAY, + AdUnitFormat.BANNER, mediationUtils ) @@ -183,7 +183,7 @@ The **default** ad format for interstitial is **DISPLAY**. In order to make a `m adUnit = MediationInterstitialAdUnit( activity, configId, - EnumSet.of(AdUnitFormat.DISPLAY, AdUnitFormat.VIDEO), + EnumSet.of(AdUnitFormat.BANNER, AdUnitFormat.VIDEO), mediationUtils ) ``` diff --git a/prebid-mobile/modules/rendering/android-sdk-integration-gam.md b/prebid-mobile/modules/rendering/android-sdk-integration-gam.md index 305f135f..22ecbeba 100644 --- a/prebid-mobile/modules/rendering/android-sdk-integration-gam.md +++ b/prebid-mobile/modules/rendering/android-sdk-integration-gam.md @@ -159,7 +159,7 @@ The **default** ad format for an interstitial ad is **DISPLAY**. In order to mak interstitialAdUnit = InterstitialAdUnit( requireContext(), configId, - EnumSet.of(AdUnitFormat.DISPLAY, AdUnitFormat.VIDEO), + EnumSet.of(AdUnitFormat.BANNER, AdUnitFormat.VIDEO), eventHandler) ``` diff --git a/prebid-mobile/modules/rendering/android-sdk-integration-max.md b/prebid-mobile/modules/rendering/android-sdk-integration-max.md index dbda51a5..31b9dc84 100644 --- a/prebid-mobile/modules/rendering/android-sdk-integration-max.md +++ b/prebid-mobile/modules/rendering/android-sdk-integration-max.md @@ -121,7 +121,7 @@ val mediationUtils = MaxMediationInterstitialUtils(maxInterstitialAd) adUnit = MediationInterstitialAdUnit( activity, configId, - EnumSet.of(AdUnitFormat.DISPLAY), + EnumSet.of(AdUnitFormat.BANNER), mediationUtils ) @@ -140,7 +140,7 @@ The **default** ad format for interstitial is **DISPLAY**. In order to make a `m adUnit = MediationInterstitialAdUnit( activity, configId, - EnumSet.of(AdUnitFormat.DISPLAY, AdUnitFormat.VIDEO), + EnumSet.of(AdUnitFormat.BANNER, AdUnitFormat.VIDEO), mediationUtils ) ``` diff --git a/prebid-mobile/modules/rendering/android-sdk-integration-pb.md b/prebid-mobile/modules/rendering/android-sdk-integration-pb.md index 64f053f5..f1b26481 100644 --- a/prebid-mobile/modules/rendering/android-sdk-integration-pb.md +++ b/prebid-mobile/modules/rendering/android-sdk-integration-pb.md @@ -138,7 +138,7 @@ The **default** ad format for interstitial is **DISPLAY**. In order to make a `m interstitialAdUnit = InterstitialAdUnit( requireContext(), configId, - EnumSet.of(AdUnitFormat.DISPLAY, AdUnitFormat.VIDEO)) + EnumSet.of(AdUnitFormat.BANNER, AdUnitFormat.VIDEO)) ``` #### Step 1: Create an Ad Unit diff --git a/prebid-mobile/modules/rendering/ios-sdk-integration-admob.md b/prebid-mobile/modules/rendering/ios-sdk-integration-admob.md index 489858d3..0a5d57a7 100644 --- a/prebid-mobile/modules/rendering/ios-sdk-integration-admob.md +++ b/prebid-mobile/modules/rendering/ios-sdk-integration-admob.md @@ -137,17 +137,17 @@ GADInterstitialAd.load(withAdUnitID: adUnitID, request: self?.gadRequest) { [wea }) ``` -The **default** ad format for interstitial is **.display**. In order to make a `multiformat bid request`, set the respective values into the `adFormats` property. +The **default** ad format for interstitial is **.banner**. In order to make a `multiformat bid request`, set the respective values into the `adFormats` property. ``` swift // Make bid request for video ad adUnit?.adFormats = [.video] -// Make bid request for both video amd disply ads -adUnit?.adFormats = [.video, .display] +// Make bid request for both video amd banner ads +adUnit?.adFormats = [.video, .banner] -// Make bid request for disply ad (default behaviour) -adUnit?.adFormats = [.display] +// Make bid request for banner ad (default behaviour) +adUnit?.adFormats = [.banner] ``` diff --git a/prebid-mobile/modules/rendering/ios-sdk-integration-gam.md b/prebid-mobile/modules/rendering/ios-sdk-integration-gam.md index 858db8e2..cfe92bb3 100644 --- a/prebid-mobile/modules/rendering/ios-sdk-integration-gam.md +++ b/prebid-mobile/modules/rendering/ios-sdk-integration-gam.md @@ -152,17 +152,17 @@ if interstitial.isReady { ``` -The **default** ad format for interstitial is **.display**. In order to make a `multiformat bid request`, set the respective values in the `adFormats` property. +The **default** ad format for interstitial is **.banner**. In order to make a `multiformat bid request`, set the respective values in the `adFormats` property. ``` swift // Make bid request for video ad adUnit?.adFormats = [.video] // Make bid request for both video amd disply ads -adUnit?.adFormats = [.video, .display] +adUnit?.adFormats = [.video, .banner] -// Make bid request for disply ad (default behaviour) -adUnit?.adFormats = [.display] +// Make bid request for banner ad (default behaviour) +adUnit?.adFormats = [.banner] ``` diff --git a/prebid-mobile/modules/rendering/ios-sdk-integration-max.md b/prebid-mobile/modules/rendering/ios-sdk-integration-max.md index 965ed0d5..fc59a138 100644 --- a/prebid-mobile/modules/rendering/ios-sdk-integration-max.md +++ b/prebid-mobile/modules/rendering/ios-sdk-integration-max.md @@ -117,17 +117,17 @@ adUnit?.fetchDemand { [weak self] result in }) ``` -The **default** ad format for interstitial is **.display**. In order to make a `multiformat bid request` set the respective values in the `adFormats` property. +The **default** ad format for interstitial is **.banner**. In order to make a `multiformat bid request` set the respective values in the `adFormats` property. ``` swift // Make bid request for video ad adUnit?.adFormats = [.video] -// Make bid request for both video amd disply ads -adUnit?.adFormats = [.video, .display] +// Make bid request for both video amd banner ads +adUnit?.adFormats = [.video, .banner] -// Make bid request for disply ad (default behaviour) -adUnit?.adFormats = [.display] +// Make bid request for banner ad (default behaviour) +adUnit?.adFormats = [.banner] ``` diff --git a/prebid-mobile/modules/rendering/ios-sdk-integration-pb.md b/prebid-mobile/modules/rendering/ios-sdk-integration-pb.md index cafc31fe..0bdb2beb 100644 --- a/prebid-mobile/modules/rendering/ios-sdk-integration-pb.md +++ b/prebid-mobile/modules/rendering/ios-sdk-integration-pb.md @@ -139,17 +139,17 @@ if interstitial.isReady { ``` -The **default** ad format for interstitial is **.display**. In order to make a `multiformat bid request`, set the respective values into the `adFormats` property. +The **default** ad format for interstitial is **.banner**. In order to make a `multiformat bid request`, set the respective values into the `adFormats` property. ``` swift // Make bid request for video ad adUnit?.adFormats = [.video] -// Make bid request for both video amd disply ads -adUnit?.adFormats = [.video, .display] +// Make bid request for both video and banner ads +adUnit?.adFormats = [.video, .banner] -// Make bid request for disply ad (default behaviour) -adUnit?.adFormats = [.display] +// Make bid request for banner ad (default behaviour) +adUnit?.adFormats = [.banner] ``` @@ -161,7 +161,7 @@ Initialize the Interstitial Ad Unit with properties: - `configID` - an ID of Stored Impression on the Prebid Server - `minSizePercentage` - specifies the minimum width and height percent an ad may occupy of a device’s real estate. -> **NOTE:** minSizePercentage - plays an important role in a bidding process for display ads. If provided space is not enough demand partners won't respond with the bids. +> **NOTE:** minSizePercentage - plays an important role in a bidding process for banner ads. If provided space is not enough demand partners won't respond with the bids. #### Step 2: Load the Ad {:.no_toc} @@ -225,4 +225,4 @@ Wait until the ad will be loaded and present it to the user in any suitable time func rewardedAdDidReceiveAd(_ rewardedAd: RewardedAdUnit) { // Now the ad is ready for display } -``` \ No newline at end of file +``` diff --git a/prebid-mobile/pbm-api/android/android-sdk-integration-gam-original-api.md b/prebid-mobile/pbm-api/android/android-sdk-integration-gam-original-api.md index cead15dc..8264e1f0 100755 --- a/prebid-mobile/pbm-api/android/android-sdk-integration-gam-original-api.md +++ b/prebid-mobile/pbm-api/android/android-sdk-integration-gam-original-api.md @@ -21,7 +21,11 @@ This is the original Prebid mobile integration approach when SDK plays the trans ![In-App Bidding with Prebid](/assets/images/prebid-mobile/prebid-in-app-bidding-overview-prebid-original-gam.png) -## Display Banner +## Banner API + +Starting with Prebid Mobile `2.1.0` you can use `BannerAdUnit` to bid over the banner and/or video demand. The default ad format is `BANNER`. To customize the bidding format, specify the ad formats in the `BannerAdUnit` constructor. + +### HTML Banner Integration example: @@ -33,8 +37,9 @@ private fun createAd() { adUnit?.setAutoRefreshInterval(refreshTimeSeconds) // 2. Configure banner parameters - val parameters = BannerBaseAdUnit.Parameters() + val parameters = BannerParameters() parameters.api = listOf(Signals.Api.MRAID_3, Signals.Api.OMID_1) + adUnit.bannerParameters = parameters // 3. Create AdManagerAdView val adView = AdManagerAdView(this) @@ -55,7 +60,7 @@ private fun createAd() { } ``` -GAM ad view listner: +GAM ad view listener: ```kotlin private fun createGAMListener(adView: AdManagerAdView): AdListener { @@ -88,7 +93,10 @@ Initialize the `BannerAdUnit` with properties: #### Step 2: Configure banner parameters {:.no_toc} -Using the `BannerBaseAdUnit.Parameters()` you can customize the bid request for BannerAdUnit. +Using the `BannerParameters()` you can customize the bid request for BannerAdUnit. + +{: .alert.alert-warning :} +Starting from PrebidMobile `2.1.0` the `BannerBaseAdUnit.Parameters` class is deprecated. Use `BannerParameters` instead. The `api` property is dedicated to adding values for API Frameworks to a bid response according to the OpenRTB 2.5](https://www.iab.com/wp-content/uploads/2016/03/OpenRTB-API-Specification-Version-2-5-FINAL.pdf) spec. The supported values for GMA SDK integration are: @@ -119,17 +127,17 @@ Be sure that you make the ad request with the same `AdManagerAdRequest` object t Once an app receives a signal that an ad is loaded, you should use the method `AdViewUtils.findPrebidCreativeSize` to verify whether it's Prebid's ad and resize the ad slot respectively to the creative's properties. -## Video Banner +### Video Banner (Outstream Video) Integration example: ```kotlin private fun createAd() { // 1. Create VideoAdUnit - adUnit = VideoAdUnit(CONFIG_ID, WIDTH, HEIGHT) + adUnit = BannerAdUnit(CONFIG_ID, WIDTH, HEIGHT, EnumSet.of(AdUnitFormat.VIDEO)) // 2. Configure video ad unit - adUnit?.parameters = configureVideoParameters() + adUnit?.videoParameters = configureVideoParameters() // 3. Create AdManagerAdView val gamView = AdManagerAdView(this) @@ -147,12 +155,15 @@ private fun createAd() { } ``` +{: .alert.alert-warning :} +Starting from PrebidMobile `2.1.0` the `VideoAdUnit` class is deprecated. Use `BannerAdUnit` class with video ad format instead. + + Configure Video parameters: ```kotlin -private fun configureVideoParameters(): VideoBaseAdUnit.Parameters { - return VideoBaseAdUnit.Parameters().apply { - +private fun configureVideoParameters(): VideoParameters { + return VideoParameters(listOf("video/x-flv", "video/mp4")).apply { api = listOf( Signals.Api.VPAID_1, Signals.Api.VPAID_2 @@ -162,7 +173,6 @@ private fun configureVideoParameters(): VideoBaseAdUnit.Parameters { minBitrate = 300 maxDuration = 30 minDuration = 5 - mimes = listOf("video/x-flv", "video/mp4") playbackMethod = listOf(Signals.PlaybackMethod.AutoPlaySoundOn) protocols = listOf( Signals.Protocols.VAST_2_0 @@ -189,18 +199,22 @@ private fun createListener(gamView: AdManagerAdView): AdListener { } ``` -#### Step 1: Create a VideoAdUnit +#### Step 1: Create a BannerAdUnit with the video ad type {:.no_toc} -Initialize the `VideoAdUnit` with the following properties: +Initialize the `BannerAdUnit` with the following properties: - `configId` - an ID of the Stored Impression on the Prebid Server - `adSize` - the size of the ad unit which will be used in the bid request. +- `adUnitFormats` - `AdUnitFormat.VIDEO` for a video ad #### Step 2: Configure video parameters {:.no_toc} -Using the `VideoParameters` you can customize the bid request for a VideoAdUnit. +Using the `VideoParameters` you can customize the bid request for a `BannerAdUnit`. + +{: .alert.alert-warning :} +Starting from PrebidMobile `2.1.0` the `VideoBaseAdUnit.Parameters` class is deprecated. Use `VideoParameters` instead. #### placement {:.no_toc} @@ -227,7 +241,6 @@ The `api` property is dedicated to adding values for API Frameworks to a bid res * `6` or `Signals.Api.MRAID_3` : MRAID-3 support signal * `7` or `Signals.Api.OMID_1` : signals OMSDK support - #### maxBitrate {:.no_toc} @@ -297,7 +310,61 @@ You should now request the ad from GAM. If the `AdManagerAdRequest` contains tar Be sure that you make the ad request with the same `AdManagerAdRequest` object that you passed to the `fetchDemand` method. Otherwise, the ad request won't contain targeting keywords, and Prebid's ad won't ever be displayed. -## Display Interstitial +### Multiformat Banner (HTML + Video) + +Integration example: + +```kotlin +// 1. Create BannerAdUnit +adUnit = BannerAdUnit(configId, WIDTH, HEIGHT, EnumSet.of(AdUnitFormat.BANNER, AdUnitFormat.VIDEO)) +adUnit?.setAutoRefreshInterval(refreshTimeSeconds) + +// 2. Configure banner and video parameters +val parameters = BannerParameters() +parameters.api = listOf(Signals.Api.MRAID_3, Signals.Api.OMID_1) +adUnit?.bannerParameters = parameters + +adUnit?.videoParameters = VideoParameters(listOf("video/mp4")) + +// 3. Create AdManagerAdView +val adView = AdManagerAdView(this) +adView.adUnitId = AD_UNIT_ID +adView.setAdSizes(AdSize(WIDTH, HEIGHT)) +adView.adListener = createGAMListener(adView) + +// Add GMA SDK banner view to the app UI +adWrapperView.addView(adView) + +// 4. Make a bid request to Prebid Server +val request = AdManagerAdRequest.Builder().build() +adUnit?.fetchDemand(request) { + + // 5. Load GAM Ad + adView.loadAd(request) +} +``` + +#### Step 1: Create a BannerAdUnit +{:.no_toc} + +Initialize the `BannerAdUnit` with properties: + +- `configId` - an ID of the Stored Impression on the Prebid Server +- `width` - the width of the ad unit which will be used in the bid request. +- `height` - the height of the ad unit which will be used in the bid request. +- `adUnitFormats` - ad unit formats for the current ad unit. + +#### Step 2-5 +{:.no_toc} + +Steps 2-5 are the same as for Display Banner. Setting up banner and video parameters can be found in Display Banner and Video Banner respectively. + + +## Interstitial API + +Starting with Prebid Mobile `2.1.0` you can use `InterstitialAdUnit ` to bid over the banner and/or video demand. The default ad format is `BANNER`. To customize the bidding format, specify the ad formats in the `InterstitialAdUnit ` constructor. + +### HTML Interstitial Integration example: @@ -373,18 +440,18 @@ Be sure that you make the ad request with the same `AdManagerAdRequest` object t Follow the [GMA SDK guide](https://developers.google.com/ad-manager/mobile-ads-sdk/android/interstitial#display_the_ad) to display an interstitial ad right after receiving it or later in a natural pauses in the flow of an app. -## Video Interstitial +### Video Interstitial Integration Example: ```kotlin private fun createAd() { - // 1. Create VideoInterstitialAdUnit - adUnit = VideoInterstitialAdUnit(CONFIG_ID) + // 1. Create InterstitialAdUnit + adUnit = InterstitialAdUnit(CONFIG_ID, EnumSet.of(AdUnitFormat.VIDEO)) // 2. Configure video ad unit - adUnit?.parameters = configureVideoParameters() + adUnit?.videoParameters = configureVideoParameters() // 3. Make a bid request to Prebid Server val request = AdManagerAdRequest.Builder().build() @@ -401,11 +468,15 @@ private fun createAd() { } ``` +{: .alert.alert-warning :} +Starting from PrebidMobile `2.1.0` the `VideoInterstitialAdUnit` class is deprecated. Use `InterstitialAdUnit` class with video ad format instead. + + Configuration function: ```kotlin -private fun configureVideoParameters(): VideoBaseAdUnit.Parameters { - return VideoBaseAdUnit.Parameters().apply { +private fun configureVideoParameters(): VideoParameters { + return VideoParameters(listOf("video/x-flv", "video/mp4")).apply { placement = Signals.Placement.Interstitial api = listOf( @@ -417,7 +488,6 @@ private fun configureVideoParameters(): VideoBaseAdUnit.Parameters { minBitrate = 300 maxDuration = 30 minDuration = 5 - mimes = listOf("video/x-flv", "video/mp4") playbackMethod = listOf(Signals.PlaybackMethod.AutoPlaySoundOn) protocols = listOf( Signals.Protocols.VAST_2_0 @@ -449,9 +519,10 @@ private fun createAdListener(): AdManagerInterstitialAdLoadCallback { #### Step 1: Create an Ad Unit {:.no_toc} -Initialize the Interstitial Video Ad Unit with the following properties: +Initialize the `InterstitialAdUnit` with the following properties: - `configId` - an ID of Stored Impression on the Prebid Server +- `adUnitFormats` - AdUnitFormat.VIDEO for a video ad #### Step 2: Configure video parameters {:.no_toc} @@ -475,7 +546,46 @@ Be sure that you make the ad request with the same `AdManagerAdRequest` object t Follow the [GMA SDK guide](https://developers.google.com/ad-manager/mobile-ads-sdk/android/interstitial#display_the_ad) to display an interstitial ad right after receiving it or later in a natural pauses in the flow of an app. -## Rewarded Video +### Multiformat Interstitial (HTML + Video) + +Integration example: + +```kotlin +// 1. Create InterstitialAdUnit +adUnit = InterstitialAdUnit(configId, EnumSet.of(AdUnitFormat.BANNER, AdUnitFormat.VIDEO)) +adUnit?.setMinSizePercentage(80, 60) +adUnit?.videoParameters = VideoParameters(listOf("video/mp4")) + + +// 2. Make a bid request to Prebid Server +val request = AdManagerAdRequest.Builder().build() +adUnit?.fetchDemand(request) { + + // 3. Load a GAM interstitial ad + AdManagerInterstitialAd.load( + this, + AD_UNIT_ID, + request, + createListener() + ) +} +``` + +#### Step 1: Create an Ad Unit +{:.no_toc} + +Initialize the `InterstitialAdUnit` with the following properties: + +- `configId` - an ID of Stored Impression on the Prebid Server +- `adUnitFormats` - ad unit formats for the current ad unit. + +#### Steps 2-3 +{:.no_toc} + +Steps 2-3 are the same as for Display Banner. Setting up banner and video parameters can be found in Display Interstitial and Video Interstitial respectively. + + +## Rewarded Video API Integration example: @@ -485,7 +595,7 @@ private fun createAd() { adUnit = RewardedVideoAdUnit(CONFIG_ID) // 2. Configure Video parameters - adUnit?.parameters = configureVideoParameters() + adUnit?.videoParameters = configureVideoParameters() // 3. Make a bid request to Prebid Server val request = AdManagerAdRequest.Builder().build() @@ -502,12 +612,11 @@ private fun createAd() { } ``` -Configure vide ad unit: +Configure video ad unit: ```kotlin -private fun configureVideoParameters(): VideoBaseAdUnit.Parameters { - return VideoBaseAdUnit.Parameters().apply { - mimes = listOf("video/mp4") +private fun configureVideoParameters(): VideoParameters { + return VideoParameters(listOf("video/mp4")).apply { protocols = listOf(Signals.Protocols.VAST_2_0) playbackMethod = listOf(Signals.PlaybackMethod.AutoPlaySoundOff) } @@ -563,17 +672,17 @@ Be sure that you make the ad request with the same `AdManagerAdRequest` object t Follow the [GMA SDK guide](https://developers.google.com/ad-manager/mobile-ads-sdk/android/rewarded#show_the_ad) to display a rewarded ad right after receiving it or later in a natural pauses in the flow of an app. -## Video Instream +## Instream Video API Integration example: ```kotlin private fun createAd() { // 1. Create VideoAdUnit - adUnit = VideoAdUnit(CONFIG_ID, WIDTH, HEIGHT) + adUnit = InStreamVideoAdUnit(CONFIG_ID, WIDTH, HEIGHT) // 2. Configure video parameters - adUnit?.parameters = configureVideoParameters() + adUnit?.videoParameters = configureVideoParameters() // 3. Init player view playerView = PlayerView(this) @@ -600,11 +709,14 @@ private fun createAd() { } ``` +{: .alert.alert-warning :} +Starting from PrebidMobile `2.1.0` the `VideoAdUnit` class is deprecated. Use `InStreamVideoAdUnit ` instead. + Configure the video ad: ```kotlin -private fun configureVideoParameters(): VideoBaseAdUnit.Parameters { - return VideoBaseAdUnit.Parameters().apply { +private fun configureVideoParameters(): VideoParameters { + return VideoParameters(listOf("video/x-flv", "video/mp4")).apply { placement = Signals.Placement.InStream api = listOf( @@ -616,7 +728,6 @@ private fun configureVideoParameters(): VideoBaseAdUnit.Parameters { minBitrate = 300 maxDuration = 30 minDuration = 5 - mimes = listOf("video/x-flv", "video/mp4") playbackMethod = listOf(Signals.PlaybackMethod.AutoPlaySoundOn) protocols = listOf( Signals.Protocols.VAST_2_0 @@ -689,7 +800,9 @@ Using Prebid util method, generate Google IMA URI for downloading the cached cre Follow the Google Guide for [integrating IMA with ExoPlayer](https://developers.google.com/interactive-media-ads/docs/sdks/android/client-side/exoplayer-extension) to run a video and show instream ad from the winning bid. -## Native Style Banner +## Native API + +### Native Banner Integration example: @@ -805,7 +918,7 @@ Now you should request the ad from GAM. If the `AdManagerAdRequest` contains tar Be sure that you make the ad request with the same `AdManagerAdRequest` object that you passed to the `fetchDemand` method. Otherwise, the ad request won't contain targeting keywords, and Prebid's ad won't ever be displayed. -## In-App Native +### In-App Native Integration example: @@ -1013,10 +1126,7 @@ Once the Prebid line item is recognized you should extract the ad from the winni Each ad unit in the Original API is a subclass of the `AdUnit` class, which provides the following properties and methods for additional configuration. -### Properties - -#### pbAdSlot -{:.no_toc} +### Ad Slot PB Ad Slot is an identifier tied to the placement the ad will be delivered in. The use case for PB Ad Slot is to pass to exchange an ID they can use to tie to reporting systems or use for data science driven model building to match with impressions sourced from alternate integrations. A common ID to pass is the ad server slot name. diff --git a/prebid-mobile/pbm-api/ios/ios-sdk-integration-gam-original-api.md b/prebid-mobile/pbm-api/ios/ios-sdk-integration-gam-original-api.md index 0cd9b06d..6d7b6d96 100644 --- a/prebid-mobile/pbm-api/ios/ios-sdk-integration-gam-original-api.md +++ b/prebid-mobile/pbm-api/ios/ios-sdk-integration-gam-original-api.md @@ -21,7 +21,11 @@ This is the original Prebid mobile integration approach when SDK plays the trans ![In-App Bidding with Prebid](/assets/images/prebid-mobile/prebid-in-app-bidding-overview-prebid-original-gam.png) -## Display Banner +## Banner API + +Starting with Prebid Mobile `2.1.0` you can use `BannerAdUnit` to bid over the banner and/or video demand. The default ad format is `.banner`. To customize the bidding format you should specify the `adFormats` property of the `BannerAdUnit`. + +### HTML Banner Integration example: @@ -33,7 +37,7 @@ adUnit.setAutoRefreshMillis(time: 30000) // 2. Configure banner parameters let parameters = BannerParameters() parameters.api = [Signals.Api.MRAID_2] -adUnit.parameters = parameters +adUnit.bannerParameters = parameters // 3. Create a GAMBannerView gamBanner = GAMBannerView(adSize: GADAdSizeFromCGSize(adSize)) @@ -89,6 +93,9 @@ The `api` property is dedicated to adding values for API Frameworks to bid respo * `6` or `Signals.Api.MRAID_3` : MRAID-3 support signal * `7` or `Signals.Api.OMID_1` : signals OMSDK support +{: .alert.alert-warning :} +Starting from PrebidMobile `2.1.0` the `parameters` property is deprecated. Use `bannerParameters` instead. + #### Step 3: Create a GAMBannerView {:.no_toc} @@ -111,23 +118,25 @@ Be sure that you make the ad request with the same `GAMRequest` object that you Once an app receives a signal that an ad is loaded, you should use the method `AdViewUtils.findPrebidCreativeSize` to verify whether it is a Prebid ad and resize the ad slot respectively to the creative's properties. -## Video Banner +### Video Banner (Outstream Video) Integration example: ``` swift // 1. Create a BannerAdUnit -adUnit = VideoAdUnit(configId: storedImpVideoBanner, size: adSize) +adUnit = BannerAdUnit(configId: CONFIG_ID, size: adSize) + +// 2. Set ad format +adUnit.adFormats = [.video] -// 2. Configure video parameters -let parameters = VideoParameters() -parameters.mimes = ["video/mp4"] +// 3. Configure video parameters +let parameters = VideoParameters(mimes: ["video/mp4"]) parameters.protocols = [Signals.Protocols.VAST_2_0] parameters.playbackMethod = [Signals.PlaybackMethod.AutoPlaySoundOff] parameters.placement = Signals.Placement.InBanner -adUnit.parameters = parameters +adUnit.videoParameters = parameters -// 3. Create a GAMBannerView +// 4. Create a GAMBannerView gamBanner = GAMBannerView(adSize: GADAdSizeFromCGSize(adSize)) gamBanner.adUnitID = gamAdUnitVideoBannerOriginal gamBanner.rootViewController = self @@ -137,28 +146,36 @@ gamBanner.delegate = self bannerView.addSubview(gamBanner) bannerView.backgroundColor = .clear -// 4. Make a bid request to Prebid Server +// 5. Make a bid request to Prebid Server let gamRequest = GAMRequest() adUnit.fetchDemand(adObject: gamRequest) { [weak self] resultCode in PrebidDemoLogger.shared.info("Prebid demand fetch for GAM \(resultCode.name())") - // 5. Load GAM Ad + // 6. Load GAM Ad self?.gamBanner.load(gamRequest) } ``` -#### Step 1: Create a VideoAdUnit +{: .alert.alert-warning :} +Starting from PrebidMobile `2.1.0` the `VideoAdUnit` class is deprecated. Use `BannerAdUnit` class with video ad format instead. + +#### Step 1: Create a BannerAdUnit {:.no_toc} -Initialize the `VideoAdUnit` with the following properties: +Initialize the `BannerAdUnit` with the following properties: - `configId` - an ID of the Stored Impression on the Prebid Server - `adSize` - the size of the ad unit which will be used in the bid request. -#### Step 2: Configure the video parameters +#### Step 2: Set ad format {:.no_toc} -Using the `VideoParameters` you can customize the bid request for VideoAdUnit. +For video ad unit, you must set video ad format. Default value for `adFormats` property is `[.banner]`. + +#### Step 3: Configure the video parameters +{:.no_toc} + +Using the `VideoParameters` you can customize the bid request for video ads. #### placement {:.no_toc} @@ -172,7 +189,6 @@ In the context of a VideoInterstitialAdUnit, rewarded video ads are typically la * `4` or `InFeed` : In-Feed placement is found in content, social, or product feeds. * `5` or `Slider`, `Floating` or `Interstitial` : Open RTB supports one of three values for option 5 as either Slider, Floating or Interstitial. If an enum value is supplied in placement, bidders will receive value 5 for placement type and assume to be interstitial with the instl flag set to 1. - #### api {:.no_toc} @@ -185,7 +201,6 @@ The `api` property is dedicated to adding values for API Frameworks to bid respo * `6` or `Signals.Api.MRAID_3` : MRAID-3 support signal * `7` or `Signals.Api.OMID_1` : signals OMSDK support - #### maxBitrate {:.no_toc} @@ -210,6 +225,7 @@ Integer representing the OpenRTB 2.5 minimum video ad duration in seconds. {:.no_toc} Array of strings representing the supported OpenRTB 2.5 content MIME types (e.g., “video/x-ms-wmv”, “video/mp4”). +Required property. #### playbackMethod {:.no_toc} @@ -237,31 +253,137 @@ Array of OpenRTB 2.5 playback methods. If none are specified, any method may be - `7` or `Signals.Protocols.VAST_4_0` : VAST 4.0 - `8` or `Signals.Protocols.VAST_4_0_Wrapper` : VAST 4.0 Wrapper - -#### Step 3: Create a GAMBannerView +#### Step 4: Create a GAMBannerView {:.no_toc} Follow the [GMA SDK documentation](https://developers.google.com/ad-manager/mobile-ads-sdk/ios/banner) to integrate a banner ad unit. -#### Step 4: Make a bid request +#### Step 5: Make a bid request {:.no_toc} The `fetchDemand` method makes a bid request to the Prebid Server. You should provide a `GAMRequest` object to this method so Prebid SDK sets the targeting keywords of the winning bid for future ad requests. -#### Step 5: Load an Ad +#### Step 6: Load an Ad {:.no_toc} You should now request the ad from GAM. If the `GAMRequest` contains targeting keywords. The respective Prebid line item will be returned from GAM and GMA SDK will render its creative. Be sure that you make the ad request with the same `GAMRequest` object that you passed to the `fetchDemand` method. Otherwise the ad request won't contain targeting keywords and Prebid's ad won't ever be displayed. -## Display Interstitial +### Multiformat Banner (HTML + Video) + +Integration example: + +``` swift +// 1. Create a BannerAdUnit +adUnit = BannerAdUnit(configId: CONFIG_ID, size: adSize) +adUnit.setAutoRefreshMillis(time: 30000) + +// 2. Set adFormats +adUnit.adFormats = [.banner, .video] + +// 3. Configure banner parameters +let bannerParameters = BannerParameters() +bannerParameters.api = [Signals.Api.MRAID_2] +adUnit.bannerParameters = bannerParameters + +// 4. Configure video parameters +let videoParameters = VideoParameters(mimes: ["video/mp4"]) +videoParameters.protocols = [Signals.Protocols.VAST_2_0] +videoParameters.playbackMethod = [Signals.PlaybackMethod.AutoPlaySoundOff] +videoParameters.placement = Signals.Placement.InBanner +adUnit.videoParameters = videoParameters + +// 5. Create a GAMBannerView +gamBanner = GAMBannerView(adSize: GADAdSizeFromCGSize(adSize)) +gamBanner.adUnitID = gamAdUnitMultiformatBannerOriginal +gamBanner.rootViewController = self +gamBanner.delegate = self + +// Add GMA SDK banner view to the app UI +bannerView?.addSubview(gamBanner) + +// 6. Make a bid request to Prebid Server +let gamRequest = GAMRequest() +adUnit.fetchDemand(adObject: gamRequest) { [weak self] resultCode in + PrebidDemoLogger.shared.info("Prebid demand fetch for GAM \(resultCode.name())") + + // 7. Load GAM Ad + self?.gamBanner.load(gamRequest) +} +``` + +Implement GADBannerViewDelegate: + +```swift +func bannerViewDidReceiveAd(_ bannerView: GADBannerView) { + + // 8. Resize ad view if needed + AdViewUtils.findPrebidCreativeSize(bannerView, success: { size in + guard let bannerView = bannerView as? GAMBannerView else { return } + bannerView.resize(GADAdSizeFromCGSize(size)) + }, failure: { (error) in + PrebidDemoLogger.shared.error("Error occuring during searching for Prebid creative size: \(error)") + }) +} +``` + +#### Step 1: Create a BannerAdUnit +{:.no_toc} + +Initialize the `BannerAdUnit` with the following properties: + +- `configId` - an ID of the Stored Impression on the Prebid Server +- `adSize` - the size of the ad unit which will be used in the bid request. + +#### Step 2: Set ad formats +{:.no_toc} + +For multiformat ad unit, you must set both banner and video ad formats. + +#### Step 3: Configure banner parameters +{:.no_toc} + +Provide configuration properties for the banner ad using the [BannerParameters](#step-2-configure-banner-parameters) object. + +#### Step 4: Configure video parameters +{:.no_toc} + +Provide configuration properties for the video ad using the [VideoParameters](#step-3-configure-the-video-parameters) object. + +#### Step 5: Create a GAMBannerView +{:.no_toc} + +Follow the [GMA SDK documentation](https://developers.google.com/ad-manager/mobile-ads-sdk/ios/banner) to integrate a banner ad unit. + +#### Step 6: Make a bid request +{:.no_toc} + +The `fetchDemand` method makes a bid request to the Prebid Server. You should provide a `GAMRequest` object to this method so Prebid SDK sets the targeting keywords of the winning bid for future ad requests. + +#### Step 7: Load an Ad +{:.no_toc} + +Now you should request the ad from GAM. If the `GAMRequest` contains targeting keywords, the respective Prebid line item will be returned from GAM and GMA SDK will render its creative. + +Be sure that you make the ad request with the same `GAMRequest` object that you passed to the `fetchDemand` method. Otherwise, the ad request won't contain targeting keywords, and Prebid's ad won't ever be displayed. + +#### Step 8: Adjust the ad view size +{:.no_toc} + +Once an app receives a signal that an ad is loaded, you should use the method `AdViewUtils.findPrebidCreativeSize` to verify whether it is a Prebid ad and resize the ad slot respectively to the creative's properties. + +## Interstitial API + +Starting with Prebid Mobile `2.1.0` you can use `InterstitialAdUnit ` to bid over the banner and/or video demand. The default ad format is `.banner`. To customize the bidding format you should specify the `adFormats` property of the `InterstitialAdUnit `. + +### HTML Interstitial Integration example: ``` swift // 1. Create an Interstitial Ad Unit -adUnit = InterstitialAdUnit(configId: storedImpDisplayInterstitial) +adUnit = InterstitialAdUnit(configId: CONFIG_ID) // 2. Make a bid request to Prebid Server let gamRequest = GAMRequest() @@ -283,7 +405,7 @@ adUnit.fetchDemand(adObject: gamRequest) { [weak self] resultCode in } ``` -#### Step 1: InterstitialAdUnit +#### Step 1: Create an InterstitialAdUnit {:.no_toc} Initialize the InterstitialAdUnit with the following properties: @@ -298,6 +420,9 @@ Initialize the InterstitialAdUnit with the following properties: > Prebid Server will send the eligible size list to each bidder to solicit a bid. For a full description of the Prebid Server logic, please refer to the [Prebid Server PR 797](https://github.com/prebid/prebid-server/pull/797/files). +{: .alert.alert-warning :} +Starting from PrebidMobile `2.1.0` the `parameters` property is deprecated. Use `bannerParameters` instead. + #### Step 2: Make a bid request {:.no_toc} @@ -315,34 +440,36 @@ Be sure that you make the ad request with the same `GAMRequest` object that you Follow the [GMA SDK guide](https://developers.google.com/ad-manager/mobile-ads-sdk/ios/interstitial#display_the_ad) to display an interstitial ad right after receiving it or later in a natural pauses in the flow of an app. -## Video Interstitial +### Video Interstitial Integration Example: ```swift -// 1. Create a VideoInterstitialAdUnit -adUnit = VideoInterstitialAdUnit(configId: storedImpVideoInterstitial) +// 1. Create a InterstitialAdUnit +adUnit = InterstitialAdUnit(configId: CONFIG_ID) -// 2. Configure video parameters -let parameters = VideoParameters() -parameters.mimes = ["video/mp4"] +// 2. Set ad format +adUnit.adFormats = [.video] + +// 3. Configure video parameters +let parameters = VideoParameters(mimes: ["video/mp4"]) parameters.protocols = [Signals.Protocols.VAST_2_0] parameters.playbackMethod = [Signals.PlaybackMethod.AutoPlaySoundOff] -adUnit.parameters = parameters +adUnit.videoParameters = parameters -// 3. Make a bid request to Prebid Server +// 4. Make a bid request to Prebid Server let gamRequest = GAMRequest() adUnit.fetchDemand(adObject: gamRequest) { [weak self] resultCode in PrebidDemoLogger.shared.info("Prebid demand fetch for GAM \(resultCode.name())") -// 4. Load a GAM interstitial ad +// 5. Load a GAM interstitial ad GAMInterstitialAd.load(withAdManagerAdUnitID: gamAdUnitVideoInterstitialOriginal, request: gamRequest) { ad, error in guard let self = self else { return } if let error = error { PrebidDemoLogger.shared.error("Failed to load interstitial ad with error: \(error.localizedDescription)") } else if let ad = ad { - // 5. Present the interstitial ad + // 6. Present the interstitial ad ad.present(fromRootViewController: self) ad.fullScreenContentDelegate = self } @@ -350,6 +477,9 @@ GAMInterstitialAd.load(withAdManagerAdUnitID: gamAdUnitVideoInterstitialOriginal } ``` +{: .alert.alert-warning :} +Starting from PrebidMobile `2.1.0` the `VideoInterstitialAdUnit` class is deprecated. Use `InterstitialAdUnit` class with video ad format instead. + #### Step 1: Create an Ad Unit {:.no_toc} @@ -357,42 +487,127 @@ Initialize the Interstitial Video Ad Unit with properties: - `configId` - an ID of Stored Impression on the Prebid Server -#### Step 2: Configure video parameters + +#### Step 2: Set ad format {:.no_toc} -Provide configuration properties for the video ad using the [VideoParameters](#step-2-configure-video-parameters) object. +For video ad unit, you must set video ad format. Default value for `adFormats` property is `[.banner]`. -#### Step 3: Make a bid request +#### Step 3: Configure video parameters +{:.no_toc} + +Provide configuration properties for the video ad using the [VideoParameters](#step-3-configure-the-video-parameters) object. + +#### Step 4: Make a bid request {:.no_toc} The `fetchDemand` method makes a bid request to the Prebid Server. You should provide a `GAMRequest` object to this method so Prebid SDK sets the targeting keywords of the winning bid for future ad requests. -#### Step 4: Load a GAM interstitial ad +#### Step 5: Load a GAM interstitial ad {:.no_toc} Now you should request the ad from GAM. If the `GAMRequest` contains targeting keywords. The respective Prebid line item will be returned from GAM and GMA SDK will render its creative. Be sure that you make the ad request with the same `GAMRequest` object that you passed to the `fetchDemand` method. Otherwise the ad request won't contain targeting keywords and Prebid's ad won't ever be displayed. -#### Step 5: Present the interstitial ad +#### Step 6: Present the interstitial ad {:.no_toc} Follow the [GMA SDK guide](https://developers.google.com/ad-manager/mobile-ads-sdk/ios/interstitial#display_the_ad) to display an interstitial ad right after receiving it or later in a natural pauses in the flow of an app. -## Rewarded Video +### Multiformat Interstitial (HTML + Video) + +Integration example: + +``` swift +// 1. Create an InterstitialAdUnit +adUnit = InterstitialAdUnit(configId: CONFIG_ID, minWidthPerc: 60, minHeightPerc: 70) + +// 2. Set adFormats +adUnit.adFormats = [.banner, .video] + +// 3. Configure parameters +let parameters = VideoParameters(mimes: ["video/mp4"]) +parameters.protocols = [Signals.Protocols.VAST_2_0] +parameters.playbackMethod = [Signals.PlaybackMethod.AutoPlaySoundOff] +adUnit.videoParameters = parameters + +// 4. Make a bid request to Prebid Server +let gamRequest = GAMRequest() +adUnit.fetchDemand(adObject: gamRequest) { [weak self] resultCode in + PrebidDemoLogger.shared.info("Prebid demand fetch for GAM \(resultCode.name())") + + // 5. Load a GAM interstitial ad + GAMInterstitialAd.load(withAdManagerAdUnitID: gamAdUnitMultiformatInterstitialOriginal, request: gamRequest) { ad, error in + guard let self = self else { return } + + if let error = error { + PrebidDemoLogger.shared.error("Failed to load interstitial ad with error: \(error.localizedDescription)") + } else if let ad = ad { + // 5. Present the interstitial ad + ad.fullScreenContentDelegate = self + ad.present(fromRootViewController: self) + } + } +} +``` + +#### Step 1: Create an InterstitialAdUnit +{:.no_toc} + +Initialize the InterstitialAdUnit with the following properties: + +- `configId` - an ID of Stored Impression on the Prebid Server +- `minWidthPerc`: Optional parameter to specify the minimum width percent an ad may occupy of a device's real estate. Support in SDK version 1.2+ +- `minHeightPrec`: Optional parameter to specify the minimum height percent an ad may occupy of a device's real estate. Support in SDK version 1.2+ + +> **NOTE:** As of version 1.2+, Prebid SDK has extended the functionality of Interstitial ad monetization by using a smart ad size selection process to monetize sizes smaller than full screen ads. App developers can specify a minimum width and minimum height percentage an ad can occupy of a devices real state, with Prebid Server (PBS) deriving a limited set of ad sizes (max 10) as eligible for the auction. + +> PBS will take the AdUnit's size (width and height) as the max size for the interstitial as size, generating a list of ad sizes, selecting the first 10 sizes that fall within the imp's max size and minimum percentage size. All the interstitial parameters will still be passed to the bidders, allowing them to use their own size matching algorithms if they prefer. + +> Prebid Server will send the eligible size list to each bidder to solicit a bid. For a full description of the Prebid Server logic, please refer to the [Prebid Server PR 797](https://github.com/prebid/prebid-server/pull/797/files). + +#### Step 2: Set ad formats +{:.no_toc} + +For multiformat ad unit, you must set both banner and video ad formats. + +#### Step 3: Configure parameters +{:.no_toc} + +Provide configuration properties for the banner ad using the [BannerParameters](#step-2-configure-banner-parameters) object. +Provide configuration properties for the video ad using the [VideoParameters](#step-3-configure-the-video-parameters) object. + +#### Step 4: Make a bid request +{:.no_toc} + +The `fetchDemand` method makes a bid request to the Prebid Server. You should provide a `GAMRequest` object to this method so Prebid SDK sets the targeting keywords of the winning bid for future ad requests. + +#### Step 5: Load a GAM interstitial ad +{:.no_toc} + +You should now request the ad from GAM. If the `GAMRequest` contains targeting keywords. The respective Prebid line item will be returned from GAM and GMA SDK will render its creative. + +Be sure that you make the ad request with the same `GAMRequest` object that you passed to the `fetchDemand` method. Otherwise the ad request won't contain targeting keywords and Prebid's ad won't ever be displayed. + +#### Step 6: Present the interstitial ad +{:.no_toc} + +Follow the [GMA SDK guide](https://developers.google.com/ad-manager/mobile-ads-sdk/ios/interstitial#display_the_ad) to display an interstitial ad right after receiving it or later in a natural pauses in the flow of an app. + +## Rewarded Video API Integration example: ``` swift // 1. Create a RewardedVideoAdUnit -adUnit = RewardedVideoAdUnit(configId: storedImpVideoRewarded) +adUnit = RewardedVideoAdUnit(configId: CONFIG_ID) // 2. Configure video parameters -let parameters = VideoParameters() -parameters.mimes = ["video/mp4"] +let parameters = VideoParameters(mimes: ["video/mp4"]) parameters.protocols = [Signals.Protocols.VAST_2_0] parameters.playbackMethod = [Signals.PlaybackMethod.AutoPlaySoundOff] -adUnit.parameters = parameters +adUnit.videoParameters = parameters // 3. Make a bid request to Prebid Server adUnit.fetchDemand(adObject: gamRequest) { [weak self] resultCode in @@ -414,7 +629,7 @@ adUnit.fetchDemand(adObject: gamRequest) { [weak self] resultCode in } } ``` -#### Step 1: Create an Ad Unit +#### Step 1: Create a RewardedVideoAdUnit {:.no_toc} Initialize the Rewarded Video Ad Unit with properties: @@ -424,7 +639,10 @@ Initialize the Rewarded Video Ad Unit with properties: #### Step 2: Configure video parameters {:.no_toc} -Provide configuration properties for the video ad using the [VideoParameters](#step-2-configure-video-parameters) object. +Provide configuration properties for the video ad using the [VideoParameters](#step-3-configure-the-video-parameters) object. + +{: .alert.alert-warning :} +Please, note that starting from PrebidMobile `2.1.0` the `parameters` property is deprecated. Use `videoParameters` instead. #### Step 3: Make a bid request {:.no_toc} @@ -443,20 +661,19 @@ Be sure that you make the ad request with the same `GAMRequest` object that you Follow the [GMA SDK guide](https://developers.google.com/ad-manager/mobile-ads-sdk/ios/rewarded#show_the_ad) to display a rewarded ad right after receiving it or later in natural pauses in the flow of an app. -## Video Instream +## Instream Video API Integration example: ```swift -// 1. Create VideoAdUnit -adUnit = VideoAdUnit(configId: storedImpVideo, size: CGSize(width: 1,height: 1)) +// 1. Create InstreamVideoAdUnit +adUnit = InstreamVideoAdUnit(configId: CONFIG_ID, size: CGSize(width: 1,height: 1)) // 2. Configure Video Parameters -let parameters = VideoParameters() -parameters.mimes = ["video/mp4"] +let parameters = VideoParameters(mimes: ["video/mp4"]) parameters.protocols = [Signals.Protocols.VAST_2_0] parameters.playbackMethod = [Signals.PlaybackMethod.AutoPlaySoundOn] -adUnit.parameters = parameters +adUnit.videoParameters = parameters // 3. Prepare IMAAdsLoader adsLoader = IMAAdsLoader(settings: nil) @@ -530,10 +747,13 @@ func adsManagerDidRequestContentResume(_ adsManager: IMAAdsManager) { } ``` -#### Step 1: Create an Ad Unit +{: .alert.alert-warning :} +Starting from PrebidMobile `2.1.0` the `VideoAdUnit` class is deprecated. Use `InstreamVideoAdUnit` class instead. + +#### Step 1: Create an InstreamVideoAdUnit {:.no_toc} -Initialize the Video Ad Unit with properties: +Initialize the Instream Video Ad Unit with properties: - `configId` - an ID of Stored Impression on the Prebid Server - `size` - Width and height of the video ad unit. @@ -541,7 +761,7 @@ Initialize the Video Ad Unit with properties: #### Step 2: Configure video parameters {:.no_toc} -Provide configuration properties for the video ad using the [VideoParameters](#step-2-configure-video-parameters) object. +Provide configuration properties for the video ad using the [VideoParameters](#step-3-configure-the-video-parameters) object. #### Step 3: Prepare IMAAdsLoader {:.no_toc} @@ -553,7 +773,6 @@ Prepare the in-stream setup according to the [Google's docs](https://developers. The `fetchDemand` method makes a bid request to the Prebid Server. You should use the version of the `fetchDemand` which returns the targeting keywords in the callback. Later you will construct the IMA ad request using these keywords. - #### Step 5: Generate GAM Instream URI {:.no_toc} @@ -575,7 +794,9 @@ On a successful load event, the `IMAAdsLoader` calls the adsLoadedWithData metho Lastly, to manage events and state changes, the ads manager needs a delegate of its own. The `IMAAdManagerDelegate` has methods to handle ad events and errors, as well as methods to trigger play and pause on your video content. -## Native Style Banner +## Native API + +### Native Banner Integration example: @@ -602,7 +823,7 @@ Then integrate the native style ad using GAM Banner ad unit ```swift // 1. Create NativeRequest -nativeUnit = NativeRequest(configId: nativeStoredImpression, assets: nativeRequestAssets) +nativeUnit = NativeRequest(configId: CONFIG_ID, assets: nativeRequestAssets) nativeUnit.context = ContextType.Social nativeUnit.placementType = PlacementType.FeedContent nativeUnit.contextSubType = ContextSubType.Social @@ -677,7 +898,7 @@ You should now request the ad from GAM. If the `GAMRequest` contains targeting k Be sure that you make the ad request with the same `GAMRequest` object that you passed to the `fetchDemand` method. Otherwise the ad request won't contain targeting keywords and Prebid's ad won't ever be displayed. -## In-App Native +### In-App Native At a high level the in app rendering process works like this: @@ -704,25 +925,25 @@ These instructions will enable you to create a creative template in either Googl 6. Name your new format. 7. Choose `ADD VARIABLE` and add the following variable names and placeholders. - {: .table .table-bordered .table-striped } - | Variable Name | Placeholder | - |---------------------+----------------------------------| - | isPrebid | [%isPrebid%] | - | hb_cache_id_local | [%hb_cache_id_local%] | +{: .table .table-bordered .table-striped } +| Variable Name| Placeholder| +|--------------+------------| +| isPrebid | [%isPrebid%] | +| hb_cache_id_local | [%hb_cache_id_local%] | - Make sure to indicate that the variables are required. +Make sure to indicate that the variables are required. 8. Return to the home screen, click `Delivery > Creatives`, and create a creative with `Native Format`, choosing the template you created. In the user-defined variables you just created, set the following values: {: .table .table-bordered .table-striped } - | Variable Name | Value | - |---------------------+----------------------------------| - | isPrebid | 1 | - | hb_cache_id_local | %%PATTERN:hb_cache_id_local%% | +| Variable Name | Value | +|---------------------+----------------------------------| +| isPrebid | 1 | +| hb_cache_id_local | %%PATTERN:hb_cache_id_local%% | 9. Create Prebid line items with price priority and a display ad type that is targeting `hb_pb key-values`. Associate the creative you added in steps 4 thru 8 (making sure to choose your native format as expected creatives on the line item) to the ad unit you created in the second step. -### Integration Example +#### Integration Example {:.no_toc} Prepare the set of requested assets first. @@ -868,10 +1089,7 @@ Once the Prebid line item is recognized, the `NativeAdDelegate` will be activate Each ad unit in the original API is a subclass of the `AdUnit` class, which provides the following properties and methods for the additional configuration. -### Properties - -#### pbAdSlot -{:.no_toc} +### Ad Slot PB Ad Slot is an identifier tied to the placement the ad will be delivered in. The use case for PB Ad Slot is to pass to exchange an ID they can use to tie to reporting systems or use for data science driven model building to match with impressions sourced from alternate integrations. A common ID to pass is the ad server slot name. @@ -898,7 +1116,6 @@ Allows to resume the stopped autorefresh for the ad unit with predefined autoref ### Context Keyword - #### addContextKeyword {:.no_toc} From c2c8151ea50465cc6279cbee09bd541aea30b194 Mon Sep 17 00:00:00 2001 From: bretg Date: Thu, 27 Apr 2023 16:20:13 -0400 Subject: [PATCH 186/762] deprecating rhythmone (#4523) --- dev-docs/bidders/rhythmone.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/dev-docs/bidders/rhythmone.md b/dev-docs/bidders/rhythmone.md index ab4b8b2e..770b23eb 100644 --- a/dev-docs/bidders/rhythmone.md +++ b/dev-docs/bidders/rhythmone.md @@ -10,9 +10,11 @@ gdpr_supported: true schain_supported: true gvl_id: 36 sidebarType: 1 +enable_download: false --- - +{: .alert.alert-warning :} +The rhythmone bidder is deprecated, and will be removed in a future release of Prebid.js and Prebid Server. ### Bid Params From 0311b8dff0de7025924eff21e5a1f74ab2a8bf06 Mon Sep 17 00:00:00 2001 From: bretg Date: Thu, 27 Apr 2023 16:46:04 -0400 Subject: [PATCH 187/762] mobile home page typos (#4526) * mobile home page typos * table header --- prebid-mobile/prebid-mobile.md | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/prebid-mobile/prebid-mobile.md b/prebid-mobile/prebid-mobile.md index 03f8e5ff..4ee540ef 100644 --- a/prebid-mobile/prebid-mobile.md +++ b/prebid-mobile/prebid-mobile.md @@ -17,11 +17,11 @@ Prebid Mobile libraries are available for iOS and Android. * TOC {:toc} -## Benefits and Fetures +## Benefits and Features Prebid SDK rendering offers the following benefits: -- **Transparent, open source header bidding solution**. The single integration point with Prebid Server**, enabling direct access to more mobile buyers. +- **Transparent, open source header bidding solution**. The single integration point with Prebid Server, enabling direct access to more mobile buyers. - **Monetization without an Ad Server**: Publishers who do not have a direct sales force or have no need for an ad server can still access Prebid's mobile demand stack. Publishers will be able to render ads directly without relying on any 3rd party SDKs. - **Reduced ad delivery latency**: The rendering module enables Prebid SDK to render ads immediately when demand is returned from Prebid Server or when receiving the render signal from an ad server. The render process should vastly reduce ad delivery speeds. - **Less infrastructure**: The rendering API does not rely on Prebid Server's Cache server, reducing the cost and utility of Prebid Server Cache. @@ -53,20 +53,18 @@ Prebid SDK supports following integration scenarios: In all scenarios, Prebid SDK leverages Prebid Server for demand. -The next chart shows which API is used for which Ad Server +The following chart shows which API is used for which Ad Server {: .table .table-bordered .table-striped } -| |Original API|Rendering API|Mediation API| +|Ad Server|Original API|Rendering API|Mediation API| |------------|------------|-------------|-------------| |No Ad Server| | ✅ | | |GAM | ✅ | ✅ | | |AdMob | | | ✅ | |MAX | | | ✅ | -Nothe that you can integrate Prebid demand into GAM setup using one of the options - Original API, Rendering API. - -Below are the processes for all modes: +The following sections describe each integration method. ### No Ad Server From 077df14ce2498612a9b078d7c1231fb50aad6991 Mon Sep 17 00:00:00 2001 From: Chris Huie Date: Fri, 28 Apr 2023 01:54:14 -0600 Subject: [PATCH 188/762] add pbs gpp suport (#4525) * add pbs gpp suport * move to bottom --- dev-docs/pbs-bidders.md | 1 + 1 file changed, 1 insertion(+) diff --git a/dev-docs/pbs-bidders.md b/dev-docs/pbs-bidders.md index ca45b46a..093f62c8 100644 --- a/dev-docs/pbs-bidders.md +++ b/dev-docs/pbs-bidders.md @@ -56,6 +56,7 @@ Publishers are advised to check with legal counsel before doing business with an | **Mobile App Support** | {% if page.pbs_app_supported and page.pbs_app_supported == false %}no{% elsif page.pbs_app_supported and page.pbs_app_supported == true %}yes{% else %}check with bidder{% endif %} | **Prebid Server Adapter** | yes | | **Floors Support** | {% if page.floors_supported == false %}no{% elsif page.floors_supported == true %}yes{% else %}check with bidder{% endif %} | **First Party Data Support** | {% if page.fpd_supported == true %}yes{% elsif page.fpd_supported == false %}no{% else %}check with bidder{% endif %} | | **Multi Format Support** | {% if page.multiformat_supported %}{{page.multiformat_supported}}{% else %}check with bidder{% endif %} | **ORTB Blocking Support** | {% if page.ortb_blocking_supported == true %}yes{% elsif page.ortb_blocking_supported == false %}no{% elsif page.ortb_blocking_supported == 'partial' %}partial{% else %}check with bidder{% endif %} | +| **GPP Support** | {% if page.gpp_supported == true %}yes{% else %}no{% endif %} |

"Send All Bids" Ad Server Keys

From 80a2645882436316fa4c1ac7e60bce97cb1b1e5b Mon Sep 17 00:00:00 2001 From: TM Date: Fri, 28 Apr 2023 09:55:56 +0200 Subject: [PATCH 189/762] banner support added (#4524) Co-authored-by: Tomasz Mielcarz --- dev-docs/bidders/adrino.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dev-docs/bidders/adrino.md b/dev-docs/bidders/adrino.md index ba44df65..225727b8 100644 --- a/dev-docs/bidders/adrino.md +++ b/dev-docs/bidders/adrino.md @@ -5,7 +5,7 @@ description: Prebid Adrino Bidder Adapter pbjs: true pbs: true biddercode: adrino -media_types: no-display, native +media_types: banner, native gdpr_supported: true gvl_id: 1072 sidebarType: 1 From 13cb6b2a947e717fe6f0f115199770b037bf72b2 Mon Sep 17 00:00:00 2001 From: TheMediaGrid <44166371+TheMediaGrid@users.noreply.github.com> Date: Fri, 28 Apr 2023 10:59:59 +0200 Subject: [PATCH 190/762] TrustX: update legacy doc (#4518) --- dev-docs/bidders/trustxstandalone.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/dev-docs/bidders/trustxstandalone.md b/dev-docs/bidders/trustxstandalone.md index 45c8797b..f67fa71d 100644 --- a/dev-docs/bidders/trustxstandalone.md +++ b/dev-docs/bidders/trustxstandalone.md @@ -13,6 +13,8 @@ pbjs_version_notes: 6.x and before sidebarType: 1 --- +#### Is relevant for versions 6.X and before + ### Table of Contents - [Table of Contents](#table-of-contents) From f0a8a0dc897dc1d70b10a2cc7c3fbc94578e5d54 Mon Sep 17 00:00:00 2001 From: bretg Date: Fri, 28 Apr 2023 05:10:01 -0400 Subject: [PATCH 191/762] GPID: clarifying when gpt-pre-auction can be used (#4512) --- features/pbAdSlot.md | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/features/pbAdSlot.md b/features/pbAdSlot.md index 8da35d63..37b125f9 100644 --- a/features/pbAdSlot.md +++ b/features/pbAdSlot.md @@ -54,11 +54,13 @@ someday we'll deprecate it in favor of the more standard GPID. There are two ways a publisher can inject these values into the header bidding auctions: -1. Supply them manually on the PBJS AdUnits -2. Install the [GPT Pre-Auction module](/dev-docs/modules/gpt-pre-auction.html) +1. Supply them manually on the PBJS AdUnits. This is required for in-stream video and for publishers not using GAM. +2. If you're using GPT, install the [GPT Pre-Auction module](/dev-docs/modules/gpt-pre-auction.html) ### Defining them on the PBJS Ad Unit +This approach what you'll have to use for in-stream video and for publishers not using GAM. + #### Example 1 - unique ad slot names In this example, there's no need for the "UNIQUIFIER" string because every ad slot From 3ac6fc775295bad5206d0dc95edf86f69f952c5c Mon Sep 17 00:00:00 2001 From: Nima Sarayan <36764654+nimasrn@users.noreply.github.com> Date: Fri, 28 Apr 2023 12:46:58 +0330 Subject: [PATCH 192/762] Updated docs for Vidoomy blocking supported (#4493) --- dev-docs/bidders/vidoomy.md | 64 +++++++++++++++++++++++++++++++++---- 1 file changed, 57 insertions(+), 7 deletions(-) diff --git a/dev-docs/bidders/vidoomy.md b/dev-docs/bidders/vidoomy.md index aba41d23..18be825a 100644 --- a/dev-docs/bidders/vidoomy.md +++ b/dev-docs/bidders/vidoomy.md @@ -12,23 +12,73 @@ coppa_supported: true pbs: true sidebarType: 1 schain_supported: true +ortb_blocking_supported: true --- ### Note: + [Vidoomy](https://vidoomy.com/), for more info please contact support@vidoomy.com ### Bid Params {: .table .table-bordered .table-striped } -| Name | Scope | Description | Example | Type | -|------------------|----------|------------------|------------------------------|----------| -| `id` | required | id | `123123` | `string` | -| `pid` | required | pid | `'123123'` | `string` | +| Name | Scope | Description | Example | Type | +|-------|----------|-------------|------------|----------| +| `id` | required | id | `123123` | `string` | +| `pid` | required | pid | `'123123'` | `string` | ### Bid Params (Prebid Server) {: .table .table-bordered .table-striped } -| Name | Scope | Description | Example | Type | -|------------------|----------|------------------|------------------------------|----------| -| `zoneId` | required | Zone Id | "123123" | `string` | + +| Name | Scope | Description | Example | Type | +|----------|----------|---------------------------------------------|-------------------|----------------| +| `zoneId` | required | Zone Id | "123123" | `string` | +| `bcat` | optional | List of blocked advertiser categories (IAB) | `['IAB1-1']` | `string array` | +| `badv` | optional | Blocked Advertiser Domains | `['example.com']` | `string array` | +| `bapp` | optional | blocked advertiser mobile app bundles | `['app.com']` | `string array` | +| `btype` | optional | blocked creative types (e.g. XHTML) | `[1, 2, 3]` | `int array` | +| `battr` | optional | blocked creative attributes (e.g. audio) | `[1, 2, 3]` | `int array` | + +Notes: + +- Preferred to provide the `bcat`, `badv`, `bapp`, `btype` and `battr` within the first party data (above). When both + methods are provided, first + party data values will be prioritized. + +### First Party Data + +Publishers can use the `ortb2` configuration parameter to provide First Party Data. + +#### OpenRTB Parameters + +The following table contains currently supported parameters we parse. + +{: .table .table-bordered .table-striped } + +| Name | Scope | Description | Example | Type | +|---------|----------|---------------------------------------------|-------------------|---------| +| `bcat` | optional | List of blocked advertiser categories (IAB) | `['IAB1-1']` | `Array` | +| `badv` | optional | Blocked Advertiser Domains | `['example.com']` | `Array` | +| `bapp` | optional | blocked advertiser mobile app bundles | `['app.com']` | `Array` | +| `btype` | optional | blocked creative types (e.g. XHTML) | `[1, 2, 3]` | `Array` | +| `battr` | optional | blocked creative attributes (e.g. audio) | `[1, 2, 3]` | `Array` | + +Notes: + +- will extract the bcat,badv,bapp,btype,battr if passed within `ortb2` + +Example configuration: + +``` +pbjs.setConfig({ + ortb2: { + bcat: ['IAB1-1'], + badv: ['example.com'], + bapp: ['app.com'], + btype: [1, 2, 3], + battr: [1, 2, 3] + } +}); +``` From 34456b3f724237e748f4e34d84af84db9679f81d Mon Sep 17 00:00:00 2001 From: Nisar Thadathil Date: Fri, 28 Apr 2023 16:24:50 +0530 Subject: [PATCH 193/762] Updated documentation for Vidoomy bidfloor and userId module (#4474) * Updated docs for Vidoomy blocking supported * Updated documentation for Vidoomy bidfloor support --------- Co-authored-by: nima --- dev-docs/bidders/vidoomy.md | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/dev-docs/bidders/vidoomy.md b/dev-docs/bidders/vidoomy.md index 18be825a..19476f40 100644 --- a/dev-docs/bidders/vidoomy.md +++ b/dev-docs/bidders/vidoomy.md @@ -13,28 +13,31 @@ pbs: true sidebarType: 1 schain_supported: true ortb_blocking_supported: true +userIds: all +floors_supported: true --- ### Note: [Vidoomy](https://vidoomy.com/), for more info please contact support@vidoomy.com -### Bid Params +### Client Side Bid Params {: .table .table-bordered .table-striped } +| Name | Scope | Description | Example | Type | +|------------------|----------|------------------|------------------------------|----------| +| `id` | required | id | `'123123'` | `string` | +| `pid` | required | pid | `'123123'` | `string` | +| `bidfloor` | optional | CPM bidfloor in USD | `0.08` | `float` | -| Name | Scope | Description | Example | Type | -|-------|----------|-------------|------------|----------| -| `id` | required | id | `123123` | `string` | -| `pid` | required | pid | `'123123'` | `string` | -### Bid Params (Prebid Server) +### Server Side Bid Params (Prebid Server) {: .table .table-bordered .table-striped } | Name | Scope | Description | Example | Type | |----------|----------|---------------------------------------------|-------------------|----------------| -| `zoneId` | required | Zone Id | "123123" | `string` | +| `zoneId` | required | Zone Id | `'123123'` | `string` | | `bcat` | optional | List of blocked advertiser categories (IAB) | `['IAB1-1']` | `string array` | | `badv` | optional | Blocked Advertiser Domains | `['example.com']` | `string array` | | `bapp` | optional | blocked advertiser mobile app bundles | `['app.com']` | `string array` | @@ -81,4 +84,4 @@ pbjs.setConfig({ battr: [1, 2, 3] } }); -``` +``` \ No newline at end of file From 74e824f1fdfe4890a5a5a6814e08811bf7aecc02 Mon Sep 17 00:00:00 2001 From: Patrick McCann Date: Tue, 2 May 2023 14:27:37 -0400 Subject: [PATCH 194/762] Gdpr warnings (#4529) * Update apstream.md * Update cleanmedianet.md * Update engageya.md * Update gamoshi.md * Update gamoshi.md * Update logan.md * Update logan.md * Update mathildeads.md * Update smilewanted.md * Update triplelift.md * Update videoreach.md * Update videoreach.md * Update beop.md * Update yahoossp.md * Update logan.md * Update triplelift.md * Update yahoossp.md * Update apstream.md * Update beop.md * Update cleanmedianet.md * Update engageya.md * Update logan.md * Update mathildeads.md * Update videoreach.md * Update aol.md * Update triplelift.md --------- Co-authored-by: bretg --- dev-docs/bidders/aol.md | 10 +++++++--- dev-docs/bidders/apstream.md | 6 +++++- dev-docs/bidders/beop.md | 4 ++++ dev-docs/bidders/cleanmedianet.md | 4 ++++ dev-docs/bidders/engageya.md | 6 +++++- dev-docs/bidders/logan.md | 6 +++++- dev-docs/bidders/mathildeads.md | 6 +++++- dev-docs/bidders/smilewanted.md | 6 +++++- dev-docs/bidders/videoreach.md | 5 ++++- dev-docs/bidders/yahoossp.md | 6 +++++- 10 files changed, 49 insertions(+), 10 deletions(-) diff --git a/dev-docs/bidders/aol.md b/dev-docs/bidders/aol.md index 536916ab..2e0a80f0 100644 --- a/dev-docs/bidders/aol.md +++ b/dev-docs/bidders/aol.md @@ -4,17 +4,21 @@ title: AOL description: Prebid AOL Bidder Adaptor pbjs: true biddercode: aol -gdpr_supported: true +gdpr_supported: false usp_supported: true gvl_id: 25 userIds: connectId sidebarType: 1 --- +### Disclosure + +This adapter may not handle user syncs for TCF2 or GPP correctly. The user sync consent querystring parameters are generated at the time of the bid request and might be stale at the time of the user sync. See https://github.com/prebid/Prebid.js/pull/9345#issuecomment-1362887086 + ### IMPORTANT NOTICE! **TL;DR** -1. The `aol` adapter is scheduled to be depreciated. -2. Our New `yahoossp` is available for early adoption. +1. The `aol` adapter is scheduled to be deprecated. +2. Our New `yahoossp` is available for adoption. 3. Please contact your Account Manager/Executive for migration details. Dear Publishers & Partners, diff --git a/dev-docs/bidders/apstream.md b/dev-docs/bidders/apstream.md index f521dc93..45a2bf89 100644 --- a/dev-docs/bidders/apstream.md +++ b/dev-docs/bidders/apstream.md @@ -5,11 +5,15 @@ description: AP Stream Bidder Adapter biddercode: apstream pbjs: true media_types: banner -gdpr_supported: true +gdpr_supported: false gvl_id: 394 sidebarType: 1 --- +### Disclosure + +Note: This bidder passes consent strings but not the gdprApplies flag to its backend. This may result in some incorrect TCF2 processing, such as when the consent string is not yet available but the publisher has decided GDPR always applies. See https://github.com/prebid/Prebid.js/issues/7775 + ### Bid Params {: .table .table-bordered .table-striped } diff --git a/dev-docs/bidders/beop.md b/dev-docs/bidders/beop.md index c6ae7b9c..bc7acb12 100644 --- a/dev-docs/bidders/beop.md +++ b/dev-docs/bidders/beop.md @@ -7,6 +7,10 @@ biddercode: beop sidebarType: 1 --- +### Disclosure + +Note: This bidder never sends gdprApplies to its endpoint. This may result in some incorrect GDPR processing, such as when the consent string is not yet available but the publisher has decided GDPR always applies. See https://github.com/prebid/Prebid.js/issues/7775 + ### Bid Params {: .table .table-bordered .table-striped } diff --git a/dev-docs/bidders/cleanmedianet.md b/dev-docs/bidders/cleanmedianet.md index 5b1d420d..012797c7 100644 --- a/dev-docs/bidders/cleanmedianet.md +++ b/dev-docs/bidders/cleanmedianet.md @@ -21,6 +21,10 @@ gvl_id: multiformat_supported: will-bid-on-any --- +### Disclosure + +Note: This bidder appears to only consider gdprApplies if a consent string is available. This may result in some incorrect GDPR processing, such as when the consent string is not yet available but the publisher has decided GDPR always applies. See https://github.com/prebid/Prebid.js/issues/7775 + ### Bid params {: .table .table-bordered .table-striped } diff --git a/dev-docs/bidders/engageya.md b/dev-docs/bidders/engageya.md index 7b1e0523..59acd25c 100644 --- a/dev-docs/bidders/engageya.md +++ b/dev-docs/bidders/engageya.md @@ -5,10 +5,14 @@ description: Prebid Engageya Bidder Adapter media_type: banner, native biddercode: engageya pbjs: true -gdpr_supported: true +gdpr_supported: false sidebarType: 1 --- +### Disclosure + +Note: This bidder appears to only consider gdprApplies if a consent string is available. This may result in some incorrect TCF2 processing, such as when the consent string is not yet available but the publisher has decided GDPR always applies. See https://github.com/prebid/Prebid.js/issues/7775 + ### Bid params {: .table .table-bordered .table-striped } diff --git a/dev-docs/bidders/logan.md b/dev-docs/bidders/logan.md index dabd33ac..8280d42b 100644 --- a/dev-docs/bidders/logan.md +++ b/dev-docs/bidders/logan.md @@ -6,12 +6,16 @@ biddercode: logan usp_supported: true schain_supported: true media_types: banner, video, native -gdpr: true +gdpr_supported: false pbjs: true pbs: true sidebarType: 1 --- +### Disclosure + +Note: This bidder appears to only consider gdprApplies if a consent string is available. This may result in some incorrect GDPR processing, such as when the consent string is not yet available but the publisher has decided GDPR always applies. See https://github.com/prebid/Prebid.js/issues/7775 + ### Bid Params {: .table .table-bordered .table-striped } diff --git a/dev-docs/bidders/mathildeads.md b/dev-docs/bidders/mathildeads.md index f5c0043b..564b53eb 100644 --- a/dev-docs/bidders/mathildeads.md +++ b/dev-docs/bidders/mathildeads.md @@ -6,13 +6,17 @@ biddercode: mathildeads usp_supported: true schain_supported: true media_types: banner, video, native -gdpr_supported: true +gdpr_supported: false pbjs: true pbs: false pbs_app_supported: false sidebarType: 1 --- +### Disclosure + +Note: This bidder appears to only consider gdprApplies if a consent string is available. This may result in some incorrect TCF2 processing, such as when the consent string is not yet available but the publisher has decided GDPR always applies. See https://github.com/prebid/Prebid.js/issues/7775 + ### Prebid.JS Bid Params {: .table .table-bordered .table-striped } diff --git a/dev-docs/bidders/smilewanted.md b/dev-docs/bidders/smilewanted.md index a56e2e1e..13dd71ae 100644 --- a/dev-docs/bidders/smilewanted.md +++ b/dev-docs/bidders/smilewanted.md @@ -6,13 +6,17 @@ media_types: banner, video pbjs: true pbs: true biddercode: smilewanted -gdpr_supported: true +gdpr_supported: false usp_supported: true userIds: all gvl_id: 639 sidebarType: 1 --- +### Disclosure + +Note: This bidder appears to only consider gdprApplies if a consent string is available.. This may result in some incorrect TCF2 processing, such as when the consent string is not yet available but the publisher has decided GDPR always applies. See https://github.com/prebid/Prebid.js/issues/7775 + ### Note To use us as a bidder you must have an account and an active "zoneId" on our Smile Wanted platform. diff --git a/dev-docs/bidders/videoreach.md b/dev-docs/bidders/videoreach.md index 2420efc1..e74f82d5 100644 --- a/dev-docs/bidders/videoreach.md +++ b/dev-docs/bidders/videoreach.md @@ -5,10 +5,13 @@ description: Video Reach Bidder Adapter for Prebid.js pbjs: true biddercode: videoreach media_types: banner, video -gdpr_supported: true +gdpr_supported: false sidebarType: 1 --- +### Disclosure + +Note: This bidder's user syncs appear to only consider gdprApplies if a consent string is available. This may result in some incorrect TCF2 processing, such as when the consent string is not yet available but the publisher has decided GDPR always applies. See https://github.com/prebid/Prebid.js/issues/7775 ### Bid Params diff --git a/dev-docs/bidders/yahoossp.md b/dev-docs/bidders/yahoossp.md index 5be9c7b3..b5b077a3 100644 --- a/dev-docs/bidders/yahoossp.md +++ b/dev-docs/bidders/yahoossp.md @@ -7,7 +7,7 @@ pbjs: true media_types: banner, video biddercode: yahoossp prebid_member: true -gdpr_supported: true +gdpr_supported: false usp_supported: true schain_supported: true coppa_supported: true @@ -16,6 +16,10 @@ userIds: All sidebarType: 1 --- +### Disclosure + +This adapter may not handle user syncs for TCF2 or GPP correctly. The user sync consent querystring parameters are generated at the time of the bid request and might be stale at the time of the user sync. See https://github.com/prebid/Prebid.js/pull/9345#issuecomment-1362887086 + ### Important Notice (JS vs PBS) There are differences between our Prebid.js & Prebid-Server Yahoo SSP adapters. The Prebid-server adapter currently does not support: From c9e2e1b6dffd0a69e7fbe52d574ea9bd919c549a Mon Sep 17 00:00:00 2001 From: bretg Date: Tue, 2 May 2023 16:32:26 -0400 Subject: [PATCH 195/762] PBS auction endpoint price granularity (#4532) native is supported per https://github.com/prebid/prebid-server/issues/857 --- .../endpoints/openrtb2/pbs-endpoint-auction.md | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/prebid-server/endpoints/openrtb2/pbs-endpoint-auction.md b/prebid-server/endpoints/openrtb2/pbs-endpoint-auction.md index a6904a80..ea68c7a9 100644 --- a/prebid-server/endpoints/openrtb2/pbs-endpoint-auction.md +++ b/prebid-server/endpoints/openrtb2/pbs-endpoint-auction.md @@ -375,6 +375,7 @@ to set these params on the response at `response.seatbid[i].bid[j].ext.prebid.ta | mediatypepricegranularity | no | Defines how PBS quantizes bid prices into buckets, allowing for different ranges by media type. | (see below) | object | | mediatypepricegranularity.banner | no | Defines how PBS quantizes bid prices into buckets for banners. | (see below) | object | | mediatypepricegranularity.video | no | Defines how PBS quantizes bid prices into buckets for video. | (see below) | object | +| mediatypepricegranularity.native | no | Defines how PBS quantizes bid prices into buckets for native. | (see below) | object | | mediatypepricegranularity.TYPE.precision | no | How many decimal places are there in price buckets. | Defaults to 2 | integer | | mediatypepricegranularity.TYPE.ranges | no | Same as pricegranularity.ranges | (see below) | array of objects | | includewinners | no | Whether to include targeting for the winning bids in response.seatbid[].bid[]. ext.prebid.targeting. Defaults to false. | true | boolean | @@ -416,19 +417,20 @@ One of "includewinners" or "includebidderkeys" must be true (both default to fal The parameter "includeformat" indicates the type of the bid (banner, video, etc) for multiformat requests. It will add the key `hb_format` and/or `hb_format_{bidderName}` as per "includewinners" and "includebidderkeys" above. -MediaType PriceGranularity (PBS-Java only) - when a single OpenRTB request contains multiple impressions with different mediatypes, or a single impression supports multiple formats, the different mediatypes may need different price granularities. If `mediatypepricegranularity` is present, `pricegranularity` would only be used for any mediatypes not specified. +MediaType PriceGranularity - when a single OpenRTB request contains multiple impressions with different mediatypes, or a single impression supports multiple formats, the different mediatypes may need different price granularities. If `mediatypepricegranularity` is present, `pricegranularity` would only be used for any mediatypes not specified. +For example: ``` { "ext": { "prebid": { "targeting": { - "mediatypepricegranularity": { - "banner": { - "ranges": [ + "pricegranularity": { // use this for banner and native + "ranges": [ {"max": 20, "increment": 0.5} ] - }, + }, + "mediatypepricegranularity": { // video gets a different set of ranges "video": { "ranges": [ {"max": 10, "increment": 1}, @@ -468,7 +470,8 @@ MediaType PriceGranularity (PBS-Java only) - when a single OpenRTB request conta The winning bid for each `request.imp[i]` will also contain `hb_bidder`, `hb_size`, and `hb_pb` (with _no_ {bidderName} suffix). To prevent these keys, set `request.ext.prebid.targeting.includeWinners` to false. -**NOTE**: Targeting keys are limited to 20 characters. If {bidderName} is too long, the returned key +**NOTES**: +- Targeting keys are limited to 20 characters. If {bidderName} is too long, the returned key will be truncated to only include the first 20 characters. ##### Buyer UID From 9bf44d0e478a2bc158deacf9b0b8fa6da04fa01f Mon Sep 17 00:00:00 2001 From: congdu-kun <126609480+congdu-kun@users.noreply.github.com> Date: Wed, 3 May 2023 12:56:07 -0700 Subject: [PATCH 196/762] add documentation for PAIR ID userid submodule (#4462) * add documentation for PAIR ID userid submodule * Add liveramp storageKey parameter to Pair Id doc * Add a short blurb for PAIR * Add link to PAIR technical doc --- dev-docs/modules/userid-submodules/pair.md | 65 ++++++++++++++++++++++ 1 file changed, 65 insertions(+) create mode 100644 dev-docs/modules/userid-submodules/pair.md diff --git a/dev-docs/modules/userid-submodules/pair.md b/dev-docs/modules/userid-submodules/pair.md new file mode 100644 index 00000000..06715598 --- /dev/null +++ b/dev-docs/modules/userid-submodules/pair.md @@ -0,0 +1,65 @@ +--- +layout: userid +title: Google PAIR ID +description: pair PairId User ID sub-module +useridmodule: pairIdSystem +--- + +Developed by and for use with Display and Video 360, PAIR (Publisher Advertiser Identity Reconciliation) is a secure and privacy-forward way for enabling advertisers and publishers to reconcile their +first-party data for marketing use cases via advanced data encryption methods without the +reliance on third-party cookies. PAIR can help advertisers and publishers maintain control of first-party data while ensuring there is no pooling of data, no leakage of data, no leakage of insights, durablility for the future using secure encryption methods, and no user tracking across publishers. See this [document](https://services.google.com/fh/files/misc/pair_visual_final_10242022.pdf) for more information about PAIR. + +Add it to your Prebid.js package with: + +{: .alert.alert-info :} +gulp build --modules=pairIdSystem + +## PAIR ID Configuration + +{: .table .table-bordered .table-striped } +| Param under userSync.userIds[] | Scope | Type | Description | Example | +| --- | --- | --- | --- | --- | +| name | Required | String | The name of PAIR ID user ID module. | `"pairId"` | +| params | Optional | Object | Container of all module params. | | +| params.liveramp | Optional | Object | Container of all liveramp cleanroom specified params. | | +| params.liveramp.storageKey | Optional | String | storage key to fetch liveramp provided PAIR Id, the default key is `"_lr_pairId_"` | `"_lr_pairId_custom"` | + +## PAIR ID Examples + +Publishers manage PAIR Ids themselves can store pairIds as a byte64 encoded array of ids in local storage and/or 1st party cookies entry `pairId`. + +{% highlight javascript %} + +// should have byte64 value ready in 'pairId' local storage/cookie entry + +pbjs.setConfig({ + userSync: { + userIds: [{ + name: 'pairId' + }] + } +}); +{% endhighlight %} + +Or if to use cleanrooms provided implementation, it can be specified by adding the provider and their configs to the config, take liveramp as an example. + +{% highlight javascript %} + +// value in 'pairid' local storage/cookie entry will be combined with ids provided by cleamroom liveramp + +pbjs.setConfig({ + userSync: { + userIds: [{ + name: 'pairId', + params: { + liveramp: { + storageKey: '_lr_pairId_custom' + } + }, + }] + } +}); +{% endhighlight %} + + + From 81b10f9525d1332052e6621494123bdf4872b9ed Mon Sep 17 00:00:00 2001 From: bretg Date: Wed, 3 May 2023 16:10:12 -0400 Subject: [PATCH 197/762] mobile FAQ (#4530) * mobile FAQ * Update faq/prebid-mobile-faq.md Co-authored-by: Muki Seiler * adding new entries from Yurii --------- Co-authored-by: Muki Seiler --- _data/sidebar.yml | 16 ++++ faq/faq.md | 16 ++-- faq/prebid-mobile-faq.md | 174 +++++++++++++++++++++++++++++++++++++++ faq/prebid-server-faq.md | 6 +- 4 files changed, 205 insertions(+), 7 deletions(-) create mode 100644 faq/prebid-mobile-faq.md diff --git a/_data/sidebar.yml b/_data/sidebar.yml index 8129f229..7b85c62d 100644 --- a/_data/sidebar.yml +++ b/_data/sidebar.yml @@ -652,6 +652,14 @@ sectionTitle: subgroup: 0 +- sbSecId: 2 + title: Prebid Mobile FAQ + link: /faq/prebid-mobile-faq.html + isHeader: 0 + isSectionHeader: 0 + sectionTitle: + subgroup: 0 + # - sbSecId: 2 # title: Modules # link: @@ -1442,6 +1450,14 @@ sectionTitle: subgroup: 0 +- sbSecId: 5 + title: Prebid Server FAQ + link: /faq/prebid-server-faq.html + isHeader: 0 + isSectionHeader: 0 + sectionTitle: + subgroup: 0 + - sbSecId: 5 title: Versions link: diff --git a/faq/faq.md b/faq/faq.md index de57ee61..6a19bb86 100644 --- a/faq/faq.md +++ b/faq/faq.md @@ -10,19 +10,25 @@ sidebarType: 7 Everyone has questions. We have answers - at least to some of the most frequently asked questions. -## [Prebid.js](/dev-docs/faq.html) +## Prebid.js Check out the [Prebid.js FAQ](/dev-docs/faq.html). If you don't find what you need there, here are some additional resources: - [Troubleshooting](/troubleshooting/troubleshooting.html) - [About Prebid.js](/prebid/prebidjs.html) -- [Training Videos](/videos/index.html) -- [Resources](/support/index.html) +- [Support Resources](/support/index.html) -## [Prebid Server](/faq/prebid-server-faq.html) +## Prebid Server If you don't find answers to your questions in the [Prebid Server FAQ](/faq/prebid-server-faq.html), you can learn more here: - [Troubleshooting](/troubleshooting/troubleshooting.html) - [Prebid Server Overview](/prebid-server/overview/prebid-server-overview.html) -- [Resources](/support/index.html) +- [Support Resources](/support/index.html) + +## Prebid Mobile SDK + +Please see the [Prebid Mobile FAQ](/faq/prebid-mobile-faq.html). You can learn more at: + +- [Prebid Mobile home page](/prebid-mobile/prebid-mobile.html) +- [Support Resources](/support/index.html) diff --git a/faq/prebid-mobile-faq.md b/faq/prebid-mobile-faq.md new file mode 100644 index 00000000..d8ee30bb --- /dev/null +++ b/faq/prebid-mobile-faq.md @@ -0,0 +1,174 @@ +--- +layout: page_v2 +title: Prebid Mobile FAQ | Prebid +description: Prebid Mobile FAQ +sidebarType: 2 +--- + +# Prebid Mobile FAQ +{:.no_toc} + +This page has answers to some frequently asked questions about Prebid Mobile. If you don't find what you're looking for here, there are other ways to [get help](/support/index.html). + +* TOC +{:toc} + +## General + +### What size is the SDK? + +Compiled sizes: +- Android: 800 KB +- iOS: 3.2 Mb + +Note: these sizes will go down as several assets will be pulled out into a CDN over the coming months. + +### Does the SDK have UI components? If so, are they localized? + +The Prebid SDK has no localized UI components. + +Most probably you will use an integration approach that doesn’t utilize UI component at all, as they are used only with the Rendering API. + +### Is the SDK compressed using any compression tools? + +No. + +### Is the SDK encrypted or obfuscated in any way? + +No. + +## Dependencies + +### Does the SDK use third-party libraries? + +Just the Open Measurement SDK. + +### Does it have external dependencies? + +No. + +### Does it use open-source libraries? If so, which licences are used? + +No. The Prebid SDK is itself a library open sourced under the Apache 2 license. + +### Are there any back-end dependencies to this SDK? + +Yes - the app developer must have a [Prebid Server](/prebid-server/index.html) at their disposal. This is open source software that they may run themselves, or they may contract with a [Managed Service](https://prebid.org/product-suite/managed-services/). + +## Communication + +### Does the SDK make network requests and how often and how heavy? + +Yes. Its main job is to formulate requests to [Prebid Server](/prebid-server/endpoints/openrtb2/pbs-endpoint-auction.html) to obtain bids for ad units. + +The frequency of HTTPS network calls is up to the app developer. It depends on whether and how frequently ad units are refreshed. The payload size will depend on how many ad units are present in the app and what kind of consent strings are present. For one ad unit, the size should be under 2KB, with each ad unit adding a couple hundred bytes. + +## Maintenance + +### How often is the SDK updated? + +It varies, but on average, it's updated about once per month. + +The open source repos have a list of releases: +https://github.com/prebid/prebid-mobile-ios/releases +https://github.com/prebid/prebid-mobile-android/releases + +### How does one update the Prebid Mobile version? + +The best way is to integrate SDK via dependency managers - CocoaPods (iOS) and Maven (Android). You can specify the particular version or point the dependency manager to the latest SDK version. In the second case, the new version of SDK will be added to the app as soon as released. + +### If a bug is found in the SDK, what is the process for reporting it? + +Please open a github issue: + +https://github.com/prebid/prebid-mobile-ios/issues +https://github.com/prebid/prebid-mobile-android/issues + +### Is there a support forum where we can monitor issues and resolutions? + +Yes, you may monitor github issues and pull requests at the repositories noted above. + +### Are there debug/logging options that can be toggled on/off? +Yes. + +1. You can change app console log verbose level via PrebiMobile.shared.logLevel +2. You can set the OpenRtb 'test' flag for Prebid Server to return additional server-side information. See 'debug' in https://docs.prebid.org/prebid-mobile/pbm-api/android/code-integration-android.html and https://docs.prebid.org/prebid-mobile/pbm-api/ios/code-integration-ios.html + +## Privacy/Security + +### Does the SDK store any data locally on the device? If so, what is it? + +If the developer calls certain functions, the SDK will store the results for future auctions. See the "Local Storage" section of +https://docs.prebid.org/prebid-mobile/pbm-api/android/pbm-targeting-params-android.html + +In all other cases SDK plays a transport role. It collects information from API (if it’s allowed by privacy settings) and sends it in the bid requests to the server. SDK uses the following datasources: +- TCF API - SDK reads data from UserDefaults +- Configuration / Targeting API - publishers provide data to SDK in runtime +- Device API - SDK collects device info using public OS API, like user agent, OS version, location + +### Does the SDK send any Personal Information over the network? + +The Prebid SDK sends information provided by the publisher using the Targeting API. We recommend that publishers avoid targeting to personal information unless reviewed by their own legal teams. + +The SDK will send IP address and device latitude/longitude information. Prebid Server will anonymize requests as required by regulations, including GDPR, COPPA, CCPA. See the [Prebid Server privacy features](/prebid-server/features/pbs-privacy.html) for more details. + +### Is the SDK GDPR compliant? + +Yes - the SDK will forward TCF consent strings to Prebid Server where requests may be anonymized or restricted. It is up to the entity hosting Prebid Server to configure the server properly. + +Also note that Prebid.org is committed to other privacy initiatives such as the IAB's Global Privacy Platform, including US National Privacy and TCF-Canada. + +### How does the SDK allow for deletion of user private data? + +SDK does’t commit any action on managing user data. Only publishers using SDK’s API can provide/store/remove user data. + +## Performance + +### Does the SDK do any work in the background? If so, what is it? + +The SDK will receive responses from Prebid Server in the background and call the application-defined callbacks. + +The developer may set up auto-refresh for ad units. If in the background, Prebid SDK will not perform bid requests. + +### Has power usage related to this SDK been tested? + +No. We'd welcome any community member to help us with requirements, code, and/or results. + +### How long does it take to initialize? +Is not measured, but very fast. Because it makes only initialization of internal classes and optional health check calls to PBS. The result of the health check call does not influence the SDK behavior, so publishers may not wait for its result during the initialization. + +## API Questions + +### What is the difference between Original API and Rendering API? + +The main difference is that with Original API, the Prebid demand is rendered by the Ad Server SDK (Google Mobile Ads SDK) using Prebid Universal Creative. But with Rendering API, Prebid SDK renders the winning bid in its own Web or Video views. + +## iOS Specifics + +### Does the SDK support Swift 3+? + +Yes. Prebid SDK is developed with latest Xcode version. + +### Does it ship as a CocoaPod? + +Yes - https://cocoapods.org/pods/PrebidMobile + +### Is it bit code enabled? + +Starting with 2.1.0: No + +### Does it support 64-bit? +Yes. + +## Android Specifics + +### What are the targeted APIs? + +Android API 32. + +### Does it include Broadcast Receivers in the Manifest? + +No. + +## Further Reading +- [Prebid Mobile home page](/prebid-mobile/prebid-mobile.html) diff --git a/faq/prebid-server-faq.md b/faq/prebid-server-faq.md index 827f51f1..9a58f8d7 100644 --- a/faq/prebid-server-faq.md +++ b/faq/prebid-server-faq.md @@ -26,8 +26,10 @@ but it's not necessary for contributing code as a community member. ## How can I debug Prebid Server requests? + When invoking Prebid Server through Prebid.js, this can be done just by adding `?pbjs_debug=true` to the page URL. -+ Through AMP, you can put `test: 1` in the stored request, or add `debug=1` to the query string of Prebid Server's AMP endpoint. -+ If calling directly, add `test: 1` to the JSON. ++ Through AMP, you can put `ext.prebid.debug: true` in the stored request, or add `debug=1` to the query string of Prebid Server's AMP endpoint. ++ If calling directly, add `ext.prebid.debug: true` to the JSON. + +The OpenRTB `test:1` flag will also turn on debugging, and for true test requests, is the most appropriate thing to do, depending on your scenario. SSPs may not respond or log `test` requests. ## Why are there two versions of Prebid Server? Are they kept in sync? From bcf152a64652a36ab0f0382b85cafa49bdbe2417 Mon Sep 17 00:00:00 2001 From: Muki Seiler Date: Thu, 4 May 2023 21:41:30 +0200 Subject: [PATCH 198/762] Fix #4539 by allowing GA if consent is already given (#4540) --- _includes/footer.html | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/_includes/footer.html b/_includes/footer.html index 79da5595..c4b6cdae 100644 --- a/_includes/footer.html +++ b/_includes/footer.html @@ -26,15 +26,21 @@ anonymize_ip: true }); - // new google analytics v4 property - gtag('config', 'G-GM972HCTEB'); - - // use the global variable provided in the head-common to wait for onetrust - window.onetrustLoaded.then(() => { - // grant consent if one trust says so. We use the callback to update gtag consent status + // grant consent if one trust says so. We use the callback to update gtag consent status + function oneTrustGaConsent() { OneTrust.InsertHtml('given', 'prebid-google-analytics-consent', function() { gtag('consent', 'update', {'ad_storage': 'granted','analytics_storage': 'granted'}); }, {}, 'C0002'); + } + + + // use the global variable provided in the head-common to wait for onetrust + window.onetrustLoaded.then(() => { + // if consent has already been given + oneTrustGaConsent(); + + // if a users sees the first layer message and gives consent + OneTrust.OnConsentChanged(() => oneTrustGaConsent()); }); From 344217b52664d8903f2dcd2b067c80b6655b092b Mon Sep 17 00:00:00 2001 From: Jean-Baptiste Date: Fri, 5 May 2023 17:55:38 +0200 Subject: [PATCH 199/762] greenbids RTD provider (#4517) * greenbids RTD provider * update doc * code formatting Co-authored-by: Muki Seiler * Code formatting Co-authored-by: Muki Seiler --------- Co-authored-by: Muki Seiler --- dev-docs/modules/greenbidsRtdProvider.md | 72 ++++++++++++++++++++++++ 1 file changed, 72 insertions(+) create mode 100644 dev-docs/modules/greenbidsRtdProvider.md diff --git a/dev-docs/modules/greenbidsRtdProvider.md b/dev-docs/modules/greenbidsRtdProvider.md new file mode 100644 index 00000000..a30eb510 --- /dev/null +++ b/dev-docs/modules/greenbidsRtdProvider.md @@ -0,0 +1,72 @@ +--- +layout: page_v2 +title: Greenbids Realtime Module +display_name: Greenbids Realtime Module +description: The Greenbids RTD adapter allows to dynamically filter calls to SSP to reduce outgoing call to the programmatics chain, reducing ad serving carbon impact +page_type: module +module_type: rtd +module_code : greenbidsRtdProvider +enable_download : true +vendor_specific: true +sidebarType : 1 +--- + +# Greenbids Realtime Module +{:.no_toc} + +* TOC +{:toc} + +## Overview + +The Greenbids RTD adapter allows to dynamically filter calls to SSP to reduce outgoing call to the programmatics chain, reducing ad serving carbon impact + +## Configuration + +This module is configured as part of the `realTimeData.dataProviders` object. + +{: .table .table-bordered .table-striped } +| Name | Scope | Description | Example | Type | +|------------|----------|----------------------------------------|---------------|----------| +| `name ` | required | Real time data module name | `'greenbidsRtdProvider'` | `string` | +| `waitForIt ` | required (mandatory true value) | Tells prebid auction to wait for the result of this module | `'true'` | `boolean` | +| `params` | required | | | `Object` | +| `params.pbuid` | required | The client site id provided by Greenbids. | `'TEST_FROM_GREENBIDS'` | `string` | +| `params.targetTPR` | optional (default 0.95) | Target True positive rate for the throttling model | `0.99` | `[0-1]` | +| `params.timeout` | optional (default 200) | Maximum amount of milliseconds allowed for module to finish working (has to be <= to the realTimeData.auctionDelay property) | `200` | `number` | + +#### Example + +```javascript +const greenbidsDataProvider = { + name: 'greenbidsRtdProvider', + waitForIt: true, + params: { + pbuid: 'TEST_FROM_GREENBIDS', + timeout: 200 + } +}; +pbjs.setConfig({ + realTimeData: { + auctionDelay: 200, + dataProviders: [greenbidsDataProvider] + } +}); +``` + +## Integration +To install the module, follow these instructions: + +#### Step 1: Contact Greenbids to get a pbuid and account + +#### Step 2: Integrate the Greenbids Analytics Adapter (see prebid Analytics modules) + +#### Step 3: Prepare the base Prebid file + +- Option 1: Use Prebid [Download](/download.html) page to build the prebid package. Ensure that you do check *Greenbids Realtime Module* module + +- Option 2: From the command line, run `gulp build --modules=greenbidsRtdProvider,...` + +#### Step 4: Set configuration + +Enable Greenbids Real Time Module using `pbjs.setConfig`. Example is provided in Configuration section. \ No newline at end of file From 1d546d7418c5a4c1e49d1f07b02aa4e7a4ea3a2a Mon Sep 17 00:00:00 2001 From: bretg Date: Fri, 5 May 2023 17:17:04 -0400 Subject: [PATCH 200/762] first batch of intro videos (#4516) * initial control of intro videos * adding next two videos * missing paren * fixed link * added Prebid Server * padding * updated CSS --- _layouts/home.html | 3 +- overview/all-videos.md | 16 +++++ overview/intro-to-header-bidding-video.md | 70 +++++++++++++++++++ overview/intro-to-header-bidding.md | 10 +++ overview/intro-video.md | 50 +++++++++++++ overview/intro.md | 17 +++++ prebid-mobile/prebid-mobile-video.md | 46 ++++++++++++ prebid-mobile/prebid-mobile.md | 10 +++ .../overview/prebid-server-overview-video.md | 65 +++++++++++++++++ .../overview/prebid-server-overview.md | 9 +++ prebid/prebidjs-video.md | 54 ++++++++++++++ prebid/prebidjs.md | 12 ++++ 12 files changed, 361 insertions(+), 1 deletion(-) create mode 100644 overview/all-videos.md create mode 100644 overview/intro-to-header-bidding-video.md create mode 100644 overview/intro-video.md create mode 100644 prebid-mobile/prebid-mobile-video.md create mode 100644 prebid-server/overview/prebid-server-overview-video.md create mode 100644 prebid/prebidjs-video.md diff --git a/_layouts/home.html b/_layouts/home.html index 4738f798..fec6c2de 100644 --- a/_layouts/home.html +++ b/_layouts/home.html @@ -9,7 +9,8 @@

Prebid Documentation

-

Welcome to the Prebid.org technical documentation portal. Here you will find the help you need to work with the Prebid.org family of products. Visit Prebid.org for general product overviews, blog updates, and additional information on membership and events. If you're wondering what Header Bidding is all about, check out our Introduction to Header Bidding

+

Welcome to the Prebid.org technical documentation portal. Here you will find the help you need to work with the Prebid.org family of Header Bidding products. You could start with the video introduction to Prebid or visit Prebid.org for general product overviews, blog updates, and additional information on membership and events. If you're wondering what Header Bidding is all about, check out our Introduction to Header Bidding

. +
diff --git a/overview/all-videos.md b/overview/all-videos.md new file mode 100644 index 00000000..2d299d32 --- /dev/null +++ b/overview/all-videos.md @@ -0,0 +1,16 @@ +--- +layout: page_v2 +title: All Prebid Training Video +description: Directory of Prebid Video Overviews +sidebarType: 0 +--- + +# Video Overviews + +These are the multi-media overviews that Prebid has created covering various aspect of Header Bidding and Prebid. + +1. [Intro to Header Bidding](/overview/intro-to-header-bidding-video.html) - A high-level explanation of what header bidding is, what its benefits are, and how it works. +2. [Intro to Prebid](/overview/intro-video.html) - A high-level introduction to the Prebid community and its products. +3. [Intro to Prebid.js](/prebid/prebidjs-video.html) - A high-level overview of Prebid.js, Prebid’s header bidding product for websites. +4. [Intro to Prebid Mobile](/prebid-mobile/prebid-mobile-video.html) - A high-level overview of Prebid Mobile, Prebid’s header bidding product for iOS and Android applications. +4. [Intro to Prebid Server](/prebid-server/overview/prebid-server-overview-video.html) - A high-level overview of Prebid Server, Prebid’s solution for header bidding in the cloud. diff --git a/overview/intro-to-header-bidding-video.md b/overview/intro-to-header-bidding-video.md new file mode 100644 index 00000000..9a278ae9 --- /dev/null +++ b/overview/intro-to-header-bidding-video.md @@ -0,0 +1,70 @@ +--- +layout: page_v2 +title: Video Intro to Header Bidding +description: A video overview of Header Bidding +sidebarType: 0 +--- + +# A Video Introduction to Header Bidding + +A high-level explanation of what header bidding is, what its benefits are, and how it works. + +
+ +Further Content: +- [Intro to Header Bidding](/overview/intro-to-header-bidding.html) +- [Header Bidding with Prebid](/overview/intro.html#header-bidding-with-prebid) +- [All videos](/overview/all-videos.html) + +Related Videos: +- [Introduction to Prebid](/overview/intro-video.html) +- [Introduction to Prebid.js](/prebid/prebidjs-video.html) + +## Transcript + +Header bidding is a technology used by website publishers and app developers to sell advertising opportunities through programmatic advertising marketplaces. It uses real-time auctions to maximize the value of ads online. + +### Yield Management Problem +To understand why header bidding is important, let's explore the problem it aims to solve. Publishers and app developers earn money through advertising, and they want to maximize the revenue they earn from a finite amount of traffic. This challenge is similar to a farmer working to maximize the amount of vegetables their land yields, or an airline maximizing the airfare they earn for seats on flights. This problem is called yield management or yield optimization. + +To maximize yield, a seller will need to form relationships with a selection of buyers that are able to buy advertising impressions at good prices. They’ll also set up an advertising technology stack that gives their buyers the opportunity to compete for each and every ad impression. The ad stack is also responsible for rendering the ads and offers the seller controls that influence pricing, ad quality, and user experience. Analytics, A/B testing, and other optimization tools help the seller grow their yield over time. + +In digital media, there are two prominent techniques for managing yield: the waterfall and header bidding. + +### Before Header Bidding: The Waterfall +The waterfall predates header bidding, and header bidding was developed to overcome shortcomings in the waterfall’s ability to maximize yield. + +Let’s break this down: + +In a waterfall, the seller creates a prioritized ranking of their buyer partners. Each time an impression is available for sale, the top partner in the ranking is shown the opportunity and has the option to buy it or refuse it. If they choose to buy, they deliver their ad. If they refuse, the waterfall shows the impression to the next partner in the ranking, and the cycle repeats until a willing buyer is found. + +The waterfall’s design limits publishers’ ability to maximize yield, because it doesn’t expose impression opportunities to all of the potential buyers and can’t find the best price for each impression. Its sequential nature also makes it a slow process, which causes some impressions to go unsold. + +### Header Bidding: A Better Solution to the Yield Management Problem +Header bidding overcomes many of the waterfall’s limitations using a simple, time-tested mechanism: auctions. + +Auctions allow all potential buyers to see the impression simultaneously and compete for it by bidding. This ensures that the impression is sold for a fair price and delivers the ad quickly and efficiently. + +Publishers and app developers find that header bidding allows them to work with more buyers than the waterfall does. Header bidding also allows buyers to find their target audiences more easily and deliver more effective advertising campaigns + +### How Header Bidding Works +Let’s get into how header bidding works: + +For most sellers, header bidding is one component of an advertising technology stack. The header bidding component is known as the “header bidding wrapper”, and it works in close coordination with the seller’s primary ad server. + +When a web page or app loads, the header bidding wrapper also loads. The wrapper initiates an auction for the available ad spaces on the page, and sends bid requests to potential buyers, notifying them that an impression is available for sale. + +In a fraction of a second, the buyers respond with bids containing the ad they want to serve, the price they're willing to pay, and other relevant information. The header bidding wrapper then collects and passes these bids to the primary ad server. + +The ad server considers the header bidding bids alongside other potential buyers and decides which buyer wins. Within the ad server, header bidding bids compete based on price and do not interfere with the delivery of reserved, guaranteed and sponsorship campaigns. When the ad server chooses a header bidding buyer, it works with the wrapper to render the ad to the page. + +### Header Bidding and Prebid +Header bidding began to appear in 2015, and has since replaced the waterfall on most websites. In mobile app environments, header bidding is quickly gaining popularity. Prebid.org formed to help publishers and advertising technology companies coordinate their efforts around header bidding, and Prebid is now the industry standard. Prebid is a non-profit member-based organization that offers open-source solutions for header bidding for all major ad formats, device types, and environments. + +### Learn More +If you want to learn more about header bidding and Prebid, visit docs.prebid.org. + + +## Related Reading +- [Intro to Header Bidding](/overview/intro-to-header-bidding.html) +- [All video overviews](/overview/all-videos.html) diff --git a/overview/intro-to-header-bidding.md b/overview/intro-to-header-bidding.md index fc03f918..f1237a94 100644 --- a/overview/intro-to-header-bidding.md +++ b/overview/intro-to-header-bidding.md @@ -18,6 +18,16 @@ Let’s start by saying that the term “header bidding” is a bit of a misnome * TOC {:toc} +## Overview + +A video overview of header bidding. + +
+ +Further Reading: +- [Transcript of this video overview](/overview/intro-to-header-bidding-video.html) +- [Header Bidding with Prebid](/overview/intro.html#header-bidding-with-prebid) + ## Brief Description Header bidding is a process that enables publishers to capture bids for ad units from demand sources that might otherwise have been missed. By implementing header bidding, a publisher can gather bids from multiple sources that will then compete directly with bids from the ad server. What this means is that header bidding can help you, as a publisher, make more money and improve your ad quality by making the auctions for your ad space more competitive and transparent. diff --git a/overview/intro-video.md b/overview/intro-video.md new file mode 100644 index 00000000..df04a354 --- /dev/null +++ b/overview/intro-video.md @@ -0,0 +1,50 @@ +--- +layout: page_v2 +title: Video Intro to Prebid.org +description: A video overview of Prebid org and products +sidebarType: 0 +--- + +# A Video Overview of Prebid.org + +A high-level introduction to the Prebid community and its products. + +
+ +Further Content: +- [Intro to Prebid](/overview/intro.html) +- [Introduction for Developers](/developers.html) +- [Prebid Membership](https://prebid.org/membership) +- [Prebid on Github](https://github.com/prebid) +- [All videos](/overview/all-videos.html) + +Related Videos: +- [Introduction to Header Bidding](/overview/intro-to-header-bidding-video.html) +- [Introduction to Prebid.js](/prebid/prebidjs-video.html) +- [Introduction to Prebid Mobile](/prebid-mobile/prebid-mobile-video.html) +- Introduction to Prebid Server (coming soon) + +## Transcript + +Prebid is a non-profit organization, a JavaScript library, and a suite of products that extend the capabilities of the publisher ad stack. + +Prebid is a member-based organization made up of companies in the digital publishing and advertising technology industries. These companies work together through Prebid.org to build free, open source software that monetizes digital media through advertising. + +### Why Prebid? +Prebid addresses the need for reliable shared technology in programmatic advertising. Serving a single ad is a complex and tightly choreographed routine that requires the cooperation of many entities. This process takes just a few seconds and occurs several billion times per day, accounting for billions of dollars per year in advertising spend. + +With such high stakes, the digital media industry needs standards that are accessible, transparent, and fair. Prebid establishes the foundation for sellers, buyers, and vendors to work together effectively to create high quality digital media supply chains and maximize the value of publishers’ content. + +### A Brief History of Prebid +The birth of Prebid can be traced back to Prebid.js, an open-source JavaScript library that provided a simple and reliable way to implement header bidding on websites. Header bidding is technology that connects websites to programmatic advertising marketplaces. In the early days of header bidding, these integrations were complicated and opaque. This made it difficult for publishers to maximize the value of their content and difficult for advertisers to buy advertising space efficiently and transparently. + +Prebid.js addressed these problems by creating a standardized, transparent platform for header bidding. Following the rapid adoption of Prebid.js, Prebid.org was formed to oversee the development of Prebid technology and create new products. + +### Prebid’s Products +Today, Prebid has three product areas: Prebid.js, Prebid Mobile, and Prebid Server. Prebid.js is a client-side header bidding wrapper for websites, while Prebid Mobile enables header bidding in iOS and Android applications. Prebid Server makes it possible to run header bidding auctions in the cloud for monetizing websites, apps, long form video streams, digital out-of-home, and other forms of media. + +### Prebid.org +Prebid Org has a Board of Directors representing its publisher, buyer, and technology provider members. The Board steers Prebid, upholding its principles and setting its goals. Within Prebid.org, there are also several Project Management Committees, each of which drives the development of a specific Product area. The Committees are made up of people who work for Prebid’s member companies. Prebid also has a small full-time staff that does software development, community development, and administration. The Prebid community also includes companies who offer proprietary products and services that extend Prebid’s capabilities and provide enterprise support. + +### Learn More +To learn more about Prebid, visit prebid.org. To get started using Prebid, visit docs.prebid.org. To learn about becoming a Prebid Member, visit prebid.org/membership. To contribute to the software, visit Prebid's Github repository at github.com/prebid. diff --git a/overview/intro.md b/overview/intro.md index 5b54f572..7189697d 100644 --- a/overview/intro.md +++ b/overview/intro.md @@ -16,6 +16,18 @@ Prebid is the leading header bidding solution. It is free and fully open source, {: .alert.alert-info :} If you’re looking for a marketing-level overview of the Prebid software and organization, including product features, membership, events, and so on, visit [Prebid.org](https://prebid.org/). +## Overview + +A video overview of Prebid. + +
+ +Further Reading: +- [Transcript of this video overview](/overview/intro-video.html) +- [Introduction for Developers](/developers.html) +- [Prebid Membership](https://prebid.org/membership) +- [Prebid on Github](https://github.com/prebid) + ## Header Bidding with Prebid The Prebid.org suite of products leads the industry in providing header bidding to publishers. @@ -174,3 +186,8 @@ Prebid also has an active member community that ensures Prebid will continue to The ad server you’re working with makes their money by taking a cut of the winning bid price, so you might be wondering if Prebid also takes a cut. The answer is NO. Prebid is free to anyone who wants to use it. So how does Prebid continue to evolve as a quality set of products (not to mention provide events and great documentation) without taking in fees? Through dedicated volunteers from member companies, alongside a small handful of employees and an occasional contractor paid through Prebid.org membership dues. All dues go into serving the Prebid community and providing a voice for our members in the world of header bidding. You don’t have to be a Prebid.org member to use Prebid. However, we do highly encourage you to explore the benefits of membership and consider joining. No matter the size of your company, Prebid has membership options available that will provide value to anyone interested in header bidding today and in the future. For more information on Prebid.org membership, see [Prebid.org Membership Overview](https://prebid.org/membership/). + +## Related Reading +- [Introduction to Header Bidding](/overview/intro-to-header-bidding-video.html) +- [Prebid Product Suite](https://prebid.org/product-suite/) +- [What is Prebid.js](/prebid/prebidjs.html) diff --git a/prebid-mobile/prebid-mobile-video.md b/prebid-mobile/prebid-mobile-video.md new file mode 100644 index 00000000..098d4f84 --- /dev/null +++ b/prebid-mobile/prebid-mobile-video.md @@ -0,0 +1,46 @@ +--- +layout: page_v2 +title: Video Intro to Prebid Mobile +description: A video overview of Prebid Mobile SDK +sidebarType: 0 +--- + +# A Video Overview of Prebid Mobile + +A high-level overview of Prebid Mobile, Prebid’s header bidding product for iOS and Android applications. + +
+ +Further Content: +- [Intro to Prebid](/overview/intro.html) +- [Prebid Managed Services](https://prebid.org/product-suite/managed-services/) +- [All videos](/overview/all-videos.html) + +Related Videos: +- [Introduction to Header Bidding](/overview/intro-to-header-bidding-video.html) +- Introduction to Prebid Server (coming soon) + +## Transcript + +Prebid is a non-profit organization, a JavaScript library, and a suite of products that extend the capabilities of the publisher ad stack. + +Prebid is a member-based organization made up of companies in the digital publishing and advertising technology industries. These companies work together through Prebid.org to build free, open source software that monetizes digital media through advertising. + +### Why Prebid? +Prebid addresses the need for reliable shared technology in programmatic advertising. Serving a single ad is a complex and tightly choreographed routine that requires the cooperation of many entities. This process takes just a few seconds and occurs several billion times per day, accounting for billions of dollars per year in advertising spend. + +With such high stakes, the digital media industry needs standards that are accessible, transparent, and fair. Prebid establishes the foundation for sellers, buyers, and vendors to work together effectively to create high quality digital media supply chains and maximize the value of publishers’ content. + +### A Brief History of Prebid +The birth of Prebid can be traced back to Prebid.js, an open-source JavaScript library that provided a simple and reliable way to implement header bidding on websites. Header bidding is technology that connects websites to programmatic advertising marketplaces. In the early days of header bidding, these integrations were complicated and opaque. This made it difficult for publishers to maximize the value of their content and difficult for advertisers to buy advertising space efficiently and transparently. + +Prebid.js addressed these problems by creating a standardized, transparent platform for header bidding. Following the rapid adoption of Prebid.js, Prebid.org was formed to oversee the development of Prebid technology and create new products. + +### Prebid’s Products +Today, Prebid has three product areas: Prebid.js, Prebid Mobile, and Prebid Server. Prebid.js is a client-side header bidding wrapper for websites, while Prebid Mobile enables header bidding in iOS and Android applications. Prebid Server makes it possible to run header bidding auctions in the cloud for monetizing websites, apps, long form video streams, digital out-of-home, and other forms of media. + +### Prebid.org +Prebid Org has a Board of Directors representing its publisher, buyer, and technology provider members. The Board steers Prebid, upholding its principles and setting its goals. Within Prebid.org, there are also several Project Management Committees, each of which drives the development of a specific Product area. The Committees are made up of people who work for Prebid’s member companies. Prebid also has a small full-time staff that does software development, community development, and administration. The Prebid community also includes companies who offer proprietary products and services that extend Prebid’s capabilities and provide enterprise support. + +### Learn More +To learn more about Prebid, visit prebid.org. To get started using Prebid, visit docs.prebid.org. To learn about becoming a Prebid Member, visit prebid.org/membership. To contribute to the software, visit Prebid's Github repository at github.com/prebid. diff --git a/prebid-mobile/prebid-mobile.md b/prebid-mobile/prebid-mobile.md index 4ee540ef..a8f2833e 100644 --- a/prebid-mobile/prebid-mobile.md +++ b/prebid-mobile/prebid-mobile.md @@ -17,6 +17,16 @@ Prebid Mobile libraries are available for iOS and Android. * TOC {:toc} +## Video Overview of Prebid Mobile + +A high-level overview of Prebid Mobile, Prebid’s header bidding product for iOS and Android applications. + +
+ +Further Content: +- [Transcript of this video](/prebid-mobile/prebid-mobile-video.html) +- [Prebid Managed Services](https://prebid.org/product-suite/managed-services/) + ## Benefits and Features Prebid SDK rendering offers the following benefits: diff --git a/prebid-server/overview/prebid-server-overview-video.md b/prebid-server/overview/prebid-server-overview-video.md new file mode 100644 index 00000000..6af75d18 --- /dev/null +++ b/prebid-server/overview/prebid-server-overview-video.md @@ -0,0 +1,65 @@ +--- +layout: page_v2 +title: Video Intro to Prebid Server +description: A video overview of Prebid Server +sidebarType: 5 +--- + +# A Video Overview of Server + +A high-level overview of Prebid Server, Prebid’s solution for header bidding in the cloud. + +
+ +Further Content: +- [Intro to Prebid](/overview/intro.html) +- [Prebid Server Overview](/prebid-server/overview/prebid-server.html) +- [Prebid Membership](https://prebid.org/membership) +- [Prebid on Github](https://github.com/prebid) +- [All videos](/overview/all-videos.html) + +Related Videos: +- [Introduction to Header Bidding](/overview/intro-to-header-bidding-video.html) +- [Introduction to Prebid Mobile](/prebid-mobile/prebid-mobile-video.html) + +## Transcript + +### About Prebid Server + +Prebid Server is a solution for running real-time advertising auctions in the cloud. + +It works in conjunction with Prebid.js, Prebid SDK, and other technologies to make header bidding possible for any ad format in any type of digital media. + +Prebid Server has everything necessary to sell advertising opportunities through server-side header bidding, including bidder integrations, privacy controls, creative caching, currency conversion, price floors, and analytics. + +It supports more than 150 demand sources, including many of the world’s largest exchanges, DSPs, ad networks, and agencies. + +### Why Prebid Server? + +Prebid Server brings the revenue-maximizing power of header bidding to environments that don’t support standard JavaScript. + +Header bidding originated as a JavaScript technology for websites, and the leading solution for header bidding in standard browser-based environments is Prebid.js. Prebid.js is very popular, but it only works on normal websites. Mobile apps, AMP websites, long-form video, and digital out-of-home need their own solution for header bidding, and that’s what Prebid Server provides. + +Prebid Server can also be used to augment Prebid.js on websites. Prebid Server can be a powerful tool in yield management strategies that aim to maximize both advertising revenue and user experience. + +### How Prebid Server Works +Prebid Server is open-source code that is free to use. To use it, you’ll need to set up a server to host the solution. You can set up your own servers, or use one of the managed services offered by companies in the Prebid community. + +Let’s walk through an example of Prebid Server in use. + +A digital advertising seller sets Prebid Server up on a server. + +Prebid Server receives ad requests from a personal computer, a mobile device, or another server. + +Prebid Server is able to enrich ad requests it receives, which means that it adds additional contextual information like IP-based location. It’s also able to interpret user consent and take actions such as restricting auction functions or limiting the sharing of personal data. + +Next, Prebid Server runs the auction. It sends bid requests to bidders, who respond with bids. Prebid Server validates each of the bids, checking for things like privacy compliance and adherence to price floors. It then finalizes the auction and transmits the results to the system that sent it the initial ad request. + +The seller who uses and hosts Prebid Server configures it to work how they want it to. Settings like privacy and consent controls, price floors, auction controls, the selection of bidders, and ad request enrichment functions are all determined by configurations that the seller sets. + +### Getting Started +To learn more about Prebid Server, including information about setting up your own hosting server, visit docs.prebid.org. + +To learn more about Prebid community companies that offer hosting services, visit prebid.org. + +If you are a developer who would like to see the source code or contribute to Prebid Server, visit Prebid on Github at github.com/prebid/. diff --git a/prebid-server/overview/prebid-server-overview.md b/prebid-server/overview/prebid-server-overview.md index 9b10da72..d5f0419b 100644 --- a/prebid-server/overview/prebid-server-overview.md +++ b/prebid-server/overview/prebid-server-overview.md @@ -30,6 +30,15 @@ The Prebid Cache is an adjunct to Prebid Server that stores VAST and bids as nee Explore [Prebid Server features](/prebid-server/features/pbs-feature-idx.html) in more detail. +## Video Introduction + +A high-level overview of Prebid Server, Prebid’s solution for header bidding in the cloud. + +
+ +Further Reading: +- [Transcript of this video overview](/prebid-server/overview/prebid-server-overview-video.html) + ## Where to Run Prebid Server Unlike Prebid.js, Prebid Server is a server. It needs somewhere to run, and that somewhere ought to be scaleable, distributed, and fast. diff --git a/prebid/prebidjs-video.md b/prebid/prebidjs-video.md new file mode 100644 index 00000000..f1f72226 --- /dev/null +++ b/prebid/prebidjs-video.md @@ -0,0 +1,54 @@ +--- +layout: page_v2 +title: Video Intro to Prebid.js +description: A video overview of Prebid org and products +sidebarType: 0 +--- + +# A Video Overview of Prebid.js + +A high-level overview of Prebid.js, Prebid’s header bidding product for websites. + +
+ +Further Content: +- [Intro to Header Bidding](/overview/intro-to-header-bidding.html) +- [Header Bidding with Prebid](/overview/intro.html#header-bidding-with-prebid) +- [What is Prebid.js?](/prebid/prebidjs.html) +- [Prebid.js Developer Quick Start](/dev-docs/getting-started.html) +- [All videos](/overview/all-videos.html) + +Related Videos +- [Introduction to Prebid](/overview/intro-video.html) +- [Introduction to Header Bidding](/overview/intro-to-header-bidding-video.html) +- Prebid.js Impression Flow (coming soon) +- Components of Prebid.js (coming soon) +- Identity in Prebid.js (coming soon) + +## Transcript + +### Introduction +Prebid js is a powerful, open-source header bidding wrapper that allows publishers to monetize their websites by running an auction for any ad on any page. + +It’s the industry standard in header bidding. It’s used by tens of thousands of websites and supports more than 200 demand sources. + +### Features and Capabilities +Prebid.js allows a publisher to set up a detailed map of their advertising inventory across one or many websites. It allows them to select which demand partners should compete to bid on each ad slot and provides a robust set of controls over ad slots, auction dynamics, and page performance. There is also a set of optional add-ons for analytics, ad request enrichment, identity and privacy control, price floors, and more. These tools allow publishers to maximize revenue while preserving user experience and privacy. Prebid.js is flexible and modular, allowing it to integrate cleanly into any ad stack. + +### What makes Prebid.js different +What distinguishes Prebid.js from other header bidding solutions is its robust set of features, its extensive adoption among sellers and buyers of digital advertising, and its principles of transparency, fairness, and open-source. Prebid.js is built by the community that uses it. As an open platform, Prebid.js also lays the foundation for an innovative ecosystem in which independent companies offer Prebid-compatible products and services. +### How Prebid.js is Made +Prebid.js is built collaboratively by Prebid member companies and Prebid.org.. This team works together under the oversight of the Prebid.js Product Management Committee, which is the group within Prebid.org that is responsible for developing Prebid.js. The Product Management Committee maintains Prebid.js’ roadmap and coordinates the software’s development. + +### How Prebid.js Works +When a publisher uses Prebid.js, they create a wrapper. The wrapper includes Prebid’s core auction and ad serving functions, as well as add-ons that the publisher uses to customize the wrapper to their needs. The publisher chooses a list of buyers, which Prebid calls bidders. For each bidder, the publisher adds a specific block of code called a bid adapter to their wrapper. Each bidder develops its own bid adapter and contributes it to the Prebid library. + +Let’s run through an example Prebid auction: + +Prebid.js is installed to the website. Each time a new impression opportunity becomes available, Prebid.js notifies the bidders, who respond with bids. Then, Prebid might select an auction winner and render its ad to the page, but more commonly, it will pass the bid information on to the ad server, which makes a final decision about which ad source should be awarded the impression. Within the ad server, header bidding bids compete based on price, and do not compete with the delivery of reserved, guaranteed, and sponsorship campaigns. When the ad server chooses a header bidding buyer, it works with the wrapper to render the ad to the page. + +### Getting Started +Prebid.js is free to use. You can get started with your own installation of the latest version of Prebid by visiting docs.prebid.org. + +There are also several companies that offer Prebid.js managed services, which may include technical support, ad operations and yield optimization services, hosting services, and extra product features like user interfaces or analytics. To learn more about these, visit prebid.org. + diff --git a/prebid/prebidjs.md b/prebid/prebidjs.md index 5433f70a..b0916743 100644 --- a/prebid/prebidjs.md +++ b/prebid/prebidjs.md @@ -11,6 +11,18 @@ sidebarType: 1 Prebid.js is a feature-rich header bidding platform for the web, including more than 300 demand sources and 50 analytics adapters. It supports currency conversion, GDPR, common ID systems, and multiple ad servers. +## Video Overview of Prebid.js + +A high-level overview of Prebid.js, Prebid’s header bidding product for websites. + +
+ +Further Reading: +- [Transcript of this video overview](/prebid/prebidjs-video.html) +- [Intro to Header Bidding](/overview/intro-to-header-bidding.html) +- [Header Bidding with Prebid](/overview/intro.html#header-bidding-with-prebid) +- [Prebid.js Developer Quick Start](/dev-docs/getting-started.html) + ## How Does Prebid.js Work? At a high level, header bidding with Prebid.js involves just a few steps: From 169026dffc039daab64f0b67ad2e1ea510c73d1e Mon Sep 17 00:00:00 2001 From: samuel-palmer-relevant-digital <77437973+samuel-palmer-relevant-digital@users.noreply.github.com> Date: Wed, 10 May 2023 13:29:48 +0200 Subject: [PATCH 201/762] New Adapter: Relevant Digital (#4426) * New Adapter: Relevant Digital * Added documentation for new parameters * Added documentation for forgotten 'pbsBufferMs' parameter --- dev-docs/bidders/relevantdigital.md | 133 ++++++++++++++++++++++++++++ 1 file changed, 133 insertions(+) create mode 100644 dev-docs/bidders/relevantdigital.md diff --git a/dev-docs/bidders/relevantdigital.md b/dev-docs/bidders/relevantdigital.md new file mode 100644 index 00000000..3015428f --- /dev/null +++ b/dev-docs/bidders/relevantdigital.md @@ -0,0 +1,133 @@ +--- +layout: bidder +title: Relevant Digital +description: Relevant Digital Bid Adapter +biddercode: relevantdigital +pbjs: true +gdpr_supported: true +usp_supported: true +coppa_supported: false +schain_supported: true +floors_supported: true +media_types: banner, video, native +userIds: all +prebid_member: true +safeframes_ok: true +deals_supported: true +pbs: false +pbs_app_supported: false +fpd_supported: true +ortb_blocking_supported: no +gvl_id: 1100 +multiformat_supported: true +sidebarType: 1 +--- + +### Bid Params + +{: .table .table-bordered .table-striped } +| Name | Scope | Description | Example | Type | +|---------------|----------|---------------------------------------------------------|----------------------------|--------------| +| `placementId` | required | The placement id. | `'6204e83a077_620f9e8e4fe'` | `String` | +| `pbsHost` | required if not set in config | Host name of the server. | `'pbs-example.relevant-digital.com'` | `String` | +| `accountId` | required if not set in config | The account id. | `'6204e5fa70e3ad108'` | `String` | +| `useSourceBidderCode` | optional | Set to `true` in order to use the bidder code of the actual server-side bidder in bid responses. You **MUST** also use `allowAlternateBidderCodes: true` in `bidderSettings` if you enabled this - as otherwise the bids will be rejected.| `true` | `Boolean` | + +### Config Parameters + +{: .table .table-bordered .table-striped } +| Name | Scope | Description | Example | Type | +|---------------|----------|---------------------------------------------------------|----------------------------|--------------| +| `pbsHost` | required if not set in bid parameters | Host name of the server. | `'pbs-example.relevant-digital.com'` | `String` | +| `accountId` | required if not set in bid parameters | The account id. | `'6204e5fa70e3ad108'` | `String` | +| `pbsBufferMs` | optional | How much less in *milliseconds* the server's internal timeout should be compared to the normal Prebid timeout. Default is *250*. To be increased in cases of frequent timeouts. | `250` | `Integer` | +| `useSourceBidderCode` | optional | Set to `true` in order to use the bidder code of the actual server-side bidder in bid responses. You **MUST** also use `allowAlternateBidderCodes: true` in `bidderSettings` if you enabled this - as otherwise the bids will be rejected.| `true` | `Boolean` | + +### Example setup using pbjs.setConfig() +This is the recommended method to set the global configuration parameters. +```javascript +pbjs.setConfig({ + relevantdigital: { + pbsHost: 'pbs-example.relevant-digital.com', + accountId: '6204e5fa70e3ad10821b84ff', + }, +}); + +var adUnits = [ + { + code: 'test-div', + mediaTypes: { banner: { sizes: [[300, 250], [320, 320]] }}, + bids: [ + { + bidder: 'relevantdigital', + params: { + placementId: '6204e83a077c5825441b8508_620f9e8e4fe67c1f87cd30ed', + } + } + ], + } +]; +``` +# Example setup using only bid params +This method to set the global configuration parameters (like **pbsHost**) in **params** could simplify integration of a provider for some publishers. Setting different global config-parameters on different bids is not supported in general*, as the first settings found will be used and any subsequent global settings will be ignored. + + * _The exception is `useSourceBidderCode` which can be overriden individually per ad unit._ +```javascript +var adUnits = [ + { + code: 'test-div', + mediaTypes: { banner: { sizes: [[300, 250], [320, 320]] }}, + bids: [ + { + bidder: 'relevantdigital', + params: { + placementId: '6204e83a077c5825441b8508_620f9e8e4fe67c1f87cd30ed', + pbsHost: 'pbs-example.relevant-digital.com', + accountId: '6204e5fa70e3ad10821b84ff', + } + } + ], + } +]; +``` + +### Example setup with multiple providers +**Notice:** Placements below are _not_ live test placements +```javascript + +pbjs.aliasBidder('relevantdigital', 'providerA'); +pbjs.aliasBidder('relevantdigital', 'providerB'); + +pbjs.setConfig({ + providerA: { + pbsHost: 'pbs-example-a.relevant-digital.com', + accountId: '620533ae7f5bbe1691bbb815', + }, + providerB: { + pbsHost: 'pbs-example-b.relevant-digital.com', + accountId: '990533ae7f5bbe1691bbb815', + }, +}); + +var adUnits = [ + { + code: 'test-div', + mediaTypes: { banner: { sizes: [[300, 250], [320, 320]] }}, + bids: [ + { + bidder: 'providerA', + params: { + placementId: '610525862d7517bfd4bbb81e_620523b7d1dbed6b0fbbb817', + } + }, + { + bidder: 'providerB', + params: { + placementId: '990525862d7517bfd4bbb81e_770523b7d1dbed6b0fbbb817', + } + }, + ], + } +]; +``` + From 51be78be4741d8f6e768adaebf69efd8ced27f3d Mon Sep 17 00:00:00 2001 From: xwang202 <57196235+xwang202@users.noreply.github.com> Date: Wed, 10 May 2023 20:01:47 +0800 Subject: [PATCH 202/762] FreeWheel SSP Adapter: add gpp_supported (#4538) --- dev-docs/bidders/freewheelssp.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/dev-docs/bidders/freewheelssp.md b/dev-docs/bidders/freewheelssp.md index 04429dd8..4b48260e 100644 --- a/dev-docs/bidders/freewheelssp.md +++ b/dev-docs/bidders/freewheelssp.md @@ -1,6 +1,6 @@ --- layout: bidder -title: freeWheelssp +title: FreeWheelssp description: Freewheel Bidder Adaptor pbjs: true pbs: true @@ -9,6 +9,7 @@ aliasCode: freewheel-ssp gvl_id: 285 gdpr_supported: true usp_supported: true +gpp_supported: true coppa_supported: true schain_supported: true media_types: video From 6fe597de6ca927c97e4eacfda7421cd54aa74314 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 10 May 2023 05:02:25 -0700 Subject: [PATCH 203/762] Bump engine.io and socket.io (#4536) Bumps [engine.io](https://github.com/socketio/engine.io) and [socket.io](https://github.com/socketio/socket.io). These dependencies needed to be updated together. Updates `engine.io` from 6.2.1 to 6.4.2 - [Release notes](https://github.com/socketio/engine.io/releases) - [Changelog](https://github.com/socketio/engine.io/blob/main/CHANGELOG.md) - [Commits](https://github.com/socketio/engine.io/compare/6.2.1...6.4.2) Updates `socket.io` from 4.5.3 to 4.6.1 - [Release notes](https://github.com/socketio/socket.io/releases) - [Changelog](https://github.com/socketio/socket.io/blob/main/CHANGELOG.md) - [Commits](https://github.com/socketio/socket.io/compare/4.5.3...4.6.1) --- updated-dependencies: - dependency-name: engine.io dependency-type: indirect - dependency-name: socket.io dependency-type: indirect ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- package-lock.json | 126 ++++++++++++++++++++++++++++++---------------- 1 file changed, 84 insertions(+), 42 deletions(-) diff --git a/package-lock.json b/package-lock.json index ac50a842..fe50e54f 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1090,10 +1090,13 @@ "dev": true }, "node_modules/@types/cors": { - "version": "2.8.12", - "resolved": "https://registry.npmjs.org/@types/cors/-/cors-2.8.12.tgz", - "integrity": "sha512-vt+kDhq/M2ayberEtJcIN/hxXy1Pk+59g2FV/ZQceeaTyCtCucjL2Q7FXlFjtWn4n15KCr1NE2lNNFhp0lEThw==", - "dev": true + "version": "2.8.13", + "resolved": "https://registry.npmjs.org/@types/cors/-/cors-2.8.13.tgz", + "integrity": "sha512-RG8AStHlUiV5ysZQKq97copd2UmVYw3/pRMLefISZ3S1hK104Cwm7iLQ3fTKx+lsUH2CE8FlLaYeEA2LSeqYUA==", + "dev": true, + "dependencies": { + "@types/node": "*" + } }, "node_modules/@types/glob": { "version": "7.1.3", @@ -4666,9 +4669,9 @@ } }, "node_modules/engine.io": { - "version": "6.2.1", - "resolved": "https://registry.npmjs.org/engine.io/-/engine.io-6.2.1.tgz", - "integrity": "sha512-ECceEFcAaNRybd3lsGQKas3ZlMVjN3cyWwMP25D2i0zWfyiytVbTpRPa34qrr+FHddtpBVOmq4H/DCv1O0lZRA==", + "version": "6.4.2", + "resolved": "https://registry.npmjs.org/engine.io/-/engine.io-6.4.2.tgz", + "integrity": "sha512-FKn/3oMiJjrOEOeUub2WCox6JhxBXq/Zn3fZOMCBxKnNYtsdKjxhl7yR3fZhM9PV+rdE75SU5SYMc+2PGzo+Tg==", "dev": true, "dependencies": { "@types/cookie": "^0.4.1", @@ -4680,7 +4683,7 @@ "cors": "~2.8.5", "debug": "~4.3.1", "engine.io-parser": "~5.0.3", - "ws": "~8.2.3" + "ws": "~8.11.0" }, "engines": { "node": ">=10.0.0" @@ -4739,9 +4742,9 @@ } }, "node_modules/engine.io/node_modules/ws": { - "version": "8.2.3", - "resolved": "https://registry.npmjs.org/ws/-/ws-8.2.3.tgz", - "integrity": "sha512-wBuoj1BDpC6ZQ1B7DWQBYVLphPWkm8i9Y0/3YdHjHKHiohOJ1ws+3OccDWtH+PoC9DZD5WOTrJvNbWvjS6JWaA==", + "version": "8.11.0", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.11.0.tgz", + "integrity": "sha512-HPG3wQd9sNQoT9xHyNCXoDUa+Xw/VevmY9FoHyQ+g+rrMn4j6FB4np7Z0OhdTgjx6MgQLK7jwSy1YecU1+4Asg==", "dev": true, "engines": { "node": ">=10.0.0" @@ -10600,27 +10603,51 @@ "dev": true }, "node_modules/socket.io": { - "version": "4.5.3", - "resolved": "https://registry.npmjs.org/socket.io/-/socket.io-4.5.3.tgz", - "integrity": "sha512-zdpnnKU+H6mOp7nYRXH4GNv1ux6HL6+lHL8g7Ds7Lj8CkdK1jJK/dlwsKDculbyOHifcJ0Pr/yeXnZQ5GeFrcg==", + "version": "4.6.1", + "resolved": "https://registry.npmjs.org/socket.io/-/socket.io-4.6.1.tgz", + "integrity": "sha512-KMcaAi4l/8+xEjkRICl6ak8ySoxsYG+gG6/XfRCPJPQ/haCRIJBTL4wIl8YCsmtaBovcAXGLOShyVWQ/FG8GZA==", "dev": true, "dependencies": { "accepts": "~1.3.4", "base64id": "~2.0.0", "debug": "~4.3.2", - "engine.io": "~6.2.0", - "socket.io-adapter": "~2.4.0", - "socket.io-parser": "~4.2.0" + "engine.io": "~6.4.1", + "socket.io-adapter": "~2.5.2", + "socket.io-parser": "~4.2.1" }, "engines": { "node": ">=10.0.0" } }, "node_modules/socket.io-adapter": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/socket.io-adapter/-/socket.io-adapter-2.4.0.tgz", - "integrity": "sha512-W4N+o69rkMEGVuk2D/cvca3uYsvGlMwsySWV447y99gUPghxq42BxqLNMndb+a1mm/5/7NeXVQS7RLa2XyXvYg==", - "dev": true + "version": "2.5.2", + "resolved": "https://registry.npmjs.org/socket.io-adapter/-/socket.io-adapter-2.5.2.tgz", + "integrity": "sha512-87C3LO/NOMc+eMcpcxUBebGjkpMDkNBS9tf7KJqcDsmL936EChtVva71Dw2q4tQcuVC+hAUy4an2NO/sYXmwRA==", + "dev": true, + "dependencies": { + "ws": "~8.11.0" + } + }, + "node_modules/socket.io-adapter/node_modules/ws": { + "version": "8.11.0", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.11.0.tgz", + "integrity": "sha512-HPG3wQd9sNQoT9xHyNCXoDUa+Xw/VevmY9FoHyQ+g+rrMn4j6FB4np7Z0OhdTgjx6MgQLK7jwSy1YecU1+4Asg==", + "dev": true, + "engines": { + "node": ">=10.0.0" + }, + "peerDependencies": { + "bufferutil": "^4.0.1", + "utf-8-validate": "^5.0.2" + }, + "peerDependenciesMeta": { + "bufferutil": { + "optional": true + }, + "utf-8-validate": { + "optional": true + } + } }, "node_modules/socket.io-client": { "version": "4.6.1", @@ -13882,10 +13909,13 @@ "dev": true }, "@types/cors": { - "version": "2.8.12", - "resolved": "https://registry.npmjs.org/@types/cors/-/cors-2.8.12.tgz", - "integrity": "sha512-vt+kDhq/M2ayberEtJcIN/hxXy1Pk+59g2FV/ZQceeaTyCtCucjL2Q7FXlFjtWn4n15KCr1NE2lNNFhp0lEThw==", - "dev": true + "version": "2.8.13", + "resolved": "https://registry.npmjs.org/@types/cors/-/cors-2.8.13.tgz", + "integrity": "sha512-RG8AStHlUiV5ysZQKq97copd2UmVYw3/pRMLefISZ3S1hK104Cwm7iLQ3fTKx+lsUH2CE8FlLaYeEA2LSeqYUA==", + "dev": true, + "requires": { + "@types/node": "*" + } }, "@types/glob": { "version": "7.1.3", @@ -16885,9 +16915,9 @@ } }, "engine.io": { - "version": "6.2.1", - "resolved": "https://registry.npmjs.org/engine.io/-/engine.io-6.2.1.tgz", - "integrity": "sha512-ECceEFcAaNRybd3lsGQKas3ZlMVjN3cyWwMP25D2i0zWfyiytVbTpRPa34qrr+FHddtpBVOmq4H/DCv1O0lZRA==", + "version": "6.4.2", + "resolved": "https://registry.npmjs.org/engine.io/-/engine.io-6.4.2.tgz", + "integrity": "sha512-FKn/3oMiJjrOEOeUub2WCox6JhxBXq/Zn3fZOMCBxKnNYtsdKjxhl7yR3fZhM9PV+rdE75SU5SYMc+2PGzo+Tg==", "dev": true, "requires": { "@types/cookie": "^0.4.1", @@ -16899,7 +16929,7 @@ "cors": "~2.8.5", "debug": "~4.3.1", "engine.io-parser": "~5.0.3", - "ws": "~8.2.3" + "ws": "~8.11.0" }, "dependencies": { "cookie": { @@ -16909,9 +16939,9 @@ "dev": true }, "ws": { - "version": "8.2.3", - "resolved": "https://registry.npmjs.org/ws/-/ws-8.2.3.tgz", - "integrity": "sha512-wBuoj1BDpC6ZQ1B7DWQBYVLphPWkm8i9Y0/3YdHjHKHiohOJ1ws+3OccDWtH+PoC9DZD5WOTrJvNbWvjS6JWaA==", + "version": "8.11.0", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.11.0.tgz", + "integrity": "sha512-HPG3wQd9sNQoT9xHyNCXoDUa+Xw/VevmY9FoHyQ+g+rrMn4j6FB4np7Z0OhdTgjx6MgQLK7jwSy1YecU1+4Asg==", "dev": true, "requires": {} } @@ -21805,24 +21835,36 @@ } }, "socket.io": { - "version": "4.5.3", - "resolved": "https://registry.npmjs.org/socket.io/-/socket.io-4.5.3.tgz", - "integrity": "sha512-zdpnnKU+H6mOp7nYRXH4GNv1ux6HL6+lHL8g7Ds7Lj8CkdK1jJK/dlwsKDculbyOHifcJ0Pr/yeXnZQ5GeFrcg==", + "version": "4.6.1", + "resolved": "https://registry.npmjs.org/socket.io/-/socket.io-4.6.1.tgz", + "integrity": "sha512-KMcaAi4l/8+xEjkRICl6ak8ySoxsYG+gG6/XfRCPJPQ/haCRIJBTL4wIl8YCsmtaBovcAXGLOShyVWQ/FG8GZA==", "dev": true, "requires": { "accepts": "~1.3.4", "base64id": "~2.0.0", "debug": "~4.3.2", - "engine.io": "~6.2.0", - "socket.io-adapter": "~2.4.0", - "socket.io-parser": "~4.2.0" + "engine.io": "~6.4.1", + "socket.io-adapter": "~2.5.2", + "socket.io-parser": "~4.2.1" } }, "socket.io-adapter": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/socket.io-adapter/-/socket.io-adapter-2.4.0.tgz", - "integrity": "sha512-W4N+o69rkMEGVuk2D/cvca3uYsvGlMwsySWV447y99gUPghxq42BxqLNMndb+a1mm/5/7NeXVQS7RLa2XyXvYg==", - "dev": true + "version": "2.5.2", + "resolved": "https://registry.npmjs.org/socket.io-adapter/-/socket.io-adapter-2.5.2.tgz", + "integrity": "sha512-87C3LO/NOMc+eMcpcxUBebGjkpMDkNBS9tf7KJqcDsmL936EChtVva71Dw2q4tQcuVC+hAUy4an2NO/sYXmwRA==", + "dev": true, + "requires": { + "ws": "~8.11.0" + }, + "dependencies": { + "ws": { + "version": "8.11.0", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.11.0.tgz", + "integrity": "sha512-HPG3wQd9sNQoT9xHyNCXoDUa+Xw/VevmY9FoHyQ+g+rrMn4j6FB4np7Z0OhdTgjx6MgQLK7jwSy1YecU1+4Asg==", + "dev": true, + "requires": {} + } + } }, "socket.io-client": { "version": "4.6.1", From 0cfb5288c4573161e799358e54d1830de561fa21 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 10 May 2023 05:25:45 -0700 Subject: [PATCH 204/762] Bump lodash from 4.17.20 to 4.17.21 (#4555) Bumps [lodash](https://github.com/lodash/lodash) from 4.17.20 to 4.17.21. - [Release notes](https://github.com/lodash/lodash/releases) - [Commits](https://github.com/lodash/lodash/compare/4.17.20...4.17.21) --- updated-dependencies: - dependency-name: lodash dependency-type: indirect ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- package-lock.json | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/package-lock.json b/package-lock.json index fe50e54f..13368f79 100644 --- a/package-lock.json +++ b/package-lock.json @@ -7347,9 +7347,9 @@ } }, "node_modules/lodash": { - "version": "4.17.20", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.20.tgz", - "integrity": "sha512-PlhdFcillOINfeV7Ni6oF1TAEayyZBoZ8bcshTHqOYJYlrqzRK5hagpagky5o4HfCzzd1TRkXPMFq6cKk9rGmA==", + "version": "4.17.21", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", + "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", "dev": true }, "node_modules/lodash.isfinite": { @@ -19066,9 +19066,9 @@ } }, "lodash": { - "version": "4.17.20", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.20.tgz", - "integrity": "sha512-PlhdFcillOINfeV7Ni6oF1TAEayyZBoZ8bcshTHqOYJYlrqzRK5hagpagky5o4HfCzzd1TRkXPMFq6cKk9rGmA==", + "version": "4.17.21", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", + "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", "dev": true }, "lodash.isfinite": { From 271f69363137f45e78cf7b23007abab966055753 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 10 May 2023 05:45:42 -0700 Subject: [PATCH 205/762] Bump y18n from 4.0.0 to 4.0.3 (#4553) Bumps [y18n](https://github.com/yargs/y18n) from 4.0.0 to 4.0.3. - [Release notes](https://github.com/yargs/y18n/releases) - [Changelog](https://github.com/yargs/y18n/blob/y18n-v4.0.3/CHANGELOG.md) - [Commits](https://github.com/yargs/y18n/compare/v4.0.0...y18n-v4.0.3) --- updated-dependencies: - dependency-name: y18n dependency-type: indirect ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- package-lock.json | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/package-lock.json b/package-lock.json index 13368f79..079782b3 100644 --- a/package-lock.json +++ b/package-lock.json @@ -12654,9 +12654,9 @@ } }, "node_modules/y18n": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.0.tgz", - "integrity": "sha512-r9S/ZyXu/Xu9q1tYlpsLIsa3EeLXXk0VwlxqTcFRfg9EhMW+17kbt9G0NrgCmhGb5vT2hyhJZLfDGx+7+5Uj/w==", + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.3.tgz", + "integrity": "sha512-JKhqTOwSrqNA1NY5lSztJ1GrBiUodLMmIZuLiDaMRJ+itFd+ABVE8XBjOvIWL+rSqNDC74LCSFmlb/U4UZ4hJQ==", "dev": true }, "node_modules/yallist": { @@ -23530,9 +23530,9 @@ "dev": true }, "y18n": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.0.tgz", - "integrity": "sha512-r9S/ZyXu/Xu9q1tYlpsLIsa3EeLXXk0VwlxqTcFRfg9EhMW+17kbt9G0NrgCmhGb5vT2hyhJZLfDGx+7+5Uj/w==", + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.3.tgz", + "integrity": "sha512-JKhqTOwSrqNA1NY5lSztJ1GrBiUodLMmIZuLiDaMRJ+itFd+ABVE8XBjOvIWL+rSqNDC74LCSFmlb/U4UZ4hJQ==", "dev": true }, "yallist": { From 11753deb8348137a7a7ad77f5071557a4408c86b Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 10 May 2023 05:57:47 -0700 Subject: [PATCH 206/762] Bump ini from 1.3.5 to 1.3.8 (#4557) Bumps [ini](https://github.com/npm/ini) from 1.3.5 to 1.3.8. - [Release notes](https://github.com/npm/ini/releases) - [Changelog](https://github.com/npm/ini/blob/main/CHANGELOG.md) - [Commits](https://github.com/npm/ini/compare/v1.3.5...v1.3.8) --- updated-dependencies: - dependency-name: ini dependency-type: indirect ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- package-lock.json | 17 +++++++---------- 1 file changed, 7 insertions(+), 10 deletions(-) diff --git a/package-lock.json b/package-lock.json index 079782b3..961e5307 100644 --- a/package-lock.json +++ b/package-lock.json @@ -6509,13 +6509,10 @@ "dev": true }, "node_modules/ini": { - "version": "1.3.5", - "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.5.tgz", - "integrity": "sha512-RZY5huIKCMRWDUqZlEi72f/lmXKMvuszcMBduliQ3nnWbx9X/ZBQO7DijMEYS9EhHBb2qacRUMtC7svLwe0lcw==", - "dev": true, - "engines": { - "node": "*" - } + "version": "1.3.8", + "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz", + "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==", + "dev": true }, "node_modules/internal-ip": { "version": "4.3.0", @@ -18408,9 +18405,9 @@ "dev": true }, "ini": { - "version": "1.3.5", - "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.5.tgz", - "integrity": "sha512-RZY5huIKCMRWDUqZlEi72f/lmXKMvuszcMBduliQ3nnWbx9X/ZBQO7DijMEYS9EhHBb2qacRUMtC7svLwe0lcw==", + "version": "1.3.8", + "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz", + "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==", "dev": true }, "internal-ip": { From 94f8a794872b78f8c56e757440812de44f1ca79c Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 10 May 2023 06:02:22 -0700 Subject: [PATCH 207/762] Bump elliptic from 6.5.3 to 6.5.4 (#4554) Bumps [elliptic](https://github.com/indutny/elliptic) from 6.5.3 to 6.5.4. - [Commits](https://github.com/indutny/elliptic/compare/v6.5.3...v6.5.4) --- updated-dependencies: - dependency-name: elliptic dependency-type: indirect ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- package-lock.json | 36 ++++++++++++++++++------------------ 1 file changed, 18 insertions(+), 18 deletions(-) diff --git a/package-lock.json b/package-lock.json index 961e5307..84232c60 100644 --- a/package-lock.json +++ b/package-lock.json @@ -4615,18 +4615,18 @@ "dev": true }, "node_modules/elliptic": { - "version": "6.5.3", - "resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.5.3.tgz", - "integrity": "sha512-IMqzv5wNQf+E6aHeIqATs0tOLeOTwj1QKbRcS3jBbYkl5oLAserA8yJTT7/VyHUYG91PRmPyeQDObKLPpeS4dw==", + "version": "6.5.4", + "resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.5.4.tgz", + "integrity": "sha512-iLhC6ULemrljPZb+QutR5TQGB+pdW6KGD5RSegS+8sorOZT+rdQFbsQFJgvN3eRqNALqJer4oQ16YvJHlU8hzQ==", "dev": true, "dependencies": { - "bn.js": "^4.4.0", - "brorand": "^1.0.1", + "bn.js": "^4.11.9", + "brorand": "^1.1.0", "hash.js": "^1.0.0", - "hmac-drbg": "^1.0.0", - "inherits": "^2.0.1", - "minimalistic-assert": "^1.0.0", - "minimalistic-crypto-utils": "^1.0.0" + "hmac-drbg": "^1.0.1", + "inherits": "^2.0.4", + "minimalistic-assert": "^1.0.1", + "minimalistic-crypto-utils": "^1.0.1" } }, "node_modules/elliptic/node_modules/bn.js": { @@ -16862,18 +16862,18 @@ "dev": true }, "elliptic": { - "version": "6.5.3", - "resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.5.3.tgz", - "integrity": "sha512-IMqzv5wNQf+E6aHeIqATs0tOLeOTwj1QKbRcS3jBbYkl5oLAserA8yJTT7/VyHUYG91PRmPyeQDObKLPpeS4dw==", + "version": "6.5.4", + "resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.5.4.tgz", + "integrity": "sha512-iLhC6ULemrljPZb+QutR5TQGB+pdW6KGD5RSegS+8sorOZT+rdQFbsQFJgvN3eRqNALqJer4oQ16YvJHlU8hzQ==", "dev": true, "requires": { - "bn.js": "^4.4.0", - "brorand": "^1.0.1", + "bn.js": "^4.11.9", + "brorand": "^1.1.0", "hash.js": "^1.0.0", - "hmac-drbg": "^1.0.0", - "inherits": "^2.0.1", - "minimalistic-assert": "^1.0.0", - "minimalistic-crypto-utils": "^1.0.0" + "hmac-drbg": "^1.0.1", + "inherits": "^2.0.4", + "minimalistic-assert": "^1.0.1", + "minimalistic-crypto-utils": "^1.0.1" }, "dependencies": { "bn.js": { From 630fcbacb9e2236d96b8c20322449da22b1ae47b Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 10 May 2023 06:17:32 -0700 Subject: [PATCH 208/762] Bump node-notifier and webpack-notifier (#4556) Bumps [node-notifier](https://github.com/mikaelbr/node-notifier) and [webpack-notifier](https://github.com/Turbo87/webpack-notifier). These dependencies needed to be updated together. Updates `node-notifier` from 5.4.3 to 9.0.1 - [Changelog](https://github.com/mikaelbr/node-notifier/blob/master/CHANGELOG.md) - [Commits](https://github.com/mikaelbr/node-notifier/compare/v5.4.3...v9.0.1) Updates `webpack-notifier` from 1.8.0 to 1.15.0 - [Release notes](https://github.com/Turbo87/webpack-notifier/releases) - [Changelog](https://github.com/Turbo87/webpack-notifier/blob/master/CHANGELOG.md) - [Commits](https://github.com/Turbo87/webpack-notifier/compare/v1.8.0...v1.15.0) --- updated-dependencies: - dependency-name: node-notifier dependency-type: indirect - dependency-name: webpack-notifier dependency-type: indirect ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- package-lock.json | 226 ++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 200 insertions(+), 26 deletions(-) diff --git a/package-lock.json b/package-lock.json index 84232c60..4c7be5d2 100644 --- a/package-lock.json +++ b/package-lock.json @@ -5948,7 +5948,7 @@ "node_modules/growly": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/growly/-/growly-1.3.0.tgz", - "integrity": "sha1-8QdIy+dq+WS3yWyTxrzCivEgwIE=", + "integrity": "sha512-+xGQY0YyAWCnqy7Cd++hc2JqMYzlm0dG30Jd0beaA64sROr8C4nt8Yc9V5Ro3avlSUDTN0ulqP/VBKi1/lLygw==", "dev": true }, "node_modules/handle-thing": { @@ -6723,6 +6723,21 @@ "node": ">=0.10.0" } }, + "node_modules/is-docker": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/is-docker/-/is-docker-2.2.1.tgz", + "integrity": "sha512-F+i2BKsFrH66iaUFc0woD8sLy8getkwTwtOBjvs56Cx4CgJDeKQeqfz8wAYiSb8JOprWhHH5p77PbmYCvvUuXQ==", + "dev": true, + "bin": { + "is-docker": "cli.js" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/is-extendable": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", @@ -7889,16 +7904,80 @@ "dev": true }, "node_modules/node-notifier": { - "version": "5.4.3", - "resolved": "https://registry.npmjs.org/node-notifier/-/node-notifier-5.4.3.tgz", - "integrity": "sha512-M4UBGcs4jeOK9CjTsYwkvH6/MzuUmGCyTW+kCY7uO+1ZVr0+FHGdPdIf5CCLqAaxnRrWidyoQlNkMIIVwbKB8Q==", + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/node-notifier/-/node-notifier-9.0.1.tgz", + "integrity": "sha512-fPNFIp2hF/Dq7qLDzSg4vZ0J4e9v60gJR+Qx7RbjbWqzPDdEqeVpEx5CFeDAELIl+A/woaaNn1fQ5nEVerMxJg==", "dev": true, "dependencies": { "growly": "^1.3.0", - "is-wsl": "^1.1.0", - "semver": "^5.5.0", + "is-wsl": "^2.2.0", + "semver": "^7.3.2", "shellwords": "^0.1.1", - "which": "^1.3.0" + "uuid": "^8.3.0", + "which": "^2.0.2" + } + }, + "node_modules/node-notifier/node_modules/is-wsl": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-2.2.0.tgz", + "integrity": "sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww==", + "dev": true, + "dependencies": { + "is-docker": "^2.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/node-notifier/node_modules/lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "dev": true, + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/node-notifier/node_modules/semver": { + "version": "7.5.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.0.tgz", + "integrity": "sha512-+XC0AD/R7Q2mPSRuy2Id0+CGTZ98+8f+KvwirxOKIEyid+XSx6HbC63p+O4IndTHuX5Z+JxQ0TghCkO5Cg/2HA==", + "dev": true, + "dependencies": { + "lru-cache": "^6.0.0" + }, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/node-notifier/node_modules/uuid": { + "version": "8.3.2", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", + "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==", + "dev": true, + "bin": { + "uuid": "dist/bin/uuid" + } + }, + "node_modules/node-notifier/node_modules/which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "dev": true, + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "node-which": "bin/node-which" + }, + "engines": { + "node": ">= 8" } }, "node_modules/node-releases": { @@ -12397,14 +12476,42 @@ } }, "node_modules/webpack-notifier": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/webpack-notifier/-/webpack-notifier-1.8.0.tgz", - "integrity": "sha512-I6t76NoPe5DZCCm5geELmDV2wlJ89LbU425uN6T2FG8Ywrrt1ZcUMz6g8yWGNg4pttqTPFQJYUPjWAlzUEQ+cQ==", + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/webpack-notifier/-/webpack-notifier-1.15.0.tgz", + "integrity": "sha512-N2V8UMgRB5komdXQRavBsRpw0hPhJq2/SWNOGuhrXpIgRhcMexzkGQysUyGStHLV5hkUlgpRiF7IUXoBqyMmzQ==", "dev": true, "dependencies": { - "node-notifier": "^5.1.2", - "object-assign": "^4.1.0", - "strip-ansi": "^3.0.1" + "node-notifier": "^9.0.0", + "strip-ansi": "^6.0.0" + }, + "peerDependencies": { + "@types/webpack": ">4.41.31" + }, + "peerDependenciesMeta": { + "@types/webpack": { + "optional": true + } + } + }, + "node_modules/webpack-notifier/node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/webpack-notifier/node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" } }, "node_modules/webpack-sources": { @@ -17929,7 +18036,7 @@ "growly": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/growly/-/growly-1.3.0.tgz", - "integrity": "sha1-8QdIy+dq+WS3yWyTxrzCivEgwIE=", + "integrity": "sha512-+xGQY0YyAWCnqy7Cd++hc2JqMYzlm0dG30Jd0beaA64sROr8C4nt8Yc9V5Ro3avlSUDTN0ulqP/VBKi1/lLygw==", "dev": true }, "handle-thing": { @@ -18577,6 +18684,12 @@ "integrity": "sha1-YTObbyR1/Hcv2cnYP1yFddwVSuE=", "dev": true }, + "is-docker": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/is-docker/-/is-docker-2.2.1.tgz", + "integrity": "sha512-F+i2BKsFrH66iaUFc0woD8sLy8getkwTwtOBjvs56Cx4CgJDeKQeqfz8wAYiSb8JOprWhHH5p77PbmYCvvUuXQ==", + "dev": true + }, "is-extendable": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", @@ -19532,16 +19645,61 @@ } }, "node-notifier": { - "version": "5.4.3", - "resolved": "https://registry.npmjs.org/node-notifier/-/node-notifier-5.4.3.tgz", - "integrity": "sha512-M4UBGcs4jeOK9CjTsYwkvH6/MzuUmGCyTW+kCY7uO+1ZVr0+FHGdPdIf5CCLqAaxnRrWidyoQlNkMIIVwbKB8Q==", + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/node-notifier/-/node-notifier-9.0.1.tgz", + "integrity": "sha512-fPNFIp2hF/Dq7qLDzSg4vZ0J4e9v60gJR+Qx7RbjbWqzPDdEqeVpEx5CFeDAELIl+A/woaaNn1fQ5nEVerMxJg==", "dev": true, "requires": { "growly": "^1.3.0", - "is-wsl": "^1.1.0", - "semver": "^5.5.0", + "is-wsl": "^2.2.0", + "semver": "^7.3.2", "shellwords": "^0.1.1", - "which": "^1.3.0" + "uuid": "^8.3.0", + "which": "^2.0.2" + }, + "dependencies": { + "is-wsl": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-2.2.0.tgz", + "integrity": "sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww==", + "dev": true, + "requires": { + "is-docker": "^2.0.0" + } + }, + "lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "dev": true, + "requires": { + "yallist": "^4.0.0" + } + }, + "semver": { + "version": "7.5.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.0.tgz", + "integrity": "sha512-+XC0AD/R7Q2mPSRuy2Id0+CGTZ98+8f+KvwirxOKIEyid+XSx6HbC63p+O4IndTHuX5Z+JxQ0TghCkO5Cg/2HA==", + "dev": true, + "requires": { + "lru-cache": "^6.0.0" + } + }, + "uuid": { + "version": "8.3.2", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", + "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==", + "dev": true + }, + "which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "dev": true, + "requires": { + "isexe": "^2.0.0" + } + } } }, "node-releases": { @@ -23391,14 +23549,30 @@ } }, "webpack-notifier": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/webpack-notifier/-/webpack-notifier-1.8.0.tgz", - "integrity": "sha512-I6t76NoPe5DZCCm5geELmDV2wlJ89LbU425uN6T2FG8Ywrrt1ZcUMz6g8yWGNg4pttqTPFQJYUPjWAlzUEQ+cQ==", + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/webpack-notifier/-/webpack-notifier-1.15.0.tgz", + "integrity": "sha512-N2V8UMgRB5komdXQRavBsRpw0hPhJq2/SWNOGuhrXpIgRhcMexzkGQysUyGStHLV5hkUlgpRiF7IUXoBqyMmzQ==", "dev": true, "requires": { - "node-notifier": "^5.1.2", - "object-assign": "^4.1.0", - "strip-ansi": "^3.0.1" + "node-notifier": "^9.0.0", + "strip-ansi": "^6.0.0" + }, + "dependencies": { + "ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true + }, + "strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "requires": { + "ansi-regex": "^5.0.1" + } + } } }, "webpack-sources": { From 6e9cc5b1014904d2c8e051930a63b161a11ca5b8 Mon Sep 17 00:00:00 2001 From: bretg Date: Wed, 10 May 2023 13:21:35 -0400 Subject: [PATCH 209/762] Flagging emx_digital as deprecated (#4564) --- dev-docs/bidders/emx_digital.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/dev-docs/bidders/emx_digital.md b/dev-docs/bidders/emx_digital.md index d9dbf610..8e508c7a 100644 --- a/dev-docs/bidders/emx_digital.md +++ b/dev-docs/bidders/emx_digital.md @@ -15,6 +15,9 @@ userIds: identityLink, uid2 sidebarType: 1 --- +{: .alert.alert-warning :} +The emx_digital bidder is deprecated, and will be removed in a future release of Prebid.js and Prebid Server. + ### Registration To use this bidder you will need an account and a valid tagid from our exchange. For further information, please contact your Account Manager or adops@emxdigital.com. From 1e2dfbc42f6847827c52e2d7ab64050dda0c0bb3 Mon Sep 17 00:00:00 2001 From: bretg Date: Wed, 10 May 2023 16:52:32 -0400 Subject: [PATCH 210/762] PBS: fix video cache example (#4566) --- prebid-server/endpoints/openrtb2/pbs-endpoint-auction.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/prebid-server/endpoints/openrtb2/pbs-endpoint-auction.md b/prebid-server/endpoints/openrtb2/pbs-endpoint-auction.md index ea68c7a9..d081a6ac 100644 --- a/prebid-server/endpoints/openrtb2/pbs-endpoint-auction.md +++ b/prebid-server/endpoints/openrtb2/pbs-endpoint-auction.md @@ -684,7 +684,7 @@ If the `ext.prebid.cache.vastxml` object is present, Prebid Server will make a b "ext": { "prebid": { "cache": { - "bids": { + "vastXml": { "url": "https://example.com:443/cache?uuid=385b283c-22cb-49a0-8c0b-8b88c49d9fe9", "cacheId": "385b283c-22cb-49a0-8c0b-8b88c49d9fe9" } From f607cd59cb157b2106d5a88868341aa57d7c7e59 Mon Sep 17 00:00:00 2001 From: rimaburder-index <55195208+rimaburder-index@users.noreply.github.com> Date: Thu, 11 May 2023 12:42:56 -0400 Subject: [PATCH 211/762] Update ix.md (#4565) * Update ix.md added the version from which we support the Index bidder-specific data * Update ix.md Updated step 6 (about FPD) in the set up steps to make it clearer to understand --- dev-docs/bidders/ix.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/dev-docs/bidders/ix.md b/dev-docs/bidders/ix.md index 20679f04..9f528a1a 100644 --- a/dev-docs/bidders/ix.md +++ b/dev-docs/bidders/ix.md @@ -122,7 +122,7 @@ In this configuration Prebid.js calls Index directly from the browser using our } }); ``` -5. (Optional) Set up First Party Data (FPD) using the Index bidder-specific FPD (preferred method) setting or the Prebid FPD module. For more information, see the [Set up First Party Data (FPD)](#set-up-first-party-data-fpd) section below. +5. (Optional) Set up First Party Data (FPD). For more information about the data types we support and the instructions for each option, see the [Set up First Party Data (FPD)](#set-up-first-party-data-fpd) section below. 6. (Optional) If you want to monetize instream video, you need to enable a cache endpoint in the [pbjs.setConfig()](https://docs.prebid.org/dev-docs/publisher-api-reference/setConfig.html) function as follows:
```javascript pbjs.setConfig({ @@ -160,7 +160,7 @@ In this configuration, Prebid.js makes a call to Prebid Server and then Prebid S } }); ``` -6. (Optional) Set up First Party Data (FPD) using the Index bidder-specific FPD (preferred method) setting or the Prebid FPD module. For more information, see the [Set up First Party Data (FPD)](#set-up-first-party-data-fpd) section below. +6. (Optional) Set up First Party Data (FPD). For more information about the data types we support and the instructions for each option, see the [Set up First Party Data (FPD)](#set-up-first-party-data-fpd) section below. 7. (Optional) If you want to monetize instream video, you need to enable a cache endpoint in the `[pbjs.setConfig()]` function as follows: ```javascript pbjs.setConfig({ @@ -226,7 +226,7 @@ pbjs.setConfig({ ### Index bidder-specific data -Use this data type to specify key-value pairs that will be included in your query string when targeting deals. For example, if a user visits a news page, you can pass that information by submitting a key-value pair for `category = news`. You can then create a deal in the Index UI and activate the deal only on pages that contain `category = news` as the key-value pair. +This data type is available from Prebid version 7.49.0 and above. You can use it to specify key-value pairs that will be included in your query string when targeting deals. For example, if a user visits a news page, you can pass that information by submitting a key-value pair for `category = news`. You can then create a deal in the Index UI and activate the deal only on pages that contain `category = news` as the key-value pair. To include the FPD in a bid request, in the `[pbjs.setConfig()]` object at the `ix` bidder level, provide the key-values in the `firstPartyData` parameter. Make sure that you set it before the `pbjs.requestBids` configuration. If you want to change the values, you can update the `pbjs.setConfig` once again. The change will be reflected in all future bid requests. From 75c9e1c5e5ab459dead90cea4bb8bff1d6b48236 Mon Sep 17 00:00:00 2001 From: bretg Date: Thu, 11 May 2023 12:48:38 -0400 Subject: [PATCH 212/762] axonix param table formatting (#4548) * axonix param table formatting * added type column --- dev-docs/bidders/axonix.md | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/dev-docs/bidders/axonix.md b/dev-docs/bidders/axonix.md index b0d5c66d..c4f843b3 100644 --- a/dev-docs/bidders/axonix.md +++ b/dev-docs/bidders/axonix.md @@ -14,10 +14,10 @@ sidebarType: 1 The Axonix Bidding adapter requires setup before beginning. Please contact us at support.axonix@emodoinc.com. ### Bid Params - -| Name | Scope | Description | Example | -| :------------ | :------- | :---------------------------------------------- | :------------------------------------- | -| `supplyId` | required | Supply UUID | `'2c426f78-bb18-4a16-abf4-62c6cd0ee8de'` | -| `region` | optional | Cloud region | `'us-east-1'` | -| `endpoint` | optional | Supply custom endpoint | `'https://open-rtb.axonix.com/custom'` | -| `instl` | optional | Set to 1 if using interstitial (default: 0) | `1` | +{: .table .table-bordered .table-striped } +| Name | Scope | Description | Example | Type | +|------------|-------|----------------------------------------------|-------------------------------------|------| +| `supplyId` | required | Supply UUID | `'2c426f78-bb18-4a16-abf4-62c6cd0ee8de'` | string | +| `region` | optional | Cloud region | `'us-east-1'` | string | +| `endpoint` | optional | Supply custom endpoint | `'https://open-rtb.axonix.com/custom'` | string | +| `instl` | optional | Set to 1 if using interstitial (default: 0) | `1` | integer | From 9d7074693805c73468c19395719eb66b9fdc597b Mon Sep 17 00:00:00 2001 From: Piotr Jaworski <109736938+piotrj-rtbh@users.noreply.github.com> Date: Fri, 12 May 2023 22:02:25 +0200 Subject: [PATCH 213/762] RTB House Bid Adapter: docs update - `bcat` & `badv` ORTB params support (#4522) * RTBHouse Bid Adapter: adds channel as optional param, updates bidder flags * RTBHouse Bid Adapter: fixed table descriptions * RTBHouse Bid Adapter: minor textual changes on bidder docs * ortb_blocking_supported and description section * ortb_blocking_supported and description section (#1) * ortb_blocking_supported and description section * rephrasing * ORTB blocking examples update * Javascript type for examples added * typo fix * code fix * Prebid Server setup by host companies --------- Co-authored-by: Leandro Otani Co-authored-by: rtbh-lotani <83652735+rtbh-lotani@users.noreply.github.com> --- dev-docs/bidders/rtbhouse.md | 31 +++++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) diff --git a/dev-docs/bidders/rtbhouse.md b/dev-docs/bidders/rtbhouse.md index 3feec1ce..60b4ca65 100644 --- a/dev-docs/bidders/rtbhouse.md +++ b/dev-docs/bidders/rtbhouse.md @@ -13,6 +13,7 @@ media_types: banner, native schain_supported: true userIds: id5Id, identityLink, pubProvidedId pbs_app_supported: true +ortb_blocking_supported: partial sidebarType: 1 --- @@ -27,6 +28,36 @@ sidebarType: 1 | `bidfloor` | optional | Minimal CPM value | `0.01` | `float` | | `channel` | optional | Inventory channel identifier, limited to 50 characters | `Partner 1 - News` | `string` | +#### ORTB Blocking +RTB House supports blocking advertisers in `badv` and categories in `bcat` parameters. +The blocked advertisers/categories list has no length limitation, but response timeout is more likely to occur as the number of entries grow. +Blocked advertisers list (`badv`) is an array of domains as strings. +Blocked categories list (`bcat`) is an array of IAB categories as strings. + +For example: +##### Globally defined ORTB Blocking: +```javascript +pbjs.setConfig({ + ortb2: { + badv: ["domain1.com", "domain2.com"], + bcat: ["IAB23-1", "IAB23-5", "IAB25-3", "IAB25-2"] + } +)}; +``` +##### ORTB Blocking specific only to rtbhouse bidder: +```javascript +pbjs.setBidderConfig({ + bidders: ['rtbhouse'], + config:{ + ortb2: { + badv: ["domain1.com", "domain2.com"], + bcat: ["IAB23-1", "IAB23-5", "IAB25-3", "IAB25-2"] + } + } +}); +``` +### Setting up the Prebid Server Adapter +If you’re a Prebid Server host company looking to enable the RTB House server-side adapter, you'll need to contact prebid@rtbhouse.com. They will guide you through the process. Do not use the default bidder config file as it will require custom partner code to be entered. It will be provided by RTB House. ### Please note: From b13c32f12f23aedbbc72b45760f957b980df3abf Mon Sep 17 00:00:00 2001 From: YakirLavi <73641910+YakirLavi@users.noreply.github.com> Date: Sat, 13 May 2023 17:54:16 +0300 Subject: [PATCH 214/762] Rise Bid Adapter: update documentation - support Coppa param (#4505) * Update Rise readme * fix rise doc * change rise docs * fix rise docs * added is_wrapper parameter to rise doc * changed is_wrapper to boolean * add coppa support documentation (#6) --------- Co-authored-by: noamtzu Co-authored-by: Noam Tzuberi Co-authored-by: innay --- dev-docs/bidders/rise.md | 1 + 1 file changed, 1 insertion(+) diff --git a/dev-docs/bidders/rise.md b/dev-docs/bidders/rise.md index 5a6efbfe..0088d620 100644 --- a/dev-docs/bidders/rise.md +++ b/dev-docs/bidders/rise.md @@ -7,6 +7,7 @@ pbjs: true biddercode: rise media_types: banner, video schain_supported: true +coppa_supported: true gdpr_supported: true usp_supported: true floors_supported: true From ad36a89cebe6788fa57aead13b7273fc7983ca18 Mon Sep 17 00:00:00 2001 From: YakirLavi <73641910+YakirLavi@users.noreply.github.com> Date: Sat, 13 May 2023 18:23:53 +0300 Subject: [PATCH 215/762] MinuteMedia: Update documentation - Coppa support (#4506) * Update Rise readme * fix rise doc * change rise docs * fix rise docs * added is_wrapper parameter to rise doc * changed is_wrapper to boolean * update documentation - coppa param --------- Co-authored-by: noamtzu Co-authored-by: Noam Tzuberi Co-authored-by: innay Co-authored-by: YakirLavi From 2f275bba776114dc80b36324d307d9b0ad7c0280 Mon Sep 17 00:00:00 2001 From: EngageMediaHB <130045707+EngageMediaHB@users.noreply.github.com> Date: Sat, 13 May 2023 19:41:53 +0300 Subject: [PATCH 216/762] add EMTV adapter doc (#4472) --- dev-docs/bidders/emtv.md | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) create mode 100644 dev-docs/bidders/emtv.md diff --git a/dev-docs/bidders/emtv.md b/dev-docs/bidders/emtv.md new file mode 100644 index 00000000..8de30ab0 --- /dev/null +++ b/dev-docs/bidders/emtv.md @@ -0,0 +1,30 @@ +--- +layout: bidder +title: EMTV +description: Prebid EMTV Bidder Adapter +biddercode: emtv +usp_supported: true +gdpr_supported: true +coppa_supported: true +schain_supported: true +floors_supported: true +media_types: banner, video, native +multiformat_supported: will-not-bid +pbjs: true +pbs: true +pbs_app_supported: true +safeframes_ok: true +sidebarType: 1 +--- + +### Bid Params + +{: .table .table-bordered .table-striped } +| Name | Scope | Description | Example | Type | +|---------------|----------|-----------------------|-----------|-----------| +| `placementId` | optional | Placement Id | `'0'` | `'string'` | +| `endpointId` | optional | Endpoint Id | `'0'` | `'string'` | + +### Note + +For the prebid server and prebid.js you only need to use one parameter: either placementId or endpointId From f46a6582cd9a171e293429ee566232a4a4bc46b1 Mon Sep 17 00:00:00 2001 From: Jason Quaccia Date: Sun, 14 May 2023 11:51:12 -0700 Subject: [PATCH 217/762] added docs for the adjustAlternateBids bidderSettings functionality (#4547) --- .../publisher-api-reference/bidderSettings.md | 37 ++++++++++++++++++- 1 file changed, 36 insertions(+), 1 deletion(-) diff --git a/dev-docs/publisher-api-reference/bidderSettings.md b/dev-docs/publisher-api-reference/bidderSettings.md index 2da634a2..34b7810e 100644 --- a/dev-docs/publisher-api-reference/bidderSettings.md +++ b/dev-docs/publisher-api-reference/bidderSettings.md @@ -48,7 +48,8 @@ Some sample scenarios where publishers may wish to alter the default settings: | allowZeroCpmBids | standard or adapter-specific | 6.2.0 | false | Would allow bids with a 0 CPM to be accepted by Prebid.js and could be passed to the ad server. | | storageAllowed | standard or adapter-specific | 6.13.0 | true in 6.x, false after 7.0 | Allow use of cookies and/or local storage. | | allowAlternateBidderCodes | standard or adapter-specific | 6.23.0 | true in v6.x
false from v7.0| Allow adapters to bid with alternate bidder codes. | -| allowedAlternateBidderCodes | standard or adapter-specific | 6.23.0 | n/a | Array of bidder codes for which an adapter can bid.
`undefined` or `['*']` will allow adapter to bid with any bidder code. | +| allowedAlternateBidderCodes | standard or adapter-specific | 6.23.0 | n/a | Array of bidder codes for which an adapter can bid.
`undefined` or `['*']` will allow adapter to bid with any bidder code. | +| adjustAlternateBids | standard or adapter-specific | 7.48.0 | false | Optionally allow alternate bidder codes to use an adapter's bidCpmAdjustment function by default instead of the standard bidCpmAdjustment function if present (note: if a bidCpmAdjustment function exists for the alternate bidder code within bidderSettings, then this will be used instead of falling back to the adapter's bidCpmAdjustment function). | ##### 2.1. adserverTargeting @@ -317,4 +318,38 @@ pbjs.bidderSettings = { In the above example, `groupm` bid will have a bid adjustment of 80% since the `bidCpmAdjustment` function says so.
If `appnexus` bids with another bidder code, say `appnexus2`. This bidder code will adjust the bid cpm to 95% because it will apply the `bidCpmAdjustment` function from `standard` setting, since the `bidCpmAdjustment` is missing for given bidder code I.e `appnexus2` +##### 2.10. adjustAlternateBids + +Optionally allow alternate bidder codes originating from a specific bid adapter to fallback to that same adapter's bidCpmAdjustment function. When adjustAlternateBids is set to true, the prioity of which bidCpmAdjustment function to utilize will be as follows based on what is present within the bidderSettings object: + +1. Alternate bidder code bidCpmAdjustment function +2. Adapter bidCpmAdjustment function +3. The standard bidCpmAdjustment function + +{% highlight js %} + +pbjs.bidderSettings = { + standard: { + allowAlternateBidderCodes: false, + bidCpmAdjustment: function(bidCpm, bid){ return bidCpm * .95; }, + [...] + }, + pubmatic: { + allowAlternateBidderCodes: true, + allowedAlternateBidderCodes: ["groupm"], + adjustAlternateBids: true, + bidCpmAdjustment: function(bidCpm, bid){ return bidCpm * .85; }, + [...] + }, + appnexus: { + allowAlternateBidderCodes: true, + allowedAlternateBidderCodes: ["*"], + bidCpmAdjustment: function(bidCpm, bid){ return bidCpm * .90; }, + [...] + } +} +{% endhighlight %} + +In the above example, if PubMatic were to return the "groupm" bidder code then the bidCpmAdjustment function under `pubmatic` would be used instead of what is available under `standard`. +
From 84ed532d5b59bc193b3bc9ff9cf94f90ea173fed Mon Sep 17 00:00:00 2001 From: franfrvr <130403896+franfrvr@users.noreply.github.com> Date: Mon, 15 May 2023 05:57:18 +0100 Subject: [PATCH 218/762] New Adapter: FRVR Ad Network (#4515) * New Adapter: FRVR Ad Network * New Adapter: FRVR Ad Network email contact * New Adapter: FRVR Ad Network feedback --- dev-docs/bidders/frvradn.md | 32 ++++++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) create mode 100644 dev-docs/bidders/frvradn.md diff --git a/dev-docs/bidders/frvradn.md b/dev-docs/bidders/frvradn.md new file mode 100644 index 00000000..8bcaf89f --- /dev/null +++ b/dev-docs/bidders/frvradn.md @@ -0,0 +1,32 @@ +--- +layout: bidder +title: FRVR Ad Network +description: FRVR Ad Network Prebid Bidder Adapter +biddercode: frvradn +gdpr_supported: true +usp_supported: true +coppa_supported: true +schain_supported: true +floors_supported: true +media_types: banner, video, native +multiformat_supported: will-bid-on-one +safeframes_ok: true +userIds: all +pbjs: false +pbs: true +pbs_app_supported: true +gvl_id: 1107 +sidebarType: 1 +--- + +### Registration + +FRVR Ad Network Bidding adapter requires setup before beginning. Please contact us at info@frvr.com + +### Bid Params + +{: .table .table-bordered .table-striped } +| Name | Scope | Description | Example | Type | +|---------------|----------|--------------|-----------|----------| +| `publisher_id` | required | Publisher ID | `'11111'` | `string` | +| `ad_unit_id` | required | Ad Unit ID | `'22222'` | `string` | \ No newline at end of file From 8c648e00760e0bec1edffd230a87398aba8d9f10 Mon Sep 17 00:00:00 2001 From: Parth Shah Date: Mon, 15 May 2023 21:08:51 +0530 Subject: [PATCH 219/762] chore(prebid): update dev docs to include tagId in video example (#4537) --- dev-docs/bidders/deepintent.md | 1 + 1 file changed, 1 insertion(+) diff --git a/dev-docs/bidders/deepintent.md b/dev-docs/bidders/deepintent.md index 8c35e4cc..37a8f1c2 100644 --- a/dev-docs/bidders/deepintent.md +++ b/dev-docs/bidders/deepintent.md @@ -110,6 +110,7 @@ var videoAdUnits = [ bids: [{ bidder: 'deepintent', params: { + tagId: "1399", // required publisherId: '32572', // required adSlot: '38519891@300x250' // required video: { From b87804eca280a89876694de3c8a45e40d8801aad Mon Sep 17 00:00:00 2001 From: Piotr Jaworski <109736938+piotrj-rtbh@users.noreply.github.com> Date: Mon, 15 May 2023 19:40:32 +0200 Subject: [PATCH 220/762] Add RTB House Bid Adapter as example implementation of FLEDGE (#4568) * RTBHouse Bid Adapter: adds channel as optional param, updates bidder flags * RTBHouse Bid Adapter: fixed table descriptions * RTBHouse Bid Adapter: minor textual changes on bidder docs * ortb_blocking_supported and description section * ortb_blocking_supported and description section (#1) * ortb_blocking_supported and description section * rephrasing * ORTB blocking examples update * Javascript type for examples added * typo fix * code fix * Prebid Server setup by host companies * RTB House Bidder added as an example implementation interpretResponse with FLEDGE --------- Co-authored-by: Leandro Otani Co-authored-by: rtbh-lotani <83652735+rtbh-lotani@users.noreply.github.com> --- dev-docs/modules/fledgeForGpt.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dev-docs/modules/fledgeForGpt.md b/dev-docs/modules/fledgeForGpt.md index f26d439b..1fec14e2 100644 --- a/dev-docs/modules/fledgeForGpt.md +++ b/dev-docs/modules/fledgeForGpt.md @@ -147,7 +147,7 @@ for more details. This means that the AuctionConfig objects returned from `inter the request it should be associated with. This may raise the question: why isn't the AuctionConfig object returned as part of the bid? The answer is that it's possible to participate in the FLEDGE auction without returning a contextual bid. -An example of this can be seen in the OpenX OpenRTB bid adapter [here](https://github.com/prebid/Prebid.js/blob/master/modules/openxOrtbBidAdapter.js#L327). +An example of this can be seen in the OpenX OpenRTB bid adapter [here](https://github.com/prebid/Prebid.js/blob/master/modules/openxOrtbBidAdapter.js#L327) or RTB House bid adapter [here](https://github.com/prebid/Prebid.js/blob/8fe7115021fd348d0f3b090da48c40c095078800/modules/rtbhouseBidAdapter.js#LL135C4-L135C4). Other than the addition of the `bidId` field, the `AuctionConfig` object should adhere to the requirements set forth in FLEDGE. The details of creating an `AuctionConfig` object are beyond the scope of this document. From 6411572158ef6513a0975d42871f00a102f3062f Mon Sep 17 00:00:00 2001 From: Jason Quaccia Date: Mon, 15 May 2023 11:14:24 -0700 Subject: [PATCH 221/762] Documentation for Billing Deferral (#4546) * added documention for billing deferral * some more doc updates * updated triggerBilling example * Update triggerBilling.md * Update bidder-adaptor.md * Update InterstitialAds.md --------- Co-authored-by: bretg --- dev-docs/adunit-reference.md | 3 +- dev-docs/bidder-adaptor.md | 28 ++++++++++++++++++- .../publisher-api-reference/triggerBilling.md | 25 +++++++++++++++++ features/InterstitialAds.md | 9 ++++++ 4 files changed, 63 insertions(+), 2 deletions(-) create mode 100644 dev-docs/publisher-api-reference/triggerBilling.md diff --git a/dev-docs/adunit-reference.md b/dev-docs/adunit-reference.md index 93751c65..b1476368 100644 --- a/dev-docs/adunit-reference.md +++ b/dev-docs/adunit-reference.md @@ -40,6 +40,7 @@ See the table below for the list of properties on the ad unit. For example ad u | `ttlBuffer` | Optional | Number | TTL buffer override for this adUnit. See [setConfig({ttlBuffer})](/dev-docs/publisher-api-reference/setConfig.html#setConfig-ttlBuffer) | | `renderer` | Optional | Object | Custom renderer, typically used for [outstream video](/dev-docs/show-outstream-video-ads.html) | | `video` | Optional | Object | Used to link an Ad Unit to the [Video Module][videoModule]. For allowed params see the [adUnit.video reference](#adUnit-video). | +| `deferBilling` | Optional | Boolean | Used by a publisher to flag adUnits as being separately billable. This allows for a publisher to trigger billing manually for winning bids. See [pbjs.triggerBilling](/dev-docs/publisher-api-reference/triggerBilling.html) and [onBidBillable](/dev-docs/bidder-adaptor.html#registering-on-bid-billable) for more info. | @@ -604,7 +605,7 @@ pbjs.addAdUnits({ }); {% endhighlight %} -For more information on Interstitial ads, reference the [Interstitial feature page](/features/InterstitialAds.html). +For more information on Interstitial ads, reference the [Interstitial feature page](/features/InterstitialAds.html). Additionally, to assist with billing optimization and interstitial ads, the triggerBilling and onBidBillable functionality can be utilized. See [pbjs.triggerBilling](/dev-docs/publisher-api-reference/triggerBilling.html) and [onBidBillable](/dev-docs/bidder-adaptor.html#registering-on-bid-billable) for more info. diff --git a/dev-docs/bidder-adaptor.md b/dev-docs/bidder-adaptor.md index 26002888..f3ba6622 100644 --- a/dev-docs/bidder-adaptor.md +++ b/dev-docs/bidder-adaptor.md @@ -8,7 +8,6 @@ sidebarType: 1 --- - # How to Add a New Prebid.js Bidder Adapter {:.no_toc} @@ -609,6 +608,33 @@ Sample data received by this function: } {% endhighlight %} +### Registering on Bid Billable + +The `onBidBillable` function will be called when it deems a bid to be billable. When a bid wins, it is by default also billable. That is, by default, onBidWon and onBidBillable will be called one after the other. However, a publisher can flag adUnits as being separately billable: `pbjs.addAdUnits({deferBilling: true, ...})`. Winning bids for adUnits with `deferBilling` set to true, trigger the onBidWon function but not the onBidBillable function. When appropriate (e.g. an interstitial is displayed), the publisher may then call the public API method, `pbjs.triggerBilling(winningAdIdToBill)` passing the winning bid to be billed, which will trigger onBidBillable. + +Sample data received by this function (same as what is recieved for onBidWon): + +{% highlight js %} +{ + "bidder": "example", + "width": 300, + "height": 250, + "adId": "330a22bdea4cac", + "mediaType": "banner", + "cpm": 0.28 + "ad": "...", + "requestId": "418b37f85e772c", + "adUnitCode": "div-gpt-ad-1460505748561-0", + "size": "350x250", + "adserverTargeting": { + "hb_bidder": "example", + "hb_adid": "330a22bdea4cac", + "hb_pb": "0.20", + "hb_size": "350x250" + } +} +{% endhighlight %} + ### Registering on Set Targeting The `onSetTargeting` function will be called when the adserver targeting has been set for a bid from the adapter. diff --git a/dev-docs/publisher-api-reference/triggerBilling.md b/dev-docs/publisher-api-reference/triggerBilling.md new file mode 100644 index 00000000..ab44945a --- /dev/null +++ b/dev-docs/publisher-api-reference/triggerBilling.md @@ -0,0 +1,25 @@ +--- +layout: api_prebidjs +title: pbjs.triggerBilling +description: +sidebarType: 1 +--- + + +Allows a publisher the option to manually trigger billing for a winning bid (The winning bid to be billed is passed through the function below as an argument). + +{% highlight js %} + +pbjs.triggerBilling(winningAdIdToBill); + +{% endhighlight %} + +{: .alert.alert-warning :} +Note: In order to use `pbjs.triggerBilling`, the following is also required. + +- Any bid adapters a publisher integrates with must include the onBidBillable(bid) method which will be invoked by Prebid.js when it deems a bid to be billable (When a bid wins, it is by default also billable. That is, by default, Prebid.js will invoke onBidWon and onBidBillable one after the other). +- A publisher must flag all adUnits as being separately billable via the deferBilling key: `pbjs.addAdUnits({deferBilling: true, ...})` (Setting deferBilling to true will trigger onBidWon but not onBidBillable). +- When appropriate (e.g. an interstitial is displayed), the publisher may call `pbjs.triggerBilling(winningAdIdToBill)`, which would then trigger onBidBillable. + + +
diff --git a/features/InterstitialAds.md b/features/InterstitialAds.md index 67a68304..d943385a 100644 --- a/features/InterstitialAds.md +++ b/features/InterstitialAds.md @@ -76,6 +76,15 @@ utils.deepAccess(bidRequest.ortb2Imp, 'instl') The assumption is that bid adapters will copy the values to the appropriate protocol location for their endpoint. +## Billing Deferral + +Optimizing when billing occurs for an interstitial ad can sometimes be tricky. The following built-in Prebid.js functionality can help assist with this: +- Bid adapters can provide a method called `onBidBillable(bid)` which will be invoked by Prebid.js when it deems a bid to be billable (Note: A bid adapter must have the onBidBillable method configured for this to work). +- When a bid wins, it is by default also billable. That is, by default, Prebid.js will invoke the bid adapter methods onBidWon and onBidBillable one after the other. +- A publisher can flag individual adUnits as being separately billable with the following configuration: `pbjs.addAdUnits({deferBilling: true, ...})` +- Winning bids for adUnits with deferBilling set to true will trigger a bid adapters onBidWon method but not their onBidBillable method. +- Finally, when appropriate (e.g. an interstitial is displayed), the publisher may call `pbjs.triggerBilling(winningAdIdToBill)` with the winning bid to be billed, which would trigger a bid adapters onBidBillable method. + ## Related Topics - The [AdUnit Reference](/dev-docs/adunit-reference.html) From 0087ff0e4bbf73a89982a921e39889a3cc47cba4 Mon Sep 17 00:00:00 2001 From: Volodymyr Pavlov <48243894+grakholsky@users.noreply.github.com> Date: Mon, 15 May 2023 21:21:01 +0300 Subject: [PATCH 222/762] adtrgtme: update adapter params (#4531) * adtrgtme: add bid param site_id * adtrgtme: update bid param example site_id --- dev-docs/bidders/adtrgtme.md | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/dev-docs/bidders/adtrgtme.md b/dev-docs/bidders/adtrgtme.md index c0af0853..e6d969d5 100644 --- a/dev-docs/bidders/adtrgtme.md +++ b/dev-docs/bidders/adtrgtme.md @@ -24,3 +24,11 @@ sidebarType: 1 ### Note: The Adtrgtme bidding adapter requires setup before beginning. Please contact us at info@adtarget.me + +### Bid Params + +{: .table .table-bordered .table-striped } + +| Name | Scope | Description | Example | Type | +|-----------|----------|-------------|--------------|----------| +| `site_id` | required | Site ID | `1234567890` | `uint64` | \ No newline at end of file From 6371e353b533b091eafc8d1b14486314178b1dc1 Mon Sep 17 00:00:00 2001 From: Jason Quaccia Date: Mon, 15 May 2023 13:45:01 -0700 Subject: [PATCH 223/762] fix for defer billing docs (#4570) --- dev-docs/bidder-adaptor.md | 2 +- dev-docs/publisher-api-reference/triggerBilling.md | 4 ++-- features/InterstitialAds.md | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/dev-docs/bidder-adaptor.md b/dev-docs/bidder-adaptor.md index f3ba6622..1f1ea8a2 100644 --- a/dev-docs/bidder-adaptor.md +++ b/dev-docs/bidder-adaptor.md @@ -610,7 +610,7 @@ Sample data received by this function: ### Registering on Bid Billable -The `onBidBillable` function will be called when it deems a bid to be billable. When a bid wins, it is by default also billable. That is, by default, onBidWon and onBidBillable will be called one after the other. However, a publisher can flag adUnits as being separately billable: `pbjs.addAdUnits({deferBilling: true, ...})`. Winning bids for adUnits with `deferBilling` set to true, trigger the onBidWon function but not the onBidBillable function. When appropriate (e.g. an interstitial is displayed), the publisher may then call the public API method, `pbjs.triggerBilling(winningAdIdToBill)` passing the winning bid to be billed, which will trigger onBidBillable. +The `onBidBillable` function will be called when it deems a bid to be billable. When a bid wins, it is by default also billable. That is, by default, onBidWon and onBidBillable will be called one after the other. However, a publisher can flag adUnits as being separately billable: `pbjs.addAdUnits({deferBilling: true, ...})`. Winning bids for adUnits with `deferBilling` set to true, trigger the onBidWon function but not the onBidBillable function. When appropriate (e.g. an interstitial is displayed), the publisher may then call the public API method, `pbjs.triggerBilling(winningBidObjectToBill)` passing the winning bid to be billed, which will trigger onBidBillable. Sample data received by this function (same as what is recieved for onBidWon): diff --git a/dev-docs/publisher-api-reference/triggerBilling.md b/dev-docs/publisher-api-reference/triggerBilling.md index ab44945a..f6e96bd0 100644 --- a/dev-docs/publisher-api-reference/triggerBilling.md +++ b/dev-docs/publisher-api-reference/triggerBilling.md @@ -10,7 +10,7 @@ Allows a publisher the option to manually trigger billing for a winning bid (The {% highlight js %} -pbjs.triggerBilling(winningAdIdToBill); +pbjs.triggerBilling(winningBidObjectToBill); {% endhighlight %} @@ -19,7 +19,7 @@ Note: In order to use `pbjs.triggerBilling`, the following is also required. - Any bid adapters a publisher integrates with must include the onBidBillable(bid) method which will be invoked by Prebid.js when it deems a bid to be billable (When a bid wins, it is by default also billable. That is, by default, Prebid.js will invoke onBidWon and onBidBillable one after the other). - A publisher must flag all adUnits as being separately billable via the deferBilling key: `pbjs.addAdUnits({deferBilling: true, ...})` (Setting deferBilling to true will trigger onBidWon but not onBidBillable). -- When appropriate (e.g. an interstitial is displayed), the publisher may call `pbjs.triggerBilling(winningAdIdToBill)`, which would then trigger onBidBillable. +- When appropriate (e.g. an interstitial is displayed), the publisher may call `pbjs.triggerBilling(winningBidObjectToBill)`, which would then trigger onBidBillable.
diff --git a/features/InterstitialAds.md b/features/InterstitialAds.md index d943385a..e8766372 100644 --- a/features/InterstitialAds.md +++ b/features/InterstitialAds.md @@ -83,7 +83,7 @@ Optimizing when billing occurs for an interstitial ad can sometimes be tricky. - When a bid wins, it is by default also billable. That is, by default, Prebid.js will invoke the bid adapter methods onBidWon and onBidBillable one after the other. - A publisher can flag individual adUnits as being separately billable with the following configuration: `pbjs.addAdUnits({deferBilling: true, ...})` - Winning bids for adUnits with deferBilling set to true will trigger a bid adapters onBidWon method but not their onBidBillable method. -- Finally, when appropriate (e.g. an interstitial is displayed), the publisher may call `pbjs.triggerBilling(winningAdIdToBill)` with the winning bid to be billed, which would trigger a bid adapters onBidBillable method. +- Finally, when appropriate (e.g. an interstitial is displayed), the publisher may call `pbjs.triggerBilling(winningBidObjectToBill)` with the winning bid to be billed, which would trigger a bid adapters onBidBillable method. ## Related Topics From 97b9e087117c17c23197fe1acc920b94bb809616 Mon Sep 17 00:00:00 2001 From: Patrick Loughrey Date: Mon, 15 May 2023 16:45:37 -0400 Subject: [PATCH 224/762] Triplelift Bidder Docs: Clarifying Native Support (#4569) * TL-34447 Add GPP Support to Prebid.org * TL-27059: Added pDMP documentation * Update triplelift.md * Triplelift: Update video params * Triplelift: Clarifying native documentation * Triplelift: Clarifying native documentation --------- Co-authored-by: bretg --- dev-docs/bidders/triplelift_native.md | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/dev-docs/bidders/triplelift_native.md b/dev-docs/bidders/triplelift_native.md index cb2e77f1..4085b6e4 100644 --- a/dev-docs/bidders/triplelift_native.md +++ b/dev-docs/bidders/triplelift_native.md @@ -14,7 +14,7 @@ userIds: criteo, identityLink, unifiedId prebid_member: true safeframes_ok: true deals_supported: true -pbjs: true +pbjs: false pbs: true pbs_app_supported: true fpd_supported: true @@ -23,9 +23,10 @@ sidebarType: 1 --- {: .alert.alert-info :} -The Triplelift Prebid Server bidding adapter and user sync endpoint require setup before beginning. Please contact us at prebid@triplelift.com. +This is a Prebid Server adapter for running component native only. For the standard Prebid JS Triplelift bid adapter, see the "Triplelift" bidder. If you are interested in running component native via Prebid JS, please contact us at prebid@triplelift.com. -This is a Prebid Server adapter for running component native only. For the standard Prebid JS Triplelift bid adapter, see the "Triplelift" bidder. +{: .alert.alert-info :} +The Triplelift Prebid Server bidding adapter and user sync endpoint require setup before beginning. Please contact us at prebid@triplelift.com. ### Table of Contents From 063deed22b69349aaab79e0497b525b162d75aea Mon Sep 17 00:00:00 2001 From: bretg Date: Mon, 15 May 2023 17:44:05 -0400 Subject: [PATCH 225/762] mobile fixes (#4572) --- _data/sidebar.yml | 6 +++--- _layouts/home.html | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/_data/sidebar.yml b/_data/sidebar.yml index 7b85c62d..0bba0c02 100644 --- a/_data/sidebar.yml +++ b/_data/sidebar.yml @@ -761,7 +761,7 @@ subgroup: 2 - sbSecId: 2 - title: Prebid Utilities + title: Prebid Utility Functions link: /prebid-mobile/pbm-api/ios/pbm-util-ios.html isHeader: 0 isSectionHeader: 0 @@ -778,7 +778,7 @@ subgroup: 3 - sbSecId: 2 - title: Code Integration + title: SDK Integration link: /prebid-mobile/pbm-api/android/code-integration-android.html isHeader: 0 isSectionHeader: 0 @@ -786,7 +786,7 @@ subgroup: 3 - sbSecId: 2 - title: GAM Original API + title: GAM Original Integration link: /prebid-mobile/pbm-api/android/android-sdk-integration-gam-original-api.html isHeader: 0 isSectionHeader: 0 diff --git a/_layouts/home.html b/_layouts/home.html index fec6c2de..19af7069 100644 --- a/_layouts/home.html +++ b/_layouts/home.html @@ -40,7 +40,7 @@

Prebid Documentation

Prebid Mobile SDK

Lightweight SDK enabling app publishers to move beyond the waterfall

View Docs -

Download Mobile SDK

+

Download Mobile SDK

From 6aa84b8193e8d98c8d804cc8598bbec9096e137a Mon Sep 17 00:00:00 2001 From: bretg Date: Tue, 16 May 2023 12:45:12 -0400 Subject: [PATCH 226/762] disabling openxoutstream from download (#4577) --- dev-docs/bidders/openxoutstream.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/dev-docs/bidders/openxoutstream.md b/dev-docs/bidders/openxoutstream.md index e5a304ac..7602e7dd 100644 --- a/dev-docs/bidders/openxoutstream.md +++ b/dev-docs/bidders/openxoutstream.md @@ -9,8 +9,11 @@ prebid_member: true coppa_supported: true gvl_id: 69 sidebarType: 1 +enable_download : false --- +{: .alert.alert-warning :} +Deprecated adapter ### Bid Params From f1b618d12b1c41e9ca5055136d57cd4857f429c6 Mon Sep 17 00:00:00 2001 From: Andrew Date: Tue, 16 May 2023 18:43:46 -0700 Subject: [PATCH 227/762] document new plcmt field (#4550) * document new plcmt field * Update dev-docs/adunit-reference.md Co-authored-by: Muki Seiler --------- Co-authored-by: Muki Seiler --- dev-docs/adunit-reference.md | 1 + 1 file changed, 1 insertion(+) diff --git a/dev-docs/adunit-reference.md b/dev-docs/adunit-reference.md index b1476368..88213cc1 100644 --- a/dev-docs/adunit-reference.md +++ b/dev-docs/adunit-reference.md @@ -104,6 +104,7 @@ See [Prebid Native Implementation](/prebid/native-implementation.html) for detai | `context` | Recommended | String | The video context, either `'instream'`, `'outstream'`, or `'adpod'` (for long-form videos). Example: `context: 'outstream'`. Defaults to 'instream'. | | `useCacheKey` | Optional | Boolean | Defaults to `false`. While context `'instream'` always will return an vastUrl in bidResponse, `'outstream'` will not. Setting this `true` will use cache url defined in global options also for outstream responses. | | `placement` | Recommended | Integer | 1=in-stream, 2=in-banner, 3=in-article, 4=in-feed, 5=interstitial/floating. **Highly recommended** because some bidders require more than context=outstream. | +| `plcmt` | Recommended | Integer | 1=in-stream, 2=accompanying content, 3=interstitial, 4=no content/standalone. **Highly recommended** to comply with new IAB video specifications. See [AdCOM v1 spec](https://github.com/InteractiveAdvertisingBureau/AdCOM/blob/develop/AdCOM%20v1.0%20FINAL.md#list_plcmtsubtypesvideo) | | `playerSize` | Optional | Array[Integer,Integer] | The size (width, height) of the video player on the page, in pixels. Example: `playerSize: [640, 480]` | | `api` | Recommended | Array[Integer] | List of supported API frameworks for this impression. If an API is not explicitly listed, it is assumed not to be supported. For list, see [OpenRTB 2.5 spec][openRTB]. If your video player or video ads SDK supports [Open Measurement][OpenMeasurement], **recommended** to set `7` for OMID-1| | `mimes` | Recommended | Array[String] | Content MIME types supported, e.g., `"video/x-ms-wmv"`, `"video/mp4"`. **Required by OpenRTB when using [Prebid Server][pbServer]**. | From 11f9477a77429a228a5c20c9c430a4c1a4967319 Mon Sep 17 00:00:00 2001 From: Jason Quaccia Date: Wed, 17 May 2023 06:58:49 -0700 Subject: [PATCH 228/762] Added code example for how to use pbjs.triggerBilling (#4573) * fix for defer billing docs * added defer billing coding example to show usage * copy update * updated docs for pbjs.triggerBilling method --- .../publisher-api-reference/triggerBilling.md | 70 ++++++++++++++++--- 1 file changed, 62 insertions(+), 8 deletions(-) diff --git a/dev-docs/publisher-api-reference/triggerBilling.md b/dev-docs/publisher-api-reference/triggerBilling.md index f6e96bd0..bb84d585 100644 --- a/dev-docs/publisher-api-reference/triggerBilling.md +++ b/dev-docs/publisher-api-reference/triggerBilling.md @@ -6,20 +6,74 @@ sidebarType: 1 --- -Allows a publisher the option to manually trigger billing for a winning bid (The winning bid to be billed is passed through the function below as an argument). - -{% highlight js %} - -pbjs.triggerBilling(winningBidObjectToBill); - -{% endhighlight %} +Allows a publisher the option to manually trigger billing for a winning bid or bids when ready to do so. {: .alert.alert-warning :} -Note: In order to use `pbjs.triggerBilling`, the following is also required. +Note: In order to use `pbjs.triggerBilling`, see the following bullet points below: - Any bid adapters a publisher integrates with must include the onBidBillable(bid) method which will be invoked by Prebid.js when it deems a bid to be billable (When a bid wins, it is by default also billable. That is, by default, Prebid.js will invoke onBidWon and onBidBillable one after the other). - A publisher must flag all adUnits as being separately billable via the deferBilling key: `pbjs.addAdUnits({deferBilling: true, ...})` (Setting deferBilling to true will trigger onBidWon but not onBidBillable). - When appropriate (e.g. an interstitial is displayed), the publisher may call `pbjs.triggerBilling(winningBidObjectToBill)`, which would then trigger onBidBillable. +See below for an example of how triggerBilling can be used: + +{: .alert.alert-warning :} +Note: The logic to decide when to invoke `pbjs.triggerBilling` is open-ended. One common use case could be to listen for an "on view" event emitted from your ad server.

For instance, the example below listens for GPT's "impressionViewable" event to determine if a deferred ad unit has become visible and is therefore ready for billing. The utilized approach to determine when to invoke `pbjs.triggerBilling` should be customized to your specific needs (For more on GPT's "impressionViewable" event, see: [https://developers.google.com/publisher-tag/reference#googletag.events.impressionviewableevent](https://developers.google.com/publisher-tag/reference#googletag.events.impressionviewableevent)).

Additionally, the example below takes into account the possibility of multiple deferred ad units being present on a page that could potentially invoke the triggerBilling function (see the "deferredAdUnitIds" variable in the snippet below). The amount of deferred ad units needed on a page are dependent on your needs and could vary. + +{% highlight js %} +... + +var adUnits = [ + { + code: "deferred-ad-element-id-1", + deferBilling: true, // decide whether an ad unit should be deferred + ... + }, + { + code: "deferred-ad-element-id-2", + deferBilling: true, // decide whether an ad unit should be deferred + ... + } +]; + +pbjs.que.push(function () { // standard prebid configuration + pbjs.addAdUnits(adUnits); + pbjs.requestBids({ + bidsBackHandler: sendAdserverRequest, + timeout: 1000, + }); +}); + +function sendAdserverRequest(bids, timedOut, auctionId) { + let winningBidsWithDeferredAdUnits = []; // bids associated with deferred ad units that win the Prebid auction will be added to this array (there could be one or many winning bids) + let deferredAdUnitIds = ['deferred-ad-element-id-1', 'deferred-ad-element-id-2']; // enter the ad unit ids you would like to defer billing for (there could be one or many deferred ad unit ids) + + deferredAdUnitIds.forEach(deferredAdUnitId => { + if (bids[deferredAdUnitId]) { + // confirm each deferred ad unit came back with the bid responses + pbjs.onEvent("bidWon", (bid) => { + if (bid.adUnitCode === deferredAdUnitId) { + // confirm bid for deferred ad unit has won + winningBidsWithDeferredAdUnits.push(bid); + } + }); + } + }); + + // next, run some custom logic to detect if a publisher is ready to trigger billing (ex: the ad unit became visible). + // note: the following code block inside of the "impressionViewable" event listener is just one example of how to trigger billing for deferred ad units by utilizing GPT's "impressionViewable" event. + googletag.pubads().addEventListener("impressionViewable", (event) => { + const adSlotId = event.slot.getSlotElementId(); + winningBidsWithDeferredAdUnits.find(bid => { + if (bid.adUnitCode === adSlotId) { // confirm if the ad slot that became viewable was a deferred ad slot + pbjs.triggerBilling(bid); + } + }); + }); +} + +... + +{% endhighlight %}
From b02f6118f567732eab567524f688bb9fd7893e4c Mon Sep 17 00:00:00 2001 From: Gen Whitt <107279666+genwhittTTD@users.noreply.github.com> Date: Wed, 17 May 2023 18:47:15 -0400 Subject: [PATCH 229/762] Edits to the Unified ID 2.0 page. (#4576) --- .../modules/userid-submodules/unified2.md | 94 +++++++++++-------- 1 file changed, 54 insertions(+), 40 deletions(-) diff --git a/dev-docs/modules/userid-submodules/unified2.md b/dev-docs/modules/userid-submodules/unified2.md index cc410d5b..058e5b1b 100644 --- a/dev-docs/modules/userid-submodules/unified2.md +++ b/dev-docs/modules/userid-submodules/unified2.md @@ -5,82 +5,96 @@ description: Unified ID 2.0 User ID sub-module useridmodule: uid2IdSystem --- +Unified ID 2.0 (UID2) is an open-source identity solution built for the open internet. It leverages encrypted email and phone number data to provide a privacy-conscious, secure, and accurate identity standard for the entire digital advertising ecosystem. -Unified ID 2 (often just called 'UID2') is an email based id solution that is owned and operated by the prebid community. Unified ID 2 relies on user consent before an id can be added to the bid stream. Consent can be gathered by SSO providers who have integrated against the UID2 framework, or Publishers own login & consent mechaninism. +UID2 relies on user consent before an ID can be added to the bid stream. Consent can be gathered by SSO providers who have integrated against the UID2 framework, or through a publisher's own login and consent mechanism. -Add it to your Prebid.js package with: +To add UID2 to your Prebid.js package, run the following: {: .alert.alert-info :} gulp build --modules=uid2IdSystem -## Unified ID Registration +## Unified ID 2.0 Registration -You can set up Unified ID 2 in one of these ways: +You can set up Unified ID 2.0 in one of these ways: -- Include the module to your pb.js wrapper. You will need to apply for Publisher access to the UID2 system at [The Trade Desk's UID2 portal](https://www.thetradedesk.com/us/about-us/industry-initiatives/unified-id-solution-2-0#request-access). Using this option, you will need to generate UID2 tokens server-side (there is currently no client-side-only flow without using an SSO provider). You provide these tokens to Prebid.js either using a cookie or directly in configuration. -- Utilize a [managed services](https://prebid.org/product-suite/managed-services/) company who can do this for you. +- Include the module to your pb.js wrapper. You will need to apply for publisher access [on the UID2 website](https://unifiedid.com/request-access). Using this option, you must generate UID2 tokens server-side. There is currently no flow for client-side only, unless you use an SSO provider. You provide these tokens to Prebid.js either by using a cookie or directly in the configuration. +- Use a [managed services](https://prebid.org/product-suite/managed-services/) company that can do this for you. -Each publisher’s privacy policy should take UnifiedId 2 into account. +Each publisher’s privacy policy should take UnifiedID 2.0 into account. -## Unified ID 2 Tokens +## Unified ID 2.0 Tokens -UID2 tokens are generated on the server-side by making an API call to a UID2 operator using details provided when you receive UID2 Publisher access. This API will return a JSON data structure with multiple values, including an advertising token and a refresh token. For full functionality, the entire object should be provided, either JSON-encoded as a server-set cookie or by being included in the configuration object (see examples). +UID2 tokens are generated on the server side by making an API call to a UID2 operator using details provided when you receive UID2 publisher access. This API returns a JSON data structure with multiple values, including an advertising token and a refresh token. For full functionality, provide the entire object in one of these ways: +- JSON-encoded as a cookie. +- Included in the configuration object. -Sample token response object: +For examples, see [Unified ID 2.0 Examples](#unified-id-20-examples). -`{`
  `"advertising_token": "...",`
  `"refresh_token": "...",`
  `"identity_expires": 1633643601000,`
  `"refresh_from": 1633643001000,`
  `"refresh_expires": 1636322000000,`
  `"refresh_response_key": "wR5t6HKMfJ2r4J7fEGX9Gw=="`
`}` +The following sample is fictitious, but shows what the token response object looks like: -When this full data structure is provided, the module will automatically refresh the token periodically, as long as the refresh token hasn't expired. +```javascript +{ + "advertising_token": "...", + "refresh_token": "...", + "identity_expires": 1633643601000, + "refresh_from": 1633643001000, + "refresh_expires": 1636322000000, + "refresh_response_key": "wR5t6HKMfJ2r4J7fEGX9Gw==" +} +``` -## Unified ID 2 Legacy Mode +When this full data structure is provided, the module automatically refreshes the token periodically, as long as the refresh token hasn't expired. -There is a legacy mode where either the value of the advertising token can be provided directly (see the `value` param in the *Configuration* section), or via a legacy cookie. In this mode, no attempt is made to automatically refresh the token. +## Unified ID 2.0 Server-Only Mode -To use the cookie-based legacy mode, set a cookie named `__uid2_advertising_token` to the value of the advertising token only. For example: +There is a server-only mode where the value of the advertising token can be provided either directly (see the `value` parameter in the [Unified ID 2.0 Configuration](#unified-id-20-configuration) section) or via a cookie. In this mode, no attempt is made to automatically refresh the token. + +To use the cookie-based server-only mode, set a cookie named `__uid2_advertising_token` to the value of the advertising token only, as shown in this fictitious example: `__uid2_advertising_token=eb33b0cb-8d35-4722-b9c0-1a31d4064888` -## Unified ID 2 Configuration +## Unified ID 2.0 Configuration -The below parameters apply only to the UID 2.0 User ID Module integration. +The following parameters apply only to the Unified ID 2.0 module integration. {: .table .table-bordered .table-striped } | Param under userSync.userIds[] | Scope | Type | Description | Example | | --- | --- | --- | --- | --- | -| name | Required | String | ID value for the UID20 module - `"uid2"` | `"uid2"` | -| params.uid2Token | Optional | Object | The initial UID2 token. This should be `body` element of the decrypted response from a call to the `/token/generate` or `/token/refresh` endpoint. | See the sample token above. | -| params.uid2ServerCookie | Optional | String | The name of a cookie which holds the initial UID2 token, set by the server. The cookie should contain JSON in the same format as the alternative uid2Token param. **If uid2Token is supplied, this param is ignored.** | See the sample token above. | +| name | Required | String | ID value for the Unified ID 2.0 module - `"uid2"` | `"uid2"` | +| params.uid2Token | Optional | Object | The initial UID2 token. This should be the `body` element of the decrypted response from a call to the `/token/generate` or `/token/refresh` endpoint. | See the sample token above. | +| params.uid2ServerCookie | Optional | String | The name of a cookie that holds the initial UID2 token, set by the server. The cookie should contain JSON in the same format as the alternative uid2Token param. **If uid2Token is supplied, this param is ignored.** | See the sample token above. | | params.uid2ApiBase | Optional | String | Overrides the default UID2 API endpoint. | `https://prod.uidapi.com` _(default)_ | -| value | Not recommended | Object | Used only if the page has a separate mechanism for storing the UID 2.O ID. The value is an object containing the values to be sent to the adapters. In this scenario, no URL is called and nothing is added to local storage. Tokens will **not** be automatically refreshed. | `{"uid2": { "id": "eb33b0cb-8d35-4722-b9c0-1a31d4064888"}}` | +| value | Not recommended | Object | Used only if the page has a separate mechanism for storing the UID 2.0 ID. The value is an object containing the values to be sent to the adapters. In this scenario, no URL is called and nothing is added to local storage, and the tokens are **not** automatically refreshed. | `{"uid2": { "id": "eb33b0cb-8d35-4722-b9c0-1a31d4064888"}}` | -## Unified ID 2 Example +## Unified ID 2.0 Examples -Publisher has set a server-side cookie called `uid2_identity` containing the UID2 token generation response object: +In the following example, the publisher has set a cookie called `uid2_identity` containing the UID2 token generation response object: {% highlight javascript %} pbjs.setConfig({ - userSync: { - userIds: [{ - name: 'uid2', - params: { - uid2ServerCookie: 'uid2_identity' - } - }] - } + userSync: { + userIds: [{ + name: 'uid2', + params: { + uid2ServerCookie: 'uid2_identity' + } + }] + } }); {% endhighlight %} -Publisher has retrieved a server-generated UID2 response and it is currently stored in the JavaScript variable `uid2Identity`: +In the following example, the publisher has retrieved a server-generated UID2 response, and it is currently stored in the JavaScript variable `uid2Identity`: {% highlight javascript %} pbjs.setConfig({ - userSync: { - userIds: [{ - name: 'uid2', - params: { - uid2Token: uid2Identity - } - }] - } + userSync: { + userIds: [{ + name: 'uid2', + params: { + uid2Token: uid2Identity + } + }] + } }); {% endhighlight %} From 7d961c50c26c4bba686c8e50697631fdc6565772 Mon Sep 17 00:00:00 2001 From: Ilia Medvedev Date: Thu, 18 May 2023 05:48:30 +0600 Subject: [PATCH 230/762] New adapter: Adsyield (#4533) --- dev-docs/bidders/adsyield.md | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/dev-docs/bidders/adsyield.md b/dev-docs/bidders/adsyield.md index d4264a96..645ea7dc 100644 --- a/dev-docs/bidders/adsyield.md +++ b/dev-docs/bidders/adsyield.md @@ -3,6 +3,7 @@ layout: bidder title: AdsYield description: Prebid AdsYield Bidder Adaptor pbjs: true +pbs: true biddercode: adsyield aliasCode: admixer media_types: video @@ -14,6 +15,13 @@ sidebarType: 1 ### Bid Params {: .table .table-bordered .table-striped } -| Name | Scope | Description | Example | Type | -|---------------|----------|------------------------------------------------------------------------------------------------------------------|----------------------------------------|----------| -| `zone` | required | The unique identifier of the ad placement. Could be obtained from the AdsYield UI or from your account manager. | "e5ff8e48-4bd0-4a2c-9236-55530ab8981d" | `string` | + +| Name | Scope | Description | Example | Type | +|---------------|----------|-----------------------------------------------------------------------------------------------------------------|------------------------------------------|-----------| +| `zone` | required | The unique identifier of the ad placement. Could be obtained from the AdsYield UI or from your account manager. | `'e5ff8e48-4bd0-4a2c-9236-55530ab8981d'` | `string` | +| `host` | required | Ad network's RTB host | `'open-adsyield.com'` | `string` | +| `publisherId` | required | Publisher ID | `12345` | `integer` | + +Adsyield server-side Prebid Server adapter requires only `publisherId` and `host` parameters. But Adsyield client-side Prebid.js adapter requires only `zone`. + +Adsyield server-side Prebid Server adapter supports only `banner`, `video`, `audio`, `native` media types. But Adsyield client-side Prebid.js adapter supports only `video` media types, doesn't support `banner`, `audio` and `native`. From 0b0295116104007c1efbb6bb0a5c5a815d87a881 Mon Sep 17 00:00:00 2001 From: prebid-sp <131664583+prebid-sp@users.noreply.github.com> Date: Thu, 18 May 2023 05:24:18 +0530 Subject: [PATCH 231/762] added silverpush adapter docs (#4510) * added silverpush adapter docs * Remove
from table * added table classes for video params doc --------- Co-authored-by: Amit Jangra Co-authored-by: Muki Seiler --- dev-docs/bidders/silverpush.md | 133 +++++++++++++++++++++++++++++++++ 1 file changed, 133 insertions(+) create mode 100644 dev-docs/bidders/silverpush.md diff --git a/dev-docs/bidders/silverpush.md b/dev-docs/bidders/silverpush.md new file mode 100644 index 00000000..51458be1 --- /dev/null +++ b/dev-docs/bidders/silverpush.md @@ -0,0 +1,133 @@ +--- +layout: bidder +title: Silverpush +description: Prebid Silverpush Bidder Adaptor +pbjs: true +pbs: true +biddercode: silverpush +media_types: banner, video +schain_supported: true +gdpr_supported: true +usp_supported: true +coppa_supported: true +gpp_supported: true +floors_supported: true +userIds: +prebid_member: false +fpd_supported: false +multiformat_supported: will-bid-on-one +sidebarType: 1 +--- + +### Registration +The Example Bidding adapter requires setup before beginning. Please contact us at prebid@silverpush.co. + + +### Bid Parameters + +#### Banner + +{: .table .table-bordered .table-striped } +| Name | Scope | Description | Example | Type | +| -------------- | ----------- | ------------------------------------------ | ------------- | ------------ | +| `publisherId` | required | Publisher id provided by silverpush | "123456" | String | +| `bidFloor` | optional | Minimum price in USD. bidFloor applies to a specific unit. For example, use the following value to set a $1.50 floor: 1.50.
| 1.50 | Number | + + +#### mediaTypes.banner + +The following banner parameters are supported here so publishers may fully declare their banner inventory: + +{: .table .table-bordered .table-striped } +| Name | Scope | Description | Example | Type | +| --------- | ------------| ----------------------------------------------------------------- | --------- | --------- | +| sizes | required | Avalaible sizes supported for banner ad unit | [ [300, 250], [300, 600] ] | [[Integer, Integer], [Integer, Integer]] | + + +### AdUnit Format for Banner +```javascript +const adUnits = [{ + code: 'div-1', + mediaTypes: { + banner: { + sizes: [ [300, 250], [300,600] ] + } + }, + bids: [{ + bidder: 'silverpush', + params: { + publisherId: "123456", + bidFloor: 1.2 + } + }] +}]; +``` + +#### Video + +{: .table .table-bordered .table-striped } +| Name | Scope | Description | Example | Type | +| ---- | ----- | ----------- | ------- | ---- | +| `publisherId` | required | Publisher id provided by silverpush | "123456" | String | +| `bidFloor` | optional | Minimum price in USD. bidFloor applies to a specific unit. For example, use the following value to set a $1.50 floor: 1.50. | 1.50 | Number | + +#### mediaTypes.video + + +The following video parameters are supported here so publishers may fully declare their video inventory: + +{: .table .table-bordered .table-striped } +| Name | Scope | Description | Example | Type | +| --------- | ------------| ----------------------------------------------------------------- | --------- | --------- | +| context | required | instream or outstream |"outstream" | string | +| playerSize | required | Avalaible sizes supported for video ad unit. | [300, 250] | [Integer, Integer] | +| mimes | required | List of content MIME types supported by the player. | ["video/mp4"]| [String]| +| protocols | required | Supported video bid response protocol values. | [2,3,5,6] | [integers]| +| api | required | Supported API framework values. | [2] | [integers] | +| maxduration | required | Maximum video ad duration in seconds. | 30 | Integer | +| minduration | required | Minimum video ad duration in seconds. | 6 | Integer | +| startdelay | required | Indicates the start delay in seconds for pre-roll, mid-roll, or post-roll ad placements. | 0 | Integer | +| placement | required | Placement type for the impression. | 1 | Integer | +| minbitrate | optional | Minimum bit rate in Kbps. | 300 | Integer | +| maxbitrate | optional | Maximum bit rate in Kbps. | 9600 | Integer | +| playbackmethod | optional | Playback methods that may be in use. Only one method is typically used in practice. | [2]| [Integers] | +| linearity | optional | OpenRTB2 linearity. in-strea,overlay... | 1 | Integer | +| skip | optional | Indicates if the player will allow the video to be skipped, where 0 = no, 1 = yes . | 1 | Integer | +| skipafter | optional | Number of seconds a video must play before skipping is enabled; only applicable if the ad is skippable. | 5 | Integer | +| delivery | optional | OpenRTB2 delivery. Supported delivery methods (e.g., streaming, progressive). If none specified, assume all are supported. | 1 | [Integer] | + + + + +### AdUnit Format for Video +```javascript +var videoAdUnits = [{ + code: 'video-1', + mediaTypes: { + video: { + api: [1, 2, 4, 6], + mimes: ['video/mp4'], + context: 'instream', // or 'outstream' + playerSize: [ 640, 480 ], + protocols: [4,5,6,7], + placement: 1, + minduration: 0, + maxduration: 60, + startdelay: 0 + } + }, + bids: [ + { + bidder: 'silverpush', + params: { + publisherId: "123456", + bidfloor: 2.5 + } + } + ] +}] +``` + + +## Additional Details +For any queries, reach us at prebid@silverpush.co. \ No newline at end of file From a921b0d9d42b407eba61845f4d1dfcb5cc990e49 Mon Sep 17 00:00:00 2001 From: Viktor Dreiling <34981284+3link@users.noreply.github.com> Date: Thu, 18 May 2023 15:26:00 +0200 Subject: [PATCH 232/762] Update liveintent.md (#4580) Co-authored-by: Viktor Dreiling --- dev-docs/modules/userid-submodules/liveintent.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/dev-docs/modules/userid-submodules/liveintent.md b/dev-docs/modules/userid-submodules/liveintent.md index 8f0cc8db..16f79fd6 100644 --- a/dev-docs/modules/userid-submodules/liveintent.md +++ b/dev-docs/modules/userid-submodules/liveintent.md @@ -123,6 +123,7 @@ NOTE: For optimal performance, the LiveIntent ID module should be called at ever | name | Required | String | The name of this module. | `'liveIntentId'` | | params | Required | Object | Container of all module params. || | params.publisherId |Optional| String | The unique identifier for each publisher (for existing LiveIntent customers)|`'12432415'`| +| params.distributorId |Optional| String | The unique identifier for each distributor (for existing LiveIntent customers). Will be ignored if `params.liCollectConfig.appId` is provided. |`'did-0123'`| | params.ajaxTimeout |Optional| Number |This configuration parameter defines the maximum duration of a call to the IdentityResolution endpoint. By default, 1000 milliseconds.|`1000`| | params.partner | Optional| String |The name of the partner whose data will be returned in the response.|`'prebid'`| | params.identifiersToResolve |Optional| Array[String] |Used to send additional identifiers in the request for LiveIntent to resolve against the LiveIntent ID.|`['my-id']`| @@ -188,6 +189,7 @@ pbjs.setConfig({ name: "liveIntentId", params: { publisherId: "9896876", + distributorId: "did-0123", identifiersToResolve: ["my-own-cookie"], url: "https://publisher.liveintent.com/idex", partner: "prebid", @@ -208,3 +210,5 @@ pbjs.setConfig({ } }) ``` + +Please note: the distributorId will be ignored when liCollectConfig.appId is present. From bc82c144e0c9c52bfac2338f0884cdf003b136b8 Mon Sep 17 00:00:00 2001 From: bretg Date: Thu, 18 May 2023 10:32:28 -0400 Subject: [PATCH 233/762] Second batch of training videos (#4571) * training videos 2.1-2.3 * fixed link * fix space * add link * making sidebar groupings consistent --------- Co-authored-by: Chris Huie --- _data/sidebar.yml | 24 +++- identity/prebid-identity-video.md | 54 +++++++++ identity/prebid-identity.md | 11 +- overview/all-videos.md | 13 +- overview/intro-video.md | 2 +- prebid-mobile/prebid-mobile-video.md | 2 +- .../overview/prebid-server-overview-video.md | 2 +- prebid/prebidjs-components-video.md | 111 ++++++++++++++++++ prebid/prebidjs-flow-video.md | 102 ++++++++++++++++ prebid/prebidjs-video.md | 8 +- 10 files changed, 312 insertions(+), 17 deletions(-) create mode 100644 identity/prebid-identity-video.md create mode 100644 prebid/prebidjs-components-video.md create mode 100644 prebid/prebidjs-flow-video.md diff --git a/_data/sidebar.yml b/_data/sidebar.yml index 0bba0c02..ee8cb8b2 100644 --- a/_data/sidebar.yml +++ b/_data/sidebar.yml @@ -136,7 +136,7 @@ sbCollapseId: prebidjs - sbSecId: 1 - title: Developer Quick Start + title: General link: isHeader: 1 headerId: devquickstart @@ -161,6 +161,22 @@ sectionTitle: subgroup: 0 +- sbSecId: 1 + title: Basic Impression Flow + link: /prebid/prebidjs-flow-video.html + isHeader: 0 + isSectionHeader: 0 + sectionTitle: + subgroup: 0 + +- sbSecId: 1 + title: Prebid.js Components + link: /prebid/prebidjs-components-video.html + isHeader: 0 + isSectionHeader: 0 + sectionTitle: + subgroup: 0 + - sbSecId: 1 title: Consent Management Best Practices link: /dev-docs/cmp-best-practices.html @@ -862,7 +878,7 @@ sbCollapseId: ad-ops - sbSecId: 3 - title: Overview + title: General link: isHeader: 1 headerId: adopsoverview @@ -1175,7 +1191,7 @@ sbCollapseId: prebid-video - sbSecId: 4 - title: Overview + title: General link: isHeader: 1 headerId: vidoverview @@ -1386,7 +1402,7 @@ sbCollapseId: prebid-server - sbSecId: 5 - title: Overview + title: General link: isHeader: 1 headerId: serveroverview diff --git a/identity/prebid-identity-video.md b/identity/prebid-identity-video.md new file mode 100644 index 00000000..746e3381 --- /dev/null +++ b/identity/prebid-identity-video.md @@ -0,0 +1,54 @@ +--- +layout: page_v2 +title: Video Intro to Prebid Identity Solutions +description: A video overview of Prebid Identity Solutions +sidebarType: 9 +--- + +# A Video Overview of Prebid Identity Solutions + +An explanation of Prebid’s user identity and consent management tools. + +
+ +Further Content: +- [User Identity Overview](/identity/prebid-identity.html) +- [SharedID](/identity/sharedid.html) +- [Prebid.js Modules](/dev-docs/modules/) +- [All Videos](/overview/all-videos.html) + +Related Videos: +- [Introduction to Prebid.js](/prebid/prebidjs-video.html) +- [Components of Prebid.js](/prebid/prebidjs-components-video.html) + +## Transcript + +### Introduction + +Prebid offers a powerful set of tools that help publishers to integrate with user identity solutions in a way that follows their organization’s privacy strategy. + +Digital media sellers need to have sophisticated practices for handling the data that describes users and audiences. To increase the value of impression opportunities surfaced to buyers, publishers may wish to transmit a pseudonymous user identifier in Prebid.js bid requests. These identifiers are a form of ad request enrichment. They can help increase the value of impression opportunities to buyers by unlocking the buyer’s ability to perform actions like frequency capping and audience targeting. + +At the same time, all members of the digital advertising supply chain have a responsibility to protect the privacy of internet users and to comply with privacy and data laws. Therefore, all sellers must develop an identity and privacy strategy that is rooted in their approach to monetization, user experience, and regulatory compliance. Prebid’s tools can be used to integrate with identity solutions and execute on an identity and privacy strategy. Prebid does not provide legal advice and makes no guarantees about compliance with any law or regulation. + +### Identity Solutions: SharedId and User ID Module + +Sellers using Prebid.js can transmit identity signals using Prebid’s SharedId service or any other major identity solution. SharedId is an open-source identity solution developed and maintained by Prebid. It stores a unique user ID in the publisher’s domain and makes it accessible to Prebid auction bidders. Bidders may then use this identifier for ad targeting, frequency capping, or other purposes. In addition to SharedId, Prebid also supports dozens of other popular identity servies. The benefits and mechanics of each service vary, and it is up to the seller to decide which providers align best with their privacy and identity strategies. + +The Prebid.js User ID Module is used to integrate SharedId and other services into Prebid.js. The providers of identity solutions build submodules that are compatible with the User ID module. The submodules allow the provider’s service to get and set identifiers and expose the identifiers to bidders. + +Publishers have complete control over which user ID submodules are included in their Prebid.js wrappers. Prebid.js also allows publishers to establish controls over user IDs, such as restricting when and how user syncing can occur during the header bidding auction. + +### Privacy Solutions: Consent Modules +Prebid.js also includes tools that allow publishers to execute on their privacy, consent, and regulatory compliance strategies. These tools work in close coordination with the User ID module and Prebid adapters to control whether, when, and how user identifiers are created or shared. + +Collectively, these tools are called Consent Management Modules. They connect to the publisher’s Consent Management Platform, or CMP to make the user’s preferences about data use available to Prebid.js and to Prebid bidders. + +Consent Management modules allow Publishers and bidders to use consent data to decide when to activate user ID modules, whether to allow bidders to perform cookie syncs, and whether or not to serve ads. + +These modules are designed to provide tools related to specific regulations, but do not guarantee compliance with any regulatory requirements. + +### Getting Started + +To learn more about the Prebid User ID Module, SharedID, and Prebid Consent Management Modules, visit docs.prebid.org + diff --git a/identity/prebid-identity.md b/identity/prebid-identity.md index d83d63b1..ade27e93 100644 --- a/identity/prebid-identity.md +++ b/identity/prebid-identity.md @@ -14,7 +14,16 @@ To do this, Prebid offers a number of identity-related products that encourage a - [Prebid.js User Identity Module](/dev-docs/modules/userId.html). This module supports more than 20 different flavors of global IDs with different features that publishers can work with. - [SharedID](/identity/sharedid.html). This native hosted ID offering from Prebid is simple, free, robust, and privacy-minded. -- **Coming soon:** [Unified ID 2.0](https://prebid.org/blog/prebid-org-to-serve-as-operator-of-unified-id-2-0/) + +## Overview + +An explanation of Prebid’s user identity and consent management tools. + +
+ +Further Reading: +- [Transcript of this video overview](/identity/prebid-identity-video.html) +- [Prebid.js Modules](/dev-docs/modules/) ## Prebid.js and Identity diff --git a/overview/all-videos.md b/overview/all-videos.md index 2d299d32..2a49c4c4 100644 --- a/overview/all-videos.md +++ b/overview/all-videos.md @@ -7,10 +7,13 @@ sidebarType: 0 # Video Overviews -These are the multi-media overviews that Prebid has created covering various aspect of Header Bidding and Prebid. +Multimedia overviews covering various aspect of Header Bidding and Prebid. 1. [Intro to Header Bidding](/overview/intro-to-header-bidding-video.html) - A high-level explanation of what header bidding is, what its benefits are, and how it works. -2. [Intro to Prebid](/overview/intro-video.html) - A high-level introduction to the Prebid community and its products. -3. [Intro to Prebid.js](/prebid/prebidjs-video.html) - A high-level overview of Prebid.js, Prebid’s header bidding product for websites. -4. [Intro to Prebid Mobile](/prebid-mobile/prebid-mobile-video.html) - A high-level overview of Prebid Mobile, Prebid’s header bidding product for iOS and Android applications. -4. [Intro to Prebid Server](/prebid-server/overview/prebid-server-overview-video.html) - A high-level overview of Prebid Server, Prebid’s solution for header bidding in the cloud. +1. [Intro to Prebid.org](/overview/intro-video.html) - A high-level introduction to the Prebid community and its products. +1. [Intro to Prebid.js](/prebid/prebidjs-video.html) - A high-level overview of Prebid.js, Prebid’s header bidding product for websites. +1. [Intro to Prebid Mobile](/prebid-mobile/prebid-mobile-video.html) - A high-level overview of Prebid Mobile, Prebid’s header bidding product for iOS and Android applications. +1. [Intro to Prebid Server](/prebid-server/overview/prebid-server-overview-video.html) - A high-level overview of Prebid Server, Prebid’s solution for header bidding in the cloud. +1. [Identity in Prebid.js](/identity/prebid-identity-video.html) - An explanation of Prebid’s user identity and consent management tools. +1. [Prebid.js Impression Flow](/prebid/prebidjs-flow-video.html) - A step-by-step walkthrough of a typical Prebid.js auction. +1. [Components of Prebid.js](/prebid/prebidjs-components-video.html) - An explanation of Prebid.js’ components and a guide to using Prebid.js reference documentation. diff --git a/overview/intro-video.md b/overview/intro-video.md index df04a354..e05aeb2a 100644 --- a/overview/intro-video.md +++ b/overview/intro-video.md @@ -22,7 +22,7 @@ Related Videos: - [Introduction to Header Bidding](/overview/intro-to-header-bidding-video.html) - [Introduction to Prebid.js](/prebid/prebidjs-video.html) - [Introduction to Prebid Mobile](/prebid-mobile/prebid-mobile-video.html) -- Introduction to Prebid Server (coming soon) +- [Introduction to Prebid Server](/prebid-server/overview/prebid-server-overview-video.html) ## Transcript diff --git a/prebid-mobile/prebid-mobile-video.md b/prebid-mobile/prebid-mobile-video.md index 098d4f84..2acd57c4 100644 --- a/prebid-mobile/prebid-mobile-video.md +++ b/prebid-mobile/prebid-mobile-video.md @@ -18,7 +18,7 @@ Further Content: Related Videos: - [Introduction to Header Bidding](/overview/intro-to-header-bidding-video.html) -- Introduction to Prebid Server (coming soon) +- [Introduction to Prebid Server](/prebid-server/overview/prebid-server-overview-video.html) ## Transcript diff --git a/prebid-server/overview/prebid-server-overview-video.md b/prebid-server/overview/prebid-server-overview-video.md index 6af75d18..8d9fa005 100644 --- a/prebid-server/overview/prebid-server-overview-video.md +++ b/prebid-server/overview/prebid-server-overview-video.md @@ -16,7 +16,7 @@ Further Content: - [Prebid Server Overview](/prebid-server/overview/prebid-server.html) - [Prebid Membership](https://prebid.org/membership) - [Prebid on Github](https://github.com/prebid) -- [All videos](/overview/all-videos.html) +- [All Videos](/overview/all-videos.html) Related Videos: - [Introduction to Header Bidding](/overview/intro-to-header-bidding-video.html) diff --git a/prebid/prebidjs-components-video.md b/prebid/prebidjs-components-video.md new file mode 100644 index 00000000..1cbf56ec --- /dev/null +++ b/prebid/prebidjs-components-video.md @@ -0,0 +1,111 @@ +--- +layout: page_v2 +title: Video Intro to Prebid.js Components +description: A video overview of Prebid.js Components +sidebarType: 1 +--- + +# A Video Overview of Prebid.js Components + +An explanation of Prebid.js’ components and a guide to using Prebid.js reference documentation. + +
+ +Further Content: +- [Ad Unit Reference](/dev-docs/adunit-reference.html) +- [Bidder Params Reference](/dev-docs/bidders.html) +- [Modules Overview](/dev-docs/modules/) +- [Analytics Overview](/overview/analytics.html) +- [Prebid.js Download](/download.html) +- [Prebid.js Configuration Reference](/dev-docs/publisher-api-reference/setConfig.html) +- [All videos](/overview/all-videos.html) + +Related Videos +- [Introduction to Prebid.js](/prebid/prebidjs-video.html) +- [Prebid.js Impression Flow](/prebid/prebidjs-flow-video.html) +- [Identity in Prebid.js](/identity/prebid-identity-video.html) + +## Transcript + +### Introduction + +This video will take a tour of Prebid.js. We’ll show you Prebid.js’ basic components and explain how they work together to serve ads. + +The video assumes that you have a basic understanding of what Prebid.js does. For some background, check out our other videos, including the Introduction to Prebid.js, and the Prebid.js Impression Flow, which walks through a Prebid.js auction step-by-step. + +A typical Prebid.js installation includes four basic components: the Prebid.js core, modules, bid adapters, and Ad Units. + +Prebid.js core components are the functional components of Prebid.js that do things like execute the auction. Prebid.js must include these components in order to work properly. + +Modules are optional components that extend Prebid.js’ capabilities. There are many different kinds of modules for purposes like ad request enrichment, analytics, consent management, and more. + +Bid adapters are functional components that allow bidders to be integrated into Prebid.js. Each bidder has its own bid adapter. + +Finally, Ad Units are where ad slots are defined within Prebid.js. They describe the characteristics of ad slots and are used to determine the set of bidders that are allowed to serve on each slot. + +Now we’ll explore modules, bid adapters, and ad units in more detail. As we go, we’ll refer to the relevant sections of the Prebid.js reference documentation, which lives at docs.prebid.org. Check the notes section below this video for links to all of the documentation referred to in the video. + +### Bid Adapters + +We’ll start with bid adapters. + +Bid adapters are plugins that enable Prebid.js to send bid requests to and receive bid responses from bidders. A company that wants to be able to compete in Prebid auctions builds their own bid adapter and contributes it to the Prebid repository + +When the Prebid auction runs, bid adapters construct a bid request into the bidder’s proprietary format. The request can include information from the Ad Unit and from other sources such as consent modules and real time data modules. + +Bid adapters also allow Prebid.js to translate each bidder’s response into a format that Prebid understands. + +### Ad Units + +An Ad Unit represents a single ad slot on a web page, and contains all the information needed for Prebid.js to request bids for the slot. + +Each ad unit has a unique identifier called an ad unit code, and includes two key blocks of information that are configured by the publisher: Media Types and Bids. + +#### Media Types + +Media Types define the ad formats that the ad placement can display, such as banner, native, or video. Within the mediaType configuration, the publisher describes the characteristics of the ad slot. + +For example, the banner ad mediaType allows the publisher to specify the dimensions of the slot, and the video mediaType lets the publisher specify whether the slot is an instream or outstream placement. + +An ad unit can include multiple mediaTypes, which makes the slot a multi-format slot. + +The Ad Unit Reference at docs.prebid.org contains detailed information about Ad Units and Media Types. + +#### Bids + +Bids is an array of bid objects: one for each bidder who is enabled to compete for the ad slot’s impression opportunities. + +To include a bidder in auctions for a given Ad Unit, the publisher adds a bid object for the bidder to the Ad Unit. + +The contents of the bid object are used to control the data that’s sent to bidders in bid requests. Bidders decide which parameters appear in their own bid objects. Common parameters are bidder-specific identifiers of the publisher, site, and ad slot. Publishers work with their bidder partners to configure these parameters. + +The Bidder Params reference is where to look for documentation on how to configure Prebid bidders parameters. + +### Modules + +Next, we’ll discuss Prebid modules, which are optional components that add extra functionality to Prebid.js. Some modules have been built by the core Prebid team, while others have been contributed by Prebid member companies and third-party developers. Modules are always open-source. In some cases, companies will develop a module to help power a Prebid-related paid service. + +There are many types of modules in Prebid. They serve many purposes and can plug into any phase of the Prebid.js auction. For more information on the auction phases, check out the Prebid.js Impression Flow video. Prebid.js Modules page at docs.prebid.org has a list of all of Prebid.js’ modules, including a short description of each one. + +In this video, we’ll focus on a few key categories of modules: + +One category is modules for ad request enrichment, which is the process of adding extra information to bid requests. Ad request enrichment can help publishers improve monetization by helping bidders evaluate impression opportunities more effectively. Enrichment data is a broad category, and can include user identifiers, seller-defined audiences, contextual targeting data, viewability signals, and more. + +Another important and commonly-used category is consent management modules. These modules allow publishers to execute on their approach to user privacy and data consent. To learn more about consent management, check out our video on Identity in Prebid.js. + +A final key category are modules commonly known as analytics adapters. These are vital for getting the best possible performance out of Prebid. Analytics adapters are used to gather information about Prebid auctions and send it to servers that will aggregate the data into reports. There are dozens of analytics adapters. A complete list of analytics adapters can be found on the Analytics for Prebid page at docs.prebid.org. + +The capabilities of Prebid’s modules go even further beyond these three key categories. For example, some modules help publishers optimize Prebid’s performance by controlling auction settings like bid timeout and price floors dynamically. More information about these can be found on the Prebid.js modules page. + +When you’re ready to build a Prebid.js wrapper with a hand-picked selection of modules, visit the Download page at docs.prebid.org. + +### Prebid.js Configuration + +As we’ve already seen, much of a Prebid.js integration’s parameters are configured inside ad units. However, there are also settings of Prebid.js that apply globally, such as general auction controls and the parameters of modules. These settings are stored in the Prebid.js configuration, which is set using the pbjs.setConfig() method. + +Many of Prebid’s most important settings live here, including bidder timeout, user sync settings, and price granularity. + +Detailed documentation of the Prebid.js configuration can be found in the publisher API reference. https://docs.prebid.org/dev-docs/publisher-api-reference/setConfig.html + +That’s it for this overview of Prebid.js for more information, check the links in the description below or visit docs.prebid.org. + diff --git a/prebid/prebidjs-flow-video.md b/prebid/prebidjs-flow-video.md new file mode 100644 index 00000000..c8c5e779 --- /dev/null +++ b/prebid/prebidjs-flow-video.md @@ -0,0 +1,102 @@ +--- +layout: page_v2 +title: Video Intro to the Prebid.js Auction +description: A video overview of a Prebid.js Auction +sidebarType: 1 +--- + +# A Video Walkthrough of a Typical Prebid.js Auction + +A step-by-step walkthrough of a typical Prebid.js auction. + +
+ +Further Content: +- [Intro to Header Bidding](/overview/intro-to-header-bidding.html) +- [Header Bidding with Prebid](/overview/intro.html#header-bidding-with-prebid) +- [What is Prebid.js?](/prebid/prebidjs.html) +- [Prebid.js Quick Start](/dev-docs/getting-started.html) +- [All videos](/overview/all-videos.html) + +Related Videos +- [Introduction to Prebid](/overview/intro-video.html) +- [Introduction to Header Bidding](/overview/intro-to-header-bidding-video.html) +- [Components of Prebid.js](/prebid/prebid-components-video.html)) +- [Identity in Prebid.js](/identity/prebid-identity-video.html) + +## Transcript + +### Introduction + +This video will walk through the steps required to serve a display ad through an ordinary Prebid.js integration. +- This is the simplest and most common type of Prebid auction. Specifically, it is a client-side auction for a display ad running in a single-format ad slot on a website that uses a primary ad server. +- There are many variations on this basic form, which include: + - Auctions for other ad formats, such as video or native + - Auctions that use Prebid Server + - Auctions that use Prebid.js without a primary ad server + - Auctions in other environments such as AMP, mobile apps, and long-form video. +- Let’s start with a high-level overview of the steps: + - When the page loads, Prebid.js loads. The page invokes Prebid.js, which goes through a three-stage process: Pre-Auction, Auction and Post Auction. + - In the Pre-Auction stage, Prebid.js gathers information that it needs to run auctions for the ad slots on the page. + - Next comes the Auction stage: + - Prebid.js makes bid requests to bidders that the publisher has selected + - The bidders respond to Prebid.js with bids + - Finally, the post-auction stage begins + - Prebid.js gathers the bids and reformats them into a format that the primary ad server will understand + - For each ad slot, requests are sent to the ad server. These requests contains information about the bids Prebid.js received. + - The ad server receives the requests and decides which of the publisher’s ad buyers should serve an ad. Prebid bidders are considered alongside other potential buyers. + - When the primary ad server selects a Prebid bidder, it returns Prebid code that renders the ad to the page. + +### Impression Flow + +Now, we’ll go through the process in detail. + +1. **Pre-Auction** + 1. The user requests the page, the publishers’ CMS is called and returns the page source, which includes instructions to load Prebid.js and begin an auction for one or more Ad Units + 1. An Ad Unit represents a unique ad slot on the page. + 1. The Ad Unit contains information about the attributes of the ad slot, such as the ad format, and dimensions. The Ad Unit also includes the list of bidders that are allowed to bid on the ad slot. + 1. In Prebid, the word “auction” refers to the process by which bids are solicited and received for one or more Ad Units. A bidder will usually receive a single HTTP request that contains information about one or more Ad Units, and the bidder is able to bid on any or all of them. + 1. Before the auction begins, Prebid.js is able to retrieve other optional information, depending on how the publisher has configured it. This information can include: + 1. User consent information from the publisher’s consent management platform + 1. Ad request enrichment data that describes the user, site, or page + 1. Price floor information + 1. And more +1. **Auction** - The auction begins. + 1. Prebid.js sends bid requests to bidders. + 1. Bidders will receive an HTTP request that contains one or more ad units. Which ad units each bidder receives depends on how the ad units are set up by the publisher. + 1. Bid requests contain information about the ad units, page, user, and auction, including the page URL, ad slot identifiers, user identifiers, first party data, consent data, supply chain data, price floors and more. + 1. A bidder’s bid adapter is the component that formats the bid requests the bidder receives. Bidders build and maintain their own bid adapters and submit them to the open-source Prebid.js repository. + 1. At this point, Prebid.js will also start a timer that it uses to enforce the publisher’s configured bid timeout. The bid timeout determines the amount of time that Prebid.js will wait to receive bidders’ responses. + 1. Bidders consider the impression opportunity. They will consult their own sources of demand and determine whether they are able to offer an ad for the opportunity. If they do, they’ll also decide upon a price they would be willing to pay. + 1. Bidders return responses. + 1. The bidder’s HTTP response contains their bids for the Ad Units in the auction. The bidder isn’t required to place a bid, and bids only on the ad units they hope to win. + 1. Responses that include a bid will contain a URL that refers to the ad’s creative, a price, and other information such as deal IDs. + 1. Bids that Prebid.js receives before the bid timeout period has elapsed are considered valid bids. The bid timeout is set by the publisher in the Prebid.js configuration. Bids not received before the bid timeout will be logged as timed-out bids. + 1. Prebid.js processes responses + 1. As Prebid.js receives responses from bidders, it processes them + 1. Bidders’ bid adapters are responsible for parsing the bidders’ responses and exposing bid information to Prebid.js. + 1. Bid processing starts with extracting information from the bid, which can include bid prices, deal IDs, and ad format information. + 1. Where necessary, Prebid.js will perform other validations or transformations like price floor enforcement or currency conversion + 1. Prebid’s auction completes when either all of the bidders have responded and Prebid has processed their bids, or when the timeout period set by the publisher has elapsed. + 1. After the auction has completed, Prebid formats the bid information as a set of key-value pairs that the primary ad server will understand. +1. **Post-Auction** + 1. With the Prebid auction complete, the ad server is called + 1. A request is sent to the primary ad server for each of the slots on the page. These requests will contain the bid key-value pairs. + 1. The ad server receives its request and evaluates the demand sources that the publisher has enabled, which includes but is not limited to Prebid bidders. + 1. Other demand sources that the ad server might consider are: + 1. Direct-sold campaigns with reservations, guarantees, or sponsorships + 1. Bids from other header bidding or programmatic sources + 1. Waterfall-style demand sources such as ad networks + 1. Each ad server works a little bit differently. For more information about how Prebid.js works with ad servers, refer to Prebid’s Ad Ops documentation. + 1. When the ad server selects a Prebid bid to serve, it returns a piece of Prebid code called a creative. + 1. **Ad Rendering** + 1. The creative triggers the ad rendering process, in which Prebid.js retrieves the bidder’s ad and renders it to the ad slot on the page. + +### Conclusion + +- So that’s how an ad is served through Prebid.js +- Publishers can measure their monetization performance, troubleshoot issues, and maximize yield by gathering data about their header bidding auctions. Prebid supports a standardized interface for analytics adapters that allows publishers to integrate header bidding analytics tools that give them the insights they need. +- Prebid.js logs events throughout the auction and ad serving process. These events are exposed to analytics adapters, and they include the start of the auction, requests to bidders, bid responses, timeouts, ad server requests, ad renders, and more. +- Tools like the Professor Prebid browser extension also have the ability to monitor Prebid.js events and can be used for troubleshooting, debugging, and optimization. +- To learn more about the Prebid Auction and about Prebid’s analytics, optimization, and troubleshooting tools, visit [docs.prebid.org](docs.prebid.org). + diff --git a/prebid/prebidjs-video.md b/prebid/prebidjs-video.md index f1f72226..bf52d839 100644 --- a/prebid/prebidjs-video.md +++ b/prebid/prebidjs-video.md @@ -2,7 +2,7 @@ layout: page_v2 title: Video Intro to Prebid.js description: A video overview of Prebid org and products -sidebarType: 0 +sidebarType: 1 --- # A Video Overview of Prebid.js @@ -21,9 +21,9 @@ Further Content: Related Videos - [Introduction to Prebid](/overview/intro-video.html) - [Introduction to Header Bidding](/overview/intro-to-header-bidding-video.html) -- Prebid.js Impression Flow (coming soon) -- Components of Prebid.js (coming soon) -- Identity in Prebid.js (coming soon) +- [Prebid.js Impression Flow](/prebid/prebidjs-flow-video.html) +- [Components of Prebid.js](/prebid/prebidjs-components-video.html) +- [Identity in Prebid.js](/identity/prebid-identity-video.html) ## Transcript From 205d291e2bb1282e7e12426ef75d79e02538bea9 Mon Sep 17 00:00:00 2001 From: bretg Date: Thu, 18 May 2023 10:38:51 -0400 Subject: [PATCH 234/762] axonix table formatting (#4584) --- dev-docs/bidders/axonix.md | 1 + 1 file changed, 1 insertion(+) diff --git a/dev-docs/bidders/axonix.md b/dev-docs/bidders/axonix.md index c4f843b3..2e9f5067 100644 --- a/dev-docs/bidders/axonix.md +++ b/dev-docs/bidders/axonix.md @@ -14,6 +14,7 @@ sidebarType: 1 The Axonix Bidding adapter requires setup before beginning. Please contact us at support.axonix@emodoinc.com. ### Bid Params + {: .table .table-bordered .table-striped } | Name | Scope | Description | Example | Type | |------------|-------|----------------------------------------------|-------------------------------------|------| From 6da7574e82fb533963271bba9538d5c8dca75efb Mon Sep 17 00:00:00 2001 From: bretg Date: Thu, 18 May 2023 16:34:02 -0400 Subject: [PATCH 235/762] update ipv6 anon (#4585) --- prebid-server/features/pbs-privacy.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/prebid-server/features/pbs-privacy.md b/prebid-server/features/pbs-privacy.md index aac617e7..be915bd6 100644 --- a/prebid-server/features/pbs-privacy.md +++ b/prebid-server/features/pbs-privacy.md @@ -85,7 +85,7 @@ If `regs.coppa` is set to '1' on the OpenRTB request, the following anonymizatio - Removes all ID fields: device.ifa, device.macsha1, device.macmd5, device.dpidsha1, device.dpidmd5, device.didsha1, device.didmd5 - Truncate ip field - remove lowest 8 bits. -- Truncate ipv6 field - remove lowest 32 bits. +- Truncate ipv6 field - anonymize as noted below. - Remove geo.lat, geo.lon. geo.metro, geo.city, and geo.zip - Remove user.id, user.buyeruid, user.yob, and user.gender From e0a380ed2ebd4881ca797ca7fbd8584f330fa580 Mon Sep 17 00:00:00 2001 From: adxcgcom <31470944+adxcgcom@users.noreply.github.com> Date: Thu, 18 May 2023 21:06:16 +0000 Subject: [PATCH 236/762] Update adxcg.md (#4581) * Update adxcg.md * remove gvlid * add back N/A gvl --------- Co-authored-by: Chris Huie --- dev-docs/analytics/adxcg.md | 28 +++++++++++++++++++++++++++- 1 file changed, 27 insertions(+), 1 deletion(-) diff --git a/dev-docs/analytics/adxcg.md b/dev-docs/analytics/adxcg.md index 527c436b..17784bc0 100644 --- a/dev-docs/analytics/adxcg.md +++ b/dev-docs/analytics/adxcg.md @@ -3,9 +3,35 @@ layout: analytics title: Adxcg description: Adxcg Analytics Adapter modulecode: adxcg +gdpr_supported: false +usp_supported: false +coppa_supported: false +prebid_member: false +gvl_id: N/A +enable_download: false --- #### Registration -Please visit [https://www.adxcg.com/](https://www.adxcg.com/) for more information. +The Adxcg analytics adapter requires setup and approval from the Adxcg team, even for existing accounts. +Please reach out to your account team or visit [https://www.adxcg.com/](https://www.adxcg.com/) for more information. + +#### Analytics Options + +{: .table .table-bordered .table-striped } +| Name | Scope | Description | Example | Type | +|-------------|---------|--------------------|-----------------------------------------------------------------------------------------------------------------------------|-------------------------------------------------------------------------------------|------------------| +| publisherId | required | The Adxcg publisher account ID | `'42'` | string | + + +### Example Configuration + +``` + pbjs.enableAnalytics({ + provider: 'adxcg', + options: { + publisherId: 'OBTAIN-FROM-ADXCG' + } + }); +``` From 24e679ae6e0b3f8956649661bdfb1c1b755c19db Mon Sep 17 00:00:00 2001 From: Marios Kosmas <110163065+mariosk5@users.noreply.github.com> Date: Fri, 19 May 2023 00:12:04 +0300 Subject: [PATCH 237/762] New adapter: Project Agora (#4567) --- dev-docs/bidders/projectagora.md | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) create mode 100644 dev-docs/bidders/projectagora.md diff --git a/dev-docs/bidders/projectagora.md b/dev-docs/bidders/projectagora.md new file mode 100644 index 00000000..908b9ccf --- /dev/null +++ b/dev-docs/bidders/projectagora.md @@ -0,0 +1,27 @@ +--- +layout: bidder +title: Project Agora +description: Prebid Project Agora Bidder Adapter +biddercode: projectagora +pbjs: true +pbs: false +aliasCode: appnexus +gdpr_supported: true +media_types: banner, video, native +gvl_id: 1032 +schain_supported: true +userId: all +sidebarType: 1 +--- +### Bid Params + +{: .table .table-bordered .table-striped } +| Name | Scope | Description | Example | Type | +|---------------|----------|-----------------------|-----------|-----------| +| `placementID` | required | Placement id | `'11111'` | `string` | + +Project Agora is an aliased bidder for AppNexus. + +### Note: + +The Project Agora bidder adapter requires setup before beginning. Please contact us at pub_support@projectagora.com. From 66cc3ada429c8d78410ab274d72448971d509339 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Miko=C5=82aj=20Robakowski?= Date: Thu, 18 May 2023 23:46:05 +0200 Subject: [PATCH 238/762] Add Eskimi bidder documentation (#4471) * Add Eskimi bidder documentation * add safeframes_ok and ortb_blocking_supported fields to eskimi bidder docs --- dev-docs/bidders/eskimi.md | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) create mode 100644 dev-docs/bidders/eskimi.md diff --git a/dev-docs/bidders/eskimi.md b/dev-docs/bidders/eskimi.md new file mode 100644 index 00000000..e1b452dd --- /dev/null +++ b/dev-docs/bidders/eskimi.md @@ -0,0 +1,24 @@ +--- +layout: bidder +title: Eskimi +description: Prebid Eskimi Bidder Adapter +pbjs: true +pbs: false +biddercode: eskimi +deals_supported: false +media_types: banner +gvl_id: 814 +sidebarType: 1 +schain_supported: true +floors_supported: true +safeframes_ok: false +ortb_blocking_supported: false +--- + + +### Bid Params + +{: .table .table-bordered .table-striped } +| Name | Scope | Description | Example | Type | +|-------------------|----------|-------------------------------|---------|------------| +| `placementId` | required | The placement ID from Eskimi. | `612` | `integer` | From 7cab5d6ed1ac7914abe795deb83a0e3f5737af26 Mon Sep 17 00:00:00 2001 From: bretg Date: Sun, 21 May 2023 10:48:32 -0400 Subject: [PATCH 239/762] adding mobile FAQ entries (#4586) --- faq/prebid-mobile-faq.md | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/faq/prebid-mobile-faq.md b/faq/prebid-mobile-faq.md index d8ee30bb..b5e9e02d 100644 --- a/faq/prebid-mobile-faq.md +++ b/faq/prebid-mobile-faq.md @@ -37,6 +37,17 @@ No. No. +### Is the SDK synchronous? + +Prebid SDK is always async. The completion handler for the main fetchDemand() method is called asynchronously when the bid response (or timeout, network error, etc.) is received. The app defines the desired timeout. + +### How long do bids remain valid? + +Prebid SDK does not support a [limited bid cache](dev-docs/faq.html#does-prebidjs-cache-bids) like Prebid.js does. Which means it's up to the app to build any kind of pre-fetch or bid-cache feature. Notes: + +1. If Prebid Cache is being utilized, the Time-To-Live for that cache should be understood. By default, the TTL for Prebid Cache is 5 minutes for banners and 15 minutes for video, but this can be changed. +2. No matter what the Cache TTL is set to, it's important that any pre-fetch or bid-cache feature built into the app should respect the OpenRTB `seatbid.bid.exp` field for each bid, which is the expiration of the bid in seconds. + ## Dependencies ### Does the SDK use third-party libraries? From de95c6f7d7293c18b5ae048717287960aed6630a Mon Sep 17 00:00:00 2001 From: Alexander Jones Date: Thu, 25 May 2023 08:04:16 -0500 Subject: [PATCH 240/762] typo (#4588) --- prebid-server/use-cases/pbs-sdk.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/prebid-server/use-cases/pbs-sdk.md b/prebid-server/use-cases/pbs-sdk.md index 8232659d..cfd5bbb3 100644 --- a/prebid-server/use-cases/pbs-sdk.md +++ b/prebid-server/use-cases/pbs-sdk.md @@ -265,7 +265,7 @@ Prebid Universal Creative loads in the webiview, which sees the `hb_env=mobile-a ### Load Ad -The Prebid Universal Crative will parse the response, looking for the `adm` object, loading the full markup into the webview. +The Prebid Universal Creative will parse the response, looking for the `adm` object, loading the full markup into the webview. ## Further Reading From ba9bf2990913e44d96bacd3669fd8c1fabd87229 Mon Sep 17 00:00:00 2001 From: Eyvaz Ahmadzada <62054743+eyvazahmadzada@users.noreply.github.com> Date: Fri, 26 May 2023 16:41:03 +0400 Subject: [PATCH 241/762] IntentIQ: added enableCookieStorage optional parameter docs (#4595) * added: enable cookie param docs * added: enableCookieStorage default value info --- dev-docs/modules/userid-submodules/intentiq.md | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/dev-docs/modules/userid-submodules/intentiq.md b/dev-docs/modules/userid-submodules/intentiq.md index 6c7487b8..e64cdedd 100644 --- a/dev-docs/modules/userid-submodules/intentiq.md +++ b/dev-docs/modules/userid-submodules/intentiq.md @@ -41,6 +41,7 @@ Please find below list of parameters that could be used in configuring Intent IQ | params.percentage | Required | Number | This a percentage value for our A/B testing group distribution. The values supposed to be in range of 0 to 100. We suggest to set it to 95 percent for optimal balance ofbetween prefromance and preceision. | `95` | | params.pcid | Optional | String | This is the partner cookie ID, it is a dynamic value attached to the request. | `"g3hC52b"` | | params.pai | Optional | String | This is the partner customer ID / advertiser ID, it is a dynamic value attached to the request. | `"advertiser1"` | +| params.enableCookieStorage | Optional | Boolean | This is a parameter allowing to enable or disable cookie storage. Defaults to false. | `"true"` | ### Configuration example @@ -53,6 +54,7 @@ pbjs.setConfig({ params: { partner: 123456, // valid partner id percentage: 95, + enableCookieStorage: true }, storage: { type: "html5", @@ -76,7 +78,8 @@ pbjs.setConfig({ partner: 123456 // valid partner id pcid: PCID_VARIABLE, // string value, dynamically loaded into a variable before setting the configuration pai: PAI_VARIABLE , // string value, dynamically loaded into a variable before setting the configuration - percentage: 95 + percentage: 95, + enableCookieStorage: false }, storage: { type: "html5", From fc9c89b0e873a8f74108e07457e9075cad3d22cc Mon Sep 17 00:00:00 2001 From: Denis Logachov Date: Fri, 26 May 2023 17:47:10 +0300 Subject: [PATCH 242/762] Adkernel: documenting diDNA display alias (#4600) --- dev-docs/bidders/didnadisplay.md | 34 ++++++++++++++++++++++++++++++++ 1 file changed, 34 insertions(+) create mode 100644 dev-docs/bidders/didnadisplay.md diff --git a/dev-docs/bidders/didnadisplay.md b/dev-docs/bidders/didnadisplay.md new file mode 100644 index 00000000..92a3a497 --- /dev/null +++ b/dev-docs/bidders/didnadisplay.md @@ -0,0 +1,34 @@ +--- +layout: bidder +title: diDNA Display +description: diDNA Display Bidder Adaptor +biddercode: didnadisplay +pbjs: true +pbs: false +media_types: banner, native, video +gdpr_supported: true +usp_supported: true +coppa_supported: true +pbs_app_supported: false +schain_supported: true +userIds: all +fpd_supported: true +prebid_member: false +ortb_blocking_supported: true +multiformat_supported: will-bid-on-one +floors_supported: true +aliasCode: adkernel +sidebarType: 1 +--- + +### Note: + +The diDNA Display bidding adapter requires setup and approval before implementation. Please reach out to for more details. + +### Bid Params + +{: .table .table-bordered .table-striped } +| Name | Scope | Description | Example | Type | +|----------|----------|-----------------------|---------------------------|----------| +| `host` | required | RTB host | `'cpm.didna.io'` | `string` | +| `zoneId` | required | Zone Id | 30164 | `integer` | From c6d13c8f8921065f762718d5a60705f2e41cb241 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 26 May 2023 08:20:05 -0700 Subject: [PATCH 243/762] Bump socket.io-parser from 4.2.1 to 4.2.3 (#4597) Bumps [socket.io-parser](https://github.com/socketio/socket.io-parser) from 4.2.1 to 4.2.3. - [Release notes](https://github.com/socketio/socket.io-parser/releases) - [Changelog](https://github.com/socketio/socket.io-parser/blob/main/CHANGELOG.md) - [Commits](https://github.com/socketio/socket.io-parser/compare/4.2.1...4.2.3) --- updated-dependencies: - dependency-name: socket.io-parser dependency-type: indirect ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- package-lock.json | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/package-lock.json b/package-lock.json index 4c7be5d2..5447d89a 100644 --- a/package-lock.json +++ b/package-lock.json @@ -10741,9 +10741,9 @@ } }, "node_modules/socket.io-parser": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/socket.io-parser/-/socket.io-parser-4.2.1.tgz", - "integrity": "sha512-V4GrkLy+HeF1F/en3SpUaM+7XxYXpuMUWLGde1kSSh5nQMN4hLrbPIkD+otwh6q9R6NOQBN4AMaOZ2zVjui82g==", + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/socket.io-parser/-/socket.io-parser-4.2.3.tgz", + "integrity": "sha512-JMafRntWVO2DCJimKsRTh/wnqVvO4hrfwOqtO7f+uzwsQMuxO6VwImtYxaQ+ieoyshWOTJyV0fA21lccEXRPpQ==", "dev": true, "dependencies": { "@socket.io/component-emitter": "~3.1.0", @@ -22034,9 +22034,9 @@ } }, "socket.io-parser": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/socket.io-parser/-/socket.io-parser-4.2.1.tgz", - "integrity": "sha512-V4GrkLy+HeF1F/en3SpUaM+7XxYXpuMUWLGde1kSSh5nQMN4hLrbPIkD+otwh6q9R6NOQBN4AMaOZ2zVjui82g==", + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/socket.io-parser/-/socket.io-parser-4.2.3.tgz", + "integrity": "sha512-JMafRntWVO2DCJimKsRTh/wnqVvO4hrfwOqtO7f+uzwsQMuxO6VwImtYxaQ+ieoyshWOTJyV0fA21lccEXRPpQ==", "dev": true, "requires": { "@socket.io/component-emitter": "~3.1.0", From b45617b16dfdb9f85047b2e5bd79ec7bfda37f77 Mon Sep 17 00:00:00 2001 From: Patrick McCann Date: Fri, 26 May 2023 12:12:20 -0400 Subject: [PATCH 244/762] Update roxot.md (#4593) --- dev-docs/analytics/roxot.md | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/dev-docs/analytics/roxot.md b/dev-docs/analytics/roxot.md index b0ab67b2..859f3ef3 100644 --- a/dev-docs/analytics/roxot.md +++ b/dev-docs/analytics/roxot.md @@ -7,5 +7,20 @@ modulecode: roxot #### Registration -Please visit [https://roxot.com/](https://roxot.com/) for more information. +To start using Prebid Analytics, please, email us at contact@roxot.com to provide us with your billing info and get your personal publisher ID which is used in the prebid config on your site/s. + +Add the following code to your prebid.js config to activate Prebid Analytics: + +#### Example Configuration +``` + +pbjs.que.push(function () { + pbjs.enableAnalytics({ + provider: 'roxot', + options: { + publisherIds: ["YOUR-PUBLISHER-ID"] + } + }); +}); +``` From 3d74491979814c5d417304843c642122cba86059 Mon Sep 17 00:00:00 2001 From: Ioan-Alexandru Stef <126675343+ioan-alexandru-stef-smaato@users.noreply.github.com> Date: Tue, 30 May 2023 20:14:11 +0300 Subject: [PATCH 245/762] Smaato: Add skadn note for AdPods (#4592) * PREB-39 added skadn note for AdPods * PREB-39 change userId to userIds --- dev-docs/bidders/smaato.md | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/dev-docs/bidders/smaato.md b/dev-docs/bidders/smaato.md index 89e5054c..dfab0ab7 100644 --- a/dev-docs/bidders/smaato.md +++ b/dev-docs/bidders/smaato.md @@ -9,7 +9,7 @@ usp_supported: true coppa_supported: true gpp_supported: true media_types: banner, video, native -userId: criteo, pubCommonId, unifiedId +userIds: all pbjs: true pbs: true pbs_app_supported: true @@ -59,6 +59,10 @@ The Smaato adapter will convert bidfloors to 'USD' currency as needed. | `adbreakId` | required | Your Smaato adbreak id. Required for adpod (long-form video) requests | `'41002234'` | `string` | | `app` | optional | Object containing mobile app parameters. See the [App Object](#smaato-app-object) for details.| `app : { ifa: '56700000-9cf0-22bd-b23e-46b96e40003a'}` | `object` | +##### Note + +In case of AdPods, the Smaato adapter will only read the first `imp[].skadn` entry for each AdPod, such that there should only be one `skadn` occurrence per AdPod. + #### App Object From 1dcea8f14bb2f483310aafd22aa471e9cd2891d1 Mon Sep 17 00:00:00 2001 From: congdu-kun <126609480+congdu-kun@users.noreply.github.com> Date: Wed, 31 May 2023 06:09:52 -0700 Subject: [PATCH 246/762] Fix a typo in pair.md (#4608) --- dev-docs/modules/userid-submodules/pair.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dev-docs/modules/userid-submodules/pair.md b/dev-docs/modules/userid-submodules/pair.md index 06715598..1c59c5bd 100644 --- a/dev-docs/modules/userid-submodules/pair.md +++ b/dev-docs/modules/userid-submodules/pair.md @@ -22,7 +22,7 @@ gulp build --modules=pairIdSystem | name | Required | String | The name of PAIR ID user ID module. | `"pairId"` | | params | Optional | Object | Container of all module params. | | | params.liveramp | Optional | Object | Container of all liveramp cleanroom specified params. | | -| params.liveramp.storageKey | Optional | String | storage key to fetch liveramp provided PAIR Id, the default key is `"_lr_pairId_"` | `"_lr_pairId_custom"` | +| params.liveramp.storageKey | Optional | String | storage key to fetch liveramp provided PAIR Id, the default value is `"_lr_pairId"` | `"_lr_pairId_custom"` | ## PAIR ID Examples From c6d5a84a48b94f33a9064bd9f3e5256d10196cbc Mon Sep 17 00:00:00 2001 From: Andrew Date: Wed, 31 May 2023 11:42:16 -0400 Subject: [PATCH 247/762] Condense prebid video docs into something more manageable. (#4549) * Condense prebid video docs into something more manageable. * Clarify what type of video is supported be prebid and video module. --- _data/sidebar.yml | 141 ---------------- prebid-video/video-module.md | 8 +- .../integration-examples/jwplayer.html | 123 ++++++++++++++ .../integration-examples/videojs.html | 150 ++++++++++++++++++ prebid-video/video-overview.md | 7 +- 5 files changed, 283 insertions(+), 146 deletions(-) create mode 100644 prebid-video/video-module/integration-examples/jwplayer.html create mode 100644 prebid-video/video-module/integration-examples/videojs.html diff --git a/_data/sidebar.yml b/_data/sidebar.yml index ee8cb8b2..ae0f05dc 100644 --- a/_data/sidebar.yml +++ b/_data/sidebar.yml @@ -1215,39 +1215,6 @@ sectionTitle: subgroup: 0 -- sbSecId: 4 - title: Getting Started with Long Form Video for Prebid.js - link: /prebid-video/video-long-form.html - isHeader: 0 - isSectionHeader: 0 - sectionTitle: - subgroup: 0 - - -- sbSecId: 4 - title: Show Video Ads with Google Ad Manager - link: /dev-docs/show-video-with-a-dfp-video-tag.html - isHeader: 0 - isSectionHeader: 0 - sectionTitle: - subgroup: 0 - -- sbSecId: 4 - title: Show OTT Video Ads with Prebid - link: /dev-docs/show-long-form-video-with-gam.html - isHeader: 0 - isSectionHeader: 0 - sectionTitle: - subgroup: 0 - -- sbSecId: 4 - title: Outstream Video Ads - link: /dev-docs/show-outstream-video-ads.html - isHeader: 0 - isSectionHeader: 0 - sectionTitle: - subgroup: 0 - - sbSecId: 4 title: Training Videos link: /videos/prebid-video.html @@ -1281,114 +1248,6 @@ sectionTitle: subgroup: 1 -- sbSecId: 4 - title: Examples - link: - isHeader: 1 - headerId: videxamples - isSectionHeader: 0 - sectionTitle: - subgroup: 2 - -- sbSecId: 4 - title: "Instream" - link: - isHeader: 0 - isSectionHeader: 0 - isCatHeader: 1 - sectionTitle: - subgroup: 2 - -- sbSecId: 4 - title: 'Prebid Video Module: VideoJS' - link: /examples/video/instream/videoModule/videojs/video-module-videojs.html - isHeader: 0 - isSectionHeader: 0 - sectionTitle: - subgroup: 2 - -- sbSecId: 4 - title: 'JW Player (Platform)' - link: /examples/video/instream/jwplayer/pb-ve-jwplayer-platform.html - isHeader: 0 - isSectionHeader: 0 - sectionTitle: - subgroup: 2 - -- sbSecId: 4 - title: 'JW Player (Self-Hosted)' - link: /examples/video/instream/jwplayer/pb-ve-jwplayer-hosted.html - isHeader: 0 - isSectionHeader: 0 - sectionTitle: - subgroup: 2 - -- sbSecId: 4 - title: 'VideoJS' - link: /examples/video/instream/videojs/pb-ve-videojs.html - isHeader: 0 - isSectionHeader: 0 - sectionTitle: - subgroup: 2 - -- sbSecId: 4 - title: "Outstream" - link: - isHeader: 0 - isSectionHeader: 0 - isCatHeader: 1 - sectionTitle: - subgroup: 2 - -- sbSecId: 4 - title: 'Basic IMA' - link: /examples/video/outstream/basic-ima.html - isHeader: 0 - isSectionHeader: 0 - sectionTitle: - subgroup: 2 - -- sbSecId: 4 - title: 'Google Ad Manager' - link: /examples/video/outstream/pb-ve-outstream-dfp.html - isHeader: 0 - isSectionHeader: 0 - sectionTitle: - subgroup: 2 - -- sbSecId: 4 - title: 'No Server' - link: /examples/video/outstream/pb-ve-outstream-no-server.html - isHeader: 0 - isSectionHeader: 0 - sectionTitle: - subgroup: 2 - -- sbSecId: 4 - title: 'No Server (Specify Renderer)' - link: /examples/video/outstream/pb-ve-outstream-no-server-specify-renderer.html - isHeader: 0 - isSectionHeader: 0 - sectionTitle: - subgroup: 2 - -- sbSecId: 4 - title: "Long-Form (Ad Pods)" - link: - isHeader: 0 - isSectionHeader: 0 - isCatHeader: 1 - sectionTitle: - subgroup: 2 - -- sbSecId: 4 - title: 'Freewheel' - link: /examples/video/long-form/pb-ve-lf-freewheel.html - isHeader: 0 - isSectionHeader: 0 - sectionTitle: - subgroup: 2 - #--------------Prebid Server--------------| - sbSecId: 5 diff --git a/prebid-video/video-module.md b/prebid-video/video-module.md index 68114e8d..d75c2dd0 100644 --- a/prebid-video/video-module.md +++ b/prebid-video/video-module.md @@ -8,7 +8,7 @@ sidebarType: 4 # The Video Module -The Prebid Video Module allows Prebid to directly integrate with a Video Player. +The Prebid Video Module allows Prebid to directly integrate with a Video Player. Currently the Video Module only supports instream implementations. The Video Module will allow Prebid.js to automatically: - render bids in the desired video player @@ -62,6 +62,12 @@ To register a video player with Prebid, you must use `setConfig` to set a `video In order for Prebid to know which Ad Unit relates to which Video Player, you must include a `video` configuration in your Ad Unit. This allows Prebid to render the ad in the proper Video Player and obtain the Ortb data from the Video Player that will render the ad. For the list of properties in the `video` object of the ad unit please visit the [adUnit.video reference]({{site.baseurl}}/dev-docs/adunit-reference.html#adUnit.video). +#### Implementation Examples + +[Video.js]({{site.baseurl}}/prebid-video/video-module/integration-examples/videojs.html) + +[JW Player]({{site.baseurl}}/prebid-video/video-module/integration-examples/jwplayer.html) + ### Features for Publishers Integrating with the Video Module gives publishers access to the following features diff --git a/prebid-video/video-module/integration-examples/jwplayer.html b/prebid-video/video-module/integration-examples/jwplayer.html new file mode 100644 index 00000000..b96d1509 --- /dev/null +++ b/prebid-video/video-module/integration-examples/jwplayer.html @@ -0,0 +1,123 @@ + + + + + + + JW Player with Playlist + + + + + + + + +

JW Player with Playlist

+ +
Div-1: Player placeholder div
+
+ + + diff --git a/prebid-video/video-module/integration-examples/videojs.html b/prebid-video/video-module/integration-examples/videojs.html new file mode 100644 index 00000000..74d180ea --- /dev/null +++ b/prebid-video/video-module/integration-examples/videojs.html @@ -0,0 +1,150 @@ + + + + + + + + + + + + + + VideoJS with Playlist + + + + + + + + +

VideoJS with Playlist

+ +
Div-1: Player placeholder div
+ + + + + diff --git a/prebid-video/video-overview.md b/prebid-video/video-overview.md index f9cdedd4..5cfc63eb 100644 --- a/prebid-video/video-overview.md +++ b/prebid-video/video-overview.md @@ -18,11 +18,8 @@ sidebarType: 4 Prebid.js provides tools that allow header bidding video demand to compete with your ad server video demand. Prebid video demand can be incorporated for both instream, outstream, and long-form video slots. -- Instream - Instream video ads serve in-line with existing video content on your page. The ads can serve before, during, or after a piece of video content. As the publisher, you must provide your own video player that can be used to render the ads. +Prebid.js supports all the latest [OpenRTB Video types and subtypes](https://github.com/InteractiveAdvertisingBureau/AdCOM/blob/develop/AdCOM%20v1.0%20FINAL.md#list--placement-subtypes---video-). -- Outstream – Outstream video ads serve separately from any existing video content. Often, outstream video ad units are used to create video inventory on pages that do not include any video content. The outstream video ad is displayed through an associated outstream video renderer, which usually ingests configuration options that control the user experience. (For example, the outstream video player can be configured to expand within a text body on-page when in view, and collapse when the video is finished). - -- Long-form - Long-form video content always has a content arc with a beginning, middle and end. Ads display in an ad pod, a grouping of individual ads that appear either in the beginning, end or during the video content. As the publisher you must provide your own video player that can be used to render the ads. ## Implementation @@ -33,6 +30,8 @@ Here’s a high-level overview of the steps required to start using Prebid.js fo For implementation details, see [Getting Started with Video for Prebid.js]({{site.github.url}}/prebid-video/video-getting-started.html). +The [Prebid Video Module]({{site.github.url}}/prebid-video/video-getting-started.html#prebid-video-module) is the recommended way to implement video. + ## How It Works ### Instream Video From 5fbb38730c045ac9e4fd1135a4c40f2491fe7987 Mon Sep 17 00:00:00 2001 From: Piotr Jaworski <109736938+piotrj-rtbh@users.noreply.github.com> Date: Wed, 31 May 2023 19:51:43 +0200 Subject: [PATCH 248/762] RTB House: add fledge docs; reorganization (#4605) --- dev-docs/bidders/rtbhouse.md | 37 ++++++++++++++++++++++++++++++------ 1 file changed, 31 insertions(+), 6 deletions(-) diff --git a/dev-docs/bidders/rtbhouse.md b/dev-docs/bidders/rtbhouse.md index 60b4ca65..91cad3e1 100644 --- a/dev-docs/bidders/rtbhouse.md +++ b/dev-docs/bidders/rtbhouse.md @@ -28,14 +28,20 @@ sidebarType: 1 | `bidfloor` | optional | Minimal CPM value | `0.01` | `float` | | `channel` | optional | Inventory channel identifier, limited to 50 characters | `Partner 1 - News` | `string` | -#### ORTB Blocking +#### Please note: + +* Since 4.43 the bidfloor param will be ignored if a value is specified via floor module. + +* The channel param is available starting from Prebid 6.6.0. Please reach your RTBHouse representative for details on how to enable and use the channel param. + +### ORTB Blocking RTB House supports blocking advertisers in `badv` and categories in `bcat` parameters. The blocked advertisers/categories list has no length limitation, but response timeout is more likely to occur as the number of entries grow. Blocked advertisers list (`badv`) is an array of domains as strings. Blocked categories list (`bcat`) is an array of IAB categories as strings. For example: -##### Globally defined ORTB Blocking: +#### Globally defined ORTB Blocking: ```javascript pbjs.setConfig({ ortb2: { @@ -44,7 +50,7 @@ pbjs.setConfig({ } )}; ``` -##### ORTB Blocking specific only to rtbhouse bidder: +#### ORTB Blocking specific only to rtbhouse bidder: ```javascript pbjs.setBidderConfig({ bidders: ['rtbhouse'], @@ -59,8 +65,27 @@ pbjs.setBidderConfig({ ### Setting up the Prebid Server Adapter If you’re a Prebid Server host company looking to enable the RTB House server-side adapter, you'll need to contact prebid@rtbhouse.com. They will guide you through the process. Do not use the default bidder config file as it will require custom partner code to be entered. It will be provided by RTB House. -### Please note: -* Since 4.43 the bidfloor param will be ignored if a value is specified via floor module. +### Protected Audience API (FLEDGE) support +There’s an option to receive demand for Protected Audience API (FLEDGE/PAAPI) +ads using RTB House bid adapter. +Prebid’s [fledgeForGpt](https://docs.prebid.org/dev-docs/modules/fledgeForGpt.html) +module and Google Ad Manager is currently required. -* The channel param is available starting from Prebid 6.6.0. Please reach your RTBHouse representative for details on how to enable and use the channel param. +The following steps should be taken to setup Protected Audience for RTB House: + +1. Reach out to your RTB House representative for setup coordination. + +2. Build and enable FLEDGE module as described in +[fledgeForGpt](https://docs.prebid.org/dev-docs/modules/fledgeForGpt.html) +module documentation. + + a. Make sure to enable RTB House bidder to participate in FLEDGE. If there are any other bidders to be allowed for that, add them to the **bidders** array: +```javascript +pbjs.setBidderConfig({ + bidders: ["rtbhouse"], + config: { + fledgeEnabled: true + } +}); +``` From bad35d70af3571237c275491ecf924c554798cef Mon Sep 17 00:00:00 2001 From: Richard Date: Wed, 31 May 2023 20:17:16 +0200 Subject: [PATCH 249/762] Update adnuntius.md (#4591) Adds documentation for the new `maxDeals` parameter. --- dev-docs/bidders/adnuntius.md | 1 + 1 file changed, 1 insertion(+) diff --git a/dev-docs/bidders/adnuntius.md b/dev-docs/bidders/adnuntius.md index 18464e33..207e3666 100644 --- a/dev-docs/bidders/adnuntius.md +++ b/dev-docs/bidders/adnuntius.md @@ -25,6 +25,7 @@ sidebarType: 1 | `auId` | required | The ad unit ID `'0000000000072345'` leading zeros can be omitted. | `'0000000000072345'` | `string` | | `network` | optional | Used if you want to make requests to multiple networks in adnuntius. | `'adnuntius'` | `string`| | `targeting` | optional | Targeting to be sent through to adnuntius with the request. | `{ c: ['prebids'] }` | `string`| +| `maxDeals` | optional | The maximum number of deal bids to include. Default 0. | `1` | `Integer` | #### Targeting From e94db6635ba9f6f1238923a7afb1909cbc17c7fd Mon Sep 17 00:00:00 2001 From: khang-vu-ttd <109103626+khang-vu-ttd@users.noreply.github.com> Date: Wed, 31 May 2023 12:30:26 -0700 Subject: [PATCH 250/762] kvu-OPATH-760-update-docs-with-kvp (#4602) --- dev-docs/bidders/ttd.md | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/dev-docs/bidders/ttd.md b/dev-docs/bidders/ttd.md index e4533809..d5059757 100644 --- a/dev-docs/bidders/ttd.md +++ b/dev-docs/bidders/ttd.md @@ -182,3 +182,10 @@ Lists of `api`, `playbackmethod`, `protocols`, `pos`, and `expdir` potential val - `3` : Up - `4` : Down - `5` : Full Screen + +### First Party Data (Supported starting prebid v7.49) +Publishers should set [First Party Data](https://docs.prebid.org/features/firstPartyData.html) in the `ortb2` and `ortb2Imp` objects. These fields are supported: + +- `ortb2.site.ext.data` +- `ortb2.user.ext.data` +- `AdUnit.ortb2Imp.ext.data` (for AdUnit data) \ No newline at end of file From b4b8964c7477903ca4b1b351362e8c5979533937 Mon Sep 17 00:00:00 2001 From: Damyan Date: Thu, 1 Jun 2023 13:33:38 +0300 Subject: [PATCH 251/762] AdHash bid adapter changes (#4527) * AdHash documentation * multiformat_supported added * Removing globalScript flag --- dev-docs/bidders/adhash.md | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/dev-docs/bidders/adhash.md b/dev-docs/bidders/adhash.md index e8a276ff..ab7a27d1 100644 --- a/dev-docs/bidders/adhash.md +++ b/dev-docs/bidders/adhash.md @@ -4,8 +4,10 @@ title: AdHash description: Prebid AdHash Bidder Adapter pbjs: true biddercode: adhash +media_types: display, video safeframes_ok: false gdpr_supported: true +multiformat_supported: will-bid-on-any sidebarType: 1 --- @@ -17,15 +19,16 @@ Here is what you need for Prebid integration with AdHash: 3. Use the Publisher ID and Platform URL as parameters in params. Please note that a number of AdHash functionalities are not supported in the Prebid.js integration: -* Cookie-less frequency and recency capping; -* Audience segments; -* Price floors and passback tags, as they are not needed in the Preebid.js setup; -* Reservation for direct deals only, as bids are evaluated based on their price. +* Price floors and passback tags, as they are not needed in the Prebid.js setup; +* Reservation for direct deals only, as bids are evaluated based on their price; +* Fill rate reporting, as unfilled impressions can be filled by any other bidder; +* CPC deals, as bidding happens only on CPM pricing. ### Bid Params {: .table .table-bordered .table-striped } -| Name | Scope | Description | Example | Type | -|---------------|----------|--------------|------------------------------------------------|----------| -| `publisherId` | required | Publisher ID | `'0x1234567890123456789012345678901234567890'` | `string` | -| `platformURL` | required | Platform URL | `'https://adhash.org/p/example/'` | `string` | +| Name | Scope | Description | Example | Type | +|----------------|----------|----------------|------------------------------------------------|-----------| +| `publisherId` | required | Publisher ID | `'0x1234567890123456789012345678901234567890'` | `string` | +| `platformURL` | required | Platform URL | `'https://adhash.com/p/example/'` | `string` | +| `bidderURL` | optional | Bidder URL | `'https://bidder.adhash.com'` | `string` | From 142848431870e4cb683cc41ee987352ecee57360 Mon Sep 17 00:00:00 2001 From: Dmytro Shyrokov Date: Thu, 1 Jun 2023 13:34:26 +0300 Subject: [PATCH 252/762] Xeworks adapter: pbs support added (#4543) * meazy adapter docs * Xeworks Bid Adapter: update docs --------- Co-authored-by: Dmitry --- dev-docs/bidders/xe.md | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/dev-docs/bidders/xe.md b/dev-docs/bidders/xe.md index afa8396d..39682450 100644 --- a/dev-docs/bidders/xe.md +++ b/dev-docs/bidders/xe.md @@ -9,7 +9,7 @@ gdpr_supported: true usp_supported: true prebid_member: false pbjs: true -pbs: false +pbs: true schain_supported: true floors_supported: true multiformat_supported: will-bid-on-any @@ -21,11 +21,19 @@ sidebarType: 1 The Xe.works adapter requires setup before beginning. Please contact us at team@xe.works -### Bid params +### Prebid.js Bid params {: .table .table-bordered .table-striped } | Name | Scope | Description | Example | Type | |-------------|----------|-----------------------------|---------------|-----------| | `placement` | required | Placement ID | `test-banner` | `string` | | `env` | required | Environment name | `xe` | `string` | -| `ext` | optional | Specific integration config | `{}` | `object` | \ No newline at end of file +| `ext` | optional | Specific integration config | `{}` | `object` | + +### Prebid Server Bid Params + +{: .table .table-bordered .table-striped } +| Name | Scope | Description | Example | Type | +|-------------|----------|-----------------------------|------------------------------------|-----------| +| `env` | required | Environment name | `xe-stage` | `string` | +| `pid` | required | Uniq placement ID | `dc230510222b516f0eb9a10e5913d3b5` | `string` | From 5276a69a8d0ebe5fda28260a55ba6f5c81b91b30 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?L=C3=A9onard=20Labat?= Date: Thu, 1 Jun 2023 12:45:18 +0200 Subject: [PATCH 253/762] Criteo Bid Adapter : Update documentation according to latest features added about video & rwdd support (#4596) --- dev-docs/bidders/criteo.md | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) diff --git a/dev-docs/bidders/criteo.md b/dev-docs/bidders/criteo.md index c26f00e2..20bd455d 100644 --- a/dev-docs/bidders/criteo.md +++ b/dev-docs/bidders/criteo.md @@ -38,11 +38,22 @@ Prebid-Server support is on alpha test and is currently a non-finished product. | `networkId` | required | The network ID from Criteo. Please reach out your Criteo representative for more details. | `456456` | `integer` | | `nativeCallback` | optional | (Prebid.js only) Callback to perform render in native integrations. Please reach out your Criteo representative for more details. | `function(payload) { console.log(payload); }` | `function` | | `integrationMode` | optional | (Prebid.js only) Integration mode to use for ad render (none or 'AMP'). Please reach out your Criteo representative for more details. | `'AMP'` | `string` | -| `publisherSubId` | optional | Custom identifier for reporting. Please reach out your Criteo representative for more details. | `'adunit-1'` | `string` | +| `publisherSubId` | optional | Custom identifier for reporting. Please reach out your Criteo representative for more details. | `'adunit-1'` | `string` | ### First Party Data -Criteo supports both `ortb2` (`site` and `user`) and `ortb2Imp` methods to set [First Party Data](https://docs.prebid.org/features/firstPartyData.html). +Criteo supports both `ortb2` and `ortb2Imp` methods to set [First Party Data](https://docs.prebid.org/features/firstPartyData.html). + +The standard Open RTB properties supported from `ortb2` / `ortb2Imp` are described in the following table. + +{: .table .table-bordered .table-striped } +| Name | Scope | Description | Example | Type | +|-------------------|----------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|---------|-----------| +| `ortb2.user` | optional | Details via a Open RTB User object about the human user of the device; the advertising audience. | N/A | `object` | +| `ortb2.site` | optional | Details via a Open RTB Site object about the publisher’s website. | N/A | `object` | +| `ortb2Imp.rwdd` | optional | Indicates whether the user receives a reward for viewing the ad, where 0 = no, 1 = yes. | `1` | `integer` | + +Besides these standard properties, `ext` field can be used to send any publisher specific data which may have been discussed with a Criteo representative. ### Video Object @@ -65,7 +76,8 @@ In addition, Criteo adapter relies on parameters specified in the mediaTypes.vid | `playerSize` | required | Width and height of the player | `[640, 480]` | `Array` | | `protocols` | required | Supported video bid response protocols. VAST 1.0: `1`; VAST 2.0: `2`; VAST 3.0: `3`; VAST 1.0 Wrapper: `4`; VAST 2.0 Wrapper: `5`; VAST 3.0 Wrapper: `6`; | `|5, 6]` | `Array` | | `maxduration` | required | Maximum ad duration in seconds | `20` | `integer` | -| `api` | required | API frameworks supported. VPAID 1.0: `1`; VPAID 2.0: `2`; MRAID-1: `3`; ORMMA: `4`; MRAID-2: `5`; | `[1, 2]` | `Array` | +| `api` | required | API frameworks supported. VPAID 1.0: `1`; VPAID 2.0: `2`; MRAID 1.0: `3`; ORMMA: `4`; MRAID 2.0: `5`; MRAID 3.0: `6`; OMID 1.0: `7`; | `[1, 2]` | `Array` | +| `plcmt` | optional | 1=in-stream, 2=accompanying content, 3=interstitial, 4=no content/standalone. Highly recommended to comply with new IAB video specifications. | `1` | `integer` | #### Example of Video Ad-unit ``` From 1640601ede9c119e15ceddd42200f030539c9289 Mon Sep 17 00:00:00 2001 From: Nitin Nimbalkar <96475150+pm-nitin-nimbalkar@users.noreply.github.com> Date: Thu, 1 Jun 2023 16:19:38 +0530 Subject: [PATCH 254/762] Data controller Module Code renamed with actual file name (#4589) --- dev-docs/modules/dataControllerModule.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dev-docs/modules/dataControllerModule.md b/dev-docs/modules/dataControllerModule.md index 5d425c5e..79b6e86b 100644 --- a/dev-docs/modules/dataControllerModule.md +++ b/dev-docs/modules/dataControllerModule.md @@ -3,7 +3,7 @@ layout: page_v2 page_type: module title: Data Controller Module description: Filters the EIDs/SDA being transmitted to bid stream. -module_code : dataController +module_code : dataControllerModule display_name : Data Controller Module enable_download : true sidebarType : 1 From 12723a30be91ef8e33e2d47590053e0d2490b5dc Mon Sep 17 00:00:00 2001 From: maxime-dupuis <118775839+maxime-dupuis@users.noreply.github.com> Date: Thu, 1 Jun 2023 06:50:14 -0400 Subject: [PATCH 255/762] Sharethrough - Support native (#4583) --- dev-docs/bidders/sharethrough.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dev-docs/bidders/sharethrough.md b/dev-docs/bidders/sharethrough.md index d988965b..71e7ea3d 100644 --- a/dev-docs/bidders/sharethrough.md +++ b/dev-docs/bidders/sharethrough.md @@ -6,7 +6,7 @@ description: Prebid Sharethrough Adaptor gdpr_supported: true coppa_supported: true floors_supported: true -media_types: banner, video +media_types: banner, video, native safeframes_ok: true schain_supported: true userIds: all From 0b86f8790a8ad75ef5b77ab7bd903dd13446311f Mon Sep 17 00:00:00 2001 From: Nepomuk Seiler Date: Thu, 1 Jun 2023 15:19:02 +0200 Subject: [PATCH 256/762] Grant US traffic consent for GA and wait for CMP 500ms --- _includes/footer.html | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/_includes/footer.html b/_includes/footer.html index c4b6cdae..2abb9cb9 100644 --- a/_includes/footer.html +++ b/_includes/footer.html @@ -21,7 +21,11 @@ window.dataLayer = window.dataLayer || []; function gtag(){dataLayer.push(arguments);} gtag('js', new Date()); - gtag('consent', 'default', {'ad_storage': 'denied','analytics_storage': 'denied'}); + gtag('consent', 'default', { + 'analytics_storage': 'granted', + 'region': ['US'] + }); + gtag('consent', 'default', {'ad_storage': 'denied','analytics_storage': 'denied', 'wait_for_update': 500}); gtag("config", "G-GM972HCTEB", { anonymize_ip: true }); From b3ed7c6bcde2f8875346370d9a0394c813c963ef Mon Sep 17 00:00:00 2001 From: bretg Date: Thu, 1 Jun 2023 11:58:33 -0400 Subject: [PATCH 257/762] adding create table examples (#4612) --- prebid-server/hosting/pbs-database.md | 70 ++++++++++++++++++--------- 1 file changed, 46 insertions(+), 24 deletions(-) diff --git a/prebid-server/hosting/pbs-database.md b/prebid-server/hosting/pbs-database.md index 4554dc56..bed4b269 100644 --- a/prebid-server/hosting/pbs-database.md +++ b/prebid-server/hosting/pbs-database.md @@ -30,6 +30,8 @@ you to be able to integrate a few tables into that existing database and then re So instead of Prebid defining your schema, we just define the fields that need to come from the query. You can then design the SQL query and put it in PBS configuration. +That said, it's often been requested that Prebid just suggest a minimal schema, so there are examples below. + ## Database Queries Prebid Server queries the database in the following scenarios: @@ -37,8 +39,8 @@ Prebid Server queries the database in the following scenarios: {: .table .table-bordered .table-striped } | Data | SQL Config | Description | |------+---------------+-------------| -| Stored Requests | settings.database.stored-requests-query | Retrieve stored request JSON for incoming OpenRTB | -| AMP Stored Requests | settings.database.amp-stored-requests-query | Retrieve stored request JSON for incoming AMP | +| Auction endpoint Stored Requests | settings.database.stored-requests-query | Retrieve stored request JSON for incoming OpenRTB | +| AMP endpoint Stored Requests | settings.database.amp-stored-requests-query | Retrieve stored request JSON for incoming AMP | | Stored Responses | settings.database.stored-responses-query | Retrieve stored response data | | Account Data | settings.database.account-query (PBS-Java only) | Retrieve host company-specific account information | @@ -51,9 +53,10 @@ The Stored Request query needs to return fields in this order: {: .table .table-bordered .table-striped } | Field Num | Name | Type | Meaning | Default | |-----------+------+------+---------+---------| -| 1 | request ID | string | The Stored Request ID | n/a | -| 2 | request body | JSON | The body of the Stored Request | n/a | -| 3 | label | string | This is always just the static value 'request' | n/a | +| 1 | account ID | string | The Account ID may be used to distinguish between stored request IDs with the same name across accunts. (PBS-Java only) | n/a | +| 2 | request ID | string | The Stored Request ID | n/a | +| 3 | request body | JSON | The body of the Stored Request | n/a | +| 4 | label | string | Defines whether this item is a 'request' (top-level SR) or 'imp' (imp-level SR).| n/a | There are two parameters that can be passed into the query: @@ -68,13 +71,21 @@ settings: stored-requests-query: SELECT accountId, reqid, storedData, 'request' as dataType FROM stored_requests WHERE reqid IN (%REQUEST_ID_LIST%) UNION ALL SELECT accountId, reqid, storedData, 'imp' as dataType FROM stored_requests WHERE reqid IN (%IMP_ID_LIST%) ``` -This example assumes that the schema includes these fields: -- accountId: account ID, which is used to make sure that storedrequests are unique to the account -- reqid: ID of stored data item -- storedData: value of stored data item -- 'request' or 'imp': type of stored data item. +This **example** assumes that one table contains both top-level and imp-level stored requests: -Again, you can name the fields however you'd like in your database, and the query can be arbitrarily complicated as long as it returns the fields in the order and types shown here. +``` +CREATE TABLE `stored_requests` ( + `id` int(10) unsigned NOT NULL AUTO_INCREMENT, + `accountId` int(11) NOT NULL, + `reqid` varchar(50) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL, + `storedData` json NOT NULL +) +``` + +{: .alert.alert-info :} +This schema is for example only -- it's not a terribly smart schema for use in production. You should consider adding fields like insertDate and updateDate, and of course define indices. And again, you can name the fields however you'd like in your database, and the query can be arbitrarily complicated as long as it returns the fields in the order and types shown in the example query. + +Note: if we had to do it all over again, we'd get rid of the distinction between REQUEST_ID_LIST and IMP_ID_LIST. ### AMP Stored Requests @@ -89,13 +100,8 @@ settings: amp-stored-requests-query: SELECT accountId, reqid, storedData, 'request' as dataType FROM stored_requests WHERE reqid IN (%REQUEST_ID_LIST%) ``` -This example assumes that the stored_requests schema includes these fields: -- accountId: account ID, which is used to make sure that storedrequests are unique to the account -- reqid: ID of stored data item -- storedData: value of stored data item -- 'request': type of stored data item. Can be only be 'request' for AMP. +It's expected that your AMP stored requests are stored in the same schema as yourother stored requests. The query is, however, separably configurable. -Again, you can name the fields however you'd like in your database, and the query can be arbitrarily complicated as long as it returns the fields in the order and types shown here. ### Stored Responses @@ -120,9 +126,19 @@ settings: stored-responses-query: SELECT resid, responseData FROM stored_responses WHERE resid IN (%ID_LIST%) ``` -This example assumes that the stored_responses schema includes these fields: -- resid is a string field that contains the stored response ID -- responseData is a JSON field that contains the body of the stored response +This **example** schema assumes that the stored_responses schema includes these fields: +``` +CREATE TABLE `stored_responses` ( + `id` int(10) unsigned NOT NULL AUTO_INCREMENT, + `resid` varchar(50) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL, + `responseData` json NOT NULL +) +``` + +{: .alert.alert-info :} +This schema is for example only -- it's not a terribly smart schema for use in production. You should consider adding fields like insertDate and updateDate, and of course define indices. And again, you can name the fields however you'd like in your database, and the query can be arbitrarily complicated as long as it returns the fields in the order and types shown in the example query. + +Note: there's no reason you couldn't put stored responses in the same table as stored requests as long as there's a field differentiating them for use in the query. ### Account Data @@ -152,11 +168,17 @@ settings: account-query: JSON_MERGE_PATCH(JSON_OBJECT( 'id', accountId ), COALESCE(config, '{}')) as consolidated_config FROM accounts WHERE accountId = %ACCOUNT_ID% LIMIT 1 ``` -This example assumes that the accounts schema includes these fields: -- accountId is a string field that contains the account ID -- config is a JSON field that contains all the rest of the account-level fields +This **example** schema assumes that the accounts schema includes these fields: +``` +CREATE TABLE `accounts` ( + `id` int(10) unsigned NOT NULL AUTO_INCREMENT, + `accountId` int(11) NOT NULL, + `config` json NOT NULL +) +``` -Again, you can name the fields however you'd like in your database, and the query can be arbitrarily complicated as long as it returns the fields in the order and types shown here. +{: .alert.alert-info :} +This schema is for example only -- it's not a terribly smart schema for use in production. You should consider adding fields like insertDate and updateDate, and of course define indices. And again, you can name the fields however you'd like in your database, and the query can be arbitrarily complicated as long as it returns the fields in the order and types shown in the example query. See the [PBS-Java configuration docs](https://github.com/prebid/prebid-server-java/blob/master/docs/application-settings.md#configuration-document-json) for detail on the JSON structure expected as the result of the query. There are many account-level settings detailed there. From 3f35abafa904d94332f5e626ec3d7f86f5717bfc Mon Sep 17 00:00:00 2001 From: UOL - TechOps <116287445+uoladtech@users.noreply.github.com> Date: Thu, 1 Jun 2023 16:09:52 -0300 Subject: [PATCH 258/762] New adapter: Uol as an AppNexus alias (#4601) * New adapter: Uol as an AppNexus alias * Update uol.md Just changing the way the adapter name will appear --- dev-docs/bidders/uol.md | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) create mode 100644 dev-docs/bidders/uol.md diff --git a/dev-docs/bidders/uol.md b/dev-docs/bidders/uol.md new file mode 100644 index 00000000..1dd74941 --- /dev/null +++ b/dev-docs/bidders/uol.md @@ -0,0 +1,27 @@ +--- +layout: bidder +title: UOL +description: UOL Bidder Adapter +biddercode: uol +pbjs: true +pbs: false +aliasCode: appnexus +gdpr_supported: true +media_types: banner, video, native +gvl_id: 32 +schain_supported: true +userId: all +sidebarType: 1 +--- +### Bid Params + +{: .table .table-bordered .table-striped } +| Name | Scope | Description | Example | Type | +|---------------|----------|-----------------------|-----------|-----------| +| `placementID` | required | Placement id | `'11111'` | `string` | + +Uol is an aliased bidder for AppNexus. + +### Note: + +The UOL bidder adapter requires setup before beginning. Please contact us at l-dev-techops@uolinc.com. From b59cff61a784a14b784875cb72b681ad5d6eb271 Mon Sep 17 00:00:00 2001 From: bretg Date: Thu, 1 Jun 2023 15:10:52 -0400 Subject: [PATCH 259/762] PBS activity controls (#4552) * initial control of PBS activities doc * checkpoint * wordsmithing * more links, module details * fixed ipv6 masking comment --- prebid-server/developers/add-a-module.md | 19 +- .../features/pbs-activitycontrols.md | 246 ++++++++++++++++++ prebid-server/features/pbs-feature-idx.md | 1 + prebid-server/features/pbs-privacy.md | 7 + 4 files changed, 269 insertions(+), 4 deletions(-) create mode 100644 prebid-server/features/pbs-activitycontrols.md diff --git a/prebid-server/developers/add-a-module.md b/prebid-server/developers/add-a-module.md index ab608c15..6953e240 100644 --- a/prebid-server/developers/add-a-module.md +++ b/prebid-server/developers/add-a-module.md @@ -137,7 +137,17 @@ to the PBS host company. Examples: - modules may require a local SQL DB populated with application data - some modules may require access to local disk to read a security certificate -### 7. Think about Analytics Tags +### 7. Identify Sensitive Data Usage + +If your module either utilizes or supplies user-level data like User First Party Data or precise geographic information, it must adhere to the framework supplied by the [Activity Controls](/prebid-server/features/pbs-activitycontrols.html). + +For instance: +- if your module is going to supply user-level data (e.g. "job title") to bid adapters, it must check permissions for the `enrichUfpd` activity. +- if your module is going to forward the entire ORTB request to an endpoint, it must check the `transmitUfpd` and `transmitPreciseGeo` activity permissions. + +The details about how exactly to code this differs by platform. See the developer docs for Go and Java linked below. + +### 8. Think about Analytics Tags Analytics Tags (aka 'ATags') are a log mechanism provided by PBS-core to inform downstream modules about what's happened in the request so far. Use of the Analytics Tag structure @@ -153,7 +163,7 @@ that a given bidder is losing bid opportunities by not adhering to the auction p See the [Module Analytics Tag Conventions](/prebid-server/developers/module-atags.html) for more specific details about how to format ATags. -### 8. Write the Code, Config, and Unit Tests +### 9. Write the Code, Config, and Unit Tests The details of the implementation depend on the platform. @@ -165,7 +175,7 @@ Other rules for open source PBS pull request: - Unit test coverage must exceed 90%. - A maintainer email address must be provided and be a group, not an individual. e.g. "support@example.com rather than jsmith@example.com -### 9. Write the Module Documentation +### 10. Write the Module Documentation Fork the [documentation repo](https://github.com/prebid/prebid.github.io) and create a file in /prebid-server/pbs-modules. You can start by copying one of the existing files. It should contain: @@ -176,7 +186,7 @@ create a file in /prebid-server/pbs-modules. You can start by copying one of the - Analytics Tag support - Privacy Support: disclose whether the module has user privacy implications and support for GDPR, CCPA, etc. -### 10. Submit the Pull Requests +### 11. Submit the Pull Requests When everthing checks out on your dev environment, submit the PRs for review. @@ -184,3 +194,4 @@ When everthing checks out on your dev environment, submit the PRs for review. - [Prebid Server Module List](/prebid-server/pbs-modules/index.html) - [PBS Module Analytics Tags Conventions](/prebid-server/developers/module-atags.html) +- [PBS Activity Controls](/prebid-server/features/pbs-activitycontrols.html) diff --git a/prebid-server/features/pbs-activitycontrols.md b/prebid-server/features/pbs-activitycontrols.md new file mode 100644 index 00000000..51eeef68 --- /dev/null +++ b/prebid-server/features/pbs-activitycontrols.md @@ -0,0 +1,246 @@ +--- +layout: page_v2 +sidebarType: 5 +title: Prebid Server | Features | Actvity Controls + +--- + +# Prebid Server Activity Controls +{: .no_toc } + +{: .alert.alert-warning :} +This feature is currently only available in PBS-Java. + +Prebid supports a centralized control mechanism for privacy-sensitive activities. +These controls are intended to serve as building blocks for privacy protection mechanisms, allowing publishers to directly specify what should be permitted or avoided in any given regulatory environment. + +* TOC +{: toc } + +## Overview + +There are many privacy regulations that Prebid publishers need to accomodate. Prebid Server supplies [several features](/prebid-server/features/pbs-privacy.html) to help Publishers implement their legal policies, but there are scenarios where extra control is needed: + +- a Publisher's lawyers want to make a particular exception +- support hasn't been built for a regulation the Publisher needs to comply with + +### Prebid Server Is a Toolkit + +{: .alert.alert-danger :} +Important: This resource should not be construed as legal advice and Prebid.org makes no guarantees about compliance with any law or regulation. Please note that because every company and its collection, use, and storage of personal data is different, you should seek independent legal advice relating to obligations under European and /or US regulations, including the GDPR, the ePrivacy Directive and CCPA. Only a lawyer can provide you with legal advice specifically tailored to your situation. Nothing in this guide is intended to provide you with, or should be used as a substitute for, legal advice tailored to your business. + +1. Get a privacy lawyer. +2. Consider all the privacy regulations your content business is subject to. +3. Come up with a plan. +4. Use Prebid Server server features and these Activity Controls as ways to help implement your privacy plan with respect to header bidding. +5. Let us know if there are tools missing from the Prebid toolkit. + +### What is an Activity? + +We did an analysis of the things Prebid does that might be of concern to privacy regulations. We call these things "potentially restricted activities", or just "activities" for short. Some examples: + +- Syncing ID cookies +- Transmitting user first party data +- Transmitting the user's geographic location +- etc. + +The [full list of activities](#activities) is below. + +An activity control is a gatekeeper that makes a decision about whether the activity should be allowed in a specific context: + +- Should I allow this usersync for bidderB? +- Is it ok for this data to be passed to bidderC and analyticsD? +- Should I anonymize the geographic information for this request? +- etc. + +Prebid Server core checks with the Activity Controls to see whether a given activity is allowed for a given situation. The configuration for the activity comes from one of two places: either account-specific configuration or if not specified there, there's a host-level default. + +### Example Activity Control + +Here's an example account config that prevents bidderA, bidderB, and analytics adapters from receiving `user.eids[]` and `user.ext.data`: +``` +{ + privacy: { + allowactivities: { + transmitUfpd: { + default: true, + rules: [{ + condition: { + componentName: ["bidderA", "bidderB"] + }, + allow: false + },{ + condition: { + componentType: ["analytics"] + }, + allow: false + }] + } + } + } +``` + +
+ +## Configuration + +The `privacy.allowActivities` is a new account configuration option that contains a list of activity names -- see the [full list of activities below](#activities). + +``` +{ + privacy: { + allowactivities: { + ACTIVITY: { + default: true, + rules: [{ + condition: { ... }, + allow: false + },{ + ... more rules ... + }] + } + } + } +``` + +Each activity is an object that can contain these attributes: + +{: .table .table-bordered .table-striped } +| Name | Type | Description | +|------|------|-------------| +| `default` | boolean | Whether the activity should be allowed if no other rule applies. Defaults to true. | +| `rules` | array of objects | Rules for this activity | +| `rules[].condition` | object | Conditions to use for this rule. See the [rules](#rules) section below for details. If omitted, the rule always applies. | +| `rules[].allow` | boolean | Whether the activity should be allowed when this rule applies. Defaults to true. | + +`Rules` is an array of objects that a publisher can contruct to provide fine-grained control over a given activity. + +There's more about [rules](#rules) below. + + + +### Activities + +Here's the list of the 'potentially restricted activities' that Prebid Server core can restrict for Publishers: + +{: .table .table-bordered .table-striped } +| Name | Description | Effect when denied | +|----------------|-------------|---------------------------| +| `syncUser` | The [/cookie_sync](/prebid-server/endpoints/pbs-endpoint-cookieSync.html) or [/setuid](/prebid-server/endpoints/pbs-endpoint-setuid.html) endpoint has been asked to perform a sync or set-cookie. | Sync or setuid is skipped for one or more bidders. | +| `fetchBids` | A bid adapter wants to participate in an auction | Bidder is removed from the auction | +| `enrichUfpd` | A module wants to add user first party data to outgoing requests (`user.data` and `user.ext.data` in ORTB) | Module is not allowed to run. | +| `reportAnalytics` | The [/auction](/prebid-server/endpoints/openrtb2/pbs-endpoint-auction.html), [/amp](/prebid-server/endpoints/openrtb2/pbs-endpoint-amp.html), or [/event](/prebid-server/endpoints/pbs-endpoint-event.html) endpoint is about to call an analytics adapter. | Adapter is not called. | +| `transmitUfpd` | A bid adapter, analytics adapter, or module wants to access and/or transmit user FPD or EIDs to their endpoint | User FPD and EIDs are hidden from the adapter or module: `user.data`, `user.ext.data`, `user.{id, buyeruid, yob, gender}`, `user.eids`, `device.{device.ifa, macsha1, macmd5, dpidsha1, dpidmd5, didsha1, didmd5}` | +| `transmitPreciseGeo` | A bid adapter, analytics adapter, or module wants to access and/or transmit precise geolocation data to their endpoint | Latitude, longitude, and IP address are rounded off. Specifically, lat and long are truncated to two decimal places, IPv4 masks rightmost 8 bits, IPv6 masks the rightmost bits based on a configured value. | + + + +### Rules + +There are three parts to an Activity Control's rule: + +1. The priority - position within the array +2. The `condition` - logic for matching the rule +3. The `allow` status - what happens if the condition matches + +For example, this rule would allow bidderX to perform the activity if no higher priority rules take precedence. + ``` + ... + rules: [{ + condition: { + componentName: ["bidderX"] + }, + allow: true + }] + ... +``` + +Note: The Prebid.js version of this feature supports _explicit_ priority signals. That's not the case for the Prebid Server feature. Instead, for PBS, priority is implicit in the ordering of the array. + +#### Rule Conditions + +If a `condition` in a rule evaluates to true, the `allow` attribute of the rule will be utilized. If there's no condition specified, the rule's `allow` attribute will always be utilized. + +These are the conditional attributes available: + +{: .table .table-bordered .table-striped } +| Name | Scope | Description | Type | Example | +|------|------|-------------|-------|-------| +| componentType | optional | Can be "bidder", "analytics", or "module". | array of strings | ["bidder"] | +| componentName | optional | Name of a specific bid adapter, analytics adapter, or module. | array of strings | ["bidderX"] | + +{: .alert.alert-info :} +Note on names: if two components share a name (e.g. "ssp1") for both a bid adapter and an analytics adapter, the rule may need to distinguish between them by providing both `componentName` and `componentType`. + +#### Allow + +If the rule's condition matches, the `allow` attribute defines whether the rule 'votes' to allow (true) or disallow (false) the activity in question. + +If `allow` is not defined, the rule is assumed to assert **true** (i.e. allow the activity to happen). + +### Interaction with other privacy features + +Currently, the Activity Control feature is separate from other privacy features: + +1. Activity Controls are run before other privacy features. So, for instance, if a bidder is removed from a request by the `fetchBids` activity, the GDPR processing for that bidder will not take place. +1. GDPR-suppression activities must still be managed through that feature's configuration. (See details for [PBS-Go](https://github.com/prebid/prebid-server/blob/master/config/config.go) or [PBS-Java](https://github.com/prebid/prebid-server-java/blob/master/docs/config-app.md)) +1. Likewise, Activity Control rules do not override USPrivacy or COPPA. + +{: .alert.alert-info :} +While Activity Controls are currently not well integrated with other privacy features, that will change over the coming months. + + +### Examples + +#### Anonymize auctions and disable usersyncs for bidderA + +``` +{ + privacy: { + allowactivities: { + transmitUfpd: { + rules: [{ + condition: { + componentName: ["bidderA"] + }, + allow: false + }] + }, + syncUser: { + rules: [{ + condition: { + componentName: ["bidderA"] + }, + allow: false + }] + } + } + } +} +``` + +#### Prevent User First Party Data and EIDs from going to analytics adapters + +``` +{ + privacy: { + allowactivities: { + transmitUfpd: { + rules: [{ + condition: { + componentType: ["analytics"] + }, + allow: false + }] + } + } + } +} +``` + +## Modules + +Modules that perform any 'potentially restricted activity' are responsible for confirming they are allowed to perform that activity. See [Adding a PBS Module](/prebid-server/developers/add-a-module.html) for more information. + +## Further Reading +- [Prebid Server privacy regulation support](/prebid-server/features/pbs-privacy.html) diff --git a/prebid-server/features/pbs-feature-idx.md b/prebid-server/features/pbs-feature-idx.md index e7b35b38..5a8d04cc 100644 --- a/prebid-server/features/pbs-feature-idx.md +++ b/prebid-server/features/pbs-feature-idx.md @@ -37,6 +37,7 @@ title: Prebid Server | Features | [GPP](/prebid-server/features/pbs-privacy.html#gpp) | GPP TCF2/USP Support | PBS reads the Global Privacy Platform string and pulls out TCF2/USP strings when appropriate. | | | | COPPA | Core | Able to read the COPPA flag and [take appropriate enforcement action](https://github.com/prebid/prebid-server/issues/929). | | | | Global Privacy Control | Core | Passes the Sec-GPC header through to bidders. | | | +| Activity Controls | Core | [Account-level controls](/prebid-server/features/pbs-activitycontrols.html) over privacy sensitive activities. | | | | [Cache](/prebid-server/features/pbs-caching.html) | Bids core | Accepts the ext.prebid.cache.bids parameter, storing bid objects in PBC. | | | | Cache | VAST core | Accepts the ext.prebid.cache.vastxml parameter, storing VAST responses in PBC. | | | | Cache | Winning-only flag | Accepts a 'ext.prebid.cache.winningonly' parameter on the request. If true, instead of caching all bids and VAST, only the winning bid or VAST is stored. | | | diff --git a/prebid-server/features/pbs-privacy.md b/prebid-server/features/pbs-privacy.md index be915bd6..a99e20ac 100644 --- a/prebid-server/features/pbs-privacy.md +++ b/prebid-server/features/pbs-privacy.md @@ -10,6 +10,13 @@ title: Prebid Server | Features | Privacy * TOC {:toc} +## Prebid Server Activity Control Infrastructure + +Prebid Server supports a mechanism for Publisher control for overriding privacy-sensitive activities. See the [Activity Controls](/prebid-server/features/pbs-activitycontrols.html) for more information. + +Note that Activity Controls are currently not well integrated with other privacy features, but that will change as these features mature. + + ## Mobile 'Limit Ad Tracking' flag If PBS receives 'device.lmt' flag in the OpenRTB request, it does the following anonymization: From 2bed132e83de17c5cc95bcebd9149bdceaee4697 Mon Sep 17 00:00:00 2001 From: radubarbos Date: Thu, 1 Jun 2023 22:12:43 +0300 Subject: [PATCH 260/762] ConnectId auto generated puid and storage updates. (#4582) Co-authored-by: dumitrubarbos --- dev-docs/modules/userid-submodules/yahoo.md | 38 +++++++++++++++++---- 1 file changed, 32 insertions(+), 6 deletions(-) diff --git a/dev-docs/modules/userid-submodules/yahoo.md b/dev-docs/modules/userid-submodules/yahoo.md index 706988b7..2b034cda 100644 --- a/dev-docs/modules/userid-submodules/yahoo.md +++ b/dev-docs/modules/userid-submodules/yahoo.md @@ -27,8 +27,8 @@ Note: Parameters are case-sensitive. ConnectID is the proper name of our product | params | Required | Object | Container of all module params. || | params.pixelId | Required | Number | The Yahoo-supplied publisher-specific pixel ID. | `"0000"` | -| params.he | Optional | String | The SHA-256 hashed user email address which has been lowercased prior to hashing. Pass both `he` and `puid` params if present, otherwise pass either of the two that is available. |`"ed8ddbf5a171981db8ef938596ca297d5e3f84bcc280041c5880dba3baf9c1d4"`| -| params.puid | Optional | String | The publisher supplied user identifier such as a first-party cookie. Pass both `he` and `puid` params if present, otherwise pass either of the two that is available. | `"ab9iibf5a231ii1db8ef911596ca297d5e3f84biii00041c5880dba3baf9c1da"` | +| params.he | Optional | String | The SHA-256 hashed user email address which has been lowercased prior to hashing. |`"ed8ddbf5a171981db8ef938596ca297d5e3f84bcc280041c5880dba3baf9c1d4"`| +| params.puid | Optional | String | A domain-specific user identifier such as a first-party cookie. If not passed, a puid value will be auto-generated and stored in local and / or cookie storage. | `"ab9iibf5a231ii1db8ef911596ca297d5e3f84biii00041c5880dba3baf9c1da"` | {: .table .table-bordered .table-striped }
@@ -52,7 +52,7 @@ pbjs.setConfig({ ``` ``` -// [Sample #2]: Using a hashed email and a publisher-supplied user identifier such as a first-party cookie. +// [Sample #2]: Neither a hashed email nor a publisher user identifier is passed. pbjs.setConfig({ userSync: { @@ -60,14 +60,40 @@ pbjs.setConfig({ name: "connectId", params: { pixelId: "0000", - he: "ed8ddbf5a171981db8ef938596ca297d5e3f84bcc280041c5880dba3baf9c1d4", - puid: "ab9iibf5a231ii1db8ef911596ca297d5e3f84biii00041c580dba3baf9c1da" } }] } }) ``` +``` +// [Sample #3]: Using a hashed email and a publisher user identifier such as a first-party cookie. + +pbjs.setConfig({ + userSync: { + userIds: [{ + name: "connectId", + params: { + pixelId: "0000", + he: "ed8ddbf5a171981db8ef938596ca297d5e3f84bcc280041c5880dba3baf9c1d4" + puid: "ab9iibf5a231ii1db8ef911596ca297d5e3f84biii00041c580dba3baf9c1da" + } + }] + } +}) +``` + +## Implementation Verification +Follow the steps below to check that ConnectIDs are being successfully retrieved and included on ad requests. +1) Open a Prebid-enabled page on the website. +2) Open the browser console and enter pbjs.getUserIds(). +3) Verify connectId is in the list. + - If connectId is not in the list, the correct pixelId parameter is likely not being passed. Verify you are using the correct value provided by Yahoo. Reach out to [connectid.support@yahooinc.com](mailto:connectid.support@yahooinc.com) for assistance. +4) Verify that ConnectID is successfully included in the ad requests. + - Go to the Network tab and search for an ad call event to any of the SSPs that you are using (e.g., “prebid-client”). + - Navigate to the Payload tab. Check that yahoo.com is listed as a source in the user.ext.eids array. +5) Repeat steps 1-4 after an email is provided via login or some other mechanism used to collect user registration on the website. + ## Honoring Privacy Choices Yahoo ConnectID provides multiple mechanisms for users to manage their privacy choices. Users can manage their choices via [ConnectID Control Portal](http://connectid.yahoo.com), on the [Yahoo Privacy Dashboard](https://legal.yahoo.com/us/en/yahoo/privacy/dashboard/index.html) and [NAI’s Audience Matched Opt Out page](https://optout.networkadvertising.org/optout/email). No further actions are required by Publishers as Yahoo will ensure that privacy choices selected by users via one of these methods are honored. We will automatically stop generating ConnectIDs for users who have opted-out. @@ -83,7 +109,7 @@ Please note that the storage related parameters are optional. We recommend that | Param under userSync.userIds[] | Scope | Type | Description | Example | | --- | --- | --- | --- | --- | | storage | Optional | Object | Defines where and for how long the results of the call to get a user ID will be stored. | | -| storage.type | Optional | String | Defines where the resolved user ID will be stored (either `'cookie'` or `'html5'` local storage).| `'cookie'` | +| storage.type | Optional | String | Defines where the resolved user ID will be stored (either 'cookie' or 'html5' local storage). | `'cookie'` | | storage.name | Optional | String | The name of the cookie or html5 local storage where the resolved user ID will be stored. | `'connectId'` | | storage.expires | Optional | Integer | How long (in days) the user ID information will be stored. | `15` | {: .table .table-bordered .table-striped } From 289bd141d0c28d8a39174448ef5c7e5926f2fadf Mon Sep 17 00:00:00 2001 From: Aaron Friedman Date: Thu, 1 Jun 2023 16:09:54 -0400 Subject: [PATCH 261/762] FreeWheel SSP Adapter: add bidder params (#4609) Co-authored-by: Aaron Friedman --- dev-docs/bidders/freewheelssp.md | 46 ++++++++++++++++++++++++++++++-- 1 file changed, 44 insertions(+), 2 deletions(-) diff --git a/dev-docs/bidders/freewheelssp.md b/dev-docs/bidders/freewheelssp.md index 4b48260e..fa6bffc5 100644 --- a/dev-docs/bidders/freewheelssp.md +++ b/dev-docs/bidders/freewheelssp.md @@ -21,5 +21,47 @@ sidebarType: 1 {: .table .table-bordered .table-striped } | Name | Scope | Description | Example | Type | -|----------|----------|-------------|---------|----------| -| `zoneId` | required | | | `string` | +|----------|----------|-------------------------|--------|----------| +| `zoneId` | required | The zone ID for the ad. | "2003" | `string` | +| `format` | optional | The format to use for displaying the ad. Can be one of the following:
* screen-roll
* intext-roll
* sliderad
* floorad
* expand-banner
* instream
* inbanner
Note: The screen-roll, intext-roll, sliderad and floorad formats are all FreeWheel outstream formats.
Default value: "instream" | "screen-roll" | `string` | +| `bidfloor` | optional | Bid floor price. | 13.2118 | `float` | +| `bidfloorcur` | optional | Bid floor currency. | "USD" | `string` | +| `vastUrlParams` | optional | Add query parameters to the vast request. Should be a single item level JSON.
Works with formats: instream, inbanner | { protocolVersion:'3.0' } | `object` | + +When the following params are used with instream or inbanner formats, they should be included in the `vastUrlParams` object. For other formats, they should be included directly in the `params` object: + +{: .table .table-bordered .table-striped } +| Name | Scope | Description | Example | Type | +|----------|----------|-------------------------|--------|----------| +| `soundButton` | optional | If enabled, the sound will be off by default and the user will be able to turn it on/off by clicking on a button. (disabled on iOS devices)
Default value: false | true | `boolean` | +| `defaultMute` | optional | If "soundButton=true" is set, controls if the video will start with the sound muted.
Default value: true | false | `boolean` | +| `timeline` | optional | Display a progress bar to the bottom of the ad unit.
Default value: false | true | `boolean` | +| `protocolVersion` | optional | Specify the VAST version that will be used for the vastVersion parameter value on AdsSetup request.
Default Value: 4.2 | 3 .0 | `float` | +| `onOver` | optional | Allows to enable the sound only when the mouse is over the ad container.
Works with formats: screen-roll, intext-roll, sliderad, floorad, expand-banner
Default value: false | true | `boolean` | +| `closeTimeout` | optional | The duration in milliseconds before displaying the close button.
Works with formats: screen-roll, intext-roll, sliderad, floorad
Default value: 5000 | 2000 | `integer` | +| `animated` | optional | Enable an animation on opening and on closing of the video.
Works with formats: intext-roll, sliderad
Default value: true | false | `boolean` | +| `animationSpeed` | optional | If the animated parameter is set to true, allows to choose the animation speed in milliseconds.
Works with formats: intext-roll, sliderad
Default value: 700 | 500 | `integer` | +| `contentId` | optional | Displays the ad inside the content-id dom element (dom id). Requires an 'auto', 'p' or 'article' param.
Works with format: intext-roll | "element-id" | `string` | +| `auto` | optional | If value is set to "v2", position the intext-roll automatically. If contentId is set, the auto positioning will find a position inside the 'contentId' dom element.
If contentId is not set, the auto positionaing will search the best position to display the ad based on the page semantic. It will select several possible position and show the intext-roll at the time one of them is made visible.
Works with format: intext-roll
Default value: null | "v2" | `string` | +| `article` | optional | Set the location of the ad just after the given article tag in the page (0 is for the first article tag). If content-id is set, the article index is relative to articles inside the 'content-id' dom element | "element-id"
Works with format: intext-roll | `string` | +| `p` | optional | Set the location of the ad just after the given paragraph tag in the page (0 is for the first p tag). If content-id is set, the p index is relative to paragraphs inside the 'content-id' dom element.
Works with format: intext-roll | "element-id" | `string` | +| `iframeMode` | optional | Indicate to intext-roll that it is served in a friendly hidden iframe. Can be one of the following:
* normal - place ad in friendly iframe
* dfp - place ad in iframe on dfp platform
Works with format: intext-roll | "normal" | `string` | +| `inRead` | optional | When true, will keep the ad slot window on the page when the ad is done.
Works with format: intext-roll
Default value: false | true | `boolean` | +| `lang` | optional | Text language. Can be one of: [fr,en,es,it,de,nl,pt]
Works with format: intext-roll
Default value: "fr" | "en" | `string` | +| `openingTime` | optional | The time in milliseconds to display the opening animation.
Works with format: intext-roll
Default value: 0 | 100 | `integer` | +| `pauseRatio` | optional | Specify the viewabilityratio where the ad is paused. This can be a float between 0 and 1, or "never" which means never paused. The default value will pause when the ad has less than 50% viewability.
Works with formats: intext-roll, expand-banner
Default value: 0.5 | 0.9 | `float` \| `string` | +| `closeAction` | optional | Define what to do for the banner after all ads complete. Can be one of:
* collapse - will set the target css display property to "none".
* hide - will leave the target element in place, empty.
Works with formats: intext-roll, expand-banner
Default value: “collapse” | "hide" | `string` | +| `domId` | optional | id of the dom element containing the text. If this targeted div is empty, be sure it has the needed width or a width of 0px will be used. Note that the script tag should be added in the page AFTER the targeted dom element so the target will be ready when the script runs.
Works with formats: intext-roll, expand-banner | "element-id" | `string` | +| `errorAction` | optional | Define what to do for the banner after an ad error. Can be one of:
* collapse - will set the target css display property to "none".
* hide - will leave the target element in place, empty.
Works with formats: intext-roll, expand-banner
Default value: “collapse” | "hide" | `string` | +| `stickToTop` | optional | Controls if the ad will stick to the top of the browser window. Can be one of the following:
* true - The ad will stick to the top of the browser window upon scroll.
* "bottom" - The ad will stick to the top and will be hidden again when reaching the bottom of the page.
* number - The ad will stick to the top for the given distance in pixels.
Works with formats: intext-roll, expand-banner | 300 | `boolean \| string \| number` | +| `blurDisplay` | optional | Allow to choose between too blur effects for the sides of the banner. Can be one of:
* big - will show the blured video only once in the background.
* duplicate - will show the blured video twice: once for each side.
Works with format: expand-banner
Default value: "big" | "duplicate" | `string` | +| `expandDirection` | optional | Allows to force the expansion direction. Can be one of the following:
* before - Expand to the left if the banner is vertical and to the top if the banner is horizontal.
* after - Expand to the right if the banner is vertical and to the bottom if the banner is horizontal.
* center - Expand to left and right if the banner is vertical. Expand to the top and bottom if the banner is horizontal.
* auto - Expand based on the space available on the page. Expand to the left and/or right if the banner is vertical. and expand to the top and bottom if the banner is horizontal, depending on the space available.
* none - Banner will not expand
Works with format: expand-banner
Default value: "auto" | "before" | `string` | +| `zIndex` | optional | Force the z-index value on the ad container. The default value is around 4100 (see IAB guidelines). Use this parameter if it doesn't fit your needs.
Works with format: expand-banner
Default value: ~4100 | 1000 | `integer` | +| `hAlign` | optional | Horizontal side where to display the video. Can be one of:
* left - horizontal align to the left of the page.
* middle - horizontal align to the middle of the page.
* right - horizontal align to the right of the page.
Works with format: sliderad
Default value: "right" | "left" | `string` | +| `hSpacing` | optional | Set a horizontal spacing between the hAlign side and the video.
Works with format: sliderad
Default value: 10 | 20 | `integer` | +| `vAlign` | optional | Vertical side where to display the video. Can be one of:
* top - vertical align to the top of the page.
* middle - vertical align to the middle of the page.
* bottom - vertical align to the bottom of the page.
Works with format: sliderad
Default value: "bottom" | "top" | `string` | +| `vSpacing` | optional | Set a vertical spacing between the vAlign side and the video.
Works with format: sliderad
Default value: 10 | 20 | `integer` | +| `mod` | optional | Ad trigger mode. Can be one of:
* asap - play the ad asap
* click - play the ad when the user clicks a link
* scroll - play the ad when the user scrolls
Works with format: screen-roll
Default value: "asap" | "click" | `string` | +| `opacity` | optional | Define the opacity of the background. This is a number between 0 (completely transparent) and 1 (totally black).
Works with format: screen-roll
Default value: 0.4 | .5 | `float` | +| `smartPlay` | optional | Enable to use autoPlay on mobile devices.
Works with format: screen-roll
Default value: false | true | `boolean` | +| `bannerHeight` | optional | The height in pixel of the bottom banner. The video ad takes this height when its not expanded.
Works with format: floorad
Default value: 250 | 500 | `integer` | From 4336639ef47d99d263d77951d93414bc8b81b625 Mon Sep 17 00:00:00 2001 From: Gena Date: Thu, 1 Jun 2023 23:34:15 +0300 Subject: [PATCH 262/762] SSP Copper6 doc (#4587) * SSP Copper6 doc * add pbs * Update copper6.md neither copper6 nor adtelligent are listed as Prebid.org members. Flipping that flag to false. --------- Co-authored-by: bretg --- dev-docs/bidders/copper6.md | 105 ++++++++++++++++++++++++++++++++++++ 1 file changed, 105 insertions(+) create mode 100644 dev-docs/bidders/copper6.md diff --git a/dev-docs/bidders/copper6.md b/dev-docs/bidders/copper6.md new file mode 100644 index 00000000..1b03e501 --- /dev/null +++ b/dev-docs/bidders/copper6.md @@ -0,0 +1,105 @@ +--- +layout: bidder +title: SSP Copper6 +description: SSP Copper6 Bidder Adapter +biddercode: copper6 +aliasCode: adtelligent +media_types: video,banner +gdpr_supported: true +userIds: britepoolId, criteo, id5Id, identityLink, liveIntentId, netId, parrableId, pubCommonId, unifiedId +schain_supported: true +coppa_supported: true +usp_supported: true +safeframes_ok: true +prebid_member: false +pbjs: true +pbs: true +deals_supported: false +sidebarType: 1 +--- + +### Bid params + +{: .table .table-bordered .table-striped } +| Name | Scope | Description | Example | Type | +|-------|----------|---------------------------------|----------|-----------| +| `aid` | required | The source ID from Copper6 Media. | `12412` | `integer` | + +### Description +Copper6 Media header bidding adapter connects with Copper6 Media demand sources in order to fetch bids. +This adapter provides a solution for accessing Video demand and display demand. + + +### Test Parameters +``` + var adUnits = [ + + // Video instream adUnit + { + code: 'test-div', + mediaTypes: { + video: { + context: 'instream', + playerSize: [640, 480] + } + }, + bids: [{ + bidder: 'copper6', + params: { + aid: 472386 + } + }] + }, + + // Video outstream adUnit + { + code: 'test-div', + mediaTypes: { + video: { + context: 'outstream', + playerSize: [640, 480] + } + }, + bids: [{ + bidder: 'copper6', + params: { + aid: 472386 + } + }] + }, + + // Video ADPOD adUnit + { + code: 'test-div', + sizes: [[640, 480]], + mediaTypes: { + video: { + context: 'adpod', + playerSize: [640, 480] + } + }, + bids: [{ + bidder: 'copper6', + params: { + aid: 472386 + } + }] + }, + + // Banner adUnit + { + code: 'test-div', + mediaTypes:{ + banner:{ + sizes: [[300, 250]] + } + } + bids: [{ + bidder: 'copper6', + params: { + aid: 529814 + } + }] + } + ]; +``` From 26ad317791742ad8245c19e40e677117306737e9 Mon Sep 17 00:00:00 2001 From: Sir-Will Date: Fri, 2 Jun 2023 11:56:33 +0200 Subject: [PATCH 263/762] Auto select modules with URL param (#4542) * Auto select modules with URL param * Update download URL on modules change * Fix prepicks being set to early * setting ID to biddercode * Use element id as module code * Fix module code of "ID Import Library" --------- Co-authored-by: bretg --- dev-docs/modules/idLibrary.md | 2 +- download.md | 79 ++++++++++++++++++++++++++++++++--- 2 files changed, 74 insertions(+), 7 deletions(-) diff --git a/dev-docs/modules/idLibrary.md b/dev-docs/modules/idLibrary.md index 5874353f..1abb7d45 100644 --- a/dev-docs/modules/idLibrary.md +++ b/dev-docs/modules/idLibrary.md @@ -3,7 +3,7 @@ layout: page_v2 page_type: module title: ID Import Library description: Retrieve user ids deployed on your site, and return them to a configurable endpoint for ID Graphing. -module_code : currency +module_code : idImportLibrary display_name : ID Import Library enable_download : true sidebarType : 1 diff --git a/download.md b/download.md index 2728e6f0..084b55b3 100644 --- a/download.md +++ b/download.md @@ -35,6 +35,8 @@ a.tip:hover span { diff --git a/adops/adops-general-sbs.md b/adops/adops-general-sbs.md index 80ed48e5..47003d7f 100644 --- a/adops/adops-general-sbs.md +++ b/adops/adops-general-sbs.md @@ -17,10 +17,10 @@ sidebarType: 3 Prebid.org provides step-by-step instructions for manually configuring Prebid in the following ad servers: -- [Google Ad Manager](/adops/step-by-step.html) -- [Xandr Monetize Ad Server](/adops/setting-up-prebid-with-the-appnexus-ad-server.html) -- [Freewheel](/adops/setting-up-prebid-video-in-freewheel.html) -- [Smart Ad Server](/adops/setting-up-prebidjs-with-Smart-Ad-Server.html) +* [Google Ad Manager](/adops/step-by-step.html) +* [Xandr Monetize Ad Server](/adops/setting-up-prebid-with-the-appnexus-ad-server.html) +* [Freewheel](/adops/setting-up-prebid-video-in-freewheel.html) +* [Smart Ad Server](/adops/setting-up-prebidjs-with-Smart-Ad-Server.html) If you’re using a different ad server, you can use the general instructions provided here and adapt them to your ad server. @@ -40,8 +40,8 @@ For the purposes of this discussion, we’re going to refer to the elements in y Ad servers typically work in a hierarchical structure, with advertisers containing orders, which in turn contain line items. You need to have your advertisers and orders set up before you can start creating line items and creatives. The advertisers you create for Prebid will typically depend on whether you’re sending all bids or only the top price bid to the ad server. -- Send Top Bid: Create one general Prebid advertiser -- Send All Bids: Create one Prebid advertiser per bidder where orders are organized by bidder, with one or more orders containing line items targeted towards a single bidder. +* Send Top Bid: Create one general Prebid advertiser +* Send All Bids: Create one Prebid advertiser per bidder where orders are organized by bidder, with one or more orders containing line items targeted towards a single bidder. ### Create Native Template @@ -58,12 +58,12 @@ See [Key Values](/adops/key-values.html) for information on the keys you’ll ne The exact order of the following steps will differ depending on your ad server. ### General Settings - + 1. Enter a name for your line item. Suggested format: Prebid – format - bidder – price bucket. For example, `Prebid – banner - BidderA – 1.50`. 2. Set the priority of your line item to whatever you think is appropriate. Typically Prebid line items are prioritized below direct-sold but above house/remnant. 3. Enter the sizes of your creatives: -- Banner/Outstream/AMP/Video: Select the sizes of all ad slots included in the Prebid process. -- Native: Select a native template. + * Banner/Outstream/AMP/Video: Select the sizes of all ad slots included in the Prebid process. + * Native: Select a native template. 4. Long-Form (OTT) Video only: If you’re using competitive exclusions, fill in the associated field with the appropriate value. You’ll need to include this value when you set your targeting for the `hb_pb_cat_dur` key. See [Targeting](#targeting) below for more information. 5. Set your line item to start immediately, with no end date. @@ -72,16 +72,16 @@ If you’re using competitive exclusions, fill in the associated field with the ### Targeting -You’ll need to apply custom targeting specific to the Prebid values that are passed in with the ad request. - +You’ll need to apply custom targeting specific to the Prebid values that are passed in with the ad request. + {: .alert.alert-info :} These instructions assume you’re sending all bids to the ad server (the default). If you’re sending only the top price bid, your targeting keys will not include the bidder code. For example, rather than targeting price buckets with `hb_pb_BidderA`, you’ll target `hb_pb`. See [Send All Bids vs Top Price](/adops/send-all-vs-top-price.html) for more information. Target the price bucket key: `hb_pb_BIDDERCODE` (where BIDDERCODE is the actual code for your bidder, such as BidderA) with the value of the price bucket you entered as the price for this line item. The following additional keys must be added for the corresponding formats: - -**Banner/Outstream/Native:** + +**Banner/Outstream/Native:** You can use the same line item for banner, outstream, and/or native creatives. If your ad slot could be filled by two or more of these formats, you should include the hb_format_BIDDERCODE key with values specifying all expected formats. @@ -90,16 +90,16 @@ If you combine native with another format in a single line item, you’ll need t **In-Player and Outstream Video:** -Both in-player (instream) and outstream video ads receive the `hb_format_BIDDERCODE=video` key-value pair, so targeting on that key alone is not enough to choose the correct line items. If you're running both in-player and outstream video ads, they will most likely be separate line items, so you will need to target outstream line items to a “display” inventory type, or perhaps separate them by adunits. +Both in-player (instream) and outstream video ads receive the `hb_format_BIDDERCODE=video` key-value pair, so targeting on that key alone is not enough to choose the correct line items. If you're running both in-player and outstream video ads, they will most likely be separate line items, so you will need to target outstream line items to a “display” inventory type, or perhaps separate them by adunits. **Long-Form (OTT) Video:** - + For long-form video the custom key `hb_pb_cat_dur_BIDDERCODE` is required. The value of this key breaks down like this: -- _pb represents the price bucket. This is the currency amount entered as the line item price. -- _cat indicates the competitive exclusion industry code. (For engineering information, refer to the [Category Translation module](/dev-docs/modules/categoryTranslation.html)). This is the value entered as the competitive exclusion. If you are not using competitive exclusion, you can omit this portion of the value. -- _dur is the length of the video in seconds. This is the value you’ll enter as the maximum duration of the video. - +* _pb represents the price bucket. This is the currency amount entered as the line item price. +* _cat indicates the competitive exclusion industry code. (For engineering information, refer to the [Category Translation module](/dev-docs/modules/categoryTranslation.html)). This is the value entered as the competitive exclusion. If you are not using competitive exclusion, you can omit this portion of the value. +* _dur is the length of the video in seconds. This is the value you’ll enter as the maximum duration of the video. + For example, for a line item with a $10.00 CPM as the price, a competitive exclusion of “news”, and 30s entered for the video duration, you would enter the following in the custom key-value field: `hb_pb_cat_dur_BIDDERCODE = 10.00_news_30s`. If you’re not using competitive exclusion, you can have a value such as this: `hb_pb_cat_dur_BIDDERCODE = 10.00_30s`. {: .alert.alert-info :} @@ -118,19 +118,19 @@ You’ve now added all fields required for targeting Prebid line items. You can ## Create Your Creatives -The process of creating your creatives will differ based on the type of creative. +The process of creating your creatives will differ based on the type of creative. In general, you can interpret the instructions for setting up creatives in Google Ad Manager with some modifications; specifically, to the MACROs used in the ad tag. (See below for details.) Refer to the following for GAM documentation: -- [GAM Creative Setup: Banner/Outstream/AMP](/adops/gam-creative-banner-sbs.html) -- [GAM Creative Setup: Native](/adops/gam-native.html) -- [GAM Creative Setup: Video](/adops/setting-up-prebid-video-in-dfp.html) +* [GAM Creative Setup: Banner/Outstream/AMP](/adops/gam-creative-banner-sbs.html) +* [GAM Creative Setup: Native](/adops/gam-native.html) +* [GAM Creative Setup: Video](/adops/setting-up-prebid-video-in-dfp.html) We recommend using the [Prebid Universal Creative](/overview/prebid-universal-creative.html) and targeting an ad unit size of 1x1. If you’re working with banner or outstream creatives, the HTML you’ll enter in the creatives will be similar to the following (utilizing whatever macro format is supported by your ad server): -``` +```html ``` {: .alert.alert-warning :} -- Replace `%%MACRO%%` with the appropriate macro for your ad server. (Refer to your ad server’s documentation or consult with a representative for specific details regarding the proper macros and how to use them.) -- Replace BIDDERCODE with the appropriate code for the bidder your line item is targeting. For example, if you’re targeting BidderA, the macro variable for adId might look like `ucTagData.adId = "%%PATTERN:hb_adid_BidderA%%";`. -- If you're hosting your own Prebid Universal Creative, make sure it's version 1.15 or later, or replace `%%PATTERN:hb_format%%.js` with `creative.js`. + +* Replace `%%MACRO%%` with the appropriate macro for your ad server. (Refer to your ad server’s documentation or consult with a representative for specific details regarding the proper macros and how to use them.) +* Replace BIDDERCODE with the appropriate code for the bidder your line item is targeting. For example, if you’re targeting BidderA, the macro variable for adId might look like `ucTagData.adId = "%%PATTERN:hb_adid_BidderA%%";`. +* If you're hosting your own Prebid Universal Creative, make sure it's version 1.15 or later, or replace `%%PATTERN:hb_format%%.js` with `creative.js`. The example above uses the jsdelvr CDN as the domain from which the creative will serve. However, you may obtain the creative from a managed service or host it yourself. You might need to edit the creative and make adjustments to your creative settings depending on the CDN you're using. @@ -169,6 +170,6 @@ The final steps in configuring Prebid on your ad server are to do the following: ## Further Reading -- [Ad Ops Planning Guide](/adops/adops-planning-guide.html) -- [Ad Ops and Prebid Overview](/adops/before-you-start.html) - +* [Ad Ops Planning Guide](/adops/adops-planning-guide.html) +* [Ad Ops and Prebid Overview](/adops/before-you-start.html) + \ No newline at end of file diff --git a/adops/gam-creative-banner-sbs.md b/adops/gam-creative-banner-sbs.md index 796234ee..a2ee3cef 100644 --- a/adops/gam-creative-banner-sbs.md +++ b/adops/gam-creative-banner-sbs.md @@ -15,7 +15,6 @@ This page walks you through the steps required to create banner and outstream cr {: .alert.alert-success :} For complete instructions on setting up Prebid line items in Google Ad Manager, see [Google Ad Manager with Prebid Step by Step](/adops/step-by-step.html). - 1. In GAM, select **Delivery** > **Creatives**. 2. Under the **Display creatives** tab, click **New Creative**. 3. Select your advertiser, then click **Third party**. @@ -42,28 +41,28 @@ These instructions assume you're using the Prebid Universal Creative (PUC) after {: .alert.alert-warning :} Be sure to replace BIDDERCODE with the appropriate bidder. For example, if the bidder code is `PBbidder`, the `adid` would be `%%PATTERN:hb_adid_PBbidder%%`. -``` - - +```html + + ``` {: .alert.alert-danger :} @@ -73,7 +72,7 @@ Warning: Be sure none of the attribute names are longer than 20 characters. See In top-price mode, you can make use of the GAM `TARGETINGMAP` feature instead of listing out each attribute. -``` +```html -{% endhighlight %} +``` {: .alert.alert-warning :} **Creative Expiration** @@ -107,7 +106,6 @@ Note that creatives are automatically marked as inactive by the Xandr systems af **SafeFrame** If you want your creative to serve into a SafeFrame, this will need to be enabled on the site-side of the Prebid.js implementation rather than as a setting in the ad server. A developer can learn how to enable this setting for the publisher by referencing [Using Prebid.js with Xandr Publisher Ad Server]({{site.github.url}}/dev-docs/examples/use-prebid-with-appnexus-ad-server.html). Additionally if the Xandr ad server tags are configured to use SafeFrames, you **will** need to use the above creative template to properly render the creative. Earlier versions of the Prebid.js creative template may not be fully SafeFrame compliant (if they are still in-use from older setups), so it is recommended to switch to the above template in this scenario. - ## Step 3. Set up Line Items You'll need to create one line item for every price bucket you intend to serve. @@ -116,17 +114,17 @@ For example, if you want to have $0.10 price granularity, you'll need 201 line i For each line item, follow the line item setup instructions in [Create a Line Item](https://docs.xandr.com/bundle/monetize_monetize-standard/page/topics/create-a-standard-line-item.html), with the following settings: -- Set the **Revenue Type** to *CPM*. +* Set the **Revenue Type** to *CPM*. -- Set the **Revenue Value** to one of the price bucket key-values from Step 1, e.g., \$0.2. +* Set the **Revenue Value** to one of the price bucket key-values from Step 1, e.g., \$0.2. -- Under **Associated Creatives**, choose to manage creatives at the line item level. +* Under **Associated Creatives**, choose to manage creatives at the line item level. -- Associate as many creative sizes with the line item as you need. Set the **Creative Rotation** to *Even*. +* Associate as many creative sizes with the line item as you need. Set the **Creative Rotation** to *Even*. -- In your line item's targeting settings, use the key-value that matches the line item's price bucket, e.g. (you set these up in Step 1). +* In your line item's targeting settings, use the key-value that matches the line item's price bucket, e.g. (you set these up in Step 1). -- Still in the targeting settings, target the custom category `prebid_enabled`. This will allow you to turn targeting on and off for a placement (or an entire placement group) by adding it to the custom category, which you'll do in one of the later steps. This is useful for troubleshooting. +* Still in the targeting settings, target the custom category `prebid_enabled`. This will allow you to turn targeting on and off for a placement (or an entire placement group) by adding it to the custom category, which you'll do in one of the later steps. This is useful for troubleshooting. For more information about targeting custom content categories, see [Content Category Targeting](https://docs.xandr.com/bundle/monetize_monetize-standard/page/topics/content-category-targeting.html). @@ -148,7 +146,7 @@ It will also make it easy to turn the targeting on and off for a given placement ## Related Topics -- [Ad Ops and Prebid](/adops/before-you-start.html) -- [Ad Ops Planning Guide](/adops/adops-planning-guide.html) -- [Getting Started with Prebid.js for Developers](/dev-docs/getting-started.html) -- [Using Prebid.js with Xandr Publisher Ad Server](/dev-docs/examples/use-prebid-with-appnexus-ad-server.html) (Developer example) +* [Ad Ops and Prebid](/adops/before-you-start.html) +* [Ad Ops Planning Guide](/adops/adops-planning-guide.html) +* [Getting Started with Prebid.js for Developers](/dev-docs/getting-started.html) +* [Using Prebid.js with Xandr Publisher Ad Server](/dev-docs/examples/use-prebid-with-appnexus-ad-server.html) (Developer example) diff --git a/assets/css/prism.css b/assets/css/prism.css index 7375d362..010c4405 100644 --- a/assets/css/prism.css +++ b/assets/css/prism.css @@ -8,79 +8,79 @@ https://prismjs.com/download.html#themes=prism&languages=markup+css+clike+javasc code[class*="language-"], pre[class*="language-"] { - color: black; - background: none; - text-shadow: 0 1px white; - font-family: Consolas, Monaco, 'Andale Mono', 'Ubuntu Mono', monospace; - font-size: 1em; - text-align: left; - white-space: pre; - word-spacing: normal; - word-break: normal; - word-wrap: normal; - line-height: 1.5; - - -moz-tab-size: 4; - -o-tab-size: 4; - tab-size: 4; - - -webkit-hyphens: none; - -moz-hyphens: none; - -ms-hyphens: none; - hyphens: none; + color: black; + background: none; + text-shadow: 0 1px white; + font-family: Consolas, Monaco, 'Andale Mono', 'Ubuntu Mono', monospace; + font-size: 1em; + text-align: left; + white-space: pre; + word-spacing: normal; + word-break: normal; + word-wrap: normal; + line-height: 1.5; + + -moz-tab-size: 4; + -o-tab-size: 4; + tab-size: 4; + + -webkit-hyphens: none; + -moz-hyphens: none; + -ms-hyphens: none; + hyphens: none; } pre[class*="language-"]::-moz-selection, pre[class*="language-"] ::-moz-selection, code[class*="language-"]::-moz-selection, code[class*="language-"] ::-moz-selection { - text-shadow: none; - background: #b3d4fc; + text-shadow: none; + background: #b3d4fc; } pre[class*="language-"]::selection, pre[class*="language-"] ::selection, code[class*="language-"]::selection, code[class*="language-"] ::selection { - text-shadow: none; - background: #b3d4fc; + text-shadow: none; + background: #b3d4fc; } @media print { - code[class*="language-"], - pre[class*="language-"] { - text-shadow: none; - } + code[class*="language-"], + pre[class*="language-"] { + text-shadow: none; + } } /* Code blocks */ pre[class*="language-"] { - padding: 1em; - margin: .5em 0; - overflow: auto; + padding: 1em; + margin: .5em 0; + overflow: auto; } :not(pre) > code[class*="language-"], pre[class*="language-"] { - background: #f5f2f0; + background: #f5f2f0; } /* Inline code */ :not(pre) > code[class*="language-"] { - padding: .1em; - border-radius: .3em; - white-space: normal; + padding: .1em; + border-radius: .3em; + white-space: normal; } .token.comment, .token.prolog, .token.doctype, .token.cdata { - color: slategray; + color: slategray; } .token.punctuation { - color: #999; + color: #999; } .namespace { - opacity: .7; + opacity: .7; } .token.property, @@ -90,7 +90,7 @@ pre[class*="language-"] { .token.constant, .token.symbol, .token.deleted { - color: #905; + color: #905; } .token.selector, @@ -99,7 +99,7 @@ pre[class*="language-"] { .token.char, .token.builtin, .token.inserted { - color: #690; + color: #690; } .token.operator, @@ -107,36 +107,36 @@ pre[class*="language-"] { .token.url, .language-css .token.string, .style .token.string { - color: #9a6e3a; - background: hsla(0, 0%, 100%, .5); + color: #9a6e3a; + background: hsla(0, 0%, 100%, .5); } .token.atrule, .token.attr-value, .token.keyword { - color: #07a; + color: #07a; } .token.function, .token.class-name { - color: #DD4A68; + color: #DD4A68; } .token.regex, .token.important, .token.variable { - color: #e90; + color: #e90; } .token.important, .token.bold { - font-weight: bold; + font-weight: bold; } .token.italic { - font-style: italic; + font-style: italic; } .token.entity { - cursor: help; + cursor: help; } diff --git a/assets/css/style.css b/assets/css/style.css index 0af6a31a..7f633457 100644 --- a/assets/css/style.css +++ b/assets/css/style.css @@ -37,12 +37,12 @@ h4 { /* Paragraph & Typographic */ p { - line-height: 28px; - margin-bottom: 25px; - font-family: 'Lato', sans-serif; - color: #222222; - font-size: 18px; - font-weight: 400;} + line-height: 28px; + margin-bottom: 25px; + font-family: 'Lato', sans-serif; + color: #222222; + font-size: 18px; + font-weight: 400;} .centered { text-align: center; @@ -130,228 +130,228 @@ hr { } .wrapper { - display: flex; - width: 100%; - align-items: stretch; + display: flex; + width: 100%; + align-items: stretch; } /* alerts */ .pb-alert { - padding:10px; - width:65wv; - margin: 10px 0; + padding:10px; + width:65wv; + margin: 10px 0; } .pb-alert-note { - background-color: #deecf7; - color: #4b6f8d; - border: 1px solid #4b6f8d; + background-color: #deecf7; + color: #4b6f8d; + border: 1px solid #4b6f8d; } .pb-alert-warning { - background-color: #f3ddde; - color: #a94443; - border: 1px solid #a94443; + background-color: #f3ddde; + color: #a94443; + border: 1px solid #a94443; } .pb-alert-important { - background-color: #ede5ba; - color: #85720f; - border: 1px solid #85720f; + background-color: #ede5ba; + color: #85720f; + border: 1px solid #85720f; } .pb-alert-tip { - background-color: #e3efd8; - color: #527542; - border: 1px solid #527542; + background-color: #e3efd8; + color: #527542; + border: 1px solid #527542; } /********************** - API + API *********************/ .pb-api-on { - display: block; + display: block; } .pb-api-off { - display: none; + display: none; } .pb-api-list ul { - list-style-type: none; - margin: 0; - padding: 0; - overflow: hidden; + list-style-type: none; + margin: 0; + padding: 0; + overflow: hidden; } .pb-api-list-item li { - border-bottom: 1px solid #cccccc; - border-bottom-width: 75%; - background-color:transparent; - margin-bottom: 10px; + border-bottom: 1px solid #cccccc; + border-bottom-width: 75%; + background-color:transparent; + margin-bottom: 10px; } .pb-api-list-item-sans-border li { - background-color:transparent; - margin-bottom: 10px; + background-color:transparent; + margin-bottom: 10px; } .pb-api-categories { - margin-top:15px; + margin-top:15px; } .pb-api-categories li { - float: left; - margin-right: 15px; - background-color: #eeeeee; + float: left; + margin-right: 15px; + background-color: #eeeeee; } .pb-api-categories a { - color: #333333; - font-family: 'Verdana', sans-serif; - font-size: 17px; - font-weight: 400; - padding: 4px 10px; + color: #333333; + font-family: 'Verdana', sans-serif; + font-size: 17px; + font-weight: 400; + padding: 4px 10px; } .pb-api-categories a:hover { - color: #3498db; + color: #3498db; } .pb-api-search { - float:right; - margin-right: 30px; + float:right; + margin-right: 30px; } .pb-api-title { - color: #EA9622; - font-family: 'Verdana', sans-serif; - font-size: 22px; - font-weight: 400; - margin-bottom: 10px; - margin-top: 15px; + color: #EA9622; + font-family: 'Verdana', sans-serif; + font-size: 22px; + font-weight: 400; + margin-bottom: 10px; + margin-top: 15px; } .pb-api-code { - margin: 20px 0 20px 20px; + margin: 20px 0 20px 20px; } .pb-api-code-wrapper { - margin-left: 20px; + margin-left: 20px; } .pb-api-code-display { - margin: 20px 0 0 20px; - width: 70%; + margin: 20px 0 0 20px; + width: 70%; } .pb-api-code-block { - width: 70%; - backgeound-color: #333333; + width: 70%; + backgeound-color: #333333; } .pb-api-block { - margin: 20px 0 20px 20px; + margin: 20px 0 20px 20px; } .pb-api-doc-title { - color: #EA9622; - font-family: 'Verdana', sans-serif; - font-size: 20px; - font-weight: 400; - margin-bottom: 10px; + color: #EA9622; + font-family: 'Verdana', sans-serif; + font-size: 20px; + font-weight: 400; + margin-bottom: 10px; } .pb-api-doc-description { - color: #222222; - font-size: 16px; - font-family: 'Roboto', sans-serif; - font-weight: 300; - margin-bottom:10px; + color: #222222; + font-size: 16px; + font-family: 'Roboto', sans-serif; + font-weight: 300; + margin-bottom:10px; } .pb-api-doc-description ul, ol { - font-size: 15px; + font-size: 15px; } .pb-api-code-title-bar { - background-color: #E4E8ED; - text-align: left; - border-top-left-radius: 5px; - border-top-right-radius: 5px; - padding-left: 5px; - margin-left: 20px; - margin-top: 10px; + background-color: #E4E8ED; + text-align: left; + border-top-left-radius: 5px; + border-top-right-radius: 5px; + padding-left: 5px; + margin-left: 20px; + margin-top: 10px; } .pb-api-doc-sub-title { - color: #EA9622; - font-family: 'Verdana', sans-serif; - font-size: 17px; - font-weight: 400; - margin: 15px 0; + color: #EA9622; + font-family: 'Verdana', sans-serif; + font-size: 17px; + font-weight: 400; + margin: 15px 0; } .pb-api-doc-section-title { - font-size: 17px; - font-weight: 400; - color: #333333; - margin:15px 0; + font-size: 17px; + font-weight: 400; + color: #333333; + margin:15px 0; } .pb-api-list-item-description { - margin-top 5px; - font-size:17px; + margin-top 5px; + font-size:17px; } .pb-api-table { - margin-top: 20px; - width:70%; + margin-top: 20px; + width:70%; } .pb-api-table-title { - color: #333333; - font-family: 'Verdana', sans-serif; - font-size: 17px; - font-weight: 400; - text-align: center; - background-color: #aaaaaa; - border-top-left-radius: 5px; - border-top-right-radius: 5px; + color: #333333; + font-family: 'Verdana', sans-serif; + font-size: 17px; + font-weight: 400; + text-align: center; + background-color: #aaaaaa; + border-top-left-radius: 5px; + border-top-right-radius: 5px; } .pb-api-table-text { - color: #222222; - font-size: 16px; - font-family: 'Roboto', sans-serif; - font-weight: 300; + color: #222222; + font-size: 16px; + font-family: 'Roboto', sans-serif; + font-weight: 300; } .pb-api-spacing { - margin-top: 25px; + margin-top: 25px; } .pb-api-alert { - font-size:15px; + font-size:15px; } .pb-api-button { - width: 120px; - height: 30px; - background-color: #cccccc; - border: 1px solid #333333; - color: #33333; - font-size: 15px; - font-family: 'Roboto', sans-serif; - font-weight: 400; + width: 120px; + height: 30px; + background-color: #cccccc; + border: 1px solid #333333; + color: #33333; + font-size: 15px; + font-family: 'Roboto', sans-serif; + font-weight: 400; } @@ -393,17 +393,17 @@ hr { /* API */ .categoryBox { - background-color: #f3ddde; - color: #a94443; - border: 1px solid #a94443; + background-color: #f3ddde; + color: #a94443; + border: 1px solid #a94443; } /* NavBar */ .navbar { - z-index:100 - font-family: 'Roboto', sans-serif; + z-index:100 + font-family: 'Roboto', sans-serif; } .navbar-default { @@ -428,63 +428,63 @@ hr { } .navbar-brand img { - max-width: 200px; - max-height: 35px; + max-width: 200px; + max-height: 35px; } .navbar-brand{ - float:left; - height:50px; - padding:10px 15px; - font-size:18px; - line-height:20px + float:left; + height:50px; + padding:10px 15px; + font-size:18px; + line-height:20px } .pb-mobile-nav { - display: none; + display: none; } .pb-mobile-dropdown-header { - font-size: 13px; - font-weight: 500; - color: #3498db; + font-size: 13px; + font-weight: 500; + color: #3498db; } .pb-mobile-dropdown-item { - font-size: 13px; - font-weight: 400; + font-size: 13px; + font-weight: 400; } .navbar-default .navbar-nav > li > a.pb-mobile-dropdown { - font-size:13px; - margin:0; - padding-left:5px; - padding-top:2px; - padding-bottom:2px; + font-size:13px; + margin:0; + padding-left:5px; + padding-top:2px; + padding-bottom:2px; } .pb_menu_btn { - display: none; - float:left; - margin-right: 5px; - margin-top: 10px; + display: none; + float:left; + margin-right: 5px; + margin-top: 10px; } .pb-video-list-title { - margin-top: 15px; - font-weight: 700; + margin-top: 15px; + font-weight: 700; } .pb-video-list { - margin-top: 5px; - padding-top: 0; - list-style-type:none; - font-weight:400; + margin-top: 5px; + padding-top: 0; + list-style-type:none; + font-weight:400; } .pb-video-link { - font-weight: 400; + font-weight: 400; } /* DropDown*/ @@ -495,11 +495,11 @@ hr { } .dropdown-toggle { - font-weight: 400; + font-weight: 400; } .dropdown-menu>li>a { - font-weight: 400; + font-weight: 400; } .dropdown-submenu { @@ -534,23 +534,23 @@ hr { /* 404 error */ .error404 { - width:100%; - height: 100%; - text-align: center; - margin-top: 100px; + width:100%; + height: 100%; + text-align: center; + margin-top: 100px; } .error404 h1 { - color: #FF0000; - font-size: 60px; - font-weight: bold; + color: #FF0000; + font-size: 60px; + font-weight: bold; } /************** - Sidebar + Sidebar **************/ /* side bar */ @@ -570,62 +570,62 @@ hr { .sidebar { - min-width: 300px; - background-color: #f6f8fa; - padding-left: 50px; - padding-top: 20px; - padding-bottom: 10px; - padding-right:30px; - margin-left: 0px; - font-family: 'Verdana', sans-serif; + min-width: 300px; + background-color: #f6f8fa; + padding-left: 50px; + padding-top: 20px; + padding-bottom: 10px; + padding-right:30px; + margin-left: 0px; + font-family: 'Verdana', sans-serif; } .sidebar ul { - color: #333333; + color: #333333; } .pb-section-title { - display: inline-block; - font-size:17px; - padding-bottom: 10px; - margin-top:5px; - margin-bottom: 5px; - color: #3498db; + display: inline-block; + font-size:17px; + padding-bottom: 10px; + margin-top:5px; + margin-bottom: 5px; + color: #3498db; } .pb-section-subtitle { - font-size:16px; - padding-bottom: 10px; - margin-top:5px; - margin-bottom: 5px; + font-size:16px; + padding-bottom: 10px; + margin-top:5px; + margin-bottom: 5px; } .pb-nav-item { - display:inline-block; - font-size:14px; - padding-left: 5px; + display:inline-block; + font-size:14px; + padding-left: 5px; } .pb-first-item { - padding-top: 10px; + padding-top: 10px; } .pb-last-item { - padding-bottom: 10px; + padding-bottom: 10px; } .list-group-item-header { - font-weight: 400; - font-size: 20px; + font-weight: 400; + font-size: 20px; } .list-group-item { - font-weight: 400; - margin:0; - padding: 3px 0 3px 5px; - border-width:0; - font-size: 16px; - background-color: transparent; + font-weight: 400; + margin:0; + padding: 3px 0 3px 5px; + border-width:0; + font-size: 16px; + background-color: transparent; } @@ -650,65 +650,65 @@ pre { /************* Home Page ************/ .pb-homepage { - position: relative; - margin-top:70px; - width:100%; - height: 90%; + position: relative; + margin-top:70px; + width:100%; + height: 90%; } .pb-homepage-container { - text-align: center; + text-align: center; } .pb-message-box { - display: inline-block; - width: 70%; - border: 1px solid gray; - border-radius: 50px; - font-family: 'Roboto', sans-serif; - font-size: 16px; - padding: 4px; + display: inline-block; + width: 70%; + border: 1px solid gray; + border-radius: 50px; + font-family: 'Roboto', sans-serif; + font-size: 16px; + padding: 4px; } .pb-message-box a:link { - color: #dd9e21; + color: #dd9e21; } .pb-message-box a:hover { - color: #855a09; + color: #855a09; } .pb-message-box a:visited { - color: #1689db; + color: #1689db; } .pb-align-left { - text-align: start; + text-align: start; } .pb-align-right { - text-align: right; + text-align: right; } .pb-margin-top { - margin-top:20px; + margin-top:20px; } .pb-outline { - border: 1px dashed purple; + border: 1px dashed purple; } .pb-rule { - padding-top: 10px; + padding-top: 10px; } .pb-link-title { - font-family: 'Roboto', sans-serif; - font-weight: 700; - padding-top: 5px; - padding-bottom: 10px; - border-bottom-left-radius: 20px; - border-bottom-right-radius: 20px; + font-family: 'Roboto', sans-serif; + font-weight: 700; + padding-top: 5px; + padding-bottom: 10px; + border-bottom-left-radius: 20px; + border-bottom-right-radius: 20px; } @@ -717,295 +717,295 @@ pre { /**********Container****************/ .pb-container { - width:75%; - margin-left:auto; - margin-right:auto; + width:75%; + margin-left:auto; + margin-right:auto; } .pb-outer { - width:100%; - padding-top:25%; - position:relative + width:100%; + padding-top:25%; + position:relative } .pb-inner { - position: absolute; - top: 0; - left: 0; - right: 0; - bottom: 0; + position: absolute; + top: 0; + left: 0; + right: 0; + bottom: 0; } /*************Hover Effect***************/ .pb-home-links { - width: 75%; - font-family: 'Verdana', sans-serif; - margin-left:auto; - margin-right:auto; + width: 75%; + font-family: 'Verdana', sans-serif; + margin-left:auto; + margin-right:auto; } .pb-home-links-panel { - float:left; - margin-left:auto; - margin-right: auto; - width: 33%; - height: 100%; - text-align: center; + float:left; + margin-left:auto; + margin-right: auto; + width: 33%; + height: 100%; + text-align: center; } .pb-home-links-panel img { - display: inline-block; - width: 60%; - height: 60%; + display: inline-block; + width: 60%; + height: 60%; } .pb-home-links-outer-panel { - float:left; - margin-top:40px; - margin-left:auto; - margin-right: auto; - width: 33%; - height: 100%; - text-align: center; + float:left; + margin-top:40px; + margin-left:auto; + margin-right: auto; + width: 33%; + height: 100%; + text-align: center; } .pb-home-links-outer-panel img { - display: inline-block; - width: 50%; - height: 50%; + display: inline-block; + width: 50%; + height: 50%; } .pb-home-links-panel p { - margin-top:0px; + margin-top:0px; } .pb-panel-title { - display: block; - font-size:35px; - color: #ffffff; - margin-top: 30px; + display: block; + font-size:35px; + color: #ffffff; + margin-top: 30px; } .pb-center-title { - font-size:35px; - color: #ffffff; - margin-top: 20px; + font-size:35px; + color: #ffffff; + margin-top: 20px; } .pb-home-link-container:hover .pb-home-link-visible { - display: none; + display: none; } .pb-home-link-container:hover .pb-home-link-hidden { - display: block; + display: block; } .pb-home-link-hidden { - display:none; + display:none; } .pb-lg-homelink { - width: 40%; - height: 40%; + width: 40%; + height: 40%; } .pb-md-honelink { - width:30%; - height:3 0%; + width:30%; + height:3 0%; } /**********Message****************/ .pb-message-container { - margin-top: 140px; - width:75%; - margin-left:auto; - margin-right:auto; - text-align: center; + margin-top: 140px; + width:75%; + margin-left:auto; + margin-right:auto; + text-align: center; } .pb-message { - display: inline-block; - margin-left: auto; - margin-right: auto; - width: 100%; - background-color: white; - opacity: .8; - text-align: center; - padding: 5px; + display: inline-block; + margin-left: auto; + margin-right: auto; + width: 100%; + background-color: white; + opacity: .8; + text-align: center; + padding: 5px; } .pb--empty-message { - display: inline-block; - margin-left: auto; - margin-right: auto; - width: 100%; - opacity: .8; - text-align: center; - padding: 5px; + display: inline-block; + margin-left: auto; + margin-right: auto; + width: 100%; + opacity: .8; + text-align: center; + padding: 5px; } .pb-message > h3 { - color: #333333; - font-size:1.7vw; - font-family: 'Roboto', sans-serif; - margin-right: auto; - margin-left: auto; + color: #333333; + font-size:1.7vw; + font-family: 'Roboto', sans-serif; + margin-right: auto; + margin-left: auto; } /*===========Benefits===================*/ .pb_benefits { - background-color: #ffffff; - width: 80%; - padding-bottom: 40px; - margin-top:260px; - margin-left: auto; - margin-right: auto; - opacity:.80; - overflow:hidden; + background-color: #ffffff; + width: 80%; + padding-bottom: 40px; + margin-top:260px; + margin-left: auto; + margin-right: auto; + opacity:.80; + overflow:hidden; } .pb-benefits-title { - text-align: center; - padding-top:5px; - padding-bottom:5px; + text-align: center; + padding-top:5px; + padding-bottom:5px; } .pb-benefits-title > h2 { - font-family: 'Roboto', sans-serif; - color: #47547c; - font-size:3.5vw; - font-weight: 400; + font-family: 'Roboto', sans-serif; + color: #47547c; + font-size:3.5vw; + font-weight: 400; } .pb-benefits-container { - width: 100%; - height: 100%; + width: 100%; + height: 100%; } .pb-benefits-row { - display: inline-block; - width:100%; - height: 42%; + display: inline-block; + width:100%; + height: 42%; } .pb-benefits-panel { - width:100%; - height:100%; - margin-top:100px; + width:100%; + height:100%; + margin-top:100px; } .pb-benefits-panel-left { - float:left; - width:50%; + float:left; + width:50%; } .pb-benefits-panel-right { - float:right; - width:50%; - padding-right: 5%; + float:right; + width:50%; + padding-right: 5%; } .pb-benefits-panel-img { - float: left; - height: 100%; - width:30%; - text-align:right; - padding-right:10px; + float: left; + height: 100%; + width:30%; + text-align:right; + padding-right:10px; } .pb-benefits-panel-img > img { - max-width:60%; - max-height:60%; + max-width:60%; + max-height:60%; } .pb-benefits-panel-content { - float:right; - height: 100%; - width:70%; + float:right; + height: 100%; + width:70%; } .pb-benefits-panel-content-title { - font-family: 'Roboto', sans-serif; - color: #47547c; - font-size:2.5vw; - font-weight: 400; + font-family: 'Roboto', sans-serif; + color: #47547c; + font-size:2.5vw; + font-weight: 400; } .pb-benefits-panel-content-text { - font-family: 'Lato', sans-serif; - color: #47547c; - font-size:1.7vw; - font-weight: 400; + font-family: 'Lato', sans-serif; + color: #47547c; + font-size:1.7vw; + font-weight: 400; } /************ Carousel ****************/ .pb_home_belowfold_carousel { - border-top-left-radius: 12px; - border-top-right-radius: 12px; - padding-top: 20px; - text-align:center; + border-top-left-radius: 12px; + border-top-right-radius: 12px; + padding-top: 20px; + text-align:center; } .pb_carousel_title { - margin-top:100px; - margin-bottom:50px; - margin-left:auto; - margin-right:auto; - padding-bottom: 10px; - color: #ffffff; - font-family: 'Roboto', sans-serif; - font-size: 4vw; - font-weight: 700; + margin-top:100px; + margin-bottom:50px; + margin-left:auto; + margin-right:auto; + padding-bottom: 10px; + color: #ffffff; + font-family: 'Roboto', sans-serif; + font-size: 4vw; + font-weight: 700; } .carousel-item > h3 { - font-family: 'Roboto', sans-serif; - font-size: 2.4vw; - padding-top: 5px; - padding-bottom:3px; - border-top-left-radius: 12px; - border-top-right-radius: 12px; - background-color: #47547c; - color: #ffffff; - margin:0; + font-family: 'Roboto', sans-serif; + font-size: 2.4vw; + padding-top: 5px; + padding-bottom:3px; + border-top-left-radius: 12px; + border-top-right-radius: 12px; + background-color: #47547c; + color: #ffffff; + margin:0; } .carousel-item > h4 { - font-family: 'Lato', sans-serif; - font-size: 1.7vw; - color: #47547c; - padding-left: 10px; - padding-right: 10px; + font-family: 'Lato', sans-serif; + font-size: 1.7vw; + color: #47547c; + padding-left: 10px; + padding-right: 10px; } .slide { - background-color: #ffffff; - width: 70%; - height:250px; - margin-left: auto; - margin-right: auto; - border-top-left-radius: 12px; - border-top-right-radius: 12px; + background-color: #ffffff; + width: 70%; + height:250px; + margin-left: auto; + margin-right: auto; + border-top-left-radius: 12px; + border-top-right-radius: 12px; } .item { - text-align: center; + text-align: center; } .pb_carousel_indicators { - margin-top: 150px; + margin-top: 150px; } @@ -1106,58 +1106,58 @@ pre { /************ Partners ****************/ .partners { - text-align: center; + text-align: center; } .partners div.title { - width:100%; - padding-top: 30px; + width:100%; + padding-top: 30px; } .partners div.tableTitle { - width:100%; - padding-top: 30px; - padding-bottom: 30px; + width:100%; + padding-top: 30px; + padding-bottom: 30px; } .partners h3 { - margin:0; - padding: 0; - font-size:large; + margin:0; + padding: 0; + font-size:large; } .partners img.founders { - width: 100px; + width: 100px; } .partners img.standard { - width: 125px; + width: 125px; } .pb_tbl_title h3 { - padding-bottom: 20px; + padding-bottom: 20px; } .pb_standard_tbl td { - padding-left: 10px; - padding-right: 10px; + padding-left: 10px; + padding-right: 10px; } .partners ul { - list-style-type: none; + list-style-type: none; display: table; - width: 100%; + width: 100%; } .partners li { - display: table-cell; - text-align: center; + display: table-cell; + text-align: center; } .partners a[href^="http://"]:after, @@ -1166,7 +1166,7 @@ pre { } .pb-sm-img { - width: 50%; + width: 50%; height: 50%; } @@ -1177,7 +1177,7 @@ pre { } .pb-lg-img { - width: 70%; + width: 70%; height: 70%; } @@ -1186,105 +1186,105 @@ pre { } /**************************** - Blog + Blog ***************************/ .pb-blog { - margin-left:50px; - font-family: 'Verdana', sans-serif; - font-size: 34px; - font-weight: 400; + margin-left:50px; + font-family: 'Verdana', sans-serif; + font-size: 34px; + font-weight: 400; } .pb-blog h1 { - display: table; - padding: 3px 8px; - font-family: 'Verdana', sans-serif; - color: #ffffff; - font-size: 34px; - font-weight: 400; + display: table; + padding: 3px 8px; + font-family: 'Verdana', sans-serif; + color: #ffffff; + font-size: 34px; + font-weight: 400; } /******************************** - Content Pages + Content Pages *********************************/ .bs-docs-container { - margin-top: 70px; - margin-left:0; + margin-top: 70px; + margin-left:0; } .col-sm-9 { - padding-top: 20px; - margin:0; + padding-top: 20px; + margin:0; } .pb-content { - padding: 20px; - margin-left: 20px; + padding: 20px; + margin-left: 20px; } .pb-blog p { - font-family: 'Lato', sans-serif; - color: #222222; - font-size: 16px; - font-weight: 400; + font-family: 'Lato', sans-serif; + color: #222222; + font-size: 16px; + font-weight: 400; } .pb-content h1 { - /*background-color: #EA9622;*/ - display: table; - padding: 3px 0px; - font-family: 'Verdana', sans-serif; - color: #EA9622; - font-size: 34px; - font-weight: 400; - width:75wv; + /*background-color: #EA9622;*/ + display: table; + padding: 3px 0px; + font-family: 'Verdana', sans-serif; + color: #EA9622; + font-size: 34px; + font-weight: 400; + width:75wv; } .pb-content, .pb-blog h2 { - font-family: 'Verdana', sans-serif; - color: #000000; - font-size: 27px; - font-weight: 400; + font-family: 'Verdana', sans-serif; + color: #000000; + font-size: 27px; + font-weight: 400; } .pb-content, .pb-blog h3 { - font-family: 'Verdana', sans-serif; - color: #333333; - font-size: 24px; - font-weight: 400; + font-family: 'Verdana', sans-serif; + color: #333333; + font-size: 24px; + font-weight: 400; } .pb-content, .pb-blog h4 { - font-family: 'Verdana', sans-serif; - color: #333333; - font-size: 20px; - font-weight: 400; + font-family: 'Verdana', sans-serif; + color: #333333; + font-size: 20px; + font-weight: 400; } .pb-content, .pb-blog h5 { - font-family: 'Verdana', sans-serif; - color: #333333; - font-size: 18px; - font-weight: 400; + font-family: 'Verdana', sans-serif; + color: #333333; + font-size: 18px; + font-weight: 400; } .pb-content, .pb-blog ul, ol, li { - font-family: 'Lato', sans-serif; - font-size: 18px; + font-family: 'Lato', sans-serif; + font-size: 18px; } .pb-img, ,pb-blog { @@ -1297,633 +1297,633 @@ pre { /************* - Footer + Footer ******************/ .pb_footer { - display: block; - width: 75%; - font-family: 'Dosis', sans-serif; - font-weight: 400; - font-size:21px; - padding-top: 30px 0; - margin-left: auto; - margin-right: auto; - text-align: center; + display: block; + width: 75%; + font-family: 'Dosis', sans-serif; + font-weight: 400; + font-size:21px; + padding-top: 30px 0; + margin-left: auto; + margin-right: auto; + text-align: center; } /************ Was This Helpful Form ****************/ .wthHeader { - background-color: #EA9622; - border-top-left-radius: 5px; - border-top-right-radius: 5px; - height: 10px; - width: 100%; - margin-bottom: 15px; + background-color: #EA9622; + border-top-left-radius: 5px; + border-top-right-radius: 5px; + height: 10px; + width: 100%; + margin-bottom: 15px; } .wthBordered { - border: 1px solid #cccccc; - border-top-left-radius: 5px; - border-top-right-radius: 5px; - margin-top: 10px; - padding-left: 7px; + border: 1px solid #cccccc; + border-top-left-radius: 5px; + border-top-right-radius: 5px; + margin-top: 10px; + padding-left: 7px; } .wthForm { - padding-left: 15px; + padding-left: 15px; } .wthForm.input { - margin-top: 5px; - margin-bottom: 5px; + margin-top: 5px; + margin-bottom: 5px; } .wthSubmit { - margin-top: 5px; - margin-bottom: 5px; + margin-top: 5px; + margin-bottom: 5px; } .wthLabel { - font-family: 'Lato', sans-serif; - font-weight: 400; - font-size:18px; - color: #EA9622; - margin-top: 5px; - margin-bottom: 5px; + font-family: 'Lato', sans-serif; + font-weight: 400; + font-size:18px; + color: #EA9622; + margin-top: 5px; + margin-bottom: 5px; } .wthTitle { - font-family: 'Lato', sans-serif; - font-weight: 700; - font-size:24px; - color: #3498db; + font-family: 'Lato', sans-serif; + font-weight: 700; + font-size:24px; + color: #3498db; } /* - Responsive - There are 3 trigger levels, 1024, 768 and 480 + Responsive + There are 3 trigger levels, 1024, 768 and 480 */ /*small browsers*/ @media screen and (max-width: 1300px) { - .pb-top-text h1 { - font-size:60px; - } + .pb-top-text h1 { + font-size:60px; + } - .pb-top-text h2 { - font-size:30px; - } + .pb-top-text h2 { + font-size:30px; + } - .pb-panel-title { - font-size:33px; - } + .pb-panel-title { + font-size:33px; + } - .slide { - height: 140px; - } + .slide { + height: 140px; + } - } + } - /*iPad Pro*/ - @media screen and (max-width: 1024px) { + /*iPad Pro*/ + @media screen and (max-width: 1024px) { - .pb-message-container { - margin-top: 100px; - } + .pb-message-container { + margin-top: 100px; + } - .pb_benefits { - margin-top: 50px; - } + .pb_benefits { + margin-top: 50px; + } - .pb-benefits-panel { - margin-top:0px; + .pb-benefits-panel { + margin-top:0px; - .carousel-inner h3 { - font-size: 30px; - } + .carousel-inner h3 { + font-size: 30px; + } - .carousel-inner h4 { - padding-top: 20px; - font-size: 24px; - } + .carousel-inner h4 { + padding-top: 20px; + font-size: 24px; + } - .pb_carousel_indicators { - margin-top: 100px; - } + .pb_carousel_indicators { + margin-top: 100px; + } - .bs-docs-section { - line-height: 1.6; - font-size: large; - margin-right: 10em; - } + .bs-docs-section { + line-height: 1.6; + font-size: large; + margin-right: 10em; + } - .slide { - height: 160px; - } + .slide { + height: 160px; + } - .container { - width: 88%; - } + .container { + width: 88%; + } - } + } - /*iPad */ - @media screen and (max-width: 768px) { + /*iPad */ + @media screen and (max-width: 768px) { - .pb-top-text h1 { - font-size:40px; - } + .pb-top-text h1 { + font-size:40px; + } - .pb-top-text h2 { - font-size:20px; - } + .pb-top-text h2 { + font-size:20px; + } - .pb-panel-title { - font-size:30px; - } + .pb-panel-title { + font-size:30px; + } - .pb_benefits { - margin-top: 50px; - } + .pb_benefits { + margin-top: 50px; + } - .pb_carousel_title { - margin-top:50px; - margin-bottom:10px; - } + .pb_carousel_title { + margin-top:50px; + margin-bottom:10px; + } - .slide { - height: 110px; - } + .slide { + height: 110px; + } - .pb_carousel_indicators { - margin-top: 150px; - } + .pb_carousel_indicators { + margin-top: 150px; + } - } + } - /*iPhone Plus */ - @media screen and (max-width: 414px) { + /*iPhone Plus */ + @media screen and (max-width: 414px) { - /* hide side nav on phone devices*/ - #sidebar { - display: none; - } + /* hide side nav on phone devices*/ + #sidebar { + display: none; + } - .pb-top-text h1 { - font-size:20px; - } + .pb-top-text h1 { + font-size:20px; + } - .pb-top-text h2 { - font-size:12px; - } + .pb-top-text h2 { + font-size:12px; + } - .pb-home-links-panel { - margin-top: -10px; - } + .pb-home-links-panel { + margin-top: -10px; + } - .pb-outer-title { - margin-top: 5px; - } + .pb-outer-title { + margin-top: 5px; + } - .pb-home-links { - margin-top:-10px; - } + .pb-home-links { + margin-top:-10px; + } - .pb-home-links-outer-panel { - margin-top:20px; - } + .pb-home-links-outer-panel { + margin-top:20px; + } - .pb-panel-title { - font-size:14px; - } + .pb-panel-title { + font-size:14px; + } - .pb-message-container { - margin-top: 50px; - } + .pb-message-container { + margin-top: 50px; + } - .pb_benefits { - margin-top: 20px; - } + .pb_benefits { + margin-top: 20px; + } - .pb_carousel_title { - margin-top:-10px; - margin-bottom:20px; - } + .pb_carousel_title { + margin-top:-10px; + margin-bottom:20px; + } - .slide { - height: 70px; - } + .slide { + height: 70px; + } - .pb-main-nav { - display:none; - } + .pb-main-nav { + display:none; + } - .pb-mobile-nav { - display: block; - } + .pb-mobile-nav { + display: block; + } - .pb_carousel_indicators { - margin-top: 10px; - height: 10px; - } + .pb_carousel_indicators { + margin-top: 10px; + height: 10px; + } - .pb-content { - width: 85%; - margin-left: -20px; - } + .pb-content { + width: 85%; + margin-left: -20px; + } - .pb-content p { - font-size: 15px; - font-weight: 400; - line-height: inherit; - width: 85%; - } + .pb-content p { + font-size: 15px; + font-weight: 400; + line-height: inherit; + width: 85%; + } - } + } - /* iPhone X*/ - @media screen and (max-width: 375px) { + /* iPhone X*/ + @media screen and (max-width: 375px) { - .pb-top-text h1 { - font-size:22px; - } + .pb-top-text h1 { + font-size:22px; + } - .pb-top-text h2 { - font-size:11px; - margin-top: 0px; - } + .pb-top-text h2 { + font-size:11px; + margin-top: 0px; + } - .pb-panel-title { - font-size:12px; - } + .pb-panel-title { + font-size:12px; + } - .pb-home-links-panel { - margin-top: -15px; - } + .pb-home-links-panel { + margin-top: -15px; + } - .pb_benefits { - margin-top: 40px; - } + .pb_benefits { + margin-top: 40px; + } - .pb_home_belowfold_carousel { - padding-top: 60px; - } + .pb_home_belowfold_carousel { + padding-top: 60px; + } - .pb_carousel_title { - margin-top:-20px; - margin-bottom:0px; - } + .pb_carousel_title { + margin-top:-20px; + margin-bottom:0px; + } - .slide { - height: 80px; - } + .slide { + height: 80px; + } - .pb_carousel_indicators { - margin-top: 0px; - height: 22px; - } + .pb_carousel_indicators { + margin-top: 0px; + height: 22px; + } - .carousel-indicators { - padding-top: 140px; - } + .carousel-indicators { + padding-top: 140px; + } - } + } - /* iPhone 6, 7, 8 Galaxy S5 (different width) */ - @media screen and (max-width: 360px) { + /* iPhone 6, 7, 8 Galaxy S5 (different width) */ + @media screen and (max-width: 360px) { - .pb-top-text h1 { - font-size:18px; - } + .pb-top-text h1 { + font-size:18px; + } - .pb-top-text > h2 { - font-size:9px; - margin-top: 0px; - } + .pb-top-text > h2 { + font-size:9px; + margin-top: 0px; + } - .pb-home-links-outer-panel { - margin-top:10px; - } + .pb-home-links-outer-panel { + margin-top:10px; + } - .pb_benefits { - margin-top: 70px; - } + .pb_benefits { + margin-top: 70px; + } - } + } - /*iPhone 5*/ - @media screen and (max-width: 320px) { + /*iPhone 5*/ + @media screen and (max-width: 320px) { - .pb-home-links-outer-panel { - margin-top:3px; - } + .pb-home-links-outer-panel { + margin-top:3px; + } - .pb_benefits { - margin-top: 50px; - } + .pb_benefits { + margin-top: 50px; + } - } + } @media screen and (max-width: 768px) { - .col-sm-9 { - padding-top: 10px; - } + .col-sm-9 { + padding-top: 10px; + } - .pb-content { + .pb-content { - font-size: 15px; - font-weight: 400; - width: 85%; - margin-left: 0px; - - } - - .pb-content p { - font-size: 15px; - font-weight: 400; - line-height: inherit; - width: 85%; - } - - .pb-content li { - font-size: 15px; - font-weight: 400; - } - - .pb-content h1 { - font-size: 24px; - } - - .pb-content h2 { - font-size: 20px; - } - - .pb-content h3 { - font-size: 18px; - } - - .pb_footer { - display: block; - font-size:15px; - } - - /*Previous @media*/ - - #pb-home-demo { - margin-top: 30px; - } - - #pb-home-demo .col-sm-7 .lead { - margin-left: 0; - padding-left: 0; - } - - .pb-sm-left { - text-align: left; - } - - .pb-sm-center { - text-align: center; - } - - .pb-sm-right { - text-align: right; - } - - .pb-img { - -webkit-box-shadow: 2px 2px 8px -2px rgba(0,0,0,0.35); - -moz-box-shadow: 2px 2px 8px -2px rgba(0,0,0,0.35); - box-shadow: 2px 2px 8px -2px rgba(0,0,0,0.35); - margin-top: 10px; - margin-bottom: 10px; - } - - - .blog-related-posts { - color: #aaa; - margin-top: 40px; - } - - .bs-callout code { - background-color: transparent; - } - - .bs-docs-footer { - margin-top: 60px; - } - - - .nav.nav-tabs { - margin-bottom: 15px; - font-weight: bold; - } - - .bs-callout { - padding-top: 0px; - padding-bottom: 10px; - } - - #chart_div { - height: 400px; - } - - .docs-sidebar { - margin-top: 20px; - padding: 20px; - padding-top: 10px; - padding-bottom: 10px; - border-radius: 2px; - } - - .docs-sidebar .nav>li>a{ - padding: 0px; - padding-bottom: 10px; - color: #555; - } - - .docs-sidebar .nav>li>a:hover{ - color: #337ab7; - background: transparent; - } - - .docs-sidebar .nav>li>a.selected { - color: #337ab7; - } - - .docs-sidebar h5 { - font-weight: 700; - font-size: 13px; - margin-top: 15px; - } - - .bs-docs-nav { - border-bottom: solid 1px #AAA; - } - - .bg-info { - padding: 10px; - border-radius: 5px; - } - - .bg-warning { - padding: 10px; - border-radius: 5px; - margin-bottom: 5px; - } - - .bg-danger { - padding: 10px; - border-radius: 5px; - } - - table.jsfiddle-line-number { - width: 100%; - border: 0; - } - - table.jsfiddle-line-number .line-number { - padding-top: 61px; - vertical-align: text-top; - line-height: 21px; - width: 17px; - color: #aaa; - font-size: 13px; - text-align: right; - } - - .blog-date { - margin-top: 45px; - text-align: right; - width: 80%; - font-size: 20px; - color: #aaa; - } - - #example-tab { - padding-left:10px; - } - - #example-tab li { - margin-bottom: 6px; - } - - table:not(.jsfiddle-line-number) { - table-layout: fixed; - word-wrap: break-word; - } - - div.pl-doc-entry{ - position: absolute; - } - - .prebid-mobile-notice { - margin-top: 2em; - } - - .pb-lg-img { - width: 85%; - height: 85%; - } - - .pb-xlg-img { + font-size: 15px; + font-weight: 400; + width: 85%; + margin-left: 0px; + + } + + .pb-content p { + font-size: 15px; + font-weight: 400; + line-height: inherit; + width: 85%; + } + + .pb-content li { + font-size: 15px; + font-weight: 400; + } + + .pb-content h1 { + font-size: 24px; + } + + .pb-content h2 { + font-size: 20px; + } + + .pb-content h3 { + font-size: 18px; + } + + .pb_footer { + display: block; + font-size:15px; + } + + /*Previous @media*/ + + #pb-home-demo { + margin-top: 30px; + } + + #pb-home-demo .col-sm-7 .lead { + margin-left: 0; + padding-left: 0; + } + + .pb-sm-left { + text-align: left; + } + + .pb-sm-center { + text-align: center; + } + + .pb-sm-right { + text-align: right; + } + + .pb-img { + -webkit-box-shadow: 2px 2px 8px -2px rgba(0,0,0,0.35); + -moz-box-shadow: 2px 2px 8px -2px rgba(0,0,0,0.35); + box-shadow: 2px 2px 8px -2px rgba(0,0,0,0.35); + margin-top: 10px; + margin-bottom: 10px; + } + + + .blog-related-posts { + color: #aaa; + margin-top: 40px; + } + + .bs-callout code { + background-color: transparent; + } + + .bs-docs-footer { + margin-top: 60px; + } + + + .nav.nav-tabs { + margin-bottom: 15px; + font-weight: bold; + } + + .bs-callout { + padding-top: 0px; + padding-bottom: 10px; + } + + #chart_div { + height: 400px; + } + + .docs-sidebar { + margin-top: 20px; + padding: 20px; + padding-top: 10px; + padding-bottom: 10px; + border-radius: 2px; + } + + .docs-sidebar .nav>li>a{ + padding: 0px; + padding-bottom: 10px; + color: #555; + } + + .docs-sidebar .nav>li>a:hover{ + color: #337ab7; + background: transparent; + } + + .docs-sidebar .nav>li>a.selected { + color: #337ab7; + } + + .docs-sidebar h5 { + font-weight: 700; + font-size: 13px; + margin-top: 15px; + } + + .bs-docs-nav { + border-bottom: solid 1px #AAA; + } + + .bg-info { + padding: 10px; + border-radius: 5px; + } + + .bg-warning { + padding: 10px; + border-radius: 5px; + margin-bottom: 5px; + } + + .bg-danger { + padding: 10px; + border-radius: 5px; + } + + table.jsfiddle-line-number { + width: 100%; + border: 0; + } + + table.jsfiddle-line-number .line-number { + padding-top: 61px; + vertical-align: text-top; + line-height: 21px; + width: 17px; + color: #aaa; + font-size: 13px; + text-align: right; + } + + .blog-date { + margin-top: 45px; + text-align: right; + width: 80%; + font-size: 20px; + color: #aaa; + } + + #example-tab { + padding-left:10px; + } + + #example-tab li { + margin-bottom: 6px; + } + + table:not(.jsfiddle-line-number) { + table-layout: fixed; + word-wrap: break-word; + } + + div.pl-doc-entry{ + position: absolute; + } + + .prebid-mobile-notice { + margin-top: 2em; + } + + .pb-lg-img { + width: 85%; + height: 85%; + } + + .pb-xlg-img { width: 100%; } - .pb-md-img { - width: 60%; - height: 60%; - } + .pb-md-img { + width: 60%; + height: 60%; + } - #pb-home-demo { - margin-top: 30px; - } + #pb-home-demo { + margin-top: 30px; + } - #pb-home-demo .col-sm-7 .lead { - margin-left: 0; - padding-left: 0; - } + #pb-home-demo .col-sm-7 .lead { + margin-left: 0; + padding-left: 0; + } - .pb-sm-left { - text-align: left; - } + .pb-sm-left { + text-align: left; + } - .pb-sm-center { - text-align: center; - } + .pb-sm-center { + text-align: center; + } - .pb-sm-right { - text-align: right; - } + .pb-sm-right { + text-align: right; + } } @media screen and (max-width: 414px) { - #wrapper { - padding-left: 0; - -webkit-transition: all 0.5s ease; - -moz-transition: all 0.5s ease; - -o-transition: all 0.5s ease; - transition: all 0.5s ease; - } - - #wrapper.toggled { - padding-left: 250px; - } - - #sidebar-wrapper { - z-index: 1000; - position: fixed; - left: 250px; - width: 0; - height: 100%; - margin-left: -250px; - overflow-y: auto; - background: #f6f8fa; - -webkit-transition: all 0.5s ease; - -moz-transition: all 0.5s ease; - -o-transition: all 0.5s ease; - transition: all 0.5s ease; - } - - #wrapper.toggled #sidebar-wrapper { - width: 250px; - } - - .pb-lg-img { - width: 65%; - height: 65%; - } - - .pb-xlg-img { + #wrapper { + padding-left: 0; + -webkit-transition: all 0.5s ease; + -moz-transition: all 0.5s ease; + -o-transition: all 0.5s ease; + transition: all 0.5s ease; + } + + #wrapper.toggled { + padding-left: 250px; + } + + #sidebar-wrapper { + z-index: 1000; + position: fixed; + left: 250px; + width: 0; + height: 100%; + margin-left: -250px; + overflow-y: auto; + background: #f6f8fa; + -webkit-transition: all 0.5s ease; + -moz-transition: all 0.5s ease; + -o-transition: all 0.5s ease; + transition: all 0.5s ease; + } + + #wrapper.toggled #sidebar-wrapper { + width: 250px; + } + + .pb-lg-img { + width: 65%; + height: 65%; + } + + .pb-xlg-img { width: 100%; } - .pb-md-img { - width: 45%; - height: 45%; - } + .pb-md-img { + width: 45%; + height: 45%; + } - .pb_footer { - display: block; - font-size:10px; - } + .pb_footer { + display: block; + font-size:10px; + } } @@ -2113,21 +2113,21 @@ div.pl-doc-entry{ } /******************* - API + API .categoryBox { - display:block; - float: left; - margin-right:10px; - line-height:40px; - height: 40px; - padding-left: 15px; - padding-right: 15px; - background-color:#f6f8fa; - text-align:center; + display:block; + float: left; + margin-right:10px; + line-height:40px; + height: 40px; + padding-left: 15px; + padding-right: 15px; + background-color:#f6f8fa; + text-align:center; } diff --git a/dev-docs/activity-controls.md b/dev-docs/activity-controls.md index c4642272..2b01c465 100644 --- a/dev-docs/activity-controls.md +++ b/dev-docs/activity-controls.md @@ -19,8 +19,8 @@ These controls are intended to serve as building blocks for privacy protection m There are many privacy regulations that Prebid publishers need to accomodate. Prebid supplies [modules](/dev-docs/faq.html#how-does-prebid-support-privacy-regulations) to help Publishers implement their legal policies, but there are scenarios where extra control is needed: -- a Publisher's lawyers want to make a particular exception -- a module hasn't been built for a regulation the Publisher needs to support +* a Publisher's lawyers want to make a particular exception +* a module hasn't been built for a regulation the Publisher needs to support ### Prebid Is a Toolkit @@ -37,19 +37,19 @@ Important: This resource should not be construed as legal advice and Prebid.org We did an analysis of the things Prebid.js does and identified those related to privacy regulations. We call these things "potentially restricted activities", or just "activities" for short. Here are some: -- Setting a cookie -- Syncing ID cookies -- Transmitting user first party data -- etc. +* Setting a cookie +* Syncing ID cookies +* Transmitting user first party data +* etc. The [full list of activities Prebid.js supports](#activities) is below. Think of an activity control as a 'gatekeeper' that makes the decision about whether the activity should be allowed in this specific context: -- Should I allow this cookie to be set for bidderA? -- Should I allow this usersync for bidderB? -- Is it ok for this data to be passed to bidderC and analyticsD? -- etc. +* Should I allow this cookie to be set for bidderA? +* Should I allow this usersync for bidderB? +* Is it ok for this data to be passed to bidderC and analyticsD? +* etc. Prebid.js core checks with the Activity Controls to see whether an activity is allowed. The configuration for the activity can come from modules, custom functions in the page, or a rule-based JSON config. @@ -60,7 +60,7 @@ In this example, bidderX wants to set a cookie through StorageManager, which que Here's an example JSON config that disables accessing local storage (including cookies) for everything except the bid adapter `bidderX`: -``` +```javascript pbjs.setConfig({ allowActivities: { accessDevice: { @@ -76,14 +76,14 @@ pbjs.setConfig({ }) ``` -
+ ## Configuration `allowActivities` is a new option to [setConfig](/dev-docs/publisher-api-reference/setConfig.html). It contains a list of activity names -- see the [full list of activities below](#activities). Each activity is an object that can contain these attributes: {: .table .table-bordered .table-striped } -| Name | Type | Description | +| Name | Type | Description | |------|------|-------------| | `default` | Boolean | Whether the activity should be allowed if no other rule applies. Defaults to true. | | `rules` | Array of objects | Rules for this activity | @@ -93,14 +93,14 @@ pbjs.setConfig({ `Rules` is an array of objects that a publisher can contruct to provide fine-grained control over a given activity. For instance, you could set up a series of rules that says: -- Amongst the bid adapters, BidderA is always allowed to receive user first party data -- Always let analytics adapters receive user first party data -- otherwise, let the active privacy modules decide -- if they refuse to decide, then the overall default is to allow the transmitting of user first party data +* Amongst the bid adapters, BidderA is always allowed to receive user first party data +* Always let analytics adapters receive user first party data +* otherwise, let the active privacy modules decide +* if they refuse to decide, then the overall default is to allow the transmitting of user first party data There's more about [rules](#parameters) below. - + ### Activities @@ -112,7 +112,7 @@ Here's the list of the 'potentially restricted activities' that Prebid.js core c | `accessDevice` | A component wants to use device storage | Storage is disabled | [`storageType`](#params-accessDevice) | | `enrichEids` | A user ID or RTD submodule wants to add user IDs to outgoing requests | User IDs are discarded | None | | `enrichUfpd` | A Real Time Data (RTD) submodule wants to add user first party data to outgoing requests (`user.data` in ORTB) | User FPD is discarded | None | -| `fetchBids` | A bid adapter wants to participate in an auction | Bidder is removed from the auction | [`configName`](#params-fetchBids) | +| `fetchBids` | A bid adapter wants to participate in an auction | Bidder is removed from the auction | [`configName`](#params-fetchBids) | | `reportAnalytics` | An analytics adapter is being enabled through `pbjs.enableAnalytics` | Adapter remains disabled | None | | `syncUser` | A bid adapter wants to fetch a [user sync](/dev-docs/publisher-api-reference/setConfig.html#setConfig-Configure-User-Syncing) | User sync is skipped | [`syncType`, `syncUrl`](#params-syncUser) | | `transmitEids` | A bid adapter or RTD submodule wants to access and/or transmit user IDs to their endpoint | User IDs are hidden from the component | [`configName`](#params-fetchBids) | @@ -121,37 +121,38 @@ Here's the list of the 'potentially restricted activities' that Prebid.js core c | `transmitUfpd` | A bid adapter or RTD submodule wants to access and/or transmit user FPD to their endpoint | User FPD is hidden from the component | [`configName`](#params-fetchBids) | - + ### Rules - - There are three parts to an Activity Control's rule: - + +There are three parts to an Activity Control's rule: + 1. The priority 2. The condition 3. The allow flag - For example, this rule would allow bidderX to perform the activity if no higher priority rules take precedence. - ``` - ... - rules: [{ - priority: 10, // average priority - condition(params) { - return params.componentName === 'bidderX' - }, - allow: true - }] - ... +For example, this rule would allow bidderX to perform the activity if no higher priority rules take precedence. + +```javascript +... + rules: [{ + priority: 10, // average priority + condition(params) { + return params.componentName === 'bidderX' + }, + allow: true + }] +... ``` - + #### Rule Priority Activity control rules in Prebid.js can be created by two main sources: -- Publisher `setConfig({allowActivities})` as in the examples shown here. When set this way, rules are consider the highest priority value of 1. -- Modules can set activity control rules, e.g. [usersync](/dev-docs/publisher-api-reference/setConfig.html#setConfig-Configure-User-Syncing), [bidderSettings](/dev-docs/publisher-api-reference/bidderSettings.html), the [GPP](/dev-docs/modules/consentManagementGpp.html) or [GDPR](/dev-docs/modules/gdprEnforcement.html) modules. Rules set by modules have a less urgent priority of 10. +* Publisher `setConfig({allowActivities})` as in the examples shown here. When set this way, rules are consider the highest priority value of 1. +* Modules can set activity control rules, e.g. [usersync](/dev-docs/publisher-api-reference/setConfig.html#setConfig-Configure-User-Syncing), [bidderSettings](/dev-docs/publisher-api-reference/bidderSettings.html), the [GPP](/dev-docs/modules/consentManagementGpp.html) or [GDPR](/dev-docs/modules/gdprEnforcement.html) modules. Rules set by modules have a less urgent priority of 10. When rules are processed, they are sorted by priority, and all rules of the same priority are considered to happen at the same time. The details: @@ -204,7 +205,7 @@ pbjs.setConfig({ ``` #### Rule Conditions - + A `condition` is a javascript function that receives information about the activity that is about to be performed. If a condition evaluates to true, the `allow` attribute of the rule will be utilized. If there's no condition specified, the rule's `allow` attribute will always be utilized. These are the parameters available to the condition function: @@ -212,13 +213,13 @@ These are the parameters available to the condition function: {: .table .table-bordered .table-striped } | Name | Type | Available for | Description | |------|------|-------------|---------------| -| `componentType` | String | All activities | One of: `'bidder'`, `'userId'`, `'rtd'`, `'analytics'`, or `'prebid'`; identifies the type of component (usually a module) that wishes to perform the activity. `'prebid'` is reserved for Prebid core itself and a few "privileged" modules such as the [PBS adapter](/dev-docs/modules/prebidServer.html). | +| `componentType` | String | All activities | One of: `'bidder'`, `'userId'`, `'rtd'`, `'analytics'`, or `'prebid'`; identifies the type of component (usually a module) that wishes to perform the activity. `'prebid'` is reserved for Prebid core itself and a few "privileged" modules such as the [PBS adapter](/dev-docs/modules/prebidServer.html). | | `componentName` | String | All activities | Name of the component; this is (depending on the type) either a bidder code, user ID or RTD submodule name, analytics provider code, or module name. | | `component` | String | All activities | This is always a dot-separated concatenation of `componentType` and `componentName`; for example, with `{componentType: 'bidder', componentName: 'bidderX'}`, `component` is `'bidder.bidderX'`. | | `adapterCode` | String | All activities | If `componentType` is `'bidder'`, and `componentName` is an [alias](/dev-docs/publisher-api-reference/aliasBidder.html), then `adapterCode` is the bidder code that was aliased; or identical to `componentName` if the bidder is not an alias. This is undefined when the component is not a bidder.| -| `configName` | String | `fetchBids` | When the Prebid Server adapter is part of an auction, this is the name given to its [s2s configuration](/dev-docs/modules/prebidServer.md), if any. | -| `storageType` | String | `accessDevice` | Either `'html5'` or `'cookie'` - the device storage mechanism being accessed. | -| `syncType` | String | `syncUser` | Either `'iframe'` or `'image'` - the type of user sync. | +| `configName` | String | `fetchBids` | When the Prebid Server adapter is part of an auction, this is the name given to its [s2s configuration](/dev-docs/modules/prebidServer.md), if any. | +| `storageType` | String | `accessDevice` | Either `'html5'` or `'cookie'` - the device storage mechanism being accessed. | +| `syncType` | String | `syncUser` | Either `'iframe'` or `'image'` - the type of user sync. | | `syncUrl` | String | `syncUser` | URL of the user sync. | #### Allow Flag @@ -286,5 +287,6 @@ pbjs.setConfig({ }) ``` -## Further Reading -- [FAQ: How does Prebid.js support privacy regulations](/dev-docs/faq.html#how-does-prebid-support-privacy-regulations) +## Further Reading + +* [FAQ: How does Prebid.js support privacy regulations](/dev-docs/faq.html#how-does-prebid-support-privacy-regulations) diff --git a/dev-docs/add-rtd-submodule.md b/dev-docs/add-rtd-submodule.md index b2c118c0..fbf85669 100644 --- a/dev-docs/add-rtd-submodule.md +++ b/dev-docs/add-rtd-submodule.md @@ -6,16 +6,17 @@ sidebarType: 1 --- # How to Add a Real Time Data Submodule + {:.no_toc} Sub-modules interact with the Real-Time Data (RTD) core module to add data to bid requests or add targeting values for the primary ad server. - * TOC {:toc } ## Overview + The point of the Real Time Data (RTD) infrastructure is to make configuration consistent for publishers. Rather than having dozens of different modules with disparate config approaches, being a Real-Time Data sub-module means plugging into a framework for publishers to control how sub-modules behave. For example, publishers can define how long the auction can be delayed and give some sub-modules priority over others. @@ -40,13 +41,13 @@ Here is the flow for how the RTD-core module interacts with its sub-modules: The activities performed by the RTD-core module are on the left-hand side, while the functions that can be provided by your RTD sub-module are on the right-hand side. Note that you don't need to implement all of the functions - you'll want to plan out your functionality and develop the appropriate functions. - ## Creating a Sub-Module When you create a Real-Time Data sub-module, you will be operating under the umbrella of the Real-Time Data core module. Here are the services core provides: -- your sub-module will be initialized as soon as pbjs.setConfig({realTimeData}) is called. If you can initialize at the time of code load, that can be done at the bottom of your javascript file. -- whenever any of your functions is called, it will be passed the config params provided by the publisher. As a result, you should not call getConfig(). -- your functions will also be passed all available privacy information. As a result, you do not need to query to get GDPR, US Privacy, or any other consent parameters. + +* your sub-module will be initialized as soon as pbjs.setConfig({realTimeData}) is called. If you can initialize at the time of code load, that can be done at the bottom of your javascript file. +* whenever any of your functions is called, it will be passed the config params provided by the publisher. As a result, you should not call getConfig(). +* your functions will also be passed all available privacy information. As a result, you do not need to query to get GDPR, US Privacy, or any other consent parameters. Working with any Prebid project requires using Github. In general, we recommend the same basic workflow for any project: @@ -65,7 +66,8 @@ with the [module rules](/dev-docs/module-rules.html) that apply globally and to Create a markdown file under `modules` with the name of the module suffixed with 'RtdProvider', e.g., `exRtdProvider.md` Example markdown file: -{% highlight text %} + +```md # Overview Module Name: Ex Rtd Provider @@ -76,7 +78,7 @@ Maintainer: prebid@example.com RTD provider for Example.com. Contact prebid@example.com for information. -{% endhighlight %} +``` ### Step 2: Build the Module @@ -90,7 +92,7 @@ In order to let RTD-core know where to find the functions in your sub-module, cr | param name | type | Scope | Description | Params | | :------------ | :------------ | :------ | :------ | :------ | | name | string | required | must match the name provided by the publisher in the on-page config | n/a | -| gvlid | number | optional | global vendor list ID for your submodule | n/a | +| gvlid | number | optional | global vendor list ID for your submodule | n/a | | init | function | required | defines the function that does any auction-level initialization required | config, userConsent | | getTargetingData | function | optional | defines a function that provides ad server targeting data to RTD-core | adUnitArray, config, userConsent | | getBidRequestData | function | optional | defines a function that provides bid request data to RTD-core | reqBidsConfigObj, callback, config, userConsent | @@ -100,32 +102,35 @@ In order to let RTD-core know where to find the functions in your sub-module, cr | onBidResponseEvent | function |optional | listens to the BID_RESPONSE event and calls a sub-module function that lets it know when a bid response has been collected | bidResponse, config, userConsent | For example: -{% highlight text %} + +```javascript export const subModuleObj = { name: 'ExampleRTDModule', init: init, getTargetingData: sendDataToModule }; -{% endhighlight %} +``` #### Register the submodule Register submodule to RTD-core: -{% highlight text %} +```javascript submodule('realTimeData', subModuleObject); -{% endhighlight %} +``` #### User Consent Several of the interfaces get a `userConsent` object. It's an object that carries these attributes: -- [gdpr](/dev-docs/modules/consentManagement.html#bidder-adapter-gdpr-integration) - GDPR -- [usp](/dev-docs/modules/consentManagementUsp.html#bidder-adapter-us-privacy-integration) - US Privacy (aka CCPA) -- [coppa](/dev-docs/publisher-api-reference/setConfig.html#setConfig-coppa) - the Child Online Privacy Protection Act + +* [gdpr](/dev-docs/modules/consentManagement.html#bidder-adapter-gdpr-integration) - GDPR +* [usp](/dev-docs/modules/consentManagementUsp.html#bidder-adapter-us-privacy-integration) - US Privacy (aka CCPA) +* [coppa](/dev-docs/publisher-api-reference/setConfig.html#setConfig-coppa) - the Child Online Privacy Protection Act These are provided so you can do the right thing with respect to regulations. The only privacy requirement imposed by the RTD-core is that sub-modules make make use of the StorageManager instead of attempting to access cookies or localstorage directly. #### The init() function + 1. This function receives module configuration and userConsent parameters 2. If the function returns `false`, the submodule will be ignored. @@ -137,7 +142,8 @@ This is the function that will allow RTD sub-modules to merge ad server targetin 1. RTD-core will call this function with an array of adUnits, config, and userConsent as parameters 2. Your sub-module should respond with per-adslot data that should be set as key values on the ad server targeting in this format: -{% highlight text %} + +```json { "slotA":{ "p":0.56, // ad server targeting variable (e.g. p) for slotA is 0.56 @@ -146,11 +152,11 @@ This is the function that will allow RTD sub-modules to merge ad server targetin "p":0.824, // ad server targeting variable (e.g. p) for slotB is 0.824 } } -{% endhighlight %} +``` **Code Example** -{% highlight text %} +```javascript /** @type {RtdSubmodule} */ export const subModuleObj = { name: 'ExampleRTDModule', @@ -170,34 +176,34 @@ function returnTargetingData(adUnits, config, userConsent) { } submodule('realTimeData', subModuleObj); -{% endhighlight %} +``` #### getBidRequestData This is the function that will allow RTD sub-modules to modify the AdUnit object for each auction. It's called as part of the requestBids hook. 1. RTD-core will call this function with: - - reqBidsConfigObj: a slightly modified version of the object that's passed to `pbjs.requestBids` (see [below](#reqBidsConfigObj)). Note that several auctions can happen concurrently, so the sub-module must be ready to support this. - - callback: lets RTD-core know which auction the sub-module is done with. - - config: the sub-module's config params provided by the publisher - - userConsent object (see above) + 1. reqBidsConfigObj: a slightly modified version of the object that's passed to `pbjs.requestBids` (see [below](#reqBidsConfigObj)). Note that several auctions can happen concurrently, so the sub-module must be ready to support this. + 2. callback: lets RTD-core know which auction the sub-module is done with. + 3. config: the sub-module's config params provided by the publisher + 4. userConsent object (see above) 2. Your sub-module may update the reqBidsConfigObj and hit the callback. To inject data into the bid requests, you should follow one of these conventions: - - Recommended: use one of these [First Party Data](/features/firstPartyData.html) conventions: - - For AdUnit-specific first party data, set AdUnit.ortb2Imp.ext.data.ATTRIBUTES - - For global first party data, including bidder-specific data, modify the `reqBidsConfigObj` as shown [below](#reqBidsConfigObj) - - Not recommended: Place your data in bidRequest.rtd.RTDPROVIDERCODE.ATTRIBUTES and then get individual adapters to specifically read that location. Note that this method won't pass data to Prebid Server adapters. + 1. Recommended: use one of these [First Party Data](/features/firstPartyData.html) conventions: + 1. For AdUnit-specific first party data, set AdUnit.ortb2Imp.ext.data.ATTRIBUTES + 2. For global first party data, including bidder-specific data, modify the `reqBidsConfigObj` as shown [below](#reqBidsConfigObj) + 2. Not recommended: Place your data in bidRequest.rtd.RTDPROVIDERCODE.ATTRIBUTES and then get individual adapters to specifically read that location. Note that this method won't pass data to Prebid Server adapters. - + The `reqBidsConfigObj` parameter is a copy of the object passed to [`requestBids`](/dev-docs/publisher-api-reference/requestBids.html), except for: -- `adUnits` and `timeout` are always defined (if the publisher didn't provide them, the default values are filled in - `pbjs.adUnits` and `getConfig('bidderTimeout')` respectively) -- `ortb2` is replaced with an `ortb2Fragments` object, intended to be inspected and / or modified by your module. +* `adUnits` and `timeout` are always defined (if the publisher didn't provide them, the default values are filled in - `pbjs.adUnits` and `getConfig('bidderTimeout')` respectively) +* `ortb2` is replaced with an `ortb2Fragments` object, intended to be inspected and / or modified by your module. The `ortb2Fragments` parameter is an object containing two properties: -- `global`, an object containing global (not bidder-specific) first party data in the same OpenRTB format used by `setConfig({ortb2})` -- `bidder`, a map from bidder code to bidder-specific, OpenRTB-formatted first party data. +* `global`, an object containing global (not bidder-specific) first party data in the same OpenRTB format used by `setConfig({ortb2})` +* `bidder`, a map from bidder code to bidder-specific, OpenRTB-formatted first party data. Your module may modify either or both with additional data. If adding bidder-specific data in `ortb2Fragments.bidder`, it should also support a parameter to allow the publisher to define which bidders are to receive the data. @@ -207,7 +213,7 @@ at the time `requestBids` is called, and RTD submodules that wish to modify it a **Code Example** -{% highlight text %} +```javascript /** @type {RtdSubmodule} */ export const subModuleObj = { name: 'ExampleRTDModule2', @@ -233,13 +239,15 @@ function alterBidRequests(reqBidsConfigObj, callback, config, userConsent) { } submodule('realTimeData', subModuleObj); -{% endhighlight %} +``` #### beforeInit + 1. Use this function to take action to make sure data will be served as soon as possible (AJAX calls, pixels, etc..) 2. This function is **not** invoked by the RTD module, and should be invoked at the bottom of the submodule. #### Using event listeners + 1. The RTD-core module listens for 3 events - `AUCTION_INIT`, `AUCTION_END`, and `BID_RESPONSE`. 2. Each time one of the events fires, RTD-core will invoke the corresponding function on each sub-module, allowing the sub-module to make changes to the event object. 3. To use this on your sub-module, define the required functions as noted in the table above and the examples below. @@ -247,7 +255,8 @@ submodule('realTimeData', subModuleObj); **Code Example** Here is a code example with both mandatory and optional functions: -{% highlight text %} + +```javascript /** @type {RtdSubmodule} */ export const subModuleObj = { name: 'ExampleRTDModule3', @@ -286,8 +295,7 @@ function beforeInit(){ } beforeInit(); -{% endhighlight %} - +``` ### Step 3: Add unit tests @@ -305,7 +313,7 @@ Once everything looks good, submit the code, tests, and markdown as a pull reque 2. Create a new file for your RTD sub-module in dev-docs/modules/ExampleRtdProvider.md. Take a look at the other *RtdProvider.md files in that directory for the important header values. Specifically it requires the following: - ``` + ```markdown --- layout: page_v2 title: Example Module @@ -322,6 +330,7 @@ Once everything looks good, submit the code, tests, and markdown as a pull reque [Useful publisher-facing documentation] ``` + 3. Submit the pull request to the prebid.github.io repo. ### Step 6: Wait for Prebid volunteers to review diff --git a/dev-docs/add-video-submodule.md b/dev-docs/add-video-submodule.md index 811494d7..bb44cdeb 100644 --- a/dev-docs/add-video-submodule.md +++ b/dev-docs/add-video-submodule.md @@ -9,10 +9,10 @@ sidebarType: 1 {:.no_toc} Video submodules interact with the Video Module to integrate Prebid with Video Players, allowing Prebid to automatically: -- render bids in the desired video player. -- mark used bids as won. -- trigger player and media events. -- populate the oRTB Video Impression and Content params in the bid request. +* render bids in the desired video player. +* mark used bids as won. +* trigger player and media events. +* populate the oRTB Video Impression and Content params in the bid request. * TOC {:toc } @@ -28,11 +28,12 @@ Publishers who use players from different vendors on the same page can use multi ## Requirements The Video Module only supports integration with Video Players that meet the following requirements: -- Must support parsing and reproduction of VAST ads. - - Input can be an ad tag URL or the actual Vast XML. -- Must expose an API that allows the procurement of [Open RTB params](https://www.iab.com/wp-content/uploads/2016/03/OpenRTB-API-Specification-Version-2-5-FINAL.pdf) for Video (section 3.2.7) and Content (section 3.2.16). -- Must emit javascript events for Ads and Media. - - see [Event Registration](#event-registration). + +* Must support parsing and reproduction of VAST ads. + * Input can be an ad tag URL or the actual Vast XML. +* Must expose an API that allows the procurement of [Open RTB params](https://www.iab.com/wp-content/uploads/2016/03/OpenRTB-API-Specification-Version-2-5-FINAL.pdf) for Video (section 3.2.7) and Content (section 3.2.16). +* Must emit javascript events for Ads and Media. + * see [Event Registration](#event-registration). ## Creating a Submodule @@ -49,7 +50,8 @@ Working with any Prebid project requires using Github. In general, we recommend Create a markdown file under `modules` with the name of the module suffixed with 'VideoProvider', i.e. `exampleVideoProvider.md`. Example markdown file: -{% highlight text %} + +```md # Overview Module Name: Example Video Provider @@ -66,16 +68,16 @@ Video provider for Example Player. Contact someone@example.com for information. Your page must link the Example Player build from our CDN. Alternatively you can use npm to load the build. -{% endhighlight %} +``` ### Step 2: Add a Vendor Code Vendor codes are required to indicate which submodule type to instantiate. Add your vendor code constant to an export const in `vendorCodes.js` in Prebid.js under `libraries/video/constants/vendorCodes.js`. i.e. in `vendorCodes.js`: -{% highlight text %} +```javascript export const EXAMPLE_PLAYER_VENDOR = 3; -{% endhighlight %} +``` ### Step 3: Build the Module @@ -89,7 +91,7 @@ Your submodule should also import the `submodule` function from `src/hook.js` an **Code Example** -{% highlight text %} +```javascript import { submodule } from '../src/hook.js'; function exampleSubmoduleFactory(videoProviderConfig) { @@ -102,7 +104,7 @@ function exampleSubmoduleFactory(videoProviderConfig) { exampleSubmoduleFactory.vendorCode = EXAMPLE_VENDOR; submodule('video', exampleSubmoduleFactory); -{% endhighlight %} +``` #### The Submodule object @@ -121,7 +123,8 @@ The submodule object must adhere to the following interface: | destroy | function | required | Deallocates the submodule and destroys the associated video player. n/a | void | void | For example: -{% highlight text %} + +```javascript const exampleSubmodule = { init: init, getId: getId, @@ -132,9 +135,9 @@ const exampleSubmodule = { offEvent: offEvent, destroy: destroy }; -{% endhighlight %} +``` - + #### Event Registration @@ -158,7 +161,8 @@ Submodules must support attaching and detaching event listeners on the video pla #### Update .submodules.json In prebid.js, add your new submodule to `.submodules.json` under the `videoModule` as such: -{% highlight text %} + +```json { "parentModules": { "videoModule": [ @@ -166,7 +170,7 @@ In prebid.js, add your new submodule to `.submodules.json` under the `videoModul ] } } -{% endhighlight %} +``` ## Shared Resources for Developers diff --git a/dev-docs/adunit-reference.md b/dev-docs/adunit-reference.md index 88213cc1..471d79c0 100644 --- a/dev-docs/adunit-reference.md +++ b/dev-docs/adunit-reference.md @@ -6,18 +6,19 @@ sidebarType: 1 --- # Ad Unit Reference + {:.no_toc} The ad unit object is where you configure what kinds of ads you will show in a given ad slot on your page, including: -+ Allowed media types (e.g., banner, native, and/or video) -+ Allowed sizes -+ AdUnit-specific first party data +* Allowed media types (e.g., banner, native, and/or video) +* Allowed sizes +* AdUnit-specific first party data It's also where you will configure bidders, e.g.: -+ Which bidders are allowed to bid for that ad slot -+ What information is passed to those bidders via their [parameters]({{site.baseurl}}/dev-docs/bidders.html) +* Which bidders are allowed to bid for that ad slot +* What information is passed to those bidders via their [parameters]({{site.baseurl}}/dev-docs/bidders.html) This page describes the properties of the `adUnit` object. @@ -42,7 +43,7 @@ See the table below for the list of properties on the ad unit. For example ad u | `video` | Optional | Object | Used to link an Ad Unit to the [Video Module][videoModule]. For allowed params see the [adUnit.video reference](#adUnit-video). | | `deferBilling` | Optional | Boolean | Used by a publisher to flag adUnits as being separately billable. This allows for a publisher to trigger billing manually for winning bids. See [pbjs.triggerBilling](/dev-docs/publisher-api-reference/triggerBilling.html) and [onBidBillable](/dev-docs/bidder-adaptor.html#registering-on-bid-billable) for more info. | - + ### adUnit.bids @@ -61,7 +62,7 @@ Note that `bids` is optional only for [Prebid Server stored impressions](#stored | `ortb2Imp` | Optional | Object | OpenRTB first-party data specific to this bidder. This is merged with, and takes precedence over, `adUnit.ortb2Imp`.| | `renderer` | Optional | Object | Custom renderer. Takes precedence over `adUnit.renderer`, but applies only to this bidder. | - + ### adUnit.mediaTypes @@ -74,7 +75,7 @@ See the table below for the list of properties in the `mediaTypes` object of the | [`native`](#adUnit.mediaTypes.native) | At least one of the `banner`, `native`, or `video` objects are required. | Object | Defines properties of a native ad. For properties, see [`adUnit.mediaTypes.native`](#adUnit.mediaTypes.native). | | [`video`](#adUnit.mediaTypes.video) | At least one of the `banner`, `native`, or `video` objects are required. | Object | Defines properties of a video ad. For examples, see [`adUnit.mediaTypes.video`](#adUnit.mediaTypes.video). | - + #### adUnit.mediaTypes.banner @@ -85,7 +86,7 @@ See the table below for the list of properties in the `mediaTypes` object of the | `pos` | Optional | Integer | OpenRTB page position value: 0=unknown, 1=above-the-fold, 3=below-the-fold, 4=header, 5=footer, 6=sidebar, 7=full-screen | | `name` | Optional | String | Name for this banner ad unit. Can be used for testing and debugging. | - + #### adUnit.mediaTypes.native @@ -93,7 +94,7 @@ The `native` object contains properties that correspond to the assets of the nat See [Prebid Native Implementation](/prebid/native-implementation.html) for details. - + #### adUnit.mediaTypes.video @@ -140,10 +141,9 @@ If `'video.context'` is set to `'adpod'` then the following parameters are also | `contentLengthSec` | Optional | Number | A number representing the length of the video in seconds. Example: `contentLengthSec = 1` | | `contentMode` | Optional | String | A string indicating the type of content being displayed in the video player. There are two options, `live` and `on-demand`. Example: `contentMode = 'on-demand'` | + - - - + ### adUnit.video @@ -163,18 +163,18 @@ When using the Video Module, the mediaTypes.video properties get filled out auto ## Examples -+ [Banner](#adUnit-banner-example) -+ [Video](#adUnit-video-example) - - [With the Video Module](#adUnit-video-module-example) - - [Instream](#adUnit-video-example-instream) - - [Outstream](#adUnit-video-example-outstream) - - [Adpod (Long-Form)](#adUnit-video-example-adpod) -+ [Native](#adUnit-native-example) -+ [Multi-Format](#adUnit-multi-format-example) -+ [Twin Codes](#adUnit-twin-codes-example) -+ [First Party Data](#adUnit-fpd-example) +* [Banner](#adUnit-banner-example) +* [Video](#adUnit-video-example) + * [With the Video Module](#adUnit-video-module-example) + * [Instream](#adUnit-video-example-instream) + * [Outstream](#adUnit-video-example-outstream) + * [Adpod (Long-Form)](#adUnit-video-example-adpod) +* [Native](#adUnit-native-example) +* [Multi-Format](#adUnit-multi-format-example) +* [Twin Codes](#adUnit-twin-codes-example) +* [First Party Data](#adUnit-fpd-example) - + ### Banner @@ -208,6 +208,7 @@ pbjs.addAdUnits({ #### With the Video Module For an example of a video ad unit linked to the Video Module, see below. For more detailed instructions see the [Video Module docs][videoModule]. + ```javascript pbjs.addAdUnits({ code: slot.code, @@ -230,7 +231,7 @@ pbjs.addAdUnits({ }); ``` - + #### Instream @@ -258,7 +259,7 @@ pbjs.addAdUnits({ }); ``` - + #### Outstream @@ -312,7 +313,8 @@ pbjs.addAdUnits({ ... }); ``` - + + #### Adpod (Long-Form) @@ -346,7 +348,7 @@ var longFormatAdUnit = { } ``` - + ### Native @@ -362,27 +364,27 @@ pbjs.addAdUnits({ assets: [{ required: 1, img: { - type: 1, + type: 1, hmin: 50 }, - },{ + },{ required: 1, title: { len: 80 }, - },{ + },{ required: 1, data: { type: 1, len: 30 }, - },{ + },{ required: 1, data: { type: 2, len: 100 }, - },{ + },{ required: 1, img: { type: 3, @@ -390,8 +392,8 @@ pbjs.addAdUnits({ wmin: 267 } }] - } - } + } + } }, bids: [ { @@ -404,13 +406,13 @@ pbjs.addAdUnits({ }); ``` - + ### Multi-Format For an example of a multi-format ad unit, see below. For more detailed instructions, see [Show Multi-Format Ads]({{site.baseurl}}/dev-docs/show-multi-format-ads.html). -{% highlight js %} +```javascript pbjs.addAdUnits([{ code: 'div-banner-native', @@ -421,16 +423,16 @@ pbjs.addAdUnits([{ ] }, native: { - ortb: { - ver: "1.2", - assets: [{ - required: 1, - img: { - type: 1, - hmin: 50 - } - }] - } + ortb: { + ver: "1.2", + assets: [{ + required: 1, + img: { + type: 1, + hmin: 50 + } + }] + } }, }, bids: [{ @@ -471,16 +473,16 @@ pbjs.addAdUnits([{ ] }, native: { - ortb: { - ver: "1.2", - assets: [{ - required: 1, - img: { - type: 1, - hmin: 50 - } - }] - } + ortb: { + ver: "1.2", + assets: [{ + required: 1, + img: { + type: 1, + hmin: 50 + } + }] + } }, video: { context: 'outstream', @@ -496,20 +498,21 @@ pbjs.addAdUnits([{ } ]); -{% endhighlight %} +``` - + ### Twin AdUnit Codes It's ok to have multiple AdUnits with the same `code`. This can be useful in scenarios where bidders have different capabilities for the same spot on the page. e.g. -- BidderA should receive both media types, while BidderB gets only one -- BidderA gets one size while BidderB gets another +* BidderA should receive both media types, while BidderB gets only one +* BidderA gets one size while BidderB gets another In this example, bidderA gets both banner and outstream, while bidderB gets only banner. -{% highlight js %} + +```javascript var adUnits = [ { code: 'test-div', @@ -550,18 +553,18 @@ In this example, bidderA gets both banner and outstream, while bidderB gets only ] } ]; -{% endhighlight %} +``` In this example, bidderA receives 2 bidRequest objects while bidderB receives one. If a bidder provides more than one bid for the same AdUnit.code, Prebid.js will use the highest bid when it's time to set targeting. - + ### First Party Data Example of an adunit-specific block of first party data: -{% highlight js %} +```javascript pbjs.addAdUnits({ code: "test-div", mediaTypes: { @@ -571,27 +574,28 @@ pbjs.addAdUnits({ }, ortb2Imp: { ext: { - data: { + data: { pbadslot: "homepage-top-rect", adUnitSpecificContextAttribute: "123" - } + } } }, ... }); -{% endhighlight %} +``` Notes: -- Only contextual data should be added on the AdUnit; user-related data goes in the [global first party data](/dev-docs/publisher-api-reference/setConfig.html#setConfig-fpd) config. -- For additional help with analytics and reporting you can use the [Prebid Ad Slot](/features/pbAdSlot.html), a special type of first party data. - +* Only contextual data should be added on the AdUnit; user-related data goes in the [global first party data](/dev-docs/publisher-api-reference/setConfig.html#setConfig-fpd) config. +* For additional help with analytics and reporting you can use the [Prebid Ad Slot](/features/pbAdSlot.html), a special type of first party data. + + ### Interstitial Ads Example of an adunit-specific interstitial signal: -{% highlight js %} +```javascript pbjs.addAdUnits({ code: "test-div", mediaTypes: { @@ -600,15 +604,15 @@ pbjs.addAdUnits({ } }, ortb2Imp: { - instl:1 + instl:1 }, ... }); -{% endhighlight %} +``` For more information on Interstitial ads, reference the [Interstitial feature page](/features/InterstitialAds.html). Additionally, to assist with billing optimization and interstitial ads, the triggerBilling and onBidBillable functionality can be utilized. See [pbjs.triggerBilling](/dev-docs/publisher-api-reference/triggerBilling.html) and [onBidBillable](/dev-docs/bidder-adaptor.html#registering-on-bid-billable) for more info. - + ### Prebid Server stored impressions @@ -675,16 +679,14 @@ pbjs.addAdUnits({ ## Related Topics -+ [Publisher API Reference](/dev-docs/publisher-api-reference) -+ [Conditional Ad Units][conditionalAds] -+ [Show Native Ads](/prebid/native-implementation.html) -+ [Show Video Ads](/dev-docs/show-video-with-a-dfp-video-tag.html) -+ [Show Outstream Video Ads](/dev-docs/show-outstream-video-ads.html) -+ [Show Long-Form Video Ads](/prebid-video/video-long-form.html) -+ [Prebid.org Video Examples](/examples/video/) -+ [Prebid.org Native Examples](/dev-docs//examples/native-ad-example.html) - - +* [Publisher API Reference](/dev-docs/publisher-api-reference) +* [Conditional Ad Units][conditionalAds] +* [Show Native Ads](/prebid/native-implementation.html) +* [Show Video Ads](/dev-docs/show-video-with-a-dfp-video-tag.html) +* [Show Outstream Video Ads](/dev-docs/show-outstream-video-ads.html) +* [Show Long-Form Video Ads](/prebid-video/video-long-form.html) +* [Prebid.org Video Examples](/examples/video/) +* [Prebid.org Native Examples](/dev-docs//examples/native-ad-example.html) diff --git a/dev-docs/analytics-ga.md b/dev-docs/analytics-ga.md index 6e9ebaa9..b147025d 100644 --- a/dev-docs/analytics-ga.md +++ b/dev-docs/analytics-ga.md @@ -19,7 +19,7 @@ nav_section: reference ### Code Example -{% highlight js %} +```javascript // If you're using GA, this should already be in your page: (function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){ @@ -38,7 +38,7 @@ pbjs.que.push(function() { }); }); -{% endhighlight %} +``` ##### A Few Requirements @@ -56,7 +56,7 @@ See [this link](https://developers.google.com/analytics/devguides/collection/pro To track a lower volume of traffic in Google Analytics, you may specify a sample rate in the options. For example, to set up a 5% sample rate: -{% highlight js %} +```javascript pbjs.que.push(function() { pbjs.enableAnalytics({ provider: 'ga', @@ -67,7 +67,7 @@ pbjs.que.push(function() { } }); }); -{% endhighlight %} +``` At the start of each page, Prebid chooses a random number between 0 and 1 and logs the analytics only if the number is less than the supplied sample rate, which defaults to 1 (100%). @@ -82,11 +82,11 @@ Prebid.js sends out GA-compatible [Events](https://support.google.com/analytics/ In this example, the page has 1 ad unit with 3 bidders. The timeout is set to 400ms. Let's go through what Prebid Analytics sends out to GA: {: .table .table-bordered .table-striped } -| Time | What Happened | GA Events Sent | +| Time | What Happened | GA Events Sent | | :---- |:--------| :-------| -| 15ms | Prebid.js sends out bid requests to bidders AppNexus, OpenX, and Pubmatic. | Event 1: Category=`Prebid.js Bids`, Action=`Requests`, Label=`appnexus`, Value=1.
Event 2: Category=`Prebid.js Bids`, Action=`Requests`, Label=`openx`, Value=1.
Event 3: Category=`Prebid.js Bids`, Action=`Requests`, Label=`pubmatic`, Value=1 | -| 203ms | AppNexus' bid came back with a CPM of $2.314 and a latency of 188ms. | Event 1: Category=`Prebid.js Bids`, Action=`Bids`, Label=`appnexus`, Value=231.
Event 2: Category=`Prebid.js Bids`, Action=`Bid Load Time`, Label=`appnexus`, Value=188 | -| 274ms | Pubmatic's bid came back with a CPM of $0 and a latency of 259ms. | No bid event sent out because it is a no bid.
Event 1: Category=`Prebid.js Bids`, Action=`Bid Load Time`, Label=`appnexus`, Value=259 | +| 15ms | Prebid.js sends out bid requests to bidders AppNexus, OpenX, and Pubmatic. | Event 1: Category=`Prebid.js Bids`, Action=`Requests`, Label=`appnexus`, Value=1.
Event 2: Category=`Prebid.js Bids`, Action=`Requests`, Label=`openx`, Value=1.
Event 3: Category=`Prebid.js Bids`, Action=`Requests`, Label=`pubmatic`, Value=1 | +| 203ms | AppNexus' bid came back with a CPM of $2.314 and a latency of 188ms. | Event 1: Category=`Prebid.js Bids`, Action=`Bids`, Label=`appnexus`, Value=231.
Event 2: Category=`Prebid.js Bids`, Action=`Bid Load Time`, Label=`appnexus`, Value=188 | +| 274ms | Pubmatic's bid came back with a CPM of $0 and a latency of 259ms. | No bid event sent out because it is a no bid.
Event 1: Category=`Prebid.js Bids`, Action=`Bid Load Time`, Label=`appnexus`, Value=259 | | 415ms | Timeout is up because 400ms has passed since bid requests were sent. OpenX has timed out. | Event 1: Category=`Prebid.js Bids`, Action=`Timeouts`, Label=`openx`, Value=1 | | 476ms | OpenX's bid came back with a CPM of $2.831 and a latency of 461ms (a bid may still come back after a timeout). | Event 1: Category=`Prebid.js Bids`, Action=`Bids`, Label=`openx`, Value=283.
Event 2: Category=`Prebid.js Bids`, Action=`Bid Load Time`, Label=`openx`, Value=461 | | 572ms | Google Ad Manager completed its auction and the AppNexus $2.314 bid won. | Event 3: Category=`Prebid.js Bids`, Action=`Wins`, Label=`appnexus`, Value=231 | diff --git a/dev-docs/bidder-adaptor.md b/dev-docs/bidder-adaptor.md index 1f1ea8a2..cb671cfd 100644 --- a/dev-docs/bidder-adaptor.md +++ b/dev-docs/bidder-adaptor.md @@ -9,6 +9,7 @@ sidebarType: 1 # How to Add a New Prebid.js Bidder Adapter + {:.no_toc} At a high level, a bidder adapter is responsible for: @@ -23,12 +24,12 @@ This page has instructions for writing your own bidder adapter. The instruction ## Planning your Adapter -+ [Required Adapter Rules](#bidder-adaptor-Required-Adapter-Conventions) -+ [Required Files](#bidder-adaptor-Required-Files) -+ [Designing your Bid Params](#bidder-adaptor-Designing-your-Bid-Params) -+ [HTTP Simple Requests](#bidder-adaptor-HTTP-simple-requests) +* [Required Adapter Rules](#bidder-adaptor-Required-Adapter-Conventions) +* [Required Files](#bidder-adaptor-Required-Files) +* [Designing your Bid Params](#bidder-adaptor-Designing-your-Bid-Params) +* [HTTP Simple Requests](#bidder-adaptor-HTTP-simple-requests) - + ### Required Adapter Rules @@ -43,7 +44,7 @@ In order to provide a fast and safe header bidding environment for publishers, t {: .alert.alert-danger :} The above list is **not** the full list of requirements. Failure to follow any of the required conventions defined in the [Module Rules](/dev-docs/module-rules.html) could lead to delays in approving your adapter for inclusion in Prebid.js. If you'd like to apply for an exception to one of the rules, make your request in a new [Prebid.js issue](https://github.com/prebid/Prebid.js/issues). - + ### Required Files @@ -51,16 +52,16 @@ With each adapter submission, there are two files required to be in the pull req * `modules/exampleBidAdapter.js`: the file containing the code for the adapter * `modules/exampleBidAdapter.md`: a markdown file containing key information about the adapter: - * The contact email of the adapter's maintainer. - * A test ad unit that will consistently return test creatives. This helps us to ensure future Prebid.js updates do not break your adapter. Note that if your adapter supports video (instream and/or outstream context) or native, you must also provide example parameters for each type. + * The contact email of the adapter's maintainer. + * A test ad unit that will consistently return test creatives. This helps us to ensure future Prebid.js updates do not break your adapter. Note that if your adapter supports video (instream and/or outstream context) or native, you must also provide example parameters for each type. Example markdown file: -{% highlight text %} +```md # Overview -``` +```markdown Module Name: Example Bidder Adapter Module Type: Bidder Adapter Maintainer: prebid@example.com @@ -71,7 +72,8 @@ Maintainer: prebid@example.com Module that connects to Example's demand sources # Test Parameters -``` + +```javascript var adUnits = [ { code: 'test-div', @@ -107,9 +109,9 @@ Module that connects to Example's demand sources ]; ``` -{% endhighlight %} +```html - + ### Designing your Bid Params @@ -117,7 +119,7 @@ The parameters of your ad request will be stored in the ad unit's `bid.params` o For more information about the kinds of information that can be passed using these parameters, see the example below, as well as [the existing bidder parameters]({{site.baseurl}}/dev-docs/bidders.html). -{% highlight js %} +```javascript { var adUnits = [{ @@ -144,9 +146,9 @@ For more information about the kinds of information that can be passed using the }] }]; -{% endhighlight %} +``` - + ### HTTP Simple Requests @@ -188,19 +190,20 @@ If you're the type that likes to skip to the answer instead of going through a t {: .alert.alert-warning :} If your adapter interfaces with an ORTB backend, you may take advantage of Prebid's [ORTB conversion library](https://github.com/prebid/Prebid.js/blob/master/libraries/ortbConverter/README.md), which provides most of the implementation for `buildRequests` and `interpretResponse`. -+ [Overview](#bidder-adaptor-Overview) -+ [Building the Request](#bidder-adaptor-Building-the-Request) -+ [Interpreting the Response](#bidder-adaptor-Interpreting-the-Response) -+ [Registering User Syncs](#bidder-adaptor-Registering-User-Syncs) -+ [Registering on Timeout](#bidder-adaptor-Registering-on-Timout) +* [Overview](#bidder-adaptor-Overview) +* [Building the Request](#bidder-adaptor-Building-the-Request) +* [Interpreting the Response](#bidder-adaptor-Interpreting-the-Response) +* [Registering User Syncs](#bidder-adaptor-Registering-User-Syncs) +* [Registering on Timeout](#bidder-adaptor-Registering-on-Timout) - + ### Overview The new code will reside under the `modules` directory with the name of the bidder suffixed by 'BidAdapter', e.g., `exampleBidAdapter.js`. Here are some guidelines for choosing a bidder code: + - The bidder code must be lower case alphanumeric. The only special character allowed is underscore. - The bidder code must be unique - make sure none of the other bid adapters is using the same code. - The bidder code should be unique for the first 6 characters - this consideration helps with generating unique targeting keys for use by some ad exchanges, such as Google Ad Manager. @@ -216,7 +219,7 @@ Compared to previous versions of Prebid, the new `BaseAdapter` model saves the a A high level example of the structure: -{% highlight js %} +```javascript import * as utils from 'src/utils'; import { registerBidder } from 'src/adapters/bidderFactory'; @@ -241,15 +244,15 @@ export const spec = { } registerBidder(spec); -{% endhighlight %} +``` - + ### Note on ORTB adapters If your adapter interfaces with an ORTB backend, you may take advantage of Prebid's [ORTB conversion library](https://github.com/prebid/Prebid.js/blob/master/libraries/ortbConverter/README.md), which provides most of the implementation for `buildRequests` and `interpretResponse`. - + ### Building the Request @@ -258,12 +261,12 @@ When the page asks Prebid.js for bids, your module's `buildRequests` function wi - `validBidRequests[]` - An array of bidRequest objects, one for each AdUnit that your module is involved in. This array has been processed for special features like sizeConfig, so it's the list that you should be looping through. - `bidderRequest` - The master bidRequest object. This object is useful because it carries a couple of bid parameters that are global to all the bids. -{% highlight js %} +```javascript buildRequests: function(validBidRequests, bidderRequest) { ... return ServerRequestObjects; } -{% endhighlight %} +``` Building the request will use data from several places: @@ -276,7 +279,7 @@ Building the request will use data from several places: Here is a sample array entry for `validBidRequests[]`: -{% highlight js %} +```javascript [{ adUnitCode: "test-div", auctionId: "b06c5141-fe8f-4cdf-9d7d-54415490a917", @@ -294,7 +297,7 @@ Here is a sample array entry for `validBidRequests[]`: src: "client", transactionId: "54a58774-7a41-494e-9aaf-fa7b79164f0c" }] -{% endhighlight %} +``` Retrieve your bid parameters from the `params` object. @@ -312,7 +315,7 @@ Other notes: Here is a sample bidderRequest object: -{% highlight js %} +```javascript { auctionId: "b06c5141-fe8f-4cdf-9d7d-54415490a917", auctionStart: 1579746300522, @@ -332,7 +335,7 @@ Here is a sample bidderRequest object: stack: ["http://mypage.org?pbjs_debug=true"] } } -{% endhighlight %} +``` Notes on parameters in the bidderRequest object: - **auctionID** is unique per call to `requestBids()`, but is the same across ad units. @@ -403,7 +406,7 @@ ServerRequest objects. These objects have this structure: Here's a sample block of code returning a ServerRequest object: -{% highlight js %} +```javascript return { method: 'POST', @@ -411,15 +414,15 @@ return { data: payloadObject }; -{% endhighlight %} +``` - + ### Interpreting the Response The `interpretResponse` function will be called when the browser has received the response from your server. The function will parse the response and create a bidResponse object containing one or more bids. The adapter should indicate no valid bids by returning an empty array. An example showing a single bid: -{% highlight js %} +```javascript // if the bid response was empty or an error, return [] // otherwise parse the response and return a bidResponses array @@ -450,7 +453,7 @@ The `interpretResponse` function will be called when the browser has received th brandId: BRAND_ID, brandName: BRAND_NAME, dchain: DEMAND_CHAIN_OBJECT, - demandSource: DEMAND_SOURCE + demandSource: DEMAND_SOURCE mediaType: MEDIA_TYPE, networkId: NETWORK_ID, networkName: NETWORK_NAME, @@ -461,7 +464,7 @@ The `interpretResponse` function will be called when the browser has received th bidResponses.push(bidResponse); return bidResponses; -{% endhighlight %} +``` {: .alert.alert-info :} Please provide as much information as possible in the `meta` object. Publishers use this @@ -519,7 +522,7 @@ bid currency. Header Bidding is a first-price auction, the best candidate for Prebid won't resolve any other macros in the creative (e.g. AUCTION_ID, AUCTION_CURRENCY). - + ### Registering User Syncs @@ -529,7 +532,7 @@ Given an array of all the responses from the server, `getUserSyncs` is used to d See below for an example implementation. For more examples, search for `getUserSyncs` in the [modules directory in the repo](https://github.com/prebid/Prebid.js/tree/master/modules). -{% highlight js %} +```javascript { getUserSyncs: function(syncOptions, serverResponses, gdprConsent, uspConsent) { @@ -558,9 +561,9 @@ See below for an example implementation. For more examples, search for `getUser } } -{% endhighlight %} +``` - + ### Registering on Timeout @@ -568,7 +571,7 @@ The `onTimeout` function will be called when an adapter has timed out for an auc Sample data passed to this function: -{% highlight js %} +```javascript [{ "bidder": "example", "bidId": "51ef8751f9aead", @@ -579,7 +582,7 @@ Sample data passed to this function: "timeout": 3000, "auctionId": "18fd8b8b0bd757" }] -{% endhighlight %} +``` ### Registering on Bid Won @@ -587,7 +590,7 @@ The `onBidWon` function will be called when a bid from the adapter won the aucti Sample data received by this function: -{% highlight js %} +```javascript { "bidder": "example", "width": 300, @@ -606,7 +609,7 @@ Sample data received by this function: "hb_size": "350x250" } } -{% endhighlight %} +``` ### Registering on Bid Billable @@ -614,7 +617,7 @@ The `onBidBillable` function will be called when it deems a bid to be billable. Sample data received by this function (same as what is recieved for onBidWon): -{% highlight js %} +```javascript { "bidder": "example", "width": 300, @@ -633,7 +636,7 @@ Sample data received by this function (same as what is recieved for onBidWon): "hb_size": "350x250" } } -{% endhighlight %} +``` ### Registering on Set Targeting @@ -641,7 +644,7 @@ The `onSetTargeting` function will be called when the adserver targeting has bee Sample data received by this function: -{% highlight js %} +```javascript { "bidder": "example", "width": 300, @@ -660,7 +663,7 @@ Sample data received by this function: "hb_size": "350x250" } } -{% endhighlight %} +``` ### Registering on Bidder Error @@ -668,7 +671,7 @@ The `onBidderError` function will be called when the bidder responded with an er Sample data received by this function: -{% highlight js %} +```javascript { error: XMLHttpRequest, bidderRequest: { @@ -692,13 +695,13 @@ Sample data received by this function: } } } -{% endhighlight %} +``` ### Adding adapter aliases Use aliases if you want to reuse your adapter using other name for your partner/client, or just a shortcut name. -{% highlight js %} +```javascript export const spec = { code: 'appnexus', @@ -713,7 +716,7 @@ export const spec = { ... } -{% endhighlight %} +``` spec.aliases can be an array of strings or objects. @@ -748,7 +751,7 @@ Follow the steps in this section to ensure that your adapter properly supports v Add the `supportedMediaTypes` argument to the spec object, and make sure VIDEO is in the list: -{% highlight js %} +```javascript export const spec = { code: BIDDER_CODE, @@ -756,7 +759,7 @@ export const spec = { ... } -{% endhighlight %} +``` {: .alert.alert-info :} If your adapter supports banner and video media types, make sure to include `'banner'` in the `supportedMediaTypes` array as well @@ -793,11 +796,11 @@ Video ad units have a publisher-defined video context, which can be either `'ins mediaTypes: { video: { context: 'outstream', - playerSize: [640, 480], - mimes: ['video/mp4'], - protocols: [1, 2, 3, 4, 5, 6, 7, 8], - playbackmethod: [2], - skip: 1 + playerSize: [640, 480], + mimes: ['video/mp4'], + protocols: [1, 2, 3, 4, 5, 6, 7, 8], + playbackmethod: [2], + skip: 1 // video params must be read from here in place of // or instead of bidder-specific parameters }, @@ -896,7 +899,7 @@ In both use cases, adapter is requesting bid responses for 20 placements in one Adapter must add following new properties to bid response -{% highlight js %} +```javascript { meta: { primaryCatId: '', // only needed if you want to ensure competitive separation @@ -906,7 +909,7 @@ Adapter must add following new properties to bid response durationSeconds: 30 } } -{% endhighlight %} +``` Appnexus Adapter uses above explained approach. You can refer [here](https://github.com/prebid/Prebid.js/blob/master/modules/appnexusBidAdapter.js) @@ -927,7 +930,7 @@ If the demand partner is going to use Prebid API for this process, their adapter **Example** -``` +```javascript getMappingFileInfo: function() { return { url: '', @@ -941,7 +944,7 @@ The mapping file is stored locally to expedite category conversion. Depending on To get the subcategory to use, call this function, which needs to be imported from the `bidderFactory`. -``` +```javascript getIabSubCategory(bidderCode, pCategory) ``` @@ -955,12 +958,12 @@ getIabSubCategory(bidderCode, pCategory) **Example** -{% highlight js %} +```javascript import { getIabSubCategory } from '../src/adapters/bidderFactory'; let primaryCatId = getIabSubCategory(bidderCode, pCategory) -{% endhighlight %} +``` #### Outstream Video Renderers @@ -976,7 +979,7 @@ The returned VAST URL or raw VAST XML should be added into `bid.vastUrl` or `bid For example: -{% highlight js %} +```javascript function createBid(status, reqBid, response) { let bid = bidfactory.createBid(status, reqBid); @@ -991,7 +994,7 @@ function createBid(status, reqBid, response) { return bid; } -{% endhighlight %} +``` ### Deals in Ad Pods @@ -1023,7 +1026,7 @@ The adapter code sample below fulfills requirement #2, unpacking the server's re 1. Checking for native assets on the response. 2. If present, filling in the `native` object with those assets. -{% highlight js %} +```javascript /* Does the bidder respond with native assets? */ else if (FEATURES.NATIVE && rtbBid.rtb.native) { @@ -1045,7 +1048,7 @@ else if (FEATURES.NATIVE && rtbBid.rtb.native) { }; } -{% endhighlight %} +``` The full list of assets your bidder can set are defined [by legacy Prebid.js](/prebid/native-implementation-legacy.html#3-prebidjs-native-adunit-overview). All assets can be returned as strings, or images can be returned as objects with attributes `url`, `height`, and `width`. @@ -1097,7 +1100,7 @@ For example tests, see [the existing adapter test suites](https://github.com/pre ## Full Bid Adapter Example -{% highlight js %} +```javascript import * as utils from 'src/utils'; import {config} from 'src/config'; @@ -1106,8 +1109,8 @@ import {BANNER, VIDEO, NATIVE} from 'src/mediaTypes.js'; const BIDDER_CODE = 'example'; export const spec = { code: BIDDER_CODE, - gvlid: 0000000000, - supportedMediaTypes: [BANNER, VIDEO, NATIVE], + gvlid: 0000000000, + supportedMediaTypes: [BANNER, VIDEO, NATIVE], aliases: [{code: "myAlias", gvlid: 99999999999} ], /** * Determines whether or not the given bid request is valid. @@ -1239,7 +1242,7 @@ export const spec = { } registerBidder(spec); -{% endhighlight %} +``` ## Submitting your adapter @@ -1317,5 +1320,5 @@ The Prebid.org [download page](/download.html) will automatically be updated wit ## Further Reading -+ [Prebid.js Repo - Bidder Adapter Sources](https://github.com/prebid/Prebid.js/tree/master/modules) -+ [Module Rules](/dev-docs/module-rules.html) +* [Prebid.js Repo - Bidder Adapter Sources](https://github.com/prebid/Prebid.js/tree/master/modules) +* [Module Rules](/dev-docs/module-rules.html) diff --git a/dev-docs/bidders/aax.md b/dev-docs/bidders/aax.md index 0d242b41..011159bf 100644 --- a/dev-docs/bidders/aax.md +++ b/dev-docs/bidders/aax.md @@ -29,7 +29,7 @@ sidebarType: 1 | `crid` | required | The placement id provided by Aax. | `'aax_crid'` | `string` | | `video` | required for video Ad units | Object containing video targeting parameters. See [Video Object](#aax-video-object) for details.|`video: { maxduration: 60 }` | `object` | - + #### Video Object @@ -40,20 +40,21 @@ sidebarType: 1 |minduration|integer|(Recommended) Specifies the minimum video ad duration, in seconds.|10| |maxduration|integer|(Recommended) Specifies the maximum video ad duration, in seconds.|60| |w|integer|(Recommended) Specifies the width of the video player, in pixels. Required if playerSize not present in `mediaTypes.video`|640| -|h|integer|(Recommended) Specifies the height of the video player, in pixels. Required if playerSize not present in `mediaTypes.video`|480| -|startdelay |integer | (Recommended) Specifies the start delay of the video ad|0| -|battr| array of integers|Specifies the video creative attributes to block. Refer to section 5.3 of the IAB specification for a list of attributes.| [ 13, 14 ]| -playbackmethod| array of integers| Specifies the allowed playback methods. If not specified, all are assumed to be allowed. Currently supported values are: `1: Autoplay, sound on`; `2: Autoplay, sound off`; `3: Click to play`; `4: Mouse over to play`|[1, 3]| -|api| array of integers| Specifies the supported API frameworks for this impression. If an API is not explicitly listed, it is assumed not to be supported. Currently supported values are: `1: VPAID 1.0`; `2: VPAID 2.0`; `3: MRAID-1`; `4: ORMMA`; `5: MRAID-2`|[1, 2]| -|protocols |array of integers| Array of supported video protocols. Currently supported values are: `1: VAST 1.0`; `2: VAST 2.0`; `3: VAST 3.0`; `4: VAST 1.0 Wrapper`; `5: VAST 2.0 Wrapper`; `6: VAST 3.0 Wrapper`; `7: VAST 4.0`|[1, 2]| -|placement |integer|Placement type for the impression. Possible options: `1: In-Stream`; `2: In-banner`; `3: Outstream/In-article`; `4: In-feed`; `5: Interstitial/Slider/Floating`; `6: Long-Form`;|1| +|h|integer|(Recommended) Specifies the height of the video player, in pixels. Required if playerSize not present in `mediaTypes.video`|480| +|startdelay |integer | (Recommended) Specifies the start delay of the video ad|0| +|battr| array of integers|Specifies the video creative attributes to block. Refer to section 5.3 of the IAB specification for a list of attributes.| [ 13, 14 ]| +playbackmethod| array of integers| Specifies the allowed playback methods. If not specified, all are assumed to be allowed. Currently supported values are: `1: Autoplay, sound on`; `2: Autoplay, sound off`; `3: Click to play`; `4: Mouse over to play`|[1, 3]| +|api| array of integers| Specifies the supported API frameworks for this impression. If an API is not explicitly listed, it is assumed not to be supported. Currently supported values are: `1: VPAID 1.0`; `2: VPAID 2.0`; `3: MRAID-1`; `4: ORMMA`; `5: MRAID-2`|[1, 2]| +|protocols |array of integers| Array of supported video protocols. Currently supported values are: `1: VAST 1.0`; `2: VAST 2.0`; `3: VAST 3.0`; `4: VAST 1.0 Wrapper`; `5: VAST 2.0 Wrapper`; `6: VAST 3.0 Wrapper`; `7: VAST 4.0`|[1, 2]| +|placement |integer|Placement type for the impression. Possible options: `1: In-Stream`; `2: In-banner`; `3: Outstream/In-article`; `4: In-feed`; `5: Interstitial/Slider/Floating`; `6: Long-Form`;|1| Besides the above-mentioned parameters, we support all other OpenRTB 2.x video objects as optional parameters. In addition to `bids[].params.video`, Aax adapter consumes parameters specified in the `mediaTypes.video`. #### Example of Instream Video Ad-unit -``` + +```javascript var videoAdUnit = { code: 'video1', mediaTypes: { @@ -75,7 +76,8 @@ var videoAdUnit = { ``` #### Example of Native Ad-unit -``` + +```javascript var adUnits = [{ code: 'div-gpt-ad-6874091242345-0', mediaTypes: { @@ -102,7 +104,8 @@ var adUnits = [{ ``` #### Example of Banner Ad-unit -``` + +```javascript var adUnits = [{ code: 'div-gpt-ad-6874091242345-0', mediaTypes: { diff --git a/dev-docs/bidders/adlivetech.md b/dev-docs/bidders/adlivetech.md index 3f378af1..bb2d7921 100644 --- a/dev-docs/bidders/adlivetech.md +++ b/dev-docs/bidders/adlivetech.md @@ -24,7 +24,7 @@ sidebarType: 1 - [Bidder Config](#bidder-config) - [First Party Data](#first-party-data) - + ### Bid Params @@ -35,12 +35,13 @@ sidebarType: 1 | `keywords` | optional | A set of key-value pairs applied to all ad slots on the page. Values can be empty. | `keywords: { topic: ['stress', 'fear'] }` | `object` | | `bidFloor` | optional | Floor of the impression opportunity. If present in the request overrides XML info. | `0.8` | `float` | - + ### Bidder Config You can allow writing in localStorage `pbjs.setBidderConfig` for the bidder `adlivetech` -``` + +```javascript pbjs.setBidderConfig({ bidders: ["adlivetech"], config: { @@ -48,9 +49,10 @@ pbjs.setBidderConfig({ } }) ``` + If it will be "true" this allow Adlivetech Bid Adapter to write userId in first party localStorage - + ### First Party Data diff --git a/dev-docs/bidders/apacdex.md b/dev-docs/bidders/apacdex.md index 9ba8994a..18062444 100644 --- a/dev-docs/bidders/apacdex.md +++ b/dev-docs/bidders/apacdex.md @@ -25,7 +25,7 @@ sidebarType: 1 - [Sample Video Ad Unit: Instream](#sample-video-ad-unit-instream) - [Sample Video Ad Unit: Outstream](#sample-video-ad-unit-outstream) - + ### Bid Params @@ -39,7 +39,7 @@ sidebarType: 1 (*) Please do not use `placementId` and `siteId` at the same time. - + ### Geo Object @@ -54,7 +54,7 @@ If the publisher has GEO data of the user's device. Make it available through th | `lastfix` | optional | Number of seconds since this geolocation fix was established. Note that devices may cache location data across multiple fetches. Ideally, this value should be from the time the actual fix was taken. | `30` | `integer` | | `utcoffset` | optional | Local time as the number +/- of minutes from UTC. | `-420` | `integer` | - + ### Video Ad Unit @@ -80,10 +80,11 @@ Publishers declare video inventory by passing the following parameters via media Lists of values are in the [OpenRTB 2.5](https://www.iab.com/wp-content/uploads/2016/03/OpenRTB-API-Specification-Version-2-5-FINAL.pdf) documentation as referenced above. - + ### Sample Banner Ad Unit -``` + +```javascript var adUnits = [ { code: 'test-div', @@ -105,10 +106,11 @@ var adUnits = [ ]; ``` - + ### Sample Video Ad Unit: Instream -``` + +```javascript var instreamAdUnit = { code: 'test-div', sizes: [[640, 480]], @@ -139,13 +141,15 @@ var instreamAdUnit = { ] }; ``` -mediaTypes.video object reference to section 3.2.7 Object: Video in the OpenRTB 2.5 document + +`mediaTypes.video` object reference to section 3.2.7 Object: Video in the OpenRTB 2.5 document You must review all video parameters to ensure validity for your player and DSPs - + ### Sample Video Ad Unit: Outstream -``` + +```javascript var outstreamAdUnit = { code: 'test-div', sizes: [[410, 231]], @@ -175,5 +179,6 @@ var outstreamAdUnit = { ] }; ``` -mediaTypes.video object reference to section 3.2.7 Object: Video in the OpenRTB 2.5 document + +`mediaTypes.video` object reference to section 3.2.7 Object: Video in the OpenRTB 2.5 document You must review all video parameters to ensure validity for your player and DSPs diff --git a/dev-docs/bidders/appier.md b/dev-docs/bidders/appier.md index 6271f7de..50610247 100644 --- a/dev-docs/bidders/appier.md +++ b/dev-docs/bidders/appier.md @@ -9,7 +9,7 @@ gdpr_supported: true sidebarType: 1 --- - + #### Bid Params @@ -18,14 +18,13 @@ sidebarType: 1 |-----------|----------|---------------------------|------------|----------| | `hzid` | required | The zone ID from Appier. | `"WhM5WIOp"` | `string` | - - + #### Custom Settings (Optional) Set the "farm" to use region-specific server -``` +```javascript pbjs.que.push(function() { // use the bid server in Taiwan (country code: tw) pbjs.setConfig({ @@ -38,7 +37,7 @@ pbjs.que.push(function() { Explicitly override the bid server used for bidding -``` +```javascript pbjs.que.push(function() { pbjs.setConfig({ appier: { diff --git a/dev-docs/bidders/appnexus.md b/dev-docs/bidders/appnexus.md index 4eb2b4f7..255049c3 100644 --- a/dev-docs/bidders/appnexus.md +++ b/dev-docs/bidders/appnexus.md @@ -20,7 +20,7 @@ gvl_id: 32 sidebarType: 1 --- -### Disclosure: +### Disclosure This adapter is known to use an HTTP 1 endpoint. Header bidding often generates multiple requests to the same host and bidders are encouraged to change to HTTP 2 or above to help improve publisher page performance via multiplexing. @@ -41,7 +41,7 @@ This adapter is known to use an HTTP 1 endpoint. Header bidding often generates - [Debug Auction](#debug-auction) - [Prebid Server Test Request](#prebid-server-test-request) - + {: .alert.alert-danger :} All AppNexus (Xandr) placements included in a single call to `requestBids` must belong to the same parent Publisher. If placements from two different publishers are included in the call, the AppNexus bidder will not return any demand for those placements.
@@ -77,7 +77,7 @@ The table below will reflect both formats, though it's recommended to use the lo | `externalImpId` or `external_imp_id` | optional | Specifies the unique identifier of an externally generated auction. | `'bacbab02626452b097f6030b3c89ac05'` | `string` | | `generate_ad_pod_id` | optional | Signal to AppNexus to split impressions by ad pod and add unique ad pod id to each request. Specific to long form video endpoint only. Supported by Prebid Server, not Prebid JS. | `true` | `boolean` | - + #### Video Object @@ -92,8 +92,7 @@ The table below will reflect both formats, though it's recommended to use the lo | `playback_method` | A string that sets the playback method supported by the publisher. Allowed values: `"auto_play_sound_on"`; `"auto_play_sound_off"`; `"click_to_play"`; `"mouse_over"`; `"auto_play_sound_unknown"`. | `string` | | `frameworks` | Array of integers listing API frameworks supported by the publisher. Allowed values: None: `0`; VPAID 1.0: `1`; VPAID 2.0: `2`; MRAID 1.0: `3`; MRAID 2.0: `4`; ORMMA: `5`; OMID 1.0 `6`. | `Array` | - - + #### User Object @@ -107,8 +106,7 @@ The table below will reflect both formats, though it's recommended to use the lo | `dnt` | Do not track flag. Indicates if tracking cookies should be disabled for this auction | `true` | `boolean` | | `language` | Two-letter ANSI code for this user's language. | `EN` | `string` | - - + #### App Object @@ -121,13 +119,13 @@ AppNexus supports using prebid within a mobile app's webview. If you are interes | `device_id` | Object that contains the advertising identifiers of the user (`idfa`, `aaid`, `md5udid`, `sha1udid`, or `windowsadid`). | `{ aaid: "38400000-8cf0-11bd-b23e-10b96e40000d" }` | `object` | | `geo` | Object that contains the latitude (`lat`) and longitude (`lng`) of the user. | `{ lat: 40.0964439, lng: -75.3009142 }` | `object` | - + #### Custom Targeting keys AppNexus returns custom keys that can be sent to the adserver through bidderSettings: buyerMemberId, dealPriority, and dealCode. The following snippet demonstrates how to add these custom keys as key-value pairs. -``` +```javascript pbjs.bidderSettings = { appnexus: { adserverTargeting: [ @@ -153,14 +151,15 @@ pbjs.bidderSettings = { } ``` - + #### Auction Level Keywords It's possible to pass a set of keywords for the whole request, rather than a particular adUnit. Though they would apply to all adUnits (which include the appnexus bidder) in an auction, these keywords can work together with the bidder level keywords (if for example you want to have specific targeting for a particular adUnit). Below is an example of how to define these auction level keywords for the appnexus bidder: -``` + +```javascript pbjs.setConfig({ appnexusAuctionKeywords: { genre: ['classical', 'jazz'], @@ -171,14 +170,13 @@ pbjs.setConfig({ Like in the bidder.params.keywords, the values here can be empty. Please see the section immediately below for more details. - + #### Passing Keys Without Values It's possible to use the `keywords` parameter to define keys that do not have any associated values. Keys with empty values can be created in Prebid.js and can also be sent through Prebid Server to AppNexus. The following are examples of sending keys with empty values: - -``` +```javascript keywords: { myKeyword: '', myOtherKeyword: [''] @@ -189,14 +187,14 @@ The preceding example passes the key `myKeyword` with an empty value. The key `m You can define keys with values and without values in the same `keywords` definition. In this next example, we've defined the key `color` with an array of values: `red`, `blue`, and `green`. We've followed that with the key `otherKeyword` with an empty value array. -``` +```javascript keywords: { color: ['red', 'blue', 'green'], otherKeyword: [''] } ``` - + #### First Party Data @@ -206,14 +204,13 @@ At this time however, the `appnexus` bidder only reads the First Party Data when PBS/PSP supports all first party data fields: site, user, segments, and imp-level first party data. - - + #### User Sync in AMP If you are syncing user id's with Prebid Server and are using AppNexus' managed service, see [AMP Implementation Guide cookie-sync instructions](/dev-docs/show-prebid-ads-on-amp-pages.html#user-sync) for details. - + #### Mobile App Display Manager Version @@ -231,9 +228,9 @@ Enabling the AppNexus Debug Auction feature should only be done for diagnosing t To understand what is happening behind the scenes during an auction, you can enable a debug auction by adding an `apn_prebid_debug` cookie with a JSON string. For example: -{% highlight js %} +```javascript { "enabled": true, "dongle": "QWERTY", "debug_timeout": 1000, "member_id": 958 } -{% endhighlight %} +``` To view the results of the debug auction, add the `pbjs_debug=true` query string parameter and open your browser's developer console. @@ -251,22 +248,22 @@ The following test parameters can be used to verify that Prebid Server is workin server-side Appnexus adapter. This example includes an `imp` object with an Appnexus test placement ID and sizes that would match with the test creative. -``` - "imp": [{ - "id": "some-impression-id", - "banner": { - "format": [{ - "w": 600, - "h": 500 - }, { - "w": 300, - "h": 600 - }] - }, - "ext": { - "appnexus": { - "placement_id": 13144370 - } - } - }] +```json +"imp": [{ + "id": "some-impression-id", + "banner": { + "format": [{ + "w": 600, + "h": 500 + }, { + "w": 300, + "h": 600 + }] + }, + "ext": { + "appnexus": { + "placement_id": 13144370 + } + } +}] ``` diff --git a/dev-docs/bidders/astraone.md b/dev-docs/bidders/astraone.md index e286f085..044075e2 100644 --- a/dev-docs/bidders/astraone.md +++ b/dev-docs/bidders/astraone.md @@ -15,28 +15,25 @@ You can use this adapter to get a bid from AstraOne. Please reach out to your AstraOne account team before using this plugin to get placeId. The code below returns a demo ad. - ### Bid Params {: .table .table-bordered .table-striped } | Name | Scope | Description | Example | Type | |---------------------|---------------------|-------------------------------------------------------------------|-------------------------------------------------------------------------------|----------| | `placeId` | required | The place id. | '5af45ad34d506ee7acad0c26' | `string` | -| `imageUrl` | required | URL of the image on which the banner will be displayed. | 'https://creative.astraone.io/files/default_image-1-600x400.jpg' | `string` | +| `imageUrl` | required | URL of the image on which the banner will be displayed. | `'https://creative.astraone.io/files/default_image-1-600x400.jpg'` | `string` | | `placement` | required | Adunit placement, possible values: inImage | 'inImage' | `string` | - ### InImage Example page - ```html - - Prebid.js Banner Example - - - + + Prebid.js Banner Example + + + + -

Prebid.js InImage Banner Test

+

Prebid.js InImage Banner Test

-
- +
+ - -
+ +
``` diff --git a/dev-docs/bidders/duration.md b/dev-docs/bidders/duration.md index 4943f689..f7980da4 100644 --- a/dev-docs/bidders/duration.md +++ b/dev-docs/bidders/duration.md @@ -26,51 +26,52 @@ sidebarType: 1 | `placementId` | optional | placementId is provided by your Duration Media account manager(s). This parameter allows to report on a specific ad unit | | `integer` | | `video`| optional | Object containing video targeting parameters. Note that this parameter is not used in Prebid Server. See [Video Object](#duration-video-object) for details. | `video: { playback_method: ['auto_play_sound_off'] }` | `object`| - ### Note + If you are using Google Ad Manager (GAM), it is highly recommended to make sure the “Serve in Safeframe” box in creative settings is unchecked. If you absolutely want to run Duration Media in a Saferame creative, please contact your Duration Media repsentative to coordinate this setup. ### Test Parameters -``` - var adUnits = [ - { - code: 'test-div1', - mediaTypes: { - banner: { - sizes: [[300, 250]], // a display size - } - }, - bids: [ - { - bidder: "duration", - params: { - siteId: 2, - placementId: 3 - } - } - ] - },{ - code: 'test-div2', - mediaTypes: { - banner: { - sizes: [[320, 50]], // a mobile size + +```javascript +var adUnits = [ + { + code: 'test-div1', + mediaTypes: { + banner: { + sizes: [[300, 250]], // a display size + } + }, + bids: [ + { + bidder: "duration", + params: { + siteId: 2, + placementId: 3 } - }, - bids: [ - { - bidder: "duration", - params: { - siteId: 2 - } + } + ] + },{ + code: 'test-div2', + mediaTypes: { + banner: { + sizes: [[320, 50]], // a mobile size + } + }, + bids: [ + { + bidder: "duration", + params: { + siteId: 2 } - ] - } - ]; + } + ] + } +]; ``` - + #### Video Object @@ -84,4 +85,3 @@ If you absolutely want to run Duration Media in a Saferame creative, please cont | `minduration` | Integer that defines the minimum video ad duration in seconds. | `integer` | | `maxduration` | Integer that defines the maximum video ad duration in seconds. | `integer` | | `frameworks` | Array of integers listing API frameworks supported by the publisher. Allowed values: None: `0`; VPAID 1.0: `1`; VPAID 2.0: `2`; MRAID 1.0: `3`; ORMMA: `4`; MRAID 2.0: `5`. | `Array` | - diff --git a/dev-docs/bidders/goldbach.md b/dev-docs/bidders/goldbach.md index 343dbbaa..f637f537 100644 --- a/dev-docs/bidders/goldbach.md +++ b/dev-docs/bidders/goldbach.md @@ -29,7 +29,7 @@ sidebarType: 1 - [Mobile App Display Manager Version](#mobile-app-display-manager-version) - [Debug Auction](#debug-auction) - + {: .alert.alert-danger :} All Goldbach (Xandr) placements included in a single call to `requestBids` must belong to the same parent Publisher. If placements from two different publishers are included in the call, the Goldbach bidder will not return any demand for those placements.
@@ -61,7 +61,7 @@ All Goldbach (Xandr) placements included in a single call to `requestBids` must | `externalImpId` | optional | Specifies the unique identifier of an externally generated auction. | `'bacbab02626452b097f6030b3c89ac05'` | `string` | | `generate_ad_pod_id`| optional | Signal to Goldbach to split impressions by ad pod and add unique ad pod id to each request. Specific to long form video endpoint only. Supported by Prebid Server, not Prebid JS. | `true` | `boolean` | - + #### Video Object @@ -76,8 +76,7 @@ All Goldbach (Xandr) placements included in a single call to `requestBids` must | `playback_method` | A string that sets the playback method supported by the publisher. Allowed values: `"auto_play_sound_on"`; `"auto_play_sound_off"`; `"click_to_play"`; `"mouse_over"`; `"auto_play_sound_unknown"`. | `string` | | `frameworks` | Array of integers listing API frameworks supported by the publisher. Allowed values: None: `0`; VPAID 1.0: `1`; VPAID 2.0: `2`; MRAID 1.0: `3`; MRAID 2.0: `4`; ORMMA: `5`; OMID 1.0 `6`. | `Array` | - - + #### User Object @@ -91,8 +90,7 @@ All Goldbach (Xandr) placements included in a single call to `requestBids` must | `dnt` | Do not track flag. Indicates if tracking cookies should be disabled for this auction | `true` | `boolean` | | `language` | Two-letter ANSI code for this user's language. | `EN` | `string` | - - + #### App Object @@ -105,13 +103,13 @@ Goldbach supports using prebid within a mobile app's webview. If you are interes | `device_id` | Object that contains the advertising identifiers of the user (`idfa`, `aaid`, `md5udid`, `sha1udid`, or `windowsadid`). | `{ aaid: "38400000-8cf0-11bd-b23e-10b96e40000d" }` | `object` | | `geo` | Object that contains the latitude (`lat`) and longitude (`lng`) of the user. | `{ lat: 40.0964439, lng: -75.3009142 }` | `object` | - + #### Custom Targeting keys Goldbach returns custom keys that can be sent to the adserver through bidderSettings: buyerMemberId, dealPriority, and dealCode. The following snippet demonstrates how to add these custom keys as key-value pairs. -``` +```javascript pbjs.bidderSettings = { godlbach: { adserverTargeting: [ @@ -137,14 +135,14 @@ pbjs.bidderSettings = { } ``` - + #### Passing Keys Without Values It's possible to use the `keywords` parameter to define keys that do not have any associated values. Keys with empty values can be created in Prebid.js and can also be sent through Prebid Server to Goldbach. The following are examples of sending keys with empty values: -``` +```javascript keywords: { myKeyword: '', myOtherKeyword: [''] @@ -155,20 +153,20 @@ The preceding example passes the key `myKeyword` with an empty value. The key `m You can define keys with values and without values in the same `keywords` definition. In this next example, we've defined the key `color` with an array of values: `red`, `blue`, and `green`. We've followed that with the key `otherKeyword` with an empty value array. -``` +```javascript keywords: { color: ['red', 'blue', 'green'], otherKeyword: [''] } ``` - + #### User Sync in AMP If you are syncing user id's with Prebid Server and are using Goldbach's managed service, see [AMP Implementation Guide cookie-sync instructions](/dev-docs/show-prebid-ads-on-amp-pages.html#user-sync) for details. - + #### Mobile App Display Manager Version @@ -186,9 +184,9 @@ Enabling the Goldbach Debug Auction feature should only be done for diagnosing t To understand what is happening behind the scenes during an auction, you can enable a debug auction by adding an `apn_prebid_debug` cookie with a JSON string. For example: -{% highlight js %} +```javascript { "enabled": true, "dongle": "QWERTY", "debug_timeout": 1000, "member_id": 958 } -{% endhighlight %} +``` To view the results of the debug auction, add the `pbjs_debug=true` query string parameter and open your browser's developer console. @@ -199,4 +197,3 @@ To view the results of the debug auction, add the `pbjs_debug=true` query string | `dongle` | Your account's unique debug password. | `QWERTY` | `string` | | `member_id` | The ID of the member running the debug auction | `958` | `integer` | | `debug_timeout` | The timeout for the debug auction results to be returned | `3000` | `integer` | - diff --git a/dev-docs/bidders/grid.md b/dev-docs/bidders/grid.md index c3984c8b..f366b36f 100644 --- a/dev-docs/bidders/grid.md +++ b/dev-docs/bidders/grid.md @@ -27,7 +27,7 @@ sidebarType: 1 - [First Party Data](#first-party-data) - [Native setup example (s2s only)](#native-setup-example-s2s-only) - + ### Bid Params @@ -37,12 +37,13 @@ sidebarType: 1 | `uid` | required | Represents the MediaGrid bidder system Ad Slot ID associated with the respective div id from the site page. | `1` | `integer` | | `bidFloor` | optional | Floor of the impression opportunity. If present in the request overrides XML info. | `0.8` | `float` | - + ### Bidder Config You can allow writing in localStorage `pbjs.setBidderConfig` for the bidder `grid` -``` + +```javascript pbjs.setBidderConfig({ bidders: ["grid"], config: { @@ -50,9 +51,10 @@ pbjs.setBidderConfig({ } }) ``` + If it will be "true" this allow TheMediaGrid Bid Adapter to write userId in first party localStorage - + ### First Party Data @@ -73,12 +75,13 @@ AdUnit-specific data using `AdUnit.ortb2Imp` supports following fields: - `ortb2.imp[].ext.data.*` - `ortb2.imp[].instl` - + ### Native setup example (s2s only) Setup native in adUnit mediaTypes, for example: -``` + +```javascript ... mediaTypes: { native: { diff --git a/dev-docs/bidders/hybrid.md b/dev-docs/bidders/hybrid.md index aaeebc1e..7520627d 100644 --- a/dev-docs/bidders/hybrid.md +++ b/dev-docs/bidders/hybrid.md @@ -15,16 +15,14 @@ You can use this adapter to get a bid from Hybrid.ai Please reach out to your Hybrid.ai account team before using this plugin to get placeId. The code below returns a demo ad. - ### Bid Params {: .table .table-bordered .table-striped } -| Name | Scope | Description | Example | Type | -|---------------------|------------------------|-------------------------------------------------------------------|--------------------------------------|----------| -| `placeId` | required | The place id. | '5af45ad34d506ee7acad0c26' | `string` | -| `placement` | required | Adunit placement, possible values: banner, video, inImage | 'banner' | `string` | -| `imageUrl` | required for inImage | URL of the image on which the banner will be displayed | 'https://hybrid.ai/images/image.jpg' | `string` | - +| Name | Scope | Description | Example | Type | +|---------------------|------------------------|-------------------------------------------------------------------|----------------------------------------|----------| +| `placeId` | required | The place id. | '5af45ad34d506ee7acad0c26' | `string` | +| `placement` | required | Adunit placement, possible values: banner, video, inImage | 'banner' | `string` | +| `imageUrl` | required for inImage | URL of the image on which the banner will be displayed | `'https://hybrid.ai/images/image.jpg'` | `string` | ### Sample Banner Ad Unit @@ -94,10 +92,10 @@ var adUnits = [{ - - Prebid.js Banner Example - - - + + Prebid.js Banner Example + + + + -

Prebid.js Banner Ad Unit Test

-
- - -
+

Prebid.js Banner Ad Unit Test

+
+ + +
``` diff --git a/dev-docs/bidders/improvedigital.md b/dev-docs/bidders/improvedigital.md index eebe5e9a..739baf9f 100755 --- a/dev-docs/bidders/improvedigital.md +++ b/dev-docs/bidders/improvedigital.md @@ -33,7 +33,6 @@ sidebarType: 1 | `extend` | optional | See the [Extend mode section](#improvedigital-extend) | `true` | `boolean` | | `rendererConfig` | optional | Configuration object for JS renderer of the RAZR creatives. Provided by Improve Digital. | `{ key1: value1 }` | `object` | - ### Configuration @@ -41,7 +40,8 @@ sidebarType: 1 #### Sizes By default, the adapter doesn't send Prebid ad unit sizes to Improve Digital's ad server and the sizes defined for each placement in the Polaris platform will be used. If the ad server should only respond with creative sizes as defined in Prebid ad unit configuration, turn on `usePrebidSizes` adapter parameter like this: -``` + +```javascript pbjs.setConfig({ improvedigital: { usePrebidSizes: true } }); @@ -53,7 +53,7 @@ pbjs.setConfig({ Global configuration for the special creative format renderer. Please use [rendererConfig bid param](#improvedigital-params) for ad slot specific configuration. -``` +```javascript pbjs.setConfig({ improvedigital: { rendererConfig: { @@ -69,10 +69,11 @@ pbjs.setConfig({ Improve Digital Extend mode provides publishers with access to additional demand from other SSPs. Before enabling please contact our team for more information. The Extend mode can be enabled: + * per ad unit via the `extend` [bid param](#improvedigital-params) * for all ad units via `setConfig()`: -``` +```javascript pbjs.setConfig({ improvedigital: { extend: true @@ -80,42 +81,46 @@ pbjs.setConfig({ }); ``` - + ### Examples Examples of different ad unit formats can be found in [Prebid.js ad unit reference](https://docs.prebid.org/dev-docs/adunit-reference.html#adUnit-banner-example). Improve Digital bidder must be added in the ad unit's `bids` array. Example: - pbjs.addAdUnits({ - code: 'banner1', - sizes: [[728, 90], [970, 250]], - bids: [ - { - bidder: 'improvedigital', - params: { - placementId: 1111111, - publisherId: 1234 - } +```javascript +pbjs.addAdUnits({ + code: 'banner1', + sizes: [[728, 90], [970, 250]], + bids: [ + { + bidder: 'improvedigital', + params: { + placementId: 1111111, + publisherId: 1234 } - ] - }); + } + ] +}); +``` #### Example for Key-Values - pbjs.addAdUnits({ - code: 'banner1', - sizes: [[600, 290]], - bids: [ - { - bidder: 'improvedigital', - params: { - placementId: 1111111, - publisherId: 1234, - keyValues: { - testKey1: ["testValueA"], - testKey2: ["testValueB", "testValueC"] - } +```javascript +pbjs.addAdUnits({ + code: 'banner1', + sizes: [[600, 290]], + bids: [ + { + bidder: 'improvedigital', + params: { + placementId: 1111111, + publisherId: 1234, + keyValues: { + testKey1: ["testValueA"], + testKey2: ["testValueB", "testValueC"] } } - ] - }); + } + ] +}); +``` diff --git a/dev-docs/bidders/ix-server.md b/dev-docs/bidders/ix-server.md index dbcd1baa..1c9e08bb 100644 --- a/dev-docs/bidders/ix-server.md +++ b/dev-docs/bidders/ix-server.md @@ -26,21 +26,20 @@ sidebarType: 1 ## Table of contents -- [Table of contents](#table-of-contents) -- [Introduction](#introduction) -- [Supported media types](#supported-media-types) -- [Setup instructions to call Index through Prebid Server](#setup-instructions-to-call-index-through-prebid-server) - - [Call Index from a web browser](#call-index-from-a-web-browser) - - [Call Index from Prebid Mobile SDK](#call-index-from-prebid-mobile-sdk) - - [Call Index from CTV/long-form video environment](#call-index-from-ctvlong-form-video-environment) - - [Call Index from any other server-to-server OpenRTB environment](#call-index-from-any-other-server-to-server-openrtb-environment) -- [Bid request parameters](#bid-request-parameters) - - [Banner](#banner) - - [Video](#video) -- [Examples](#examples) - - - +* [Table of contents](#table-of-contents) +* [Introduction](#introduction) +* [Supported media types](#supported-media-types) +* [Setup instructions to call Index through Prebid Server](#setup-instructions-to-call-index-through-prebid-server) + * [Call Index from a web browser](#call-index-from-a-web-browser) + * [Call Index from Prebid Mobile SDK](#call-index-from-prebid-mobile-sdk) + * [Call Index from CTV/long-form video environment](#call-index-from-ctvlong-form-video-environment) + * [Call Index from any other server-to-server OpenRTB environment](#call-index-from-any-other-server-to-server-openrtb-environment) +* [Bid request parameters](#bid-request-parameters) + * [Banner](#banner) + * [Video](#video) +* [Examples](#examples) + + ## Introduction @@ -51,11 +50,11 @@ Publishers can use Prebid Server in any of the following ways with Index Exchang * In CTV apps and other long-form video environments, you (or the SSAI vendor) can make a call to Prebid Server using OpenRTB, and then Prebid Server uses our server-side adapter to call Index. For set up instructions, see [Call Index from CTV/long-form video environment](#set-up-instructions-to-call-index-through-prebid-server) section on this page. * In any other server-to-server OpenRTB environment, you can send OpenRTB bid requests to the Prebid Server host of your choice. For set up instructions, see [Call Index from any other server-to-server OpenRTB environment](#call-index-from-ortb) section on this page. -**Note about sending multiple ad slots in a single bid request:** Index accepts up to 100 valid ad slots in a single bid request. If a single bid request contains more than 100 ad slots (including invalid ad slots), only the first 100 valid ad slots are accepted and the rest are ignored. For example streaming TV media owners can signal multiple ad pods for long-form programming in a single request. +**Note about sending multiple ad slots in a single bid request:** Index accepts up to 100 valid ad slots in a single bid request. If a single bid request contains more than 100 ad slots (including invalid ad slots), only the first 100 valid ad slots are accepted and the rest are ignored. For example streaming TV media owners can signal multiple ad pods for long-form programming in a single request. - + -## Supported media types +## Supported media types The following table lists the media types that Index supports. For information about the the Time-To-Live (TTL) for each media type, see [How Index counts impressions](https://kb.indexexchange.com/publishers/billing/how_Index_counts_impressions.htm) in our Knowledge Base. @@ -66,24 +65,23 @@ The following table lists the media types that Index supports. For information a | video | Supported, including ad pods for OTT | | native | Supported | - -## Setup instructions to call Index through Prebid Server + + +## Setup instructions to call Index through Prebid Server **Note:** If you are hosting your own Prebid Server instance, you must contact your Index Exchange Representative to get an endpoint and setup instructions. If you are using an existing Prebid Server instance that is already configured to call Index, depending on whether you want to call Index from the browser, mobile app, CTV, or long-form video, follow any of the below sections to complete the Index-specific configuration. + - - -### Call Index from a web browser +### Call Index from a web browser If you want to call Index from a web environment, you can use Prebid.js to call Prebid Server and then Prebid Server uses our server-side adapter to call Index. For setup instructions, see the Index-specific configuration steps in [Set up instructions for Prebid.js](https://docs.prebid.org/dev-docs/bidders/ix.html) in our Prebid.js documentation on the Prebid site. + - - -### Call Index from Prebid Mobile SDK +### Call Index from Prebid Mobile SDK **Before you begin:** Contact your Index Exchange representative to get your `siteId`. You must provide this site ID to your Prebid Server host company. @@ -91,31 +89,32 @@ If you want to call Index from a web environment, you can use Prebid.js to call To add Index as a bidder to your mobile app: -1. Inform your Prebid Server hosting company to add `ix `as a bidder in the configuration and include the `siteId` that Index provides to you at the time of integration. +1. Inform your Prebid Server hosting company to add `ix`as a bidder in the configuration and include the `siteId` that Index provides to you at the time of integration. 2. Define the Index-specific parameters at the bidder level. For information about these parameters, see the [Bid request parameters](#bid-request-parameters) section below. 3. Include any ad unit level required or optional parameters provided in Prebid's [Prebid Mobile API - iOS](https://docs.prebid.org/prebid-mobile/pbm-api/ios/ios-sdk-integration-gam-original-api.html) and [Prebid Mobile API - Android](https://docs.prebid.org/prebid-mobile/pbm-api/android/android-sdk-integration-gam-original-api.html) documentation. - + ### Call Index from CTV/long-form video environment - + **Before you begin:** Contact your Index Exchange Representative to get the `siteId`. You must provide this site ID to your Prebid Server host company. **Note:** To implement CTV and long-form video using Prebid Server, follow Prebid's [Long Form Video](https://docs.prebid.org/prebid-server/use-cases/pbs-lfv.html) documentation. To add Index as a bidder: -1. Inform your Prebid Server hosting company to add `ix `as a bidder in the configuration and include the `siteId` that Index provides to you at the time of integration. +1. Inform your Prebid Server hosting company to add `ix`as a bidder in the configuration and include the `siteId` that Index provides to you at the time of integration. 2. Define the Index-specific parameters at the bidder level. For information about these parameters, see the [Bid request parameters](#bid-request-parameters) section below. 3. Include any ad unit level required or optional parameters provided in Prebid's [/openrtb2/video](https://docs.prebid.org/prebid-server/endpoints/openrtb2/pbs-endpoint-video.html) documentation. - + -### Call Index from any other server-to-server OpenRTB environment +### Call Index from any other server-to-server OpenRTB environment To request bids from Index: -* In requests that you make to your Prebid Server host, add `imp.ext.ix` and include the `siteId `that Index provides to you at the time of integration.
+* In requests that you make to your Prebid Server host, add `imp.ext.ix` and include the `siteId` that Index provides to you at the time of integration.
+ **Example:** ```javascript @@ -128,27 +127,24 @@ To request bids from Index: }], ``` + - - -## Bid request parameters +## Bid request parameters For a list of the OpenRTB fields that Index supports in bid requests, see [List of supported OpenRTB bid request fields for sellers](https://kb.indexexchange.com/publishers/openrtb_integration/list_of_supported_openrtb_bid_request_fields_for_sellers.htm#List_of_supported_OpenRTB_bid_request_fields_for_sellers). The following are the required fields for the various supported media types. +### Banner -### Banner - -You must include these parameters at the bidder level. +You must include these parameters at the bidder level. {: .table .table-bordered .table-striped } | Key | Scope | Type | Description | |---|---|---|---| | `siteId` | Required | String | An Index-specific identifier that is associated with this ad unit. This is similar to a placement ID or an ad unit ID that some other modules have. For example, `'3723'`, `'6482'`, `'3639'`| -### Video - -You must include these parameters at the bidder level. +### Video +You must include these parameters at the bidder level. {: .table .table-bordered .table-striped } | Key | Scope | Type | Description | @@ -157,7 +153,6 @@ You must include these parameters at the bidder level. If you are using Index's outstream player and have placed the video object at the bidder level, you must include the Index required parameters at the bidder level. You can include the optional parameters to specify the outstream player configurations. - {: .table .table-bordered .table-striped } | Key | Scope | Type | Description | |---|---|---|---| @@ -168,14 +163,13 @@ If you are using Index's outstream player and have placed the video object at th | `video.playerConfig.floatOnScroll` | Optional | Boolean | A boolean specifying whether you want to use the player's floating capabilities, where:
- `true`: Use the Index player's float capabilities.
**Note:** If you set `floatOnScroll` to `true`, Index updates the placement value to `5`.
**Note:** We do not recommend using the player's default float capabilities if you have more than one outstream ad unit per page.
-`false`: Do not use the Index player's float capabilities (default). | | `video.playerConfig.floatSize` | Optional | Integer[] | The height and width of the floating player in pixels. If you do not specify a float size, the player adjusts to the aspect ratio of the player size that is defined when it is not floating. Index recommends that you review and test the float size to your user experience preference. | -
+ -## Examples +## Examples **Banner** - -```javascript +```json { "id": "ix-banner-id", "imp": [ @@ -230,11 +224,9 @@ If you are using Index's outstream player and have placed the video object at th } ``` +**Video** -**Video** - - -```javascript +```json { "id": "ix-video-example", "imp": [ diff --git a/dev-docs/bidders/ix.md b/dev-docs/bidders/ix.md index 9f528a1a..57beb1b4 100644 --- a/dev-docs/bidders/ix.md +++ b/dev-docs/bidders/ix.md @@ -25,27 +25,27 @@ sidebarType: 1 ## Table of contents -- [Table of contents](#table-of-contents) -- [Introduction](#introduction) -- [Supported media types](#supported-media-types) -- [Set up Prebid.js to call Index directly from the browser (client-side adapter)](#set-up-prebidjs-to-call-index-directly-from-the-browser-client-side-adapter) -- [Set up Prebid.js to call Index through Prebid Server (server-side adapter)](#set-up-prebidjs-to-call-index-through-prebid-server-server-side-adapter) -- [Modules to include in your build process](#modules-to-include-in-your-build-process) -- [Set up First Party Data (FPD)](#set-up-first-party-data-fpd) - - [Global data](#prebid-fpd-module) - - [Index bidder-specific data](#index-bidder-specific-fpd-module) - - [AdUnit-specific data](#adunit-specific-data) -- [Index's outstream video player](#indexs-outstream-video-player) -- [Prebid Native configuration](#prebid-native-configuration) -- [Bid request parameters](#bid-request-parameters) - - [Banner](#banner) - - [Video](#video) - - [Native](#native) -- [Multi-format ad units](#multi-format-ad-units) -- [Examples](#examples) - - - +* [Table of contents](#table-of-contents) +* [Introduction](#introduction) +* [Supported media types](#supported-media-types) +* [Set up Prebid.js to call Index directly from the browser (client-side adapter)](#set-up-prebidjs-to-call-index-directly-from-the-browser-client-side-adapter) +* [Set up Prebid.js to call Index through Prebid Server (server-side adapter)](#set-up-prebidjs-to-call-index-through-prebid-server-server-side-adapter) +* [Modules to include in your build process](#modules-to-include-in-your-build-process) +* [Set up First Party Data (FPD)](#set-up-first-party-data-fpd) + * [Global data](#prebid-fpd-module) + * [Index bidder-specific data](#index-bidder-specific-fpd-module) + * [AdUnit-specific data](#adunit-specific-data) +* [Index's outstream video player](#indexs-outstream-video-player) +* [Prebid Native configuration](#prebid-native-configuration) +* [Bid request parameters](#bid-request-parameters) + * [Banner](#banner) + * [Video](#video) + * [Native](#native) +* [Multi-format ad units](#multi-format-ad-units) +* [Examples](#examples) + + + ## Introduction @@ -54,15 +54,18 @@ Publishers can use Prebid.js to call Index Exchange (Index) in any of the follow * **Call through our client-side adapter:** Prebid.js calls Index directly from the browser using our client-side adapter. This option tends to have a better cookie match rate. For configuration instructions, see the [Set up Prebid.js to call Index directly from the browser (client-side adapter)](#client-side-adapter) on this page. * **Call through our server-side adapter**: Prebid.js makes a call to Prebid Server and then Prebid Server uses our server-side adapter to call Index. This reduces workload on the browser. For configuration instructions, see the [Set up Prebid.js to call Index through Prebid Server (server-side adapter)](#server-side-adapter) on this page. -**Notes:** +**Notes:** + * **Send multiple ad slots in a single bid request**: Index accepts up to 100 valid ad slots in a single bid request. If a single bid request contains more than 100 ad slots (including invalid ad slots), only the first 100 valid ad slots are accepted and the rest are ignored. For example streaming TV media owners can signal multiple ad pods for long-form programming in a single request. * **How to view bid requests sent to Index:** - * In your browser, open a new tab. - * Open the **Developer tools**. - * In **Developer tools**, click the **Network** tab. - * In the **Network** tab, search for requests sent to `casalemedia.com/cygnus` (from version 6.28.0 and earlier) or `casalemedia.com/openrtb/pbjs` (from version 6.29.0 and later). These are the bid requests sent to Index. -* **Recommended Global Bidder settings:** For our adapter, Index recommends enabling local storage. As of Prebid.js 7.x, local storage access must be explicitly specified. By leveraging local storage, Index is able to take advantage of the latest features our exchange has to offer. For instructions on enabling local storage, see Prebid’s [pbjs.bidderSettings](https://docs.prebid.org/dev-docs/publisher-api-reference/bidderSettings.html) documentation.
-Example: + * In your browser, open a new tab. + * Open the **Developer tools**. + * In **Developer tools**, click the **Network** tab. + * In the **Network** tab, search for requests sent to `casalemedia.com/cygnus` (from version 6.28.0 and earlier) or `casalemedia.com/openrtb/pbjs` (from version 6.29.0 and later). These are the bid requests sent to Index. +* **Recommended Global Bidder settings:** For our adapter, Index recommends enabling local storage. As of Prebid.js 7.x, local storage access must be explicitly specified. By leveraging local storage, Index is able to take advantage of the latest features our exchange has to offer. For instructions on enabling local storage, see Prebid’s [pbjs.bidderSettings](https://docs.prebid.org/dev-docs/publisher-api-reference/bidderSettings.html) documentation. + +### Example + ```javascript pbjs.bidderSettings = { ix: { @@ -71,9 +74,9 @@ pbjs.bidderSettings = { }; ``` - + -## Supported media types +## Supported media types The following table lists the media types that Index supports. For information about the the Time-To-Live (TTL) for each media type, see [How Index counts impressions](https://kb.indexexchange.com/publishers/billing/how_Index_counts_impressions.htm) in our Knowledge Base. @@ -85,30 +88,32 @@ The following table lists the media types that Index supports. For information a | video | Supported | | native | Supported | - + ## Set up Prebid.js to call Index directly from the browser (client-side adapter) In this configuration Prebid.js calls Index directly from the browser using our client-side adapter. Follow the quick start instructions provided in Prebid's [Getting Started for Developers](https://docs.prebid.org/dev-docs/getting-started.html) documentation. Complete the following steps to complete the Index-specific configuration: - 1. Build the binary in one of the following ways: * [Download Prebid.js](https://docs.prebid.org/download.html) from the Prebid site to use the standard compiled binary that Prebid includes in the download process and select **Index Exchange** as an adapter. - * Build it on your own from the source code by following the instructions in [Prebid.js project README](https://github.com/prebid/Prebid.js/blob/master/README.md#build-optimization). If you use this method, you will need to include several modules in your build process. See the [Index modules to include in your build process](#modules-to-include-in-your-build-process) section below. + * Build it on your own from the source code by following the instructions in [Prebid.js project README](https://github.com/prebid/Prebid.js/blob/master/README.md#build-optimization). If you use this method, you will need to include several modules in your build process. See the [Index modules to include in your build process](#modules-to-include-in-your-build-process) section below. 2. Define the Index-specific parameters at the bidder level which include adding `ix` as the bidder and the `siteId`. For Index's bidder-specific parameters, see the [Bid request parameters](#bid-request-parameters) section below.
-**Example:** +**Example:** + ```javascript { - bidder: 'ix', - params: { - siteId: '123456' - } + bidder: 'ix', + params: { + siteId: '123456' } +} ``` 3. Define your ad units in the `adUnit` object. This includes the details about the ad slots such as the media types, ad size, and ad code. For more information about this object, see Prebid's [Ad Unit Reference](https://docs.prebid.org/dev-docs/adunit-reference.html) documentation. 4. Enable user syncing by adding the following code in the [pbjs.setConfig()](https://docs.prebid.org/dev-docs/publisher-api-reference/setConfig.html) function. Index strongly recommends enabling user syncing through iFrames, though we do also support image-based syncing. This functionality improves DSP user match rates and increases the Index bid rate and bid price. Make sure to call `pbjs.setConfig()` only once. This configuration is optional in Prebid, but required by Index.
-**Example:** + +**Example:** + ```javascript pbjs.setConfig({ userSync: { @@ -122,21 +127,22 @@ In this configuration Prebid.js calls Index directly from the browser using our } }); ``` + 5. (Optional) Set up First Party Data (FPD). For more information about the data types we support and the instructions for each option, see the [Set up First Party Data (FPD)](#set-up-first-party-data-fpd) section below. 6. (Optional) If you want to monetize instream video, you need to enable a cache endpoint in the [pbjs.setConfig()](https://docs.prebid.org/dev-docs/publisher-api-reference/setConfig.html) function as follows:
-```javascript - pbjs.setConfig({ - cache: { - url: 'https://prebid.adnxs.com/pbc/v1/cache' - } - }); -``` + ```javascript + pbjs.setConfig({ + cache: { + url: 'https://prebid.adnxs.com/pbc/v1/cache' + } + }); + ``` 7. (Optional) If you want to monetize outstream video, you can choose among the following options. Outstream video is available from Prebid.js version 6.25 or higher. * Use Index’s outstream video player. For more information, see the [Index's outstream video player ](#indexs-outstream-video-player)section below. * Use your own outstream video player. For more information, see [Prebid's documentation on how to show video ads.](https://docs.prebid.org/dev-docs/show-outstream-video-ads.html) 8. (Optional) Configure Prebid Native with Index. For more information, see the [Prebid Native](#prebid-native-configuration) section below. Prebid Native is available from Prebid.js version 7.4.0 or higher. - + ## Set up Prebid.js to call Index through Prebid Server (server-side adapter) @@ -176,14 +182,15 @@ In this configuration, Prebid.js makes a call to Prebid Server and then Prebid S - + ## Modules to include in your build process If you are building the JS binary on your own from source code, follow the instructions in [Prebid.js project README](https://github.com/prebid/Prebid.js/blob/master/README.md#build-optimization). You will need to include the `ixBidAdapter`. If you want to show video ads with Google Ad Manager, also include the `dfpAdServerVideo` module. We highly recommend adding the `gptPreAuction` module as well, which improves a DSP's ability to bid accurately on your supply. The following is an example build command that include these modules:
`gulp build --modules=ixBidAdapter,dfpAdServerVideo,gptPreAuction,fooBidAdapter,bazBidAdapter` -If you are using a JSON file to specify modules, add `ixBidAdapter` and `dfpAdServerVideo` to the modules array as follows: +If you are using a JSON file to specify modules, add `ixBidAdapter` and `dfpAdServerVideo` to the modules array as follows: + ```javascript [ "ixBidAdapter", @@ -195,13 +202,13 @@ If you are using a JSON file to specify modules, add `ixBidAdapter` and `dfpAdSe ``` - + ## Set up First Party Data (FPD) You can set up the Prebid.js FPD module using Global data, Index bidder-specific site data, or ad unit-specific data. Index supports deal targeting in all the three FPD types. - + ### Global data @@ -222,7 +229,7 @@ pbjs.setConfig({ }); ``` - + ### Index bidder-specific data @@ -241,30 +248,30 @@ To include the FPD in a bid request, in the `[pbjs.setConfig()]` object at the ` } }); ``` - + + ### AdUnit-specific data Use this data type to specify key-value pairs at the ad unit level when targeting deals and apply it to all bidders. This will be available from Prebid.js version 7.46 and above. To include the adUnit-specific data in a bid request, see Prebid's [Supplying AdUnit-Specific Data](https://docs.prebid.org/features/firstPartyData.html#supplying-adunit-specific-data) documentation. - ```javascript ortb2Imp: { ext: { data: { pbadslot: "homepage-top-rect", adUnitSpecificAttribute: "123" - } - } - } + } + } +} ``` - + ## Index's outstream video player Publishers who are using Index as a bidding adapter in Prebid.js can show outstream video ads on their site using Index's outstream video player. This allows a video ad to be placed anywhere on a publisher’s site, such as in-article, in-feed, and more. Outstream video is available from Prebid.js version 6.25 or higher.
-**Note:** When you use the Index renderer for outstream video, all impressions are considered viewable, which is similar to how Google's ActiveView counts impressions for outstream. This is because Index renders the outstream video as soon as it is in view and concurrently fires any impression pixels in the VAST. +**Note:** When you use the Index renderer for outstream video, all impressions are considered viewable, which is similar to how Google's ActiveView counts impressions for outstream. This is because Index renders the outstream video as soon as it is in view and concurrently fires any impression pixels in the VAST. To use Index’s outstream video player, in your Prebid.js configuration:
@@ -304,10 +311,9 @@ var adUnits = [{ }] ``` - *Please note that your use of the outstream video player will be governed by and subject to the terms and conditions of i) any master services or license agreement entered into by you and Index Exchange; ii) the information provided on our knowledge base linked [here](https://kb.indexexchange.com/publishers/prebid_integration/outstream_video_prebidjs.htm) and [here](https://kb.indexexchange.com/publishers/guidelines/standard_contractual_clauses.htm), and iii) our [Privacy Policy](https://www.indexexchange.com/privacy/). Your use of Index's outstream video player constitutes your acknowledgement and acceptance of the foregoing.* - + ## Prebid Native configuration @@ -354,17 +360,15 @@ pbjs.addAdUnits({ }); ``` + - - -## Bid request parameters +## Bid request parameters For a list of the OpenRTB fields that Index supports in bid requests, see [List of supported OpenRTB bid request fields for sellers](https://kb.indexexchange.com/publishers/openrtb_integration/list_of_supported_openrtb_bid_request_fields_for_sellers.htm#List_of_supported_OpenRTB_bid_request_fields_for_sellers). The following are the required fields for the various supported media types. +### Banner -### Banner - -You must include these parameters at the bidder level. +You must include these parameters at the bidder level. {: .table .table-bordered .table-striped } @@ -372,10 +376,9 @@ You must include these parameters at the bidder level. |---|---|---|---| | `siteId` | Required | String | An Index-specific identifier that is associated with this ad unit. This is similar to a placement ID or an ad unit ID that some other modules have. For example, `'3723'`, `'6482'`, `'3639'`| -### Video - -You must include these parameters at the bidder level. +### Video +You must include these parameters at the bidder level. {: .table .table-bordered .table-striped } @@ -397,14 +400,14 @@ If you are using Index's outstream player and have placed the video object at th | `video.playerConfig.floatOnScroll` | Optional | Boolean | A boolean specifying whether you want to use the player's floating capabilities, where:
- `true`: Use the Index player's float capabilities.
**Note:** If you set `floatOnScroll` to `true`, Index updates the placement value to `5`.
**Note:** We do not recommend using the player's default float capabilities if you have more than one outstream ad unit per page.
-`false`: Do not use the Index player's float capabilities (default). | | `video.playerConfig.floatSize` | Optional | Integer[] | The height and width of the floating player in pixels. If you do not specify a float size, the player adjusts to the aspect ratio of the player size that is defined when it is not floating. Index recommends that you review and test the float size to your user experience preference. | - ### Native Index supports the same set of native assets that Prebid.js recognizes. For the list of native assets, see [Prebid.js Native Implementation Guide on the Prebid site.](https://docs.prebid.org/prebid/native-implementation.html#3-prebidjs-native-adunit-overview) -
+ ## Multi-format ad units + Index supports multi-format ad units, see [Show Multi-Format Ads with Prebid.js](https://docs.prebid.org/dev-docs/show-multi-format-ads.html). For multi-format ad units, you can optionally specify a different siteId for each multi-format type at the bidder level. This is useful if you have deals set up with Index at the siteId level. See multi-format examples [here](#examples). The following are the parameters that you can specify for each multi-format type at the bidder level. @@ -418,15 +421,12 @@ The following are the parameters that you can specify for each multi-format type | `video.siteId` | Optional | String | An Index-specific identifier that is associated with this ad unit. This siteId will be prioritized over the default siteID for `video` format in the multi-format ad unit.| | `native.siteId` | Optional | String | An Index-specific identifier that is associated with this ad unit. This siteId will be prioritized over the default siteID for `native` format in the multi-format ad unit.| + - - -## Examples - +## Examples **Banner** - ```javascript var adUnits = [{ code: 'banner-div-a', @@ -444,15 +444,13 @@ var adUnits = [{ siteId: '123456' } } - }] + ] }]; ``` - **Video (instream):**
-**Note**: `context` can either be `'instream'` or `'outstream'`. - +**Note**: `context` can either be `'instream'` or `'outstream'`. ```javascript var adUnits = [{ @@ -485,10 +483,8 @@ var adUnits = [{ ``` - **Video (outstream)** - ```javascript var adUnits = [{ code: 'div-gpt-ad-1571167646410-1', @@ -520,10 +516,8 @@ var adUnits = [{ ``` - **Prebid Native** - ```javascript pbjs.addAdUnits({ code: slot.code, @@ -567,6 +561,7 @@ pbjs.addAdUnits({ ``` **Multi-format SiteId Overrides** + ```javascript var adUnits = [{ code: slot.code, diff --git a/dev-docs/bidders/medianet.md b/dev-docs/bidders/medianet.md index 7f38bd69..d882554e 100644 --- a/dev-docs/bidders/medianet.md +++ b/dev-docs/bidders/medianet.md @@ -26,7 +26,7 @@ sidebarType: 1 | `bidfloor` | optional | Bidfloor for the impression | `1.0` | `float` | | `video` | required for video Ad units | Object containing video targeting parameters. See [Video Object](#media.net-video-object) for details.|`video: { maxduration: 60 }` | `object` | -
+ #### Video Object @@ -37,20 +37,21 @@ sidebarType: 1 |minduration|integer|(Recommended) Specifies the minimum video ad duration, in seconds.|10| |maxduration|integer|(Recommended) Specifies the maximum video ad duration, in seconds.|60| |w|integer|(Recommended) Specifies the width of the video player, in pixels. Required if playerSize not present in `mediaTypes.video`|640| -|h|integer|(Recommended) Specifies the height of the video player, in pixels. Required if playerSize not present in `mediaTypes.video`|480| -|startdelay |integer | (Recommended) Specifies the start delay of the video ad|0| -|battr| array of integers|Specifies the video creative attributes to block. Refer to section 5.3 of the IAB specification for a list of attributes.| [ 13, 14 ]| -playbackmethod| array of integers| Specifies the allowed playback methods. If not specified, all are assumed to be allowed. Currently supported values are: `1: Autoplay, sound on`; `2: Autoplay, sound off`; `3: Click to play`; `4: Mouse over to play`|[1, 3]| -|api| array of integers| Specifies the supported API frameworks for this impression. If an API is not explicitly listed, it is assumed not to be supported. Currently supported values are: `1: VPAID 1.0`; `2: VPAID 2.0`; `3: MRAID-1`; `4: ORMMA`; `5: MRAID-2`|[1, 2]| -|protocols |array of integers| Array of supported video protocols. Currently supported values are: `1: VAST 1.0`; `2: VAST 2.0`; `3: VAST 3.0`; `4: VAST 1.0 Wrapper`; `5: VAST 2.0 Wrapper`; `6: VAST 3.0 Wrapper`; `7: VAST 4.0`|[1, 2]| -|placement |integer|Placement type for the impression. Possible options: `1: In-Stream`; `2: In-banner`; `3: Outstream/In-article`; `4: In-feed`; `5: Interstitial/Slider/Floating`; `6: Long-Form`;|1| +|h|integer|(Recommended) Specifies the height of the video player, in pixels. Required if playerSize not present in `mediaTypes.video`|480| +|startdelay|integer |(Recommended) Specifies the start delay of the video ad|0| +|battr|array of integers|Specifies the video creative attributes to block. Refer to section 5.3 of the IAB specification for a list of attributes.| [ 13, 14 ]| +playbackmethod|array of integers|Specifies the allowed playback methods. If not specified, all are assumed to be allowed. Currently supported values are: `1: Autoplay, sound on`; `2: Autoplay, sound off`; `3: Click to play`; `4: Mouse over to play`|[1, 3]| +|api| array of integers|Specifies the supported API frameworks for this impression. If an API is not explicitly listed, it is assumed not to be supported. Currently supported values are: `1: VPAID 1.0`; `2: VPAID 2.0`; `3: MRAID-1`; `4: ORMMA`; `5: MRAID-2`|[1, 2]| +|protocols|array of integers|Array of supported video protocols. Currently supported values are: `1: VAST 1.0`; `2: VAST 2.0`; `3: VAST 3.0`; `4: VAST 1.0 Wrapper`; `5: VAST 2.0 Wrapper`; `6: VAST 3.0 Wrapper`; `7: VAST 4.0`|[1, 2]| +|placement|integer|Placement type for the impression. Possible options: `1: In-Stream`; `2: In-banner`; `3: Outstream/In-article`; `4: In-feed`; `5: Interstitial/Slider/Floating`; `6: Long-Form`;|1| Besides the above-mentioned parameters, we support all other OpenRTB 2.x video objects as optional parameters. In addition to `bids[].params.video`, Media.net adapter consumes parameters specified in the `mediaTypes.video`. #### Example of Instream Video Ad-unit -``` + +```javascript var videoAdUnit = { code: 'video1', mediaTypes: { @@ -78,7 +79,8 @@ var videoAdUnit = { ``` #### Example of Native Ad-unit -``` + +```javascript var adUnits = [{ code: 'div-gpt-ad-1544091247692-0', mediaTypes: { @@ -111,7 +113,8 @@ var adUnits = [{ ``` #### Example of Banner Ad-unit -``` + +```javascript var adUnits = [{ code: 'div-gpt-ad-1460505748561-0', mediaTypes: { @@ -138,4 +141,3 @@ var adUnits = [{ }] }]; ``` - diff --git a/dev-docs/bidders/mgid.md b/dev-docs/bidders/mgid.md index d52a4baf..6e004742 100644 --- a/dev-docs/bidders/mgid.md +++ b/dev-docs/bidders/mgid.md @@ -23,7 +23,7 @@ sidebarType: 1 - [Test Parameters](#test-parameters) - [User Sync](#user-sync) - + ### Description @@ -31,7 +31,7 @@ One of the easiest way to gain access to MGID demand sources - MGID header bidd MGID header bidding adapter connects with MGID demand sources to fetch bids for display placements. Please reach out to your account manager or for more information. - + ### Bid params @@ -43,13 +43,13 @@ MGID header bidding adapter connects with MGID demand sources to fetch bids for | `bidFloor` | optional | Lowest value of expected bid price | `1.1` | `float` | | `currency` | optional | Currency of request and response | `'GBP'` | `string` | - - + ### Test Parameters 300x600 banner test -``` + +```javascript var adUnits = [{ code: 'div-prebid', mediaTypes: { @@ -68,7 +68,8 @@ var adUnits = [{ ``` 300x250 banner test -``` + +```javascript var adUnits = [{ code: 'div-prebid', mediaTypes: { @@ -87,7 +88,8 @@ var adUnits = [{ ``` native test -``` + +```javascript var adUnits = [{ code: 'div-prebid', mediaTypes: { @@ -120,7 +122,7 @@ var adUnits = [{ }]; ``` - + ### User Sync diff --git a/dev-docs/bidders/openx.md b/dev-docs/bidders/openx.md index 7e3fc168..56ebee98 100644 --- a/dev-docs/bidders/openx.md +++ b/dev-docs/bidders/openx.md @@ -22,7 +22,7 @@ sidebarType: 1 ### Registration -If you have any questions regarding set up, please reach out to your account manager or support@openx.com. +If you have any questions regarding set up, please reach out to your account manager or [support@openx.com]. Please note that OpenX is transitioning its serving architecture and currently has 2 bid adapters as of Prebid 7. The legacy adapter is named openxBidAdapter. The newer of the two is openxOrtbBidAdapter. Publishers are welcome to test with openxOrtbBidAdapter and give feedback. @@ -31,6 +31,7 @@ After the transition openxOrtbBidAdapter will replace openxBidAdapter. IMPORTANT: only include either openxBidAdapter or openxOrtbBidAdapter in your build. ### Bid Parameters + #### Banner {: .table .table-bordered .table-striped } @@ -45,8 +46,8 @@ IMPORTANT: only include either openxBidAdapter or openxOrtbBidAdapter in your bu ** platform is deprecated. Please use delDomain instead. If you have any questions please contact your representative. - ### AdUnit Format for Banner + ```javascript var adUnits = [ { @@ -113,8 +114,8 @@ The following video parameters are supported here so publishers may fully declar | placement | recommended | Placement type for the impression. (see openRTB v2.5 section 5.9 for options) | 1 | integer | | | | | | | - ### AdUnit Format for Video + ```javascript var videoAdUnits = [ { @@ -147,8 +148,8 @@ var videoAdUnits = [ }] ``` - ## Example + ```javascript var adUnits = [ { @@ -199,13 +200,14 @@ var adUnits = [ ]; ``` -#### First Party Data +### First Party Data + OpenX supports FPD configured under `ortb2.user`and `ortb2.site.content` as described [here](/features/firstPartyData.html). -Ad unit specific FPD is not supported, and segment taxonomies (`segtax`) are simply passed through. If you have any -questions, please reach out to us at prebid@openx.com +Ad unit specific FPD is not supported, and segment taxonomies (`segtax`) are simply passed through. If you have any questions, please reach out to us at [prebid@openx.com] -Example: -``` +Example: + +```javascript pbjs.setConfig({ ... ortb2: { @@ -236,6 +238,7 @@ pbjs.setConfig({ ``` ### Configuration + Add the following code to enable user syncing. By default, Prebid.js version 0.34.0+ turns off user syncing through iframes. OpenX strongly recommends enabling user syncing through iframes. This functionality improves DSP user match rates and increases the OpenX bid rate and bid price. Be sure to call `pbjs.setConfig()` only once. @@ -249,6 +252,6 @@ pbjs.setConfig({ ``` ## Additional Details -[Banner Ads](https://docs.openx.com/Content/developers/containers/prebid-adapter.html) (Customer login required.) -[Video Ads](https://docs.openx.com/Content/developers/containers/prebid-video-adapter.html) (Customer login required.) +* [Banner Ads](https://docs.openx.com/Content/developers/containers/prebid-adapter.html) (Customer login required.) +* [Video Ads](https://docs.openx.com/Content/developers/containers/prebid-video-adapter.html) (Customer login required.) diff --git a/dev-docs/bidders/playwire.md b/dev-docs/bidders/playwire.md index 325e7748..a2e47aec 100644 --- a/dev-docs/bidders/playwire.md +++ b/dev-docs/bidders/playwire.md @@ -25,7 +25,7 @@ sidebarType: 1 - [Bidder Config](#bidder-config) - [First Party Data](#first-party-data) - + ### Bid Params @@ -36,12 +36,13 @@ sidebarType: 1 | `keywords` | optional | A set of key-value pairs applied to all ad slots on the page. Values can be empty. | `keywords: { topic: ['stress', 'fear'] }` | `object` | | `bidFloor` | optional | Floor of the impression opportunity. If present in the request overrides XML info. | `0.8` | `float` | - + ### Bidder Config You can allow writing in localStorage `pbjs.setBidderConfig` for the bidder `playwire` -``` + +```javascript pbjs.setBidderConfig({ bidders: ["playwire"], config: { @@ -49,9 +50,10 @@ pbjs.setBidderConfig({ } }) ``` + If it will be "true" this allow Playwire Bid Adapter to write userId in first party localStorage - + ### First Party Data diff --git a/dev-docs/bidders/redtram.md b/dev-docs/bidders/redtram.md index 211f5d06..8d18f3ec 100644 --- a/dev-docs/bidders/redtram.md +++ b/dev-docs/bidders/redtram.md @@ -29,13 +29,13 @@ sidebarType: 1 - [Bid params](#bid-params) - [Test Parameters](#test-parameters) - + ### Description Redtram header bidding adapter connects with redtram demand sources to fetch bids for display placements. Please reach out to your account manager or for more information. - + ### Bid params @@ -45,13 +45,13 @@ Redtram header bidding adapter connects with redtram demand sources to fetch bid | `placementId`| optional | The placement ID from Redtram | `'23611'` | `string` | | `bidFloor` | optional | Lowest value of expected bid price | `1.1` | `float` | - - + ### Test Parameters 300x250 banner test -``` + +```javascript var adUnits = [{ code: 'prebid-place', mediaTypes: { diff --git a/dev-docs/bidders/richaudience.md b/dev-docs/bidders/richaudience.md index ec16d027..c6181034 100644 --- a/dev-docs/bidders/richaudience.md +++ b/dev-docs/bidders/richaudience.md @@ -28,8 +28,8 @@ sidebarType: 1 | `keywords` | optional | A key-value applied only to the configured bid. This value is optional. Strings separated by semicolon. | `car=mercedes;car=audi;` | `string` | | `player` | optional | Object containing video targeting parameters. See [Video Object](#ra-video-object) for details. | `player: {init: 'open', end: 'close', skin: 'dark'}` | `object` | + - ### Video Object {: .table .table-bordered .table-striped } diff --git a/dev-docs/bidders/rubicon.md b/dev-docs/bidders/rubicon.md index 0ac9554a..9514c035 100644 --- a/dev-docs/bidders/rubicon.md +++ b/dev-docs/bidders/rubicon.md @@ -25,7 +25,7 @@ sidebarType: 1 ### Registration -For both Prebid.js and Prebid Server, the Rubicon Project adapter requires setup and approval from the Magnite team, even for existing accounts. Please reach out to your account team or globalsupport@magnite.com for more information. +For both Prebid.js and Prebid Server, the Rubicon Project adapter requires setup and approval from the Magnite team, even for existing accounts. Please reach out to your account team or [globalsupport@magnite.com] for more information. ### Bid Params @@ -42,23 +42,25 @@ For both Prebid.js and Prebid Server, the Rubicon Project adapter requires setup | `inventory` | optional | See below for details on First Party Data. In release 4.29 and earlier, this parameter allows the definition of an object defining arbitrary key-value pairs concerning the page for use in targeting. The values must be arrays of strings. | `{"rating":["5-star"], "prodtype":["tech","mobile"]}` | `object` | | `visitor` | optional | See below for details on First Party Data. In release 4.29 and earlier, this parameter allows the definition of an object defining arbitrary key-value pairs concerning the visitor for use in targeting. The values must be arrays of strings. | `{"ucat":["new"], "search":["iphone"]}` | `object` | | `keywords` | optional | See below for details on First Party Data. In release 4.29 and earlier, this can be used to influence reports for client-side display. To get video or server-side reporting, please use First Party data or the inventory/visitor parameters. | `["travel", "tourism"]` | `Array` | -| `video` | required for video | Video targeting parameters. See the [video section below](#rubicon-video). | `{"language": "en"}` | `object` | +| `video` | required for video | Video targeting parameters. See the [video section below](#mediatypesvideo). | `{"language": "en"}` | `object` | | pchain | optional | deprecated option that was an early alternative to schain | "GAM:11111-reseller1:22222" | string | | `bidonmultiformat` | optional | Beta parameter - please check with your account manager before setting this value | `boolean` | `true` | #### First Party Data In release 4.30 and later, publishers should use the `ortb2` method of setting First Party Data. The following fields are supported: -- ortb2.site.ext.data.* -- ortb2.site.keywords -- ortb2.site.content.data[] -- ortb2.user.ext.data.* -- ortb2.user.data[] + +* ortb2.site.ext.data.* +* ortb2.site.keywords +* ortb2.site.content.data[] +* ortb2.user.ext.data.* +* ortb2.user.data[] With regards to Contextual and Audience segments, the Magnite exchange supports the IAB standard taxonomies. See [the segment management user guide](https://resources.rubiconproject.com/resource/publisher-resources/segment-management-user-guide/) for more information. Example first party data that's available to all bidders and all adunits: -``` + +```javascript pbjs.setConfig({ ortb2: { site: { @@ -81,7 +83,8 @@ pbjs.setConfig({ ``` Example of first party data available only to the Rubicon Project bidder. Applies across all ad units. -``` + +```javascript pbjs.setBidderConfig({ bidders: ["rubicon"], config: { @@ -107,7 +110,8 @@ pbjs.setBidderConfig({ ``` For Prebid.js 4.29 and before, use the bidder specific AdUnit parameters noted above: -``` + +```javascript var adUnit = { ... bids: [{ @@ -137,12 +141,13 @@ Rubicon supports passing up to 50 domains in `badv` for anything hitting Prebid 4. AMP For example: -``` + +```javascript pbjs.setConfig({ ortb2: { badv: ["domain1.com", "domain2.com"] } -)}; +}); ``` #### mediaTypes.video @@ -152,7 +157,7 @@ The following video parameters are supported here so publishers may fully declar {: .table .table-bordered .table-striped } | Name | Scope | Description | Example | Type | |----------------|--------------------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|---------|-----------| -| context | required | instream or outstream |"outstream" | string | +| context | required | instream or outstream |"outstream" | string | | playerSize| required | width, height of the player in pixels | [640,360] - will be translated to w and h in bid request | array | | mimes | required | List of content MIME types supported by the player (see openRTB v2.5 for options) | ["video/mp4"]| array| | protocols | required | Supported video bid response protocol values
1: VAST 1.0
2: VAST 2.0
3: VAST 3.0
4: VAST 1.0 Wrapper
5: VAST 2.0 Wrapper
6: VAST 3.0 Wrapper
7: VAST 4.0
8: VAST 4.0 Wrapper | [2,3,5,6] | array| @@ -169,7 +174,6 @@ The following video parameters are supported here so publishers may fully declar | placement* | recommended | Placement type for the impression. (see openRTB v2.5 section 5.9 for options) | 1 | integer | | | | | | | - #### bids.params.video The following Rubicon Project-specific video parameters are supported: @@ -182,7 +186,7 @@ The following Rubicon Project-specific video parameters are supported: Here's a video example for Prebid.js 2.5 or later: -``` +```javascript var videoAdUnit = { code: 'myVideoAdUnit', mediaTypes: { @@ -216,7 +220,6 @@ We recommend discussing video demand with your Magnite account representative. Lists of values are in the [OpenRTB 2.5](https://www.iab.com/wp-content/uploads/2016/03/OpenRTB-API-Specification-Version-2-5-FINAL.pdf) documentation as referenced above. - #### Outstream Video As of Prebid.js 4.37 Magnite's Rubicon Project adapter supports outstream video in two ways: using your own renderer or using ours. See the [Prebid.org Outstream documentation](/dev-docs/show-outstream-video-ads.html) for more information on using your own renderer. @@ -227,7 +230,7 @@ The Magnite outstream renderer is a JavaScript tag that will load our outstream The renderer appearance can be configured with the following parameters, all of them optional. If any parameter is missing, the default value will be used. All options are case-sensitive and unknown options will be ignored. Additional advanced options are available by calling your Magnite account representative. -``` +```javascript pbjs.setConfig({ rubicon: { rendererConfig: { @@ -241,15 +244,15 @@ pbjs.setConfig({ }); ``` - * The Rubicon Project exchange does not make multi-format requests. If multiple mediatypes are defined, we bid on banner first, then video. Native bids will only be made if it's the only mediatype present. * Note that only the Prebid-Server-side rubicon adapter currently supports native. ### Setting up the Prebid Server Adapter -If you're a Prebid Server host company looking to enable the Rubicon server-side adapter, you'll need to contact globalsupport@magnite.com. They will provide: -- a Magnite DV+ XAPI login and password that you'll place in the PBS config -- a partner code you can use for cookie-syncing with Magnite's service +If you're a Prebid Server host company looking to enable the Rubicon server-side adapter, you'll need to contact [globalsupport@magnite.com]. They will provide: + +* a Magnite DV+ XAPI login and password that you'll place in the PBS config +* a partner code you can use for cookie-syncing with Magnite's service ### Configuration @@ -258,7 +261,8 @@ If you're a Prebid Server host company looking to enable the Rubicon server-side By default, the Rubicon Project adapter sends one request to rubiconproject.com for each AdUnit. For example, if there are 4 PBJS AdUnits defined on the page, you'll see 4 calls out to rubiconproject.com/fastlane.json. As of PBJS 1.12, the Rubicon Project adapter supports `Single Request` mode, where all AdUnit requests are made in a single call to rubiconproject.com. To turn this feature on, call `setConfig`: -``` + +```javascript pbjs.setConfig({ rubicon: {singleRequest: true} }); @@ -276,6 +280,6 @@ For Prebid, the Rubicon Project bid adapter reports the revenue type as ‘gross It’s important to note that what the Rubicon Prebid bid adapter reports is not directly related to the setting with the Rubicon Project exchange. If you are a publisher who has set your Rubicon exchange revenue type set to ‘gross’ and you'd like the Rubicon bid adapter to also report 'gross', you can change the 2.35+ default 'net' setting in Prebid.js with: -``` +```javascript pbjs.setConfig({ rubicon: {netRevenue: false} }); ``` diff --git a/dev-docs/bidders/smaato.md b/dev-docs/bidders/smaato.md index dfab0ab7..1dd1b947 100644 --- a/dev-docs/bidders/smaato.md +++ b/dev-docs/bidders/smaato.md @@ -35,19 +35,19 @@ sidebarType: 1 - [First Party Data](#first-party-data) - [Test Parameters](#test-parameters) -
+ ### Registration -The Smaato adapter requires setup and approval from the Smaato team, even for existing Smaato publishers. Please reach out to your account team or prebid@smaato.com for more information. +The Smaato adapter requires setup and approval from the Smaato team, even for existing Smaato publishers. Please reach out to your account team or [prebid@smaato.com] for more information. - + ### Note The Smaato adapter will convert bidfloors to 'USD' currency as needed. - + ### Bid Params @@ -63,7 +63,7 @@ The Smaato adapter will convert bidfloors to 'USD' currency as needed. In case of AdPods, the Smaato adapter will only read the first `imp[].skadn` entry for each AdPod, such that there should only be one `skadn` occurrence per AdPod. - + #### App Object @@ -75,7 +75,7 @@ Smaato supports using prebid within a mobile app's webview. | `ifa` | String that contains the advertising identifier of the user (e.g. idfa or aaid). | `'56700000-9cf0-22bd-b23e-46b96e40003a'` | `string` | | `geo` | Object that contains the latitude (`lat`) and longitude (`lon`) of the user. | `{ lat: 33.3, lon: -88.8 }` | `object` | - + ### Example Ad Units @@ -205,10 +205,12 @@ var adUnit = { }; ``` - + ### First Party Data + Publishers should use the `ortb2` method of setting First Party Data. The following fields are supported: + - ortb2.site.keywords - ortb2.site.content - ortb2.user.keywords @@ -248,13 +250,13 @@ pbjs.setConfig({ }); ``` - + ### Test Parameters Following example includes sample `imp` object with publisherId and adSlot which can be used to test Smaato Adapter -``` +```json "imp":[ { "id":"1C86242D-9535-47D6-9576-7B1FE87F282C", diff --git a/dev-docs/bidders/smartadserver.md b/dev-docs/bidders/smartadserver.md index 2b24156e..295ee921 100644 --- a/dev-docs/bidders/smartadserver.md +++ b/dev-docs/bidders/smartadserver.md @@ -39,7 +39,7 @@ The Smart AdServer bidder adapter requires setup and approval from the Equativ ( **Note:** The site, page and format identifiers have to all be provided or all empty. - + #### Video Object @@ -70,47 +70,48 @@ The Smart AdServer bidder adapter requires setup and approval from the Equativ ( ### Examples Without site/page/format : -``` - "imp": [{ - "id": "some-impression-id", - "banner": { - "format": [{ - "w": 600, - "h": 500 - }, { - "w": 300, - "h": 600 - }] - }, - "ext": { - "smartadserver": { - "networkId": 73 - } - } - }] + +```json + "imp": [{ + "id": "some-impression-id", + "banner": { + "format": [{ + "w": 600, + "h": 500 + }, { + "w": 300, + "h": 600 + }] + }, + "ext": { + "smartadserver": { + "networkId": 73 + } + } + }] ``` With site/page/format : -``` - "imp": [{ - "id": "some-impression-id", - "banner": { - "format": [{ - "w": 600, - "h": 500 - }, { - "w": 300, - "h": 600 - }] - }, - "ext": { - "smartadserver": { +```json + "imp": [{ + "id": "some-impression-id", + "banner": { + "format": [{ + "w": 600, + "h": 500 + }, { + "w": 300, + "h": 600 + }] + }, + "ext": { + "smartadserver": { "networkId": 73 "siteId": 1, "pageId": 2, "formatId": 3 - } - } - }] + } + } + }] ``` diff --git a/dev-docs/bidders/smartx.md b/dev-docs/bidders/smartx.md index 678ae6cd..453d58a9 100644 --- a/dev-docs/bidders/smartx.md +++ b/dev-docs/bidders/smartx.md @@ -16,6 +16,7 @@ sidebarType: 1 --- ### Registration + Please reach out to your smartclip business contact for any questions and assistance in configuration. ### Bid Params @@ -37,7 +38,7 @@ Please reach out to your smartclip business contact for any questions and assist | `max_duration` | optional | Maximum video ad duration in seconds | `60` | `integer` | | `sitekey` | optional | Sitekey provided by smartclip. | `'foo.bar.baz'` | `string` | - + #### outstream_options Object diff --git a/dev-docs/bidders/spotx.md b/dev-docs/bidders/spotx.md index a692ccb0..c9863480 100644 --- a/dev-docs/bidders/spotx.md +++ b/dev-docs/bidders/spotx.md @@ -41,8 +41,7 @@ The SpotX adapter requires setup and approval from your Magnite account manager. | `position` | optional | Number corresponding to the position of the ad. See SpotX documentation [here](https://developer.spotxchange.com/content/local/docs/sdkDocs/EASI/easi-integration.md#common-javascript-attributes) | | `integer` | | `page` | optional | The URL of the page the ad is being displayed on. Used to override the detected referrer if necessary | `'https://www.spotx.tv'` | `string` | - - + #### outstream_options Object diff --git a/dev-docs/bidders/triplelift.md b/dev-docs/bidders/triplelift.md index 109444a6..e5c1d514 100644 --- a/dev-docs/bidders/triplelift.md +++ b/dev-docs/bidders/triplelift.md @@ -30,13 +30,13 @@ sidebarType: 1 - [Banner](#banner) - [Video](#video) - [Example Configuration](#example-configuration) - - [Banner](#banner-1) + - [Banner](#banner-configuration) - [Video (Instream)](#video-instream) - [Video (Outstream)](#video-outstream) - [First Party Data](#first-party-data) - [Programmatic DMP](#triplelift-programmatic-dmp) - + ### Overview @@ -45,7 +45,7 @@ Publishers may integrate with Triplelift through our Prebid.js and/or Prebid Ser {: .alert.alert-info :} The Triplelift Prebid Server bidding adapter and user sync endpoint require setup before beginning. Please contact us at prebid@triplelift.com. - + ### Bid Params @@ -58,7 +58,6 @@ The Triplelift Prebid Server bidding adapter and user sync endpoint require setu | `inventoryCode` | required | TripleLift inventory code for this ad unit (provided to you by your partner manager) | `'pubname_top_banner'` | `string` | | `floor` | optional | Bid floor | `1.00` | `float` | - #### Video Triplelift bid params for video mediaTypes are identical, but be sure to include the appropriate video.placement value to indicate instream/outstream format. Speak with your partner manager about which value to place here based on what formats are enabled. @@ -72,13 +71,13 @@ See the [Ad Unit Reference](https://docs.prebid.org/dev-docs/adunit-reference.ht | `adUnit.mediaTypes.video.placement` | required | Instream: 1; Outstream: 3, 4, 5. | `3` | `int` | | `adUnit.mediaTypes.video.playerSize` | required | Video player dimensions or size in pixels | `[640, 480]` | `integer array` | - + ### Example Configuration -#### Banner +#### Banner Configuration -``` +```javascript var adUnits = [ { code: 'top-banner', @@ -101,7 +100,7 @@ var adUnits = [ #### Video (Instream) -``` +```javascript var videoAdUnit = { code: 'video1', mediaTypes: { @@ -123,7 +122,7 @@ var videoAdUnit = { #### Video (Outstream) -``` +```javascript var videoAdUnit = { code: 'video1', mediaTypes: { @@ -143,27 +142,29 @@ var videoAdUnit = { }; ``` - + ### First Party Data Publishers should use the `ortb2` method of setting [First Party Data](https://docs.prebid.org/features/firstPartyData.html). The following fields are supported: + - `ortb2.site.*`: Standard IAB OpenRTB 2.5 site fields - `ortb2.user.*`: Standard IAB OpenRTB 2.5 user fields AdUnit-specific data is supported using `AdUnit.ortb2Imp.ext.*` - + ### Programmatic DMP -Triplelift provides audience and contextual targeting via the integration of a Programmatic DMP tag. Please reach out to your Triplelift representative to discuss specifics of the integration. +Triplelift provides audience and contextual targeting via the integration of a Programmatic DMP tag. Please reach out to your Triplelift representative to discuss specifics of the integration. + +#### Requirements -#### Requirements: - Prebid v7.1.0 or later - In Prebid's `bidderSettings`, the `storageAllowed` parameter must be set to **true**. In Prebid v7.0 and later, `storageAllowed` defaults to false, so you will need to explicitly set this value to true. - ``` + ```javascript pbjs.bidderSettings = { triplelift: { storageAllowed: true diff --git a/dev-docs/bidders/triplelift_native.md b/dev-docs/bidders/triplelift_native.md index 4085b6e4..7a58f447 100644 --- a/dev-docs/bidders/triplelift_native.md +++ b/dev-docs/bidders/triplelift_native.md @@ -23,10 +23,10 @@ sidebarType: 1 --- {: .alert.alert-info :} -This is a Prebid Server adapter for running component native only. For the standard Prebid JS Triplelift bid adapter, see the "Triplelift" bidder. If you are interested in running component native via Prebid JS, please contact us at prebid@triplelift.com. +This is a Prebid Server adapter for running component native only. For the standard Prebid JS Triplelift bid adapter, see the "Triplelift" bidder. If you are interested in running component native via Prebid JS, please contact us at [prebid@triplelift.com]. {: .alert.alert-info :} -The Triplelift Prebid Server bidding adapter and user sync endpoint require setup before beginning. Please contact us at prebid@triplelift.com. +The Triplelift Prebid Server bidding adapter and user sync endpoint require setup before beginning. Please contact us at [prebid@triplelift.com]. ### Table of Contents @@ -34,7 +34,7 @@ The Triplelift Prebid Server bidding adapter and user sync endpoint require setu - [Bid Params](#bid-params) - [First Party Data](#first-party-data) - + ### Bid Params @@ -44,10 +44,11 @@ The Triplelift Prebid Server bidding adapter and user sync endpoint require setu | inventoryCode | required | TripleLift inventory code for this ad unit (provided to you by your partner manager) | 'code1' | string | | floor | optional | the bid floor, in usd | 1.2 | number | - + ### First Party Data Triplelift supports standard IAB OpenRTB 2.5 First Party Data fields, including: + - `site.*` - `user.*` diff --git a/dev-docs/bidders/trustx.md b/dev-docs/bidders/trustx.md index f05359fd..bf7fbbf1 100644 --- a/dev-docs/bidders/trustx.md +++ b/dev-docs/bidders/trustx.md @@ -27,7 +27,7 @@ sidebarType: 1 - [Bidder Config](#bidder-config) - [First Party Data](#first-party-data) - + ### Bid Params @@ -39,7 +39,8 @@ sidebarType: 1 | `bidFloor` | optional | Floor of the impression opportunity. If present in the request overrides XML info. | `0.8` | `float` | Parameter `keywords` must have following format: -``` + +```javascript { "site":{ "publisher1":[ @@ -61,12 +62,13 @@ Parameter `keywords` must have following format: } ``` - + ### Bidder Config You can allow writing in localStorage `pbjs.setBidderConfig` for the bidder `trustx` -``` + +```javascript pbjs.setBidderConfig({ bidders: ["trustx"], config: { @@ -74,10 +76,12 @@ pbjs.setBidderConfig({ } }) ``` + If it will be "true" this allow TheMediaGrid Bid Adapter to write userId in first party localStorage If you want to make alias on TrustX Bid Adapter, you must set `forceBidderName` in bidderConfig as `"trustx"`. -``` + +```javascript pbjs.setBidderConfig({ bidders: ["aliasName"], config: { @@ -86,7 +90,7 @@ pbjs.setBidderConfig({ }) ``` - + ### First Party Data diff --git a/dev-docs/bidders/trustxstandalone.md b/dev-docs/bidders/trustxstandalone.md index f67fa71d..f29d5091 100644 --- a/dev-docs/bidders/trustxstandalone.md +++ b/dev-docs/bidders/trustxstandalone.md @@ -21,7 +21,7 @@ sidebarType: 1 - [Bid Params](#bid-params) - [First Party Data](#first-party-data) - + ### Bid Params @@ -33,7 +33,7 @@ sidebarType: 1 | `keywords` | optional (pbjs only) | A set of key-value pairs applied to all ad slots on the page. Values can be empty. | `keywords: { topic: ['stress', 'fear'] }` | `object` | | `useNewFormat` | optional (pbjs only) | Indicates to use the new ad request format. | `true` | `boolean` | - + ### First Party Data diff --git a/dev-docs/bidders/ucfunnel.md b/dev-docs/bidders/ucfunnel.md index 3ea94149..78e9a0d3 100644 --- a/dev-docs/bidders/ucfunnel.md +++ b/dev-docs/bidders/ucfunnel.md @@ -18,14 +18,14 @@ sidebarType: 1 ### Prebid JS -#### Bid params +#### Bid params (Prebid.js) {: .table .table-bordered .table-striped } | Name | Scope | Description | Example | Type | |--------|----------|-------------------------------------------------|---------|----------| | `adid` | required | The ad unit ID retrived from ucfunnel dashboard | | `string` | -``` +```javascript var adUnits = [{ code: 'div-gpt-ad-1460505748511-01', sizes: [ @@ -43,17 +43,17 @@ var adUnits = [{ {: .alert.alert-info :} Sizes set in the `adUnit` object will also apply to the ucfunnel bid requests. - -### Examples + - - [Banner Ads](https://cdn.aralego.net/ucfad/test/ucfunnel/compliance/pbjs_banner.html) - - [Instream Video Ads](https://cdn.aralego.net/ucfad/test/ucfunnel/compliance/pbjs_video.html) - - [Native Ads](https://cdn.aralego.net/ucfad/test/ucfunnel/compliance/pbjs_native.html) +### Examples +- [Banner Ads](https://cdn.aralego.net/ucfad/test/ucfunnel/compliance/pbjs_banner.html) +- [Instream Video Ads](https://cdn.aralego.net/ucfad/test/ucfunnel/compliance/pbjs_video.html) +- [Native Ads](https://cdn.aralego.net/ucfad/test/ucfunnel/compliance/pbjs_native.html) ### Prebid server -#### Bid params +#### Bid params (Prebid Server) {: .table .table-bordered .table-striped } | Name | Scope | Description | Example | Type | diff --git a/dev-docs/conditional-ad-units.md b/dev-docs/conditional-ad-units.md index dfcfbbc7..41d7b54d 100644 --- a/dev-docs/conditional-ad-units.md +++ b/dev-docs/conditional-ad-units.md @@ -37,7 +37,7 @@ to send them requests from display or tablets. We'll start with how to set up the labels from `sizeConfig`: -{% highlight js %} +```javascript pbjs.setConfig({ sizeConfig: [{ @@ -55,12 +55,12 @@ pbjs.setConfig({ }] }); -{% endhighlight %} +``` In the above `sizeConfig`, labels are applied for each of the 3 screen sizes that can later be used in conditional ad unit logic. Now you need to label your AdUnits to match. For example: -{% highlight js %} +```javascript var AdUnits = [{ code: "ad-slot-1", @@ -85,7 +85,7 @@ var AdUnits = [{ ] }] -{% endhighlight %} +``` How this works: @@ -113,7 +113,7 @@ Assuming the same `sizeConfig` as in the first use case above, the AdUnit would placements, but the conditional `labelAny` is added to them both. This will cause the bid to be fired only if one or more of the strings in the array matches a defined label. -{% highlight js %} +```javascript var AdUnits = [{ code: "ad-slot-1", @@ -139,7 +139,7 @@ var AdUnits = [{ ] }] -{% endhighlight %} +``` How this works: @@ -153,7 +153,7 @@ How this works: Here's another way of doing the same thing as shown in the previous section: -{% highlight js %} +```javascript var AdUnits = [{ code: "ad-slot-1", @@ -185,7 +185,7 @@ var AdUnits = [{ ] }] -{% endhighlight %} +``` ## Some Ad Unit Auctions Should Be Skipped Entirely for Some Devices @@ -193,7 +193,7 @@ var AdUnits = [{ Say there's a responsive page where one of the ad units only supports larger sizes, so it doesn't make sense on phones. To suppress the ad unit for mobile users, we can apply conditional logic to the entire ad unit. Here's an example using the global sizeConfig approach (banner only): -{% highlight js %} +```javascript var AdUnits = [{ code: "ad-slot-1", @@ -221,7 +221,7 @@ var AdUnits = [{ See the [Advanced Size Mapping module](/dev-docs/modules/sizeMappingV2.html) if you need to do something like this for video. -{% endhighlight %} +``` ## Some Bid Requests Apply Only to Users Originating from Certain Countries @@ -232,17 +232,17 @@ certain region. It's really not worth sending them bid requests for users outside of their geographic area. Assuming the page can figure out where the user's from, a label can be implemented and applied to make the bid conditional. -{% highlight js %} +```javascript // page logic determines the 'europeanUser' boolean If (europeanUser) { reqArgs={labels:['eur']}; } pbjs.requestBids(reqArgs); -{% endhighlight %} +``` Then this label can be applied to conditions in the AdUnit just like labels that originate from `sizeConfig`. E.g. -{% highlight js %} +```javascript var AdUnits = [{ code: "ad-slot-1", mediaTypes: { @@ -261,7 +261,7 @@ var AdUnits = [{ ... ] }] -{% endhighlight %} +``` This example shows that the 'euroMobileBidder' is only interested in receiving bids that have **both** labels: diff --git a/dev-docs/faq.md b/dev-docs/faq.md index d5dc451d..f5dd8137 100644 --- a/dev-docs/faq.md +++ b/dev-docs/faq.md @@ -140,7 +140,7 @@ All prebid adapters that get merged should automatically detect if they're servi In other words, you shouldn't have to do anything other than make sure your own page loads Prebid.js securely, e.g., ```html - ``` (Except that you should *never never never* use the copy of Prebid.js at that URL in production, it isn't meant for production use and may break everything at any time.) diff --git a/dev-docs/integrate-with-the-prebid-analytics-api.md b/dev-docs/integrate-with-the-prebid-analytics-api.md index a433dfc4..960a5d49 100644 --- a/dev-docs/integrate-with-the-prebid-analytics-api.md +++ b/dev-docs/integrate-with-the-prebid-analytics-api.md @@ -12,19 +12,21 @@ sidebarType: 1 # How to Add a Prebid.js Analytics Adapter + {:.no_toc} The Prebid Analytics API provides a way to get analytics data from `Prebid.js` and send it to the analytics provider of your choice, such as Google Analytics. Because it's an open source API, you can write an adapter to send analytics data to any provider you like. Integrating with the Prebid Analytics API has the following benefits: -+ It decouples your analytics from the `Prebid.js` library so you can choose the analytics provider you like, based on your needs. +* It decouples your analytics from the `Prebid.js` library so you can choose the analytics provider you like, based on your needs. -+ You can selectively build the `Prebid.js` library to include only the analytics adapters for the provider(s) you want. This keeps the library small and minimizes page load time. +* You can selectively build the `Prebid.js` library to include only the analytics adapters for the provider(s) you want. This keeps the library small and minimizes page load time. -+ Since this API separates your analytics provider's code from `Prebid.js`, the upgrade and maintenance of the two systems are separate. If you want to upgrade your analytics library, there is no need to upgrade or test the core of `Prebid.js`. +* Since this API separates your analytics provider's code from `Prebid.js`, the upgrade and maintenance of the two systems are separate. If you want to upgrade your analytics library, there is no need to upgrade or test the core of `Prebid.js`. [//]: # (This comment is a separator that allows the list above and the TOC to be rendered at the same time) * TOC + {:toc } ## Architecture of the Analytics API @@ -56,7 +58,9 @@ with the [module rules](/dev-docs/module-rules.html) that apply globally and to Create a markdown file under `modules` with the name of the bidder suffixed with 'AnalyticsAdapter', e.g., `exAnalyticsAdapter.md` Example markdown file: -{% highlight text %} + +```md + # Overview Module Name: Ex Analytics Adapter @@ -67,7 +71,7 @@ Maintainer: prebid@example.com Analytics adapter for Example.com. Contact prebid@example.com for information. -{% endhighlight %} +``` ### Step 2: Add analytics source code @@ -77,8 +81,8 @@ Analytics adapter for Example.com. Contact prebid@example.com for information. 3. There are two types of analytics adapters. The example here focuses on the 'endpoint' type. See [AnalyticsAdapter.js](https://github.com/prebid/Prebid.js/blob/master/libraries/analyticsAdapter/AnalyticsAdapter.js) for more info on the 'bundle' type. - * endpoint - Calls the specified URL on analytics events. Doesn't require a global context. - * bundle - An advanced option expecting a global context. + 1. endpoint - Calls the specified URL on analytics events. Doesn't require a global context. + 2. bundle - An advanced option expecting a global context. 4. In order to get access to the configuration passed in from the page, the analytics adapter needs to specify an enableAnalytics() function, but it should also call @@ -92,7 +96,7 @@ The best way to get started is to look at some of the existing AnalyticsAdapter. Here's a skeleton outline: -{% highlight js %} +```javascript import {ajax} from '../src/ajax.js'; import adapter from '../libraries/analyticsAdapter/AnalyticsAdapter.js'; import CONSTANTS from '../src/constants.json'; @@ -121,7 +125,7 @@ adaptermanager.registerAnalyticsAdapter({ }); export default exAnalytics; -{% endhighlight %} +``` #### Reading TCF2 enforcement actions @@ -129,7 +133,7 @@ Analytics adapters can learn what happened with regards to GDPR TCF2 enforcement The callback will receive an object with the following attributes: -``` +```javascript { storageBlocked: ['moduleA', 'moduleB'], biddersBlocked: ['moduleB'], @@ -146,8 +150,8 @@ There are two error events analytics modules may wish to listen for: auctionDebu #### Analytics adapter best practices -+ listen only to the events required -+ batch up calls to the backend for post-auction logging rather than calling immediately after each event. +* listen only to the events required +* batch up calls to the backend for post-auction logging rather than calling immediately after each event. ### Step 3: Add unit tests @@ -169,7 +173,7 @@ Add a documentation file for your new analytics adapter. 3. Update the metadata fields at the top of the file to suit your needs: -``` +```markdown layout: analytics title: Your Company Name description: Your Company Analytics Adapter @@ -186,13 +190,11 @@ What does it mean to "support" the privacy protocols? At a high level, it means specifically discussed privacy policy actions and rules with your lawyers and implemented the results of that discussion. Some specific examples: -- GDPR support means: the analytics endpoint respects GDPR consent, Special Feature 1, and deals with any other Purposes declared in the vendor's Global Vendor List -- COPPA support means: analytics companies should not be building targeting profiles for users on sites flagged as COPPA -- USP/CCPA support means: analytics adapters cannot share user information if that user has opted out of sale - +1. GDPR support means: the analytics endpoint respects GDPR consent, Special Feature 1, and deals with any other Purposes declared in the vendor's Global Vendor List +2. COPPA support means: analytics companies should not be building targeting profiles for users on sites flagged as COPPA +3. USP/CCPA support means: analytics adapters cannot share user information if that user has opted out of sale 4. Update the body of the file to describe the options publishers have when configuring your adapter. See other adapters (e.g. rubicon.md) for a template. - 5. Submit the pull request to the prebid.github.io repo. ### Step 6: Wait for Prebid volunteers to review @@ -201,6 +203,6 @@ We sometimes get pretty busy, so it can take a couple of weeks for the review pr ## Further Reading -- [Analytics for Prebid](/overview/analytics.html) (Overview and list of analytics providers) -- [Module Rules](/dev-docs/module-rules.html) -- [Instream Video Ads Tracking](/dev-docs/modules/instreamTracking.html) +* [Analytics for Prebid](/overview/analytics.html) (Overview and list of analytics providers) +* [Module Rules](/dev-docs/module-rules.html) +* [Instream Video Ads Tracking](/dev-docs/modules/instreamTracking.html) diff --git a/dev-docs/modules/adpod.md b/dev-docs/modules/adpod.md index 0519cd9d..bab5d938 100644 --- a/dev-docs/modules/adpod.md +++ b/dev-docs/modules/adpod.md @@ -75,7 +75,7 @@ To enable publishers to prioritize video deals with direct buys and over deals a ### Examples: -{% highlight js %} +```javascript // This will replace the cpm with dealId in cache key as well as targeting kv pair when prioritizeDeals flag is set to true. pbjs.setConfig({ adpod: { @@ -92,10 +92,10 @@ pbjs.setConfig({ } } }) -{% endhighlight %} +``` If the bidder returns multiple bid, each bid can have a different priority/deal tier set. To give publishers control over the deal tier a `filterBids` option has been added to `pbjs.adServers.freewheel.getTargeting` to select certain deal bids. -{% highlight js %} +```javascript pbjs.adServers.freewheel.getTargeting({ codes: [adUnitCode1], @@ -103,11 +103,11 @@ pbjs.adServers.freewheel.getTargeting({ //pass targeting to player api } }); -{% endhighlight %} +``` #### Return -{% highlight js %} +```javascript // Sample return targeting key value pairs { 'adUnitCode-1': [ @@ -125,7 +125,7 @@ pbjs.adServers.freewheel.getTargeting({ } ] } -{% endhighlight %} +``` ## Further Reading diff --git a/dev-docs/modules/bidViewable.md b/dev-docs/modules/bidViewable.md index a9da963a..f5776afb 100644 --- a/dev-docs/modules/bidViewable.md +++ b/dev-docs/modules/bidViewable.md @@ -49,7 +49,7 @@ The default logic used to find a matching Prebid.js bid for a GPT slot is | `bidViewability.customMatchFunction` | Optional | function(bid, slot) | this function will be used to find the matching winning bid for the GPT slot. See above for the default. | ## Example of setting module config -{% highlight js %} +```javascript pbjs.setConfig({ bidViewability: { enabled: true, @@ -60,14 +60,14 @@ The default logic used to find a matching Prebid.js bid for a GPT slot is } } }); -{% endhighlight %} +``` ## Example of consuming BID_VIEWABLE event -{% highlight js %} +```javascript pbjs.onEvent('bidViewable', function(bid){ console.log('got bid details in bidViewable event', bid); }); -{% endhighlight %} +``` ## Related Reading diff --git a/dev-docs/modules/bidViewableIO.md b/dev-docs/modules/bidViewableIO.md index 92d79be5..d6fe0416 100644 --- a/dev-docs/modules/bidViewableIO.md +++ b/dev-docs/modules/bidViewableIO.md @@ -50,20 +50,20 @@ Note that there are other viewability modules in Prebid.js: | `bidViewabilityIO.enabled` | Required | Boolean | when set to true, the module will emit BID_VIEWABLE when applicable. Default: `false` | ## Example of setting module config -{% highlight js %} +```javascript pbjs.setConfig({ bidViewabilityIO: { enabled: true, } }); -{% endhighlight %} +``` ## Example of consuming BID_VIEWABLE event -{% highlight js %} +```javascript pbjs.onEvent('bidViewable', function(bid){ console.log('got bid details in bidViewable event', bid); }); -{% endhighlight %} +``` ## Related Reading diff --git a/dev-docs/modules/consentManagement.md b/dev-docs/modules/consentManagement.md index 963b003d..2b956730 100644 --- a/dev-docs/modules/consentManagement.md +++ b/dev-docs/modules/consentManagement.md @@ -98,7 +98,7 @@ A related parameter is `deviceAccess`, which is at the global level of Prebid.js Example 1: IAB CMP using custom timeout and setting GDPR in-scope by default. -{% highlight js %} +```javascript var pbjs = pbjs || {}; pbjs.que = pbjs.que || []; pbjs.que.push(function() { @@ -112,11 +112,11 @@ Example 1: IAB CMP using custom timeout and setting GDPR in-scope by default. } }); }); -{% endhighlight %} +``` Example 2: IAB CMP using custom timeout in combination with actionTimeout and setting GDPR in-scope by default. The following will wait `500ms` for the CMP to load, if it does an additional `10000ms` will be waited for a user to provide consent (if none had yet been provided). -{% highlight js %} +```javascript var pbjs = pbjs || {}; pbjs.que = pbjs.que || []; pbjs.que.push(function() { @@ -131,11 +131,11 @@ Example 2: IAB CMP using custom timeout in combination with actionTimeout and se } }); }); -{% endhighlight %} +``` Example 3: Static CMP using custom data passing. -{% highlight js %} +```javascript var pbjs = pbjs || {}; pbjs.que = pbjs.que || []; pbjs.que.push(function() { @@ -173,15 +173,15 @@ Example 3: Static CMP using custom data passing. } }); }); -{% endhighlight %} +``` ## Build the Package Follow the basic build instructions in the GitHub Prebid.js repo's main [README](https://github.com/prebid/Prebid.js/blob/master/README.md). To include the consent management module, an additional option must be added to the **gulp build** command: -{% highlight bash %} +```bash gulp build --modules=consentManagement,bidAdapter1,bidAdapter2 -{% endhighlight %} +``` You can also use the [Prebid.js Download](/download.html) page. @@ -196,7 +196,7 @@ If you are submitting changes to an adapter to support TCF v2.0, please also sub To find the GDPR consent information to pass along to your system, adapters should look for the `bidderRequest.gdprConsent` field in their `buildRequests()` method. Here is a sample of how the data is structured in the `bidderRequest` object: -{% highlight js %} +```javascript { "bidderCode": "bidderA", "auctionId": "e3a336ad-2222-4a1c-bbbb-ecc7c5294a34", @@ -209,7 +209,7 @@ Here is a sample of how the data is structured in the `bidderRequest` object: }, ... } -{% endhighlight %} +``` **gdprConsent Data Fields** @@ -236,7 +236,7 @@ One of two general approaches can be taken by the adapter to populate this field The following is an example of how the integration could look for the former option: -{% highlight js %} +```javascript ... buildRequests: function (bidRequests, bidderRequest) { ... @@ -250,7 +250,7 @@ buildRequests: function (bidRequests, bidderRequest) { ... } ... -{% endhighlight %} +``` The implementation of the latter option is up to the adapter, but the general premise is the same. You would check to see if the `bidderRequest.gdprConsent.gdprApplies` field is undefined and if so, set the derived value from your independent system. @@ -261,11 +261,11 @@ If neither option are taken, then there is the remote chance this field's value The `gdprConsent` object is also available when registering `userSync` pixels. The object can be accessed by including it as an argument in the `getUserSyncs` function: -{% highlight js %} +```javascript getUserSyncs: function(syncOptions, responses, gdprConsent, usPrivacy) { ... } -{% endhighlight %} +``` Depending on your needs, you could include the consent information in a query of your pixel and/or, given the consent choices, determine if you should drop the pixels at all. @@ -297,7 +297,7 @@ At a high level, this could be done as follows: Below is sample code for implementing the stub functions. Sample code for formatting the consent string can be obtained [here](https://github.com/appnexus/cmp). -{% highlight js %} +```javascript var iabConsentData; // build the IAB consent string var gdprApplies; // true if gdpr applies to the user, else false var responseCode; // false if there was an error, else true @@ -355,7 +355,7 @@ var responseCode; // false if there was an error, else true } } })(window, document); -{% endhighlight %} +``` #### Explanation of Parameters diff --git a/dev-docs/modules/consentManagementGpp.md b/dev-docs/modules/consentManagementGpp.md index c0e3be1f..d5c46f46 100644 --- a/dev-docs/modules/consentManagementGpp.md +++ b/dev-docs/modules/consentManagementGpp.md @@ -78,7 +78,7 @@ In addition to the static approach described above, there is another means to pa Example 1: IAB CMP using a custom timeout -{% highlight js %} +```javascript var pbjs = pbjs || {}; pbjs.que = pbjs.que || []; pbjs.que.push(function() { @@ -91,11 +91,11 @@ Example 1: IAB CMP using a custom timeout } }); }); -{% endhighlight %} +``` Example 2: Static CMP using custom data passing. -{% highlight js %} +```javascript var pbjs = pbjs || {}; pbjs.que = pbjs.que || []; pbjs.que.push(function() { @@ -115,15 +115,15 @@ Example 2: Static CMP using custom data passing. } }); }); -{% endhighlight %} +``` ## Build the Package Follow the basic build instructions in the GitHub Prebid.js repo's main [README](https://github.com/prebid/Prebid.js/blob/master/README.md). To include the consent management module, an additional option must be added to the **gulp build** command: -{% highlight bash %} +```bash gulp build --modules=consentManagementGpp,bidAdapter1,bidAdapter2 -{% endhighlight %} +``` You can also use the [Prebid.js Download](/download.html) page. @@ -138,7 +138,7 @@ If you are submitting changes to an adapter to support GPP, please also submit a To find the GPP consent information to pass along to your system, adapters should look for the `bidderRequest.gppConsent` field in their `buildRequests()` method; this field includes a copy of the full GPPData object from the CMP, in case additional information (beyond the gppString and applicableSections values) is needed. Alternatively if only the consent string and/or the applicableSections values are needed, these two values can also be found in the `bidderRequest.ortb2.regs` field under the OpenRTB 2.6 field names (`gpp` and `gpp_sid`). Here is a sample of how the data is structured in the `bidderRequest` object: -{% highlight js %} +```javascript { "bidderCode": "bidderA", "auctionId": "e3a336ad-2222-4a1c-bbbb-ecc7c5294a34", @@ -157,18 +157,18 @@ Here is a sample of how the data is structured in the `bidderRequest` object: }, ... } -{% endhighlight %} +``` ### UserSync Integration The `gppConsent` object is also available when registering `userSync` pixels. The object can be accessed by including it as an argument in the `getUserSyncs` function: -{% highlight js %} +```javascript getUserSyncs: function(syncOptions, responses, gdprConsent, usPrivacy, gppConsent) { ... } -{% endhighlight %} +``` Depending on your needs, you could include the consent information in a query of your pixel and/or, given the consent choices, determine if you should drop the pixels at all. diff --git a/dev-docs/modules/consentManagementUsp.md b/dev-docs/modules/consentManagementUsp.md index f42bf1cd..c9853e77 100644 --- a/dev-docs/modules/consentManagementUsp.md +++ b/dev-docs/modules/consentManagementUsp.md @@ -97,7 +97,7 @@ to the GDPR implementation, though US-Privacy doesn't specifically use that term Example 1: Support both US Privacy and GDPR -{% highlight js %} +```javascript var pbjs = pbjs || {}; pbjs.que = pbjs.que || []; pbjs.que.push(function() { @@ -114,11 +114,11 @@ Example 1: Support both US Privacy and GDPR } }); }); -{% endhighlight %} +``` Example 2: Support US Privacy; timeout the api availability at zero because it is always available if it applies -{% highlight js %} +```javascript var pbjs = pbjs || {}; pbjs.que = pbjs.que || []; pbjs.que.push(function() { @@ -131,11 +131,11 @@ Example 2: Support US Privacy; timeout the api availability at zero because it i } }); }); -{% endhighlight %} +``` Example 3: Static CMP using custom data passing. Placing this config call in the command queue before loading Prebid is important to ensure the string is available before Prebid begins making external calls. -{% highlight js %} +```javascript var pbjs = pbjs || {}; pbjs.que = pbjs.que || []; pbjs.que.push(function() { @@ -152,11 +152,11 @@ Example 3: Static CMP using custom data passing. Placing this config call in the } }); }); -{% endhighlight %} +``` Example 4: Static CMP with USP string set to does not apply for all fields, which may be useful to prevent excessive interaction with the `__uspapi` outside of the geographic scope. Placing this config call in the command queue before loading Prebid is important to ensure it is available early. -{% highlight js %} +```javascript var pbjs = pbjs || {}; pbjs.que = pbjs.que || []; pbjs.que.push(function() { @@ -173,14 +173,14 @@ Example 4: Static CMP with USP string set to does not apply for all fields, whic } }); }); -{% endhighlight %} +``` ## Build the Package Follow the basic build instructions in the GitHub Prebid.js repo's main [README](https://github.com/prebid/Prebid.js/blob/master/README.md). To include the consent management module, an additional option must be added to the the **gulp build** command: -{% highlight bash %} +```bash gulp build --modules=consentManagementUsp,bidAdapter1,bidAdapter2 -{% endhighlight %} +``` ## Adapter Integration @@ -191,7 +191,7 @@ If you are submitting changes to an adapter to support this approach, please als To find the US Privacy/CCPA notice and opt-out status information to pass along to your system, adapters should look for the `bidderRequest.uspConsent` field in their `buildRequests()` method. Below is a sample of how the data is structured in the `bidderRequest` object: -{% highlight js %} +```javascript { "bidderCode": "bidderA", "auctionId": "e3a336ad-2222-4a1c-bbbb-ecc7c5554a34", @@ -199,18 +199,18 @@ Below is a sample of how the data is structured in the `bidderRequest` object: "uspConsent": "1YYY", ... } -{% endhighlight %} +``` ### UserSync Integration The `usPrivacy` object is also available when registering `userSync` pixels. The object can be accessed by including it as an argument in the `getUserSyncs` function: -{% highlight js %} +```javascript getUserSyncs: function(syncOptions, responses, gdprConsent, usPrivacy) { ... } -{% endhighlight %} +``` Depending on your needs, you could include the US-Privacy information in a query of your pixel and/or, given the notice and opt-out status choices, determine if you should drop the pixels at all. diff --git a/dev-docs/modules/currency.md b/dev-docs/modules/currency.md index bc8dd356..9d18ac35 100644 --- a/dev-docs/modules/currency.md +++ b/dev-docs/modules/currency.md @@ -53,7 +53,7 @@ For example, the default Prebid "low granularity" bucket is: The following config translates the "low granularity" bucket with a conversion rate of 108 yen to 1 US dollar. It also defines the default conversion rate as being 110 yen to the dollar. -{% highlight js %} +```javascript pbjs.setConfig({ "priceGranularity": "low", "currency": { @@ -62,7 +62,7 @@ pbjs.setConfig({ "defaultRates": { "USD": { "JPY": 110 }} } }); -{% endhighlight %} +``` This results in a granularity rule that's scaled up to make sense in Yen: @@ -172,7 +172,7 @@ from USD to JPY is 110. Adding the currency module to a page is done with a call to the setConfig API with one or more parameters. The simplest recommended implementation would be: -{% highlight js %} +```javascript pbjs.setConfig({ "currency": { "adServerCurrency": "JPY", @@ -180,13 +180,13 @@ pbjs.setConfig({ "defaultRates": { "USD": { "JPY": 110 }} } }); -{% endhighlight %} +``` {: .alert.alert-warning :} Note that the `defaultRates` attribute is optional, but recommended in case there's an issue loading the currency file. In this example, the publisher is providing their own `conversionRateFile`: -{% highlight js %} +```javascript pbjs.setConfig({ "currency": { // enables currency feature @@ -198,10 +198,10 @@ pbjs.setConfig({ "defaultRates": { "USD": { "GPB": 0.75 }} } }); -{% endhighlight %} +``` And finally, here's an example where the conversion rate is specified right in the config, so the external file won't be loaded: -{% highlight js %} +```javascript pbjs.setConfig({ "currency": { "adServerCurrency": "JPY", @@ -209,7 +209,7 @@ pbjs.setConfig({ "rates": { "USD": { "JPY": 110.21 }} } }); -{% endhighlight %} +``` ## Building the Prebid package with Currency Support @@ -218,9 +218,9 @@ pbjs.setConfig({ Follow the basic build instructions on the Gihub repo's main README. To include the module, an additional option must be added to the the gulp build command: -{% highlight js %} +```javascript gulp build --modules=currency,exampleBidAdapter -{% endhighlight %} +``` This command will build the following files: @@ -235,7 +235,7 @@ After testing, get your javascript file(s) out to your Content Delivery Network Note that there are more dynamic ways of combining these components for publishers or integrators ready to build a more advanced infrastructure. - + ## Functions diff --git a/dev-docs/modules/debugging.md b/dev-docs/modules/debugging.md index 23538a64..35f3ea06 100644 --- a/dev-docs/modules/debugging.md +++ b/dev-docs/modules/debugging.md @@ -13,15 +13,16 @@ sidebarType : 1 This module allows to "intercept" bids and replace their contents with arbitrary data for the purposes of testing and development. -Bids intercepted in this way are never seen by bid adapters or their backend SSPs, but they are nonetheless injected into the auction as if they originated from them. +Bids intercepted in this way are never seen by bid adapters or their backend SSPs, but they are nonetheless injected into the auction as if they originated from them. {: .pb-alert .pb-alert-warning :} For convenience, `debugging` configuration is persisted to the browser's session storage, so that you may type `pbjs.setConfig({debugging: ...})` in the console and reload the page to immediately see the effects. This means that you need to remember to **deactivate debuggging (or clear session storage) when you are done**. - -### Usage example + -The following will intercept all bids for the ad unit with code "test-div", and replace them with mocks that have `cpm: 10`: +## Usage example + +The following will intercept all bids for the ad unit with code "test-div", and replace them with mocks that have `cpm: 10`: ```javascript pbjs.setConfig({ @@ -56,7 +57,8 @@ pbjs.setConfig({ Rules are evaluated on each bid in the order they are provided: the first one that has a matching `when` definition takes the bid out of the normal auction flow and replaces it according to its `then` definition. - + + ### Match rules The match rule can be provided as a function that takes the bid request as its only argument and returns `true` if the bid should be intercepted, `false` otherwise. The [example above](#example) could be written as: @@ -79,9 +81,9 @@ pbjs.setConfig({ Alternatively, the rule can be expressed as an object, and it matches if for each `key`-`value` pair: - - `bidRequest[key] === value`, or - - `value` is a function and `value(bidRequest[key])` is `true`, or - - `value` is a regular expression and it matches `bidRequest[key]`. +- `bidRequest[key] === value`, or +- `value` is a function and `value(bidRequest[key])` is `true`, or +- `value` is a regular expression and it matches `bidRequest[key]`. To illustrate, these definitions are equivalent: @@ -103,7 +105,8 @@ To illustrate, these definitions are equivalent: }; ``` - + + ### Replace rules The replace rule can be provided as a function that takes the bid request as its only argument and returns an object with the desired response properties. The [first example above](#example) could be written as: @@ -144,7 +147,8 @@ To illustrate, the following definitions are equivalent: } ``` - + + ### Rule options {: .table .table-bordered .table-striped } diff --git a/dev-docs/modules/dfp_express.md b/dev-docs/modules/dfp_express.md index 55da3c20..37183767 100644 --- a/dev-docs/modules/dfp_express.md +++ b/dev-docs/modules/dfp_express.md @@ -36,9 +36,9 @@ Definitions: ## Page integration Adding the module to a page is done by adding just one line of javascript: -{% highlight js %} +```javascript + ## pbjs + {% for page in api_pages %}
  • {{page.title}}
  • {% endfor %} - - diff --git a/dev-docs/publisher-api-reference/adServers.dfp.buildAdpodVideoUrl.md b/dev-docs/publisher-api-reference/adServers.dfp.buildAdpodVideoUrl.md index abb5491e..02adfbb2 100644 --- a/dev-docs/publisher-api-reference/adServers.dfp.buildAdpodVideoUrl.md +++ b/dev-docs/publisher-api-reference/adServers.dfp.buildAdpodVideoUrl.md @@ -1,7 +1,7 @@ --- layout: api_prebidjs title: pbjs.adServers.dfp.buildAdpodVideoUrl(options) [Alpha] -description: +description: adServers.dfp.buildAdpodVideoUrl API sidebarType: 1 --- @@ -57,4 +57,4 @@ pbjs.que.push(function(){ }); ``` -{% include alerts/alert_warning.html content="Set the `pbjs.setConfig.cache.url` to the URL that will cache the VAST XML. " %} \ No newline at end of file +{% include alerts/alert_warning.html content="Set the `pbjs.setConfig.cache.url` to the URL that will cache the VAST XML. " %} diff --git a/dev-docs/publisher-api-reference/adServers.dfp.buildVideoUrl.md b/dev-docs/publisher-api-reference/adServers.dfp.buildVideoUrl.md index bac83f2a..6c8ccae3 100644 --- a/dev-docs/publisher-api-reference/adServers.dfp.buildVideoUrl.md +++ b/dev-docs/publisher-api-reference/adServers.dfp.buildVideoUrl.md @@ -1,7 +1,7 @@ --- layout: api_prebidjs title: pbjs.adServers.dfp.buildVideoUrl(options) -description: +description: adServers.dfp.buildVideoUrl API sidebarType: 1 --- @@ -81,4 +81,4 @@ var videoUrl = pbjs.adServers.dfp.buildVideoUrl({ {: .alert.alert-warning :} -In the event of collisions, querystring values passed via `options.params` take precedence over those passed via `options.url`. \ No newline at end of file +In the event of collisions, querystring values passed via `options.params` take precedence over those passed via `options.url`. diff --git a/dev-docs/publisher-api-reference/adServers.freewheel.getTargeting.md b/dev-docs/publisher-api-reference/adServers.freewheel.getTargeting.md index d45c2e23..12b22adf 100644 --- a/dev-docs/publisher-api-reference/adServers.freewheel.getTargeting.md +++ b/dev-docs/publisher-api-reference/adServers.freewheel.getTargeting.md @@ -1,7 +1,7 @@ --- layout: api_prebidjs title: pbjs.adServers.freewheel.getTargeting(options) -description: +description: adServers.freewheel.getTargeting API sidebarType: 1 --- @@ -14,7 +14,6 @@ Use this method to get targeting key-value pairs to be sent to the ad server. + `pbjs.adServers.freewheel.getTargeting(options)`: returns key-value pair from the ad server. ```javascript - pbjs.adServers.freewheel.getTargeting({ codes: [adUnitCode1], callback: function(err, targeting) { @@ -22,6 +21,7 @@ pbjs.adServers.freewheel.getTargeting({ } }); ``` + #### Argument Reference ##### The `options` object @@ -30,4 +30,4 @@ pbjs.adServers.freewheel.getTargeting({ | Param | Scope | Type | Description | | --- | --- | --- | --- | | codes | Optional | `Array` | [`adUnitCode1`] | -| callback | Required | `Function` | Callback function to execute when targeting data is back. | \ No newline at end of file +| callback | Required | `Function` | Callback function to execute when targeting data is back. | diff --git a/dev-docs/publisher-api-reference/addAdUnits.md b/dev-docs/publisher-api-reference/addAdUnits.md index b5eefaef..4af75f02 100644 --- a/dev-docs/publisher-api-reference/addAdUnits.md +++ b/dev-docs/publisher-api-reference/addAdUnits.md @@ -8,10 +8,10 @@ sidebarType: 1 Takes one ad unit object or an array of ad unit objects and adds them to the Prebid auction. For usage examples, see [Examples](#addAdUnits-Examples) below and the [Getting Started]({{site.baseurl}}/dev-docs/getting-started.html) page. -+ [Ad Unit Properties](#addAdUnits-AdUnitProperties) -+ [Examples](#addAdUnits-Examples) +* [Ad Unit Properties](#addAdUnits-AdUnitProperties) +* [Examples](#addAdUnits-Examples) - + #### Ad Unit Properties @@ -28,13 +28,13 @@ See the table below for the list of properties on the ad unit. For example ad u | `labelAll` | optional | array | An array of string labels, used for showing responsive and conditional ads. With the `labelAll` conditional, every element of the target array must match an element of the label array in order for the condition to be true. Works with the `sizeConfig` object passed in to [pbjs.setConfig]({{site.baseurl}}/dev-docs/publisher-api-reference/setConfig.html). | | `video` | Optional | Object | Used to link an Ad Unit to the [Video Module]({{site.github.url}}/prebid-video/video-module.html). For allowed params see the [adUnit.video reference](#adUnit-video). | - + ##### Bids See the table below for the list of properties in the `bids` array of the ad unit. For example ad units, see the [Examples](#addAdUnits-Examples) below. -Note that `bids` is optional only for [Prebid Server stored impressions](/dev-docs/modules/prebidServer.html#stored-imp), and required in all other cases. +Note that `bids` is optional only for [Prebid Server stored impressions](/dev-docs/modules/prebidServer.html#stored-imp), and required in all other cases. {: .table .table-bordered .table-striped } @@ -45,7 +45,7 @@ Note that `bids` is optional only for [Prebid Server stored impressions](/dev-do | `labelAny` | optional | array | An array of string labels, used for showing responsive ads. With the `labelAny` operator, just one label has to match for the condition to be true. Works with the `sizeConfig` object passed in to [pbjs.setConfig]({{site.baseurl}}/dev-docs/publisher-api-reference/setConfig.html). | | `labelAll` | optional | array | An array of string labels, used for showing responsive and conditional ads. With the `labelAll` conditional, every element of the target array must match an element of the label array in order for the condition to be true. Works with the `sizeConfig` object passed in to [pbjs.setConfig]({{site.baseurl}}/dev-docs/publisher-api-reference/setConfig.html). | - + ##### Media Types @@ -62,24 +62,23 @@ See the table below for the list of properties in the `mediaTypes` object of the For the list of properties please visit the [adUnit.video reference]({{site.baseurl}}/dev-docs/adunit-reference.html#adUnit.video). - + #### Examples -- [Ad Unit Properties](#ad-unit-properties) - - [Bids](#bids) - - [Media Types](#media-types) -- [Video](#video) -- [Examples](#examples) - - [Native](#native) - - [Video](#video-1) - - [Banner](#banner) - - [Multi-format](#multi-format) +* [Ad Unit Properties](#ad-unit-properties) + * [Bids](#bids) + * [Media Types](#media-types) +* [Video](#video) +* [Examples](#examples) + * [Native](#mediatype-native) + * [Video](#mediatype-video) + * [Banner](#mediatype-banner) + * [Multi-format](#multi-format) + - - -##### Native +##### MediaType Native For an example of a native ad unit, see below. For more detailed instructions, see [Show Native Ads]({{site.baseurl}}/dev-docs/show-native-ads.html). @@ -124,11 +123,11 @@ pbjs.addAdUnits({ {% include dev-docs/native-image-asset-sizes.md %} - + -##### Video +##### MediaType Video -If using the Video Module, see below. For more information on the Video Module, see the [Video Module docs]({{site.github.url}}/prebid-video/video-module.html). +If using the Video Module, see below. For more information on the Video Module, see the [Video Module docs]({{site.github.url}}/prebid-video/video-module.html). ```javascript pbjs.addAdUnits({ @@ -204,9 +203,9 @@ pbjs.addAdUnit({ }) ``` - + -##### Banner +##### MediaType Banner For an example of a banner ad unit, see below. For more detailed instructions, see [Getting Started]({{site.baseurl}}/dev-docs/getting-started.html). @@ -229,7 +228,7 @@ pbjs.addAdUnits({ }) ``` - + ##### Multi-format @@ -251,10 +250,10 @@ pbjs.addAdUnits({ video: { context: 'outstream', playerSize: [640, 480], - mimes: ['video/mp4'], - protocols: [1, 2, 3, 4, 5, 6, 7, 8], - playbackmethod: [2], - skip: 1 + mimes: ['video/mp4'], + protocols: [1, 2, 3, 4, 5, 6, 7, 8], + playbackmethod: [2], + skip: 1 }, }, bids: [ diff --git a/dev-docs/publisher-api-reference/aliasBidder.md b/dev-docs/publisher-api-reference/aliasBidder.md index 1b5c6ee3..ff4886f2 100644 --- a/dev-docs/publisher-api-reference/aliasBidder.md +++ b/dev-docs/publisher-api-reference/aliasBidder.md @@ -8,11 +8,11 @@ sidebarType: 1 To define an alias for a bidder adapter, call this method at runtime: -{% highlight js %} +```javascript pbjs.aliasBidder('appnexus', 'newAlias', optionsObject ); -{% endhighlight %} +``` Defining an alias can help avoid user confusion since it's possible to send parameters to the same adapter but in different contexts (e.g, The publisher uses `"appnexus"` for demand and also uses `"newAlias"` which is an SSP partner that uses the `"appnexus"` adapter to serve their own unique demand). diff --git a/dev-docs/publisher-api-reference/aliasRegistry.md b/dev-docs/publisher-api-reference/aliasRegistry.md index f3773f55..6740d839 100644 --- a/dev-docs/publisher-api-reference/aliasRegistry.md +++ b/dev-docs/publisher-api-reference/aliasRegistry.md @@ -8,16 +8,16 @@ sidebarType: 1 Exposes the aliasRegistry. It can be used to fetch the entire aliasRegistry object or an individual adapter code by alias name. -{% highlight js %} - -pbjs.aliasRegistry; or pbjs.aliasRegistry[aliasName]; - -{% endhighlight %} +```javascript +pbjs.aliasRegistry; +// or +pbjs.aliasRegistry['aliasName']; +``` {: .alert.alert-warning :} Note that by default, the alias registry will be made public. If you would like the registry to be private, you can utilize the `setConfig` option below: -``` +```javascript pbjs.setConfig({aliasRegistry: 'private'}) ``` diff --git a/dev-docs/publisher-api-reference/bidderSettings.md b/dev-docs/publisher-api-reference/bidderSettings.md index 34b7810e..c8079ca6 100644 --- a/dev-docs/publisher-api-reference/bidderSettings.md +++ b/dev-docs/publisher-api-reference/bidderSettings.md @@ -1,7 +1,7 @@ --- layout: api_prebidjs title: pbjs.bidderSettings -description: +description: bidderSettings API sidebarType: 1 --- @@ -11,8 +11,7 @@ sidebarType: 1 The bidderSettings object provides a way to define some behaviors for the platform and specific adapters. The basic structure is a 'standard' section with defaults for all adapters, and then one or more adapter-specific sections that override behavior for that bidder: -{% highlight js %} - +```javascript pbjs.bidderSettings = { standard: { [...] @@ -24,8 +23,7 @@ pbjs.bidderSettings = { [...] }, } - -{% endhighlight %} +``` Defining bidderSettings is optional; the platform has default values for all of the options. Adapters may specify their own default settings, though this isn't common. @@ -42,7 +40,7 @@ Some sample scenarios where publishers may wish to alter the default settings: | --- | --- | --- | --- | --- | | adserverTargeting | standard or adapter-specific | all | see below | Define which key/value pairs are sent to the ad server. | | bidCpmAdjustment | standard or adapter-specific | all | n/a | Custom CPM adjustment function. Could, for example, adjust a bidder's gross-price bid to net price. | -| inverseCpmAdjustment | standard or adapter-specific | 7.33.0 | n/a | Inverse of `bidCpmAdjustment` | +| inverseCpmAdjustment | standard or adapter-specific | 7.33.0 | n/a | Inverse of `bidCpmAdjustment` | | sendStandardTargeting | adapter-specific | 0.13.0 | true | If adapter-specific targeting is specified, can be used to suppress the standard targeting for that adapter. | | suppressEmptyKeys | standard or adapter-specific | 0.13.0 | false | If custom adserverTargeting functions are specified that may generate empty keys, this can be used to suppress them. | | allowZeroCpmBids | standard or adapter-specific | 6.2.0 | false | Would allow bids with a 0 CPM to be accepted by Prebid.js and could be passed to the ad server. | @@ -72,12 +70,11 @@ The key value pair targeting is applied to the bid's corresponding ad unit. Your If you'd like to customize the key value pairs, you can overwrite the settings as the below example shows. *Note* that once you updated the settings, let your ad ops team know about the change, so they can update the line item targeting accordingly. See the [Ad Ops](/adops/before-you-start.html) documentation for more information. - + There's no need to include the following code if you choose to use the *below default setting*. -{% highlight js %} - +```javascript pbjs.bidderSettings = { standard: { adserverTargeting: [{ @@ -113,8 +110,7 @@ pbjs.bidderSettings = { }] } } - -{% endhighlight %} +``` {: .alert.alert-warning :} Note that the existence of `bidderSettings.adserverTargeting.standard` will prevent the system from adding the standard display targeting values: hb_bidder, hb_adid, hb_pb, hb_size, and hb_format. However, if the mediaType is video and `bidderSettings.adserverTargeting.standard` does not specify hb_uuid, hb_cache_id, or hb_cache_host, they will be added unless `bidderSettings.sendStandardTargeting` is set to false. @@ -127,7 +123,7 @@ settings as the below example for AppNexus shows. *Note that the line item setup has to match the targeting change* -{% highlight js %} +```javascript pbjs.bidderSettings = { appnexus: { sendStandardTargeting: false, @@ -146,8 +142,7 @@ pbjs.bidderSettings = { ] } } -{% endhighlight %} - +``` In other words, the above config sends 2 pairs of key/value strings targeting for every AppNexus bid and for every ad unit. The 1st pair would be `apn_pbMg` => the value of `bidResponse.pbMg`. The 2nd pair would be `apn_adId` => the value of `bidResponse.adId`. You can find the bidResponse object documentation [here](/troubleshooting/troubleshooting-guide.html#common-bid-response-parameters). @@ -159,8 +154,7 @@ Now let's say you would like to define a bidder-specific price bucket function r *Note: this will only impact the price bucket sent to the ad server for targeting. It won't actually impact the cpm value used for ordering the bids.* -{% highlight js %} - +```javascript pbjs.bidderSettings = { standard: { [...] @@ -181,10 +175,10 @@ pbjs.bidderSettings = { return "pb6"; // all bids $6 and above are assigned to price bucket 'pb6' } }] - [...] + // [...] } } -{% endhighlight %} +``` ##### 2.2. bidCpmAdjustment @@ -194,13 +188,12 @@ In this case, the publisher may want to adjust the bidder's returned price to ru header bidding auction. Otherwise, this bidder's gross price will unfairly win over your other demand sources who report the real price. -Custom adjustment can be provided as a function taking 3 arguments: `bidCpmAdjustment(cpm, bidResponse, bidRequest)`. -Note that either `bidResponse` or `bidRequest` may be missing, although at least one of them is guaranteed to be present. This is because Prebid will sometimes need to run adjustment when no bid has been made yet; see [inverseCpmAdjustment](#inverseCpmAdjustment) below. +Custom adjustment can be provided as a function taking 3 arguments: `bidCpmAdjustment(cpm, bidResponse, bidRequest)`. +Note that either `bidResponse` or `bidRequest` may be missing, although at least one of them is guaranteed to be present. This is because Prebid will sometimes need to run adjustment when no bid has been made yet; see [inverseCpmAdjustment](#23-inversecpmadjustment) below. For example: -{% highlight js %} - +```javascript pbjs.bidderSettings = { standard: { ... } aol: { @@ -211,20 +204,18 @@ pbjs.bidderSettings = { } } }; - -{% endhighlight %} +``` In the above example, the AOL bidder will inherit from "standard" adserverTargeting keys, so that you don't have to define the targeting keywords again. ##### 2.3. inverseCpmAdjustment -When using [price floors](/dev-docs/modules/floors.html), Prebid attempts to calculate the inverse of `bidCpmAdjustment`, so that the floor values it requests from SSPs take into account how the bid will be adjusted. +When using [price floors](/dev-docs/modules/floors.html), Prebid attempts to calculate the inverse of `bidCpmAdjustment`, so that the floor values it requests from SSPs take into account how the bid will be adjusted. For example, if the adjustment is `bidCpm * .85` as above, floors are adjusted by `bidFloor * 1 / .85`. The automatically derived inverse function is correct only when `bidCpmAdjustment` is a simple multiplication. If it isn't, the inverse should also be provided through `inverseCpmAdjustment`. For example: -{% highlight js %} - +```javascript pbjs.bidderSettings = { aol: { bidCpmAdjustment : function(cpm) { @@ -234,12 +225,8 @@ pbjs.bidderSettings = { return Math.max(0.2, (cpm / .85) + 0.2) } } -} }; - -{% endhighlight %} - - +``` ##### 2.4. sendStandardTargeting @@ -258,23 +245,24 @@ If a custom adServerTargeting function can return an empty value, this boolean f ##### 2.6. allowZeroCpmBids By default, 0 CPM bids are ignored by Prebid.js entirely. However if there's a valid business reason to allow these bids, this setting can be enabled to allow -either specific bid adapter(s) or all bid adapters the permission for these bids to be processed by Prebid.js and potentially sent to the respective ad server +either specific bid adapter(s) or all bid adapters the permission for these bids to be processed by Prebid.js and potentially sent to the respective ad server (depending on the Prebid.js auction results). ##### 2.7. storageAllowed This setting defines if the bid adapter can access browser cookies or local storage. Allowed values are: - - an array containing either `'html5'`, `'cookie'` or both to allow specific storage methods (e.g. `['cookie']` enables cookies but not local storage) - - `true` to allow any storage method; - - `false` to disable all storage. - +* an array containing either `'html5'`, `'cookie'` or both to allow specific storage methods (e.g. `['cookie']` enables cookies but not local storage) +* `true` to allow any storage method; +* `false` to disable all storage. +
    Default value is `true` in version 6.x
    Default value is `false` in version 7.x Note that: - - [Disabling device access](/dev-docs/publisher-api-reference/setConfig.html#setConfig-deviceAccess) will prevent access to storage regardless of this setting; - - `storageAllowed` will only affect bid adapters and not any other type of module (such as analytics or RTD). + +* [Disabling device access](/dev-docs/publisher-api-reference/setConfig.html#setConfig-deviceAccess) will prevent access to storage regardless of this setting; +* `storageAllowed` will only affect bid adapters and not any other type of module (such as analytics or RTD). @@ -284,12 +272,11 @@ If this flag is set to `true`, bidders that have not been explicitly requested i
    Default value is `true` in version 6.x
    Default value will be `false` from version 7.0 - ##### 2.9. allowedAlternateBidderCodes This array will work in conjunction with `allowAlternateBidderCodes`. In this array, you can specify the names of the bidder for which an adapter can accept the bid. If the value is not specified for the array or `[‘*’]` is specified, Prebid will accept bids of all the bidders for the given adapter. -{% highlight js %} +```javascript pbjs.bidderSettings = { standard: { @@ -313,7 +300,7 @@ pbjs.bidderSettings = { [...] } } -{% endhighlight %} +``` In the above example, `groupm` bid will have a bid adjustment of 80% since the `bidCpmAdjustment` function says so.
    If `appnexus` bids with another bidder code, say `appnexus2`. This bidder code will adjust the bid cpm to 95% because it will apply the `bidCpmAdjustment` function from `standard` setting, since the `bidCpmAdjustment` is missing for given bidder code I.e `appnexus2` @@ -326,7 +313,7 @@ Optionally allow alternate bidder codes originating from a specific bid adapter 2. Adapter bidCpmAdjustment function 3. The standard bidCpmAdjustment function -{% highlight js %} +```javascript pbjs.bidderSettings = { standard: { @@ -348,7 +335,7 @@ pbjs.bidderSettings = { [...] } } -{% endhighlight %} +``` In the above example, if PubMatic were to return the "groupm" bidder code then the bidCpmAdjustment function under `pubmatic` would be used instead of what is available under `standard`. diff --git a/dev-docs/publisher-api-reference/enableAnalytics.md b/dev-docs/publisher-api-reference/enableAnalytics.md index 7e6ac4fb..7ba8ac68 100644 --- a/dev-docs/publisher-api-reference/enableAnalytics.md +++ b/dev-docs/publisher-api-reference/enableAnalytics.md @@ -1,7 +1,7 @@ --- layout: api_prebidjs title: pbjs.enableAnalytics(config) -description: +description: enableAnalytics API sidebarType: 1 --- @@ -10,7 +10,7 @@ Enables sending event data to the analytics provider of your choice. For a list ### Example -``` +```javascript pbjs.enableAnalytics([{ provider: "analyticsA", options: { @@ -31,16 +31,13 @@ pbjs.enableAnalytics([{ | `includeEvents` | Optional | Array of strings | Event whitelist; if provided, only these events will be forwarded to the adapter | | `excludeEvents` | Optional | Array of strings | Event blacklist; if provided, these events will not be forwarded to the adapter | - Note each analytics adapter has its own invocation parameters. Analytics adapters that are built in the standard way should support a `option.sampling` parameter. You'll need to check with your analytics provider to confirm whether their system recommends the use of this parameter. They may have alternate methods of sampling. - ### See also -- [Prebid.js events](/dev-docs/publisher-api-reference/getEvents.html) -- [How to Add an Analytics Adapter](/dev-docs/integrate-with-the-prebid-analytics-api.html). - +* [Prebid.js events](/dev-docs/publisher-api-reference/getEvents.html) +* [How to Add an Analytics Adapter](/dev-docs/integrate-with-the-prebid-analytics-api.html).
    diff --git a/dev-docs/publisher-api-reference/getAdserverTargeting.md b/dev-docs/publisher-api-reference/getAdserverTargeting.md index d054407e..296c69a7 100644 --- a/dev-docs/publisher-api-reference/getAdserverTargeting.md +++ b/dev-docs/publisher-api-reference/getAdserverTargeting.md @@ -1,13 +1,12 @@ --- layout: api_prebidjs title: pbjs.getAdserverTargeting() -description: +description: getAdserverTargeting API sidebarType: 1 ---
    - Returns all ad server targeting for all ad units. Note that some bidder's response may not have been received if you call this function too quickly after the requests are sent. The targeting keys can be configured in [ad server targeting](/dev-docs/publisher-api-reference/bidderSettings.html). @@ -20,7 +19,7 @@ When [deals are enabled]({{site.baseurl}}/adops/deals.html), the object returned **Returned Object Example:** -{% highlight js %} +```javascript { "/9968336/header-bid-tag-0": { "hb_bidder": "rubicon", @@ -39,4 +38,4 @@ When [deals are enabled]({{site.baseurl}}/adops/deals.html), the object returned "hb_deal_appnexus": "ABC_123" } } -{% endhighlight %} +``` diff --git a/dev-docs/publisher-api-reference/getAdserverTargetingForAdUnitCode.md b/dev-docs/publisher-api-reference/getAdserverTargetingForAdUnitCode.md index 94e6056b..4d76b768 100644 --- a/dev-docs/publisher-api-reference/getAdserverTargetingForAdUnitCode.md +++ b/dev-docs/publisher-api-reference/getAdserverTargetingForAdUnitCode.md @@ -1,7 +1,7 @@ --- layout: api_prebidjs title: pbjs.getAdserverTargetingForAdUnitCode([adunitCode]) -description: +description: getAdserverTargetingForAdUnitCode API sidebarType: 1 --- @@ -21,10 +21,10 @@ This function returns the query string targeting parameters available at this mo **Returned Object Example:** -{% highlight js %} +```javascript { "hb_bidder": "rubicon", "hb_adid": "13f44b0d3c", "hb_pb": "0.50" } -{% endhighlight %} +``` diff --git a/dev-docs/publisher-api-reference/getAllPrebidWinningBids.md b/dev-docs/publisher-api-reference/getAllPrebidWinningBids.md index 8c3fac69..9d9bb092 100644 --- a/dev-docs/publisher-api-reference/getAllPrebidWinningBids.md +++ b/dev-docs/publisher-api-reference/getAllPrebidWinningBids.md @@ -1,11 +1,11 @@ --- layout: api_prebidjs title: pbjs.getAllPrebidWinningBids() -description: +description: getAllPrebidWinningBids API sidebarType: 1 --- Use this method to get all of the bids that have won their respective auctions but not rendered on the page. Useful for [troubleshooting your integration]({{site.baseurl}}/dev-docs/prebid-troubleshooting-guide.html). -+ `pbjs.getAllPrebidWinningBids()`: returns an array of bid objects that have won their respective auctions but not rendered on the page. \ No newline at end of file +* `pbjs.getAllPrebidWinningBids()`: returns an array of bid objects that have won their respective auctions but not rendered on the page. diff --git a/dev-docs/publisher-api-reference/getAllWinningBids.md b/dev-docs/publisher-api-reference/getAllWinningBids.md index b47fc716..f05f13bb 100644 --- a/dev-docs/publisher-api-reference/getAllWinningBids.md +++ b/dev-docs/publisher-api-reference/getAllWinningBids.md @@ -1,11 +1,11 @@ --- layout: api_prebidjs title: pbjs.getAllWinningBids() -description: +description: getAllWinningBids API sidebarType: 1 --- Use this method to get all of the bids that have won their respective auctions and also rendered on the page. Useful for [troubleshooting your integration]({{site.baseurl}}/dev-docs/prebid-troubleshooting-guide.html). -+ `pbjs.getAllWinningBids()`: returns an array of bid objects that have won their respective auctions and also rendered on the page. \ No newline at end of file +* `pbjs.getAllWinningBids()`: returns an array of bid objects that have won their respective auctions and also rendered on the page. diff --git a/dev-docs/publisher-api-reference/getBidResponses.md b/dev-docs/publisher-api-reference/getBidResponses.md index cab2bcf4..44ae1d92 100644 --- a/dev-docs/publisher-api-reference/getBidResponses.md +++ b/dev-docs/publisher-api-reference/getBidResponses.md @@ -1,7 +1,7 @@ --- layout: api_prebidjs title: pbjs.getBidResponses() -description: +description: getBidResponses API sidebarType: 1 --- @@ -47,14 +47,12 @@ This function returns the bid responses at the given moment. -
    - -{% highlight bash %} +```json { "/9968336/header-bid-tag-0": { "bids": [ @@ -168,7 +166,8 @@ This function returns the bid responses at the given moment. ] } } -{% endhighlight %} +``` +
    @@ -182,84 +181,83 @@ This function returns the bid responses at the given moment. -
    -{% highlight bash %} +```json { - "div-banner-outstream-native" : { - "bids" : [ - { - "pbMg" : "10.00", - "pbLg" : "5.00", - "width" : 0, - "requestTimestamp" : 1516315716062, - "creativeId" : 81589325, - "pbCg" : "", - "adUnitCode" : "div-banner-outstream-native", - "size" : "0x0", - "bidder" : "appnexus", - "pbAg" : "10.00", - "adId" : "473965c9df19d2", - "adserverTargeting" : { - "hb_native_icon" : "https://vcdn.adnxs.com/p/creative-image/d4/06/e2/33/d406e233-a5f9-44a6-a3e0-8a714bf0e980.png", - "hb_native_title" : "This is a Prebid Native Multi-Format Creative", - "hb_native_brand" : "Prebid.org", - "hb_adid" : "473965c9df19d2", - "hb_pb" : "10.00", - "hb_source" : "client", - "hb_bidder" : "appnexus", - "hb_native_image" : "https://vcdn.adnxs.com/p/creative-image/9e/26/5f/b2/9e265fb2-50c8-43f0-88ef-a5a48a9d0dcf.jpg", - "hb_size" : "0x0", - "hb_mediatype" : "native", - "hb_native_body" : "This is a Prebid Native Creative. There are many like it, but this one is mine.", - "hb_native_linkurl" : "https://prebid.org/dev-docs/show-native-ads.html" - }, - "native" : { - "icon" : { - "url" : "https://vcdn.adnxs.com/p/creative-image/d4/06/e2/33/d406e233-a5f9-44a6-a3e0-8a714bf0e980.png", - "height" : 75, - "width" : 75 - }, - "body" : "This is a Prebid Native Creative. There are many like it, but this one is mine.", - "image" : { - "url" : "https://vcdn.adnxs.com/p/creative-image/9e/26/5f/b2/9e265fb2-50c8-43f0-88ef-a5a48a9d0dcf.jpg", - "height" : 2250, - "width" : 3000 - }, - "clickUrl" : "https://prebid.org/dev-docs/show-native-ads.html", - "clickTrackers" : [ - "..." - ], - "title" : "This is a Prebid Native Multi-Format Creative", - "impressionTrackers" : [ - "..." - ], - "sponsoredBy" : "Prebid.org" - }, - "timeToRespond" : 143, - "mediaType" : "native", - "bidderCode" : "appnexus", - "source" : "client", - "auctionId" : "1338a6fb-e514-48fc-8db6-872ddf3babdb", - "responseTimestamp" : 1516315716205, - "netRevenue" : true, - "pbDg" : "10.00", - "pbHg" : "10.00", - "ttl" : 300, - "status" : "targetingSet", - "height" : 0, - "statusMessage" : "Bid available", - "cpm" : 10, - "currency" : "USD" - } - ] - } - } -{% endhighlight %} + "div-banner-outstream-native" : { + "bids" : [ + { + "pbMg" : "10.00", + "pbLg" : "5.00", + "width" : 0, + "requestTimestamp" : 1516315716062, + "creativeId" : 81589325, + "pbCg" : "", + "adUnitCode" : "div-banner-outstream-native", + "size" : "0x0", + "bidder" : "appnexus", + "pbAg" : "10.00", + "adId" : "473965c9df19d2", + "adserverTargeting" : { + "hb_native_icon" : "https://vcdn.adnxs.com/p/creative-image/d4/06/e2/33/d406e233-a5f9-44a6-a3e0-8a714bf0e980.png", + "hb_native_title" : "This is a Prebid Native Multi-Format Creative", + "hb_native_brand" : "Prebid.org", + "hb_adid" : "473965c9df19d2", + "hb_pb" : "10.00", + "hb_source" : "client", + "hb_bidder" : "appnexus", + "hb_native_image" : "https://vcdn.adnxs.com/p/creative-image/9e/26/5f/b2/9e265fb2-50c8-43f0-88ef-a5a48a9d0dcf.jpg", + "hb_size" : "0x0", + "hb_mediatype" : "native", + "hb_native_body" : "This is a Prebid Native Creative. There are many like it, but this one is mine.", + "hb_native_linkurl" : "https://prebid.org/dev-docs/show-native-ads.html" + }, + "native" : { + "icon" : { + "url" : "https://vcdn.adnxs.com/p/creative-image/d4/06/e2/33/d406e233-a5f9-44a6-a3e0-8a714bf0e980.png", + "height" : 75, + "width" : 75 + }, + "body" : "This is a Prebid Native Creative. There are many like it, but this one is mine.", + "image" : { + "url" : "https://vcdn.adnxs.com/p/creative-image/9e/26/5f/b2/9e265fb2-50c8-43f0-88ef-a5a48a9d0dcf.jpg", + "height" : 2250, + "width" : 3000 + }, + "clickUrl" : "https://prebid.org/dev-docs/show-native-ads.html", + "clickTrackers" : [ + "..." + ], + "title" : "This is a Prebid Native Multi-Format Creative", + "impressionTrackers" : [ + "..." + ], + "sponsoredBy" : "Prebid.org" + }, + "timeToRespond" : 143, + "mediaType" : "native", + "bidderCode" : "appnexus", + "source" : "client", + "auctionId" : "1338a6fb-e514-48fc-8db6-872ddf3babdb", + "responseTimestamp" : 1516315716205, + "netRevenue" : true, + "pbDg" : "10.00", + "pbHg" : "10.00", + "ttl" : 300, + "status" : "targetingSet", + "height" : 0, + "statusMessage" : "Bid available", + "cpm" : 10, + "currency" : "USD" + } + ] + } +} +```
    diff --git a/dev-docs/publisher-api-reference/getBidResponsesForAdUnitCode.md b/dev-docs/publisher-api-reference/getBidResponsesForAdUnitCode.md index 64c39ab4..1b95567d 100644 --- a/dev-docs/publisher-api-reference/getBidResponsesForAdUnitCode.md +++ b/dev-docs/publisher-api-reference/getBidResponsesForAdUnitCode.md @@ -1,12 +1,11 @@ --- layout: api_prebidjs title: pbjs.getBidResponsesForAdUnitCode(adUnitCode) -description: +description: getBidResponsesForAdUnitCode API sidebarType: 1 --- - -Returns bidResponses for the specified adUnitCode. See full documentation at [pbjs.getBidResponses()](#module_pbjs.getBidResponses). +Returns bidResponses for the specified adUnitCode. See full documentation at [pbjs.getBidResponses()](module_pbjs.getBidResponses). **Kind**: static method of `pbjs` diff --git a/dev-docs/publisher-api-reference/getConfig.md b/dev-docs/publisher-api-reference/getConfig.md index c85d4f3c..d614562e 100644 --- a/dev-docs/publisher-api-reference/getConfig.md +++ b/dev-docs/publisher-api-reference/getConfig.md @@ -1,29 +1,27 @@ --- layout: api_prebidjs title: pbjs.getConfig([string]) -description: +description: getConfig API sidebarType: 1 --- ## Overview -The `getConfig` function is used for retrieving the current configuration object or subscribing to configuration updates. When called with no parameters, the entire config object is returned. When called with a string parameter, a single configuration property matching that parameter is returned. Be careful with use of this function, as it returns a reference to the configuration instead of a clone. The readConfig function has been introduced for safer use. +The `getConfig` function is used for retrieving the current configuration object or subscribing to configuration updates. When called with no parameters, the entire config object is returned. When called with a string parameter, a single configuration property matching that parameter is returned. Be careful with use of this function, as it returns a reference to the configuration instead of a clone. The readConfig function has been introduced for safer use. -{% highlight js %} +```javascript /* Get config object */ config.getConfig() /* Get debug config */ config.getConfig('debug') -{% endhighlight %} - +``` ### Subscribe The `getConfig` function contains a `subscribe` feature that adds a callback function to a set of listeners that are invoked whenever `setConfig` is called. The `subscribed` function will be passed the `options` object that was used in the `setConfig` call. Individual topics can be subscribed to by passing a string as the first parameter and a callback function as the second. For example: -{% highlight js %} - +```javascript /* Subscribe to all configuration changes */ getConfig((config) => console.log('config set:', config)); @@ -33,7 +31,6 @@ getConfig('logging', (config) => console.log('logging set:', config)); /* Unsubscribe */ const unsubscribe = getConfig(...); unsubscribe(); // no longer listening - -{% endhighlight %} +```
    diff --git a/dev-docs/publisher-api-reference/getConsentMetadata.md b/dev-docs/publisher-api-reference/getConsentMetadata.md index c3afe053..663dac84 100644 --- a/dev-docs/publisher-api-reference/getConsentMetadata.md +++ b/dev-docs/publisher-api-reference/getConsentMetadata.md @@ -1,14 +1,13 @@ --- layout: api_prebidjs title: pbjs.getConsentMetadata() -description: +description: getConsentMetadata API sidebarType: 1 --- - The `getConsentMetadata()` function will return basic information about the status of supported (and configured!) consent content within Prebid. -``` +```javascript pbjs.getConsentMetadata() // returns e.g. { "coppa": false, @@ -23,4 +22,4 @@ pbjs.getConsentMetadata() // returns e.g. "usp": "1YYY" } } -``` \ No newline at end of file +``` diff --git a/dev-docs/publisher-api-reference/getEvents.md b/dev-docs/publisher-api-reference/getEvents.md index 399c899f..cc643102 100644 --- a/dev-docs/publisher-api-reference/getEvents.md +++ b/dev-docs/publisher-api-reference/getEvents.md @@ -1,7 +1,7 @@ --- layout: api_prebidjs title: pbjs.getEvents() -description: +description: getEvents API sidebarType: 1 --- @@ -14,10 +14,11 @@ The `getEvents` method returns a copy of all emitted events since the page loade **Returns**: `array of objects` **Returned Object Params**: -- eventType (see table below) -- args (varies for each event type) -- id (only for bidWon, set to adUnit.code) -- elapsedTime + +* eventType (see table below) +* args (varies for each event type) +* id (only for bidWon, set to adUnit.code) +* elapsedTime The available events are: @@ -47,13 +48,13 @@ The available events are: The example below shows how these events can be used. -{% highlight js %} - pbjs.getEvents().forEach(event => { - console.log("event: "+event.eventType) - }); -{% endhighlight %} - +```javascript +pbjs.getEvents().forEach(event => { + console.log("event: "+event.eventType) +}); +``` ## See Also -- [onEvent](/dev-docs/publisher-api-reference/onEvent.html) -- [offEvent](/dev-docs/publisher-api-reference/offEvent.html) + +* [onEvent](/dev-docs/publisher-api-reference/onEvent.html) +* [offEvent](/dev-docs/publisher-api-reference/offEvent.html) diff --git a/dev-docs/publisher-api-reference/getHighestCpmBids.md b/dev-docs/publisher-api-reference/getHighestCpmBids.md index ac3051d7..6794aac0 100644 --- a/dev-docs/publisher-api-reference/getHighestCpmBids.md +++ b/dev-docs/publisher-api-reference/getHighestCpmBids.md @@ -1,15 +1,15 @@ --- layout: api_prebidjs title: pbjs.getHighestCpmBids([adUnitCode]) -description: +description: getHighestCpmBids API sidebarType: 1 --- Use this method to retrieve an array of winning bids. -+ `pbjs.getHighestCpmBids()`: with no argument, returns an array of winning bid objects for each ad unit on page -+ `pbjs.getHighestCpmBids(adUnitCode)`: when passed an ad unit code, returns an array with the winning bid object for that ad unit +* `pbjs.getHighestCpmBids()`: with no argument, returns an array of winning bid objects for each ad unit on page +* `pbjs.getHighestCpmBids(adUnitCode)`: when passed an ad unit code, returns an array with the winning bid object for that ad unit {: .alert.alert-warning :} -Note that from **Prebid 3.0** onwards, `pbjs.getHighestCpmBids` will not return rendered bids. \ No newline at end of file +Note that from **Prebid 3.0** onwards, `pbjs.getHighestCpmBids` will not return rendered bids. diff --git a/dev-docs/publisher-api-reference/getHighestUnusedBidResponseForAdUnitCode.md b/dev-docs/publisher-api-reference/getHighestUnusedBidResponseForAdUnitCode.md index b6a584c7..03058d70 100644 --- a/dev-docs/publisher-api-reference/getHighestUnusedBidResponseForAdUnitCode.md +++ b/dev-docs/publisher-api-reference/getHighestUnusedBidResponseForAdUnitCode.md @@ -1,7 +1,7 @@ --- layout: api_prebidjs title: pbjs.getHighestUnusedBidResponseForAdUnitCode(adUnitCode) -description: +description: getHighestUnusedBidResponseForAdUnitCode API sidebarType: 1 --- diff --git a/dev-docs/publisher-api-reference/getNoBids.md b/dev-docs/publisher-api-reference/getNoBids.md index 399fc947..deb7ff20 100644 --- a/dev-docs/publisher-api-reference/getNoBids.md +++ b/dev-docs/publisher-api-reference/getNoBids.md @@ -1,11 +1,11 @@ --- layout: api_prebidjs title: pbjs.getNoBids() -description: +description: getNoBids API sidebarType: 1 --- Use this method to get all of the bid requests that resulted in a NO_BID. These are bid requests that were sent to a bidder but, for whatever reason, the bidder decided not to bid on. Used by debugging snippet in the [Troubleshooting Guide](/troubleshooting/troubleshooting-guide.html). -+ `pbjs.getNoBids()`: returns an array of bid request objects that were deliberately not bid on by a bidder. +* `pbjs.getNoBids()`: returns an array of bid request objects that were deliberately not bid on by a bidder. diff --git a/dev-docs/publisher-api-reference/getNoBidsForAdUnitCode.md b/dev-docs/publisher-api-reference/getNoBidsForAdUnitCode.md index c8eae807..395e46d3 100644 --- a/dev-docs/publisher-api-reference/getNoBidsForAdUnitCode.md +++ b/dev-docs/publisher-api-reference/getNoBidsForAdUnitCode.md @@ -1,7 +1,7 @@ --- layout: api_prebidjs title: pbjs.getNoBidsForAdUnitCode(adUnitCode) -description: +description: getNoBidsForAdUnitCode API sidebarType: 1 --- diff --git a/dev-docs/publisher-api-reference/getUserIds.md b/dev-docs/publisher-api-reference/getUserIds.md index 56a68932..839454f1 100644 --- a/dev-docs/publisher-api-reference/getUserIds.md +++ b/dev-docs/publisher-api-reference/getUserIds.md @@ -1,7 +1,7 @@ --- layout: api_prebidjs title: pbjs.getUserIds() -description: +description: getUserIds API sidebarType: 1 --- @@ -11,6 +11,6 @@ To use this function, include the [UserId module](/dev-docs/modules/userId.html) If you need to export the user IDs stored by Prebid User ID module, the `getUserIds()` function will return an object formatted the same as bidRequest.userId. -``` +```javascript pbjs.getUserIds() // returns object like bidRequest.userId. e.g. {"pubcid":"1111", "tdid":"2222"} -``` \ No newline at end of file +``` diff --git a/dev-docs/publisher-api-reference/getUserIdsAsEids.md b/dev-docs/publisher-api-reference/getUserIdsAsEids.md index 69e6a562..2aa58a69 100644 --- a/dev-docs/publisher-api-reference/getUserIdsAsEids.md +++ b/dev-docs/publisher-api-reference/getUserIdsAsEids.md @@ -1,7 +1,7 @@ --- layout: api_prebidjs title: pbjs.getUserIdsAsEids() -description: +description: getUserIdsAsEids API sidebarType: 1 --- @@ -11,7 +11,7 @@ To use this function, include the [UserId module](/dev-docs/modules/userId.html) If you need to export the user IDs stored by Prebid User ID module in ORTB Eids frormat, then the `getUserIdsAsEids()` function will return an array formatted as per [ORTB Eids](https://github.com/prebid/Prebid.js/blob/master/modules/userId/eids.md). -``` +```javascript pbjs.getUserIdsAsEids() // returns userIds in ORTB Eids format. e.g. [ { @@ -33,4 +33,4 @@ pbjs.getUserIdsAsEids() // returns userIds in ORTB Eids format. e.g. }] } ] -``` \ No newline at end of file +``` diff --git a/dev-docs/publisher-api-reference/getUserIdsAsync.md b/dev-docs/publisher-api-reference/getUserIdsAsync.md index 639cef4c..fb002160 100644 --- a/dev-docs/publisher-api-reference/getUserIdsAsync.md +++ b/dev-docs/publisher-api-reference/getUserIdsAsync.md @@ -1,7 +1,7 @@ --- layout: api_prebidjs title: pbjs.getUserIdsAsync() -description: +description: getUserIdsAsync API sidebarType: 1 --- @@ -10,7 +10,7 @@ To use this function, include the [UserId module](/dev-docs/modules/userId.html) `getUserIdsAsync()` returns a promise to the same value returned by [getUserIds()](/dev-docs/publisher-api-reference/getUserIds.html), but it's guaranteed to resolve only once the complete set of IDs is available: -``` +```javascript pbjs.getUserIdsAsync().then(function (userIds) { // all IDs are available here: pbjs.getUserIds() // same as the `userIds` argument diff --git a/dev-docs/publisher-api-reference/installedModules.md b/dev-docs/publisher-api-reference/installedModules.md index 465de4dc..51686a3c 100644 --- a/dev-docs/publisher-api-reference/installedModules.md +++ b/dev-docs/publisher-api-reference/installedModules.md @@ -1,14 +1,15 @@ --- layout: api_prebidjs title: pbjs.installedModules -description: +description: installedModules API sidebarType: 1 --- When a Prebid.js package is built, the list of modules compiled into it are placed in the pbjs.installedModules array. e.g. if this builds the package: -``` + +```bash gulp build --modules=a,b,c ``` diff --git a/dev-docs/publisher-api-reference/markWinningBidAsUsed.md b/dev-docs/publisher-api-reference/markWinningBidAsUsed.md index 8562bf26..45dfbdd6 100644 --- a/dev-docs/publisher-api-reference/markWinningBidAsUsed.md +++ b/dev-docs/publisher-api-reference/markWinningBidAsUsed.md @@ -1,7 +1,7 @@ --- layout: api_prebidjs title: pbjs.markWinningBidAsUsed(markBidRequest) -description: +description: markWinningBidAsUsed API sidebarType: 1 --- @@ -17,4 +17,4 @@ If you know the adId, then be specific, otherwise Prebid will retrieve the winni | Param | Type | Description | | --- | --- | --- | | adUnitCode | `string` | (Optional) The ad unit code | -| adId | `string` | (Optional) The id representing the ad we want to mark | \ No newline at end of file +| adId | `string` | (Optional) The id representing the ad we want to mark | diff --git a/dev-docs/publisher-api-reference/mergeBidderConfig.md b/dev-docs/publisher-api-reference/mergeBidderConfig.md index a99a68cf..25673d00 100644 --- a/dev-docs/publisher-api-reference/mergeBidderConfig.md +++ b/dev-docs/publisher-api-reference/mergeBidderConfig.md @@ -1,7 +1,7 @@ --- layout: api_prebidjs title: pbjs.mergeBidderConfig(options) -description: +description: mergeBidderConfig API sidebarType: 1 --- @@ -9,13 +9,13 @@ This is the same as [`setBidderConfig(options, true)`](/dev-docs/publisher-api-r The page usage is: -{% highlight js %} +```javascript pbjs.mergeBidderConfig({ bidders: ['bidderA'], config: { customArg: "customVal" } }); -{% endhighlight %} +``` Intrepration: When 'bidderA' calls `getConfig('customArg')`, it will receive the object that contains 'customArg'. If any other bidder calls `getConfig('customArg')`, it will receive nothing. diff --git a/dev-docs/publisher-api-reference/mergeConfig.md b/dev-docs/publisher-api-reference/mergeConfig.md index 968cf137..ef31eacf 100644 --- a/dev-docs/publisher-api-reference/mergeConfig.md +++ b/dev-docs/publisher-api-reference/mergeConfig.md @@ -1,7 +1,7 @@ --- layout: api_prebidjs title: pbjs.mergeConfig(options) -description: +description: mergeConfig API sidebarType: 1 --- diff --git a/dev-docs/publisher-api-reference/offEvent.md b/dev-docs/publisher-api-reference/offEvent.md index bc220b9c..603b1680 100644 --- a/dev-docs/publisher-api-reference/offEvent.md +++ b/dev-docs/publisher-api-reference/offEvent.md @@ -1,7 +1,7 @@ --- layout: api_prebidjs title: pbjs.offEvent(eventType, handler, id) -description: +description: offEvent API sidebarType: 1 --- @@ -24,34 +24,34 @@ events for a specific item in the event context. Example -{% highlight js %} - /* This handler will be called only for rightAdUnit */ - /* Uses the `pbjs.offEvent` method to remove the handler once it has been called */ - var bidWonHandler = function bidWonHandler() { - console.log('bidWonHandler: ', arguments); - pbjs.offEvent('bidWon', bidWonHandler, rightAdUnit); - }; - - var rightAdUnit="/111111/right"; - pbjs.que.push(function () { - var adUnits = [{ - code: rightAdUnit, - ... - },{ - ... - }]; - pbjs.addAdUnits(adUnits); - pbjs.requestBids({ - ... - }); - - /* Register a callback for just the rightSlot `bidWon` event */ - /* Note that defining an event that uses the 3rd parameter must come after initiating the auction */ - pbjs.onEvent('bidWon', bidWonHandler, rightAdUnit); - - ... -{% endhighlight %} +```javascript +/* This handler will be called only for rightAdUnit */ +/* Uses the `pbjs.offEvent` method to remove the handler once it has been called */ +var bidWonHandler = function bidWonHandler() { + console.log('bidWonHandler: ', arguments); + pbjs.offEvent('bidWon', bidWonHandler, rightAdUnit); +}; + +var rightAdUnit="/111111/right"; +pbjs.que.push(function () { + var adUnits = [{ + code: rightAdUnit, + // ... + },{ + // ... + }]; + pbjs.addAdUnits(adUnits); + pbjs.requestBids({ + //... + }); + + /* Register a callback for just the rightSlot `bidWon` event */ + /* Note that defining an event that uses the 3rd parameter must come after initiating the auction */ + pbjs.onEvent('bidWon', bidWonHandler, rightAdUnit); +}); +``` ## See Also -- [getEvents](/dev-docs/publisher-api-reference/getEvents.html) -- [onEvent](/dev-docs/publisher-api-reference/onEvent.html) + +* [getEvents](/dev-docs/publisher-api-reference/getEvents.html) +* [onEvent](/dev-docs/publisher-api-reference/onEvent.html) diff --git a/dev-docs/publisher-api-reference/onEvent.md b/dev-docs/publisher-api-reference/onEvent.md index 9aa5d9f4..92d26e97 100644 --- a/dev-docs/publisher-api-reference/onEvent.md +++ b/dev-docs/publisher-api-reference/onEvent.md @@ -1,7 +1,7 @@ --- layout: api_prebidjs title: pbjs.onEvent(eventType, handler, id) -description: +description: onEvent API sidebarType: 1 --- @@ -31,39 +31,42 @@ this method registers the callback for every `bidWon` event. Currently, `bidWon` is the only event that accepts the `id` parameter. Example 1: Basic event logging -``` - /* Log when ad units are added to Prebid */ - pbjs.onEvent('addAdUnits', function() { - console.log('Ad units were added to Prebid.') - console.log(pbjs.adUnits); - }); - /* Log when Prebid wins the ad server auction */ - pbjs.onEvent('bidWon', function(data) { - console.log(data.bidderCode+ ' won the ad server auction for ad unit ' +data.adUnitCode+ ' at ' +data.cpm+ ' CPM'); - }); +```javascript +/* Log when ad units are added to Prebid */ +pbjs.onEvent('addAdUnits', function() { + console.log('Ad units were added to Prebid.') + console.log(pbjs.adUnits); +}); +/* Log when Prebid wins the ad server auction */ +pbjs.onEvent('bidWon', function(data) { + console.log(data.bidderCode+ ' won the ad server auction for ad unit ' +data.adUnitCode+ ' at ' +data.cpm+ ' CPM'); +}); ``` Example 2: Dynamically modify the auction -``` - var bidderFilter = function bidderFilter(adunits) { - // pub-specific logic to optimize bidders - // e.g. "remove any that haven't bid in the last 4 refreshes" - }; - pbjs.onEvent('beforeRequestBids', bidderFilter); + +```javascript +var bidderFilter = function bidderFilter(adunits) { + // pub-specific logic to optimize bidders + // e.g. "remove any that haven't bid in the last 4 refreshes" +}; +pbjs.onEvent('beforeRequestBids', bidderFilter); ``` Example 3: Log errors and render fails to your own endpoint -``` - pbjs.onEvent('adRenderFailed', function () { - // pub-specific logic to call their own endpoint - }); - pbjs.onEvent('auctionDebug', function () { - // pub-specific logic to call their own endpoint - }); + +```javascript +pbjs.onEvent('adRenderFailed', function () { + // pub-specific logic to call their own endpoint + }); +pbjs.onEvent('auctionDebug', function () { + // pub-specific logic to call their own endpoint + }); ``` ## See Also -- [getEvents](/dev-docs/publisher-api-reference/getEvents.html) -- [offEvent](/dev-docs/publisher-api-reference/offEvent.html) + +* [getEvents](/dev-docs/publisher-api-reference/getEvents.html) +* [offEvent](/dev-docs/publisher-api-reference/offEvent.html) diff --git a/dev-docs/publisher-api-reference/readConfig.md b/dev-docs/publisher-api-reference/readConfig.md index 38caa096..8d1c53a0 100644 --- a/dev-docs/publisher-api-reference/readConfig.md +++ b/dev-docs/publisher-api-reference/readConfig.md @@ -6,14 +6,14 @@ sidebarType: 1 --- -The `readConfig` function is used for retrieving the current configuration object or subscribing to configuration updates. When called with no parameters, the entire config object is returned. When called with a string parameter, a single configuration property matching that parameter is returned. The readConfig function has been introduced for safer use of the getConfig functionality, as it returns a clone. +The `readConfig` function is used for retrieving the current configuration object or subscribing to configuration updates. When called with no parameters, the entire config object is returned. When called with a string parameter, a single configuration property matching that parameter is returned. The readConfig function has been introduced for safer use of the getConfig functionality, as it returns a clone. -{% highlight js %} +```javascript /* Get config object */ config.readConfig() /* Get debug config */ config.readConfig('debug') -{% endhighlight %} +```
    diff --git a/dev-docs/publisher-api-reference/refreshUserIds.md b/dev-docs/publisher-api-reference/refreshUserIds.md index c698413f..8e7eccb5 100644 --- a/dev-docs/publisher-api-reference/refreshUserIds.md +++ b/dev-docs/publisher-api-reference/refreshUserIds.md @@ -1,7 +1,7 @@ --- layout: api_prebidjs title: pbjs.refreshUserIds(options, callback) -description: +description: refreshUserIds API sidebarType: 1 --- @@ -18,8 +18,7 @@ The `refreshUserIds` function allows you to force either all or a subset of user | options.submoduleNames | optional | Array of strings | The userId submodule names that should be refreshed. If this option is omitted, all userId submodules are refreshed. | | callback | optional | Function | Callback that is called after refreshing user ids has completed | - -``` +```javascript pbjs.refreshUserIds(); pbjs.refreshUserIds({ submoduleNames: ['britepoolId'] }, () => console.log("Done!")); ``` diff --git a/dev-docs/publisher-api-reference/registerSignalSources.md b/dev-docs/publisher-api-reference/registerSignalSources.md index 7529cc36..aca0b73b 100644 --- a/dev-docs/publisher-api-reference/registerSignalSources.md +++ b/dev-docs/publisher-api-reference/registerSignalSources.md @@ -8,7 +8,7 @@ sidebarType: 1 {: .alert.alert-info :} To use this function, include the [UserId module](/dev-docs/modules/userId.html) in your Prebid.js build. -This function will register all configured encrypted signals as described in the [UserId module ESP configuration](/dev-docs/modules/userId.html#esp-configurations). +This function will register all configured encrypted signals as described in the [UserId module ESP configuration](/dev-docs/modules/userId.html#esp-configurations). The condition can only be called under two conditions diff --git a/dev-docs/publisher-api-reference/removeAdUnit.md b/dev-docs/publisher-api-reference/removeAdUnit.md index 54c6f209..e70baf5f 100644 --- a/dev-docs/publisher-api-reference/removeAdUnit.md +++ b/dev-docs/publisher-api-reference/removeAdUnit.md @@ -1,7 +1,7 @@ --- layout: api_prebidjs title: pbjs.removeAdUnit(adUnitCode) -description: +description: removeAdUnit API sidebarType: 1 --- @@ -10,7 +10,6 @@ Remove adUnit(s) from the pbjs configuration, If adUnit is not given then it wil **Kind**: static method of pbjs API. - {: .table .table-bordered .table-striped } | Param | Scope | Type | Description | | --- | --- | --- | --- | diff --git a/dev-docs/publisher-api-reference/renderAd.md b/dev-docs/publisher-api-reference/renderAd.md index 5d9b1d7d..8e07f516 100644 --- a/dev-docs/publisher-api-reference/renderAd.md +++ b/dev-docs/publisher-api-reference/renderAd.md @@ -1,7 +1,7 @@ --- layout: api_prebidjs title: pbjs.renderAd(doc, id, options) -description: +description: renderAd API sidebarType: 1 --- @@ -16,12 +16,12 @@ If this property is set the value of clickThrough will replace any occurrence of {: .alert.alert-info :} Note: In regards to `options.clickThrough`: + - To make use of this feature, bid adapters would be required to respond with ad tags including the ${CLICKTHROUGH} macro. - The renderAd function must be invoked with the options argument. Ex: `renderAd(doc, bidId, {clickThrough: 'https://someadserverclickurl.com'});` - Not compatible with safeframes (since the logic around rendering safeframe's does not invoke the renderAd function). - Not supported with Prebid Universal Creative at this time, only the standard pbjs.renderAd method. - {: .table .table-bordered .table-striped } | Param | Scope | Type | Description | | --- | --- | --- | --- | diff --git a/dev-docs/publisher-api-reference/requestBids.md b/dev-docs/publisher-api-reference/requestBids.md index c1e07910..94af1512 100644 --- a/dev-docs/publisher-api-reference/requestBids.md +++ b/dev-docs/publisher-api-reference/requestBids.md @@ -1,7 +1,7 @@ --- layout: api_prebidjs title: pbjs.requestBids(requestObj) -description: +description: requestBids API sidebarType: 1 --- @@ -22,26 +22,25 @@ Request bids. When `adUnits` or `adUnitCodes` are not specified, request bids fo | requestObj.adUnits | Optional | `Array of objects` | AdUnitObjects to request. Use this or `requestObj.adUnitCodes`. Default to all `adUnits` if empty. | | requestObj.timeout | Optional | `Integer` | Timeout for requesting the bids specified in milliseconds | | requestObj.bidsBackHandler | Optional | `function` | Callback to execute when all the bid responses are back or the timeout hits. Callback will be passed 3 arguments - `bids`, `timedOut`, and `auctionId` - [see below](#result) | -| requestObj.labels | Optional | `Array of strings` | Defines [labels](#labels) that may be matched on ad unit targeting conditions. | +| requestObj.labels | Optional | `Array of strings` | Defines `labels` that may be matched on ad unit targeting conditions. | | requestObj.auctionId | Optional | `String` | Defines an auction ID to be used rather than having the system generate one. This can be useful if there are multiple wrappers on a page and a single auction ID is desired to tie them together in analytics. | | requestObj.ortb2 | Optional | `Object` | Additional [first-party data](/features/firstPartyData.html) to use for this auction only | | requestObj.ttlBuffer | Optional | `Number` | TTL buffer override for this auction. See [setConfig({ttlBuffer})](/dev-docs/publisher-api-reference/setConfig.html#setConfig-ttlBuffer) | - - + **Result**: {: .table .table-bordered .table-stripped :} | Param | Type | Description | | --- | --- | --- | -| bids | Object | Bids received; see [getBidResponses](getBidResponses.html) for details | +| bids | Object | Bids received; see [getBidResponses](getBidResponses.html) for details | | timedOut | Boolean | true if any bidder timed out | | auctionId | String | the auction's ID | Example call: -``` +```javascript pbjs.requestBids({ bidsBackHandler: sendAdserverRequest, timeout: 1000, @@ -50,7 +49,8 @@ pbjs.requestBids({ ``` Example parameters sent to the bidsBackHandler: -``` + +```javascript function sendAdserverRequest(bids, timedOut, auctionId) { // bids // {"test-div":{"bids":[{"bidderCode":"bidderA", ...}]}} diff --git a/dev-docs/publisher-api-reference/setBidderConfig.md b/dev-docs/publisher-api-reference/setBidderConfig.md index e882f233..3a2cbf0a 100644 --- a/dev-docs/publisher-api-reference/setBidderConfig.md +++ b/dev-docs/publisher-api-reference/setBidderConfig.md @@ -1,7 +1,7 @@ --- layout: api_prebidjs title: pbjs.setBidderConfig(options, mergeFlag) -description: +description: setBidderConfig API sidebarType: 1 --- @@ -17,16 +17,18 @@ Note if you would like to add to existing config you can pass `true` for the opt The page usage is: -{% highlight js %} +```javascript pbjs.setBidderConfig({ bidders: ['bidderA'], config: { customArg: "customVal" } }); -{% endhighlight %} +``` + or -{% highlight js %} + +```javascript pbjs.setBidderConfig({ bidders: ['bidderB'], config: { @@ -50,11 +52,12 @@ pbjs.setBidderConfig({ } } }); -{% endhighlight %} +``` How to interpret these examples: -- When 'bidderA' calls `getConfig('customArg')`, it will receive the object that contains 'customArg'. If any other bidder calls `getConfig('customArg')`, it will receive nothing. -- When 'bidderB' calls `getConfig('ortb2')`, it will receive this override definition rather than whatever else might have been defined globally. If any other bidder calls `getConfig('ortb2')`, it will receive the globally defined objects. + +* When 'bidderA' calls `getConfig('customArg')`, it will receive the object that contains 'customArg'. If any other bidder calls `getConfig('customArg')`, it will receive nothing. +* When 'bidderB' calls `getConfig('ortb2')`, it will receive this override definition rather than whatever else might have been defined globally. If any other bidder calls `getConfig('ortb2')`, it will receive the globally defined objects. {: .alert.alert-info :} This function is also used by the `schain` feature. Refer to the [schain](/dev-docs/modules/schain.html) documentation for examples. diff --git a/dev-docs/publisher-api-reference/setConfig.md b/dev-docs/publisher-api-reference/setConfig.md index eadf9a5f..f5810265 100644 --- a/dev-docs/publisher-api-reference/setConfig.md +++ b/dev-docs/publisher-api-reference/setConfig.md @@ -1,7 +1,7 @@ --- layout: api_prebidjs title: pbjs.setConfig(options) -description: +description: setConfig API sidebarType: 1 --- @@ -14,44 +14,45 @@ See below for usage examples. Core config: -+ [Debugging](#setConfig-Debugging) -+ [Device Access](#setConfig-deviceAccess) -+ [Bidder Timeouts](#setConfig-Bidder-Timeouts) -+ [Max Requests Per Origin](#setConfig-Max-Requests-Per-Origin) -+ [Disable Ajax Timeout](#setConfig-Disable-Ajax-Timeout) -+ [Set Timeout Buffer](#setConfig-timeoutBuffer) -+ [Set TTL Buffer](#setConfig-ttlBuffer) -+ [Turn on send all bids mode](#setConfig-Send-All-Bids) -+ [Configure send bids control](#setConfig-Send-Bids-Control) -+ [Bid cache](#setConfig-Use-Bid-Cache) -+ [Set the order in which bidders are called](#setConfig-Bidder-Order) -+ [Set the page URL](#setConfig-Page-URL) -+ [Set price granularity](#setConfig-Price-Granularity) -+ [Set media type price granularity](#setConfig-MediaType-Price-Granularity) -+ [Set custom cpm rounding](#setConfig-Cpm-Rounding) -+ [Configure server-to-server header bidding](#setConfig-Server-to-Server) -+ [Configure user syncing](#setConfig-Configure-User-Syncing) -+ [Configure targeting controls](#setConfig-targetingControls) -+ [Configure responsive ad units with `sizeConfig` and `labels`](#setConfig-Configure-Responsive-Ads) -+ [COPPA](#setConfig-coppa) -+ [First Party Data](#setConfig-fpd) -+ [Video Module to integrate with Video Players](#video-module) -+ [Caching VAST XML](#setConfig-vast-cache) -+ [Site Metadata](#setConfig-site) -+ [Disable performance metrics](#setConfig-performanceMetrics) -+ [Setting alias registry to private](#setConfig-aliasRegistry) -+ [Generic Configuration](#setConfig-Generic-Configuration) -+ [Troubleshooting configuration](#setConfig-Troubleshooting-your-configuration) +* [Debugging](#setConfig-Debugging) +* [Device Access](#setConfig-deviceAccess) +* [Bidder Timeouts](#setConfig-Bidder-Timeouts) +* [Max Requests Per Origin](#setConfig-Max-Requests-Per-Origin) +* [Disable Ajax Timeout](#setConfig-Disable-Ajax-Timeout) +* [Set Timeout Buffer](#setConfig-timeoutBuffer) +* [Set TTL Buffer](#setConfig-ttlBuffer) +* [Turn on send all bids mode](#setConfig-Send-All-Bids) +* [Configure send bids control](#setConfig-Send-Bids-Control) +* [Bid cache](#setConfig-Use-Bid-Cache) +* [Set the order in which bidders are called](#setConfig-Bidder-Order) +* [Set the page URL](#setConfig-Page-URL) +* [Set price granularity](#setConfig-Price-Granularity) +* [Set media type price granularity](#setConfig-MediaType-Price-Granularity) +* [Set custom cpm rounding](#setConfig-Cpm-Rounding) +* [Configure server-to-server header bidding](#setConfig-Server-to-Server) +* [Configure user syncing](#setConfig-Configure-User-Syncing) +* [Configure targeting controls](#setConfig-targetingControls) +* [Configure responsive ad units with `sizeConfig` and `labels`](#setConfig-Configure-Responsive-Ads) +* [COPPA](#setConfig-coppa) +* [First Party Data](#setConfig-fpd) +* [Video Module to integrate with Video Players](#video-module) +* [Caching VAST XML](#setConfig-vast-cache) +* [Site Metadata](#setConfig-site) +* [Disable performance metrics](#setConfig-performanceMetrics) +* [Setting alias registry to private](#setConfig-aliasRegistry) +* [Generic Configuration](#setConfig-Generic-Configuration) +* [Troubleshooting configuration](#setConfig-Troubleshooting-your-configuration) + Module config: other options to `setConfig()` are available if the relevant module is included in the Prebid.js build. -+ [Currency module](/dev-docs/modules/currency.html) -+ [Consent Management](/dev-docs/modules/consentManagement.html#page-integration) -+ [User ID module](/dev-docs/modules/userId.html#configuration) -+ [Adpod](/dev-docs/modules/adpod.html) -+ [IAB Category Translation](/dev-docs/modules/categoryTranslation.html) +* [Currency module](/dev-docs/modules/currency.html) +* [Consent Management](/dev-docs/modules/consentManagement.html#page-integration) +* [User ID module](/dev-docs/modules/userId.html#configuration) +* [Adpod](/dev-docs/modules/adpod.html) +* [IAB Category Translation](/dev-docs/modules/categoryTranslation.html) - + #### Debugging @@ -62,34 +63,35 @@ Note that debugging can be specified for a specific page view by adding `pbjs_debug=true` to the URL's query string. e.g. /pbjs_demo.html?pbjs_debug=true See [Prebid.js troubleshooting guide](/troubleshooting/troubleshooting-guide.html) for more information. Turn on debugging permanently in the page: -{% highlight js %} + +```javascript pbjs.setConfig({ debug: true }); -{% endhighlight %} +``` {: .alert.alert-warning :} Note that turning on debugging for Prebid Server causes most server-side adapters to consider it a test request, meaning that they won't count on reports. - + #### Device Access You can prevent Prebid.js from reading or writing cookies or HTML localstorage by setting this flag: -{% highlight js %} +```javascript pbjs.setConfig({ deviceAccess: false }); -{% endhighlight %} +``` This can be useful in GDPR, CCPA, COPPA or other privacy scenarios where a publisher has determined that header bidding should not read from or write the user's device. - + #### Bidder Timeouts Set a global bidder timeout: -{% highlight js %} +```javascript pbjs.setConfig({ bidderTimeout: 3000 }); -{% endhighlight %} +``` {: .alert.alert-warning :} **Bid Timeouts and JavaScript Timers** @@ -99,57 +101,57 @@ For more information about the asynchronous event loop and `setTimeout`, see [Ho #### Max Requests Per Origin - + Since browsers have a limit of how many requests they will allow to a specific domain before they block, Prebid.js will queue auctions that would cause requests to a specific origin to exceed that limit. The limit is different for each browser. Prebid.js defaults to a max of `4` requests per origin. That value can be configured with `maxRequestsPerOrigin`. -{% highlight js %} +```javascript // most browsers allow at least 6 requests, but your results may vary for your user base. Sometimes using all // `6` requests can impact performance negatively for users with poor internet connections. pbjs.setConfig({ maxRequestsPerOrigin: 6 }); // to emulate pre 1-x behavior and have all auctions queue (no concurrent auctions), you can set it to `1`. pbjs.setConfig({ maxRequestsPerOrigin: 1 }); -{% endhighlight %} +``` #### Disable Ajax Timeout - + Prebid core adds a timeout on XMLHttpRequest request to terminate the request once auction is timedout. Since Prebid is ignoring all the bids after timeout it does not make sense to continue the request after timeout. However, you have the option to disable this by using `disableAjaxTimeout`. -{% highlight js %} +```javascript pbjs.setConfig({ disableAjaxTimeout: true }); -{% endhighlight %} +``` #### Set Timeout Buffer - + Prebid core adds a timeout buffer to extend the time that bidders have to return a bid after the auction closes. This buffer is used to offset the "time slippage" of the setTimeout behavior in browsers. Prebid.js sets the default value to 400ms. You can change this value by setting `timeoutBuffer` to the amount of time you want to use. The following example sets the buffer to 300ms. -{% highlight js %} +```javascript pbjs.setConfig({ timeoutBuffer: 300 }); -{% endhighlight %} +``` #### Set TTL Buffer - + When an adapter bids, it provides a TTL (time-to-live); the bid is considered expired and unusuable after that time has elapsed. Core subtracts from it a buffer of 1 second; that is, a bid with TTL of 30 seconds is considered expired after 29 seconds. You can adjust this buffer with: -{% highlight js %} +```javascript pbjs.setConfig({ ttlBuffer: 10 // TTL buffer in seconds }); -{% endhighlight %} +``` #### Send All Bids - + When enableSendAllBids is **true** (the default), the page will send keywords for all bidders to your ad server. The ad server can then make the decision on which bidder will win. Some ad servers, such as Google Ad Manager, can then generate reporting on historical bid prices from all bidders. @@ -166,7 +168,7 @@ Note that targeting config must be set before either `pbjs.setTargetingForGPTAsy ##### Example results where enableSendAllBids is true -{% highlight bash %} +```bash { "hb_adid_audienceNetw": "1663076dadb443d", "hb_pb_audienceNetwor": "9.00", @@ -191,7 +193,7 @@ Note that targeting config must be set before either `pbjs.setTargetingForGPTAsy "hb_size": "300x250", "hb_format": "banner" } -{% endhighlight %} +``` You can see how the number of ad server targeting variable could get large when many bidders are present. @@ -218,11 +220,11 @@ pbjs.setConfig({ }); ``` - + #### Configure Send Bids Control - + The `sendBidsControl` object passed to `pbjs.setConfig` provides the publisher with the ability to adjust the targeting behavior when [sendAllBids](#setConfig-Send-All-Bids) is enabled. @@ -243,6 +245,7 @@ pbjs.setConfig({ } }); ``` + When this property is set, the value assigned to `bidLimit` is the maximum number of bids that will be sent to the ad server. If `bidLimit` is set to 0, sendAllBids will have no maximum bid limit and *all* bids will be sent. This setting can be helpful if you know that your ad server has a finite limit to the amount of query characters it will accept and process. {: .alert.alert-info :} @@ -250,7 +253,7 @@ Note that this feature overlaps and can be used in conjunction with [targetingCo #### Use Bid Cache - + Prebid.js currently allows for [caching and reusing bids in a very narrowly defined scope](/dev-docs/faq.html#does-prebidjs-cache-bids). However, if you'd like, you can disable this feature and prevent Prebid.js from using anything but the latest bids for @@ -260,86 +263,83 @@ a given auction. This option is available in version 1.39 as true-by-default and became false-by-default as of Prebid.js 2.0. If you want to use this feature in 2.0 and later, you'll need to set the value to true. -{% highlight js %} +```javascript pbjs.setConfig({ useBidCache: true }) -{% endhighlight %} - +``` #### Bid Cache Filter Function - + When [Bid Caching](#setConfig-Use-Bid-Cache) is turned on, a custom Filter Function can be defined to gain more granular control over which "cached" bids can be used. This function will only be called for "cached" bids from previous auctions, not "current" bids from the most recent auction. The function should take a single bid object argument, and return `true` to use the cached bid, or `false` to not use the cached bid. For Example, to turn on Bid Caching, but exclude cached video bids, you could do this: -{% highlight js %} +```javascript pbjs.setConfig({ useBidCache: true, bidCacheFilterFunction: bid => bid.mediaType !== 'video' }); -{% endhighlight %} - +``` #### Bidder Order Set the order in which bidders are called: -{% highlight js %} +```javascript pbjs.setConfig({ bidderSequence: "fixed" }) /* default is "random" */ -{% endhighlight %} +``` - + #### Page URL Override the Prebid.js page referrer for some bidders. -{% highlight js %} +```javascript pbjs.setConfig({ pageUrl: "https://example.com/index.html" }) -{% endhighlight %} - +``` - + #### Price Granularity This configuration defines the price bucket granularity setting that will be used for the `hb_pb` keyword. -{% highlight js %} +```javascript pbjs.setConfig({ priceGranularity: "medium" }) -{% endhighlight %} +``` Standard values: -+ `"low"`: $0.50 increments, capped at $5 CPM -+ `"medium"`: $0.10 increments, capped at $20 CPM (the default) -+ `"high"`: $0.01 increments, capped at $20 CPM -+ `"auto"`: Applies a sliding scale to determine granularity as shown in the [Auto Granularity](#autoGranularityBucket) table below. -+ `"dense"`: Like `"auto"`, but the bid price granularity uses smaller increments, especially at lower CPMs. For details, see the [Dense Granularity](#denseGranularityBucket) table below. -+ `customConfigObject`: If you pass in a custom config object (as shown in the [Custom CPM Bucket Sizing](#customCPMObject) example below), you can have much finer control over CPM bucket sizes, precision, and caps. +* `"low"`: $0.50 increments, capped at $5 CPM +* `"medium"`: $0.10 increments, capped at $20 CPM (the default) +* `"high"`: $0.01 increments, capped at $20 CPM +* `"auto"`: Applies a sliding scale to determine granularity as shown in the [Auto Granularity](#autoGranularityBucket) table below. +* `"dense"`: Like `"auto"`, but the bid price granularity uses smaller increments, especially at lower CPMs. For details, see the [Dense Granularity](#denseGranularityBucket) table below. +* `customConfigObject`: If you pass in a custom config object (as shown in the [Custom CPM Bucket Sizing](#customCPMObject) example below), you can have much finer control over CPM bucket sizes, precision, and caps. ##### Auto Granularity {: .table .table-bordered .table-striped } -| CPM | Granularity | Example | +| CPM | Granularity | Example | |---------------------+----------------------------------+--------| -| CPM <= $5 | $0.05 increments | $1.87 floored to $1.85 | -| CPM <= $10 and > $5 | $0.10 increments | $5.09 floored to $5.00 | -| CPM <= $20 and > $10 | $0.50 increments | $14.26 floored to $14.00 | -| CPM > $20 | Caps the price bucket at $20 | $24.82 floored to $20.00 | +| CPM <= $5 | $0.05 increments | $1.87 floored to $1.85 | +| CPM <= $10 and > $5 | $0.10 increments | $5.09 floored to $5.00 | +| CPM <= $20 and > $10 | $0.50 increments | $14.26 floored to $14.00 | +| CPM > $20 | Caps the price bucket at $20 | $24.82 floored to $20.00 | ##### Dense Granularity {: .table .table-bordered .table-striped } -| CPM | Granularity | Example | +| CPM | Granularity | Example | |------------+-------------------------------+---------| -| CPM <= $3 | $0.01 increments | $1.87 floored to $1.87 | -| CPM <= $8 and >$3 | $0.05 increments | $5.09 floored to $5.05 | -| CPM <= $20 and >$8 | $0.50 increments | $14.26 floored to $14.00 | -| CPM > $20 | Caps the price bucket at $20 | $24.82 floored to $20.00 | +| CPM <= $3 | $0.01 increments | $1.87 floored to $1.87 | +| CPM <= $8 and >$3 | $0.05 increments | $5.09 floored to $5.05 | +| CPM <= $20 and >$8 | $0.50 increments | $14.26 floored to $14.00 | +| CPM > $20 | Caps the price bucket at $20 | $24.82 floored to $20.00 | @@ -372,9 +372,9 @@ pbjs.setConfig({ Here are the rules for CPM intervals: -- `max` and `increment` must be specified -- A range's minimum value is assumed to be the max value of the previous range. The first interval starts at a min value of 0. -- `precision` is optional and defaults to 2 +* `max` and `increment` must be specified +* A range's minimum value is assumed to be the max value of the previous range. The first interval starts at a min value of 0. +* `precision` is optional and defaults to 2 {% capture warning-granularity %} As of Prebid.js 3.0, the 'min' parameter is no longer supported in custom granularities. @@ -390,8 +390,7 @@ This implies that ranges should have max values that are really the min value of {% include alerts/alert_warning.html content=warning-granularity %} - - + #### Media Type Price Granularity @@ -399,10 +398,11 @@ The standard [Prebid price granularities](#setConfig-Price-Granularity) cap out granularity as described above. Another approach is to use `mediaTypePriceGranularity` config that may be set to define different price bucket structures for different types of media: -- for each of five media types: banner, video, video-instream, video-outstream, and native. -- it is recommended that defined granularities be custom. It's possible to define "standard" granularities (e.g. "medium"), but it's not possible to mix both custom and standard granularities. -{% highlight js %} +* for each of five media types: banner, video, video-instream, video-outstream, and native. +* it is recommended that defined granularities be custom. It's possible to define "standard" granularities (e.g. "medium"), but it's not possible to mix both custom and standard granularities. + +```javascript const customPriceGranularityVideo = { 'buckets': [ { 'precision': 2, 'max': 5, 'increment': 0.25 }, @@ -419,11 +419,11 @@ const customPriceGranularityBanner = { pbjs.setConfig({'mediaTypePriceGranularity': { 'video': customPriceGranularity, // used as default for instream video - 'video-outstream': customPriceGranularityBanner, + 'video-outstream': customPriceGranularityBanner, 'banner': 'customPriceGranularityBanner' } }); -{% endhighlight %} +``` Any `mediaTypePriceGranularity` setting takes precedence over `priceGranularity`. @@ -437,16 +437,17 @@ are recognized. This was driven by the recognition that outstream often shares l If the mediatype is video, the price bucketing code further looks at the context (e.g. outstream) to see if there's a price granularity override. If it doesn't find 'video-outstream' defined, it will then look for just 'video'. - + #### Custom CPM Rounding -Prebid defaults to rounding down all bids to the nearest increment, which may cause lower CPM ads to be selected. -While this can be addressed through higher [price granularity](#setConfig-Price-Granularity), Prebid also allows setting a custom rounding function. -This function will be used by Prebid to determine what increment a bid will round to. +Prebid defaults to rounding down all bids to the nearest increment, which may cause lower CPM ads to be selected. +While this can be addressed through higher [price granularity](#setConfig-Price-Granularity), Prebid also allows setting a custom rounding function. +This function will be used by Prebid to determine what increment a bid will round to.

    You can set a simple rounding function: + ```javascript // Standard rounding pbjs.setConfig({'cpmRoundingFunction': Math.round}); @@ -468,13 +469,13 @@ const roundToNearestEvenIncrement = function (number) { pbjs.setConfig({'cpmRoundingFunction': roundToNearestEvenIncrement}); ``` - + #### Server to Server See the [Prebid Server module](/dev-docs/modules/prebidServer.html). - + #### Mobile App Post-Bid @@ -482,7 +483,7 @@ To support [post-bid](/overview/what-is-post-bid.html) scenarios on mobile apps, prebidServerBidAdapter module will accept `ortb2.app` config to forward details through the server: -{% highlight js %} +```javascript pbjs.setConfig({ ortb2: { app: { @@ -491,12 +492,12 @@ pbjs.setConfig({ } } }); -{% endhighlight %} +``` {: .alert.alert-warning :} In PBJS 4.29 and earlier, don't add the `ortb2` level here -- just `app` directly. Oh, and please upgrade. 4.29 was a long time ago. - + #### Configure User Syncing @@ -505,9 +506,9 @@ This practice is called "user syncing" because the aim is to let the bidders mat There's a good reason for bidders to be doing this -- DSPs are more likely to bid on impressions where they know something about the history of the user. However, there are also good reasons why publishers may want to control the use of these practices: -- *Page performance*: Publishers may wish to move ad-related cookie work to much later in the page load after ads and content have loaded. -- *User privacy*: Some publishers may want to opt out of these practices even though it limits their users' values on the open market. -- *Security*: Publishers may want to control which bidders are trusted to inject images and JavaScript into their pages. +* *Page performance*: Publishers may wish to move ad-related cookie work to much later in the page load after ads and content have loaded. +* *User privacy*: Some publishers may want to opt out of these practices even though it limits their users' values on the open market. +* *Security*: Publishers may want to control which bidders are trusted to inject images and JavaScript into their pages. {: .alert.alert-info :} **User syncing default behavior** @@ -515,11 +516,11 @@ If you don't tweak any of the settings described in this section, the default be For more information, see the sections below. -- [User Sync Properties](#setConfig-ConfigureUserSyncing-UserSyncProperties) -- [User Sync Examples](#setConfig-ConfigureUserSyncing-UserSyncExamples) -- [How User Syncing Works](#setConfig-ConfigureUserSyncing-HowUserSyncingWorks) +* [User Sync Properties](#setConfig-ConfigureUserSyncing-UserSyncProperties) +* [User Sync Examples](#setConfig-ConfigureUserSyncing-UserSyncExamples) +* [How User Syncing Works](#setConfig-ConfigureUserSyncing-HowUserSyncingWorks) - + ##### User Sync Properties @@ -536,7 +537,7 @@ For descriptions of all the properties that control user syncs, see the table be | `enableOverride` | Boolean | Enable/disable publisher to trigger user syncs by calling `pbjs.triggerUserSyncs()`. Default: `false`. | | `aliasSyncEnabled` | Boolean | Enable/disable registered syncs for aliased adapters. Default: `false`. | - + ##### User Sync Examples @@ -544,37 +545,37 @@ For examples of configurations that will change the default behavior, see below. Push the user syncs to later in the page load: -{% highlight js %} +```javascript pbjs.setConfig({ userSync: { syncDelay: 5000 // write image pixels 5 seconds after the auction } }); -{% endhighlight %} +``` Turn off user syncing entirely: -{% highlight js %} +```javascript pbjs.setConfig({ userSync: { syncEnabled: false } }); -{% endhighlight %} +``` Delay auction to retrieve userId module IDs first: -{% highlight js %} +```javascript pbjs.setConfig({ userSync: { auctionDelay: 1000 // delay auction up to 1 second } }); -{% endhighlight %} +``` Allow iframe-based syncs (the presence of a valid `filterSettings.iframe` object automatically enables iframe type user-syncing): -{% highlight js %} +```javascript pbjs.setConfig({ userSync: { filterSettings: { @@ -585,12 +586,13 @@ pbjs.setConfig({ } } }); -{% endhighlight %} -_Note - iframe-based syncing is disabled by default. Image-based syncing is enabled by default; it can be disabled by excluding all/certain bidders via the `filterSettings` object._ +``` + +Note - iframe-based syncing is disabled by default. Image-based syncing is enabled by default; it can be disabled by excluding all/certain bidders via the `filterSettings` object._ Only certain bidders are allowed to sync and only certain types of sync pixels: -{% highlight js %} +```javascript pbjs.setConfig({ userSync: { filterSettings: { @@ -607,11 +609,11 @@ pbjs.setConfig({ syncDelay: 6000, // 6 seconds after the auction } }); -{% endhighlight %} +``` If you want to apply the same bidder inclusion/exlusion rules for both types of sync pixels, you can use the `all` object instead specifying both `image` and `iframe` objects like so: -{% highlight js %} +```javascript pbjs.setConfig({ userSync: { /* only these bidders are allowed to sync. Both iframe and image pixels are permitted. */ @@ -625,13 +627,13 @@ pbjs.setConfig({ syncDelay: 6000, // 6 seconds after the auction } }); -{% endhighlight %} +``` -_Note - the `all` field is mutually exclusive and cannot be combined with the `iframe`/`image` fields in the `userSync` config. This restriction is to promote clear logic as to how bidders will operate in regards to their `userSync` pixels. If the fields are used together, this will be considered an invalid config and Prebid will instead use the default `userSync` logic (all image pixels permitted and all iframe pixels are blocked)._ +Note - the `all` field is mutually exclusive and cannot be combined with the `iframe`/`image` fields in the `userSync` config. This restriction is to promote clear logic as to how bidders will operate in regards to their userSync` pixels. If the fields are used together, this will be considered an invalid config and Prebid will instead use the default `userSync` logic (all image pixels permitted and all iframe pixels are blocked)._ The same bidders can drop sync pixels, but the timing will be controlled by the page: -{% highlight js %} +```javascript pbjs.setConfig({ userSync: { /* only these bidders are allowed to sync, and only image pixels */ @@ -644,15 +646,15 @@ pbjs.setConfig({ enableOverride: true // publisher will call `pbjs.triggerUserSyncs()` } }); -{% endhighlight %} +``` As noted, there's a function available to give the page control of when registered user syncs are added. -{% highlight js %} +```javascript pbjs.triggerUserSyncs(); -{% endhighlight %} +``` - + ##### How User Syncing Works @@ -664,7 +666,7 @@ The [userSync.registerSync()]({{site.baseurl}}/dev-docs/bidder-adaptor.html#bidd When user syncs are run, regardless of whether they are invoked by the platform or by the page calling pbjs.triggerUserSyncs(), the queue entries are randomized and appended to the bottom of the HTML tag. - + #### Configure Targeting Controls @@ -722,7 +724,7 @@ Between these two values (Prebid's targeting key count and the overall ad URL qu Between this feature and the overlapping [sendBidsControl.bidLimit](/dev-docs/publisher-api-reference/setConfig.html#setConfig-Send-Bids-Control), you should be able to make sure that there's not too much data going to the ad server. - + ##### Details on the allowTargetingKeys setting @@ -731,6 +733,7 @@ The `allowTargetingKeys` config creates a targeting key mask based on the defaul Prebid.js introduced the concept of optional targeting keys with 4.23. CONSTANTS.DEFAULT_TARGETING_KEYS is defined as a subset of CONSTANTS.TARGETING_KEYS. When a publisher defines targetingControls.allowTargetingKeys, this replaces the constant CONSTANTS.DEFAULT_TARGETING_KEYS and can include optional keys defined in CONSTANTS.TARGETING_KEYS. One example of this would be to make `hb_adomain` part of the default set. To accomplish this, Prebid does the following: + * Collect original targeting generated by the auction. * Generate new targeting filtered against allowed keys. * Custom targeting keys are always added to targeting. @@ -783,6 +786,7 @@ config.setConfig({ } }); ``` + Another example config showing the addition of `hb_adomain` and excluding all default targeting keys except `hb_bidder`, `hb_adid`, `hb_size` and `hb_pb`: ```javascript @@ -793,11 +797,11 @@ config.setConfig({ }); ``` - + ##### Details on the addTargetingKeys setting -The `addTargetingKeys` config is similar to `allowTargetingKeys`, except it adds to the keys in CONSTANTS.DEFAULT_TARGETING_KEYS instead of replacing them. This is useful if you need Prebid.js to generate targeting for some keys that are not allowed by default without removing any of the default ones (see [allowTargetingKeys](#targetingControls-allowTargetingKeys) for details on how targeting is generated). +The `addTargetingKeys` config is similar to `allowTargetingKeys`, except it adds to the keys in CONSTANTS.DEFAULT_TARGETING_KEYS instead of replacing them. This is useful if you need Prebid.js to generate targeting for some keys that are not allowed by default without removing any of the default ones (see [allowTargetingKeys](#targetingControls-allowTargetingKeys) for details on how targeting is generated). Note that you may specify only one of `allowTargetingKeys` or `addTargetingKeys`. @@ -851,7 +855,6 @@ config.setConfig({ }); ``` - ##### Details on the allowSendAllBidsTargetingKeys setting The `allowSendAllBidsTargetingKeys` is similar to `allowTargetingKeys` except it limits any default bidder specific keys sent to the adserver when sendAllBids is enabled. Any default bidder specific keys that do not match the mask will not be sent to the adserver. This setting can be helpful if you find that your default Prebid.js implementation is sending key values that your adserver isn't configured to process; extraneous key values may lead to the ad server request being truncated, which can cause potential issues with the delivery or rendering ads. An example of an extraneous key value many publishers may find redundant and want to remove is `hb_bidder_biddercode = biddercode`. @@ -866,8 +869,7 @@ config.setConfig({ }); ``` - - + #### Configure Responsive Ads @@ -889,19 +891,19 @@ If, on the other hand, you're only working with the banner mediaType and the AdU {% endcapture %} {% include alerts/alert_tip.html content=tip-choosing %} -+ [How it works](#sizeConfig-How-it-Works) -+ [Example](#sizeConfig-Example) -+ [Labels](#labels) +* [How it works](#sizeConfig-How-it-Works) +* [Example](#sizeConfig-Example) +* [Labels](#labels) - + ##### How Size Config Works for Banners -- Before `requestBids` sends bid requests to adapters, it will evaluate and pick the appropriate label(s) based on the `sizeConfig.mediaQuery` and device properties. Once it determines the active label(s), it will then filter the `adUnit.bids` array based on the `labels` defined and whether the `banner` mediaType was included. Ad units that include a `banner` mediaType that don't match the label definition are dropped. -- The required `sizeConfig.mediaQuery` property allows [CSS media queries](https://developer.mozilla.org/en-US/docs/Web/CSS/Media_Queries/Using_media_queries). The queries are tested using the [`window.matchMedia`](https://developer.mozilla.org/en-US/docs/Web/API/Window/matchMedia) API. -- If a label conditional (e.g. `labelAny`) doesn't exist on an ad unit, it is automatically included in all requests for bids. -- If multiple rules match, the sizes will be filtered to the intersection of all matching rules' `sizeConfig.sizesSupported` arrays. -- The `adUnit.mediaTypes.banner.sizes` selected will be filtered based on the `sizesSupported` of the matched `sizeConfig`. So the `adUnit.mediaTypes.banner.sizes` is a subset of the sizes defined from the resulting intersection of `sizesSupported` sizes and `adUnit.mediaTypes.banner.sizes`. (Note: size config will also operate on `adUnit.sizes`, however `adUnit.sizes` is deprecated in favor of `adUnit.mediaTypes`) +* Before `requestBids` sends bid requests to adapters, it will evaluate and pick the appropriate label(s) based on the `sizeConfig.mediaQuery` and device properties. Once it determines the active label(s), it will then filter the `adUnit.bids` array based on the `labels` defined and whether the `banner` mediaType was included. Ad units that include a `banner` mediaType that don't match the label definition are dropped. +* The required `sizeConfig.mediaQuery` property allows [CSS media queries](https://developer.mozilla.org/en-US/docs/Web/CSS/Media_Queries/Using_media_queries). The queries are tested using the [`window.matchMedia`](https://developer.mozilla.org/en-US/docs/Web/API/Window/matchMedia) API. +* If a label conditional (e.g. `labelAny`) doesn't exist on an ad unit, it is automatically included in all requests for bids. +* If multiple rules match, the sizes will be filtered to the intersection of all matching rules' `sizeConfig.sizesSupported` arrays. +* The `adUnit.mediaTypes.banner.sizes` selected will be filtered based on the `sizesSupported` of the matched `sizeConfig`. So the `adUnit.mediaTypes.banner.sizes` is a subset of the sizes defined from the resulting intersection of `sizesSupported` sizes and `adUnit.mediaTypes.banner.sizes`. (Note: size config will also operate on `adUnit.sizes`, however `adUnit.sizes` is deprecated in favor of `adUnit.mediaTypes`) ###### Note on sizeConfig and different mediaTypes @@ -911,13 +913,13 @@ For example, if a request contained the `banner` and `video` `mediaTypes` and i If the ad unit does not include `banner` `mediaType` at all, then the sizeConfig logic will not influence that ad Unit; it will automatically be passed into the auction. - + -##### Example +##### Size Config Example To set size configuration rules, pass in `sizeConfig` as follows: -{% highlight js %} +```javascript pbjs.setConfig({ sizeConfig: [{ @@ -954,7 +956,7 @@ pbjs.setConfig({ }] }); -{% endhighlight %} +``` ##### Labels @@ -968,22 +970,24 @@ Labels may be defined in two ways: 1. Through [`sizeConfig`](#setConfig-Configure-Responsive-Ads) 2. As an argument to [`pbjs.requestBids`](/dev-docs/publisher-api-reference/requestBids.html) -{% highlight js %} +```javascript pbjs.requestBids({labels: []}); -{% endhighlight %} +``` Labels may be targeted in the AdUnit structure by two conditional operators: `labelAny` and `labelAll`. With the `labelAny` operator, just one label has to match for the condition to be true. In the example below, either A or B can be defined in the label array to activate the bid or ad unit: -{% highlight bash %} + +```javascript labelAny: ["A", "B"] -{% endhighlight %} +``` With the `labelAll` conditional, every element of the target array must match an element of the label array in order for the condition to be true. In the example below, both A and B must be defined in the label array to activate the bid or ad unit: -{% highlight bash %} + +```javascript labelAll: ["A", "B"] -{% endhighlight %} +``` {: .alert.alert-warning :} Only one conditional may be specified on a given AdUnit or bid -- if both `labelAny` and `labelAll` are specified, only the first one will be utilized and an error will be logged to the console. It is allowable for an AdUnit to have one condition and a bid to have another. @@ -996,8 +1000,7 @@ It is important to note that labels do not act as filters for sizeConfig. In the Label targeting on the ad unit looks like the following: -{% highlight js %} - +```javascript pbjs.addAdUnits([{ code: "ad-slot-1", mediaTypes: { @@ -1048,12 +1051,11 @@ pbjs.addAdUnits([{ ] }]); -{% endhighlight %} +``` See [Conditional Ad Units]({{site.baseurl}}/dev-docs/conditional-ad-units.html) for additional use cases around labels. - - + #### COPPA @@ -1061,11 +1063,11 @@ Bidder adapters that support the Child Online Privacy Protection Act (COPPA) rea Publishers with content falling under the scope of this regulation should consult with their legal teams. The flag may be passed to supporting adapters with this config: -{% highlight js %} +```javascript pbjs.setConfig({coppa: true}); -{% endhighlight %} +``` - + #### First Party Data @@ -1077,24 +1079,25 @@ Not all bid adapters currently support reading first party data in this way, but **Scenario 1** - Global (cross-adunit) First Party Data open to all bidders -{% highlight js %} +```javascript pbjs.setConfig({ ortb2: { site: { - ... + // ... }, user: { - ... + // ... } } }); -{% endhighlight %} +``` The `ortb2` JSON structure reflects the OpenRTB standard: -- Fields that like keywords, search, content, gender, yob, and geo are values defined in OpenRTB, so should go directly under the site or user objects. -- Arbitrary values should go in site.ext.data or user.ext.data. -- Segments should go in site.content.data[] or user.data[]. -- Any other OpenRTB 2.5 field could be added here as well, e.g. site.content.language. + +* Fields that like keywords, search, content, gender, yob, and geo are values defined in OpenRTB, so should go directly under the site or user objects. +* Arbitrary values should go in site.ext.data or user.ext.data. +* Segments should go in site.content.data[] or user.data[]. +* Any other OpenRTB 2.5 field could be added here as well, e.g. site.content.language. **Scenario 2** - Auction (cross-adunit) First Party Data open to all bidders @@ -1110,7 +1113,7 @@ See the [AdUnit Reference](/dev-docs/adunit-reference.html) for AdUnit-specific See [Prebid Server First Party Data](/prebid-server/features/pbs-fpd.html) for details about passing data server-side. - + #### Video Module to integrate with Video Players @@ -1142,10 +1145,11 @@ To register a video player with Prebid, you must use `setConfig` to set a `video **Note:** You can integrate with different Player vendors. For this to work, you must ensure that the right Video Submodules are included in your build, and that the providers have the right `vendorCode`s and `divId`s. -##### Example +##### Player Integration Example Assuming your page has 2 JW Player video players, 1 video.js video player, and your ad server is GAM. -{% highlight js %} + +```javascript pbjs.setConfig({ video: { providers: [{ @@ -1181,9 +1185,9 @@ pbjs.setConfig({ } } }); -{% endhighlight %} +``` - + #### Client-side Caching of VAST XML @@ -1192,16 +1196,16 @@ video player can retrieve them when it's ready. Players don't obtain the VAST XM the JavaScript DOM in Prebid.js, but rather expect to be given a URL where it can be retrieved. There are two different flows possible with Prebid.js around VAST XML caching: -- Server-side caching: +* Server-side caching: Some video bidders (e.g. Rubicon Project) always cache the VAST XML on their servers as part of the bid. They provide a 'videoCacheKey', which is used in conjunction with the VAST URL in the ad server to retrieve the correct VAST XML when needed. In this case, Prebid.js has nothing else to do. As of Prebid.js 4.28, a publisher may specify the `ignoreBidderCacheKey` flag to re-cache these bids somewhere else using a VAST wrapper. -- Client-side caching: +* Client-side caching: Video bidders that don't cache on their servers return the entire VAST XML body. In this scenario, Prebid.js needs to copy the VAST XML to a publisher-defined cache location on the network. Prebid.js POSTs the VAST XML to the named Prebid Cache URL. It then sets the 'videoCacheKey' to the key that's returned in the response. {: .table .table-bordered .table-striped } | Cache Attribute | Required? | Type | Description | |----+--------+-----+-------| | cache.url | yes | string | The URL of the Prebid Cache server endpoint where VAST creatives will be sent. | -| cache.timeout | no | number | Timeout (in milliseconds) for network requests to the cache | +| cache.timeout | no | number | Timeout (in milliseconds) for network requests to the cache | | cache.vasttrack | no | boolean | Passes additional data to the url, used for additional event tracking data. Defaults to `false`. | | cache.ignoreBidderCacheKey | no | boolean | If the bidder supplied their own cache key, setting this value to true adds a VAST wrapper around that URL, stores it in the cache defined by the `url` parameter, and replaces the original video cache key with the new one. This can dramatically simplify ad server setup because it means all VAST creatives reside behind a single URL. The tradeoff: this approach requires the video player to unwrap one extra level of VAST. Defaults to `false`. | | cache.batchSize | no | number | Enables video cache requests to be batched by a specified amount (defaults to 1) instead of making a single request per each video. | @@ -1209,44 +1213,44 @@ be retrieved. There are two different flows possible with Prebid.js around VAST Here's an example of basic client-side caching. Substitute your Prebid Cache URL as needed: -{% highlight js %} +```javascript pbjs.setConfig({ cache: { url: 'https://prebid.adnxs.com/pbc/v1/cache' } }); -{% endhighlight %} +``` {: .alert.alert-warning :} The endpoint URL provided must be a Prebid Cache or be otherwise compatible with the [Prebid Cache interface](https://github.com/prebid/prebid-cache). As of Prebid.js 4.28, you can specify the `ignoreBidderCacheKey` option: -{% highlight js %} +```javascript pbjs.setConfig({ cache: { url: 'https://my-pbs.example.com/cache', - ignoreBidderCacheKey: true + ignoreBidderCacheKey: true } }); -{% endhighlight %} +``` As of Prebid.js 2.36, you can track client-side cached VAST XML. This functionality is useful for publishers who want to allow their analytics provider to measure video impressions. The prerequisite to using this feature is the availability of a Prebid Server that supports: -- the /vtrack endpoint -- an analytics module with connection to an analytics system that supports joining the impression event to the original auction request on the bidid -- the ability of a publisher to utilize the feature (if account-level permission is enabled) +* the /vtrack endpoint +* an analytics module with connection to an analytics system that supports joining the impression event to the original auction request on the bidid +* the ability of a publisher to utilize the feature (if account-level permission is enabled) Given those conditions, the `vasttrack` flag can be specified: -{% highlight js %} +```javascript pbjs.setConfig({ cache: { url: 'https://my-pbs.example.com/vtrack', vasttrack: true } }); -{% endhighlight %} +``` Setting the `vasttrack` parameter to `true` supplies the POST made to the `/vtrack` Prebid Server endpoint with a couple of additional parameters needed @@ -1254,7 +1258,7 @@ by the analytics system to join the event to the original auction request. Optionally, `batchSize` and `batchTimeout` can be utlilized as illustrated with the example below: -{% highlight js %} +```javascript pbjs.setConfig({ cache: { url: 'https://prebid.adnxs.com/pbc/v1/cache', @@ -1262,16 +1266,17 @@ pbjs.setConfig({ batchTimeout: 50 } }); -{% endhighlight %} +``` The example above states that a timer will be initialized and wait up to 50ms for 4 responses to have been collected and then will fire off one batch video cache request for all 4 responses. Note that the batch request will be made when the specified `batchSize` number is reached or with the number of responses that could be collected within the timeframe specified by the value for `batchTimeout`. If a batchSize is set to 2 and 5 video responses arrive (within the timeframe specified by `batchTimeout`), then three batch requests in total will be made: + 1. Batch 1 will contain cache requests for 2 videos 2. Batch 2 will contain cache requests for 2 videos 3. Batch 3 will contain cache requests for 1 video - + #### Instream tracking @@ -1289,26 +1294,26 @@ This configuration will allow Analytics Adapters and Bid Adapters to track `BID_ | `instreamTracking.pollingFreq` | Optional | Integer |The frequency of polling. Default: `500`ms | | `instreamTracking.urlPattern` | Optional | RegExp | Regex for cache url patterns, to avoid false positives. | -#### Example +#### Instream Tracking Example -{% highlight js %} +```javascript pbjs.setConfig({ 'instreamTracking': { enabled: true, } }); -{% endhighlight %} +``` More examples [here](/dev-docs/modules/instreamTracking.html#example-with-urlpattern). - + #### Site Configuration Adapters, including Prebid Server adapters, can support taking site parameters like language. Just set the `ortb2.site` object as First Party Data to make it available to client- and server-side adapters. -{% highlight js %} +```javascript pbjs.setConfig({ ortb2: { site: { @@ -1318,12 +1323,12 @@ pbjs.setConfig({ } } }); -{% endhighlight %} +``` {: .alert.alert-warning :} In PBJS 4.29 and earlier, don't add the `ortb2` level here -- just `site` directly. Oh, and please upgrade. 4.29 was a long time ago. - + #### Auction Options @@ -1336,47 +1341,51 @@ The `auctionOptions` object controls aspects related to auctions. | `suppressStaleRender` | Optional | Boolean | When true, prevents `banner` bids from being rendered more than once. It should only be enabled after auto-refreshing is implemented correctly. Default is false. ##### Examples -Exclude status of bidder _doNotWaitForMe_ when checking auction completion. -{% highlight js %} + +Exclude status of bidder *doNotWaitForMe* when checking auction completion. + +```javascript pbjs.setConfig({ 'auctionOptions': { 'secondaryBidders': ['doNotWaitForMe'] } }); -{% endhighlight %} +``` Render winning bids only once. -{% highlight js %} + +```javascript pbjs.setConfig({ 'auctionOptions': { 'suppressStaleRender': true } }); -{% endhighlight %} +``` ##### More on Stale Rendering + When auto-refreshing is done incorrectly, it could cause the same bids to be rendered repeatedly. For instance, when googletag.pubads.refresh() is called directly without removing the PBJS targeting, the same hb_ variables get re-sent to GAM, re-chosen, and re-rendered. Over and over without ever asking PBJS for updated targeting variables. PBJS performs following actions when stale rendering is detected. + * Log a warning in the browser console if pbjs_debug=true. * Emit a `STALE_RENDER` event before `BID_WON` event. Stale winning bids will continue to be rendered unless `suppressStaleRender` is set to true. Events including `STALE_RENDER` and `BID_WON` are unaffected by this option. - - + #### maxNestedIframes Prebid.js will loop upward through nested iframes to find the top-most referrer. This setting limits how many iterations it will attempt before giving up and not setting referrer. -``` +```javascript pbjs.setConfig({ maxNestedIframes: 5 // default is 10 }); ``` - + #### Real-Time Data Modules @@ -1386,22 +1395,22 @@ RTD modules, define an overall amount of time they're willing to wait for results, and even flag some of the modules as being more "important" than others. -``` +```javascript pbjs.setConfig({ - ..., + // ..., realTimeData: { auctionDelay: 100, // REQUIRED: applies to all RTD modules dataProviders: [{ name: "RTD-MODULE-1", waitForIt: true, // OPTIONAL: flag this module as important params: { - ... module-specific parameters ... + // ... module-specific parameters ... } },{ name: "RTD-MODULE-2", waitForIt: false, // OPTIONAL: flag this module as less important params: { - ... module-specific parameters ... + //... module-specific parameters ... } }] } @@ -1428,18 +1437,17 @@ Some publishers carefully manage these precious milliseconds, balancing impact of the real-time data with the revenue loss from auction delay. Notes: -- The only time `waitForIt` means anything is if some modules are flagged as true and others as false. If all modules are the same (true or false), it has no effect. -- Likewise, `waitForIt` doesn't mean anything without an auctionDelay specified. - +* The only time `waitForIt` means anything is if some modules are flagged as true and others as false. If all modules are the same (true or false), it has no effect. +* Likewise, `waitForIt` doesn't mean anything without an auctionDelay specified. - + #### Topics Iframe Configuration Topics iframe implementation is the enhancements of existing module under topicsFpdModule.js where different bidders will call the topic API under their domain to fetch the topics for respective domain and the segment data will be part of ORTB request under user.data object. Default config is maintained in the module itself. Below are the configuration which can be used to configure and override the default config maintained in the module. -``` +```javascript pbjs.setConfig({ userSync: { ..., @@ -1474,60 +1482,62 @@ pbjs.setConfig({ | topics.bidders[].iframeURL | yes | string | URL which is hosted on bidder/SSP/third-party domains which will call Topics API. | | topics.bidders[].expiry | no | integer | Max number of days where Topics data will be persist. If Data is stored for more than mentioned expiry day, it will be deleted from storage. Default is 21 days which is hardcoded in Module. | + - #### Disable performance metrics -Since version 7.17, Prebid collects fine-grained performance metrics and attaches them to several events for the purpose of analytics. If you find that this generates too much data for your analytics provider you may disable this feature with: +Since version 7.17, Prebid collects fine-grained performance metrics and attaches them to several events for the purpose of analytics. If you find that this generates too much data for your analytics provider you may disable this feature with: -``` +```javascript pbjs.setConfig({performanceMetrics: false}) ``` - + + #### Setting alias registry to private The alias registry is made public by default during an auction. It can be referenced in the following way: -``` +```javascript pbjs.aliasRegistry or pbjs.aliasRegistry[aliasName]; ``` -Inversely, if you wish for the alias registry to be private you can do so by using the option below (causing `pbjs.aliasRegistry` to return undefined): +Inversely, if you wish for the alias registry to be private you can do so by using the option below (causing `pbjs.aliasRegistry` to return undefined): -``` +```javascript pbjs.setConfig({aliasRegistry: 'private'}) ``` - + + #### Generic setConfig Configuration Some adapters may support other options, as defined in their documentation. To set arbitrary configuration values: -{% highlight js %} +```javascript pbjs.setConfig({ : }); -{% endhighlight %} +``` - + #### Troubleshooting your configuration Towards catching syntax errors, one tip is to call `pbjs.setConfig` without an object, e.g., -{% highlight js %} -pbjs.setConfig('debug', 'true')); -{% endhighlight %} +```javascript +pbjs.setConfig('debug', 'true'); +``` then Prebid.js will print an error to the console that says: -``` +```noformat ERROR: setConfig options must be an object ``` If you don't see that message, you can assume the config object is valid. -
    +
    ## Related Reading -- [Prebid.js and Ad Server Key Values](/features/adServerKvps.html) +* [Prebid.js and Ad Server Key Values](/features/adServerKvps.html) diff --git a/dev-docs/publisher-api-reference/setTargetingForAst.md b/dev-docs/publisher-api-reference/setTargetingForAst.md index 900624df..5a58ec6f 100644 --- a/dev-docs/publisher-api-reference/setTargetingForAst.md +++ b/dev-docs/publisher-api-reference/setTargetingForAst.md @@ -1,7 +1,7 @@ --- layout: api_prebidjs title: pbjs.setTargetingForAst(adUnitCode) -description: +description: setTargetingForAst API sidebarType: 1 --- diff --git a/dev-docs/publisher-api-reference/setTargetingForGPTAsync.md b/dev-docs/publisher-api-reference/setTargetingForGPTAsync.md index 30a161b6..16d682df 100644 --- a/dev-docs/publisher-api-reference/setTargetingForGPTAsync.md +++ b/dev-docs/publisher-api-reference/setTargetingForGPTAsync.md @@ -1,7 +1,7 @@ --- layout: api_prebidjs title: pbjs.setTargetingForGPTAsync([codeArr], customSlotMatching) -description: +description: setTargetingForGPTAsync API sidebarType: 1 --- @@ -20,6 +20,7 @@ This function matches AdUnits that have returned from the auction to a GPT ad sl targeting attributes to the slot so they get sent to GAM. Here's how it works: + 1. For each AdUnit code that's returned from auction or is specified in the `codeArr` parameter: 2. For each GPT ad slot on the page: 3. If the `customSlotMatching` function is defined, call it. Else, try to match the AdUnit `code` with the GPT slot name. Else try to match the AdUnit `code` with the ID of the HTML div containing the slot. @@ -34,7 +35,7 @@ the ad results should render into. This could be useful on long-scrolling pages. short to make sure they get good viewability, the logic can find an appropriate placement for the auction result depending on where the user is once the auction completes. -``` +```javascript // returns a filter function that matches either with the slot or the adUnitCode // this filter function is being invoked after the auction has completed // this means that it can be used in order to place this within viewport instead of a static div naming diff --git a/dev-docs/publisher-api-reference/triggerBilling.md b/dev-docs/publisher-api-reference/triggerBilling.md index bb84d585..8e5e314a 100644 --- a/dev-docs/publisher-api-reference/triggerBilling.md +++ b/dev-docs/publisher-api-reference/triggerBilling.md @@ -1,7 +1,7 @@ --- layout: api_prebidjs title: pbjs.triggerBilling -description: +description: triggerBilling API sidebarType: 1 --- @@ -20,7 +20,7 @@ See below for an example of how triggerBilling can be used: {: .alert.alert-warning :} Note: The logic to decide when to invoke `pbjs.triggerBilling` is open-ended. One common use case could be to listen for an "on view" event emitted from your ad server.

    For instance, the example below listens for GPT's "impressionViewable" event to determine if a deferred ad unit has become visible and is therefore ready for billing. The utilized approach to determine when to invoke `pbjs.triggerBilling` should be customized to your specific needs (For more on GPT's "impressionViewable" event, see: [https://developers.google.com/publisher-tag/reference#googletag.events.impressionviewableevent](https://developers.google.com/publisher-tag/reference#googletag.events.impressionviewableevent)).

    Additionally, the example below takes into account the possibility of multiple deferred ad units being present on a page that could potentially invoke the triggerBilling function (see the "deferredAdUnitIds" variable in the snippet below). The amount of deferred ad units needed on a page are dependent on your needs and could vary. -{% highlight js %} +```javascript ... var adUnits = [ @@ -74,6 +74,6 @@ function sendAdserverRequest(bids, timedOut, auctionId) { ... -{% endhighlight %} +```
    diff --git a/dev-docs/release-notes.md b/dev-docs/release-notes.md index 108c7d80..f30b8b0e 100644 --- a/dev-docs/release-notes.md +++ b/dev-docs/release-notes.md @@ -7,6 +7,7 @@ description: Release Notes
    # Release Notes + {:.no_toc} This page has links to release notes for each of the projects associated with Prebid.org. diff --git a/dev-docs/show-long-form-video-with-gam.md b/dev-docs/show-long-form-video-with-gam.md index b14d3018..7f9d4ef1 100644 --- a/dev-docs/show-long-form-video-with-gam.md +++ b/dev-docs/show-long-form-video-with-gam.md @@ -16,16 +16,18 @@ In this tutorial, we'll detail how to set up Prebid.js to display a Programmatic ## Prerequisites -The code example below was built with Prebid.js and the following: -- At least one video-enabled bidder supporting `adpod`. -- The [`dfpAdServerVideo` module](/dev-docs/modules/dfp_video.html), which will provide the video ad support. -- The [`categoryTranslation` module](/dev-docs/modules/categoryTranslation.html), to enable competitive separation. +The code example below was built with Prebid.js and the following: + +* At least one video-enabled bidder supporting `adpod`. +* The [`dfpAdServerVideo` module](/dev-docs/modules/dfp_video.html), which will provide the video ad support. +* The [`categoryTranslation` module](/dev-docs/modules/categoryTranslation.html), to enable competitive separation. For example, to build with the AppNexus bidder adapter and GAM use the following command: ```bash gulp build --modules=appnexusBidAdapter,dfpAdServerVideo ``` + For more information about how to build with modules, see the [Prebid module documentation](/dev-docs/modules/). {% include alerts/alert_important.html content="If competitve separation is required the optional [`categoryTranslation` module](/dev-docs/modules/categoryTranslation.html) needs to be added to the build command." %} @@ -33,12 +35,14 @@ For more information about how to build with modules, see the [Prebid module doc {% include alerts/alert_important.html content="Ensure your ad ops team has set up line items in Google Ad Manager." %} ## Ad Pod Module + When the [`dfpAdServerVideo` module](/dev-docs/modules/dfp_video.html) is included in the Prebid.js build, the [Ad Pod module](/dev-docs/modules/adpod.html), for working with ad pods, is automatically included. This module enables developers to add support for an adserver, like Google Ad Manager or Freewheel, that handles ad unit types of adpod. Specifically, the module provides functions to validate, cache, and modify long-form video bids. ## Implementation + This section provides information on how to implement and configure Prebid.js to display ad unit types of adpod. -**1. Create an ad unit** +### 1. Create an ad unit Create an ad unit that contains a video `mediaType` object and set the `mediaTypes.video.context` to `adpod`. Set the other parameters to the specific properties for the publisher's inventory. @@ -46,30 +50,29 @@ Create an ad unit that contains a video `mediaType` object and set the `mediaTyp ```javascript var videoAdUnit = [{ - code: 'sample-code', - sizes: [640,480], - mediaTypes: { - video: { - context: 'adpod', - playerSize: [640, 480], - adPodDurationSec: 300, - durationRangeSec: [15, 30], - requireExactDuration: true - } - }, - bids: [ - { - bidder: 'appnexus', - params: { - placementId: 14542875 - } + code: 'sample-code', + sizes: [640,480], + mediaTypes: { + video: { + context: 'adpod', + playerSize: [640, 480], + adPodDurationSec: 300, + durationRangeSec: [15, 30], + requireExactDuration: true + } + }, + bids: [ + { + bidder: 'appnexus', + params: { + placementId: 14542875 } - ] - }]; -}; + } + ] +}] ``` -**2. Get ad pod targeting** +### 2. Get ad pod targeting If a publisher wants to retrieve ad pod targeting and create the master tag themselves they can use the getAdPodTargeting method of the `dfpAdServerVideo` module. The method requires an array of ad unit codes and returns targeting key values and the cache id as JSON. @@ -86,23 +89,23 @@ pbjs.adServers.dfp.getAdpodTargeting({ Sample return: -```JSON +```json { - 'adUnitCode-1': [ + "adUnitCode-1": [ { - 'hb_pb_cat_dur': '10.00_
    - + -{% highlight js %} +```javascript pbjs.addAdUnits({ code: slot.code, @@ -151,7 +152,7 @@ pbjs.addAdUnits({ }, ] }) -{% endhighlight %} +``` {: .alert.alert-danger :} For each native ad unit, all of the bidders within that ad unit must have declared native support in their adapter if you want ads to appear. If there are any bidders without native support in a native ad unit, requests will not be made to those bidders. For a list of bidders with native support, see [Bidders with Video and Native Demand]({{site.baseurl}}/dev-docs/bidders.html#bidders-with-video-and-native-demand). @@ -164,16 +165,16 @@ For now there is only the `image` type, but more will be added. The image native ad type implies the following required fields: -+ image -+ title -+ sponsoredBy -+ clickUrl +* image +* title +* sponsoredBy +* clickUrl And the following optional fields: -+ body -+ icon -+ cta +* body +* icon +* cta A native "image-type" ad unit can be set up as shown in the following example. @@ -196,9 +197,9 @@ const adUnits = [{ {% include dev-docs/native-image-asset-sizes.md %} -### 3. Add your native ad tag to the page body as usual: +### 3. Add your native ad tag to the page body as usual -{% highlight html %} +```html
    -{% endhighlight %} +``` ## Sending Asset Placeholders @@ -280,8 +281,8 @@ The `native-trk.js` script from `prebid-universal-creative` can replace native p ## Working Examples -+ [Prebid Native Examples](/dev-docs/examples/native-ad-example.html) +* [Prebid Native Examples](/dev-docs/examples/native-ad-example.html) ## Further Reading -+ [GAM Step by Step - Native Creatives](/adops/gam-native.html) (Ad Ops Setup Instructions) +* [GAM Step by Step - Native Creatives](/adops/gam-native.html) (Ad Ops Setup Instructions) diff --git a/dev-docs/show-outstream-video-ads.md b/dev-docs/show-outstream-video-ads.md index 3e551682..0f6c0664 100644 --- a/dev-docs/show-outstream-video-ads.md +++ b/dev-docs/show-outstream-video-ads.md @@ -9,6 +9,7 @@ sidebarType: 4
    # Show Outstream Video Ads + {: .no_toc} Unlike instream video ads, which require you to have your own video inventory, Outstream video ads can be shown on any web page, even pages that only have text content. @@ -24,7 +25,7 @@ There should be no changes required on the ad ops side, since the outstream unit ## Prerequisites -+ Inclusion of at least one demand adapter that supports the `"video"` media type +* Inclusion of at least one demand adapter that supports the `"video"` media type ## Step 1: Set up ad units with the video media type and outstream context @@ -32,8 +33,7 @@ Use the `adUnit.mediaTypes` object to set up your ad units with the `video` medi For full details on video ad unit parameters, see [Ad Unit Reference for Video]({{site.baseurl}}/dev-docs/adunit-reference.html#adunitmediatypesvideo) -{% highlight js %} - +```javascript var videoAdUnits = [{ code: 'video1', mediaTypes: { @@ -54,8 +54,7 @@ var videoAdUnits = [{ } }] }]; - -{% endhighlight %} +``` ### Renderers @@ -85,10 +84,9 @@ A renderer is an object containing these properties: 2. `render` -- A function that tells Prebid.js how to invoke the renderer script. 3. `backupOnly` -- Optional field, if set to true, buyer or adapter renderer will be preferred - In a multiFormat adUnit, you might want the renderer to only apply to only one of the mediaTypes. You can do this by defining the renderer on the media type itself. -{% highlight js %} +```javascript pbjs.addAdUnit({ code: 'video1', // This renderer would apply to all prebid creatives... @@ -120,12 +118,11 @@ pbjs.addAdUnit({ }, ... }); -{% endhighlight %} +``` Some demand partners that return a renderer with their video bid responses may support renderer configuration with the `adUnit.renderer.options` object. These configurations are bidder specific and may include options for skippability, player size, and ad text, for example. An example renderer configuration follows: -{% highlight js %} - +```javascript pbjs.addAdUnit({ code: 'video1', mediaTypes: { @@ -145,8 +142,7 @@ pbjs.addAdUnit({ }, ... }); - -{% endhighlight %} +``` For more technical information about renderers, see [the pull request originally adding the 'Renderer' type](https://github.com/prebid/Prebid.js/pull/1082) and [the pull request allowing the 'renderer' type in the mediaType](https://github.com/prebid/Prebid.js/pull/5760). @@ -158,8 +154,7 @@ Invoke your ad server for the outstream adUnit from the body of the page in the For a live example, see [Outstream with Google Ad Manager]({{site.github.url}}/examples/video/outstream/pb-ve-outstream-dfp.html). -{% highlight html %} - +```html

    Prebid Outstream Video Ad

    - -{% endhighlight %} +``` ### Option 2: Serving without an ad server @@ -185,8 +179,7 @@ In the Prebid.js event queue, you'll need to add a function that: 1. Selects the bid that will serve for the appropriate adUnit 2. Renders the ad -{% highlight js %} - +```javascript pbjs.que.push(function () { pbjs.addAdUnits(videoAdUnits); pbjs.requestBids({ @@ -197,20 +190,19 @@ pbjs.que.push(function () { } }); }); - -{% endhighlight %} +``` For more information, see the API documentation for: -+ [requestBids](/dev-docs/publisher-api-reference/requestBids.html) -+ [getHighestCpmBids](/dev-docs/publisher-api-reference/getHighestCpmBids.html) -+ [renderAd](/dev-docs/publisher-api-reference/renderAd.html) +* [requestBids](/dev-docs/publisher-api-reference/requestBids.html) +* [getHighestCpmBids](/dev-docs/publisher-api-reference/getHighestCpmBids.html) +* [renderAd](/dev-docs/publisher-api-reference/renderAd.html) ## Working Examples Below, find links to end-to-end "working examples" demonstrating Prebid Outstream: -+ [Outstream with Google Ad Manager]({{site.github.url}}/examples/video/outstream/pb-ve-outstream-dfp.html) -+ [Outstream without an Ad Server]({{site.github.url}}/examples/video/outstream/pb-ve-outstream-no-server.html) +* [Outstream with Google Ad Manager]({{site.github.url}}/examples/video/outstream/pb-ve-outstream-dfp.html) +* [Outstream without an Ad Server]({{site.github.url}}/examples/video/outstream/pb-ve-outstream-no-server.html)
    diff --git a/dev-docs/show-prebid-ads-on-amp-pages.md b/dev-docs/show-prebid-ads-on-amp-pages.md index f812053d..555b4264 100644 --- a/dev-docs/show-prebid-ads-on-amp-pages.md +++ b/dev-docs/show-prebid-ads-on-amp-pages.md @@ -6,6 +6,7 @@ sidebarType: 2 --- # Prebid AMP Implementation Guide + {: .no_toc} This page has instructions for showing ads on Accelerated Mobile Pages (AMP) using Prebid.js. @@ -14,11 +15,11 @@ Through this implementation, [Prebid Server][PBS] fetches demand and returns key For more information about AMP RTC, see: -+ [Prebid Server and AMP](/prebid-server/use-cases/pbs-amp.html) -+ [Prebid Server AMP Endpoint Technical Documentation](/prebid-server/endpoints/openrtb2/pbs-endpoint-amp.html) -+ [Prebid Server Stored Bid Requests](https://github.com/prebid/prebid-server/blob/master/docs/developers/stored-requests.md#stored-bidrequests) -+ [AMP RTC Overview](https://github.com/ampproject/amphtml/blob/master/extensions/amp-a4a/rtc-documentation.md) -+ [AMP RTC Publisher Integration Guide](https://github.com/ampproject/amphtml/blob/master/extensions/amp-a4a/rtc-publisher-implementation-guide.md) +* [Prebid Server and AMP](/prebid-server/use-cases/pbs-amp.html) +* [Prebid Server AMP Endpoint Technical Documentation](/prebid-server/endpoints/openrtb2/pbs-endpoint-amp.html) +* [Prebid Server Stored Bid Requests](https://github.com/prebid/prebid-server/blob/master/docs/developers/stored-requests.md#stored-bidrequests) +* [AMP RTC Overview](https://github.com/ampproject/amphtml/blob/master/extensions/amp-a4a/rtc-documentation.md) +* [AMP RTC Publisher Integration Guide](https://github.com/ampproject/amphtml/blob/master/extensions/amp-a4a/rtc-publisher-implementation-guide.md) {% capture tipNote %} For ad ops setup instructions, see [Google Ad Manager with Prebid Step by Step](/adops/step-by-step.html). @@ -33,18 +34,18 @@ For ad ops setup instructions, see [Google Ad Manager with Prebid Step by Step]( To set up Prebid to serve ads into your AMP pages, you'll need: -+ An account with a [Prebid Server][PBS] instance -+ One or more Prebid Server Stored Bid Requests. A Stored Bid Request is a partial OpenRTB JSON request which: - + Specifies properties like currency, schain, price granularity, etc. - + Contains a list of demand partners and their respective parameters -+ An AMP page containing at least one amp-ad element for an AMP ad network that supports Fast Fetch and AMP RTC +* An account with a [Prebid Server][PBS] instance +* One or more Prebid Server Stored Bid Requests. A Stored Bid Request is a partial OpenRTB JSON request which: + * Specifies properties like currency, schain, price granularity, etc. + * Contains a list of demand partners and their respective parameters +* An AMP page containing at least one amp-ad element for an AMP ad network that supports Fast Fetch and AMP RTC ## Implementation -+ [Prebid Server Stored Request](#prebid-server-stored-request): This is the Prebid Server Stored Bid Request. -+ [AMP content page](#amp-content-page): This is where your content lives. -+ [HTML Creative](#html-creative): This is the creative your Ad Ops team puts in your ad server. -+ [User Sync in AMP](#user-sync): This is the `amp-iframe` pixel that must be added to your AMP page to sync users with Prebid Server. +* [Prebid Server Stored Request](#prebid-server-stored-request): This is the Prebid Server Stored Bid Request. +* [AMP content page](#amp-content-page): This is where your content lives. +* [HTML Creative](#html-creative): This is the creative your Ad Ops team puts in your ad server. +* [User Sync in AMP](#user-sync): This is the `amp-iframe` pixel that must be added to your AMP page to sync users with Prebid Server. ### Prebid Server Stored Request @@ -53,15 +54,14 @@ You will have to create at least one Stored Request for Prebid Server. Valid St An example Stored Request is given below. You'll see that the Stored Request contains some important info that doesn't come from /amp parameters: -- cur -- schain -- ext.prebid.cache.bids - needed to let Prebid Server know that you want it to store the result in PBC -- ext.prebid.targeting.pricegranularity - needed to let Prebid Server know how to calculate the price bucket -- ext.prebid.aliases -- bidders and their parameters - -```html +* cur +* schain +* ext.prebid.cache.bids - needed to let Prebid Server know that you want it to store the result in PBC +* ext.prebid.targeting.pricegranularity - needed to let Prebid Server know how to calculate the price bucket +* ext.prebid.aliases +* bidders and their parameters +```json { "id": "some-request-id", "cur": ["USD"], @@ -114,25 +114,28 @@ that doesn't come from /amp parameters: }] } ``` + This basic OpenRTB record will be enhanced by the parameters from the call to the [/amp endpoint](/prebid-server/endpoints/openrtb2/pbs-endpoint-amp.html). ### AMP content page First ensure that the amp-ad component is imported in the header. -``` +```html ``` + This script provides code libraries that will convert `` properties to the endpoint query parameters usint the [Real Time Config](https://github.com/ampproject/amphtml/blob/main/extensions/amp-a4a/rtc-documentation.md) (RTC) protocol. The `amp-ad` elements in the page body need to be set up as shown below, especially the following attributes: -+ `data-slot`: Identifies the ad slot for the auction. -+ `rtc-config`: Used to pass JSON configuration data to [Prebid Server][PBS], which handles the communication with AMP RTC. - + `vendors` is an object that defines any vendors that will be receiving RTC callouts (including Prebid Server) up to a maximum of five. The list of supported RTC vendors is maintained in [callout-vendors.js](https://github.com/ampproject/amphtml/blob/master/src/service/real-time-config/callout-vendors.js). We recommend working with your Prebid Server hosting company to set up which bidders and parameters should be involved for each AMP ad unit. - + `timeoutMillis` is an optional integer that defines the timeout in milliseconds for each individual RTC callout. The configured timeout must be greater than 0 and less than 1000ms. If omitted, the timeout value defaults to 1000ms. +* `data-slot`: Identifies the ad slot for the auction. +* `rtc-config`: Used to pass JSON configuration data to [Prebid Server][PBS], which handles the communication with AMP RTC. + * `vendors` is an object that defines any vendors that will be receiving RTC callouts (including Prebid Server) up to a maximum of five. The list of supported RTC vendors is maintained in [callout-vendors.js](https://github.com/ampproject/amphtml/blob/master/src/service/real-time-config/callout-vendors.js). We recommend working with your Prebid Server hosting company to set up which bidders and parameters should be involved for each AMP ad unit. + * `timeoutMillis` is an optional integer that defines the timeout in milliseconds for each individual RTC callout. The configured timeout must be greater than 0 and less than 1000ms. If omitted, the timeout value defaults to 1000ms. e.g. for the AppNexus cluster of Prebid Servers: + ```html - ``` Replace `MACRO` in the preceding example with the appropriate macro for the ad server. (Refer to your ad server's documentation or consult with a representative for specific details regarding the proper macros and how to use them.) @@ -225,11 +227,13 @@ To sync user IDs with Prebid Server, the `amp-iframe` below may be added to your Note that AMP constrains syncing as described in the [amp-iframe](https://amp.dev/documentation/components/amp-iframe) documentation. You may only have *one* amp-iframe on your page that is small, e.g. 1x1. Many publishers already have some kind of analytics or tracking frame on their page, so they may find it difficult to manage this. Several hacks are possible, including building a 'frankenstein' script that combines all of your required tracking into one or tying the sync to an image that's large enough to be visible. Notes: -- The following examples include a transparent image as a placeholder which will allow you to place the example at the top within the HTML body. If this is not included the iFrame must be either 600px away from the top or not within the first 75% of the viewport when scrolled to the top – whichever is smaller. For more information on this, see [amp-iframe](https://amp.dev/documentation/components/amp-iframe/) -- Note that the `sandbox` parameter to the amp-iframe must include both "allow-scripts" and "allow-same-origin". -- The load-cookie-with-consent.html file has the same argument syntax as load-cookie.html. It's a different file because it's larger and depends on the existence of an AMP Consent Management Platform. + +* The following examples include a transparent image as a placeholder which will allow you to place the example at the top within the HTML body. If this is not included the iFrame must be either 600px away from the top or not within the first 75% of the viewport when scrolled to the top – whichever is smaller. For more information on this, see [amp-iframe](https://amp.dev/documentation/components/amp-iframe/) +* Note that the `sandbox` parameter to the amp-iframe must include both "allow-scripts" and "allow-same-origin". +* The load-cookie-with-consent.html file has the same argument syntax as load-cookie.html. It's a different file because it's larger and depends on the existence of an AMP Consent Management Platform. If you're using AppNexus' managed service, you would enter something like this: + ```html diff --git a/dev-docs/show-video-with-a-dfp-video-tag.md b/dev-docs/show-video-with-a-dfp-video-tag.md index 37abf718..ce52dee3 100644 --- a/dev-docs/show-video-with-a-dfp-video-tag.md +++ b/dev-docs/show-video-with-a-dfp-video-tag.md @@ -8,6 +8,7 @@ sidebarType: 4
    # Show Video Ads with Google Ad Manager + {: .no_toc} In this tutorial, we'll show how to set up Prebid to show a video ad @@ -22,13 +23,13 @@ different video players and video-enabled bidders. The code example below was built using the following libraries: -+ [video.js](https://videojs.com/) version 5.9.2 -+ MailOnline's [videojs-vast-vpaid plugin](https://github.com/MailOnline/videojs-vast-vpaid) version 2.0.2 +* [video.js](https://videojs.com/) version 5.9.2 +* MailOnline's [videojs-vast-vpaid plugin](https://github.com/MailOnline/videojs-vast-vpaid) version 2.0.2 Also, you need to make sure to build Prebid.js with: -+ Support for at least one video-enabled bidder -+ Support for the `dfpAdServerVideo` ad server adapter, which will provide the video ad support +* Support for at least one video-enabled bidder +* Support for the `dfpAdServerVideo` ad server adapter, which will provide the video ad support For example, to build with the AppNexus bidder adapter and the Google Ad Manager Video ad server adapter, use the following command: @@ -121,12 +122,12 @@ pbjs.que.push(function() { The VAST XML has to be cached somewhere because most video players can only work with a URL that returns VAST XML, not VAST directly. Some bidders cache the VAST XML on the server side, while others depend on Prebid.js to perform the caching. -+ In general, video-enabled bidders must supply `bid.videoCacheKey`, `bid.vastXml`, or `bid.vastUrl` on their responses, and can provide any combination of the three. -+ If `pbjs.setConfig({cache: {URL}})` isn't set and the bidder supplies only `bid.vastXml` in its bid response, [`pbjs.adServers.dfp.buildVideoUrl`](/dev-docs/publisher-api-reference/adServers.dfp.buildVideoUrl.html) will not be able to generate a videoCacheKey, and it will be dropped from the auction. -+ If `pbjs.setConfig({cache: {URL}})` is defined and the bidder responds with `bid.videoCacheKey`, Prebid.js will not re-cache the VAST XML. -+ If `options.url` is passed as an argument to [`pbjs.adServers.dfp.buildVideoUrl`](/dev-docs/publisher-api-reference/adServers.dfp.buildVideoUrl.html): - + If Prebid Cache is disabled, Prebid sets `description_url` field to the bid response's `bid.vastUrl`. - + If Prebid Cache is enabled, Prebid sets `description_url` field to the cache URL. +* In general, video-enabled bidders must supply `bid.videoCacheKey`, `bid.vastXml`, or `bid.vastUrl` on their responses, and can provide any combination of the three. +* If `pbjs.setConfig({cache: {URL}})` isn't set and the bidder supplies only `bid.vastXml` in its bid response, [`pbjs.adServers.dfp.buildVideoUrl`](/dev-docs/publisher-api-reference/adServers.dfp.buildVideoUrl.html) will not be able to generate a videoCacheKey, and it will be dropped from the auction. +* If `pbjs.setConfig({cache: {URL}})` is defined and the bidder responds with `bid.videoCacheKey`, Prebid.js will not re-cache the VAST XML. +* If `options.url` is passed as an argument to [`pbjs.adServers.dfp.buildVideoUrl`](/dev-docs/publisher-api-reference/adServers.dfp.buildVideoUrl.html): + * If Prebid Cache is disabled, Prebid sets `description_url` field to the bid response's `bid.vastUrl`. + * If Prebid Cache is enabled, Prebid sets `description_url` field to the cache URL. #### Notes on multiple video advertisements on one page @@ -195,19 +196,20 @@ If you have [set up your ad server line items and creatives correctly]({{site.ba Below, find links to end-to-end "working examples" integrating Prebid.js demand with various video players: ### Using client-side adapters -+ [Akamai AMP]({{site.github.url}}/examples/video/instream/akamai/pb-ve-amp.html) -+ [Brid]({{site.github.url}}/examples/video/instream/brid/pb-ve-brid.html) -+ [Brightcove]({{site.github.url}}/examples/video/instream/brightcove/pb-ve-brightcove.html) -+ [Flowplayer]({{site.github.url}}/examples/video/instream/flowplayer/pb-ve-flowplayer.html) -+ [JWPlayer - Platform]({{site.github.url}}/examples/video/instream/jwplayer/pb-ve-jwplayer-platform.html) -+ [JWPlayer - Hosted]({{site.github.url}}/examples/video/instream/jwplayer/pb-ve-jwplayer-hosted.html) -+ [Kaltura]({{site.github.url}}/examples/video/instream/kaltura/pb-ve-kaltura.html) -+ [Ooyala]({{site.github.url}}/examples/video/instream/ooyala/pb-ve-ooyala.html) -+ [VideoJS]({{site.github.url}}/examples/video/instream/videojs/pb-ve-videojs.html) -+ [Instream and Banner Mixed](/dev-docs/examples/instream-banner-mix.html) + +* [Akamai AMP]({{site.github.url}}/examples/video/instream/akamai/pb-ve-amp.html) +* [Brid]({{site.github.url}}/examples/video/instream/brid/pb-ve-brid.html) +* [Brightcove]({{site.github.url}}/examples/video/instream/brightcove/pb-ve-brightcove.html) +* [Flowplayer]({{site.github.url}}/examples/video/instream/flowplayer/pb-ve-flowplayer.html) +* [JWPlayer - Platform]({{site.github.url}}/examples/video/instream/jwplayer/pb-ve-jwplayer-platform.html) +* [JWPlayer - Hosted]({{site.github.url}}/examples/video/instream/jwplayer/pb-ve-jwplayer-hosted.html) +* [Kaltura]({{site.github.url}}/examples/video/instream/kaltura/pb-ve-kaltura.html) +* [Ooyala]({{site.github.url}}/examples/video/instream/ooyala/pb-ve-ooyala.html) +* [VideoJS]({{site.github.url}}/examples/video/instream/videojs/pb-ve-videojs.html) +* [Instream and Banner Mixed](/dev-docs/examples/instream-banner-mix.html) ## Related Topics -+ [Setting up Prebid Video in Google Ad Manager]({{site.baseurl}}/adops/setting-up-prebid-video-in-dfp.html) +* [Setting up Prebid Video in Google Ad Manager]({{site.baseurl}}/adops/setting-up-prebid-video-in-dfp.html)
    diff --git a/dev-docs/testing-prebid.md b/dev-docs/testing-prebid.md index 9706a054..97168f71 100644 --- a/dev-docs/testing-prebid.md +++ b/dev-docs/testing-prebid.md @@ -4,14 +4,13 @@ layout: page_v2 title: Testing Prebid.js description: How to write tests for the Prebid.js library pid: 199 - top_nav_section: dev_docs - ---
    # Testing Prebid.js + {: .no_toc} Starting on 21 June 2016, all pull requests to the Prebid.js library will need to include tests with greater than 80% code coverage for any changed/added code before they can be merged into master. @@ -27,68 +26,67 @@ This page describes how to test code in the Prebid.js repository to help prepare When you are adding code to Prebid.js, or modifying code that isn't covered by an existing test, test the code according to these guidelines: -- If the module you are working on is already partially tested by a file within the `test` directory, add tests to that file -- If the module does not have any tests, create a new test file -- Group tests in a `describe` block -- Test individual units of code within an `it` block -- Within an `it` block, it may be helpful to use the "Arrange-Act-Assert" pattern - - _Arrange_: set up necessary preconditions and inputs - - e.g., creating objects, spies, etc. - - _Act_: call or act on the unit under test - - e.g., call the function you are testing with the parameters you set up - - _Assert_: check that the expected results have occurred - - e.g., use Chai assertions to check that the expected output is equal to the actual output -- Test the public interface, not the internal implementation -- If using global `pbjs` data structures in your test, take care to not completely overwrite them with your own data as that may affect other tests relying on those structures, e.g.: - - **OK**: `pbjs._bidsRequested.push(bidderRequestObject);` - - **NOT OK**: `pbjs._bidsRequested = [bidderRequestObject];` -- If you need to check `adloader.loadScript` in a test, use a `stub` rather than a `spy`. `spy`s trigger a network call which can result in a `script error` and cause unrelated unit tests to fail. `stub`s will let you gather information about the `adloader.loadScript` call without affecting external resources - -- When writing tests you may use ES2015 syntax if desired +* If the module you are working on is already partially tested by a file within the `test` directory, add tests to that file +* If the module does not have any tests, create a new test file +* Group tests in a `describe` block +* Test individual units of code within an `it` block +** Within an `it` block, it may be helpful to use the "Arrange-Act-Assert" pattern + * _Arrange_: set up necessary preconditions and inputs + * e.g., creating objects, spies, etc. + * _Act_: call or act on the unit under test + * e.g., call the function you are testing with the parameters you set up + * _Assert_: check that the expected results have occurred + * e.g., use Chai assertions to check that the expected output is equal to the actual output +* Test the public interface, not the internal implementation +* If using global `pbjs` data structures in your test, take care to not completely overwrite them with your own data as that may affect other tests relying on those structures, e.g.: + * **OK**: `pbjs._bidsRequested.push(bidderRequestObject);` + * **NOT OK**: `pbjs._bidsRequested = [bidderRequestObject];` +* If you need to check `adloader.loadScript` in a test, use a `stub` rather than a `spy`. `spy`s trigger a network call which can result in a `script error` and cause unrelated unit tests to fail. `stub`s will let you gather information about the `adloader.loadScript` call without affecting external resources +* When writing tests you may use ES2015 syntax if desired ## Running tests After checking out the Prebid.js repository and installing dev dependencies with `npm install`, use the following commands to run tests as you are working on code: -- `gulp test` will run the test suite once (`npm test` is aliased to call `gulp test`) -- `gulp serve` will run tests once and stay open, re-running tests whenever a file in the `src` or `test` directory is modified +* `gulp test` will run the test suite once (`npm test` is aliased to call `gulp test`) +* `gulp serve` will run tests once and stay open, re-running tests whenever a file in the `src` or `test` directory is modified ## Checking results and code coverage Check the test results using these guidelines: -- Look at the total number of tests run, passed, and failed (shown below the rainbow Nyan Cat in the shell window). -- If all tests are passing, great. -- Otherwise look for errors printed in the console for a description of the failing test. -- You may need to iterate on your code or tests until all tests are passing. -- Make sure existing tests still pass. -- There is a table below the testing report that shows code coverage percentage, for each file under the `src` directory. -- Each time you run tests, a code coverage report is generated in `build/coverage/lcov/lcov-report/index.html`. -- This is a static HTML page that you can load in your browser. -- On that page, navigate to the file you are testing to see which lines are being tested. -- Red indicates that a line isn't covered by a test. -- Gray indicates a line that doesn't need coverage, such as a comment or blank line. -- Green indicates a line that is covered by tests. -- The code you have added or modified must have greater than 80% coverage to be accepted. +* Look at the total number of tests run, passed, and failed (shown below the rainbow Nyan Cat in the shell window). +* If all tests are passing, great. +* Otherwise look for errors printed in the console for a description of the failing test. +* You may need to iterate on your code or tests until all tests are passing. +* Make sure existing tests still pass. +* There is a table below the testing report that shows code coverage percentage, for each file under the `src` directory. +* Each time you run tests, a code coverage report is generated in `build/coverage/lcov/lcov-report/index.html`. +* This is a static HTML page that you can load in your browser. +* On that page, navigate to the file you are testing to see which lines are being tested. +* Red indicates that a line isn't covered by a test. +* Gray indicates a line that doesn't need coverage, such as a comment or blank line. +* Green indicates a line that is covered by tests. +* The code you have added or modified must have greater than 80% coverage to be accepted. ## Examples Prebid.js already has lots of tests. Read them to see how Prebid.js is tested, and for inspiration: -- Look in `test/spec` and its subdirectories -- Tests for bidder adaptors are located in `test/spec/adapters` +* Look in `test/spec` and its subdirectories +* Tests for bidder adaptors are located in `test/spec/adapters` A test module might have the following general structure: -{% highlight js %} +```javascript // Import or require modules necessary for the test, e.g.: import { expect } from 'chai'; // may prefer 'assert' in place of 'expect' -import adapter from 'src/adapters/'; +import adapter from 'src/adapters/[adapter]'; -describe('', () => { +describe('[Adapter]', () => { - it('', () => { + it('[description of unit or feature being tested]', () => { // Arrange - set up preconditions and inputs // Act - call or act on the code under test // Assert - use chai to check that expected results have occurred @@ -98,14 +96,14 @@ describe('', () => { }); -{% endhighlight %} +``` ## Resources The Prebid.js testing stack contains some of the following tools. It may be helpful to consult their documentation during the testing process. -- [Mocha - test framework](https://mochajs.org/) -- [Chai - BDD/TDD assertion library](https://chaijs.com/) -- [Sinon - spy, stub, and mock library](https://sinonjs.org/) +* [Mocha - test framework](https://mochajs.org/) +* [Chai - BDD/TDD assertion library](https://chaijs.com/) +* [Sinon - spy, stub, and mock library](https://sinonjs.org/)
    diff --git a/dev-docs/troubleshooting-tips.md b/dev-docs/troubleshooting-tips.md index 1b2375c9..45b47efd 100644 --- a/dev-docs/troubleshooting-tips.md +++ b/dev-docs/troubleshooting-tips.md @@ -11,6 +11,7 @@ sidebarType: 1 # Tips for Troubleshooting + {:.no_toc} Moved to [the PBJS Troubleshooting Guide](/troubleshooting/troubleshooting-guide.html). diff --git a/dev-docs/vendor-billing.md b/dev-docs/vendor-billing.md index 9dc0bf9f..ce22b26d 100644 --- a/dev-docs/vendor-billing.md +++ b/dev-docs/vendor-billing.md @@ -6,6 +6,7 @@ sidebarType: 1 --- # Vendor Billing in Prebid.js + {:.no_toc} Prebid.js now supports a new event type: **Billable Event**. Billable events allow **Real Time Data (RTD)** modules to signal that their system calculated that a billing event occurred. Billable events are trackable by analytics adapters as well as publishers to track and aggregate billing data. @@ -16,7 +17,7 @@ In order to emit events, **RTD** modules simply need to utilize the existing Eve At this time there are limited requirements about the contents of billable events. However, it should be expected that partners who choose to leverage billable events may have unique requirements or implementations that will be documented individually, including adding additional parameters to the events as they see fit. -**Event Payload Parameters** +### Event Payload Parameters There are two parameters that emitters of this event must supply. Other parameters may be supplied as desired by the application. @@ -28,28 +29,31 @@ There are two parameters that emitters of this event must supply. Other paramete For example, a RTD module could emit an event like this: +```javascript +events.emit(CONSTANTS.EVENTS.BILLABLE_EVENT, { + vendor: 'vendorA', + billingId: generateUUID(), + type: 'ad_request', + transactionId: transactionId, + auctionId: auctionId +}) ``` - events.emit(CONSTANTS.EVENTS.BILLABLE_EVENT, { - vendor: 'vendorA', - billingId: generateUUID(), - type: 'ad_request', - transactionId: transactionId, - auctionId: auctionId - }) It is expected that vendors will not emit duplicate events. ## Analytics Adapter Interface [Analytics Adapters](/dev-docs/integrate-with-the-prebid-analytics-api.html) just listen for the **BILLABLE_EVENT**. It is assumed that analytics adapters and their downstream reporting handles their own tracking of events any validation of the contract between vendors and publishers. -``` - switch (eventType) { - ... - case BILLABLE_EVENT: - ... + +```javascript +switch (eventType) { + // ... + case BILLABLE_EVENT: + // ... ``` ## Related Reading + - [pbjs.getEvents()](/dev-docs/publisher-api-reference/getEvents.html) - [Real Time Data modules](/dev-docs/add-rtd-submodule.html) - [Analytics Adapters](/dev-docs/integrate-with-the-prebid-analytics-api.html) diff --git a/examples/video/instream/jwplayer/pb-ve-jwplayer-hosted.html b/examples/video/instream/jwplayer/pb-ve-jwplayer-hosted.html index 9b5f0875..55d8d70b 100644 --- a/examples/video/instream/jwplayer/pb-ve-jwplayer-hosted.html +++ b/examples/video/instream/jwplayer/pb-ve-jwplayer-hosted.html @@ -8,11 +8,11 @@ ---
    -
    -
    -

    {{ page.title }}

    -

    {{page.description }}

    -
    +
    +
    +

    {{ page.title }}

    +

    {{page.description }}

    +

    (Sorry, video code examples aren't available with your cookie privacy settings.)

    @@ -154,11 +154,11 @@

    Place this code in the page body.

    OneTrust.InsertHtml(exampleHTML, 'videoExample', null, {deleteSelectorContent: true}, 'C0003'); }) -
    +
    - + - + diff --git a/examples/video/instream/jwplayer/pb-ve-jwplayer-platform.html b/examples/video/instream/jwplayer/pb-ve-jwplayer-platform.html index 26fb0faa..936406e1 100644 --- a/examples/video/instream/jwplayer/pb-ve-jwplayer-platform.html +++ b/examples/video/instream/jwplayer/pb-ve-jwplayer-platform.html @@ -10,11 +10,11 @@
    -
    -
    -

    {{ page.title }}

    -

    {{page.description }}

    -
    +
    +
    +

    {{ page.title }}

    +

    {{page.description }}

    +

    (Sorry, video code examples aren't available with your cookie privacy settings.)

    @@ -151,7 +151,7 @@

    Place this code in the page body.

    `; -
    +
    -
    + - - + diff --git a/examples/video/long-form/long-form-video-with-freewheel.html b/examples/video/long-form/long-form-video-with-freewheel.html index 1917fd8d..5d932418 100644 --- a/examples/video/long-form/long-form-video-with-freewheel.html +++ b/examples/video/long-form/long-form-video-with-freewheel.html @@ -15,11 +15,11 @@ - - +