Repository: prebid/prebid-server
Pull request #1348 (2020-06-11 00:12:17)

Category updates based on publisher feedback.
The github (as well as sourcetree) diff does a poor job of displaying the changes in the freewheel.json file, there were just a couple of new IAB categories added and some freewheel industry group changes. Viewing the diff of that file within VSCode instead will make it a lot easier to see what actually changed.


Patch:
diff --git a/.travis.yml b/.travis.yml
index ea2c46c4..692141f7 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -1,9 +1,8 @@
 language: go
 
 go:
-  - '1.12'
   - '1.13'
-  - '1.14'
+  - '1.14.2'
 
 go_import_path: github.com/prebid/prebid-server
 
diff --git a/Dockerfile b/Dockerfile
index a8fea9c3..2c60b9e3 100644
--- a/Dockerfile
+++ b/Dockerfile
@@ -3,8 +3,8 @@ RUN apt-get update && \
     apt-get -y upgrade && \
     apt-get install -y wget
 RUN cd /tmp && \
-    wget https://dl.google.com/go/go1.12.7.linux-amd64.tar.gz && \
-    tar -xf go1.12.7.linux-amd64.tar.gz && \
+    wget https://dl.google.com/go/go1.14.2.linux-amd64.tar.gz && \
+    tar -xf go1.14.2.linux-amd64.tar.gz && \
     mv go /usr/local
 RUN mkdir -p /app/prebid-server/
 WORKDIR /app/prebid-server/
diff --git a/README.md b/README.md
index a59bf5f6..b69e7e76 100644
--- a/README.md
+++ b/README.md
@@ -18,9 +18,10 @@ For more information, see:
 
 ## Installation
 
