Body text. Proxima Nova Regular. 18pt. 28pt leading. #666. Vector-H is a high-performance MPP SQL engine with vectorized query execution that runs natively in Hadoop, powering modern decision support systems and BI by enabling developers, data scientists and business analysts to query HDFS data for machine learning, advanced analytics, statistics and more.
-
-{% if page.prevBiddercode %}
-This bidder previously had a bidder code of `{{ page.prevBiddercode }}`, but prefers new configurations to use `{{ page.biddercode }}`.
-{% endif %}
-
-{% if page.bidder_supports_deals != false %}
-
+
+ {% if page.prevBiddercode %}
+ This bidder previously had a bidder code of `{{ page.prevBiddercode }}`, but prefers new configurations to use `{{ page.biddercode }}`.
+ {% endif %}
+
+ {% if page.bidder_supports_deals != false %}
+
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.
+
+
+
+
+
+
+
+
+
Prebid.js
+
The leading web based header bidding solution used by publishers worldwide
-{% include footer.html %}
\ No newline at end of file
+{% include footer.html %}
+
+
+
diff --git a/_layouts/video_sample.html b/_layouts/video_sample.html
index e41635c5e6..1630679395 100644
--- a/_layouts/video_sample.html
+++ b/_layouts/video_sample.html
@@ -65,20 +65,25 @@
{% include nav.html %}
-
+
-
+
-
-
- {% include left_nav.html %}
+
+
+
+ {% include left_nav.html %}
+
+
-
-
+
+
{{ content }}
@@ -87,16 +92,12 @@
{% endif %}
+
-
-
-
-
-
{% if page.title != "Credits" %}
{% if page.layout != "home" %}
{% include footer.html %}
@@ -114,3 +115,5 @@
-->
+
+
diff --git a/_posts/2019-01-08-updated-website.md b/_posts/2019-01-08-updated-website.md
index f3cd3d0ba0..16eb9b21ce 100644
--- a/_posts/2019-01-08-updated-website.md
+++ b/_posts/2019-01-08-updated-website.md
@@ -21,7 +21,7 @@ permalink: /blog/updated-website
- **New Content**:
- [Prebid Server docs](/prebid-server/prebid-server-overview.html)
- [Product Management Committees](/overview/prebid-management-committees.html)
- - [Community Code of Conduct](/overview/community-code-of-conduct.html)
+ - [Community Code of Conduct](https://prebid.org/code-of-conduct/#community)
- [Prebid Members and Partners](/partners/partners.html)
- [Prebid Members providing Managed Services](https://prebid.org/product-suite/managed-services/)
- [Format index page](/formats/formats.html)
diff --git a/adops/before-you-start.md b/adops/before-you-start.md
index 34957c3e6a..6388405a29 100644
--- a/adops/before-you-start.md
+++ b/adops/before-you-start.md
@@ -100,6 +100,23 @@ For instructions on setting up pre-bid with one set of line items for each bidde
{% include alerts/alert_tip.html content=successNote %}
+## Safeframes
+
+[SafeFrames are defined by the IAB](https://www.iab.com/guidelines/safeframe/) as a "managed API-enabled iframe that opens a line of communication between the publisher page and the iframe-contained ad creative."
+
+When setting up line items in your ad server, you'll need to consider whether to make the creatives safeframes or not. In general, for standard banner and native, safeframes are a good idea. Certain special mediatypes cannot use safeframes.
+
+### Bidders known to be incompatible with safeframes
+
+{% assign bidder_pages = site.pages | where: "layout", "bidder" | where: "safeframes_ok", false %}
+
+{% for page in bidder_pages %}
+
{{ page.title }}
+{% endfor %}
+
+
+There may be others, please check with bidders directly if you have questions about their support.
+
## Work together with your dev team
Implementing header bidding requires much more collaboration with your dev team than normal Ad Ops setup. For example:
diff --git a/assets/css/main-bundle.css b/assets/css/main-bundle.css
new file mode 100644
index 0000000000..c5331071a0
--- /dev/null
+++ b/assets/css/main-bundle.css
@@ -0,0 +1 @@
+*,: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}.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}img{max-width:100%}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 .highlight,.pb-content .pb-code-hl{margin-top:20px;margin-bottom:20px;padding:20px 22px 30px;border:1px solid #dddfe3;background:#f8f9f9;font-size:16px}.pb-content .highlight pre,.pb-content .pb-code-hl pre{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}.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}.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
diff --git a/assets/images/code-of-conduct-diagram.png b/assets/images/code-of-conduct-diagram.png
new file mode 100644
index 0000000000..e8bb0fa0f3
Binary files /dev/null and b/assets/images/code-of-conduct-diagram.png differ
diff --git a/assets/images/dev-docs/IDlib.png b/assets/images/dev-docs/IDlib.png
new file mode 100644
index 0000000000..b414ce5678
Binary files /dev/null and b/assets/images/dev-docs/IDlib.png differ
diff --git a/assets/images/icon__github-octocat--knockout.svg b/assets/images/icon__github-octocat--knockout.svg
new file mode 100644
index 0000000000..4d605bde34
--- /dev/null
+++ b/assets/images/icon__github-octocat--knockout.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/assets/images/icon__product--prebid-js.svg b/assets/images/icon__product--prebid-js.svg
new file mode 100644
index 0000000000..68d78087c8
--- /dev/null
+++ b/assets/images/icon__product--prebid-js.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/assets/images/icon__product--prebid-mobile-sdk.svg b/assets/images/icon__product--prebid-mobile-sdk.svg
new file mode 100644
index 0000000000..09052c99ed
--- /dev/null
+++ b/assets/images/icon__product--prebid-mobile-sdk.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/assets/images/icon__product--prebid-server.svg b/assets/images/icon__product--prebid-server.svg
new file mode 100644
index 0000000000..9b0bc7af5e
--- /dev/null
+++ b/assets/images/icon__product--prebid-server.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/assets/images/icon__social-media--linkedin.svg b/assets/images/icon__social-media--linkedin.svg
new file mode 100644
index 0000000000..4968bd281f
--- /dev/null
+++ b/assets/images/icon__social-media--linkedin.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/assets/images/icon__social-media--twitter.svg b/assets/images/icon__social-media--twitter.svg
new file mode 100644
index 0000000000..e01615c0fd
--- /dev/null
+++ b/assets/images/icon__social-media--twitter.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/assets/images/icon__source--prebid-docs.svg b/assets/images/icon__source--prebid-docs.svg
new file mode 100644
index 0000000000..4f24bda639
--- /dev/null
+++ b/assets/images/icon__source--prebid-docs.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/assets/images/icon__source--prebid-js.svg b/assets/images/icon__source--prebid-js.svg
new file mode 100644
index 0000000000..7678b81904
--- /dev/null
+++ b/assets/images/icon__source--prebid-js.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/assets/images/icon__source--prebid-mobile.svg b/assets/images/icon__source--prebid-mobile.svg
new file mode 100644
index 0000000000..13f66663c7
--- /dev/null
+++ b/assets/images/icon__source--prebid-mobile.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/assets/images/icon__source--prebid-server.svg b/assets/images/icon__source--prebid-server.svg
new file mode 100644
index 0000000000..9ca56f8db0
--- /dev/null
+++ b/assets/images/icon__source--prebid-server.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/assets/images/icons/down-carrot-0.svg b/assets/images/icons/down-carrot-0.svg
new file mode 100644
index 0000000000..a9d3a929b1
--- /dev/null
+++ b/assets/images/icons/down-carrot-0.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/assets/images/icons/up-carrot-0.svg b/assets/images/icons/up-carrot-0.svg
new file mode 100644
index 0000000000..84bb48c066
--- /dev/null
+++ b/assets/images/icons/up-carrot-0.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/assets/images/icons/up-carrot-1.svg b/assets/images/icons/up-carrot-1.svg
new file mode 100644
index 0000000000..8a2f62c81b
--- /dev/null
+++ b/assets/images/icons/up-carrot-1.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/assets/images/prebid-logo-knockout.svg b/assets/images/prebid-logo-knockout.svg
new file mode 100644
index 0000000000..366ddb53cc
--- /dev/null
+++ b/assets/images/prebid-logo-knockout.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/assets/images/prebid-rtd-architecture.jpg b/assets/images/prebid-rtd-architecture.jpg
new file mode 100644
index 0000000000..18340beeac
Binary files /dev/null and b/assets/images/prebid-rtd-architecture.jpg differ
diff --git a/dev-docs/add-rtd-submodule.md b/dev-docs/add-rtd-submodule.md
new file mode 100644
index 0000000000..75394f8b99
--- /dev/null
+++ b/dev-docs/add-rtd-submodule.md
@@ -0,0 +1,292 @@
+---
+layout: page_v2
+title: How to Add a Prebid.js RTD submodule
+description: How to Add a Prebid.js RTD submodule
+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.
+
+The RTD infrustruture is a generic module, not useful by itself. Instead, it allows sub-modules to register and modify bid request/response and/or set targeting data for the publisher’s ad server.
+
+Publishers will decide which RTD sub-modules they want to use, and can set parameters like timeout, endpoints, etc. They will set limits on how long sub-modules are allowed to delay the auction, which will most likely be in the tens of milliseconds.
+
+## Architecture
+
+The RTD-core infrastructure uses hooks and event listeners to call the appropriate sub-modules to retrieve the data.
+Here is the flow for how the RTD-core module interacts with its sub-modules:
+
+![Prebid RTD Architecture Diagram](/assets/images/prebid-rtd-architecture.jpg){: .pb-xlg-img :}
+
+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.
+
+Working with any Prebid project requires using Github. In general, we recommend the same basic workflow for any project:
+
+1. Fork the appropriate Prebid repository (e.g. [Prebid.js](https://github.com/prebid/Prebid.js)).
+2. Create a branch in your fork for your proposed code change. (e.g. feature/exRtdSProvider)
+3. Build and test your feature/bug fix in the branch.
+4. Open a [pull request](https://help.github.com/en/desktop/contributing-to-projects/creating-a-pull-request) to the appropriate repository's master branch with a good description of the feature/bug fix.
+5. If there's something that needs to change on the prebid.org website, follow the above steps for the [website repo](https://github.com/prebid/prebid.github.io).
+
+{: .alert.alert-warning :}
+RTD sub-modules are subject to a number of specific technical rules. Please become familiar
+with the [module rules](/dev-docs/module-rules.html) that apply globally and to Real Time Data modules in particular.
+
+### Step 1: Add a markdown file describing the sub-module
+
+Create a markdown file under `modules` with the name of the module suffixed with 'RtdProvider', e.g., `exRtdProvider.md`
+
+Example markdown file:
+{% highlight text %}
+# Overview
+
+Module Name: Ex Rtd Provider
+Module Type: Rtd Provider
+Maintainer: prebid@example.com
+
+# Description
+
+RTD provider for Example.com. Contact prebid@example.com for information.
+
+{% endhighlight %}
+
+### Step 2: Build the Module
+
+Now create a javascript file under `modules` with the name of the module suffixed with 'RtdProvider', e.g., `exRtdProvider.js`
+
+#### The Sub-Module object
+
+In order to let RTD-core know where to find the functions in your sub-module, create an object called `submoduleObj` that contains key values:
+
+{: .table .table-bordered .table-striped }
+| 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 ad server targeting 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 |
+| 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 %}
+export const subModuleObj = {
+ name: 'ExampleRTDModule',
+ init: init,
+ getTargetingData: sendDataToModule
+};
+{% endhighlight %}
+
+#### Register the submodule
+
+Register submodule to RTD-core:
+
+{% highlight text %}
+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.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.
+
+See the [Building the Request](/dev-docs/bidder-adaptor.html#building-the-request) section of the Bid Adapter documentation for more details about GDPR and USP.
+
+#### getTargetingData
+
+This is the function that will allow RTD sub-modules to merge ad server targeting data into the auction. It's called at the AUCTION_END event for each auction.
+
+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 %}
+{
+ "slotA":{
+ "p":0.56, // ad server targeting variable (e.g. p) for slotA is 0.56
+ },
+ "slotB":{
+ "p":0.824, // ad server targeting variable (e.g. p) for slotB is 0.824
+ }
+}
+{% endhighlight %}
+
+**Code Example**
+
+{% highlight text %}
+/** @type {RtdSubmodule} */
+export const subModuleObj = {
+ name: 'ExampleRTDModule',
+ init: init,
+ getTargetingData: returnTargetingData
+};
+
+function init(config, userConsent) {
+ // do init stuff
+ if (initfailed) return false;
+ return true;
+}
+
+function returnTargetingData(adUnits, config, userConsent) {
+ // do stuff
+ return data;
+}
+
+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: the object that's passed to [`pbjs.requestBids`](). 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)
+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.fpd.context.data.ATTRIBUTES
+ - For global first party data, call 'pbjs.[getConfig](/dev-docs/publisher-api-reference.html#module_pbjs.getConfig)({fpd.context})' or 'pbjs.getConfig({fpd.user})', merge in the new global data, and update with `pbjs.[setConfig](/dev-docs/publisher-api-reference.html#module_pbjs.setConfig)()'.
+ - If the data is not meant to go to all bidders, the module should use 'pbjs.[setBidderConfig](/dev-docs/publisher-api-reference.html#module_pbjs.setBidderConfig)()' and support a parameter to allow the publisher to define which bidders are to receive the data.
+ - 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.
+
+**Code Example**
+
+{% highlight text %}
+/** @type {RtdSubmodule} */
+export const subModuleObj = {
+ name: 'ExampleRTDModule2',
+ init: init,
+ setBidRequestsData: alterBidRequests
+};
+
+function init(config, userConsent) {
+ // do init stuff
+ if (initfailed) return false;
+ return true;
+}
+
+function alterBidRequests(reqBidsConfigObj, callback, config, userConsent) {
+ // do stuff
+ // put data in AdUnit.fpd.* or rtd.RTDPROVIDERCODE.*
+ callback();
+}
+
+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.
+
+**Code Example**
+
+Here is a code example with both mandatory and optional functions:
+{% highlight text %}
+/** @type {RtdSubmodule} */
+export const subModuleObj = {
+ name: 'ExampleRTDModule3',
+ init: init,
+ onAuctionInitEvent: onAuctionInit,
+ onAuctionEndEvent: onAuctionEnd,
+ onBidResponseEvent: onBidResponse
+};
+
+function onAuctionInit(auctionDetails, config, userConsent) {
+ // inspect/update auction details
+}
+
+function onAuctionEnd(auctionDetails, config, userConsent) {
+ // take note of auction end
+}
+
+function onBidResponse(bidResponse, config, userConsent) {
+ //optionally update bidResponse
+}
+
+function init(config, userConsent) {
+ // do init stuff
+ if (initfailed) return false;
+ return true;
+}
+
+function beforeInit(){
+ //take actions to get data as soon as possible
+ submodule('realTimeData', subModuleObj);
+}
+
+beforeInit();
+{% endhighlight %}
+
+
+### Step 3: Add unit tests
+
+1. Create a JS file under `test/spec/modules` with the name of the bidder suffixed with 'RtdProvider_spec', e.g., `exRtdProvider_spec.js`
+
+2. Write great unit tests. See the other `RtdProvider_spec.js` files for examples.
+
+### Step 4: Submit the code
+
+Once everything looks good, submit the code, tests, and markdown as a pull request to the [Prebid.js repo](https://github.com/prebid/Prebid.js).
+
+### Step 5: Website pull request
+
+1. Create a fork of the [website repo](https://github.com/prebid/prebid.github.io) and a branch for your new adapter. (e.g. feature/exRtdProvider)
+
+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:
+
+ ```
+ ---
+ layout: page_v2
+ title: Example Module
+ description: Useful statement for what this does
+ page_type: module
+ module_type: rtd
+ module_code : example
+ enable_download : true
+ sidebarType : 1
+ ---
+
+ # Example Module
+
+ [Useful publisher-facing documentation]
+ ```
+3. Submit the pull request to the prebid.github.io repo.
+
+### Step 6: Wait for Prebid volunteers to review
+
+We sometimes get pretty busy, so it can take a couple of weeks for the review process to complete, so while you're waiting, consider [joining Prebid.org](https://prebid.org/membership/) to help us out with code reviews. (!)
diff --git a/dev-docs/bidder-adaptor.md b/dev-docs/bidder-adaptor.md
index 1ee40082b3..9252ed1066 100644
--- a/dev-docs/bidder-adaptor.md
+++ b/dev-docs/bidder-adaptor.md
@@ -303,8 +303,9 @@ Referrer information should be passed to your endpoint in contexts where the ori
- `referer`: a string containing the detected top-level URL.
- `reachedTop`: a boolean specifying whether Prebid was able to walk up to the top window.
- `numIframes`: the number of iFrames.
-- `stack`: a string of comma-separated URLs of all origins.
+- `stack`: an array of URLs of all windows from the top window down to the current window.
- `canonicalUrl`: a string containing the canonical (search engine friendly) URL defined in top-most window.
+- `isAmp`: a boolean specifying whether the detected referer was determined based on AMP page information.
The URL returned by `refererInfo` is in raw format. We recommend encoding the URL before adding it to the request payload to ensure it will be sent and interpreted correctly.
diff --git a/dev-docs/bidders.md b/dev-docs/bidders.md
index dfa96bd249..871c676bb2 100644
--- a/dev-docs/bidders.md
+++ b/dev-docs/bidders.md
@@ -51,6 +51,7 @@ You can also download the full CSV
| **Safeframes OK** | {% if page.safeframes_ok == false %}no{% elsif page.safeframes_ok == true %}yes{% else %}check with bidder{% endif %} | **USP/CCPA Support** | {% if page.usp_supported == true %}yes{% else %}no{% endif %} |
| **Supports Deals** | {% if page.bidder_supports_deals == false %}no{% elsif page.bidder_supports_deals == true %}yes{% else %}check with bidder{% endif %} | **Prebid.js Adapter** | yes |
| **IAB GVL ID** | {% if page.gvl_id %}{{page.gvl_id}}{% else %}check with bidder{% endif %} | **Prebid Server Adapter** | {% if page.pbs == true %}yes{% else %}no{% endif %} |
+| **Floors Module Support** | {% if page.getFloor == true %}yes{% else %}no{% endif %} |
+
+
+```
+
+### Example page with In-Image and GPT
+
+```html
+
+
+
+
+ Prebid.js Banner Example
+
+
+
+
+
+
+
Prebid.js Banner Ad Unit Test
+
+
+
+
+
+
+
+
+```
diff --git a/dev-docs/bidders/improvedigital.md b/dev-docs/bidders/improvedigital.md
index 530c48e7c4..baf43d571e 100644
--- a/dev-docs/bidders/improvedigital.md
+++ b/dev-docs/bidders/improvedigital.md
@@ -6,6 +6,7 @@ biddercode: improvedigital
pbjs: true
pbs: true
gdpr_supported: true
+userIds: criteo, id5Id
usp_supported: true
media_types: banner, native, video
schain_supported: true
diff --git a/dev-docs/bidders/indexExchange.md b/dev-docs/bidders/indexExchange.md
index 5ed73f868a..6c3dfef6dd 100644
--- a/dev-docs/bidders/indexExchange.md
+++ b/dev-docs/bidders/indexExchange.md
@@ -305,6 +305,27 @@ pbjs.setConfig({
});
```
+#### The **detectMissingSizes** feature
+By default, the IX bidding adapter bids on all banner sizes available in the ad unit when configured to at least one banner size. If you want the IX bidding adapter to only bid on the banner size it’s configured to, switch off this feature using `detectMissingSizes`.
+```
+pbjs.setConfig({
+ ix: {
+ detectMissingSizes: false
+ }
+ });
+```
+OR
+```
+pbjs.setBidderConfig({
+ bidders: ["ix"],
+ config: {
+ ix: {
+ detectMissingSizes: false
+ }
+ }
+ });
+```
+
### 2. Include `ixBidAdapter` in your build process
When running the build command, include `ixBidAdapter` as a module, as well as `dfpAdServerVideo` if you require video support.
diff --git a/dev-docs/bidders/inmobi.md b/dev-docs/bidders/inmobi.md
index 6c6a6ce60f..aa35cd4f72 100644
--- a/dev-docs/bidders/inmobi.md
+++ b/dev-docs/bidders/inmobi.md
@@ -5,7 +5,7 @@ description: InMobi Bidder Adapter
biddercode: inmobi
gdpr_supported: true
tcf2_supported: true
-usp_supported: true
+usp_supported: false
gvl_id: 333
coppa_supported: true
media_types: banner, video
diff --git a/dev-docs/bidders/ironsource.md b/dev-docs/bidders/ironsource.md
index 126b2900d9..3c2add5d2f 100644
--- a/dev-docs/bidders/ironsource.md
+++ b/dev-docs/bidders/ironsource.md
@@ -24,6 +24,7 @@ The IronSource adapter requires setup and approval. Please reach out to prebid-d
| `isOrg` | required | String | IronSource publisher Id provided by your IronSource representative | "56f91cd4d3e3660002000033"
| `floorPrice` | optional | Number | Minimum price in USD.
**WARNING:** Misuse of this parameter can impact revenue | 2.00
| `ifa` | optional | String | The ID for advertisers (also referred to as "IDFA") | "XXX-XXX"
+| `testMode` | optional | Boolean | This activates the test mode | false
## Example
```javascript
@@ -43,6 +44,7 @@ var adUnits = [
isOrg: '56f91cd4d3e3660002000033', // Required
floorPrice: 5.00, // Optional
ifa: 'XXX-XXX', // Optional
+ testMode: false // Optional
}
}]
}
diff --git a/dev-docs/bidders/krushmedia.md b/dev-docs/bidders/krushmedia.md
index b4b5645313..90b4734ed9 100644
--- a/dev-docs/bidders/krushmedia.md
+++ b/dev-docs/bidders/krushmedia.md
@@ -7,7 +7,7 @@ usp_supported: true
schain_supported: true
media_types: banner, video, native
gdpr: true
-pbjs: false
+pbjs: true
pbs: true
---
diff --git a/dev-docs/bidders/lunamediahb.md b/dev-docs/bidders/lunamediahb.md
new file mode 100644
index 0000000000..532de24c7d
--- /dev/null
+++ b/dev-docs/bidders/lunamediahb.md
@@ -0,0 +1,19 @@
+---
+layout: bidder
+title: LunamediaHB
+description: Prebid Lunamedia Bidder Adapter
+biddercode: lunamediahb
+usp_supported: true
+schain_supported: true
+media_types: banner, video, native
+gdpr: true
+pbjs: true
+pbs: false
+---
+
+### Prebid.Server Bid Params
+
+{: .table .table-bordered .table-striped }
+| Name | Scope | Description | Example | Type |
+|----------------|----------|----------------------------------------------------------|------------|-----------|
+| `placementId` | required | Placement Id will be generated on Lunamedia Platform. | `'0'` | `string` |
\ No newline at end of file
diff --git a/dev-docs/bidders/medianet.md b/dev-docs/bidders/medianet.md
index aae788d2ba..4bc48cd24b 100644
--- a/dev-docs/bidders/medianet.md
+++ b/dev-docs/bidders/medianet.md
@@ -53,7 +53,7 @@ var videoAdUnit = {
code: 'video1',
mediaTypes: {
video: {
- context: "outstream",
+ context: "instream",
playerSize: [640, 480]
}
},
diff --git a/dev-docs/bidders/mediasquare.md b/dev-docs/bidders/mediasquare.md
index 386f1a6519..41e621033e 100644
--- a/dev-docs/bidders/mediasquare.md
+++ b/dev-docs/bidders/mediasquare.md
@@ -9,7 +9,8 @@ tcf2_supported: true
usp_supported: true
schain_supported: true
userIds: id5Id
-media_types: banner
+media_types: banner, video, native
+glv_id: 791
---
diff --git a/dev-docs/bidders/mobilefuse.md b/dev-docs/bidders/mobilefuse.md
index 588845dbf3..ab6ef240b7 100644
--- a/dev-docs/bidders/mobilefuse.md
+++ b/dev-docs/bidders/mobilefuse.md
@@ -10,6 +10,7 @@ coppa_supported: true
biddercode: mobilefuse
ccpa_supported: true
prebid_member: true
+tcf2_supported: true
---
### Bid Params
diff --git a/dev-docs/bidders/nobidBidAdapter.md b/dev-docs/bidders/nobidBidAdapter.md
index 245f99075b..ed95d1aad9 100644
--- a/dev-docs/bidders/nobidBidAdapter.md
+++ b/dev-docs/bidders/nobidBidAdapter.md
@@ -4,12 +4,16 @@ title: Nobid
description: Prebid Nobid Bidder Adaptor
biddercode: nobid
pbjs: true
+pbs: true
media_types: banner, video
gdpr_supported: true
+tcf2_supported: true
+gvl_id: 816
usp_supported: true
schain_supported: true
coppa_supported: true
-tcf2_supported: true
+userId: criteo, unifiedId, id5Id
+safeframes_ok: true
---
### Bid Params
@@ -19,7 +23,7 @@ tcf2_supported: true
|---------------|----------|-------------|---------|----------|
| `siteId` | required | siteId is provided by your NoBid account manager(s) | | `integer` |
| `placementId` | optional | placementId is provided by your NoBid account manager(s). This parameter allows to report on a specific ad unit | | `integer` |
-| `video`| optional | Object containing video targeting parameters. See [Video Object](#nobid-video-object) for details. | `video: { playback_method: ['auto_play_sound_off'] }` | `object`|
+| `video`| optional | Object containing video targeting parameters. Note that this parameter is not used in Prebid Server. See [Video Object](#nobid-video-object) for details. | `video: { playback_method: ['auto_play_sound_off'] }` | `object`|
### Note
diff --git a/dev-docs/bidders/onetag.md b/dev-docs/bidders/onetag.md
index c4b951ce46..edf1e64a26 100644
--- a/dev-docs/bidders/onetag.md
+++ b/dev-docs/bidders/onetag.md
@@ -6,6 +6,8 @@ pbjs: true
biddercode: onetag
media_types: banner, video
gdpr_supported: true
+tcf2_supported: true
+gvl_id: 241
usp_supported: true
userIds: britepoolId, criteo, id5Id, identityLink, liveIntentId, netId, parrableId, pubCommonId, unifiedId
---
diff --git a/dev-docs/bidders/openx.md b/dev-docs/bidders/openx.md
index d0cc3bc5ee..4d52acbe32 100644
--- a/dev-docs/bidders/openx.md
+++ b/dev-docs/bidders/openx.md
@@ -10,6 +10,7 @@ schain_supported: true
gdpr_supported: true
usp_supported: true
coppa_supported: true
+getFloor: true
userIds: britepoolId, criteo, id5Id, identityLink, liveIntentId, netId, parrableId, pubCommonId, unifiedId
prebid_member: true
tcf2_supported: true
diff --git a/dev-docs/bidders/pubmatic.md b/dev-docs/bidders/pubmatic.md
index 33cdc6ec8b..7bd79e1832 100644
--- a/dev-docs/bidders/pubmatic.md
+++ b/dev-docs/bidders/pubmatic.md
@@ -8,7 +8,8 @@ gdpr_supported: true
usp_supported: true
coppa_supported: true
schain_supported: true
-userIds: britepoolId, criteo, id5Id, identityLink, liveIntentId, netId, parrableId, pubCommonId, unifiedId
+getFloor: true
+userIds: all
prebid_member: true
safeframes_ok: true
tcf2_supported: true
diff --git a/dev-docs/bidders/pubwise.md b/dev-docs/bidders/pubwise.md
new file mode 100644
index 0000000000..dcbdc2a2eb
--- /dev/null
+++ b/dev-docs/bidders/pubwise.md
@@ -0,0 +1,83 @@
+---
+layout: bidder
+title: PubWise
+description: PubWise Bidder Adaptor
+pbjs: true
+biddercode: pwbid
+media_types: banner, native
+gdpr_supported: true
+gvl_id: 842
+---
+
+### Note:
+The PubWise bid adapter requires approval. Visit http://www.PubWise.io/ to get started.
+
+### Bid params
+
+{: .table .table-bordered .table-striped }
+| Name | Scope | Description | Example | Type |
+|--------------|----------|---------------------------------------------------------------------------------------------------|--------------------------|-----------|
+| `siteId` | required | The site ID provided by the PubWise system | `'XXXXXX'` | `string` |
+| `bidFloor` | optional | Value to pass as the bidfloor for this bid | `2.50` | `currency` |
+| `isTest` | optional | A boolean to indicate 100% fill test placement request | `false` | `boolean` |
+
+### Example
+
+#### Banner
+```
+var adUnits = [
+ {
+ code: "div-gpt-ad-1460505748561-0",
+ mediaTypes: {
+ banner: {
+ sizes: [[300, 250]]
+ }
+ },
+ bids: [{
+ bidder: 'pwbid',
+ params: {
+ siteId: "xxxxxx",
+ isTest: true
+ }
+ }]
+ }
+]
+```
+#### Native
+
+```
+var adUnits = [
+ {
+ code: 'div-gpt-ad-1460505748561-1',
+ sizes: [[1, 1]],
+ mediaTypes: {
+ native: {
+ title: {
+ required: true,
+ len: 80
+ },
+ body: {
+ required: true
+ },
+ image: {
+ required: true,
+ sizes: [150, 50]
+ },
+ sponsoredBy: {
+ required: true
+ },
+ icon: {
+ required: false
+ }
+ }
+ },
+ bids: [{
+ bidder: 'pwbid',
+ params: {
+ siteId: "xxxxxx",
+ isTest: true,
+ },
+ }]
+ }
+]
+```
diff --git a/dev-docs/bidders/quantumdex.md b/dev-docs/bidders/quantumdex.md
index 4e8ae33dac..01e828a9c8 100644
--- a/dev-docs/bidders/quantumdex.md
+++ b/dev-docs/bidders/quantumdex.md
@@ -4,6 +4,7 @@ title: Quantumdex
description: Prebid Quantum Digital Exchange Bidder Adapter
pbjs: true
biddercode: quantumdex
+aliasCode: apacdex
media_types: banner, video
gdpr_supported: true
tcf2_supported: true
diff --git a/dev-docs/bidders/qwarry.md b/dev-docs/bidders/qwarry.md
new file mode 100644
index 0000000000..228684eccb
--- /dev/null
+++ b/dev-docs/bidders/qwarry.md
@@ -0,0 +1,18 @@
+---
+layout: bidder
+title: Qwarry
+description: Prebid Qwarry Bidder Adaptor
+biddercode: qwarry
+media_types: banner, video
+pbjs: true
+---
+
+
+
+### Bid Params
+
+{: .table .table-bordered .table-striped }
+| Name | Scope | Description | Example | Type |
+|-------------|----------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------|------------------------------------------|-----------|
+| `zoneToken` | required | The ID issued by Qwarry to the publisher | `'8a80d8e9-0cf9-4329-8486-6f5bbcd8a61a'` | `string` |
+| `pos` | optional | Specify the position of the ad as a relative measure of visibility or prominence. Allowed values: Above the fold: `1`; Below the fold: `3`; Middle of the fold: `7`; | `0` | `integer` |
\ No newline at end of file
diff --git a/dev-docs/bidders/rubicon.md b/dev-docs/bidders/rubicon.md
index 9445015b89..1d52c492ad 100644
--- a/dev-docs/bidders/rubicon.md
+++ b/dev-docs/bidders/rubicon.md
@@ -8,8 +8,9 @@ tcf2_supported: true
usp_supported: true
coppa_supported: true
schain_supported: true
+getFloor: true
media_types: video
-userIds: identityLink, liveIntentId, unifiedId
+userIds: all
prebid_member: true
safeframes_ok: true
bidder_supports_deals: true
@@ -31,13 +32,13 @@ For both Prebid.js and Prebid Server, the Rubicon Project adapter requires setup
| `siteId` | required | The site ID | `'13945'` | `string` |
| `zoneId` | required | The zone ID | `'23948'` | `string` |
| `sizes` | optional | Array of Rubicon Project size IDs. If not specified, the system will try to convert from the AdUnit's mediaTypes.banner.sizes. | `[15]` | `Array` |
-| `keywords` | optional | Array of page-specific keywords. May be referenced in Rubicon Project reports. | `['travel', 'tourism']` | `Array` |
-| `inventory` | optional | An object defining arbitrary key-value pairs concerning the page for use in targeting. The values must be arrays. | `{"rating":["5-star"], "prodtype":["tech","mobile"]}` | `object` |
-| `visitor` | optional | An object defining arbitrary key-value pairs concerning the visitor for use in targeting. The values must be arrays. | `{"ucat":["new"], "search":["iphone"]}` | `object` |
| `position` | optional | Set the page position. Valid values are "atf" and "btf". | `'atf'` | `string` |
| `userId` | optional | Site-specific user ID may be reflected back in creatives for analysis. Note that userId needs to be the same for all slots. | `'12345abc'` | `string` |
| `floor` | optional | Sets the global floor -- no bids will be made under this value. | `0.50` | `float` |
| `latLong` | optional | Sets the latitude and longitude for the visitor (avail since PBJS 1.10) | `[40.7608, 111.8910]` | `Array` |
+| `inventory` | optional | Please consider using the [First Party Data feature](/features/firstPartyData.html), e.g. AdUnit.fpd.context.data.ATTR. 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. | `{"rating":["5-star"], "prodtype":["tech","mobile"]}` | `object` |
+| `visitor` | optional | Please consider using the [First Party Data feature](/features/firstPartyData.html), e.g. AdUnit.fpd.user.data.ATTR. 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. | `{"ucat":["new"], "search":["iphone"]}` | `object` |
+| `keywords` | optional | Deprecated - please use the [First Party Data feature](/features/firstPartyData.html), e.g. AdUnit.fpd.context.data.keywords. This is a legacy parameter that only works 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` |
diff --git a/dev-docs/bidders/selectmedia.md b/dev-docs/bidders/selectmedia.md
index 0dc5f79eba..9b582590ed 100644
--- a/dev-docs/bidders/selectmedia.md
+++ b/dev-docs/bidders/selectmedia.md
@@ -1,6 +1,6 @@
---
layout: bidder
-title: Select Media
+title: Select Media Display
description: Prebid Select Media Bidder Adapter
pbjs: true
biddercode: selectmedia
diff --git a/dev-docs/bidders/sharethrough.md b/dev-docs/bidders/sharethrough.md
index da77260c49..9c7293b22a 100644
--- a/dev-docs/bidders/sharethrough.md
+++ b/dev-docs/bidders/sharethrough.md
@@ -8,7 +8,7 @@ media_types : native
schain_supported: true
tcf2_supported : true
title : Sharethrough
-userIds : unifiedId
+userIds : pubCommonId, unifiedId
usp_supported : true
pbjs : true
pbs : true
diff --git a/dev-docs/bidders/silvermob.md b/dev-docs/bidders/silvermob.md
new file mode 100644
index 0000000000..eb8f2b155a
--- /dev/null
+++ b/dev-docs/bidders/silvermob.md
@@ -0,0 +1,23 @@
+---
+layout: bidder
+title: SilverMob
+description: SilverMob Bidder Adapter
+biddercode: silvermob
+gdpr_supported: true/false
+media_types: banner, video, native
+pbjs: false
+pbs: true
+prebid_member: false
+---
+
+### Note:
+
+The SilverMob Bidding adapter requires setup before beginning. Please contact us at partners@silvermob.com
+
+### Bid Params
+
+{: .table .table-bordered .table-striped }
+| Name | Scope | Description | Example | Type |
+|---------------|----------|-----------------------|-----------|-----------|
+| `zoneid` | required | Placement id | `'3011'` | `string` |
+| `host` | required | Data center location | `'us'` | `string` |
\ No newline at end of file
diff --git a/dev-docs/bidders/smaato.md b/dev-docs/bidders/smaato.md
index eb1ad9b442..791b2532fe 100644
--- a/dev-docs/bidders/smaato.md
+++ b/dev-docs/bidders/smaato.md
@@ -8,8 +8,10 @@ tcf2_supported: true
usp_supported: true
coppa_supported: true
media_types: banner, video
+userIds: criteo, pubCommonId, unifiedId
pbjs: true
pbs: true
+prebid_member: true
---
### Table of Contents
diff --git a/dev-docs/bidders/smartadserver.md b/dev-docs/bidders/smartadserver.md
index 580a5c6937..545fd4b081 100644
--- a/dev-docs/bidders/smartadserver.md
+++ b/dev-docs/bidders/smartadserver.md
@@ -8,7 +8,7 @@ gdpr_supported: true
schain_supported: true
tcf2_supported: true
usp_supported: true
-userIds: britepoolId, criteo, digitrust, id5Id, identityLink, liveIntentId, netId, parrableId, pubCommonId, unifiedId
+userIds: britepoolId, criteo, id5Id, identityLink, liveIntentId, netId, parrableId, pubCommonId, unifiedId
pbjs: true
pbs: true
---
diff --git a/dev-docs/bidders/smartx.md b/dev-docs/bidders/smartx.md
index 6f7eee5c46..56b9e0b465 100644
--- a/dev-docs/bidders/smartx.md
+++ b/dev-docs/bidders/smartx.md
@@ -6,9 +6,9 @@ biddercode: smartx
media_types: no-display, video
gdpr_supported: true
tcf2_supported: true
-userIds: id5Id, pubCommonId
+userIds: none
prebid_member: true
-schain_supported: true
+schain_supported: false
usp_supported: true
safeframes_ok: false
pbjs: true
diff --git a/dev-docs/bidders/smartyads.md b/dev-docs/bidders/smartyads.md
index 540885edac..fa9328221b 100644
--- a/dev-docs/bidders/smartyads.md
+++ b/dev-docs/bidders/smartyads.md
@@ -2,21 +2,30 @@
layout: bidder
title: SmartyAds
description: Prebid SmartyAds Bidder Adaptor
-pbjs: true
biddercode: smartyads
-media_types: native
+gdpr_supported: true
+tcf2_supported: true
+usp_supported: true
+coppa_supported: true
+schain_supported: true
+userId: (list of supported vendors)
+media_types: banner, video, native
+safeframes_ok: true
+bidder_supports_deals: true
+pbjs: true
+pbs: true
---
-### Bid Params Prebid 0.34
+### Note:
-{: .table .table-bordered .table-striped }
-| Name | Scope | Description | Example | Type |
-|-------------|----------|-------------|---------|----------|
-| `banner_id` | required | | | `string` |
+The Example Bidding adapter requires setup before beginning. Please contact us at sales@smartyads.com
-### Bid Params Prebid 1.x
+### Bid Params
{: .table .table-bordered .table-striped }
-| Name | Scope | Description | Example | Type |
-|---------------|----------|-------------|---------|----------|
-| `placementId` | required | | | `string` |
+| Name | Scope | Description | Example | Type |
+|---------------|----------|-----------------------|-----------|-----------|
+| `placementId` | required (for prebid.js) | placement Id | `'0'` | `string` |
+| `host` | required (for prebid-server) | Region id | `'ns1'` | `string` |
+| `sourceid` | required (for prebid-server) | Partner id | `'smartyads'` | `string` |
+| `accountid` | required (for prebid-server) | Endpoint id | `'hash'` | `string` |
diff --git a/dev-docs/bidders/sonobi.md b/dev-docs/bidders/sonobi.md
index 6aa0616ff4..6d0643895c 100644
--- a/dev-docs/bidders/sonobi.md
+++ b/dev-docs/bidders/sonobi.md
@@ -8,6 +8,7 @@ gdpr_supported: true
userIds: britepoolId, criteo, id5Id, identityLink, liveIntentId, netId, parrableId, pubCommonId, unifiedId
pbjs: true
pbs: true
+tcf2_supported: true
---
### Note:
diff --git a/dev-docs/bidders/sovrn.md b/dev-docs/bidders/sovrn.md
index 45d6a7041f..4f93125bf1 100644
--- a/dev-docs/bidders/sovrn.md
+++ b/dev-docs/bidders/sovrn.md
@@ -6,10 +6,12 @@ pbjs: true
pbs: true
biddercode: sovrn
gdpr_supported: true
+tcf2_supported: true
usp_supported: true
-userIds: unifiedId
+userIds: britepoolId, criteo, id5Id, liveIntentId, netId, parrableId, pubCommonId, sharedId, unifiedId
prebid_member: true
schain_supported: true
+gvl_id: 13
---
### Bid Params
diff --git a/dev-docs/bidders/sspBCAdapter.md b/dev-docs/bidders/sspBCAdapter.md
index beb818194c..357636a711 100644
--- a/dev-docs/bidders/sspBCAdapter.md
+++ b/dev-docs/bidders/sspBCAdapter.md
@@ -2,11 +2,12 @@
layout: bidder
title: sspBC
description: Prebid sspBC Bidder Adaptor
-
+pbjs: true
biddercode: sspBC
media_types: banner
gdpr_supported: true
tcf2_supported: true
+gvl_id: 676
---
@@ -19,4 +20,4 @@ tcf2_supported: true
| `siteId` | required | site id | `'235911'` | `string` |
| `domain` | optional | site domain | `'somesite.com'` | `string` |
| `page` | optional | page url | `'somesite.com/index.html'` | `string` |
-| `tmax` | optional | tmax for server connection | `250` | `integer` |
+| `tmax` | optional | tmax for server connection | `400` | `integer` |
diff --git a/dev-docs/bidders/stroeerCore.md b/dev-docs/bidders/stroeerCore.md
new file mode 100644
index 0000000000..affaac4de6
--- /dev/null
+++ b/dev-docs/bidders/stroeerCore.md
@@ -0,0 +1,49 @@
+---
+layout: bidder
+title: StroeerCore
+description: Stroeer Bidder Adapter
+biddercode: stroeerCore
+media_types: banner
+gdpr_supported: false
+schain_supported: false
+coppa_supported: false
+usp_supported: false
+tcf2_supported: true
+safeframes_ok: true
+prebid_member: false
+pbjs: true
+pbs: false
+gvl_id: 136
+bidder_supports_deals: true
+---
+
+### Bid Params
+
+{: .table .table-bordered .table-striped }
+| Name | Scope | Description | Example | Type |
+|---------------|----------|--------------------|------------------------------|----------|
+| `sid` | required | Slot ID | `'06b782cc-091b-4f53-9cd2-0291679aa1ac'`| `string` |
+
+### Config Notes
+
+* Slot id (`sid`) is required. The adapter will ignore bid requests from prebid if `sid` is not provided. This must be in the decoded form. For example, "1234" as opposed to "MTM0ODA=".
+* The server ignores dimensions that are not supported by the slot or by the platform (such as 987x123).
+
+### Ad unit configuration for publishers
+
+```javascript
+const adUnits = [{
+ code: 'div-gpt-ad-1460505748561-0',
+ mediaTypes: {
+ banner: {
+ sizes: [[300, 250]],
+ }
+ },
+ bids: [{
+ bidder: 'stroeerCore',
+ params: {
+ sid: "06b782cc-091b-4f53-9cd2-0291679aa1ac"
+ }
+ }]
+}];
+```
diff --git a/dev-docs/bidders/teads.md b/dev-docs/bidders/teads.md
index 851278f9cc..adab71c25e 100644
--- a/dev-docs/bidders/teads.md
+++ b/dev-docs/bidders/teads.md
@@ -9,6 +9,8 @@ tcf2_supported: true
usp_supported: true
schain_supported: true
media_types: banner, video
+gvl_id: 132
+bidder_supports_deals: true
---
### Note:
diff --git a/dev-docs/bidders/triplelift.md b/dev-docs/bidders/triplelift.md
index 308df7dfaf..e4eedb63e0 100644
--- a/dev-docs/bidders/triplelift.md
+++ b/dev-docs/bidders/triplelift.md
@@ -6,11 +6,13 @@ gdpr_supported: true
tcf2_supported: true
usp_supported: true
schain_supported: true
+getFloor: true
coppa_supported: true
biddercode: triplelift
userIds: criteo, identityLink, unifiedId
pbjs: true
pbs: true
+pbjs_version_notes: avoid 4.3 - 4.14
---
### Bid Params
diff --git a/dev-docs/bidders/undertone.md b/dev-docs/bidders/undertone.md
index a4257053e6..94d743d670 100644
--- a/dev-docs/bidders/undertone.md
+++ b/dev-docs/bidders/undertone.md
@@ -17,7 +17,7 @@ pbjs: true
{: .table .table-bordered .table-striped }
| Name | Scope | Description | Example | Type |
|---------------|----------|-------------------------------------------|------------|-----------|
-| `placementId` | optional | Your placement ID (provided by undertone) | `"13as14d0"` | `string` |
+| `placementId` | required | Your placement ID (provided by undertone) | `"13as14d0"` | `string` |
| `publisherId` | required | publisher ID (provided by undertone) | `12345` | `integer` |
@@ -30,6 +30,7 @@ pbjs: true
| `maxDuration` | optional | Maximum video ad duration in seconds. | `30` | `integer` |
| `skippable` | optional | Skippability of the inventory. Possible values: `true` - only skippable inventory is allowed, `false` - skippable inventory is not allowed, null/missing - all inventory is allowed (default value). | `true` | `boolean` |
+Supported from version 3.27.0 and above
### Configuration
diff --git a/dev-docs/bidders/valueimpression.md b/dev-docs/bidders/valueimpression.md
index b8b8d25e11..77580ada76 100644
--- a/dev-docs/bidders/valueimpression.md
+++ b/dev-docs/bidders/valueimpression.md
@@ -4,7 +4,7 @@ title: Valueimpression
description: Prebid Valueimpression Bidder Adapter
pbjs: true
biddercode: valueimpression
-aliasCode: quantumdex
+aliasCode: apacdex
media_types: banner, video
gdpr_supported: true
tcf2_supported: true
diff --git a/dev-docs/bidders/vidazoo.md b/dev-docs/bidders/vidazoo.md
index 36ccb01c8d..441f121170 100644
--- a/dev-docs/bidders/vidazoo.md
+++ b/dev-docs/bidders/vidazoo.md
@@ -3,7 +3,7 @@ layout: bidder
title: Vidazoo
description: Prebid Vidazoo Bidder Adaptor
biddercode: vidazoo
-userIds: britepoolId, criteo, digitrust, id5Id, identityLink, liveIntentId, netId, parrableId, pubCommonId, unifiedId
+userIds: britepoolId, criteo, id5Id, identityLink, liveIntentId, netId, parrableId, pubCommonId, unifiedId
gdpr_supported: true
usp_supported: true
pbjs: true
diff --git a/dev-docs/bidders/videonow.md b/dev-docs/bidders/videonow.md
index 4d22e4c26e..11eab677fd 100644
--- a/dev-docs/bidders/videonow.md
+++ b/dev-docs/bidders/videonow.md
@@ -2,6 +2,7 @@
layout: bidder
title: videonow
description: Prebid Videonow Bidder Adaptor
+biddercode: videonow
pbjs: true
media_types: banner
---
diff --git a/dev-docs/bidders/vuukle.md b/dev-docs/bidders/vuukle.md
new file mode 100644
index 0000000000..e1a9561379
--- /dev/null
+++ b/dev-docs/bidders/vuukle.md
@@ -0,0 +1,14 @@
+---
+layout: bidder
+title: Vuukle
+description: vuukle bid adapter
+pbjs: true
+biddercode: vuukle
+---
+
+### Bid Params
+
+{: .table .table-bordered .table-striped }
+| Name | Scope | Description | Example | Type |
+|-------------+----------+-----------------------------------+----------|----------|
+| `placement` | optional | Placement id, provided by vuukle | `'1'` | `string` |
diff --git a/dev-docs/bidders/yieldmo.md b/dev-docs/bidders/yieldmo.md
index 1ebe78694d..97b8a53548 100644
--- a/dev-docs/bidders/yieldmo.md
+++ b/dev-docs/bidders/yieldmo.md
@@ -3,7 +3,7 @@ layout: bidder
title: Yieldmo
description: Prebid Yieldmo Bidder Adaptor
biddercode: yieldmo
-media_types: banner
+media_types: banner, video
userIds: pubCommonId, unifiedId, criteo
gdpr_supported: true
usp_supported: true
@@ -18,7 +18,66 @@ pbs: true
### Bid Params
{: .table .table-bordered .table-striped }
-| Name | Scope | Description | Example | Type |
-|---------------|----------|----------------------|---------------------------|----------|
+| Name | Scope | Description | Example | Type |
+|---------------|----------|----------------------|------------------------|----------|
| `placementId` | required | Yieldmo placement id | `'825209316101005155'` | `string` |
| `bidFloor` | optional | Bid Floor | `0.1` | `float` |
+
+### video parameters
+The Yieldmo adapter supports video as of Prebid v4.18.
+
+{: .table .table-bordered .table-striped }
+| Name | Scope | Description | Example | Type |
+|-------------------|----------|--------------------------------------------------------|-----------------|-----------|
+| `placement` | required | Video placement type. In-Stream: `1`; In-Banner: `2`; In-Article: `3`: In-Feed: `4`; Interstitial: `5`; see [OpenRTB 2.5 specification](https://www.iab.com/wp-content/uploads/2016/03/OpenRTB-API-Specification-Version-2-5-FINAL.pdf), List 5.9 for more details | `1` | `integer` |
+| `maxduration` | required | Maximum ad duration in seconds | `20` | `integer` |
+| `minduration` | optional | Minimum ad duration in seconds | `5` | `integer` |
+| `pos` | optional | Ad position on screen; see [OpenRTB 2.5 specification](https://www.iab.com/wp-content/uploads/2016/03/OpenRTB-API-Specification-Version-2-5-FINAL.pdf), List 5.4 for more details | `1` | `integer` |
+| `startdelay` | required if placement == 1 | Duration offset (in second) from the start of the content for showing the video ad before the start of the Video. Pre-roll: `0` (default); Mid-roll: `>0`; Default mid-roll: `-1`; Post-roll: `-2`; | `5` | `integer` |
+| `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`; | `[2, 3]` | `Array` |
+| `api` | required | API frameworks supported. VPAID 1.0: `1`; VPAID 2.0: `2`; MRAID-1: `3`; ORMMA: `4`; MRAID-2: `5`; MRAID-3: `6`; | `[1, 2]` | `Array` |
+| `playbackmethod` | required | Playback methods that may be in use; see [OpenRTB 2.5 specification](https://www.iab.com/wp-content/uploads/2016/03/OpenRTB-API-Specification-Version-2-5-FINAL.pdf), List 5.10 for more details | `[2,6]` | `Array` |
+| `skippable` | optional | If 'true', user can skip ad | `true` | `boolean` |
+| `skipafter` | optional | Number of seconds a video must play before skipping is enabled; only applicable if the ad is `skippable` | `5` | `integer` |
+
+In addition, Yieldmo adapter relies on parameters specified in the `mediaTypes.video` definition of the video ad-units, namely:
+
+{: .table .table-bordered .table-striped }
+| Name | Scope | Description | Example | Type |
+|-------------------|----------|--------------------------------------------------------|-----------------|------------------|
+| `playerSize` | required | Width and height of the player | `[640, 480]` | `Array` |
+| `context` | required | Only `instream` is supported | `instream` | `string` |
+| `mimes` | required | List of the content MIME types supported by the player | `["video/mp4"]` | `Array` |
+
+
+### Example of Video Ad-unit
+```javascript
+var videoAdUnits = [{
+ code: 'div-video-ad-1234567890',
+ mediaTypes: {
+ video: {
+ playerSize: [640, 480], // required
+ context: 'instream',
+ mimes: ['video/mp4'] // required, array of strings
+ }
+ },
+ bids: [{
+ bidder: 'yieldmo',
+ params: {
+ placementId: '1524592390382976659', // required
+ video: {
+ placement: 1, // required, integer
+ maxduration: 30, // required, integer
+ minduration: 15, // optional, integer
+ pos: 1, // optional, integer
+ startdelay: 10, // required if placement == 1
+ protocols: [2, 3], // required, array of integers
+ api: [2, 3], // required, array of integers
+ playbackmethod: [2,6], // required, array of integers
+ skippable: true, // optional, boolean
+ skipafter: 10 // optional, integer
+ }
+ }
+ }]
+}];
+```
diff --git a/dev-docs/bidders/zetaGlobal.md b/dev-docs/bidders/zetaGlobal.md
new file mode 100644
index 0000000000..1191270a93
--- /dev/null
+++ b/dev-docs/bidders/zetaGlobal.md
@@ -0,0 +1,26 @@
+---
+layout: bidder
+title: Zeta Global
+description: Zeta Global Prebid Bidder Adapter
+pbjs: true
+biddercode: zeta_global
+bidder_supports_deals: false
+media_types: banner
+gdpr_supported: true
+tcf2_supported: true
+gvl_id: 469
+---
+
+### Registration
+
+To use this bidder you will need a valid definerId. For further information, please contact jzirbel@disqus.com.
+
+### Bid Params
+
+{: .table .table-bordered .table-striped }
+| Name | Scope | Description | Example | Type |
+|-------------|----------|---------------------------------------------------------------------------------------------------------------------|-----------|-----------|
+| `ip` | required | The client IP | `0.0.0.0` | `string` |
+| `buyeruid` | required | Zeta's user id | `12345` | `string` |
+| `definerId` | required | The Definer ID from Zeta Global | `12345` | `string` |
+| `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` |
diff --git a/dev-docs/cmp-best-practices.md b/dev-docs/cmp-best-practices.md
index c6c6ba8bff..2285d78446 100644
--- a/dev-docs/cmp-best-practices.md
+++ b/dev-docs/cmp-best-practices.md
@@ -65,6 +65,10 @@ Community members are welcome to contribute more specific implementation
approaches here. Please do not attempt to extoll the virtues of one CMP
over another -- just help others with interface idiosyncacies.
+### Didomi
+
+Please follow the guidelines in the [Didomi documentation](https://developers.didomi.io/cmp/web-sdk/third-parties/custom-integrations/no-tag-manager) to make sure that the CMP is loaded before the ad server and Prebid.js.
+
### LiveRamp
LiveRamp has verified that they create the tcfapi functions and set gdprApplies=false when their CMP is removed from a geo.
diff --git a/dev-docs/getting-started.md b/dev-docs/getting-started.md
index 06a28bc39b..6b49b01937 100644
--- a/dev-docs/getting-started.md
+++ b/dev-docs/getting-started.md
@@ -19,7 +19,15 @@ The easiest way to get started with Prebid.js is to use the example code below.
{% include dev-docs/build-from-source-warning.md %}
-
+
+
+
(Sorry, jsfiddle code examples aren't available with your cookie privacy settings.)
+
+
### Next Steps
diff --git a/dev-docs/module-rules.md b/dev-docs/module-rules.md
index b009e446cc..cbcacd12c1 100644
--- a/dev-docs/module-rules.md
+++ b/dev-docs/module-rules.md
@@ -104,7 +104,8 @@ The use of the terms "must" and "should" in this document is deliberate. Howeve
### Real Time Data Module Rules
-1. All global rules apply.
+1. All global rules apply with one exception:
+ - A Real-Time Data module may load external code if it requires publisher registration and there's a prominent disclosure on the module documentation. The idea is that a publisher will not include the module if they don't approve of the external code, and since they've registered for the service, they must approve. The text of the disclosure may differ if the vendor allows Prebid to do regular reviews of a strictly versioned proprietary library.
1. Real Time Data (RTD) modules must not bid. That functionality is reserved for bid adapters.
1. RTD modules must not supply privacy-sensitive user information (including IDs) into the auction. That functionality is reserved for User ID modules.
1. RTD modules should make data available in a cross-bidder way when possible. For example, passing data through existing mechanisms like First Party Data.
diff --git a/dev-docs/modules/browsiRtdProvider.md b/dev-docs/modules/browsiRtdProvider.md
index e400ef56f9..6503cca338 100644
--- a/dev-docs/modules/browsiRtdProvider.md
+++ b/dev-docs/modules/browsiRtdProvider.md
@@ -1,9 +1,11 @@
---
layout: page_v2
title: Browsi Viewability Module
+display_name: Browsi Viewability
description: Browsi Real Time Viewability
+page_type: module
+module_type: rtd
module_code : browsi
-display_name : Browsi
enable_download : true
sidebarType : 1
---
@@ -55,7 +57,7 @@ Syntax details:
{: .table .table-bordered .table-striped }
| Name |Type | Description | Notes |
| :------------ | :------------ | :------------ |:------------ |
-| name | String | Real time data module name | Always 'browsi' |
+| name | String | Real time data module name | Always 'browsi' |
| params | Object | | |
| params.siteKey |String |Site key| |
| params.pubKey |String |Publisher key| |
@@ -64,6 +66,7 @@ Syntax details:
+
## Output
For each ad slot, the module returns expected viewability prediction in a JSON format.
diff --git a/dev-docs/modules/consentManagement.md b/dev-docs/modules/consentManagement.md
index b95e62f309..5e4d5ea4ae 100644
--- a/dev-docs/modules/consentManagement.md
+++ b/dev-docs/modules/consentManagement.md
@@ -74,7 +74,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.defaultGdprScope | `boolean` | (TCF v2.0 only) Defines what the `gdprApplies` flag should be when the CMP doesn't respond in time. | `true` |
+| 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.allowAuctionWithoutConsent | `boolean` | (TCF v1.1 only) Determines what will happen if obtaining consent information from the CMP fails; either allow the auction to proceed (`true`) or cancel the auction (`false`). Default is `true` | `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` | (TCF v2.0 only) Base64url-encoded TCF v2.0 string with segments. | |
diff --git a/dev-docs/modules/floors.md b/dev-docs/modules/floors.md
index 498ce08abf..0e2959c90e 100644
--- a/dev-docs/modules/floors.md
+++ b/dev-docs/modules/floors.md
@@ -278,6 +278,7 @@ Schema 1 restricts floors providers or publishers to applying only one data grou
{: .table .table-bordered .table-striped }
| Param | Type | Description | Default |
|---+---+---+---+---|
+| floorMin | float | The mimimum CPM floor used by the Floors Module (as of 4.13). The Floors Module will take the greater of floorMin and the matched rule CPM when evaluating getFloor() and enforcing floors. | - |
| floorProvider | string | Optional atribute (as of prebid version 4.1) used to signal to the Floor Provider's Analytics adapter their floors are being applied. They can opt to log only floors that are applied when they are the provider. If floorProvider is supplied in both the top level of the floors object and within the data object, the data object's configuration shall prevail.| - |
| enforcement | object | Controls the enforcement behavior within the 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 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 |
@@ -293,6 +294,7 @@ Schema 1 restricts floors providers or publishers to applying only one data grou
| data.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 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 |
| data.floorsSchemaVersion | string | The Floors Module supports two versions of the data schema. Version 1 allows for only one model to be applied in a given data set, whereas Version 2 allows you to sample multiple models selected by supplied weights. If no schema version is provided, the Floors Module will assume version 1 for the sake of backwards compatiblity. For schema version 2 see the next section. | 1 |
| data.modelVersion | string | Used by floor providers to train on model version performance. The expectation is a floor provider’s analytics adapter will pass the model verson back for algorithm training. | - |
+| data.modelTimestamp | int | Epoch timestamp associated with modelVersion. Can be used to track model creation of floor file for post auction analysis.| - |
| data.schema | object |allows for flexible definition of how floor data is formatted. | - |
| data.schema.delimiter | string | Character separating the floor keys. | '\|' |
| data.schema.fields | array of strings | Supported values are: gptSlot, adUnitCode, mediaType, size | - |
@@ -324,6 +326,7 @@ While some attributes are common in both schema versions, for completeness, all
{: .table .table-bordered .table-striped }
| Param | Type | Description | Default |
|---+---+---+---+---|
+| floorMin | float | The mimimum CPM floor used by the Floors Module (as of 4.13). The Floors Module will take the greater of floorMin and the matched rule CPM when evaluating getFloor() and enforcing floors. | - |
| floorProvider | string | Optional atribute (as of prebid version 4.1) used to signal to the Floor Provider's Analytics adapter their floors are being applied. They can opt to log only floors that are applied when they are the provider. If floorProvider is supplied in both the top level of the floors object and within the data object, the data object's configuration shall prevail.| - |
| enforcement | object | Controls the enforcement behavior within the 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 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 |
@@ -338,6 +341,7 @@ While some attributes are common in both schema versions, for completeness, all
| data.currency | string | Currency of floor data. Floors Module will convert currency where necessary. See Currency section for more details. | 'USD' |
| data.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 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 |
| data.floorsSchemaVersion | string | The Floors Module supports two version of the data schema. Version 1 allows for only one model to be applied in a given data set, whereas Version 2 allows you to sample multiple models selected by supplied weights. If no schema version is provided, the Floors Module will assume version 1 for the sake of backwards compatiblity.| 1 |
+| data.modelTimestamp | int | Epoch timestamp associated with modelVersion. Can be used to track model creation of floor file for post auction analysis.| - |
| data.modelGroups | array of objects | Array of model objects to be used for A/B sampling multiple models. This field is only used when data.floorsSchemaVersion = 2 | - |
| data.modelGroups[].currency | string | Currency of floor data. Floor Module will convert currency where necessary. See Currency section for more details. | 'USD' |
| data.modelGroups[].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 Floors Module is in floors mode. | 0 |
@@ -1030,23 +1034,25 @@ The price floors module will do this by leveraging the already existing implemen
{: .table .table-bordered .table-striped }
| bidRequest.floorData. | Type | Description | example |
|---+---+---+---+---|
-| skipped | Boolean | Whether the skipRate resolved to be true or false| true |
-| modelVersion | String | The name of the model| ‘floor-model-4.3’ |
-| location | String | Where the Floors Module derived the rule set. Values are one of 'adUnit', 'setConfig', 'fetch' or 'noData'. If the Floors Module code is invoked and no floors object is able to be found (either by error or other condition) the floorsModule will set location to 'noData'. When on data is found, it is up to the analtyics adapter to decide what to log. All available values will be provided in teh bidRequest object. | ‘fetch’ |
| fetchStatus | String | Provides details on the status of a fetch for a JSON floors file when fetches are attempted. Valid values are: 'success' (when fetch returns an http 200 status), 'timeout' (when fetch results not returned before either auction delay or prebid timeout) or 'error' (any http status other than 200 or other error condition). To determine if fetch succeeds but returns invalid floors data, refer to the location field to infer invalid data if 'fetch' is not resultant value. | ‘success’ |
+| floorMin | float | The mimimum CPM floor used by the Floors Module (as of 4.13). The Floors Module will take the greater of floorMin and the matched rule CPM when evaluating getFloor() and enforcing floors. | 0.10 |
+| floorProvider | string | Optional atribute (as of prebid version 4.1) used to signal to the Floor Provider's Analytics adapter their floors are being applied. They can opt to log only floors that are applied when they are the provider. If floorProvider is supplied in both the top level of the floors object and within the data object, the data object's configuration shall prevail.| "rubicon" |
+| location | String | Where the Floors Module derived the rule set. Values are one of 'adUnit', 'setConfig', 'fetch' or 'noData'. If the Floors Module code is invoked and no floors object is able to be found (either by error or other condition) the floorsModule will set location to 'noData'. When on data is found, it is up to the analtyics adapter to decide what to log. All available values will be provided in teh bidRequest object. | ‘fetch’ |
+| modelVersion | String | The name of the model| ‘floor-model-4.3’ |
+| modelTimestamp | int | Epoch timestamp associated with the modelVersion to be used for post auction analysis.| 1607126814 |
| skipRate | integer | skipRate will be populated when a skip rate is configured in the Prebid Floors Module, even if the skipRate is evaluated to false. Skip Rate is used to determine when to skip all floors logic. | 15 |
+| skipped | Boolean | Whether the skipRate resolved to be true or false| true |
**bidResponse**: When a bid response is being processed it is important for analytics adapters to know the decision which was made and the context of the rule selection. Here is the data which is attached to each bidResponse:
{: .table .table-bordered .table-striped }
| bidResponse.floorData. | Type | Description | example |
|---+---+---+---+---|
-| floorValue | number | The value of the floor chosen | 2.33 |
-| modelVersion | String | The name of the model| ‘floor-model-4.3’ |
-| floorRule | String | The matching rule for the given bidResponse | ‘div-1\|300x250\|\*’ |
-| floorCurrency | string | Currency of the matched floor | ‘USD’ |
| cpmAfterAdjustments | number | The bidder response CPM after any applicable adjustments (currency and / or bidCpmAdjustments) | 2.20 |
| enforcements | object | The input floor enforcements object. Keys are enforceJS, enforcePBS, floorDeald, bidAdjustment | { enforceJS: true, enforcePBS: false, floorDeals: false, bidAdjustment: true } |
+| floorCurrency | string | Currency of the matched floor | ‘USD’ |
+| floorRule | String | The matching rule for the given bidResponse | ‘div-1\|300x250\|\*’ |
+| floorRuleValue | number | The value of the floor chosen | 2.33 |
| matchedFields | object | Fields of the prebid auction used to match against the floorData.schema.fields. | { mediaType: ‘banner’, Size: ‘300x250, Domain: ‘www.prebid.org’, gptSlot: ‘/12345/prebid/sports’ } |
### Prebid Server Interface
@@ -1152,4 +1158,4 @@ If the currency function is unable to derive the correct cpm in any of the scena
{: .table }
| Partners| Contact |
| | Contact Magnite (Formerly Rubicon Project) support at [globalsupport@mangite.com](mailto:globalsupport@magnite.com) to use Magnite as a floor provider. |
-| pubx.ai | Reach out to PubX at [hello@pubx.ai](mailto:hello@pubx.ai) to learn more about our AI-powered dynamic floor optimization. |
\ No newline at end of file
+| pubx.ai | Reach out to PubX at [hello@pubx.ai](mailto:hello@pubx.ai) to learn more about our AI-powered dynamic floor optimization. |
diff --git a/dev-docs/modules/geoedgeRtdProvider.md b/dev-docs/modules/geoedgeRtdProvider.md
new file mode 100644
index 0000000000..4f31bf80c1
--- /dev/null
+++ b/dev-docs/modules/geoedgeRtdProvider.md
@@ -0,0 +1,84 @@
+---
+layout: page_v2
+title: Geoedge Realtime Module
+display_name: Geoedge Realtime
+description: Geoedge realtime blocking of bad ads - malware, redirect and offensive content
+page_type: module
+module_type: rtd
+module_code : geoedge
+enable_download : true
+sidebarType : 1
+---
+
+# Geoedge Realtime Module
+{:.no_toc}
+
+* TOC
+{:toc}
+
+## Overview
+
+The Geoedge Realtime module lets publishers block bad ads such as automatic redirects, malware, offensive creatives and landing pages.
+To use this module, you'll need to work with [Geoedge](https://www.geoedge.com/publishers-real-time-protection/) to get an account and cutomer key.
+
+{: .alert.alert-warning :}
+Disclosure: This module loads external code that is not open source and has not been reviewed by Prebid.org.
+
+## Integration
+
+1) Build the geoedge RTD module into the Prebid.js package with:
+
+```
+gulp build --modules=geoedgeRtdProvider,...
+```
+
+2) Use `setConfig` to instruct Prebid.js to initilize the geoedge module, as specified below.
+
+## Configuration
+
+This module is configured as part of the `realTimeData.dataProviders` object:
+
+```javascript
+pbjs.setConfig({
+ realTimeData: {
+ dataProviders: [{
+ name: 'geoedge',
+ params: {
+ key: '123123', // obtain your key from Geoedge support
+ bidders: {
+ 'bidderA': true, // monitor bids form this bidder
+ 'bidderB': false // do not monitor bids form this bidder.
+ },
+ wap: true
+ }
+ }]
+ }
+});
+```
+
+Parameters details:
+
+{: .table .table-bordered .table-striped }
+|Name |Type |Description |Notes |
+| :------------ | :------------ | :------------ |:------------ |
+|name | String | Real time data module name |Required, always 'geoedge' |
+|params | Object | | |
+|params.key | String | Customer key |Required, contact Geoedge to get your key |
+|params.bidders | Object | Bidders to monitor |Optional, list of bidder to include / exclude from monitoring. Omitting this will monitor bids from all bidders. |
+|params.wap |Boolean |Wrap after preload |Optional, defaults to `false`. Set to `true` if you want to monitor only after the module has preloaded the monitoring client. |
+
+## Example
+
+To view an integration example:
+
+1) in your cli run:
+
+```
+gulp serve --modules=appnexusBidAdapter,geoedgeRtdProvider
+```
+
+2) in your browser, navigate to:
+
+```
+http://localhost:9999/integrationExamples/gpt/geoedgeRtdProvider_example.html
+```
diff --git a/dev-docs/modules/haloRtdProvider.md b/dev-docs/modules/haloRtdProvider.md
new file mode 100644
index 0000000000..aac1bb4602
--- /dev/null
+++ b/dev-docs/modules/haloRtdProvider.md
@@ -0,0 +1,147 @@
+---
+layout: page_v2
+title: Audigent Halo Real Time Data Provider
+display_name: Audigent Halo Real-time Segmentation Module
+description: Audigent Halo Real-time Segmentation Module
+page_type: module
+module_type: rtd
+module_code : halo
+enable_download : true
+sidebarType : 1
+---
+
+# Audigent Halo RTD Segmentation Module
+{:.no_toc}
+
+* TOC
+{:toc}
+
+Audigent is a next-generation data management platform and a first-of-a-kind
+"data agency" containing some of the most exclusive content-consuming audiences
+across desktop, mobile and social platforms.
+
+This real-time data module provides quality user segmentation that can be
+attached to bid request objects destined for different SSPs in order to optimize
+targeting and increase publisher revenue. Audigent maintains a large database
+of first-party Tradedesk Unified ID, Audigent Halo ID and other id provider
+mappings to various third-party segment types that are utilizable across
+different SSPs. With this module, these segments can be retrieved and supplied
+to the SSP in real-time during the bid request cycle.
+
+## Publisher Usage
+
+Compile the Halo RTD module into your Prebid build:
+
+`gulp build --modules=userId,unifiedIdSystem,rtdModule,haloRtdProvider,appnexusBidAdapter`
+
+Add the Audigent Halo RTD provider to your Prebid config. For any adapters
+that you would like to retrieve segments for, add a mapping in the 'mapSegments'
+parameter. In this example we will configure publisher 1234 to retrieve
+appnexus segments from Audigent. See the "Parameter Descriptions" below for
+more detailed information of the configuration parameters. Currently,
+OpenRTB compatible fpd data will be added for any bid adapter in the
+"mapSegments" objects. Automated bid augmentation exists for some bidders.
+Please work with your Audigent Prebid support team (prebid@audigent.com) on
+which version of Prebid.js supports which bidders automatically.
+
+```
+pbjs.setConfig(
+ ...
+ realTimeData: {
+ auctionDelay: auctionDelay,
+ dataProviders: [
+ {
+ name: "halo",
+ waitForIt: true,
+ params: {
+ mapSegments: {
+ appnexus: true,
+ },
+ segmentCache: false,
+ requestParams: {
+ publisherId: 1234
+ }
+ }
+ }
+ ]
+ }
+ ...
+}
+```
+
+**Config Syntax details:**
+
+{: .table .table-bordered .table-striped }
+| Name |Type | Description | Notes |
+| :------------ | :------------ | :------------ |:------------ |
+| name | String | Real time data module name | Always 'halo' |
+| waitForIt | Boolean | Required to ensure that the auction is delayed until prefetch is complete | Optional. Defaults to false |
+| params | Object | | |
+| params.mapSegments | Boolean | Dictionary of bidders you would like to supply Audigent segments for. Maps to boolean values, but also allows functions for custom mapping logic. The function signature is (bid, segments) => {}. | Required |
+| params.segmentCache | Boolean | This parameter tells the Halo RTD module to attempt reading segments from a local storage cache instead of always requesting them from the Audigent server. | Optional. Defaults to false. |
+| params.requestParams | Object | Publisher partner specific configuration options, such as optional publisher id and other segment query related metadata to be submitted to Audigent's backend with each request. Contact prebid@audigent.com for more information. | Optional |
+
+## Overriding & Adding Segment Mappers
+As indicated above, it is possible to provide your own bid augmentation
+functions. This is useful if you know a bid adapter's API supports segment
+fields which aren't specifically being added to request objects in the Prebid
+bid adapter. You can also override segment mappers by passing a function
+instead of a boolean to the Halo RTD segment module. This might be useful
+if you'd like to use custom logic to determine which segments are sent
+to a specific backend.
+
+Please see the following example, which provides a function to modify bids for
+a bid adapter called adBuzz and overrides the appnexus segment mapper.
+
+```
+pbjs.setConfig(
+ ...
+ realTimeData: {
+ auctionDelay: auctionDelay,
+ dataProviders: [
+ {
+ name: "halo",
+ waitForIt: true,
+ params: {
+ mapSegments: {
+ // adding an adBuzz segment mapper
+ adBuzz: function(bid, segments) {
+ bid.params.adBuzzCustomSegments = [];
+ for (var i = 0; i < segments.length; i++) {
+ bid.params.adBuzzCustomSegments.push(segments[i].id);
+ }
+ },
+ // overriding the appnexus segment mapper to exclude certain segments
+ appnexus: function(bid, segments) {
+ for (var i = 0; i < segments.length; i++) {
+ if (segments[i].id != 'exclude_segment') {
+ bid.params.user.segments.push(segments[i].id);
+ }
+ }
+ }
+ },
+ segmentCache: false,
+ requestParams: {
+ publisherId: 1234
+ }
+ }
+ }
+ ]
+ }
+ ...
+}
+```
+
+## Testing
+
+To view an example of available segments returned by Audigent's backends:
+
+`gulp serve --modules=userId,unifiedIdSystem,rtdModule,haloRtdProvider,appnexusBidAdapter`
+
+and then point your browser at:
+
+`http://localhost:9999/integrationExamples/gpt/haloRtdProvider_example.html`
+
+
+
+
diff --git a/dev-docs/modules/idLibrary.md b/dev-docs/modules/idLibrary.md
new file mode 100644
index 0000000000..ea9bb9ea91
--- /dev/null
+++ b/dev-docs/modules/idLibrary.md
@@ -0,0 +1,94 @@
+---
+layout: page_v2
+page_type: module
+title: ID Library
+description: ID Graphing Adapter
+module_code : currency
+display_name : ID Library
+enable_download : true
+sidebarType : 1
+Maintainer: eng-dmp@magnite.com
+
+---
+
+
+# ID Library
+{:.no_toc}
+
+The ID Library module gathers and generates a map of identities present on the page. The primary usecase for this adapter is for Publishers who have included multiple UserId subadapters in their prebid.js implementation, and want to store the resulting user ids serverside for modeling or graphing purposes. The ID Library module, anchors the response of `refreshUserIds()` to a presistant identifier (md5 encrypted) and returns an map of uids. This map of uids comes in the form of a POST message in JSON format and must be output to a publisher configured endpoint.
+
+The module attempts to extract a persistant identifier in the following ways:
+
+1. From a publisher defined target element
+2. Searches for HTML input (text/email) element
+3. Searches entire document for email using regex
+
+To get started, add the module to your Prebid.js wrapper. From the command line:
+
+{: .alert.alert-info :}
+gulp build --modules=idLibrary
+
+
+## Application Flow
+
+In the idLibrary module, the persistant id is fetched from the page and synced with the user ids as follows:
+
+1. Check for a valid 'idLibrary' configuration
+1. If the configuration defines `target`, get the HTML element with the named id
+ 1. If a valid ID entry (e.g. email) exists in the target element, we're good, go on to step 5.
+ 1. Otherwise if no valid value is found, add a listener on the element
+ 1. Once the listener finds a valid value, go on to step 5.
+1. Else, scan the values of all text and email input elements on the page. If one of them has a valid persistent ID value, we found it. Go on to step 5.
+1. Else, scan the whole body tag for a valid persistent ID value. If one is found go on to step 5.
+1. If a valid persistent ID value has been found, then MD5 hash it, combine it with user IDs from the user ID module and POST to the specified endpoint.
+
+
+## Configuration:
+
+{: .table .table-bordered .table-striped }
+| Param | Required | Description |
+| --- | --- | --- |
+| url | yes | The url endpoint is used to post the MD5 hasheds|
+| target | no | Contains the element id from which the presistant value is to be read.|
+| debounce | no | Time in milliseconds the module will wait before searching for the presistant value and user ids|
+| fullscan | no | Allows the publisher to turn off the full page scan |
+
+Please note, A full scan (Step 4 above) of the body element is configured on by default but can be disabled by setting `"fullscan: false"`
+
+## Example
+
+```javascript
+ pbjs.setConfig({
+ idLibrary:{
+ url: 'url',
+ target: 'username',
+ debounce: 250
+ }
+});
+```
+
+### Post data format
+
+After the data is collected, it will be POSTed to the configured URL in this format:
+
+```json
+{
+ "hid": "MD5 hash",
+ "uids": "user ids array"
+}
+```
+
+```json
+{
+ "hid":"5dd72a98c8146bafa84313fc15eb27c2",
+ "uids":
+ {
+ "id5id":"ID5-ZHMOQ7afBOa_gZxzTSelo5KFcVwCQgM7d-BUkWtjAA",
+ "sharedid":
+ {
+ "id":"01EE77EKRHXEZVJYMSQVRJ9536",
+ "third":"01EE77EKRHXEZVJYMSQVRJ9536"
+ }
+ }
+}
+```
diff --git a/dev-docs/modules/index.md b/dev-docs/modules/index.md
index dd5b4bf164..8e69f088bc 100644
--- a/dev-docs/modules/index.md
+++ b/dev-docs/modules/index.md
@@ -34,11 +34,33 @@ If you are looking for bidder adapter parameters, see [Bidders' Params]({{site.b
| **ConsentManagement** | Collecting and passing consent information in support of privacy regulations:{::nomarkdown}
{:/} See [CMP Best Practices.](/dev-docs/cmp-best-practices.html) |
| [**Google Ad Manager Express**](/dev-docs/modules/dfp_express.html) | A simplified installation mechanism for publishers that have Google Publisher Tag (GPT) ad calls in their pages. |
| [**Supply Chain Object**](/dev-docs/modules/schain.html) | Validates and makes the Supply Object available to bidders |
-| [**User ID**](/dev-docs/modules/userId.html) | Sub-modules are available to support a range of identification approaches: Criteo RTUS, DigiTrust, ID5 Universal ID, IdentityLink, PubCommon ID, Unified ID and LiveIntent ID. |
-| [**Browsi Viewability**]({{site.baseurl}}/dev-docs/modules/browsiRtdProvider.html) | Browsi provider for real time data module. |
+| [**User ID**](/dev-docs/modules/userId.html) | Sub-modules are available to support a range of identification approaches. |
| [**Advanced Size Mapping**](/dev-docs/modules/sizeMappingV2.html) | Display Responsive AdUnits in demanding page environments. |
| [**Price Floors Module**](/dev-docs/modules/floors.html) | Configure and enforce minimum bids. |
| [**GPT Pre-Auction Module**](/dev-docs/modules/gpt-pre-auction.html) | Adds a PB Ad Slot and matching GAM ad unit name to each ad unit's first-party data before bid requests are sent to the adapters. |
+| [**ID Library**](/dev-docs/modules/idLibrary.html) | Retrieve user ids deployed on your site, and return them to a configurable endpoint for ID Graphing |
+
+## Real-Time Data Providers
+
+{% assign module_pages = site.pages | where: "page_type", "module" | where: "module_type", "rtd" %}
+
+
+
+
+
Module
+
Description
+
+
+
+{% for page in module_pages %}
+ {% if page.enable_download == false %}{% continue %}{% endif %}
+
## Video Modules
@@ -69,6 +91,5 @@ If you are looking for bidder adapter parameters, see [Bidders' Params]({{site.b
## Further Reading
+ [Source code of all modules](https://github.com/prebid/Prebid.js/tree/master/modules)
-+ [Bidders' Params]({{site.baseurl}}/dev-docs/bidders.html)
-
-
++ [Bidders' Params](/dev-docs/bidders.html)
++ [How to add a Real Time Data Submodule](/dev-docs/add-rtd-submodule.html)
diff --git a/dev-docs/modules/jwplayerRtdProvider.md b/dev-docs/modules/jwplayerRtdProvider.md
new file mode 100644
index 0000000000..bf881ef326
--- /dev/null
+++ b/dev-docs/modules/jwplayerRtdProvider.md
@@ -0,0 +1,149 @@
+---
+layout: page_v2
+title: JW Player Real Time Data Provider
+display_name: JW Player video ad targeting
+description: makes JW Player's video ad targeting information accessible to Bid Adapters.
+page_type: module
+module_type: rtd
+module_code : jwplayer
+enable_download : true
+sidebarType : 1
+---
+
+# JW Player RTD Provider
+{:.no_toc}
+
+* TOC
+{:toc}
+
+## Overview
+
+The JW Player RTD module passes contextual and performance based information about individual video impression opportunities to bid adapters in order to increase monetization.
+To use this module, you'll need to work with [JW Player](https://www.jwplayer.com/video-monetization/) to get an account and discuss the best integration path.
+
+## Implementation for Publishers:
+
+1) Compile the JW Player RTD Provider into your Prebid build:
+
+`gulp build --modules=jwplayerRtdProvider`
+
+2) Publishers must register JW Player as a Real Time Data provider by using `setConfig` to load a Prebid Config containing a `realTimeData.dataProviders` array:
+
+```javascript
+pbjs.setConfig({
+ ...,
+ realTimeData: {
+ auctionDelay: 100,
+ dataProviders: [{
+ name: "jwplayer",
+ waitForIt: true,
+ params: {
+ mediaIDs: ['abc', 'def', 'ghi', 'jkl']
+ }
+ }]
+ }
+});
+```
+
+3) Optionally, if you would like to prefetch the targeting information for certain media, you must include the media IDs in `params.mediaIDs`, as displayed above. You must also set `waitForIt` to `true` and make sure that a value is set to `realTimeData.auctionDelay`.
+
+`waitForIt` is required to ensure the auction waits for the prefetching of the relvant targeting information to complete. It signals to Prebid that you allow the module to delay the auction if necessary.
+Setting an `auctionDelay` in the `realTimeData` object is required to ensure the auction waits for prefetching to complete. The `auctionDelay` is the max time in ms that the auction will wait for the requested targeting information.
+
+**Note:** Though prefetch is optional, we highly recommend enabling it to ensure that the targeting information is available before bids are requested.
+
+**Config Syntax details:**
+
+{: .table .table-bordered .table-striped }
+| Name |Type | Description | Notes |
+| :------------ | :------------ | :------------ |:------------ |
+| name | String | Real time data module name | Always 'jwplayer' |
+| waitForIt | Boolean | Required to ensure that the auction is delayed until prefetch is complete | Optional. Defaults to false |
+| params | Object | | |
+| params.mediaIDs | Array of Strings | Media Ids for prefetching | Optional |
+
+4) Include the content's media ID and/or the player's ID in the matching AdUnit's `fpd.context.data.jwTargeting` before calling `addAdUnits`:
+
+```javascript
+ const adUnit = {
+ code: '/19968336/prebid_native_example_1',
+ ...,
+ fpd: {
+ context: {
+ data: {
+ jwTargeting: {
+ // Note: the following Ids are placeholders and should be replaced with your Ids.
+ playerID: 'abcd',
+ mediaID: '1234'
+ }
+ }
+ }
+ }
+ };
+
+ pbjs.que.push(function() {
+ pbjs.addAdUnits([adUnit]);
+ pbjs.requestBids({...});
+ });
+```
+**Note**: You may also include `jwTargeting` information in the prebid config's `fpd.context.data`. Information provided in the adUnit will always supersede the information in the config; use the config to set fallback information or information that applies to all adUnits.
+
+**AdUnit Syntax details:**
+
+{: .table .table-bordered .table-striped }
+| Name |Type | Description | Notes |
+| :------------ | :------------ | :------------ |:------------ |
+| fpd.context.data.jwTargeting | Object | | |
+| fpd.context.data.jwTargeting.mediaID | String | Media Id of the content associated to the Ad Unit | Optional but highly recommended |
+| fpd.context.data.jwTargeting.playerID | String | Id of the JW Player instance which will render the content associated to the Ad Unit | Optional but recommended |
+
+## Implementation for Bid Adapters:
+
+This section contains guidelines for bid adapters that are working with JW Player to utilize the additional targeting.
+
+Those bidders should implement the `buildRequests` function. When it is called, the `bidRequests` param will be an array of bids.
+Each bidRequest for which targeting information was found will conform to the following object structure:
+
+```json
+{
+ adUnitCode: 'xyz',
+ bidId: 'abc',
+ ...,
+ rtd: {
+ jwplayer: {
+ targeting: {
+ segments: ['123', '456'],
+ content: {
+ id: 'jw_abc123'
+ }
+ }
+ }
+ }
+}
+```
+
+Read the bidRequest.jwTargeting object and pass the values to your endpoint as appropriate.
+
+**BidRequest Syntax details:**
+
+{: .table .table-bordered .table-striped }
+| Name |Type | Description | Notes |
+| :------------ | :------------ | :------------ |:------------ |
+| rtd.jwplayer.targeting | Object | | |
+| rtd.jwplayer.targeting.segments | Array of Strings | jwpseg targeting segments | |
+| rtd.jwplayer.targeting.content | Object | | |
+| rtd.jwplayer.targeting.content.id | String | Unique identifier for the specific media asset | |
+
+## Example
+
+To view an example:
+
+- in the Prebid repo, run in your cli:
+
+`gulp serve --modules=jwplayerRtdProvider`
+
+- in your browser, navigate to:
+
+`http://localhost:9999/integrationExamples/gpt/jwplayerRtdProvider_example.html`
+
+**Note:** the mediaIds in the example are placeholder values; replace them with your existing IDs.
diff --git a/dev-docs/modules/reconciliationRtdProvider.md b/dev-docs/modules/reconciliationRtdProvider.md
new file mode 100644
index 0000000000..ddf6c4ee87
--- /dev/null
+++ b/dev-docs/modules/reconciliationRtdProvider.md
@@ -0,0 +1,86 @@
+---
+layout: page_v2
+title: Reconciliation SDK Module
+description: Reconciliation Real Time Data Module
+page_type: module
+module_type: rtd
+module_code: reconciliation
+display_name: Reconciliation
+enable_download: true
+sidebarType: 1
+---
+
+# Reconciliation SDK Module
+{:.no_toc}
+
+* TOC
+{:toc}
+
+## Overview
+
+The purpose of Reconciliation Real Time Data Provider is to allow publishers to collect supply chain structure information and vendor-specific impression IDs from ad creative suppliers. It reports the data to the Reconciliation Service, allowing publishers, advertisers and other supply chain participants to match and reconcile ad server, SSP, DSP and verification system log file records.
+Reconciliation SDK was created as part of TAG DLT initiative ([https://www.tagtoday.net/pressreleases/dlt_9_7_2020](https://www.tagtoday.net/pressreleases/dlt_9_7_2020)).
+TAG recently led a twelve-month, cross-industry pilot in the UK that evaluated the feasibility and benefits of using Distributed Ledger Technology (DLT) to increase trust and transparency in digital advertising.
+
+More information: https://www.tagtoday.net/brand-safety#dltnetwork
+Contact us: consultation@tagtoday.net
+
+Implementation works like this:
+
+1) Build the Reconciliation module into the Prebid.js package with:
+
+```
+gulp build --modules=reconciliationRtdProvider&...
+```
+
+2) Use `setConfig` to pass parameters to module
+
+## Configuration
+
+This module is configured as part of the `realTimeData.dataProviders` object:
+
+```
+ pbjs.setConfig({
+ "realTimeData": {
+ dataProviders:[{
+ name: "reconciliation",
+ params: {
+ publisherMemberId: "test_prebid_publisher",
+ allowAccess: true, //optional - false by default
+ }
+ }]
+ }
+ });
+```
+
+Syntax details:
+
+{: .table .table-bordered .table-striped }
+| Name |Type | Description | Notes |
+| :------------ | :------------ | :------------ |:------------ |
+| name | String | Real time data module name | Always 'reconciliation' |
+| params | Object | | |
+| params.publisherMemberId |String |Unique Publisher ID| |
+| params.allowAccess |Boolean |Share AdUnit IDs with advertiser Reconciliation Tags| Optional. Default to `false`|
+
+
+
+## Output
+
+For each ad slot, the module returns custom targeting values used to match impressions (publisher-adserver-advertiser).
+The module also tracks AdUnit initialization and impressions ('impression' message is sent by the Reconciliation Tag in ad markup).
+
+Custom targetings example:
+```
+{
+ "slotA":{
+ "RSDK_AUID": "/slotA-Unit",
+ "RSDK_ADID": "b5bbc103-00e9-499d-9637-bdba05b65427"
+ },
+ "slotB":{
+ "RSDK_AUID": "/slotB-Unit",
+ "RSDK_ADID": "325da95e-e37d-45fa-a46f-8ff91168b121"
+ }
+}
+```
+
diff --git a/dev-docs/modules/userId.md b/dev-docs/modules/userId.md
index 8624cca848..0d1ab73cb4 100644
--- a/dev-docs/modules/userId.md
+++ b/dev-docs/modules/userId.md
@@ -58,20 +58,20 @@ of sub-objects. The table below has the options that are common across ID system
{: .table .table-bordered .table-striped }
| Param under userSync.userIds[] | Scope | Type | Description | Example |
| --- | --- | --- | --- | --- |
-| name | Required | String | May be: `"britepoolId"`, `"criteo"`, `"haloId"`, `"id5id"`, `identityLink`, `"intentIqId"`, `"liveIntentId"`, `"lotamePanoramaId"`, `"merkleId"`, `"netId"`, `"parrableId"`, `"quantcastId"`, `"pubCommonId"`, `"pubProvidedId"`, `"sharedId"`, `"unifiedId"`, `"zeotapIdPlus"` | `"unifiedId"` |
+| name | Required | String | May be: `"britepoolId"`, `"criteo"`, `"fabrickId"`, `"haloId"`, `"id5id"`, `identityLink`, `"idx"`, `"intentIqId"`, `"liveIntentId"`, `"lotamePanoramaId"`, `"merkleId"`, `"netId"`, `"parrableId"`, `"quantcastId"`, `"pubCommonId"`, `"pubProvidedId"`, `"sharedId"`, `"unifiedId"`, `"verizonMediaId"`, `"zeotapIdPlus"` | `"unifiedId"` |
| params | Based on User ID sub-module | Object | | |
| storage | Optional | Object | The publisher can specify some kind of local storage in which to store the results of the call to get the user ID. This can be either cookie or HTML5 storage. This is not needed when `value` is specified or the ID system is managing its own storage | |
| storage.type | Required | String | Must be either `"cookie"` or `"html5"`. This is where the results of the user ID will be stored. | `"cookie"` |
| storage.name | Required | String | The name of the cookie or html5 local storage where the user ID will be stored. | `"_unifiedId"` |
| storage.expires | Strongly Recommended | Integer | How long (in days) the user ID information will be stored. If this parameter isn't specified, session cookies are used in cookie-mode, and local storage mode will create new IDs on every page. | `365` |
| storage.refreshInSeconds | Optional | Integer | The amount of time (in seconds) the user ID should be cached in storage before calling the provider again to retrieve a potentially updated value for their user ID. If set, this value should equate to a time period less than the number of days defined in `storage.expires`. By default the ID will not be refreshed until it expires.
-| value | Optional | Object | Used only if the page has a separate mechanism for storing a User ID. The value is an object containing the values to be sent to the adapters. | `{"tdid": "1111", "pubcid": {2222}, "IDP": "IDP-2233", "id5id": "ID5-12345" }` |
+| value | Optional | Object | Used only if the page has a separate mechanism for storing a User ID. The value is an object containing the values to be sent to the adapters. | `{"tdid": "1111", "pubcid": {2222}, "IDP": "IDP-2233", "id5id": {"uid": "ID5-12345"}}` |
## User ID Sub-Modules
### BritePool
-BritePool ID, provided by [BritePool](https://britepool.com) is a Universal Identity resolution which does not depend on 3rd party cookies.
+BritePool ID, provided by [BritePool](https://britepool.com) is a Universal Identity resolution which does not depend on 3rd party cookies.
Add it to your Prebid.js package with:
@@ -80,7 +80,7 @@ gulp build --modules=britepoolIdSystem
#### BritePool Registration
-Please reach out to [prebid@britepool.com](mailto:prebid@britepool.com) and request your `api_key`.
+Please reach out to [prebid@britepool.com](mailto:prebid@britepool.com) and request your `api_key`.
The BritePool privacy policy is at [https://britepool.com/services-privacy-notice/](https://britepool.com/services-privacy-notice/).
@@ -153,6 +153,79 @@ pbjs.setConfig({
});
{% endhighlight %}
+### Fabrick ID by Neustar
+
+[Neustar Fabrick™](https://www.home.neustar/fabrick) is a unified identity ecosystem that powers connections between brands, publishers, and consumers to accelerate marketing performance across online and offline channels.
+
+Add it to your Prebid.js package with:
+
+{: .alert.alert-info :}
+gulp build --modules=fabrickIdSystem
+
+#### Fabrick Registration
+
+Please reach out to [FabrickIntegrations@team.neustar](mailto:FabrickIntegrations@team.neustar) to request your `apiKey`.
+
+#### Fabrick Configuration
+
+{: .table .table-bordered .table-striped }
+| Param under userSync.userIds[] | Scope | Type | Description | Example |
+| --- | --- | --- | --- | --- |
+| name | Required | String | The name of this module. | `"fabrickId"` |
+| params | Required | Object | Container of all module params. | |
+| params.apiKey | Required | String | This is your apiKey as provided by Neustar. | |
+| params.e | | String | This is a hashed email address used to link a user to their Fabrick ID. | |
+| params.p | | String | This is a hashed phone number used to link a user to their Fabrick ID. | |
+| params.i4 | | String | This is an IPv4 address used to link a user to their Fabrick ID. | |
+| params.i6 | | String | This is an IPv6 address used to link a user to their Fabrick ID. | |
+| params.m | | String | This is a mobile advertising ID (IDFA/AAID) used to link a user to their Fabrick ID. | |
+| params.ia | | String | This is an identifier for advertising (IFA) used to link a user to their Fabrick ID. | |
+| params.iv | | String | This is an identifier for vendors (IFV) used to link a user to their Fabrick ID. | |
+
+#### Fabrick Examples
+
+1) Publisher passes an apiKey and hashed email address and elects to store the Fabrick ID envelope in a cookie.
+
+{% highlight javascript %}
+pbjs.setConfig({
+ userSync: {
+ userIds: [{
+ name: 'fabrickId',
+ params: {
+ apiKey: '123456789', // provided to you by Neustar
+ e: '31c5543c1734d25c7206f5fd591525d0295bec6fe84ff82f946a34fe970a1e66' // example hashed email address (sha256)
+ },
+ storage: {
+ name: 'pbjs_fabrickId',
+ type: 'cookie',
+ expires: 7
+ }
+ }]
+ }
+});
+{% endhighlight %}
+
+2) Publisher passes an apiKey and hashed email address and elects to store the fabrickId envelope in HTML5 localStorage.
+
+{% highlight javascript %}
+pbjs.setConfig({
+ userSync: {
+ userIds: [{
+ name: 'fabrickId',
+ params: {
+ apiKey: '123456789', // provided to you by Neustar
+ e: '31c5543c1734d25c7206f5fd591525d0295bec6fe84ff82f946a34fe970a1e66' // example hashed email address (sha256)
+ },
+ storage: {
+ type: "html5",
+ name: "pbjs_fabrickId",
+ expires: 7
+ }
+ }]
+ }
+});
+{% endhighlight %}
+
### Halo ID from Audigent
Audigent is a next-generation data management platform and a first-of-a-kind "data agency" containing some of the most exclusive content-consuming audiences across desktop, mobile and social platforms. Our HaloId module allows for user id resolution and Audigent user data segmentation to be retrieved for users across the web. For assistance setting up your module please contact us at [prebid@audigent.com](prebid@audigent.com).
@@ -221,7 +294,7 @@ pbjs.setConfig({
### ID5 Universal ID
-The ID5 Universal ID is a shared, neutral identifier that publishers and ad tech platforms can use to recognise users even in environments where 3rd party cookies are not available. The ID5 Universal ID is designed to respect users' privacy choices and publishers’ preferences throughout the advertising value chain. For more information about the ID5 Universal ID and detailed integration docs, please visit [our documentation](https://console.id5.io/docs/public/prebid). We also recommend that you sign up for our [release notes](https://id5.io/universal-id/release-notes) to stay up-to-date with any changes to the implementation of the ID5 Universal ID in Prebid.
+The ID5 Universal ID is a shared, neutral identifier that publishers and ad tech platforms can use to recognise users even in environments where 3rd party cookies are not available. The ID5 Universal ID is designed to respect users' privacy choices and publishers’ preferences throughout the advertising value chain. For more information about the ID5 Universal ID and detailed integration docs, please visit [our documentation](https://wiki.id5.io/x/BIAZ). We also recommend that you sign up for our [release notes](https://id5.io/universal-id/release-notes) to stay up-to-date with any changes to the implementation of the ID5 Universal ID in Prebid.
#### ID5 Universal ID Registration
@@ -244,13 +317,16 @@ The following configuration parameters are available:
| name | Required | String | The name of this module: `"id5Id"` | `"id5Id"` |
| params | Required | Object | Details for the ID5 Universal ID. | |
| params.partner | Required | Number | This is the ID5 Partner Number obtained from registering with ID5. | `173` |
-| params.pd | Optional | String | Publisher-supplied data used for linking ID5 IDs across domains. See [our documentation](https://wiki.id5.io/display/PD/Prebid.js+UserId+Module) for details on generating the string. Omit the parameter or leave as an empty string if no data to supply | `"MT1iNTBjY..."` |
+| params.pd | Optional | String | Publisher-supplied data used for linking ID5 IDs across domains. See [our documentation](https://wiki.id5.io/x/BIAZ) for details on generating the string. Omit the parameter or leave as an empty string if no data to supply | `"MT1iNTBjY..."` |
{: .alert.alert-info :}
**NOTE:** The ID5 Universal ID that is delivered to Prebid will be encrypted by ID5 with a rotating key to avoid unauthorized usage and to enforce privacy requirements. Therefore, we strongly recommend setting `storage.refreshInSeconds` to `8` hours (`8*3600` seconds) to ensure all demand partners receive an ID that has been encrypted with the latest key, has up-to-date privacy signals, and allows them to transact against it.
#### ID5 Universal ID Examples
+{: .alert.alert-warning :}
+**ATTENTION:** As of Prebid.js v4.14.0, ID5 requires `storage.type` to be `"html5"` and `storage.name` to be `"id5id"`. Using other values will display a warning today, but in an upcoming release, it will prevent the ID5 module from loading. This change is to ensure the ID5 module in Prebid.js interoperates properly with the [ID5 API](https://github.com/id5io/id5-api.js) and to reduce the size of publishers' first-party cookies that are sent to their web servers. If you have any questions, please reach out to us at [prebid@id5.io](mailto:prebid@id5.io).
+
1) Publisher wants to retrieve the ID5 Universal ID through Prebid.js
{% highlight javascript %}
@@ -260,16 +336,16 @@ pbjs.setConfig({
name: "id5Id",
params: {
partner: 173, // change to the Partner Number you received from ID5
- pd: "MT1iNTBjY..." // optional, see param table above for a link to how to generate this string
+ pd: "MT1iNTBjY..." // optional, see table above for a link to how to generate this
},
storage: {
- type: "cookie",
- name: "id5id.1st", // create a cookie with this name
- expires: 90, // cookie lasts for 90 days
+ type: "html5", // "html5" is the required storage type
+ name: "id5id", // "id5id" is the required storage name
+ expires: 90, // storage lasts for 90 days
refreshInSeconds: 8*3600 // refresh ID every 8 hours to ensure it's fresh
}
}],
- auctionDelay: 50 // 50ms maximum auction delay
+ auctionDelay: 50 // 50ms maximum auction delay, applies to all userId modules
}
});
{% endhighlight %}
@@ -281,7 +357,11 @@ pbjs.setConfig({
userSync: {
userIds: [{
name: "id5Id",
- value: { "id5id": "ID5-8ekgswyBTQqnkEKy0ErmeQ1GN5wV4pSmA-RE4eRedA" }
+ value: {
+ id5id: {
+ uid: "ID5-8ekgswyBTQqnkEKy0ErmeQ1GN5wV4pSmA-RE4eRedA"
+ }
+ }
}]
}
});
@@ -357,6 +437,38 @@ pbjs.setConfig({
});
{% endhighlight %}
+### IDx
+
+IDX is an alternative cookieless ID that uses anonymized and verified identifiers, provided by the users with explicit consent, which enables buy, sell, and measure targeted advertising at scale. IDX is created by Retargetly, a data company that owns the biggest consumer graph in Latin America.
+
+This sub-module enables the user’s IDx to be available in the bid request.
+
+More information of IDx can be found in [https://idx.lat/](https://idx.lat/)
+
+Add it to your Prebid.js package with:
+
+{: .alert.alert-info :}
+gulp build --modules=idxIdSystem
+
+#### IDx Configuration
+
+{: .table .table-bordered .table-striped }
+| Param under userSync.userIds[] | Scope | Type | Description | Example |
+| --- | --- | --- | --- | --- |
+| name | Required | String | `"idx"` | `"idx"` |
+
+#### IDx Example
+
+{% highlight javascript %}
+pbjs.setConfig({
+ userSync: {
+ userIds: [{
+ name: "idx"
+ }]
+ }
+});
+{% endhighlight %}
+
### IntentIQ ID
The IntentIQ ID solution is provided by intentiq.com.
@@ -475,11 +587,11 @@ The adapters can be implemented to use the lipibid as the identifier and segment
Please register with us if you’re not a LiveIntent customer already: [https://www.liveintent.com/prebid-registration/](https://www.liveintent.com/prebid-registration/)
-When adding LiveIntent’s ID to your Prebid.js package, you disclose or make available Personal Information to LiveIntent. This information made available to LiveIntent is used to (i) connect with and reference data that already exists in LiveIntent’s graph (the “LiveIntent Graph”), and (ii) authenticate and validate data in aggregate to improve the performance of the services LiveIntent provides. By activating LiveIntent’s module, you hereby confirm that with regard to all individuals to whom Personal Information relates, you have, at or before the point of collecting Personal Information or making Personal Information available to LiveIntent, provided any legally required notices, obtained any legally required consents, and provided individuals with an opportunity to opt-out of the sharing of Personal Information, if such an opt-out is required under applicable laws, such that LiveIntent can provide service to you as described here and in LiveIntent’s privacy policies for the services which can be found at [https://www.liveintent.com/services-privacy-policy/](https://www.liveintent.com/services-privacy-policy/)
+When adding LiveIntent’s ID to your Prebid.js package, you disclose or make available Personal Information to LiveIntent. This information made available to LiveIntent is used to (i) connect with and reference data that already exists in LiveIntent’s graph (the “LiveIntent Graph”), and (ii) authenticate and validate data in aggregate to improve the performance of the services LiveIntent provides. By activating LiveIntent’s module, you hereby confirm that with regard to all individuals to whom Personal Information relates, you have, at or before the point of collecting Personal Information or making Personal Information available to LiveIntent, provided any legally required notices, obtained any legally required consents, and provided individuals with an opportunity to opt-out of the sharing of Personal Information, if such an opt-out is required under applicable laws, such that LiveIntent can provide service to you as described here and in LiveIntent’s privacy policies for the services which can be found at [https://www.liveintent.com/services-privacy-policy/](https://www.liveintent.com/services-privacy-policy/)
#### How does LiveIntent ID work
-The LiveIntent ID sub-module resolves the identity of audiences by connecting impression opportunities to a stable identifier (nonID). In order to provide resolution one or more first-party cookies are used to create a stable identifier.
+The LiveIntent ID sub-module resolves the identity of audiences by connecting impression opportunities to a stable identifier (nonID). In order to provide resolution one or more first-party cookies are used to create a stable identifier.
How does LiveIntent ID sub-module decide, which first-party cookies to use:
1. By default LiveIntent ID sub-module generates its own first-party identifier on the publisher’s domain. Publishers have the option to disable the cookie generation when configuring the LiveIntent ID sub-module.
@@ -505,6 +617,7 @@ The LiveIntent ID sub-module follows the standard Prebid.js initialization based
| 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']`|
+| params.emailHash |Optional| String |The hashed email address of a user. We can accept the hashes, which use the following hashing algorithms: md5, sha1, sha2.|`1a79a4d60de6718e8e5b326e338ae533`|
| params.url | Optional| String |Use this to change the default endpoint URL if you can call the LiveIntent Identity Exchange within your own domain.|`'https://idx.my-domain.com'`|
| params.liCollectConfig |Optional| Object |Container of all collector params.||
| params.liCollectConfig.fpiStorageStrategy |Optional| String |This parameter defines whether the first party identifiers that LiveConnect creates and updates are stored in a cookie jar, or in local storage. If nothing is set, default behaviour would be `cookie`. Allowed values: [`cookie`, `ls`, `none`]|`'cookie'`|
@@ -527,11 +640,11 @@ pbjs.setConfig({
params: {
publisherId: "9896876"
},
- storage: {
- type: “cookie”,
- name: “pbjs_li_nonid”, //create a cookie with this name
- expires: 1 // cookie is stored for 1 day
- }
+ storage: {
+ type: “cookie”,
+ name: “pbjs_li_nonid”, //create a cookie with this name
+ expires: 1 // cookie is stored for 1 day
+ }
}]
}
})
@@ -547,11 +660,11 @@ pbjs.setConfig({
publisherId: "9896876",
identifiersToResolve: ["my-own-cookie"]
},
- storage: {
- type: “cookie”,
- name: “pbjs_li_nonid”, //create a cookie with this name
- expires: 1 // cookie is stored for 1 day
- }
+ storage: {
+ type: “cookie”,
+ name: “pbjs_li_nonid”, //create a cookie with this name
+ expires: 1 // cookie is stored for 1 day
+ }
}]
}
})
@@ -576,11 +689,11 @@ pbjs.setConfig({
appId: "a-0012"
}
},
- storage: {
- type: “cookie”,
- name: “pbjs_li_nonid”, //create a cookie with this name
- expires: 1 // cookie is stored for 1 day
- }
+ storage: {
+ type: “cookie”,
+ name: “pbjs_li_nonid”, //create a cookie with this name
+ expires: 1 // cookie is stored for 1 day
+ }
}]
}
})
@@ -595,7 +708,7 @@ The Lotame privacy policy is at [https://www.lotame.com/about-lotame/privacy/](h
Add it to your Prebid.js package with:
{: .alert.alert-info :}
-gulp build --modules=lotamePanoramaId
+gulp build --modules=lotamePanoramaIdSystem
#### Lotame Panorama ID Configuration
@@ -743,6 +856,21 @@ Add it to your Prebid.js package with:
{: .alert.alert-info :}
gulp build --modules=pubCommonIdSystem
+#### PubCommon ID Configuration
+
+In addition to the parameters documented above in the Basic Configuration section the following PubCommon specific configuration is available:
+
+{: .table .table-bordered .table-striped }
+| Param under userSync.userIds[] | Scope | Type | Description | Example |
+| --- | --- | --- | --- | --- |
+| name | Required | String | The name of this module. | `'pubCommonId'` |
+| params | Optional | Object | Customized parameters | |
+| params.create | Optional | Boolean | For publisher server support only. If true, the publisher's server will create the PubCommon ID cookie. Default is true. | `true` |
+| params.pixelUrl | Optional | String | For publisher server support only. This is a URL of a pixel for updating cookies' expiration times. Fired after a new ID has been created or an existing ID is being extended. No default. | `'https://example.com/ping'`
+| params.extend | Optional | Boolean | If true, the expiration time of the stored IDs will be refreshed during each page load. Default is false. | `false` |
+| params.enableSharedId | Optional | Boolean | Invokes [SharedID](/dev-docs/modules/userId.html#shared-id-user-id-submodule) as well as setting PubCommon ID. Defaults to `false` in Prebid.js 4.x. Will default to `true` in Prebid.js 5.0. | `true` |
+
+
#### PubCommon ID Examples
1) Publisher supports PubCommonID and first party domain cookie storage
@@ -779,9 +907,12 @@ pbjs.setConfig({
}
},{
name: "pubCommonId",
+ params: {
+ enableSharedId: true // optionally enable Prebid sharedID
+ },
storage: {
type: "cookie",
- name: "_pubcid", // create a cookie with this name
+ name: "_pubcid", // create a cookie with this name
expires: 180
}
}],
@@ -790,6 +921,10 @@ pbjs.setConfig({
});
{% endhighlight %}
+{: .alert.alert-info :}
+When enableSharedId is true, the browser will make an additional call to id.sharedid.org/usync. Calling to Shareid.org sets a user id in a 3rd party cookie under the sharedid.org domain. Anyone setting this additional identity should reference Sharedid.orgs optout policy at https://sharedid.org/. Prebid.js 5.0 will enable the enableSharedId option by default.
+
+
### PubProvided ID
The PubProvided Id module allows publishers to set and pass a first party user id into the bid stream. This module has several unique characteristics:
@@ -800,7 +935,7 @@ The PubProvided Id module allows publishers to set and pass a first party user i
pbjs.setConfig({
userSync: {
userIds: [{
- name: "publisherProvided",
+ name: "pubProvidedId",
params: {
eidsFunction: getIdsFn // any function that exists in the page
}
@@ -846,7 +981,7 @@ In either case, bid adapters will receive the eid values after consent is valida
2. This design allows for the setting of any number of uuids in the eids object. Publishers may work with multiple ID providers and nest their own id within the same eids object. The opportunity to link a 1st party uuid and a 3rd party generated UUID presents publishers with a unique ability to address their users in a way demand sources will understand.
-3. Finally, this module allows publishers to broadcast their user id, derived from in-house tech, directly to buyers within the confines of existing compliance (CCPA & GDPR) frameworks.
+3. Finally, this module allows publishers to broadcast their user id, derived from in-house tech, directly to buyers within the confines of existing compliance (CCPA & GDPR) frameworks.
4. The `eids.uids.ext.stype` "source-type" extension helps downstream entities know what do with the data. Currently defined values are:
@@ -856,6 +991,22 @@ In either case, bid adapters will receive the eid values after consent is valida
5. Bid adapters listening for "userIds.pubProvidedId" will not receive a string, please use the userIdAsEids value/function to return the userid as a string.
+Add it to your Prebid.js package with:
+
+{: .alert.alert-info :}
+gulp build --modules=pubProvidedId
+
+
+#### PubProvided Configuration
+
+{: .table .table-bordered .table-striped }
+| Params under usersync.userIds[]| Scope | Type | Description | Example |
+| --- | --- | --- | --- | --- |
+| name | Required | String | ID value for the ID module | `"PubProvided"` |
+| params | Optional | Object | Details for syncing. | |
+| params.eidsFunction | Optional | function | any function that exists in the page | getIdsFn() |
+| uids.atype | optional | int | ADCOM - Type of user agent the match is from | `"1"` |
+| uids.ext.stype | Optional | String | Description of how the id was generated and by whom ('ppuid','DMP','other') | `DMP` |
### Quantcast ID
@@ -894,17 +1045,17 @@ pbjs.setConfig({
### Shared ID User ID Submodule
-The Shared ID User Module generates a UUID that can be utilized to improve user matching. This module enables timely synchronization and handles opt-out via sharedId.org. This module does not require any registration.
+The Shared ID User Module generates a UUID that can be utilized to improve user matching. This module enables timely synchronization and handles opt-out via sharedId.org. This module does not require any registration.
#### Building Prebid with Shared Id Support
-Your Prebid build must include the modules for both **userId** and **sharedId** submodule.
Add it to your Prebid.js package with:
-ex: $ gulp build --modules=userId,sharedIdSystem
+{: .alert.alert-info :}
+ex: $ gulp build --modules=sharedIdSystem
#### Prebid Params
-Individual params may be set for the Shared ID User ID Submodule.
+Individual params may be set for the Shared ID User ID Submodule.
```
pbjs.setConfig({
usersync: {
@@ -1026,6 +1177,58 @@ pbjs.setConfig({
});
{% endhighlight %}
+### Verizon Media's Unified ID
+
+Verizon Media's Unified ID is a person based ID and doesn't depend on 3rd party cookies.
+
+Verizon Media's Unified ID is designed to enable ad tech platforms to recognize and match users consistently across the open web. Verizon Media's Unified ID is built on top of Verizon Media's robust and proprietary ID Graph, delivering a higher find rate of audiences on publishers' sites user targeting that respects privacy.
+
+Verizon Media's Unified ID honors privacy choices from our own [Privacy Dashboard](https://www.verizonmedia.com/policies/us/en/verizonmedia/privacy/dashboard/index.html), as well as global privacy acts.
+
+Please reach out to VerizonMedia-UIDsupport@verizonmedia.com for assistance with setup.
+
+Add support for Verizon Media's Unified ID to your Prebid.js package with:
+
+{: .alert.alert-info :}
+gulp build --modules=userId,verizonMediaIdSystem
+
+
+#### Verizon Media's Unified ID configuration
+
+{: .table .table-bordered .table-striped }
+| Param under userSync.userIds[] | Scope | Type | Description | Example |
+| --- | --- | --- | --- | --- |
+| name | Required | String | The name of this module. | `'verizonMediaId'` |
+| params | Required | Object | Container of all module params. ||
+| params.pixelId | Required | Number | The Verizon Media supplied publisher specific pixel Id | `8976` |
+| params.he | Required | String | The SHA-256 hashed user email address |`'ed8ddbf5a171981db8ef938596ca297d5e3f84bcc280041c5880dba3baf9c1d4'`|
+| storage | Required | Object | This object defines where and for how long the results of the call to get a user ID will be stored. | |
+| storage.type | Required | String | This parameter defines where the resolved user ID will be stored (either `'cookie'` or `'html5'` localstorage).| `'cookie'` |
+| storage.name | Required | String | The name of the cookie or html5 localstorage where the resolved user ID will be stored. | `'vmuid'` |
+| storage.expires | Recommended | Integer | How long (in days) the user ID information will be stored. The recommended value is `1` | `1` |
+
+#### Verizon Media's Unified ID examples
+
+```
+pbjs.setConfig({
+ userSync: {
+ userIds: [{
+ name: "verizonMediaId",
+ params: {
+ pixelId: 8976,
+ he: "ed8ddbf5a171981db8ef938596ca297d5e3f84bcc280041c5880dba3baf9c1d4"
+ },
+ storage: {
+ type: "cookie",
+ name: "vmuid",
+ expires: 1
+ }
+ }]
+ }
+})
+```
+
+
## Adapters Supporting the User ID Sub-Modules
{% assign bidder_pages = site.pages | where: "layout", "bidder" %}
@@ -1045,14 +1248,14 @@ pbjs.setConfig({
Bidders that want to support the User ID module in Prebid.js, need to update their bidder adapter to read the indicated bidRequest attributes and pass them to their endpoint.
-{: .table .table-bordered .table-striped }
+
| ID System Name | ID System Host | Prebid.js Attr | Example Value |
| --- | --- | --- | --- | --- | --- |
| BritePool ID | BritePool | bidRequest.userId.britepoolid | `"1111"` |
| CriteoID | Criteo | bidRequest.userId.criteoId | `"1111"` |
| Halo ID | Audigent | bidRequest.userId.haloId | `{"haloId":"user-halo-id", "auSeg":["segment1","segment2"]}` |
| ID+ | Zeotap | bidRequest.userId.IDP | `"1111"` |
-| ID5 ID | ID5 | bidRequest.userId.id5id | `"1111"` |
+| ID5 ID | ID5 | bidRequest.userId.id5id | `{ uid: "1111", ext: { linkType: 2 } }` |
| IdentityLink | Trade Desk | bidRequest.userId.idl_env | `"1111"` |
| IntentIQ ID | IntentIQ | bidRequest.userId.intentiqid | `"1111"` |
| LiveIntent ID | Live Intent | bidRequest.userId.lipb.lipbid | `"1111"` |
@@ -1065,6 +1268,9 @@ Bidders that want to support the User ID module in Prebid.js, need to update the
| Quantcast ID | n/a | bidRequest.userId.quantcastId | `"1111"` |
| Shared ID | SharedId | bidRequest.userId.sharedid | `{"id":"01EAJWWNEPN3CYMM5N8M5VXY22","third":"01EAJWWNEPN3CYMM5N8M5VXY22"}` |
| Unified ID | Trade Desk | bidRequest.userId.tdid | `"1111"` |
+| Verizon Media's Unified ID | Verizon Media | bidRequest.userId.vmuid | `"72d04af6e07c2eb93e9c584a131f48b6a9b963bcb2736d624e987ff8cf36d472"` |
+{: .table .table-bordered .table-striped }
+
For example, the adapter code might do something like:
@@ -1100,7 +1306,10 @@ Bidders that want to support the User ID module in Prebid Server, need to update
"source": "id5-sync.com",
"uids": [{
"id": "ID5-12345"
- }]
+ }],
+ "ext": {
+ "linkType": 2
+ }
},
{
source: "parrable.com",
@@ -1109,7 +1318,7 @@ Bidders that want to support the User ID module in Prebid Server, need to update
}]
},{
"source": "audigent.com",
- "atype": 1,
+ "atype": 1,
"uids": [{
"id": "11111111"
}]
@@ -1151,8 +1360,7 @@ Bidders that want to support the User ID module in Prebid Server, need to update
"third": "01EAJWWNEPN3CYMM5N8M5VXY22"
}
}]
- },
- {
+ },{
"source": "pub.com", // Publisher must configure their domain here
"uids": [{
"id": "01EAJWWNEPN3CYMM5N8M5VXY22",
@@ -1161,7 +1369,13 @@ Bidders that want to support the User ID module in Prebid Server, need to update
"stype": "dmp" //currently supported values (dmp,ppuid,other)
}
}]
- }]
+ },{
+ "source": "verizonmedia.com",
+ "uids": [{
+ "id": "61cef5656fb05f16d53938069f1684df4b2257e27"
+ }]
+ }
+ ]
}
}
}
@@ -1187,9 +1401,9 @@ If you need to export the user IDs stored by Prebid User ID module, the `getUser
pbjs.getUserIds() // returns object like bidRequest.userId. e.g. {"pubcid":"1111", "tdid":"2222"}
```
-You can use `getUserIdsAsEids()` to get the user IDs stored by Prebid User ID module in ORTB Eids format. Refer [eids.md](https://github.com/prebid/Prebid.js/blob/master/modules/userId/eids.md) for output format.
+You can use [`getUserIdsAsEids()`](https://docs.prebid.org/dev-docs/publisher-api-reference.html#userId.getUserIdsAsEids) to get the user IDs stored by Prebid User ID module in ORTB Eids format. Refer [eids.md](https://github.com/prebid/Prebid.js/blob/master/modules/userId/eids.md) for output format.
```
-pbjs.getUserIdsAsEids() // returns userIds in ORTB Eids format. e.g.
+pbjs.getUserIdsAsEids() // returns userIds in ORTB Eids format. e.g.
[
{
source: 'pubcid.org',
@@ -1208,9 +1422,20 @@ pbjs.getUserIdsAsEids() // returns userIds in ORTB Eids format. e.g.
rtiPartner: 'TDID'
}
}]
+ },
+
+ {
+ source: 'id5-sync.com',
+ uids: [{
+ id: 'ID5-12345',
+ atype: 1
+ },
+ ext: {
+ linkType: 2
+ }]
}
]
-```
+```
## Passing UserIds to Google Ad Manager for targeting
diff --git a/dev-docs/publisher-api-reference.md b/dev-docs/publisher-api-reference.md
index 4269d8dd94..c3e11a92a2 100644
--- a/dev-docs/publisher-api-reference.md
+++ b/dev-docs/publisher-api-reference.md
@@ -29,6 +29,7 @@ This page has documentation for the public API methods of Prebid.js.
* [.getAllWinningBids()](#module_pbjs.getAllWinningBids)
* [.getAllPrebidWinningBids()](#module_pbjs.getAllPrebidWinningBids)
* [.getNoBids()](#module_pbjs.getNoBids)
+ * [.getNoBidsForAdUnitCode(adUnitCode)](#module_pbjs.getNoBidsForAdUnitCode)
* [.setTargetingForGPTAsync([codeArr], customSlotMatching)](#module_pbjs.setTargetingForGPTAsync)
* [.setTargetingForAst()](#module_pbjs.setTargetingForAst)
* [.renderAd(doc, id)](#module_pbjs.renderAd)
@@ -66,6 +67,7 @@ This page has documentation for the public API methods of Prebid.js.
* [cache](#setConfig-vast-cache)
* [instreamTracking](#setConfig-instream-tracking) - requires [Instream Tracking Module](/dev-docs/modules/instreamTracking.html)
* [site](#setConfig-site)
+ * [auctionOptions](#setConfig-auctionOptions)
* [Generic Configuration](#setConfig-Generic-Configuration)
* [Troubleshooting your config](#setConfig-Troubleshooting-your-configuration)
* [.setBidderConfig(options)](#module_pbjs.setBidderConfig)
@@ -78,6 +80,7 @@ Functions added by optional modules
* [.adServers.freewheel.getTargeting(options)](#module_pbjs.getTargeting) - requires [Freewheel Module](/dev-docs/modules/freewheel.html)
* [.getUserIds()](#userId.getUserIds) - requires [User Id Module](/dev-docs/modules/userId.html)
* [.getUserIdsAsEids()](#userId.getUserIdsAsEids) - requires [User Id Module](/dev-docs/modules/userId.html)
+ * [.refreshUserIds(options, callback)](#userId.refreshUserIds) - requires [User Id Module](/dev-docs/modules/userId.html)
@@ -546,9 +549,33 @@ pbjs.getUserIdsAsEids() // returns userIds in ORTB Eids format. e.g.
+
+
+### pbjs.refreshUserIds(options, callback)
+
+{: .alert.alert-info :}
+To use this function, include the [UserId module](/dev-docs/modules/userId.html) in your Prebid.js build.
+
+The `refreshUserIds` function allows you to force either all or a subset of userId submodules to reinitialize their id values. You might want to do this if an event on your page occurred that would change the id value of a submodule. For example, a user logging in.
+
+{: .table .table-bordered .table-striped }
+| Param | Scope | Type | Description |
+| --- | --- | --- | --- |
+| options | optional | Object | Options object |
+| 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 |
+
+
+```
+pbjs.refreshUserIds();
+pbjs.refreshUserIds({ submoduleNames: ['britepoolId'] }, () => console.log("Done!"));
+```
+
+
+
-### pbjs.getNoBids() ⇒ `Array`
+### pbjs.getNoBids() ⇒ `Object`
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 [Tips for Troubleshooting](/dev-docs/troubleshooting-tips.html).
@@ -556,6 +583,25 @@ Use this method to get all of the bid requests that resulted in a NO_BID. These
+
+
+### pbjs.getNoBidsForAdUnitCode(adUnitCode) ⇒ `Object`
+
+Returns bid requests that resulted in a NO_BID for the specified adUnitCode. See full documentation at [pbjs.getNoBids()](#module_pbjs.getNoBids).
+
+**Kind**: static method of [pbjs](#module_pbjs)
+
+**Returns**: `Object` - NO_BID bidResponse object
+
+**Request Params:**
+
+{: .table .table-bordered .table-striped }
+| Param | Scope | Type | Description |
+| --- | --- | --- | --- |
+| adUnitCode | Required | `String` | adUnitCode |
+
+
+
### pbjs.setTargetingForGPTAsync([codeArr], customSlotMatching)
@@ -1184,7 +1230,7 @@ If a custom adServerTargeting function can return an empty value, this boolean f
### pbjs.getEvents() ⇒ `Array`
The methods `onEvent` and `offEvent` are provided for you to register
-a callback to handle a Prebid.js event.
+a callback to handle a Prebid.js event.
The `getEvents` method returns a copy of all emitted events.
@@ -2037,6 +2083,7 @@ The `targetingControls` object passed to `pbjs.setConfig` provides some options
|------------+---------+---------------------------------|
| auctionKeyMaxChars | integer | Specifies the maximum number of characters the system can add to ad server targeting. |
| alwaysIncludeDeals | boolean | If [enableSendAllBids](#setConfig-Send-All-Bids) is false, set this value to `true` to ensure that deals are sent along with the winning bid |
+| allowTargetingKeys | Array of Strings | Selects supported default targeting keys. |
{: .alert.alert-info :}
Note that this feature overlaps and can be used in conjunction with [sendBidsControl.bidLimit](/dev-docs/publisher-api-reference.html#setConfig-Send-Bids-Control).
@@ -2060,19 +2107,19 @@ Specifically, Prebid will go through the following steps with this feature:
* Collect all the available targeting keys that were generated naturally by the auction. The keys are grouped by each of the adUnits that participated in the auction.
* Prioritize these groups of targeting keys based on the following factors:
* Bids with deals are prioritized before bids without deals.
- * Bids with higher CPM are ranked before lower CPM bids.
+ * Bids with higher CPM are ranked before lower CPM bids.
**Note** - The sorting follows this order specifically, so a bid with a deal that had a $10 CPM would be sorted before a bid with no deal that had a $15 CPM.
* Convert the keys for each group into the format that they are passed to the ad server (i.e., an encoded query string) and count the number of characters that are used.
* If the count is below the running threshold set in the `setConfig` call, that set of targeting keys will be passed along. If the keys exceed the limit, then they are excluded.
- If you want to review the particular details about which sets of keys are passed/rejected, you can find them in the Prebid console debug log.
+ If you want to review the particular details about which sets of keys are passed/rejected, you can find them in the Prebid console debug log.
##### Finding the right value
Given the varying nature of how sites are set up for advertising and the varying mechanics and data-points needed by ad servers, providing a generic threshold setting is tricky. If you plan to enable this setting, it's recommended you review your own setup to determine the ideal value. The following steps provide some guidance on how to start this process:
* Use Prebid to set up a test page that uses the typical setup for your site (in terms of the number of ad slots, etc.).
-* Once it's working, look for the average number of characters Prebid uses for the auction targeting keys.
+* Once it's working, look for the average number of characters Prebid uses for the auction targeting keys.
* You can do this by enabling the Prebid debug mode, enabling this setting in your `setConfig` with a high value, and then opening the browser's console to review the Console Logs section.
* Also in the browser console, find your ad server's ad URL in the Network tab and review the details of the request to obtain information about the query data (specifically the number of characters used).
* You can copy the data to another tool to count the number of characters that are present.
@@ -2081,6 +2128,60 @@ 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.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
+
+When this property is set up, the `allowTargetingKeys` creates a default targeting key mask based on the default targeting keys defined in CONSTANTS.TARGETING_KEYS and CONSTANTS.NATIVE_KEYS. Any default keys that do not match the mask will not be sent to the adserver. This setting can be helpful if you find that your prebid implementation is by default sending key values that your adserver isn't configured to process. When extraneous key values are sent, the ad server request can be truncated, which can cause potential issues with the delivery or rendering of the ad.
+
+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.
+ * Default targeting keys are added to targeting only if they match an allowed key named in `setConfig`.
+* New targeting replaces original targeting before targeting is flattened.
+
+The targeting key names and the associated prefix value filtered by `allowTargetingKeys`:
+
+{: .table .table-bordered .table-striped }
+| Name | Value |
+|------------+------------|
+| BIDDER | `hb_bidder` |
+| AD_ID | `hb_adid` |
+| PRICE_BUCKET | `hb_pb` |
+| SIZE | `hb_size` |
+| DEAL | `hb_deal` |
+| SOURCE | `hb_source` |
+| FORMAT | `hb_format` |
+| UUID | `hb_uuid` |
+| CACHE_ID | `hb_cache_id` |
+| CACHE_HOST | `hb_cache_host` |
+| title | `hb_native_title` |
+| body | `hb_native_body` |
+| body2 | `hb_native_body2` |
+| privacyLink | `hb_native_privacy` |
+| privacyIcon | `hb_native_privicon` |
+| sponsoredBy | `hb_native_brand` |
+| image | `hb_native_image` |
+| icon | `hb_native_icon` |
+| clickUrl | `hb_native_linkurl` |
+| displayUrl | `hb_native_displayurl` |
+| cta | `hb_native_cta` |
+| rating | `hb_native_rating` |
+| address | `hb_native_address` |
+| downloads | `hb_native_downloads` |
+| likes | `hb_native_likes` |
+| phone | `hb_native_phone` |
+| price | `hb_native_price` |
+| salePrice | `hb_native_saleprice` |
+
+Below is an example config containing `allowTargetingKeys` excluding all default targeting keys except `hb_bidder`, `hb_adid`, and `hb_pb`:
+
+```javascript
+config.setConfig({
+ targetingControls: {
+ allowTargetingKeys: ['BIDDER', 'AD_ID', 'PRICE_BUCKET']
+ }
+});
+```
@@ -2366,9 +2467,9 @@ 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.
-- 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. In this scenario, 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.
For client-side caching, set the Prebid Cache URL as shown here (substituting the correct URL for the one shown here):
@@ -2452,6 +2553,27 @@ pbjs.setConfig({
});
{% endhighlight %}
+
+
+#### Auction Options
+
+The `auctionOptions` object passed to `pbjs.setConfig` provides a method to specify bidders that the Prebid auction will no longer wait for before determing the auction has completed. This may be helpful if you find there are a number of low performing and/or high timeout bidders in your page's rotation.
+
+{: .table .table-bordered .table-striped }
+| Field | Scope | Type | Description |
+|----------+---------+--------+---------------------------------------------------------------------------------------|
+| `secondaryBidders` | Required | Array of Strings | The bidders that will be removed from determining when an Auction has completed. |
+
+Example config:
+
+{% highlight js %}
+pbjs.setConfig({
+ 'auctionOptions': {
+ 'secondaryBidders': ['doNotWaitForMe']
+ }
+});
+{% endhighlight %}
+
#### Generic setConfig Configuration
diff --git a/dev-docs/show-outstream-video-ads.md b/dev-docs/show-outstream-video-ads.md
index 450a8cc999..e7021607ee 100644
--- a/dev-docs/show-outstream-video-ads.md
+++ b/dev-docs/show-outstream-video-ads.md
@@ -3,8 +3,6 @@ layout: page_v2
title: Show Outstream Video Ads
description: Show Outstream Video Ads with Prebid.js
pid: 10
-top_nav_section: dev_docs
-nav_section: prebid-video
sidebarType: 4
---
@@ -67,52 +65,51 @@ To display an outstream video, two things are needed:
Prebid.js will select the `renderer` used to display the outstream video in the following way:
-1. If a `renderer` is associated with the Prebid adUnit, it will be used to display any outstream demand associated with that adUnit. Below, we will provide an example of an adUnit with an associated `renderer`. If that renderer is specified as backup only, it will only be used when no other renderer is found.
-2. If no `renderer` is specified on the Prebid adUnit, Prebid will invoke the renderer associated with the winning (or selected) demand partner video bid. Choosing a backup only renderer allows publishers to access demand with or without an attached renderer.
+1. If a `renderer` is associated with the Prebid adUnit's video mediaType, it will be used to display any outstream demand associated with that adUnit with a mediaType of "video". (This is the preferred method.)
+2. If a `renderer` is associated with the Prebid adUnit, it will be used to display any outstream demand associated with that adUnit. Below, we will provide an example of an adUnit with an associated `renderer`. This is legacy, and number 1 is the preferred way.
+3. If no `renderer` is specified on the Prebid adUnit, Prebid will invoke the renderer associated with the winning (or selected) demand partner video bid.
{: .alert.alert-warning :}
At this time, since not all demand partners return a renderer with their video bid responses, we recommend that publishers associate a `renderer` with their Prebid video adUnits, if possible. By doing so, any Prebid adapter that supports video will be able to provide demand for a given outstream slot.
-Renderers are associated with adUnits through the `adUnit.renderer` object. This object contains three fields:
+Renderers are associated with adUnits in two ways.
+Primarily through the `adUnit.renderer` object. But also, especially for multiFormat adUnits, through the specified mediaType `adUnit.mediaTypes.video.renderer`.
+This object contains these fields:
1. `url` -- Points to a file containing the renderer script.
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 %}
pbjs.addAdUnit({
code: 'video1',
+ // This renderer would apply to all prebid creatives...
+ renderer: {
+ url: 'example.com/publishersCustomRenderer.js',
+ render: function(bid) { renderAdUnit(...) }
+ },
mediaTypes: {
video: {
context: 'outstream',
- playerSize: [640, 480]
- }
- },
- renderer: {
- url: 'https://acdn.adnxs.com/video/outstream/ANOutstreamVideo.js',
- backupOnly: true, // prefer demand renderer
- render: function (bid) {
- adResponse = {
- ad: {
- video: {
- content: bid.vastXml,
- player_height: bid.playerHeight,
- player_width: bid.playerWidth
- }
- }
+ playerSize: [640, 480],
+ // but a renderer passed in here would apply only to this mediaType.
+ // This renderer would override the above renderer if it exists.
+ renderer: {
+ url: 'example.com/videoRenderer.js',
+ render: function (bid) { renderVideo(...) }
}
- // push to render queue because ANOutstreamVideo may not be loaded yet.
- bid.renderer.push(() => {
- ANOutstreamVideo.renderAd({
- targetId: bid.adUnitCode, // target div id to render video.
- adResponse: adResponse
- });
- });
- }
- }
+ },
+ display: {
+ // With the renderer property excluded here, the display bids would
+ // use the renderer defined on the adUnit level.
+ ...,
+ },
+ },
+ ...
});
-
{% 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:
@@ -137,7 +134,7 @@ pbjs.addAdUnit({
{% endhighlight %}
-For more technical information about renderers, see [the pull request adding the 'Renderer' type](https://github.com/prebid/Prebid.js/pull/1082)
+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).
## Step 2: Show ads in the page body
diff --git a/developers.md b/developers.md
index 5b7c7064c5..8126bf86cf 100644
--- a/developers.md
+++ b/developers.md
@@ -15,25 +15,25 @@ sidebarType: 0
Key links for publisher developers.
-### Prebid.js - integrating display and video ads in standard web pages.
+**Prebid.js** - integrating display and video ads in standard web pages:
-+ [What is Prebid.js]({{site.baseurl}}/prebid/prebidjs.html)
-+ [Getting Started with Prebid.js]({{site.baseurl}}/dev-docs/getting-started.html)
-+ [Publisher API Reference]({{site.baseurl}}/dev-docs/publisher-api-reference.html)
-+ [Download a Prebid.js package]({{site.baseurl}}/download.html)
-+ [Troubleshooting Guide]({{site.baseurl}}/dev-docs/prebid-troubleshooting-guide.html)
++ [What is Prebid.js](/prebid/prebidjs.html)
++ [Getting Started with Prebid.js](/dev-docs/getting-started.html)
++ [Publisher API Reference](/dev-docs/publisher-api-reference.html)
++ [Download a Prebid.js package](/download.html)
++ [Troubleshooting Guide](/dev-docs/prebid-troubleshooting-guide.html)
-### Prebid for AMP - integrating display ads into AMP pages
+**Prebid for AMP** - integrating display ads into AMP pages:
-+ [How Prebid on AMP works]({{site.baseurl}}/dev-docs/how-prebid-on-amp-works.html)
-+ [Prebid AMP Implementation Guide]({{site.baseurl}}/dev-docs/show-prebid-ads-on-amp-pages.html)
-+ [Prebid Server AMP endpoint documentation]({{site.baseurl}}/prebid-server/endpoints/openrtb2/pbs-endpoint-amp.html)
++ [How Prebid on AMP works](/dev-docs/how-prebid-on-amp-works.html)
++ [Prebid AMP Implementation Guide](/dev-docs/show-prebid-ads-on-amp-pages.html)
++ [Prebid Server AMP endpoint documentation](/prebid-server/endpoints/openrtb2/pbs-endpoint-amp.html)
-### Prebid Mobile - integrating display, video, and native ads into iOS and Android apps
+**Prebid Mobile** - integrating display, video, and native ads into iOS and Android apps:
-+ [Getting started with Prebid Mobile]({{site.baseurl}}/prebid-mobile/prebid-mobile-pbs.html)
-+ [Android code integration]({{site.baseurl}}/prebid-mobile/pbm-api/android/code-integration-android.html)
-+ [iOS code integration]({{site.baseurl}}/prebid-mobile/pbm-api//ios/code-integration-ios.html)
++ [Getting started with Prebid Mobile](/prebid-mobile/prebid-mobile-pbs.html)
++ [Android code integration](/prebid-mobile/pbm-api/android/code-integration-android.html)
++ [iOS code integration](/prebid-mobile/pbm-api//ios/code-integration-ios.html)
---
@@ -43,12 +43,12 @@ Key links for publisher developers.
Key links for integrating into the Prebid ecosystem.
-### Prebid.js - adding an adapter
+**Prebid.js** - adding an adapter:
-+ [How to add a bid adapter]({{site.baseurl}}/dev-docs/bidder-adaptor.html)
-+ [How to add an analytics adapter]({{site.baseurl}}/dev-docs/integrate-with-the-prebid-analytics-api.html)
++ [How to add a bid adapter](/dev-docs/bidder-adaptor.html)
++ [How to add an analytics adapter](/dev-docs/integrate-with-the-prebid-analytics-api.html)
+ [Open source repository](https://github.com/prebid/Prebid.js)
-### Prebid Server - adding an adapter
+**Prebid Server** - adding an adapter:
-+ [Adding a new bid adapter]({{site.baseurl}}/prebid-server/developers/add-new-bidder-go.html)
++ [Adding a new bid adapter](/prebid-server/developers/add-new-bidder-go.html)
diff --git a/download.md b/download.md
index 02bb783a1e..d128b24d4e 100644
--- a/download.md
+++ b/download.md
@@ -171,33 +171,27 @@ Prebid.js is open source software that is offered for free as a convenience. Whi
**Note:** an important bug in the [DFP Video Module](/dev-docs/modules/dfp_video.html) was introduced with 3.27 and fixed in 4.3. The dfpVideoModule only looked in adunit.sizes but adunit.sizes was stripped. Unfortunately there's not a workaround - if you use that video module, you shouldn't use Prebid.js 3.27 through 4.2 inclusive.