-First install [Go 1.12](https://golang.org/doc/install) latest version.
+First install [Go](https://golang.org/doc/install) version 1.13 or newer.
+
 Note that prebid-server is using [Go modules](https://blog.golang.org/using-go-modules).
-If using Go version <1.13 and are inside GOPATH `GO111MODULE` needs to be set to `GO111MODULE=on`.
+We officially support the most recent two major versions of the Go runtime. However, if you'd like to use a version <1.13 and are inside GOPATH `GO111MODULE` needs to be set to `GO111MODULE=on`.
 
 Download and prepare Prebid Server:
 
diff --git a/adapters/consumable/consumable.go b/adapters/consumable/consumable.go
index 1fa23377..243f1b80 100644
--- a/adapters/consumable/consumable.go
+++ b/adapters/consumable/consumable.go
@@ -268,8 +268,11 @@ func (a *ConsumableAdapter) MakeBids(
 			//bid.referrer = utils.getTopWindowUrl();
 
 			bidderResponse.Bids = append(bidderResponse.Bids, &adapters.TypedBid{
-				Bid:     &bid,
-				BidType: getMediaTypeForImp(getImp(bid.ImpID, internalRequest.Imp)),
+				Bid: &bid,
+				// Consumable units are always HTML, never VAST.
+				// From Prebid's point of view, this means that Consumable units
+				// are always "banners".
+				BidType: openrtb_ext.BidTypeBanner,
 			})
 		}
 	}
@@ -303,16 +306,6 @@ func extractExtensions(impression openrtb.Imp) (*adapters.ExtImpBidder, *openrtb
 	return &bidderExt, &consumableExt, nil
 }
 
-func getMediaTypeForImp(imp *openrtb.Imp) openrtb_ext.BidType {
-	// TODO: Whatever logic we need here possibly as follows - may always be Video when we bid
-	if imp.Banner != nil {
-		return openrtb_ext.BidTypeBanner
-	} else if imp.Video != nil {
-		return openrtb_ext.BidTypeVideo
-	}
-	return openrtb_ext.BidTypeVideo
-}
-
 func testConsumableBidder(testClock instant, endpoint string) *ConsumableAdapter {
 	return &ConsumableAdapter{testClock, endpoint}
 }
diff --git a/config/config.go b/config/config.go
index 07384f9d..0f470c6a 100755
--- a/config/config.go
+++ b/config/config.go
@@ -49,6 +49,7 @@ type Configuration struct {
 	AMPTimeoutAdjustment int64              `mapstructure:"amp_timeout_adjustment_ms"`
 	GDPR                 GDPR               `mapstructure:"gdpr"`
 	CCPA                 CCPA               `mapstructure:"ccpa"`
+	LMT                  LMT                `mapstructure:"lmt"`
 	CurrencyConverter    CurrencyConverter  `mapstructure:"currency_converter"`
 	DefReqConfig         DefReqConfig       `mapstructure:"default_request"`
 
@@ -139,6 +140,13 @@ func (cfg *AuctionTimeouts) LimitAuctionTimeout(requested time.Duration) time.Du
 	return requested
 }
 
+// Privacy is a grouping of privacy related configs to assist in dependency injection.
+type Privacy struct {
+	CCPA CCPA
+	GDPR GDPR
+	LMT  LMT
+}
+
 type GDPR struct {
 	HostVendorID            int          `mapstructure:"host_vendor_id"`
 	UsersyncIfAmbiguous     bool         `mapstructure:"usersync_if_ambiguous"`
@@ -193,6 +201,10 @@ type CCPA struct {
 	Enforce bool `mapstructure:"enforce"`
 }
 
+type LMT struct {
+	Enforce bool `mapstructure:"enforce"`
+}
+
 type Analytics struct {
 	File FileLogs `mapstructure:"file"`
 }
@@ -805,7 +817,7 @@ func SetupViper(v *viper.Viper, filename string) {
 	v.SetDefault("adapters.telaria.endpoint", "https://ads.tremorhub.com/ad/rtb/prebid")
 	v.SetDefault("adapters.triplelift_native.disabled", true)
 	v.SetDefault("adapters.triplelift_native.extra_info", "{\"publisher_whitelist\":[]}")
-	v.SetDefault("adapters.triplelift.endpoint", "https://tlx.3lift.com/s2s/auction?supplier_id=20")
+	v.SetDefault("adapters.triplelift.endpoint", "https://tlx.3lift.com/s2s/auction?sra=1&supplier_id=20")
 	v.SetDefault("adapters.ucfunnel.endpoint", "http://apac-hk-adx.aralego.com/prebid")
 	v.SetDefault("adapters.unruly.endpoint", "http://targeting.unrulymedia.com/openrtb/2.2")
 	v.SetDefault("adapters.valueimpression.endpoint", "https://rtb.valueimpression.com/endpoint")
@@ -836,6 +848,7 @@ func SetupViper(v *viper.Viper, filename string) {
 	v.SetDefault("gdpr.tcf2.purpose_one_treatement.access_allowed", true)
 	v.SetDefault("gdpr.amp_exception", false)
 	v.SetDefault("ccpa.enforce", false)
+	v.SetDefault("lmt.enforce", true)
 	v.SetDefault("currency_converter.fetch_url", "https://cdn.jsdelivr.net/gh/prebid/currency-file@1/latest.json")
 	v.SetDefault("currency_converter.fetch_interval_seconds", 1800) // fetch currency rates every 30 minutes
 	v.SetDefault("default_request.type", "")
diff --git a/endpoints/openrtb2/amp_auction.go b/endpoints/openrtb2/amp_auction.go
index 586481dd..2dcd572c 100644
--- a/endpoints/openrtb2/amp_auction.go
+++ b/endpoints/openrtb2/amp_auction.go
@@ -407,31 +407,34 @@ func (deps *endpointDeps) overrideWithParams(httpRequest *http.Request, req *ope
 }
 
 func makeFormatReplacement(overrideWidth uint64, overrideHeight uint64, width uint64, height uint64, multisize string) []openrtb.Format {
+	var formats []openrtb.Format
 	if overrideWidth != 0 && overrideHeight != 0 {
-		return []openrtb.Format{{
+		formats = []openrtb.Format{{
 			W: overrideWidth,
 			H: overrideHeight,
 		}}
 	} else if overrideWidth != 0 && height != 0 {
-		return []openrtb.Format{{
+		formats = []openrtb.Format{{
 			W: overrideWidth,
 			H: height,
 		}}
 	} else if width != 0 && overrideHeight != 0 {
-		return []openrtb.Format{{
+		formats = []openrtb.Format{{
 			W: width,
 			H: overrideHeight,
 		}}
-	} else if parsedSizes := parseMultisize(multisize); len(parsedSizes) != 0 {
-		return parsedSizes
 	} else if width != 0 && height != 0 {
-		return []openrtb.Format{{
+		formats = []openrtb.Format{{
 			W: width,
 			H: height,
 		}}
 	}
 
-	return nil
+	if parsedSizes := parseMultisize(multisize); len(parsedSizes) != 0 {
+		formats = append(formats, parsedSizes...)
+	}
+
+	return formats
 }
 
 func setWidths(formats []openrtb.Format, width uint64) {
diff --git a/exchange/bidder.go b/exchange/bidder.go
index f9b4a522..df9f0a3b 100644
--- a/exchange/bidder.go
+++ b/exchange/bidder.go
@@ -389,7 +389,20 @@ func (bidder *bidderAdapter) doTimeoutNotification(timeoutBidder adapters.Timeou
 			}
 		} else {
 			bidder.me.RecordTimeoutNotice(false)
+			if bidder.DebugConfig.TimeoutNotification.Log {
+				msg := fmt.Sprintf("TimeoutNotification: Failed to make timeout request: method(%s), uri(%s), error(%s)", toReq.Method, toReq.Uri, err.Error())
+				util.LogRandomSample(msg, glog.Warningf, bidder.DebugConfig.TimeoutNotification.SamplingRate)
+			}
+		}
+	} else if bidder.DebugConfig.TimeoutNotification.Log {
+		reqJSON, err := json.Marshal(req)
+		var msg string
+		if err == nil {
+			msg = fmt.Sprintf("TimeoutNotification: Failed to generate timeout request: error(%s), bidder request(%s)", errL[0].Error(), string(reqJSON))
+		} else {
+			msg = fmt.Sprintf("TimeoutNotification: Failed to generate timeout request: error(%s), bidder request marshal failed(%s)", errL[0].Error(), err.Error())
 		}
+		util.LogRandomSample(msg, glog.Warningf, bidder.DebugConfig.TimeoutNotification.SamplingRate)
 	}
 
 }
diff --git a/exchange/exchange.go b/exchange/exchange.go
index 660beb64..84ae35d6 100644
--- a/exchange/exchange.go
+++ b/exchange/exchange.go
@@ -48,7 +48,7 @@ type exchange struct {
 	currencyConverter   *currencies.RateConverter
 	UsersyncIfAmbiguous bool
 	defaultTTLs         config.DefaultTTLs
-	enforceCCPA         bool
+	privacyConfig       config.Privacy
 }
 
 // Container to pass out response ext data from the GetAllBids goroutines back into the main thread
@@ -77,7 +77,11 @@ func NewExchange(client *http.Client, cache prebid_cache_client.Client, cfg *con
 	e.currencyConverter = currencyConverter
 	e.UsersyncIfAmbiguous = cfg.GDPR.UsersyncIfAmbiguous
 	e.defaultTTLs = cfg.CacheURL.DefaultTTLs
-	e.enforceCCPA = cfg.CCPA.Enforce
+	e.privacyConfig = config.Privacy{
+		CCPA: cfg.CCPA,
+		GDPR: cfg.GDPR,
+		LMT:  cfg.LMT,
+	}
 	return e
 }
 
@@ -100,7 +104,7 @@ func (e *exchange) HoldAuction(ctx context.Context, bidRequest *openrtb.BidReque
 
 	// Slice of BidRequests, each a copy of the original cleaned to only contain bidder data for the named bidder
 	blabels := make(map[openrtb_ext.BidderName]*pbsmetrics.AdapterLabels)
-	cleanRequests, aliases, errs := cleanOpenRTBRequests(ctx, bidRequest, usersyncs, blabels, labels, e.gDPR, e.UsersyncIfAmbiguous, e.enforceCCPA)
+	cleanRequests, aliases, errs := cleanOpenRTBRequests(ctx, bidRequest, usersyncs, blabels, labels, e.gDPR, e.UsersyncIfAmbiguous, e.privacyConfig)
 
 	// List of bidders we have requests for.
 	liveAdapters := listBiddersWithRequests(cleanRequests)
diff --git a/exchange/utils.go b/exchange/utils.go
index f602d1e8..54122d13 100644
--- a/exchange/utils.go
+++ b/exchange/utils.go
@@ -8,11 +8,13 @@ import (
 
 	"github.com/buger/jsonparser"
 	"github.com/mxmCherry/openrtb"
+	"github.com/prebid/prebid-server/config"
 	"github.com/prebid/prebid-server/gdpr"
 	"github.com/prebid/prebid-server/openrtb_ext"
 	"github.com/prebid/prebid-server/pbsmetrics"
 	"github.com/prebid/prebid-server/privacy"
 	"github.com/prebid/prebid-server/privacy/ccpa"
+	"github.com/prebid/prebid-server/privacy/lmt"
 )
 
 // cleanOpenRTBRequests splits the input request into requests which are sanitized for each bidder. Intended behavior is:
@@ -26,8 +28,8 @@ func cleanOpenRTBRequests(ctx context.Context,
 	blables map[openrtb_ext.BidderName]*pbsmetrics.AdapterLabels,
 	labels pbsmetrics.Labels,
 	gDPR gdpr.Permissions,
-	usersyncIfAmbiguous,
-	enforceCCPA bool) (requestsByBidder map[openrtb_ext.BidderName]*openrtb.BidRequest, aliases map[string]string, errs []error) {
+	usersyncIfAmbiguous bool,
+	privacyConfig config.Privacy) (requestsByBidder map[openrtb_ext.BidderName]*openrtb.BidRequest, aliases map[string]string, errs []error) {
 
 	impsByBidder, errs := splitImps(orig.Imp)
 	if len(errs) > 0 {
@@ -45,15 +47,24 @@ func cleanOpenRTBRequests(ctx context.Context,
 	consent := extractConsent(orig)
 	ampGDPRException := (labels.RType == pbsmetrics.ReqTypeAMP) && gDPR.AMPException()
 
-	privacyEnforcement := privacy.Enforcement{
-		COPPA: orig.Regs != nil && orig.Regs.COPPA == 1,
+	var ccpaPolicy ccpa.Policy
+	if privacyConfig.CCPA.Enforce {
+		ccpaPolicy, _ = ccpa.ReadPolicy(orig)
+	}
+
+	var lmtPolicy lmt.Policy
+	if privacyConfig.LMT.Enforce {
+		lmtPolicy = lmt.ReadPolicy(orig)
 	}
 
-	if enforceCCPA {
-		ccpaPolicy, _ := ccpa.ReadPolicy(orig)
-		privacyEnforcement.CCPA = ccpaPolicy.ShouldEnforce()
+	// request level privacy policies
+	privacyEnforcement := privacy.Enforcement{
+		CCPA:  ccpaPolicy.ShouldEnforce(),
+		COPPA: orig.Regs != nil && orig.Regs.COPPA == 1,
+		LMT:   lmtPolicy.ShouldEnforce(),
 	}
 
+	// bidder level privacy policies
 	for bidder, bidReq := range requestsByBidder {
 
 		if gdpr == 1 {
diff --git a/go.mod b/go.mod
index 0224057e..72bb9b74 100644
--- a/go.mod
+++ b/go.mod
@@ -1,6 +1,6 @@
 module github.com/prebid/prebid-server
 
-go 1.12
+go 1.13
 
 require (
 	github.com/BurntSushi/toml v0.3.1 // indirect
diff --git a/privacy/enforcement.go b/privacy/enforcement.go
index d302192e..8a5d201f 100644
--- a/privacy/enforcement.go
+++ b/privacy/enforcement.go
@@ -10,11 +10,12 @@ type Enforcement struct {
 	COPPA   bool
 	GDPR    bool
 	GDPRGeo bool
+	LMT     bool
 }
 
 // Any returns true if at least one privacy policy requires enforcement.
 func (e Enforcement) Any() bool {
-	return e.CCPA || e.COPPA || e.GDPR || e.GDPRGeo
+	return e.CCPA || e.COPPA || e.GDPR || e.GDPRGeo || e.LMT
 }
 
 // Apply cleans personally identifiable information from an OpenRTB bid request.
@@ -34,7 +35,7 @@ func (e Enforcement) getIPv6ScrubStrategy() ScrubStrategyIPV6 {
 		return ScrubStrategyIPV6Lowest32
 	}
 
-	if e.GDPR || e.CCPA {
+	if e.GDPR || e.CCPA || e.LMT {
 		return ScrubStrategyIPV6Lowest16
 	}
 
@@ -46,7 +47,7 @@ func (e Enforcement) getGeoScrubStrategy() ScrubStrategyGeo {
 		return ScrubStrategyGeoFull
 	}
 
-	if e.GDPRGeo || e.CCPA {
+	if e.GDPRGeo || e.CCPA || e.LMT {
 		return ScrubStrategyGeoReducedPrecision
 	}
 
@@ -63,7 +64,7 @@ func (e Enforcement) getUserScrubStrategy(ampGDPRException bool) ScrubStrategyUs
 	}
 
 	// If no user scrubbing is needed, then return none, else scrub ID (COPPA checked above)
-	if e.CCPA || e.GDPR {
+	if e.CCPA || e.GDPR || e.LMT {
 		return ScrubStrategyUserID
 	}
 
diff --git a/privacy/lmt/policy.go b/privacy/lmt/policy.go
new file mode 100644
index 00000000..79425bf5
--- /dev/null
+++ b/privacy/lmt/policy.go
@@ -0,0 +1,33 @@
+package lmt
+
+import (
+	"github.com/mxmCherry/openrtb"
+)
+
+const (
+	trackingUnrestricted = 0
+	trackingRestricted   = 1
+)
+
+// Policy represents the LMT (Limit Ad Tracking) policy for an OpenRTB bid request.
+type Policy struct {
+	Signal         int
+	SignalProvided bool
+}
+
+// ReadPolicy extracts the LMT (Limit Ad Tracking) policy from an OpenRTB bid request.
+func ReadPolicy(req *openrtb.BidRequest) Policy {
+	policy := Policy{}
+
+	if req != nil && req.Device != nil && req.Device.Lmt != nil {
+		policy.Signal = int(*req.Device.Lmt)
+		policy.SignalProvided = true
+	}
+
+	return policy
+}
+
+// ShouldEnforce returns true when the LMT (Limit Ad Tracking) policy is in effect.
+func (p Policy) ShouldEnforce() bool {
+	return p.SignalProvided && p.Signal == trackingRestricted
+}
diff --git a/static/adapter/appnexus/opts.json b/static/adapter/appnexus/opts.json
index 7bb297e0..41ee3c8f 100644
--- a/static/adapter/appnexus/opts.json
+++ b/static/adapter/appnexus/opts.json
@@ -5,13 +5,14 @@
     "3": "IAB10-1",
     "4": "IAB2-3",
     "5": "IAB19-8",
+    "6": "IAB22-1",
     "7": "IAB18-1",
-    "8": "IAB14-1",
+    "8": "IAB12-3",
     "9": "IAB5-1",
     "10": "IAB4-5",
     "11": "IAB13-4",
-    "13": "IAB19-2",
     "12": "IAB8-7",
+    "13": "IAB9-7",
     "14": "IAB7-1",
     "15": "IAB20-18",
     "16": "IAB10-7",
@@ -20,33 +21,79 @@
     "19": "IAB18-4",
     "20": "IAB1-5",
     "21": "IAB1-6",
-    "22": "IAB19-28",
+    "22": "IAB3-4",
     "23": "IAB19-13",
     "24": "IAB22-2",
     "25": "IAB3-9",
-    "26": "IAB17-26",
+    "26": "IAB17-18",
     "27": "IAB19-6",
     "28": "IAB1-7",
-    "29": "IAB9-5",
+    "29": "IAB9-30",
     "30": "IAB20-7",
     "31": "IAB20-17",
     "32": "IAB7-32",
     "33": "IAB16-5",
     "34": "IAB19-34",
+    "35": "IAB11-5",
+    "36": "IAB12-3",
     "37": "IAB11-4",
+    "38": "IAB12-3",
     "39": "IAB9-30",
     "41": "IAB7-44",
+    "42": "IAB7-1",
+    "43": "IAB7-30",
+    "50": "IAB19-30",
     "51": "IAB17-12",
+    "52": "IAB19-30",
     "53": "IAB3-1",
     "55": "IAB13-2",
+    "56": "IAB19-30",
+    "57": "IAB19-30",
+    "58": "IAB7-39",
+    "59": "IAB22-1",
+    "60": "IAB7-39",
     "61": "IAB21-3",
-    "62": "IAB6-4",
-    "63": "IAB15-10",
+    "62": "IAB5-1",
+    "63": "IAB12-3",
+    "64": "IAB20-18",
     "65": "IAB11-2",
+    "66": "IAB17-18",
     "67": "IAB9-9",
-    "69": "IAB7-1",
-    "71": "IAB22-2",
+    "68": "IAB9-5",
+    "69": "IAB7-44",
+    "71": "IAB22-3",
+    "73": "IAB19-30",
     "74": "IAB8-5",
-    "87": "IAB3-7"
-  }
+    "78": "IAB22-1",
+    "85": "IAB12-2",
+    "86": "IAB22-3",
+    "87": "IAB11-3",
+    "112": "IAB7-32",
+    "113": "IAB7-32",
+    "114": "IAB7-32",
+    "115": "IAB7-32",
+    "118": "IAB9-5",
+    "119": "IAB9-5",
+    "120": "IAB9-5",
+    "121": "IAB9-5",
+    "122": "IAB9-5",
+    "123": "IAB9-5",
+    "124": "IAB9-5",
+    "125": "IAB9-5",
+    "126": "IAB9-5",
+    "127": "IAB22-1",
+    "132": "IAB1-2",
+    "133": "IAB19-30",
+    "137": "IAB3-9",
+    "138": "IAB19-3",
+    "140": "IAB2-3",
+    "141": "IAB2-1",
+    "142": "IAB2-3",
+    "143": "IAB17-13",
+    "166": "IAB11-4",
+    "175": "IAB3-1",
+    "176": "IAB13-4",
+    "182": "IAB8-9",
+    "183": "IAB3-5"
+    }
 }
diff --git a/static/category-mapping/freewheel/freewheel.json b/static/category-mapping/freewheel/freewheel.json
index 7eebcce0..1c4a4fa2 100644
--- a/static/category-mapping/freewheel/freewheel.json
+++ b/static/category-mapping/freewheel/freewheel.json
@@ -3,1176 +3,1180 @@
     "id": "404",
     "name": "Publishing"
   },
-  "IAB1-2": {
-    "id": "392",
-    "name": "Entertainment"
-  },
-  "IAB1-5": {
-    "id": "419",
-    "name": "Filmed Entertainment"
-  },
-  "IAB1-6": {
-    "id": "392",
-    "name": "Entertainment"
-  },
-  "IAB1-7": {
-    "id": "392",
-    "name": "Entertainment"
-  },
-  "IAB2-1": {
-    "id": "399",
-    "name": "Automotive"
-  },
-  "IAB2-2": {
-    "id": "399",
-    "name": "Automotive"
-  },
-  "IAB2-3": {
-    "id": "399",
-    "name": "Automotive"
-  },
-  "IAB2-4": {
-    "id": "399",
-    "name": "Automotive"
-  },
-  "IAB2-5": {
-    "id": "399",
-    "name": "Automotive"
-  },
-  "IAB2-6": {
-    "id": "399",
-    "name": "Automotive"
-  },
-  "IAB2-7": {
-    "id": "399",
-    "name": "Automotive"
-  },
-  "IAB2-8": {
-    "id": "399",
-    "name": "Automotive"
-  },
-  "IAB2-9": {
-    "id": "399",
-    "name": "Automotive"
-  },
-  "IAB2-10": {
-    "id": "399",
-    "name": "Automotive"
-  },
-  "IAB2-11": {
-    "id": "399",
-    "name": "Automotive"
-  },
-  "IAB2-12": {
-    "id": "399",
-    "name": "Automotive"
-  },
-  "IAB2-13": {
-    "id": "399",
-    "name": "Automotive"
-  },
-  "IAB2-14": {
-    "id": "399",
-    "name": "Automotive"
-  },
-  "IAB2-15": {
-    "id": "399",
-    "name": "Automotive"
-  },
-  "IAB2-16": {
-    "id": "399",
-    "name": "Automotive"
-  },
-  "IAB2-17": {
-    "id": "399",
-    "name": "Automotive"
-  },
-  "IAB2-18": {
-    "id": "399",
-    "name": "Automotive"
-  },
-  "IAB2-19": {
-    "id": "399",
-    "name": "Automotive"
-  },
-  "IAB2-20": {
-    "id": "399",
-    "name": "Automotive"
-  },
-  "IAB2-21": {
-    "id": "399",
-    "name": "Automotive"
-  },
-  "IAB2-22": {
-    "id": "399",
-    "name": "Automotive"
-  },
-  "IAB2-23": {
-    "id": "399",
-    "name": "Automotive"
-  },
-  "IAB3-1": {
-    "id": "393",
-    "name": "Business Services"
-  },
-  "IAB3-2": {
-    "id": "393",
-    "name": "Business Services"
-  },
-  "IAB3-3": {
-    "id": "393",
-    "name": "Business Services"
-  },
-  "IAB3-4": {
-    "id": "409",
-    "name": "Computing Product"
-  },
-  "IAB3-5": {
-    "id": "393",
-    "name": "Business Services"
-  },
-  "IAB3-6": {
-    "id": "393",
-    "name": "Business Services"
-  },
-  "IAB3-7": {
-    "id": "398",
-    "name": "Government/Municipal"
-  },
-  "IAB3-8": {
-    "id": "393",
-    "name": "Business Services"
-  },
-  "IAB3-9": {
-    "id": "393",
-    "name": "Business Services"
-  },
-  "IAB3-10": {
-    "id": "393",
-    "name": "Business Services"
-  },
-  "IAB3-11": {
-    "id": "393",
-    "name": "Business Services"
-  },
-  "IAB3-12": {
-    "id": "393",
-    "name": "Business Services"
-  },
-  "IAB4-1": {
-    "id": "393",
-    "name": "Business Services"
-  },
-  "IAB4-2": {
-    "id": "405",
-    "name": "Educational Services"
-  },
-  "IAB4-3": {
-    "id": "405",
-    "name": "Educational Services"
-  },
-  "IAB4-4": {
-    "id": "393",
-    "name": "Business Services"
-  },
-  "IAB4-5": {
-    "id": "393",
-    "name": "Business Services"
-  },
-  "IAB4-6": {
-    "id": "393",
-    "name": "Business Services"
-  },
-  "IAB4-7": {
-    "id": "406",
-    "name": "Health Care Services"
-  },
-  "IAB4-8": {
-    "id": "405",
-    "name": "Educational Services"
-  },
-  "IAB4-9": {
-    "id": "417",
-    "name": "Telecommunications"
-  },
-  "IAB4-10": {
-    "id": "429",
-    "name": "Military"
-  },
-  "IAB4-11": {
-    "id": "393",
-    "name": "Business Services"
-  },
-  "IAB5-1": {
-    "id": "405",
-    "name": "Educational Services"
-  },
-  "IAB5-2": {
-    "id": "405",
-    "name": "Educational Services"
-  },
-  "IAB5-3": {
-    "id": "405",
-    "name": "Educational Services"
-  },
-  "IAB5-4": {
-    "id": "405",
-    "name": "Educational Services"
-  },
-  "IAB5-5": {
-    "id": "405",
-    "name": "Educational Services"
-  },
-  "IAB5-6": {
-    "id": "405",
-    "name": "Educational Services"
-  },
-  "IAB5-7": {
-    "id": "405",
-    "name": "Educational Services"
-  },
-  "IAB5-8": {
-    "id": "405",
-    "name": "Educational Services"
-  },
-  "IAB5-9": {
-    "id": "405",
-    "name": "Educational Services"
-  },
-  "IAB5-10": {
-    "id": "405",
-    "name": "Educational Services"
-  },
-  "IAB5-11": {
-    "id": "405",
-    "name": "Educational Services"
-  },
-  "IAB5-12": {
-    "id": "405",
-    "name": "Educational Services"
-  },
-  "IAB5-13": {
-    "id": "405",
-    "name": "Educational Services"
-  },
-  "IAB5-14": {
-    "id": "405",
-    "name": "Educational Services"
-  },
-  "IAB5-15": {
-    "id": "405",
-    "name": "Educational Services"
-  },
-  "IAB7-1": {
-    "id": "406",
-    "name": "Health Care Services"
-  },
-  "IAB7-2": {
-    "id": "406",
-    "name": "Health Care Services"
-  },
-  "IAB7-3": {
-    "id": "406",
-    "name": "Health Care Services"
-  },
-  "IAB7-4": {
-    "id": "406",
-    "name": "Health Care Services"
-  },
-  "IAB7-5": {
-    "id": "406",
-    "name": "Health Care Services"
-  },
-  "IAB7-6": {
-    "id": "406",
-    "name": "Health Care Services"
-  },
-  "IAB7-7": {
-    "id": "406",
-    "name": "Health Care Services"
-  },
-  "IAB7-8": {
-    "id": "406",
-    "name": "Health Care Services"
-  },
-  "IAB7-9": {
-    "id": "406",
-    "name": "Health Care Services"
-  },
-  "IAB7-10": {
-    "id": "406",
-    "name": "Health Care Services"
-  },
-  "IAB7-11": {
-    "id": "406",
-    "name": "Health Care Services"
-  },
-  "IAB7-12": {
-    "id": "406",
-    "name": "Health Care Services"
-  },
-  "IAB7-13": {
-    "id": "406",
-    "name": "Health Care Services"
-  },
-  "IAB7-14": {
-    "id": "406",
-    "name": "Health Care Services"
-  },
-  "IAB7-15": {
-    "id": "406",
-    "name": "Health Care Services"
-  },
-  "IAB7-16": {
-    "id": "406",
-    "name": "Health Care Services"
-  },
-  "IAB7-17": {
-    "id": "406",
-    "name": "Health Care Services"
-  },
-  "IAB7-18": {
-    "id": "406",
-    "name": "Health Care Services"
-  },
-  "IAB7-19": {
-    "id": "406",
-    "name": "Health Care Services"
-  },
-  "IAB7-20": {
-    "id": "406",
-    "name": "Health Care Services"
-  },
-  "IAB7-21": {
-    "id": "406",
-    "name": "Health Care Services"
-  },
-  "IAB7-22": {
-    "id": "406",
-    "name": "Health Care Services"
-  },
-  "IAB7-23": {
-    "id": "406",
-    "name": "Health Care Services"
-  },
-  "IAB7-24": {
-    "id": "406",
-    "name": "Health Care Services"
-  },
-  "IAB7-25": {
-    "id": "406",
-    "name": "Health Care Services"
-  },
-  "IAB7-26": {
-    "id": "406",
-    "name": "Health Care Services"
-  },
-  "IAB7-27": {
-    "id": "406",
-    "name": "Health Care Services"
-  },
-  "IAB7-28": {
-    "id": "406",
-    "name": "Health Care Services"
-  },
-  "IAB7-29": {
-    "id": "406",
-    "name": "Health Care Services"
-  },
-  "IAB7-30": {
-    "id": "406",
-    "name": "Health Care Services"
-  },
-  "IAB7-31": {
-    "id": "406",
-    "name": "Health Care Services"
-  },
-  "IAB7-32": {
-    "id": "406",
-    "name": "Health Care Services"
-  },
-  "IAB7-33": {
-    "id": "406",
-    "name": "Health Care Services"
-  },
-  "IAB7-34": {
-    "id": "406",
-    "name": "Health Care Services"
-  },
-  "IAB7-35": {
-    "id": "406",
-    "name": "Health Care Services"
-  },
-  "IAB7-36": {
-    "id": "406",
-    "name": "Health Care Services"
-  },
-  "IAB7-37": {
-    "id": "406",
-    "name": "Health Care Services"
-  },
-  "IAB7-38": {
-    "id": "406",
-    "name": "Health Care Services"
-  },
-  "IAB7-39": {
-    "id": "406",
-    "name": "Health Care Services"
-  },
-  "IAB7-40": {
-    "id": "406",
-    "name": "Health Care Services"
-  },
-  "IAB7-41": {
-    "id": "406",
-    "name": "Health Care Services"
-  },
-  "IAB7-42": {
-    "id": "406",
-    "name": "Health Care Services"
-  },
-  "IAB7-43": {
-    "id": "406",
-    "name": "Health Care Services"
-  },
-  "IAB7-44": {
-    "id": "406",
-    "name": "Health Care Services"
-  },
-  "IAB7-45": {
-    "id": "406",
-    "name": "Health Care Services"
-  },
-  "IAB8-1": {
-    "id": "394",
-    "name": "Food"
-  },
-  "IAB8-2": {
-    "id": "394",
-    "name": "Food"
-  },
-  "IAB8-3": {
-    "id": "394",
-    "name": "Food"
-  },
-  "IAB8-4": {
-    "id": "394",
-    "name": "Food"
-  },
-  "IAB8-5": {
-    "id": "400",
-    "name": "Beer/Wine/Liquor"
-  },
-  "IAB8-6": {
-    "id": "401",
-    "name": "Beverages"
-  },
-  "IAB8-7": {
-    "id": "394",
-    "name": "Food"
-  },
-  "IAB8-8": {
-    "id": "394",
-    "name": "Food"
-  },
-  "IAB8-9": {
-    "id": "407",
-    "name": "Restaurant/Fast Food"
-  },
-  "IAB8-10": {
-    "id": "394",
-    "name": "Food"
-  },
-  "IAB8-11": {
-    "id": "394",
-    "name": "Food"
-  },
-  "IAB8-12": {
-    "id": "394",
-    "name": "Food"
-  },
-  "IAB8-13": {
-    "id": "394",
-    "name": "Food"
-  },
-  "IAB8-14": {
-    "id": "394",
-    "name": "Food"
-  },
-  "IAB8-15": {
-    "id": "394",
-    "name": "Food"
-  },
-  "IAB8-16": {
-    "id": "394",
-    "name": "Food"
-  },
-  "IAB8-17": {
-    "id": "394",
-    "name": "Food"
-  },
-  "IAB8-18": {
-    "id": "400",
-    "name": "Beer/Wine/Liquor"
-  },
-  "IAB9-1": {
-    "id": "392",
-    "name": "Entertainment"
-  },
-  "IAB9-3": {
-    "id": "418",
-    "name": "Jewelry"
-  },
-  "IAB9-5": {
-    "id": "413",
-    "name": "Gaming"
-  },
-  "IAB9-6": {
-    "id": "412",
-    "name": "Household Products"
-  },
-  "IAB9-9": {
-    "id": "426",
-    "name": "Tobacco"
-  },
-  "IAB9-11": {
-    "id": "404",
-    "name": "Publishing"
-  },
-  "IAB9-15": {
-    "id": "404",
-    "name": "Publishing"
-  },
-  "IAB9-16": {
-    "id": "392",
-    "name": "Entertainment"
-  },
-  "IAB9-18": {
-    "id": "393",
-    "name": "Business Services"
-  },
-  "IAB9-19": {
-    "id": "418",
-    "name": "Jewelry"
-  },
-  "IAB9-23": {
-    "id": "424",
-    "name": "Photographic Equipment"
-  },
-  "IAB9-24": {
-    "id": "392",
-    "name": "Entertainment"
-  },
-  "IAB9-25": {
-    "id": "392",
-    "name": "Entertainment"
-  },
-  "IAB9-30": {
-    "id": "413",
-    "name": "Gaming"
-  },
-  "IAB10-1": {
-    "id": "415",
-    "name": "Appliances"
-  },
-  "IAB10-5": {
-    "id": "434",
-    "name": "Home Furnishings"
-  },
-  "IAB10-6": {
-    "id": "434",
-    "name": "Home Furnishings"
-  },
-  "IAB10-7": {
-    "id": "434",
-    "name": "Home Furnishings"
-  },
-  "IAB10-8": {
-    "id": "393",
-    "name": "Business Services"
-  },
-  "IAB10-9": {
-    "id": "434",
-    "name": "Home Furnishings"
-  },
-  "IAB11-1": {
-    "id": "398",
-    "name": "Government/Municipal"
-  },
-  "IAB11-2": {
-    "id": "398",
-    "name": "Government/Municipal"
-  },
-  "IAB11-3": {
-    "id": "398",
-    "name": "Government/Municipal"
-  },
-  "IAB11-4": {
-    "id": "398",
-    "name": "Government/Municipal"
-  },
-  "IAB11-5": {
-    "id": "398",
-    "name": "Government/Municipal"
-  },
-  "IAB12-1": {
-    "id": "438",
-    "name": "News"
-  },
-  "IAB12-2": {
-    "id": "438",
-    "name": "News"
-  },
-  "IAB12-3": {
-    "id": "438",
-    "name": "News"
-  },
-  "IAB13-1": {
-    "id": "393",
-    "name": "Business Services"
-  },
-  "IAB13-2": {
-    "id": "393",
-    "name": "Business Services"
-  },
-  "IAB13-3": {
-    "id": "438",
-    "name": "News"
-  },
-  "IAB13-4": {
-    "id": "391",
-    "name": "Financial Services"
-  },
-  "IAB13-5": {
-    "id": "393",
-    "name": "Business Services"
-  },
-  "IAB13-6": {
-    "id": "436",
-    "name": "Insurance"
-  },
-  "IAB13-7": {
-    "id": "393",
-    "name": "Business Services"
-  },
-  "IAB13-8": {
-    "id": "393",
-    "name": "Business Services"
-  },
-  "IAB13-9": {
-    "id": "393",
-    "name": "Business Services"
-  },
-  "IAB13-10": {
-    "id": "393",
-    "name": "Business Services"
-  },
-  "IAB13-11": {
-    "id": "393",
-    "name": "Business Services"
-  },
-  "IAB13-12": {
-    "id": "393",
-    "name": "Business Services"
-  },
-  "IAB16-1": {
-    "id": "423",
-    "name": "Pet Food/Supplies"
-  },
-  "IAB16-2": {
-    "id": "423",
-    "name": "Pet Food/Supplies"
-  },
-  "IAB16-3": {
-    "id": "423",
-    "name": "Pet Food/Supplies"
-  },
-  "IAB16-4": {
-    "id": "423",
-    "name": "Pet Food/Supplies"
-  },
-  "IAB16-5": {
-    "id": "423",
-    "name": "Pet Food/Supplies"
-  },
-  "IAB16-6": {
-    "id": "423",
-    "name": "Pet Food/Supplies"
-  },
-  "IAB16-7": {
-    "id": "423",
-    "name": "Pet Food/Supplies"
-  },
-  "IAB17-1": {
-    "id": "425",
-    "name": "Professional Sports"
-  },
-  "IAB17-2": {
-    "id": "425",
-    "name": "Professional Sports"
-  },
-  "IAB17-3": {
-    "id": "425",
-    "name": "Professional Sports"
-  },
-  "IAB17-4": {
-    "id": "425",
-    "name": "Professional Sports"
-  },
-  "IAB17-5": {
-    "id": "425",
-    "name": "Professional Sports"
-  },
-  "IAB17-6": {
-    "id": "425",
-    "name": "Professional Sports"
-  },
-  "IAB17-7": {
-    "id": "425",
-    "name": "Professional Sports"
-  },
-  "IAB17-8": {
-    "id": "425",
-    "name": "Professional Sports"
-  },
-  "IAB17-9": {
-    "id": "425",
-    "name": "Professional Sports"
-  },
-  "IAB17-10": {
-    "id": "425",
-    "name": "Professional Sports"
-  },
-  "IAB17-11": {
-    "id": "425",
-    "name": "Professional Sports"
-  },
-  "IAB17-12": {
-    "id": "425",
-    "name": "Professional Sports"
-  },
-  "IAB17-13": {
-    "id": "425",
-    "name": "Professional Sports"
-  },
-  "IAB17-14": {
-    "id": "425",
-    "name": "Professional Sports"
-  },
-  "IAB17-15": {
-    "id": "425",
-    "name": "Professional Sports"
-  },
-  "IAB17-16": {
-    "id": "425",
-    "name": "Professional Sports"
-  },
-  "IAB17-17": {
-    "id": "425",
-    "name": "Professional Sports"
-  },
-  "IAB17-18": {
-    "id": "425",
-    "name": "Professional Sports"
-  },
-  "IAB17-19": {
-    "id": "425",
-    "name": "Professional Sports"
-  },
-  "IAB17-20": {
-    "id": "425",
-    "name": "Professional Sports"
-  },
-  "IAB17-21": {
-    "id": "425",
-    "name": "Professional Sports"
-  },
-  "IAB17-22": {
-    "id": "425",
-    "name": "Professional Sports"
-  },
-  "IAB17-23": {
-    "id": "425",
-    "name": "Professional Sports"
-  },
-  "IAB17-24": {
-    "id": "425",
-    "name": "Professional Sports"
-  },
-  "IAB17-25": {
-    "id": "425",
-    "name": "Professional Sports"
-  },
-  "IAB17-26": {
-    "id": "425",
-    "name": "Professional Sports"
-  },
-  "IAB17-27": {
-    "id": "425",
-    "name": "Professional Sports"
-  },
-  "IAB17-28": {
-    "id": "425",
-    "name": "Professional Sports"
-  },
-  "IAB17-29": {
-    "id": "425",
-    "name": "Professional Sports"
-  },
-  "IAB17-30": {
-    "id": "425",
-    "name": "Professional Sports"
-  },
-  "IAB17-31": {
-    "id": "425",
-    "name": "Professional Sports"
-  },
-  "IAB17-32": {
-    "id": "425",
-    "name": "Professional Sports"
-  },
-  "IAB17-33": {
-    "id": "425",
-    "name": "Professional Sports"
-  },
-  "IAB17-34": {
-    "id": "425",
-    "name": "Professional Sports"
-  },
-  "IAB17-35": {
-    "id": "425",
-    "name": "Professional Sports"
-  },
-  "IAB17-36": {
-    "id": "425",
-    "name": "Professional Sports"
-  },
-  "IAB17-37": {
-    "id": "425",
-    "name": "Professional Sports"
-  },
-  "IAB17-38": {
-    "id": "425",
-    "name": "Professional Sports"
-  },
-  "IAB17-39": {
-    "id": "425",
-    "name": "Professional Sports"
-  },
-  "IAB17-40": {
-    "id": "425",
-    "name": "Professional Sports"
-  },
-  "IAB17-41": {
-    "id": "425",
-    "name": "Professional Sports"
-  },
-  "IAB17-42": {
-    "id": "425",
-    "name": "Professional Sports"
-  },
-  "IAB17-43": {
-    "id": "425",
-    "name": "Professional Sports"
-  },
-  "IAB17-44": {
-    "id": "425",
-    "name": "Professional Sports"
-  },
-  "IAB18-1": {
-    "id": "411",
-    "name": "Cosmetics/Toiletries"
-  },
-  "IAB18-2": {
-    "id": "397",
-    "name": "Apparel"
-  },
-  "IAB18-3": {
-    "id": "397",
-    "name": "Apparel"
-  },
-  "IAB18-4": {
-    "id": "418",
-    "name": "Jewelry"
-  },
-  "IAB18-5": {
-    "id": "397",
-    "name": "Apparel"
-  },
-  "IAB18-6": {
-    "id": "397",
-    "name": "Apparel"
-  },
-  "IAB19-2": {
-    "id": "409",
-    "name": "Computing Product"
-  },
-  "IAB19-3": {
-    "id": "409",
-    "name": "Computing Product"
-  },
-  "IAB19-4": {
-    "id": "409",
-    "name": "Computing Product"
-  },
-  "IAB19-5": {
-    "id": "424",
-    "name": "Photographic Equipment"
-  },
-  "IAB19-6": {
-    "id": "417",
-    "name": "Telecommunications"
-  },
-  "IAB19-7": {
-    "id": "409",
-    "name": "Computing Product"
-  },
-  "IAB19-8": {
-    "id": "409",
-    "name": "Computing Product"
-  },
-  "IAB19-9": {
-    "id": "409",
-    "name": "Computing Product"
-  },
-  "IAB19-10": {
-    "id": "409",
-    "name": "Computing Product"
-  },
-  "IAB19-11": {
-    "id": "409",
-    "name": "Computing Product"
-  },
-  "IAB19-12": {
-    "id": "409",
-    "name": "Computing Product"
-  },
-  "IAB19-13": {
-    "id": "404",
-    "name": "Publishing"
-  },
-  "IAB19-14": {
-    "id": "409",
-    "name": "Computing Product"
-  },
-  "IAB19-15": {
-    "id": "409",
-    "name": "Computing Product"
-  },
-  "IAB19-16": {
-    "id": "409",
-    "name": "Computing Product"
-  },
-  "IAB19-17": {
-    "id": "419",
-    "name": "Filmed Entertainment"
-  },
-  "IAB19-18": {
-    "id": "409",
-    "name": "Computing Product"
-  },
-  "IAB19-19": {
-    "id": "409",
-    "name": "Computing Product"
-  },
-  "IAB19-20": {
-    "id": "409",
-    "name": "Computing Product"
-  },
-  "IAB19-21": {
-    "id": "409",
-    "name": "Computing Product"
-  },
-  "IAB19-22": {
-    "id": "409",
-    "name": "Computing Product"
-  },
-  "IAB19-23": {
-    "id": "409",
-    "name": "Computing Product"
-  },
-  "IAB19-24": {
-    "id": "409",
-    "name": "Computing Product"
-  },
-  "IAB19-25": {
-    "id": "409",
-    "name": "Computing Product"
-  },
-  "IAB19-26": {
-    "id": "409",
-    "name": "Computing Product"
-  },
-  "IAB19-27": {
-    "id": "409",
-    "name": "Computing Product"
-  },
-  "IAB19-28": {
-    "id": "409",
-    "name": "Computing Product"
-  },
-  "IAB19-29": {
-    "id": "392",
-    "name": "Entertainment"
-  },
-  "IAB19-30": {
-    "id": "409",
-    "name": "Computing Product"
-  },
-  "IAB19-31": {
-    "id": "409",
-    "name": "Computing Product"
-  },
-  "IAB19-32": {
-    "id": "409",
-    "name": "Computing Product"
-  },
-  "IAB19-33": {
-    "id": "409",
-    "name": "Computing Product"
-  },
-  "IAB19-34": {
-    "id": "409",
-    "name": "Computing Product"
-  },
-  "IAB19-35": {
-    "id": "409",
-    "name": "Computing Product"
-  },
-  "IAB19-36": {
-    "id": "409",
-    "name": "Computing Product"
-  },
-  "IAB20-1": {
-    "id": "395",
-    "name": "Travel/Hotels/Airlines"
-  },
-  "IAB20-2": {
-    "id": "395",
-    "name": "Travel/Hotels/Airlines"
-  },
-  "IAB20-3": {
-    "id": "395",
-    "name": "Travel/Hotels/Airlines"
-  },
-  "IAB20-4": {
-    "id": "395",
-    "name": "Travel/Hotels/Airlines"
-  },
-  "IAB20-5": {
-    "id": "395",
-    "name": "Travel/Hotels/Airlines"
-  },
-  "IAB20-6": {
-    "id": "395",
-    "name": "Travel/Hotels/Airlines"
-  },
-  "IAB20-7": {
-    "id": "395",
-    "name": "Travel/Hotels/Airlines"
-  },
-  "IAB20-8": {
-    "id": "395",
-    "name": "Travel/Hotels/Airlines"
-  },
-  "IAB20-9": {
-    "id": "395",
-    "name": "Travel/Hotels/Airlines"
-  },
-  "IAB20-10": {
-    "id": "395",
-    "name": "Travel/Hotels/Airlines"
-  },
-  "IAB20-11": {
-    "id": "395",
-    "name": "Travel/Hotels/Airlines"
-  },
-  "IAB20-12": {
-    "id": "395",
-    "name": "Travel/Hotels/Airlines"
-  },
-  "IAB20-13": {
-    "id": "395",
-    "name": "Travel/Hotels/Airlines"
-  },
-  "IAB20-14": {
-    "id": "395",
-    "name": "Travel/Hotels/Airlines"
-  },
-  "IAB20-15": {
-    "id": "395",
-    "name": "Travel/Hotels/Airlines"
-  },
-  "IAB20-16": {
-    "id": "395",
-    "name": "Travel/Hotels/Airlines"
-  },
-  "IAB20-17": {
-    "id": "395",
-    "name": "Travel/Hotels/Airlines"
-  },
-  "IAB20-18": {
-    "id": "395",
-    "name": "Travel/Hotels/Airlines"
-  },
-  "IAB20-19": {
-    "id": "395",
-    "name": "Travel/Hotels/Airlines"
-  },
-  "IAB20-20": {
-    "id": "395",
-    "name": "Travel/Hotels/Airlines"
-  },
-  "IAB20-21": {
-    "id": "395",
-    "name": "Travel/Hotels/Airlines"
-  },
-  "IAB20-22": {
-    "id": "395",
-    "name": "Travel/Hotels/Airlines"
-  },
-  "IAB20-23": {
-    "id": "395",
-    "name": "Travel/Hotels/Airlines"
-  },
-  "IAB20-24": {
-    "id": "395",
-    "name": "Travel/Hotels/Airlines"
-  },
-  "IAB20-25": {
-    "id": "395",
-    "name": "Travel/Hotels/Airlines"
-  },
-  "IAB20-26": {
-    "id": "395",
-    "name": "Travel/Hotels/Airlines"
-  },
-  "IAB20-27": {
-    "id": "395",
-    "name": "Travel/Hotels/Airlines"
-  },
-  "IAB21-1": {
-    "id": "416",
-    "name": "Real Estate"
-  },
-  "IAB21-2": {
-    "id": "416",
-    "name": "Real Estate"
-  },
-  "IAB21-3": {
-    "id": "416",
-    "name": "Real Estate"
-  },
-  "IAB22-1": {
-    "id": "416",
-    "name": "Real Estate"
-  },
-  "IAB22-2": {
-    "id": "416",
-    "name": "Real Estate"
-  },
-  "IAB22-3": {
-    "id": "416",
-    "name": "Real Estate"
-  }
+	"IAB1-2": {
+		"id": "392",
+		"name": "Entertainment"
+	},
+	"IAB1-5": {
+		"id": "419",
+		"name": "Filmed Entertainment"
+	},
+	"IAB1-6": {
+		"id": "392",
+		"name": "Entertainment"
+	},
+	"IAB1-7": {
+		"id": "392",
+		"name": "Entertainment"
+	},
+	"IAB2-1": {
+		"id": "399",
+		"name": "Automotive"
+	},
+	"IAB2-2": {
+		"id": "399",
+		"name": "Automotive"
+	},
+	"IAB2-3": {
+		"id": "399",
+		"name": "Automotive"
+	},
+	"IAB2-4": {
+		"id": "399",
+		"name": "Automotive"
+	},
+	"IAB2-5": {
+		"id": "399",
+		"name": "Automotive"
+	},
+	"IAB2-6": {
+		"id": "399",
+		"name": "Automotive"
+	},
+	"IAB2-7": {
+		"id": "399",
+		"name": "Automotive"
+	},
+	"IAB2-8": {
+		"id": "399",
+		"name": "Automotive"
+	},
+	"IAB2-9": {
+		"id": "399",
+		"name": "Automotive"
+	},
+	"IAB2-10": {
+		"id": "399",
+		"name": "Automotive"
+	},
+	"IAB2-11": {
+		"id": "399",
+		"name": "Automotive"
+	},
+	"IAB2-12": {
+		"id": "399",
+		"name": "Automotive"
+	},
+	"IAB2-13": {
+		"id": "399",
+		"name": "Automotive"
+	},
+	"IAB2-14": {
+		"id": "399",
+		"name": "Automotive"
+	},
+	"IAB2-15": {
+		"id": "399",
+		"name": "Automotive"
+	},
+	"IAB2-16": {
+		"id": "399",
+		"name": "Automotive"
+	},
+	"IAB2-17": {
+		"id": "399",
+		"name": "Automotive"
+	},
+	"IAB2-18": {
+		"id": "399",
+		"name": "Automotive"
+	},
+	"IAB2-19": {
+		"id": "399",
+		"name": "Automotive"
+	},
+	"IAB2-20": {
+		"id": "399",
+		"name": "Automotive"
+	},
+	"IAB2-21": {
+		"id": "399",
+		"name": "Automotive"
+	},
+	"IAB2-22": {
+		"id": "399",
+		"name": "Automotive"
+	},
+	"IAB2-23": {
+		"id": "399",
+		"name": "Automotive"
+	},
+	"IAB3-1": {
+		"id": "393",
+		"name": "Business Services"
+	},
+	"IAB3-2": {
+		"id": "393",
+		"name": "Business Services"
+	},
+	"IAB3-3": {
+		"id": "393",
+		"name": "Business Services"
+	},
+	"IAB3-4": {
+		"id": "408",
+		"name": "Office Equipment/Supplies"
+	},
+	"IAB3-5": {
+		"id": "390",
+		"name": "Manufacturing"
+	},
+	"IAB3-6": {
+		"id": "393",
+		"name": "Business Services"
+	},
+	"IAB3-7": {
+		"id": "398",
+		"name": "Government/Municipal"
+	},
+	"IAB3-8": {
+		"id": "393",
+		"name": "Business Services"
+	},
+	"IAB3-9": {
+		"id": "393",
+		"name": "Business Services"
+	},
+	"IAB3-10": {
+		"id": "393",
+		"name": "Business Services"
+	},
+	"IAB3-11": {
+		"id": "393",
+		"name": "Business Services"
+	},
+	"IAB3-12": {
+		"id": "393",
+		"name": "Business Services"
+	},
+	"IAB4-1": {
+		"id": "393",
+		"name": "Business Services"
+	},
+	"IAB4-2": {
+		"id": "405",
+		"name": "Educational Services"
+	},
+	"IAB4-3": {
+		"id": "405",
+		"name": "Educational Services"
+	},
+	"IAB4-4": {
+		"id": "393",
+		"name": "Business Services"
+	},
+	"IAB4-5": {
+		"id": "393",
+		"name": "Business Services"
+	},
+	"IAB4-6": {
+		"id": "393",
+		"name": "Business Services"
+	},
+	"IAB4-7": {
+		"id": "406",
+		"name": "Health Care Services"
+	},
+	"IAB4-8": {
+		"id": "405",
+		"name": "Educational Services"
+	},
+	"IAB4-9": {
+		"id": "417",
+		"name": "Telecommunications"
+	},
+	"IAB4-10": {
+		"id": "429",
+		"name": "Military"
+	},
+	"IAB4-11": {
+		"id": "393",
+		"name": "Business Services"
+	},
+	"IAB5-1": {
+		"id": "405",
+		"name": "Educational Services"
+	},
+	"IAB5-2": {
+		"id": "405",
+		"name": "Educational Services"
+	},
+	"IAB5-3": {
+		"id": "405",
+		"name": "Educational Services"
+	},
+	"IAB5-4": {
+		"id": "405",
+		"name": "Educational Services"
+	},
+	"IAB5-5": {
+		"id": "405",
+		"name": "Educational Services"
+	},
+	"IAB5-6": {
+		"id": "405",
+		"name": "Educational Services"
+	},
+	"IAB5-7": {
+		"id": "405",
+		"name": "Educational Services"
+	},
+	"IAB5-8": {
+		"id": "405",
+		"name": "Educational Services"
+	},
+	"IAB5-9": {
+		"id": "405",
+		"name": "Educational Services"
+	},
+	"IAB5-10": {
+		"id": "405",
+		"name": "Educational Services"
+	},
+	"IAB5-11": {
+		"id": "405",
+		"name": "Educational Services"
+	},
+	"IAB5-12": {
+		"id": "405",
+		"name": "Educational Services"
+	},
+	"IAB5-13": {
+		"id": "405",
+		"name": "Educational Services"
+	},
+	"IAB5-14": {
+		"id": "405",
+		"name": "Educational Services"
+	},
+	"IAB5-15": {
+		"id": "405",
+		"name": "Educational Services"
+	},
+	"IAB7-1": {
+		"id": "406",
+		"name": "Health Care Services"
+	},
+	"IAB7-2": {
+		"id": "406",
+		"name": "Health Care Services"
+	},
+	"IAB7-3": {
+		"id": "406",
+		"name": "Health Care Services"
+	},
+	"IAB7-4": {
+		"id": "406",
+		"name": "Health Care Services"
+	},
+	"IAB7-5": {
+		"id": "406",
+		"name": "Health Care Services"
+	},
+	"IAB7-6": {
+		"id": "406",
+		"name": "Health Care Services"
+	},
+	"IAB7-7": {
+		"id": "406",
+		"name": "Health Care Services"
+	},
+	"IAB7-8": {
+		"id": "406",
+		"name": "Health Care Services"
+	},
+	"IAB7-9": {
+		"id": "406",
+		"name": "Health Care Services"
+	},
+	"IAB7-10": {
+		"id": "406",
+		"name": "Health Care Services"
+	},
+	"IAB7-11": {
+		"id": "406",
+		"name": "Health Care Services"
+	},
+	"IAB7-12": {
+		"id": "406",
+		"name": "Health Care Services"
+	},
+	"IAB7-13": {
+		"id": "406",
+		"name": "Health Care Services"
+	},
+	"IAB7-14": {
+		"id": "406",
+		"name": "Health Care Services"
+	},
+	"IAB7-15": {
+		"id": "406",
+		"name": "Health Care Services"
+	},
+	"IAB7-16": {
+		"id": "406",
+		"name": "Health Care Services"
+	},
+	"IAB7-17": {
+		"id": "406",
+		"name": "Health Care Services"
+	},
+	"IAB7-18": {
+		"id": "406",
+		"name": "Health Care Services"
+	},
+	"IAB7-19": {
+		"id": "406",
+		"name": "Health Care Services"
+	},
+	"IAB7-20": {
+		"id": "406",
+		"name": "Health Care Services"
+	},
+	"IAB7-21": {
+		"id": "406",
+		"name": "Health Care Services"
+	},
+	"IAB7-22": {
+		"id": "406",
+		"name": "Health Care Services"
+	},
+	"IAB7-23": {
+		"id": "406",
+		"name": "Health Care Services"
+	},
+	"IAB7-24": {
+		"id": "406",
+		"name": "Health Care Services"
+	},
+	"IAB7-25": {
+		"id": "406",
+		"name": "Health Care Services"
+	},
+	"IAB7-26": {
+		"id": "406",
+		"name": "Health Care Services"
+	},
+	"IAB7-27": {
+		"id": "406",
+		"name": "Health Care Services"
+	},
+	"IAB7-28": {
+		"id": "406",
+		"name": "Health Care Services"
+	},
+	"IAB7-29": {
+		"id": "406",
+		"name": "Health Care Services"
+	},
+	"IAB7-30": {
+		"id": "406",
+		"name": "Health Care Services"
+	},
+	"IAB7-31": {
+		"id": "406",
+		"name": "Health Care Services"
+	},
+	"IAB7-32": {
+		"id": "402",
+		"name": "Pharmaceuticals"
+	},
+	"IAB7-33": {
+		"id": "406",
+		"name": "Health Care Services"
+	},
+	"IAB7-34": {
+		"id": "406",
+		"name": "Health Care Services"
+	},
+	"IAB7-35": {
+		"id": "406",
+		"name": "Health Care Services"
+	},
+	"IAB7-36": {
+		"id": "406",
+		"name": "Health Care Services"
+	},
+	"IAB7-37": {
+		"id": "406",
+		"name": "Health Care Services"
+	},
+	"IAB7-38": {
+		"id": "406",
+		"name": "Health Care Services"
+	},
+	"IAB7-39": {
+		"id": "406",
+		"name": "Health Care Services"
+	},
+	"IAB7-40": {
+		"id": "406",
+		"name": "Health Care Services"
+	},
+	"IAB7-41": {
+		"id": "406",
+		"name": "Health Care Services"
+	},
+	"IAB7-42": {
+		"id": "406",
+		"name": "Health Care Services"
+	},
+	"IAB7-43": {
+		"id": "406",
+		"name": "Health Care Services"
+	},
+	"IAB7-44": {
+		"id": "433",
+		"name": "Drug Stores"
+	},
+	"IAB7-45": {
+		"id": "406",
+		"name": "Health Care Services"
+	},
+	"IAB8-1": {
+		"id": "394",
+		"name": "Food"
+	},
+	"IAB8-2": {
+		"id": "394",
+		"name": "Food"
+	},
+	"IAB8-3": {
+		"id": "394",
+		"name": "Food"
+	},
+	"IAB8-4": {
+		"id": "394",
+		"name": "Food"
+	},
+	"IAB8-5": {
+		"id": "400",
+		"name": "Beer/Wine/Liquor"
+	},
+	"IAB8-6": {
+		"id": "401",
+		"name": "Beverages"
+	},
+	"IAB8-7": {
+		"id": "394",
+		"name": "Food"
+	},
+	"IAB8-8": {
+		"id": "394",
+		"name": "Food"
+	},
+	"IAB8-9": {
+		"id": "407",
+		"name": "Restaurant/Fast Food"
+	},
+	"IAB8-10": {
+		"id": "394",
+		"name": "Food"
+	},
+	"IAB8-11": {
+		"id": "394",
+		"name": "Food"
+	},
+	"IAB8-12": {
+		"id": "394",
+		"name": "Food"
+	},
+	"IAB8-13": {
+		"id": "394",
+		"name": "Food"
+	},
+	"IAB8-14": {
+		"id": "394",
+		"name": "Food"
+	},
+	"IAB8-15": {
+		"id": "394",
+		"name": "Food"
+	},
+	"IAB8-16": {
+		"id": "394",
+		"name": "Food"
+	},
+	"IAB8-17": {
+		"id": "394",
+		"name": "Food"
+	},
+	"IAB8-18": {
+		"id": "400",
+		"name": "Beer/Wine/Liquor"
+	},
+	"IAB9-1": {
+		"id": "392",
+		"name": "Entertainment"
+	},
+	"IAB9-3": {
+		"id": "418",
+		"name": "Jewelry"
+	},
+	"IAB9-5": {
+		"id": "414",
+		"name": "Gambling"
+	},
+	"IAB9-6": {
+		"id": "412",
+		"name": "Household Products"
+	},
+	"IAB9-7": {
+		"id": "413",
+		"name": "Gaming"
+	},
+	"IAB9-9": {
+		"id": "426",
+		"name": "Tobacco"
+	},
+	"IAB9-11": {
+		"id": "404",
+		"name": "Publishing"
+	},
+	"IAB9-15": {
+		"id": "404",
+		"name": "Publishing"
+	},
+	"IAB9-16": {
+		"id": "392",
+		"name": "Entertainment"
+	},
+	"IAB9-18": {
+		"id": "393",
+		"name": "Business Services"
+	},
+	"IAB9-19": {
+		"id": "418",
+		"name": "Jewelry"
+	},
+	"IAB9-23": {
+		"id": "424",
+		"name": "Photographic Equipment"
+	},
+	"IAB9-24": {
+		"id": "392",
+		"name": "Entertainment"
+	},
+	"IAB9-25": {
+		"id": "392",
+		"name": "Entertainment"
+	},
+	"IAB9-30": {
+		"id": "427",
+		"name": "Toys/Games"
+	},
+	"IAB10-1": {
+		"id": "415",
+		"name": "Appliances"
+	},
+	"IAB10-5": {
+		"id": "434",
+		"name": "Home Furnishings"
+	},
+	"IAB10-6": {
+		"id": "434",
+		"name": "Home Furnishings"
+	},
+	"IAB10-7": {
+		"id": "434",
+		"name": "Home Furnishings"
+	},
+	"IAB10-8": {
+		"id": "393",
+		"name": "Business Services"
+	},
+	"IAB10-9": {
+		"id": "434",
+		"name": "Home Furnishings"
+	},
+	"IAB11-1": {
+		"id": "398",
+		"name": "Government/Municipal"
+	},
+	"IAB11-2": {
+		"id": "398",
+		"name": "Government/Municipal"
+	},
+	"IAB11-3": {
+		"id": "398",
+		"name": "Government/Municipal"
+	},
+	"IAB11-4": {
+		"id": "398",
+		"name": "Government/Municipal"
+	},
+	"IAB11-5": {
+		"id": "421",
+		"name": "Associations"
+	},
+	"IAB12-1": {
+		"id": "438",
+		"name": "News"
+	},
+	"IAB12-2": {
+		"id": "438",
+		"name": "News"
+	},
+	"IAB12-3": {
+		"id": "438",
+		"name": "News"
+	},
+	"IAB13-1": {
+		"id": "393",
+		"name": "Business Services"
+	},
+	"IAB13-2": {
+		"id": "393",
+		"name": "Business Services"
+	},
+	"IAB13-3": {
+		"id": "438",
+		"name": "News"
+	},
+	"IAB13-4": {
+		"id": "391",
+		"name": "Financial Services"
+	},
+	"IAB13-5": {
+		"id": "393",
+		"name": "Business Services"
+	},
+	"IAB13-6": {
+		"id": "436",
+		"name": "Insurance"
+	},
+	"IAB13-7": {
+		"id": "393",
+		"name": "Business Services"
+	},
+	"IAB13-8": {
+		"id": "393",
+		"name": "Business Services"
+	},
+	"IAB13-9": {
+		"id": "393",
+		"name": "Business Services"
+	},
+	"IAB13-10": {
+		"id": "393",
+		"name": "Business Services"
+	},
+	"IAB13-11": {
+		"id": "393",
+		"name": "Business Services"
+	},
+	"IAB13-12": {
+		"id": "393",
+		"name": "Business Services"
+	},
+	"IAB16-1": {
+		"id": "423",
+		"name": "Pet Food/Supplies"
+	},
+	"IAB16-2": {
+		"id": "423",
+		"name": "Pet Food/Supplies"
+	},
+	"IAB16-3": {
+		"id": "423",
+		"name": "Pet Food/Supplies"
+	},
+	"IAB16-4": {
+		"id": "423",
+		"name": "Pet Food/Supplies"
+	},
+	"IAB16-5": {
+		"id": "423",
+		"name": "Pet Food/Supplies"
+	},
+	"IAB16-6": {
+		"id": "423",
+		"name": "Pet Food/Supplies"
+	},
+	"IAB16-7": {
+		"id": "423",
+		"name": "Pet Food/Supplies"
+	},
+	"IAB17-1": {
+		"id": "425",
+		"name": "Professional Sports"
+	},
+	"IAB17-2": {
+		"id": "425",
+		"name": "Professional Sports"
+	},
+	"IAB17-3": {
+		"id": "425",
+		"name": "Professional Sports"
+	},
+	"IAB17-4": {
+		"id": "425",
+		"name": "Professional Sports"
+	},
+	"IAB17-5": {
+		"id": "425",
+		"name": "Professional Sports"
+	},
+	"IAB17-6": {
+		"id": "425",
+		"name": "Professional Sports"
+	},
+	"IAB17-7": {
+		"id": "425",
+		"name": "Professional Sports"
+	},
+	"IAB17-8": {
+		"id": "425",
+		"name": "Professional Sports"
+	},
+	"IAB17-9": {
+		"id": "425",
+		"name": "Professional Sports"
+	},
+	"IAB17-10": {
+		"id": "425",
+		"name": "Professional Sports"
+	},
+	"IAB17-11": {
+		"id": "425",
+		"name": "Professional Sports"
+	},
+	"IAB17-12": {
+		"id": "425",
+		"name": "Professional Sports"
+	},
+	"IAB17-13": {
+		"id": "425",
+		"name": "Professional Sports"
+	},
+	"IAB17-14": {
+		"id": "425",
+		"name": "Professional Sports"
+	},
+	"IAB17-15": {
+		"id": "425",
+		"name": "Professional Sports"
+	},
+	"IAB17-16": {
+		"id": "425",
+		"name": "Professional Sports"
+	},
+	"IAB17-17": {
+		"id": "425",
+		"name": "Professional Sports"
+	},
+	"IAB17-18": {
+		"id": "412",
+		"name": "Household Products"
+	},
+	"IAB17-19": {
+		"id": "425",
+		"name": "Professional Sports"
+	},
+	"IAB17-20": {
+		"id": "425",
+		"name": "Professional Sports"
+	},
+	"IAB17-21": {
+		"id": "425",
+		"name": "Professional Sports"
+	},
+	"IAB17-22": {
+		"id": "425",
+		"name": "Professional Sports"
+	},
+	"IAB17-23": {
+		"id": "425",
+		"name": "Professional Sports"
+	},
+	"IAB17-24": {
+		"id": "425",
+		"name": "Professional Sports"
+	},
+	"IAB17-25": {
+		"id": "425",
+		"name": "Professional Sports"
+	},
+	"IAB17-26": {
+		"id": "425",
+		"name": "Professional Sports"
+	},
+	"IAB17-27": {
+		"id": "425",
+		"name": "Professional Sports"
+	},
+	"IAB17-28": {
+		"id": "425",
+		"name": "Professional Sports"
+	},
+	"IAB17-29": {
+		"id": "425",
+		"name": "Professional Sports"
+	},
+	"IAB17-30": {
+		"id": "425",
+		"name": "Professional Sports"
+	},
+	"IAB17-31": {
+		"id": "425",
+		"name": "Professional Sports"
+	},
+	"IAB17-32": {
+		"id": "425",
+		"name": "Professional Sports"
+	},
+	"IAB17-33": {
+		"id": "425",
+		"name": "Professional Sports"
+	},
+	"IAB17-34": {
+		"id": "425",
+		"name": "Professional Sports"
+	},
+	"IAB17-35": {
+		"id": "425",
+		"name": "Professional Sports"
+	},
+	"IAB17-36": {
+		"id": "425",
+		"name": "Professional Sports"
+	},
+	"IAB17-37": {
+		"id": "425",
+		"name": "Professional Sports"
+	},
+	"IAB17-38": {
+		"id": "425",
+		"name": "Professional Sports"
+	},
+	"IAB17-39": {
+		"id": "425",
+		"name": "Professional Sports"
+	},
+	"IAB17-40": {
+		"id": "425",
+		"name": "Professional Sports"
+	},
+	"IAB17-41": {
+		"id": "425",
+		"name": "Professional Sports"
+	},
+	"IAB17-42": {
+		"id": "425",
+		"name": "Professional Sports"
+	},
+	"IAB17-43": {
+		"id": "425",
+		"name": "Professional Sports"
+	},
+	"IAB17-44": {
+		"id": "425",
+		"name": "Professional Sports"
+	},
+	"IAB18-1": {
+		"id": "411",
+		"name": "Cosmetics/Toiletries"
+	},
+	"IAB18-2": {
+		"id": "397",
+		"name": "Apparel"
+	},
+	"IAB18-3": {
+		"id": "397",
+		"name": "Apparel"
+	},
+	"IAB18-4": {
+		"id": "418",
+		"name": "Jewelry"
+	},
+	"IAB18-5": {
+		"id": "397",
+		"name": "Apparel"
+	},
+	"IAB18-6": {
+		"id": "397",
+		"name": "Apparel"
+	},
+	"IAB19-2": {
+		"id": "409",
+		"name": "Computing Product"
+	},
+	"IAB19-3": {
+		"id": "409",
+		"name": "Computing Product"
+	},
+	"IAB19-4": {
+		"id": "409",
+		"name": "Computing Product"
+	},
+	"IAB19-5": {
+		"id": "424",
+		"name": "Photographic Equipment"
+	},
+	"IAB19-6": {
+		"id": "417",
+		"name": "Telecommunications"
+	},
+	"IAB19-7": {
+		"id": "409",
+		"name": "Computing Product"
+	},
+	"IAB19-8": {
+		"id": "432",
+		"name": "Audio and Video Equipment"
+	},
+	"IAB19-9": {
+		"id": "409",
+		"name": "Computing Product"
+	},
+	"IAB19-10": {
+		"id": "409",
+		"name": "Computing Product"
+	},
+	"IAB19-11": {
+		"id": "409",
+		"name": "Computing Product"
+	},
+	"IAB19-12": {
+		"id": "409",
+		"name": "Computing Product"
+	},
+	"IAB19-13": {
+		"id": "404",
+		"name": "Publishing"
+	},
+	"IAB19-14": {
+		"id": "409",
+		"name": "Computing Product"
+	},
+	"IAB19-15": {
+		"id": "409",
+		"name": "Computing Product"
+	},
+	"IAB19-16": {
+		"id": "409",
+		"name": "Computing Product"
+	},
+	"IAB19-17": {
+		"id": "419",
+		"name": "Filmed Entertainment"
+	},
+	"IAB19-18": {
+		"id": "431",
+		"name": "Computing"
+	},
+	"IAB19-19": {
+		"id": "409",
+		"name": "Computing Product"
+	},
+	"IAB19-20": {
+		"id": "409",
+		"name": "Computing Product"
+	},
+	"IAB19-21": {
+		"id": "409",
+		"name": "Computing Product"
+	},
+	"IAB19-22": {
+		"id": "409",
+		"name": "Computing Product"
+	},
+	"IAB19-23": {
+		"id": "409",
+		"name": "Computing Product"
+	},
+	"IAB19-24": {
+		"id": "409",
+		"name": "Computing Product"
+	},
+	"IAB19-25": {
+		"id": "409",
+		"name": "Computing Product"
+	},
+	"IAB19-26": {
+		"id": "409",
+		"name": "Computing Product"
+	},
+	"IAB19-27": {
+		"id": "409",
+		"name": "Computing Product"
+	},
+	"IAB19-28": {
+		"id": "409",
+		"name": "Computing Product"
+	},
+	"IAB19-29": {
+		"id": "392",
+		"name": "Entertainment"
+	},
+	"IAB19-30": {
+		"id": "409",
+		"name": "Computing Product"
+	},
+	"IAB19-31": {
+		"id": "409",
+		"name": "Computing Product"
+	},
+	"IAB19-32": {
+		"id": "409",
+		"name": "Computing Product"
+	},
+	"IAB19-33": {
+		"id": "409",
+		"name": "Computing Product"
+	},
+	"IAB19-34": {
+		"id": "409",
+		"name": "Computing Product"
+	},
+	"IAB19-35": {
+		"id": "409",
+		"name": "Computing Product"
+	},
+	"IAB19-36": {
+		"id": "409",
+		"name": "Computing Product"
+	},
+	"IAB20-1": {
+		"id": "395",
+		"name": "Travel/Hotels/Airlines"
+	},
+	"IAB20-2": {
+		"id": "395",
+		"name": "Travel/Hotels/Airlines"
+	},
+	"IAB20-3": {
+		"id": "428",
+		"name": "Aerospace"
+	},
+	"IAB20-4": {
+		"id": "395",
+		"name": "Travel/Hotels/Airlines"
+	},
+	"IAB20-5": {
+		"id": "395",
+		"name": "Travel/Hotels/Airlines"
+	},
+	"IAB20-6": {
+		"id": "395",
+		"name": "Travel/Hotels/Airlines"
+	},
+	"IAB20-7": {
+		"id": "395",
+		"name": "Travel/Hotels/Airlines"
+	},
+	"IAB20-8": {
+		"id": "395",
+		"name": "Travel/Hotels/Airlines"
+	},
+	"IAB20-9": {
+		"id": "395",
+		"name": "Travel/Hotels/Airlines"
+	},
+	"IAB20-10": {
+		"id": "395",
+		"name": "Travel/Hotels/Airlines"
+	},
+	"IAB20-11": {
+		"id": "395",
+		"name": "Travel/Hotels/Airlines"
+	},
+	"IAB20-12": {
+		"id": "395",
+		"name": "Travel/Hotels/Airlines"
+	},
+	"IAB20-13": {
+		"id": "395",
+		"name": "Travel/Hotels/Airlines"
+	},
+	"IAB20-14": {
+		"id": "395",
+		"name": "Travel/Hotels/Airlines"
+	},
+	"IAB20-15": {
+		"id": "395",
+		"name": "Travel/Hotels/Airlines"
+	},
+	"IAB20-16": {
+		"id": "395",
+		"name": "Travel/Hotels/Airlines"
+	},
+	"IAB20-17": {
+		"id": "396",
+		"name": "Amusement and Recreation"
+	},
+	"IAB20-18": {
+		"id": "395",
+		"name": "Travel/Hotels/Airlines"
+	},
+	"IAB20-19": {
+		"id": "395",
+		"name": "Travel/Hotels/Airlines"
+	},
+	"IAB20-20": {
+		"id": "395",
+		"name": "Travel/Hotels/Airlines"
+	},
+	"IAB20-21": {
+		"id": "395",
+		"name": "Travel/Hotels/Airlines"
+	},
+	"IAB20-22": {
+		"id": "395",
+		"name": "Travel/Hotels/Airlines"
+	},
+	"IAB20-23": {
+		"id": "395",
+		"name": "Travel/Hotels/Airlines"
+	},
+	"IAB20-24": {
+		"id": "395",
+		"name": "Travel/Hotels/Airlines"
+	},
+	"IAB20-25": {
+		"id": "395",
+		"name": "Travel/Hotels/Airlines"
+	},
+	"IAB20-26": {
+		"id": "395",
+		"name": "Travel/Hotels/Airlines"
+	},
+	"IAB20-27": {
+		"id": "395",
+		"name": "Travel/Hotels/Airlines"
+	},
+	"IAB21-1": {
+		"id": "416",
+		"name": "Real Estate"
+	},
+	"IAB21-2": {
+		"id": "416",
+		"name": "Real Estate"
+	},
+	"IAB21-3": {
+		"id": "416",
+		"name": "Real Estate"
+	},
+	"IAB22-1": {
+		"id": "403",
+		"name": "Retail Stores/Chains"
+	},
+	"IAB22-2": {
+		"id": "403",
+		"name": "Retail Stores/Chains"
+	},
+	"IAB22-3": {
+		"id": "410",
+		"name": "Product"
+	}
 }
\ No newline at end of file


Test patch:
diff --git a/adapters/triplelift/triplelift_test.go b/adapters/triplelift/triplelift_test.go
index 2d7ed04f..6fd2b506 100644
--- a/adapters/triplelift/triplelift_test.go
+++ b/adapters/triplelift/triplelift_test.go
@@ -6,5 +6,5 @@ import (
 )
 
 func TestJsonSamples(t *testing.T) {
-	adapterstest.RunJSONBidderTest(t, "triplelifttest", NewTripleliftBidder(nil, "http://tlx.3lift.net/s2s/auction?supplier_id=20"))
+	adapterstest.RunJSONBidderTest(t, "triplelifttest", NewTripleliftBidder(nil, "http://tlx.3lift.net/s2s/auction?sra=1&supplier_id=20"))
 }
diff --git a/adapters/triplelift/triplelifttest/exemplary/optional-params.json b/adapters/triplelift/triplelifttest/exemplary/optional-params.json
index 0851bc09..90c8da5b 100644
--- a/adapters/triplelift/triplelifttest/exemplary/optional-params.json
+++ b/adapters/triplelift/triplelifttest/exemplary/optional-params.json
@@ -28,7 +28,7 @@
   "httpCalls": [
     {
       "expectedRequest": {
-        "uri": "http://tlx.3lift.net/s2s/auction?supplier_id=20",
+        "uri": "http://tlx.3lift.net/s2s/auction?sra=1&supplier_id=20",
         "body": {
           "id": "test-request-id",
           "imp": [
diff --git a/adapters/triplelift/triplelifttest/exemplary/simple-banner.json b/adapters/triplelift/triplelifttest/exemplary/simple-banner.json
index ff680037..156e07e3 100644
--- a/adapters/triplelift/triplelifttest/exemplary/simple-banner.json
+++ b/adapters/triplelift/triplelifttest/exemplary/simple-banner.json
@@ -27,7 +27,7 @@
   "httpCalls": [
     {
       "expectedRequest": {
-        "uri": "http://tlx.3lift.net/s2s/auction?supplier_id=20",
+        "uri": "http://tlx.3lift.net/s2s/auction?sra=1&supplier_id=20",
         "body": {
           "id": "test-request-id",
           "imp": [
diff --git a/adapters/triplelift/triplelifttest/exemplary/simple-video.json b/adapters/triplelift/triplelifttest/exemplary/simple-video.json
index 185446bd..846c62b4 100644
--- a/adapters/triplelift/triplelifttest/exemplary/simple-video.json
+++ b/adapters/triplelift/triplelifttest/exemplary/simple-video.json
@@ -33,7 +33,7 @@
   "httpCalls": [
     {
       "expectedRequest": {
-        "uri": "http://tlx.3lift.net/s2s/auction?supplier_id=20",
+        "uri": "http://tlx.3lift.net/s2s/auction?sra=1&supplier_id=20",
         "body": {
           "id": "test-request-id",
           "imp": [
@@ -85,7 +85,7 @@
                   "adomain": [
                     "foo.com"
                   ],
-                  "iurl": "http://tlx.3lift.net/s2s/auction?supplier_id=20",
+                  "iurl": "http://tlx.3lift.net/s2s/auction?sra=1&supplier_id=20",
                   "cid": "958",
                   "crid": "29681110",
                   "h": 250,
@@ -122,7 +122,7 @@
             "adomain": [
               "foo.com"
             ],
-            "iurl": "http://tlx.3lift.net/s2s/auction?supplier_id=20",
+            "iurl": "http://tlx.3lift.net/s2s/auction?sra=1&supplier_id=20",
             "cid": "958",
             "crid": "29681110",
             "w": 300,
diff --git a/adapters/triplelift/triplelifttest/supplemental/badresponseext.json b/adapters/triplelift/triplelifttest/supplemental/badresponseext.json
index 324c0582..6c09448f 100644
--- a/adapters/triplelift/triplelifttest/supplemental/badresponseext.json
+++ b/adapters/triplelift/triplelifttest/supplemental/badresponseext.json
@@ -27,7 +27,7 @@
   "httpCalls": [
     {
       "expectedRequest": {
-        "uri": "http://tlx.3lift.net/s2s/auction?supplier_id=20",
+        "uri": "http://tlx.3lift.net/s2s/auction?sra=1&supplier_id=20",
         "body": {
           "id": "test-request-id",
           "imp": [
diff --git a/adapters/triplelift/triplelifttest/supplemental/badstatuscode.json b/adapters/triplelift/triplelifttest/supplemental/badstatuscode.json
index 15799616..f24eb799 100644
--- a/adapters/triplelift/triplelifttest/supplemental/badstatuscode.json
+++ b/adapters/triplelift/triplelifttest/supplemental/badstatuscode.json
@@ -27,7 +27,7 @@
   "httpCalls": [
     {
       "expectedRequest": {
-        "uri": "http://tlx.3lift.net/s2s/auction?supplier_id=20",
+        "uri": "http://tlx.3lift.net/s2s/auction?sra=1&supplier_id=20",
         "body": {
           "id": "test-request-id",
           "imp": [
diff --git a/adapters/triplelift/triplelifttest/supplemental/notgoodstatuscode.json b/adapters/triplelift/triplelifttest/supplemental/notgoodstatuscode.json
index 963db593..bdcc0e3a 100644
--- a/adapters/triplelift/triplelifttest/supplemental/notgoodstatuscode.json
+++ b/adapters/triplelift/triplelifttest/supplemental/notgoodstatuscode.json
@@ -27,7 +27,7 @@
   "httpCalls": [
     {
       "expectedRequest": {
-        "uri": "http://tlx.3lift.net/s2s/auction?supplier_id=20",
+        "uri": "http://tlx.3lift.net/s2s/auction?sra=1&supplier_id=20",
         "body": {
           "id": "test-request-id",
           "imp": [
diff --git a/config/config_test.go b/config/config_test.go
index ee8e68e7..2b291fe9 100644
--- a/config/config_test.go
+++ b/config/config_test.go
@@ -43,6 +43,8 @@ gdpr:
   non_standard_publishers: ["siteID","fake-site-id","appID","agltb3B1Yi1pbmNyDAsSA0FwcBiJkfIUDA"]
 ccpa:
   enforce: true
+lmt:
+  enforce: true
 host_cookie:
   cookie_name: userid
   family: prebid
@@ -240,6 +242,7 @@ func TestFullConfig(t *testing.T) {
 	cmpBools(t, "cfg.GDPR.NonStandardPublisherMap", found, false)
 
 	cmpBools(t, "ccpa.enforce", cfg.CCPA.Enforce, true)
+	cmpBools(t, "lmt.enforce", cfg.LMT.Enforce, true)
 
 	//Assert the NonStandardPublishers was correctly unmarshalled
 	cmpStrings(t, "blacklisted_apps", cfg.BlacklistedApps[0], "spamAppID")
diff --git a/endpoints/openrtb2/amp_auction_test.go b/endpoints/openrtb2/amp_auction_test.go
index 289db3f4..731fd55e 100644
--- a/endpoints/openrtb2/amp_auction_test.go
+++ b/endpoints/openrtb2/amp_auction_test.go
@@ -832,6 +832,24 @@ func TestMultisize(t *testing.T) {
 	}.execute(t)
 }
 
+func TestSizeWithMultisize(t *testing.T) {
+	formatOverrideSpec{
+		width:     20,
+		height:    40,
+		multisize: "200x50,100x60",
+		expect: []openrtb.Format{{
+			W: 20,
+			H: 40,
+		}, {
+			W: 200,
+			H: 50,
+		}, {
+			W: 100,
+			H: 60,
+		}},
+	}.execute(t)
+}
+
 func TestHeightOnly(t *testing.T) {
 	formatOverrideSpec{
 		height: 200,
diff --git a/exchange/bidder_test.go b/exchange/bidder_test.go
index fa04e6a4..fff397f0 100644
--- a/exchange/bidder_test.go
+++ b/exchange/bidder_test.go
@@ -1229,6 +1229,64 @@ func TestSetAssetTypes(t *testing.T) {
 	}
 }
 
+func TestTimeoutNotificationOff(t *testing.T) {
+	respBody := "{\"bid\":false}"
+	respStatus := 200
+	server := httptest.NewServer(mockHandler(respStatus, "getBody", respBody))
+	defer server.Close()
+
+	bidderImpl := &notifingBidder{
+		notiRequest: adapters.RequestData{
+			Method:  "GET",
+			Uri:     server.URL + "/notify/me",
+			Body:    nil,
+			Headers: http.Header{},
+		},
+	}
+	bidder := &bidderAdapter{
+		Bidder:      bidderImpl,
+		Client:      server.Client(),
+		DebugConfig: config.Debug{},
+		me:          &metricsConfig.DummyMetricsEngine{},
+	}
+	if tb, ok := bidder.Bidder.(adapters.TimeoutBidder); !ok {
+		t.Error("Failed to cast bidder to a TimeoutBidder")
+	} else {
+		bidder.doTimeoutNotification(tb, &adapters.RequestData{})
+	}
+}
+
+func TestTimeoutNotificationOn(t *testing.T) {
+	respBody := "{\"bid\":false}"
+	respStatus := 200
+	server := httptest.NewServer(mockHandler(respStatus, "getBody", respBody))
+	defer server.Close()
+
+	bidderImpl := &notifingBidder{
+		notiRequest: adapters.RequestData{
+			Method:  "GET",
+			Uri:     server.URL + "/notify/me",
+			Body:    nil,
+			Headers: http.Header{},
+		},
+	}
+	bidder := &bidderAdapter{
+		Bidder: bidderImpl,
+		Client: server.Client(),
+		DebugConfig: config.Debug{
+			TimeoutNotification: config.TimeoutNotification{
+				Log: true,
+			},
+		},
+		me: &metricsConfig.DummyMetricsEngine{},
+	}
+	if tb, ok := bidder.Bidder.(adapters.TimeoutBidder); !ok {
+		t.Error("Failed to cast bidder to a TimeoutBidder")
+	} else {
+		bidder.doTimeoutNotification(tb, &adapters.RequestData{})
+	}
+}
+
 type goodSingleBidder struct {
 	bidRequest   *openrtb.BidRequest
 	httpRequest  *adapters.RequestData
@@ -1302,3 +1360,19 @@ func (bidder *bidRejector) MakeBids(internalRequest *openrtb.BidRequest, externa
 	bidder.httpResponse = response
 	return nil, []error{errors.New("Can't make a response.")}
 }
+
+type notifingBidder struct {
+	notiRequest adapters.RequestData
+}
+
+func (bidder *notifingBidder) MakeRequests(request *openrtb.BidRequest, reqInfo *adapters.ExtraRequestInfo) ([]*adapters.RequestData, []error) {
+	return nil, nil
+}
+
+func (bidder *notifingBidder) MakeBids(internalRequest *openrtb.BidRequest, externalRequest *adapters.RequestData, response *adapters.ResponseData) (*adapters.BidderResponse, []error) {
+	return nil, nil
+}
+
+func (bidder *notifingBidder) MakeTimeoutNotification(req *adapters.RequestData) (*adapters.RequestData, []error) {
+	return &bidder.notiRequest, nil
+}
diff --git a/exchange/exchange_test.go b/exchange/exchange_test.go
index e9b2127e..4f329962 100644
--- a/exchange/exchange_test.go
+++ b/exchange/exchange_test.go
@@ -731,7 +731,17 @@ func runSpec(t *testing.T, filename string, spec *exchangeSpec) {
 	if len(errs) != 0 {
 		t.Fatalf("%s: Failed to parse aliases", filename)
 	}
-	ex := newExchangeForTests(t, filename, spec.OutgoingRequests, aliases, spec.EnforceCCPA)
+
+	privacyConfig := config.Privacy{
+		CCPA: config.CCPA{
+			Enforce: spec.EnforceCCPA,
+		},
+		LMT: config.LMT{
+			Enforce: spec.EnforceLMT,
+		},
+	}
+
+	ex := newExchangeForTests(t, filename, spec.OutgoingRequests, aliases, privacyConfig)
 	biddersInAuction := findBiddersInAuction(t, filename, &spec.IncomingRequest.OrtbRequest)
 	categoriesFetcher, error := newCategoryFetcher("./test/category-mapping")
 	if error != nil {
@@ -816,7 +826,7 @@ func extractResponseTimes(t *testing.T, context string, bid *openrtb.BidResponse
 	}
 }
 
-func newExchangeForTests(t *testing.T, filename string, expectations map[string]*bidderSpec, aliases map[string]string, enforceCCPA bool) Exchange {
+func newExchangeForTests(t *testing.T, filename string, expectations map[string]*bidderSpec, aliases map[string]string, privacyConfig config.Privacy) Exchange {
 	adapters := make(map[openrtb_ext.BidderName]adaptedBidder)
 	for _, bidderName := range openrtb_ext.BidderMap {
 		if spec, ok := expectations[string(bidderName)]; ok {
@@ -854,7 +864,7 @@ func newExchangeForTests(t *testing.T, filename string, expectations map[string]
 		gDPR:                gdpr.AlwaysAllow{},
 		currencyConverter:   currencies.NewRateConverterDefault(),
 		UsersyncIfAmbiguous: false,
-		enforceCCPA:         enforceCCPA,
+		privacyConfig:       privacyConfig,
 	}
 }
 
@@ -1620,6 +1630,7 @@ type exchangeSpec struct {
 	OutgoingRequests map[string]*bidderSpec `json:"outgoingRequests"`
 	Response         exchangeResponse       `json:"response,omitempty"`
 	EnforceCCPA      bool                   `json:"enforceCcpa"`
+	EnforceLMT       bool                   `json:"enforceLmt"`
 	DebugLog         *DebugLog              `json:"debuglog,omitempty"`
 }
 
diff --git a/exchange/exchangetest/lmt-featureflag-off.json b/exchange/exchangetest/lmt-featureflag-off.json
new file mode 100644
index 00000000..9a15c879
--- /dev/null
+++ b/exchange/exchangetest/lmt-featureflag-off.json
@@ -0,0 +1,63 @@
+{
+    "enforceLmt": false,
+    "incomingRequest": {
+        "ortbRequest": {
+            "id": "some-request-id",
+            "site": {
+                "page": "test.somepage.com"
+            },
+            "imp": [{
+                "id": "my-imp-id",
+                "video": {
+                    "mimes": ["video/mp4"]
+                },
+                "ext": {
+                    "appnexus": {
+                        "placementId": 1
+                    }
+                }
+            }],
+            "device": {
+                "lmt": 1
+            },
+            "user": {
+                "id": "some-id",
+                "buyeruid": "some-buyer-id"
+            }
+        }
+    },
+    "outgoingRequests": {
+        "appnexus": {
+            "expectRequest": {
+                "ortbRequest": {
+                    "id": "some-request-id",
+                    "site": {
+                        "page": "test.somepage.com"
+                    },
+                    "imp": [{
+                        "id": "my-imp-id",
+                        "video": {
+                            "mimes": ["video/mp4"]
+                        },
+                        "ext": {
+                            "bidder": {
+                                "placementId": 1
+                            }
+                        }
+                    }],
+                    "device": {
+                        "lmt": 1
+                    },
+                    "user": {
+                        "id": "some-id",
+                        "buyeruid": "some-buyer-id"
+                    }
+                },
+                "bidAdjustment": 1.0
+            },
+            "mockResponse": {
+                "errors": ["appnexus-error"]
+            }
+        }
+    }
+}
\ No newline at end of file
diff --git a/exchange/exchangetest/lmt-featureflag-on.json b/exchange/exchangetest/lmt-featureflag-on.json
new file mode 100644
index 00000000..440f8c76
--- /dev/null
+++ b/exchange/exchangetest/lmt-featureflag-on.json
@@ -0,0 +1,61 @@
+{
+    "enforceLmt": true,
+    "incomingRequest": {
+        "ortbRequest": {
+            "id": "some-request-id",
+            "site": {
+                "page": "test.somepage.com"
+            },
+            "imp": [{
+                "id": "my-imp-id",
+                "video": {
+                    "mimes": ["video/mp4"]
+                },
+                "ext": {
+                    "appnexus": {
+                        "placementId": 1
+                    }
+                }
+            }],
+            "device": {
+                "lmt": 1
+            },
+            "user": {
+                "id": "some-id",
+                "buyeruid": "some-buyer-id"
+            }
+        }
+    },
+    "outgoingRequests": {
+        "appnexus": {
+            "expectRequest": {
+                "ortbRequest": {
+                    "id": "some-request-id",
+                    "site": {
+                        "page": "test.somepage.com"
+                    },
+                    "imp": [{
+                        "id": "my-imp-id",
+                        "video": {
+                            "mimes": ["video/mp4"]
+                        },
+                        "ext": {
+                            "bidder": {
+                                "placementId": 1
+                            }
+                        }
+                    }],
+                    "device": {
+                        "lmt": 1
+                    },
+                    "user": {
+                    }
+                },
+                "bidAdjustment": 1.0
+            },
+            "mockResponse": {
+                "errors": ["appnexus-error"]
+            }
+        }
+    }
+}
\ No newline at end of file
diff --git a/exchange/utils_test.go b/exchange/utils_test.go
index acbf25ff..4dad3f54 100644
--- a/exchange/utils_test.go
+++ b/exchange/utils_test.go
@@ -6,6 +6,7 @@ import (
 	"testing"
 
 	"github.com/mxmCherry/openrtb"
+	"github.com/prebid/prebid-server/config"
 	"github.com/prebid/prebid-server/openrtb_ext"
 	"github.com/prebid/prebid-server/pbsmetrics"
 	"github.com/stretchr/testify/assert"
@@ -69,8 +70,17 @@ func TestCleanOpenRTBRequests(t *testing.T) {
 			applyCOPPA: false, consentedVendors: map[string]bool{"appnexus": true, "brightroll": true}},
 	}
 
+	privacyConfig := config.Privacy{
+		CCPA: config.CCPA{
+			Enforce: true,
+		},
+		LMT: config.LMT{
+			Enforce: true,
+		},
+	}
+
 	for _, test := range testCases {
-		reqByBidders, _, err := cleanOpenRTBRequests(context.Background(), test.req, &emptyUsersync{}, map[openrtb_ext.BidderName]*pbsmetrics.AdapterLabels{}, pbsmetrics.Labels{}, &permissionsMock{}, true, true)
+		reqByBidders, _, err := cleanOpenRTBRequests(context.Background(), test.req, &emptyUsersync{}, map[openrtb_ext.BidderName]*pbsmetrics.AdapterLabels{}, pbsmetrics.Labels{}, &permissionsMock{}, true, privacyConfig)
 		if test.hasError {
 			assert.NotNil(t, err, "Error shouldn't be nil")
 		} else {
@@ -99,9 +109,80 @@ func TestCleanOpenRTBRequestsCCPA(t *testing.T) {
 	}
 
 	for _, test := range testCases {
-		req := newCCPABidRequest(t)
+		req := newBidRequest(t)
+		req.Regs = &openrtb.Regs{
+			Ext: json.RawMessage(`{"us_privacy":"1-Y-"}`),
+		}
 
-		results, _, errs := cleanOpenRTBRequests(context.Background(), req, &emptyUsersync{}, map[openrtb_ext.BidderName]*pbsmetrics.AdapterLabels{}, pbsmetrics.Labels{}, &permissionsMock{}, true, test.enforceCCPA)
+		privacyConfig := config.Privacy{
+			CCPA: config.CCPA{
+				Enforce: test.enforceCCPA,
+			},
+		}
+
+		results, _, errs := cleanOpenRTBRequests(context.Background(), req, &emptyUsersync{}, map[openrtb_ext.BidderName]*pbsmetrics.AdapterLabels{}, pbsmetrics.Labels{}, &permissionsMock{}, true, privacyConfig)
+		result := results["appnexus"]
+
+		assert.Nil(t, errs)
+
+		if test.expectDataScrub {
+			assert.Equal(t, result.User.BuyerUID, "", test.description+":User.BuyerUID")
+			assert.Equal(t, result.Device.DIDMD5, "", test.description+":Device.DIDMD5")
+		} else {
+			assert.NotEqual(t, result.User.BuyerUID, "", test.description+":User.BuyerUID")
+			assert.NotEqual(t, result.Device.DIDMD5, "", test.description+":Device.DIDMD5")
+		}
+	}
+}
+
+func TestCleanOpenRTBRequestsLMT(t *testing.T) {
+	var (
+		enabled  int8 = 1
+		disabled int8 = 0
+	)
+	testCases := []struct {
+		description     string
+		lmt             *int8
+		enforceLMT      bool
+		expectDataScrub bool
+	}{
+		{
+			description:     "Feature Flag Enabled - OpenTRB Enabled",
+			lmt:             &enabled,
+			enforceLMT:      true,
+			expectDataScrub: true,
+		},
+		{
+			description:     "Feature Flag Disabled - OpenTRB Enabled",
+			lmt:             &enabled,
+			enforceLMT:      false,
+			expectDataScrub: false,
+		},
+		{
+			description:     "Feature Flag Enabled - OpenTRB Disabled",
+			lmt:             &disabled,
+			enforceLMT:      true,
+			expectDataScrub: false,
+		},
+		{
+			description:     "Feature Flag Disabled - OpenTRB Disabled",
+			lmt:             &disabled,
+			enforceLMT:      false,
+			expectDataScrub: false,
+		},
+	}
+
+	for _, test := range testCases {
+		req := newBidRequest(t)
+		req.Device.Lmt = test.lmt
+
+		privacyConfig := config.Privacy{
+			LMT: config.LMT{
+				Enforce: test.enforceLMT,
+			},
+		}
+
+		results, _, errs := cleanOpenRTBRequests(context.Background(), req, &emptyUsersync{}, map[openrtb_ext.BidderName]*pbsmetrics.AdapterLabels{}, pbsmetrics.Labels{}, &permissionsMock{}, true, privacyConfig)
 		result := results["appnexus"]
 
 		assert.Nil(t, errs)
@@ -163,8 +244,7 @@ func newAdapterAliasBidRequest(t *testing.T) *openrtb.BidRequest {
 	}
 }
 
-func newCCPABidRequest(t *testing.T) *openrtb.BidRequest {
-	dnt := int8(1)
+func newBidRequest(t *testing.T) *openrtb.BidRequest {
 	return &openrtb.BidRequest{
 		Site: &openrtb.Site{
 			Page:   "www.some.domain.com",
@@ -178,7 +258,6 @@ func newCCPABidRequest(t *testing.T) *openrtb.BidRequest {
 			UA:       "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/67.0.3396.87 Safari/537.36",
 			IFA:      "ifa",
 			IP:       "132.173.230.74",
-			DNT:      &dnt,
 			Language: "EN",
 		},
 		Source: &openrtb.Source{
@@ -189,9 +268,6 @@ func newCCPABidRequest(t *testing.T) *openrtb.BidRequest {
 			BuyerUID: "their-id",
 			Ext:      json.RawMessage(`{"digitrust":{"id":"digi-id","keyv":1,"pref":1}}`),
 		},
-		Regs: &openrtb.Regs{
-			Ext: json.RawMessage(`{"us_privacy":"1-Y-"}`),
-		},
 		Imp: []openrtb.Imp{{
 			ID: "some-imp-id",
 			Banner: &openrtb.Banner{
diff --git a/privacy/enforcement_test.go b/privacy/enforcement_test.go
index 0e82648d..968c6354 100644
--- a/privacy/enforcement_test.go
+++ b/privacy/enforcement_test.go
@@ -21,6 +21,7 @@ func TestAny(t *testing.T) {
 				COPPA:   false,
 				GDPR:    false,
 				GDPRGeo: false,
+				LMT:     false,
 			},
 			expected: false,
 		},
@@ -31,6 +32,7 @@ func TestAny(t *testing.T) {
 				COPPA:   true,
 				GDPR:    true,
 				GDPRGeo: true,
+				LMT:     true,
 			},
 			expected: true,
 		},
@@ -41,16 +43,7 @@ func TestAny(t *testing.T) {
 				COPPA:   true,
 				GDPR:    false,
 				GDPRGeo: false,
-			},
-			expected: true,
-		},
-		{
-			description: "GDPRGeo only",
-			enforcement: Enforcement{
-				CCPA:    false,
-				COPPA:   false,
-				GDPR:    false,
-				GDPRGeo: true,
+				LMT:     true,
 			},
 			expected: true,
 		},
@@ -79,6 +72,7 @@ func TestApply(t *testing.T) {
 				COPPA:   true,
 				GDPR:    true,
 				GDPRGeo: true,
+				LMT:     true,
 			},
 			ampGDPRException:   false,
 			expectedDeviceIPv6: ScrubStrategyIPV6Lowest32,
@@ -93,6 +87,7 @@ func TestApply(t *testing.T) {
 				COPPA:   false,
 				GDPR:    false,
 				GDPRGeo: false,
+				LMT:     false,
 			},
 			ampGDPRException:   false,
 			expectedDeviceIPv6: ScrubStrategyIPV6Lowest16,
@@ -107,6 +102,7 @@ func TestApply(t *testing.T) {
 				COPPA:   true,
 				GDPR:    false,
 				GDPRGeo: false,
+				LMT:     false,
 			},
 			ampGDPRException:   false,
 			expectedDeviceIPv6: ScrubStrategyIPV6Lowest32,
@@ -121,6 +117,7 @@ func TestApply(t *testing.T) {
 				COPPA:   false,
 				GDPR:    true,
 				GDPRGeo: true,
+				LMT:     false,
 			},
 			ampGDPRException:   false,
 			expectedDeviceIPv6: ScrubStrategyIPV6Lowest16,
@@ -135,6 +132,7 @@ func TestApply(t *testing.T) {
 				COPPA:   false,
 				GDPR:    true,
 				GDPRGeo: true,
+				LMT:     false,
 			},
 			ampGDPRException:   true,
 			expectedDeviceIPv6: ScrubStrategyIPV6Lowest16,
@@ -149,6 +147,7 @@ func TestApply(t *testing.T) {
 				COPPA:   false,
 				GDPR:    false,
 				GDPRGeo: false,
+				LMT:     false,
 			},
 			ampGDPRException:   true,
 			expectedDeviceIPv6: ScrubStrategyIPV6Lowest16,
@@ -163,6 +162,7 @@ func TestApply(t *testing.T) {
 				COPPA:   true,
 				GDPR:    true,
 				GDPRGeo: true,
+				LMT:     false,
 			},
 			ampGDPRException:   true,
 			expectedDeviceIPv6: ScrubStrategyIPV6Lowest32,
@@ -177,6 +177,7 @@ func TestApply(t *testing.T) {
 				COPPA:   false,
 				GDPR:    true,
 				GDPRGeo: false,
+				LMT:     false,
 			},
 			ampGDPRException:   false,
 			expectedDeviceIPv6: ScrubStrategyIPV6Lowest16,
@@ -191,6 +192,7 @@ func TestApply(t *testing.T) {
 				COPPA:   false,
 				GDPR:    false,
 				GDPRGeo: true,
+				LMT:     false,
 			},
 			ampGDPRException:   false,
 			expectedDeviceIPv6: ScrubStrategyIPV6None,
@@ -198,6 +200,36 @@ func TestApply(t *testing.T) {
 			expectedUser:       ScrubStrategyUserNone,
 			expectedUserGeo:    ScrubStrategyGeoReducedPrecision,
 		},
+		{
+			description: "LMT Only",
+			enforcement: Enforcement{
+				CCPA:    false,
+				COPPA:   false,
+				GDPR:    false,
+				GDPRGeo: false,
+				LMT:     true,
+			},
+			ampGDPRException:   false,
+			expectedDeviceIPv6: ScrubStrategyIPV6Lowest16,
+			expectedDeviceGeo:  ScrubStrategyGeoReducedPrecision,
+			expectedUser:       ScrubStrategyUserID,
+			expectedUserGeo:    ScrubStrategyGeoReducedPrecision,
+		},
+		{
+			description: "LMT Only, ampGDPRException",
+			enforcement: Enforcement{
+				CCPA:    false,
+				COPPA:   false,
+				GDPR:    false,
+				GDPRGeo: false,
+				LMT:     true,
+			},
+			ampGDPRException:   true,
+			expectedDeviceIPv6: ScrubStrategyIPV6Lowest16,
+			expectedDeviceGeo:  ScrubStrategyGeoReducedPrecision,
+			expectedUser:       ScrubStrategyUserID,
+			expectedUserGeo:    ScrubStrategyGeoReducedPrecision,
+		},
 	}
 
 	for _, test := range testCases {
@@ -229,6 +261,7 @@ func TestApplyNoneApplicable(t *testing.T) {
 		CCPA:  false,
 		COPPA: false,
 		GDPR:  false,
+		LMT:   false,
 	}
 	enforcement.apply(req, false, m)
 
diff --git a/privacy/lmt/policy_test.go b/privacy/lmt/policy_test.go
new file mode 100644
index 00000000..45de219a
--- /dev/null
+++ b/privacy/lmt/policy_test.go
@@ -0,0 +1,128 @@
+package lmt
+
+import (
+	"testing"
+
+	"github.com/mxmCherry/openrtb"
+	"github.com/stretchr/testify/assert"
+)
+
+func TestRead(t *testing.T) {
+	var one int8 = 1
+
+	testCases := []struct {
+		description    string
+		request        *openrtb.BidRequest
+		expectedPolicy Policy
+	}{
+		{
+			description: "Nil Request",
+			request:     nil,
+			expectedPolicy: Policy{
+				Signal:         0,
+				SignalProvided: false,
+			},
+		},
+		{
+			description: "Nil Device",
+			request: &openrtb.BidRequest{
+				Device: nil,
+			},
+			expectedPolicy: Policy{
+				Signal:         0,
+				SignalProvided: false,
+			},
+		},
+		{
+			description: "Nil Device.Lmt",
+			request: &openrtb.BidRequest{
+				Device: &openrtb.Device{
+					Lmt: nil,
+				},
+			},
+			expectedPolicy: Policy{
+				Signal:         0,
+				SignalProvided: false,
+			},
+		},
+		{
+			description: "Enabled",
+			request: &openrtb.BidRequest{
+				Device: &openrtb.Device{
+					Lmt: &one,
+				},
+			},
+			expectedPolicy: Policy{
+				Signal:         1,
+				SignalProvided: true,
+			},
+		},
+	}
+
+	for _, test := range testCases {
+		p := ReadPolicy(test.request)
+		assert.Equal(t, test.expectedPolicy, p, test.description)
+	}
+}
+
+func TestShouldEnforce(t *testing.T) {
+	testCases := []struct {
+		description string
+		policy      Policy
+		expected    bool
+	}{
+		{
+			description: "Signal Not Provided - Zero",
+			policy: Policy{
+				Signal:         0,
+				SignalProvided: false,
+			},
+			expected: false,
+		},
+		{
+			description: "Signal Not Provided - One",
+			policy: Policy{
+				Signal:         1,
+				SignalProvided: false,
+			},
+			expected: false,
+		},
+		{
+			description: "Signal Not Provided - Other",
+			policy: Policy{
+				Signal:         42,
+				SignalProvided: false,
+			},
+			expected: false,
+		},
+		{
+			description: "Signal Provided - Zero",
+			policy: Policy{
+				Signal:         0,
+				SignalProvided: true,
+			},
+			expected: false,
+		},
+		{
+			description: "Signal Provided - One",
+			policy: Policy{
+				Signal:         1,
+				SignalProvided: true,
+			},
+			expected: true,
+		},
+		{
+			description: "Signal Provided - Other",
+			policy: Policy{
+				Signal:         42,
+				SignalProvided: true,
+			},
+			expected: false,
+		},
+	}
+
+	for _, test := range testCases {
+		result := test.policy.ShouldEnforce()
+		assert.Equal(t, test.expected, result, test.description)
+	}
+}