diff --git a/README.md b/README.md index 77277d72..98496f3d 100644 --- a/README.md +++ b/README.md @@ -2,19 +2,17 @@ Encode/decode consent information with the IAB GPP Framework -https://iabtechlab.com/gpp/ - ### Usage #### Maven -The official iabgpp java library is distributed through maven central. Please [search maven central](https://search.maven.org/search?q=g:com.iab.gpp) for the current release version. +The official iabgpp java library is distributed through maven central. Please [search maven central](https://search.maven.org/search?q=g:com.iabgpp) for the current release version. #### Decoding ``` - com.iab.gpp + com.iabgpp iabgpp-encoder VERSION @@ -25,7 +23,7 @@ import com.iab.gpp.encoder.GppModel; import com.iab.gpp.encoder.section.TcfEuV2; import com.iab.gpp.encoder.section.UspV1; -String gppString = "DBACDMA~CPdBusAPdBusANwAAAENAwCAAAAAAAAAAAAAAAAAAAA.QAAA.IAAA~BbA"; +String gppString = "DBACNYA~CPSG_8APSG_8ANwAAAENAwCAAAAAAAAAAAAAAAAAAAAA.QAAA.IAAA~1YNN"; GppModel gppModel = new GppModel(gppString); TcfEuV2 tcfEuV2Section = (TcfEuV2)gppModel.getSection(TcfEuV2.NAME); @@ -41,7 +39,7 @@ Integer uspV1Notice = uspV1Section.getNotice(); ``` - com.iab.gpp + com.iabgpp iabgpp-encoder VERSION @@ -80,13 +78,13 @@ List respectively. The `iabgpp-extras-jackson` library uses Jackson 2.10.3 to pa ``` - com.iab.gpp + com.iabgpp iabgpp-extras VERSION - com.iab.gpp + com.iabgpp iabgpp-extras-jackson VERSION @@ -114,3 +112,151 @@ String cmpListContent = "..."; Loader loader = new Loader(); CmpList cmpList = loader.cmpList(cmpListContent); ``` + +### Fields + +|Section Name|Section ID|Field|Data Type/Value| +|------------|----------|-----|---------------| +|tcfeuv2|2|Version|6 bit int. Value is 2.| +|tcfeuv2|2|Created|Datetime. Updated when fields are set| +|tcfeuv2|2|LastUpdated|Datetime. Updated when fields are set| +|tcfeuv2|2|CmpId|12 bit int| +|tcfeuv2|2|CmpVersion|12 bit int| +|tcfeuv2|2|ConsentScreen|6 bit int| +|tcfeuv2|2|ConsentLanguage|2 character country code| +|tcfeuv2|2|VendorListVersion|12 bit int| +|tcfeuv2|2|PolicyVersion|6 bit int. Value is 2| +|tcfeuv2|2|IsServiceSpecific|Boolean| +|tcfeuv2|2|UseNonStandardStacks|Boolean| +|tcfeuv2|2|SpecialFeatureOptins|Boolean list of size 12| +|tcfeuv2|2|PurposeConsents|Boolean list of size 24| +|tcfeuv2|2|PurposeLegitimateInterests|Boolean list of size 24| +|tcfeuv2|2|PurposeOneTreatment|Boolean| +|tcfeuv2|2|PublisherCountryCode|2 character country code| +|tcfeuv2|2|VendorConsents|Integer list of variable size| +|tcfeuv2|2|VendorLegitimateInterests|Integer list of variable size| +|tcfeuv2|2|PublisherRestrictions|Integer list of variable size| +|tcfeuv2|2|PublisherPurposesSegmentType|3 bit int. Value is 3| +|tcfeuv2|2|PublisherConsents|Boolean list of size 24| +|tcfeuv2|2|PublisherLegitimateInterests|Boolean list of size 24| +|tcfeuv2|2|NumCustomPurposes|6 bit int| +|tcfeuv2|2|PublisherCustomConsents|Boolean list where size is set by the NumCustomPurposes field| +|tcfeuv2|2|PublisherCustomLegitimateInterests|Boolean list where size is set by the NumCustomPurposes field| +|tcfeuv2|2|VendorsAllowedSegmentType|3 bit int. Value is 2| +|tcfeuv2|2|VendorsAllowed|Integer list of variable size| +|tcfeuv2|2|VendorsDisclosedSegmentType|3 bit int. Value is 1| +|tcfeuv2|2|VendorsDisclosed|Integer list of variable size| +|tcfcav1|5|Version|6 bit int. Value is 2.| +|tcfcav1|5|Created|Datetime. Updated when any fields are set| +|tcfcav1|5|LastUpdated|Datetime. Updated when any fields are set| +|tcfcav1|5|CmpId|12 bit int| +|tcfcav1|5|CmpVersion|12 bit int| +|tcfcav1|5|ConsentScreen|6 bit int| +|tcfcav1|5|ConsentLanguage|2 character country code| +|tcfcav1|5|VendorListVersion|12 bit int| +|tcfcav1|5|TcfPolicyVersion|6 bit int. Value is 2.| +|tcfcav1|5|UseNonStandardStacks|Boolean| +|tcfcav1|5|SpecialFeatureExpressConsent|Boolean list of size 12| +|tcfcav1|5|PurposesExpressConsent|Boolean list of size 24| +|tcfcav1|5|PurposesImpliedConsent|Boolean list of size 24| +|tcfcav1|5|VendorExpressConsent|Integer list of variable size| +|tcfcav1|5|VendorImpliedConsent|Integer list of variable size| +|tcfcav1|5|PubRestrictions|RangeEntry list of variable size| +|tcfcav1|5|PubPurposesSegmentType|3 bit int. Value is 3| +|tcfcav1|5|PubPurposesExpressConsent|Boolean list of size 24| +|tcfcav1|5|PubPurposesImpliedConsent|Boolean list of size 24| +|tcfcav1|5|NumCustomPurposes|6 bit int| +|tcfcav1|5|CustomPurposesExpressConsent|Boolean list where size is set by the NumCustomPurposes field| +|tcfcav1|5|CustomPurposesImpliedConsent|Boolean list where size is set by the NumCustomPurposes field| +|tcfcav1|5|DisclosedVendorsSegmentType|3 bit int. Value is 1| +|tcfcav1|5|DisclosedVendors|Integer list of variable size| +|uspv1|6|Version|6 bit int. Value is 1| +|uspv1|6|Notice|2 bit int| +|uspv1|6|OptOutSale|2 bit int| +|uspv1|6|LspaCovered|2 bit int| +|usnat|7|Version|6 bit int. Value is 1| +|usnat|7|SharingNotice|2 bit int. 0=Not applicable, 1=Yes, 2=No| +|usnat|7|SaleOptOutNotice|2 bit int. 0=Not applicable, 1=Yes, 2=No| +|usnat|7|SharingOptOutNotice|2 bit int. 0=Not applicable, 1=Yes, 2=No| +|usnat|7|TargetedAdvertisingOptOutNotice|2 bit int. 0=Not applicable, 1=Yes, 2=No| +|usnat|7|SensitiveDataProcessingOptOutNotice|2 bit int. 0=Not applicable, 1=Yes, 2=No| +|usnat|7|SensitiveDataLimitUseNotice|2 bit int. 0=Not applicable, 1=Yes, 2=No| +|usnat|7|SaleOptOut|2 bit int. 0=Not applicable, 1=Yes, 2=No| +|usnat|7|SharingOptOut|2 bit int. 0=Not applicable, 1=Yes, 2=No| +|usnat|7|TargetedAdvertisingOptOut|2 bit int. 0=Not applicable, 1=Yes, 2=No| +|usnat|7|SensitiveDataProcessing|2 bit int list of size 12. 0=Not applicable, 1=Yes, 2=No| +|usnat|7|KnownChildSensitiveDataConsents|2 bit int list of size 2. 0=Not applicable, 1=Yes, 2=No| +|usnat|7|PersonalDataConsents|2 bit int. 0=Not applicable, 1=Yes, 2=No| +|usnat|7|MspaCoveredTransaction|2 bit int. 0=Not applicable, 1=Yes, 2=No| +|usnat|7|MspaOptOutOptionMode|2 bit int. 0=Not applicable, 1=Yes, 2=No| +|usnat|7|MspaServiceProviderMode|2 bit int. 0=Not applicable, 1=Yes, 2=No| +|usnat|7|GpcSegmentType|2 bit int. Value is 1| +|usnat|7|GpcSegmentIncluded|Boolean. Default value is true| +|usnat|7|Gpc|Boolean| +|usca|8|Version|6 bit int. Value is 1| +|usca|8|SaleOptOutNotice|2 bit int. 0=Not applicable, 1=Yes, 2=No| +|usca|8|SharingOptOutNotice|2 bit int. 0=Not applicable, 1=Yes, 2=No| +|usca|8|SensitiveDataLimitUseNotice|2 bit int. 0=Not applicable, 1=Yes, 2=No| +|usca|8|SaleOptOut|2 bit int. 0=Not applicable, 1=Yes, 2=No| +|usca|8|SharingOptOut|2 bit int. 0=Not applicable, 1=Yes, 2=No| +|usca|8|SensitiveDataProcessing|2 bit int list of size 9. 0=Not applicable, 1=Yes, 2=No| +|usca|8|KnownChildSensitiveDataConsents|2 bit int list of size 2. 0=Not applicable, 1=Yes, 2=No| +|usca|8|PersonalDataConsents|2 bit int. 0=Not applicable, 1=Yes, 2=No| +|usca|8|MspaCoveredTransaction|2 bit int. 0=Not applicable, 1=Yes, 2=No| +|usca|8|MspaOptOutOptionMode|2 bit int. 0=Not applicable, 1=Yes, 2=No| +|usca|8|MspaServiceProviderMode|2 bit int. 0=Not applicable, 1=Yes, 2=No| +|usca|8|GpcSegmentType|2 bit int. Value is 1| +|usca|8|GpcSegmentIncluded|Boolean. Default value is true| +|usca|8|Gpc|Boolean| +|usva|9|Version|6 bit int. Value is 1| +|usva|9|SharingNotice|2 bit int. 0=Not applicable, 1=Yes, 2=No| +|usva|9|SaleOptOutNotice|2 bit int. 0=Not applicable, 1=Yes, 2=No| +|usva|9|TargetedAdvertisingOptOutNotice|2 bit int. 0=Not applicable, 1=Yes, 2=No| +|usva|9|SaleOptOut|2 bit int. 0=Not applicable, 1=Yes, 2=No| +|usva|9|TargetedAdvertisingOptOut|2 bit int. 0=Not applicable, 1=Yes, 2=No| +|usva|9|SensitiveDataProcessing|2 bit int list of size 8. 0=Not applicable, 1=Yes, 2=No| +|usva|9|KnownChildSensitiveDataConsents|2 bit int. 0=Not applicable, 1=Yes, 2=No| +|usva|9|MspaCoveredTransaction|2 bit int. 0=Not applicable, 1=Yes, 2=No| +|usva|9|MspaOptOutOptionMode|2 bit int. 0=Not applicable, 1=Yes, 2=No| +|usva|9|MspaServiceProviderMode|2 bit int. 0=Not applicable, 1=Yes, 2=No| +|usco|10|Version|6 bit int. Value is 1| +|usco|10|SharingNotice|2 bit int. 0=Not applicable, 1=Yes, 2=No| +|usco|10|SaleOptOutNotice|2 bit int. 0=Not applicable, 1=Yes, 2=No| +|usco|10|TargetedAdvertisingOptOutNotice|2 bit int. 0=Not applicable, 1=Yes, 2=No| +|usco|10|SaleOptOut|2 bit int. 0=Not applicable, 1=Yes, 2=No| +|usco|10|TargetedAdvertisingOptOut|2 bit int. 0=Not applicable, 1=Yes, 2=No| +|usco|10|SensitiveDataProcessing|2 bit int list of size 7. 0=Not applicable, 1=Yes, 2=No| +|usco|10|KnownChildSensitiveDataConsents|2 bit int. 0=Not applicable, 1=Yes, 2=No| +|usco|10|MspaCoveredTransaction|2 bit int. 0=Not applicable, 1=Yes, 2=No| +|usco|10|MspaOptOutOptionMode|2 bit int. 0=Not applicable, 1=Yes, 2=No| +|usco|10|MspaServiceProviderMode|2 bit int. 0=Not applicable, 1=Yes, 2=No| +|usco|10|GpcSegmentType|2 bit int. Value is 1| +|usco|10|GpcSegmentIncluded|Boolean. Default value is true| +|usco|10|Gpc|Boolean| +|usut|11|Version|6 bit int. Value is 1| +|usut|11|SharingNotice|2 bit int. 0=Not applicable, 1=Yes, 2=No| +|usut|11|SaleOptOutNotice|2 bit int. 0=Not applicable, 1=Yes, 2=No| +|usut|11|TargetedAdvertisingOptOutNotice|2 bit int. 0=Not applicable, 1=Yes, 2=No| +|usut|11|SensitiveDataProcessingOptOutNotice|2 bit int. 0=Not applicable, 1=Yes, 2=No| +|usut|11|SaleOptOut|2 bit int. 0=Not applicable, 1=Yes, 2=No| +|usut|11|TargetedAdvertisingOptOut|2 bit int. 0=Not applicable, 1=Yes, 2=No| +|usut|11|SensitiveDataProcessing|2 bit int list of size 8. 0=Not applicable, 1=Yes, 2=No| +|usut|11|KnownChildSensitiveDataConsents|2 bit int. 0=Not applicable, 1=Yes, 2=No| +|usut|11|MspaCoveredTransaction|2 bit int. 0=Not applicable, 1=Yes, 2=No| +|usut|11|MspaOptOutOptionMode|2 bit int. 0=Not applicable, 1=Yes, 2=No| +|usut|11|MspaServiceProviderMode|2 bit int. 0=Not applicable, 1=Yes, 2=No| +|usct|12|Version|6 bit int. Value is 1| +|usct|12|SharingNotice|2 bit int. 0=Not applicable, 1=Yes, 2=No| +|usct|12|SaleOptOutNotice|2 bit int. 0=Not applicable, 1=Yes, 2=No| +|usct|12|TargetedAdvertisingOptOutNotice|2 bit int. 0=Not applicable, 1=Yes, 2=No| +|usct|12|SaleOptOut|2 bit int. 0=Not applicable, 1=Yes, 2=No| +|usct|12|TargetedAdvertisingOptOut|2 bit int. 0=Not applicable, 1=Yes, 2=No| +|usct|12|SensitiveDataProcessing|2 bit int list of size 8. 0=Not applicable, 1=Yes, 2=No| +|usct|12|KnownChildSensitiveDataConsents|2 bit int list of size 3. 0=Not applicable, 1=Yes, 2=No| +|usct|12|MspaCoveredTransaction|2 bit int. 0=Not applicable, 1=Yes, 2=No| +|usct|12|MspaOptOutOptionMode|2 bit int. 0=Not applicable, 1=Yes, 2=No| +|usct|12|MspaServiceProviderMode|2 bit int. 0=Not applicable, 1=Yes, 2=No| +|usct|12|GpcSegmentType|2 bit int. Value is 1| +|usct|12|GpcSegmentIncluded|Boolean. Default value is true| +|usct|12|Gpc|Boolean| + diff --git a/iabgpp-encoder/pom.xml b/iabgpp-encoder/pom.xml index 554e8cd5..f7f25486 100644 --- a/iabgpp-encoder/pom.xml +++ b/iabgpp-encoder/pom.xml @@ -7,35 +7,17 @@ com.iabgpp iabgpp-core - 3.0.0-SNAPSHOT + 3.2.3-SNAPSHOT - com.iabgpp iabgpp-encoder - IAB GPP Java Encoder Library - 3.0.0-SNAPSHOT - Encode and decode consent information with the IAB GPP Framework jar - - - The Apache Software License, Version 2.0 - http://www.apache.org/licenses/LICENSE-2.0.txt - - - - - UTF-8 - 1.8 - 1.8 - - - org.junit.jupiter junit-jupiter-engine - 5.9.0 + 5.9.2 test @@ -43,11 +25,32 @@ - org.apache.maven.plugins - surefire - 3.0.0-M7 + maven-surefire-plugin + 2.22.2 + + + + release + + + + org.apache.maven.plugins + maven-source-plugin + + + org.apache.maven.plugins + maven-javadoc-plugin + + + org.apache.maven.plugins + maven-gpg-plugin + + + + + diff --git a/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/GppModel.java b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/GppModel.java index 02fe98d7..a85a5e25 100644 --- a/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/GppModel.java +++ b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/GppModel.java @@ -1,44 +1,124 @@ package com.iab.gpp.encoder; import java.util.ArrayList; +import java.util.Arrays; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.stream.Collectors; import com.iab.gpp.encoder.error.DecodingException; import com.iab.gpp.encoder.error.EncodingException; +import com.iab.gpp.encoder.error.InvalidFieldException; +import com.iab.gpp.encoder.field.HeaderV1Field; import com.iab.gpp.encoder.section.EncodableSection; import com.iab.gpp.encoder.section.HeaderV1; -import com.iab.gpp.encoder.section.TcfCaV2; +import com.iab.gpp.encoder.section.Sections; +import com.iab.gpp.encoder.section.TcfCaV1; import com.iab.gpp.encoder.section.TcfEuV2; +import com.iab.gpp.encoder.section.UsCa; +import com.iab.gpp.encoder.section.UsCo; +import com.iab.gpp.encoder.section.UsCt; +import com.iab.gpp.encoder.section.UsDe; +import com.iab.gpp.encoder.section.UsFl; +import com.iab.gpp.encoder.section.UsIa; +import com.iab.gpp.encoder.section.UsMt; +import com.iab.gpp.encoder.section.UsNat; +import com.iab.gpp.encoder.section.UsNe; +import com.iab.gpp.encoder.section.UsNh; +import com.iab.gpp.encoder.section.UsNj; +import com.iab.gpp.encoder.section.UsOr; +import com.iab.gpp.encoder.section.UsTn; +import com.iab.gpp.encoder.section.UsTx; +import com.iab.gpp.encoder.section.UsUt; +import com.iab.gpp.encoder.section.UsVa; import com.iab.gpp.encoder.section.UspV1; public class GppModel { private Map sections = new HashMap<>(); - private String[] sectionOrder = new String[] {TcfEuV2.NAME, TcfCaV2.NAME, UspV1.NAME}; + + private String encodedString; + + private boolean dirty = false; + private boolean decoded = true; public GppModel() { } - public GppModel(String encodedString) throws DecodingException { - if (encodedString != null && encodedString.length() > 0) { - this.decode(encodedString); - } + public GppModel(String encodedString) { + decode(encodedString); + } + + public void setFieldValue(int sectionId, String fieldName, Object value) { + setFieldValue(Sections.SECTION_ID_NAME_MAP.get(sectionId), fieldName, value); } public void setFieldValue(String sectionName, String fieldName, Object value) { + if (!this.decoded) { + this.sections = this.decodeModel(this.encodedString); + this.dirty = false; + this.decoded = true; + } + EncodableSection section = null; if (!this.sections.containsKey(sectionName)) { - if (sectionName.equals(TcfCaV2.NAME)) { - section = new TcfCaV2(); - this.sections.put(TcfCaV2.NAME, section); + if (sectionName.equals(TcfCaV1.NAME)) { + section = new TcfCaV1(); + this.sections.put(TcfCaV1.NAME, section); } else if (sectionName.equals(TcfEuV2.NAME)) { section = new TcfEuV2(); this.sections.put(TcfEuV2.NAME, section); } else if (sectionName.equals(UspV1.NAME)) { section = new UspV1(); this.sections.put(UspV1.NAME, section); + } else if (sectionName.equals(UsNat.NAME)) { + section = new UsNat(); + this.sections.put(UsNat.NAME, section); + } else if (sectionName.equals(UsCa.NAME)) { + section = new UsCa(); + this.sections.put(UsCa.NAME, section); + } else if (sectionName.equals(UsVa.NAME)) { + section = new UsVa(); + this.sections.put(UsVa.NAME, section); + } else if (sectionName.equals(UsCo.NAME)) { + section = new UsCo(); + this.sections.put(UsCo.NAME, section); + } else if (sectionName.equals(UsUt.NAME)) { + section = new UsUt(); + this.sections.put(UsUt.NAME, section); + } else if (sectionName.equals(UsCt.NAME)) { + section = new UsCt(); + this.sections.put(UsCt.NAME, section); + } else if (sectionName.equals(UsFl.NAME)) { + section = new UsFl(); + this.sections.put(UsFl.NAME, section); + } else if (sectionName.equals(UsMt.NAME)) { + section = new UsMt(); + this.sections.put(UsMt.NAME, section); + } else if (sectionName.equals(UsOr.NAME)) { + section = new UsOr(); + this.sections.put(UsOr.NAME, section); + } else if (sectionName.equals(UsTx.NAME)) { + section = new UsTx(); + this.sections.put(UsTx.NAME, section); + } else if (sectionName.equals(UsDe.NAME)) { + section = new UsDe(); + this.sections.put(UsDe.NAME, section); + } else if (sectionName.equals(UsIa.NAME)) { + section = new UsIa(); + this.sections.put(UsIa.NAME, section); + } else if (sectionName.equals(UsNe.NAME)) { + section = new UsNe(); + this.sections.put(UsNe.NAME, section); + } else if (sectionName.equals(UsNh.NAME)) { + section = new UsNh(); + this.sections.put(UsNh.NAME, section); + } else if (sectionName.equals(UsNj.NAME)) { + section = new UsNj(); + this.sections.put(UsNj.NAME, section); + } else if (sectionName.equals(UsTn.NAME)) { + section = new UsTn(); + this.sections.put(UsTn.NAME, section); } } else { section = this.sections.get(sectionName); @@ -46,12 +126,23 @@ public void setFieldValue(String sectionName, String fieldName, Object value) { if (section != null) { section.setFieldValue(fieldName, value); + this.dirty = true; } else { - throw new Error(sectionName + " not found"); + throw new InvalidFieldException(sectionName + "." + fieldName + " not found"); } } + public Object getFieldValue(int sectionId, String fieldName) { + return getFieldValue(Sections.SECTION_ID_NAME_MAP.get(sectionId), fieldName); + } + public Object getFieldValue(String sectionName, String fieldName) { + if (!this.decoded) { + this.sections = this.decodeModel(this.encodedString); + this.dirty = false; + this.decoded = true; + } + if (this.sections.containsKey(sectionName)) { return this.sections.get(sectionName).getFieldValue(fieldName); } else { @@ -59,7 +150,17 @@ public Object getFieldValue(String sectionName, String fieldName) { } } + public boolean hasField(int sectionId, String fieldName) { + return hasField(Sections.SECTION_ID_NAME_MAP.get(sectionId), fieldName); + } + public boolean hasField(String sectionName, String fieldName) { + if (!this.decoded) { + this.sections = this.decodeModel(this.encodedString); + this.dirty = false; + this.decoded = true; + } + if (this.sections.containsKey(sectionName)) { return this.sections.get(sectionName).hasField(fieldName); } else { @@ -67,17 +168,47 @@ public boolean hasField(String sectionName, String fieldName) { } } + public boolean hasSection(int sectionId) { + return hasSection(Sections.SECTION_ID_NAME_MAP.get(sectionId)); + } + public boolean hasSection(String sectionName) { + if (!this.decoded) { + this.sections = this.decodeModel(this.encodedString); + this.dirty = false; + this.decoded = true; + } + return this.sections.containsKey(sectionName); } public HeaderV1 getHeader() { + if (!this.decoded) { + this.sections = this.decodeModel(this.encodedString); + this.dirty = false; + this.decoded = true; + } + HeaderV1 header = new HeaderV1(); - header.setFieldValue("SectionIds", this.getSectionIds()); + try { + header.setFieldValue("SectionIds", this.getSectionIds()); + } catch (InvalidFieldException e) { + + } return header; } + public EncodableSection getSection(int sectionId) { + return getSection(Sections.SECTION_ID_NAME_MAP.get(sectionId)); + } + public EncodableSection getSection(String sectionName) { + if (!this.decoded) { + this.sections = this.decodeModel(this.encodedString); + this.dirty = false; + this.decoded = true; + } + if (this.sections.containsKey(sectionName)) { return this.sections.get(sectionName); } else { @@ -85,8 +216,32 @@ public EncodableSection getSection(String sectionName) { } } - public TcfCaV2 getTcfCaV2Section() { - return (TcfCaV2) getSection(TcfCaV2.NAME); + public void deleteSection(int sectionId) { + deleteSection(Sections.SECTION_ID_NAME_MAP.get(sectionId)); + } + + public void deleteSection(String sectionName) { + if (!this.decoded) { + this.sections = this.decodeModel(this.encodedString); + this.dirty = false; + this.decoded = true; + } + + if (this.sections.containsKey(sectionName)) { + this.sections.remove(sectionName); + this.dirty = true; + } + } + + public void clear() { + this.sections.clear(); + this.encodedString = null; + this.dirty = false; + this.decoded = true; + } + + public TcfCaV1 getTcfCaV1Section() { + return (TcfCaV1) getSection(TcfCaV1.NAME); } public TcfEuV2 getTcfEuV2Section() { @@ -97,10 +252,80 @@ public UspV1 getUspV1Section() { return (UspV1) getSection(UspV1.NAME); } + public UsNat getUsNatSection() { + return (UsNat) getSection(UsNat.NAME); + } + + public UsCa getUsCaSection() { + return (UsCa) getSection(UsCa.NAME); + } + + public UsVa getUsVaSection() { + return (UsVa) getSection(UsVa.NAME); + } + + public UsCo getUsCoSection() { + return (UsCo) getSection(UsCo.NAME); + } + + public UsUt getUsUtSection() { + return (UsUt) getSection(UsUt.NAME); + } + + public UsCt getUsCtSection() { + return (UsCt) getSection(UsCt.NAME); + } + + public UsFl getUsFlSection() { + return (UsFl) getSection(UsFl.NAME); + } + + public UsMt getUsMtSection() { + return (UsMt) getSection(UsMt.NAME); + } + + public UsOr getUsOrSection() { + return (UsOr) getSection(UsOr.NAME); + } + + public UsTx getUsTxSection() { + return (UsTx) getSection(UsTx.NAME); + } + + public UsDe getUsDeSection() { + return (UsDe) getSection(UsDe.NAME); + } + + public UsIa getUsIaSection() { + return (UsIa) getSection(UsIa.NAME); + } + + public UsNe getUsNeSection() { + return (UsNe) getSection(UsNe.NAME); + } + + public UsNh getUsNhSection() { + return (UsNh) getSection(UsNh.NAME); + } + + public UsNj getUsNjSection() { + return (UsNj) getSection(UsNj.NAME); + } + + public UsTn getUsTnSection() { + return (UsTn) getSection(UsTn.NAME); + } + public List getSectionIds() { + if (!this.decoded) { + this.sections = this.decodeModel(this.encodedString); + this.dirty = false; + this.decoded = true; + } + List sectionIds = new ArrayList<>(); - for (int i = 0; i < this.sectionOrder.length; i++) { - String sectionName = this.sectionOrder[i]; + for (int i = 0; i < Sections.SECTION_ORDER.size(); i++) { + String sectionName = Sections.SECTION_ORDER.get(i); if (this.sections.containsKey(sectionName)) { EncodableSection section = this.sections.get(sectionName); sectionIds.add(section.getId()); @@ -109,50 +334,132 @@ public List getSectionIds() { return sectionIds; } - public String encode() throws EncodingException { + protected String encodeModel(Map sections) { List encodedSections = new ArrayList<>(); List sectionIds = new ArrayList<>(); - for (int i = 0; i < this.sectionOrder.length; i++) { - String sectionName = this.sectionOrder[i]; - if (this.sections.containsKey(sectionName)) { - EncodableSection section = this.sections.get(sectionName); + for (int i = 0; i < Sections.SECTION_ORDER.size(); i++) { + String sectionName = Sections.SECTION_ORDER.get(i); + if (sections.containsKey(sectionName)) { + EncodableSection section = sections.get(sectionName); encodedSections.add(section.encode()); sectionIds.add(section.getId()); } } HeaderV1 header = new HeaderV1(); - header.setFieldValue("SectionIds", this.getSectionIds()); + try { + header.setFieldValue("SectionIds", getSectionIds()); + } catch (InvalidFieldException e) { + throw new EncodingException(e); + } encodedSections.add(0, header.encode()); String encodedString = encodedSections.stream().collect(Collectors.joining("~")); return encodedString; } - public void decode(String str) throws DecodingException { - this.sections.clear(); + protected Map decodeModel(String str) { + if (str == null || str.isEmpty() || str.startsWith("D")) { + Map sections = new HashMap<>(); - String[] encodedSections = str.split("~"); - HeaderV1 header = new HeaderV1(encodedSections[0]); - this.sections.put(HeaderV1.NAME, header); + if (str != null && !str.isEmpty()) { + String[] encodedSections = str.split("~"); + HeaderV1 header = new HeaderV1(encodedSections[0]); + sections.put(HeaderV1.NAME, header); - @SuppressWarnings("unchecked") - List sectionIds = (List) header.getFieldValue("SectionIds"); - for (int i = 0; i < sectionIds.size(); i++) { - if (sectionIds.get(i).equals(TcfEuV2.ID)) { - TcfEuV2 section = new TcfEuV2(encodedSections[i + 1]); - this.sections.put(TcfEuV2.NAME, section); - } else if (sectionIds.get(i).equals(TcfCaV2.ID)) { - TcfCaV2 section = new TcfCaV2(encodedSections[i + 1]); - this.sections.put(TcfCaV2.NAME, section); - } else if (sectionIds.get(i).equals(UspV1.ID)) { - UspV1 section = new UspV1(encodedSections[i + 1]); - this.sections.put(UspV1.NAME, section); + @SuppressWarnings("unchecked") + List sectionIds = (List) header.getFieldValue("SectionIds"); + for (int i = 0; i < sectionIds.size(); i++) { + if (sectionIds.get(i).equals(TcfEuV2.ID)) { + TcfEuV2 section = new TcfEuV2(encodedSections[i + 1]); + sections.put(TcfEuV2.NAME, section); + } else if (sectionIds.get(i).equals(TcfCaV1.ID)) { + TcfCaV1 section = new TcfCaV1(encodedSections[i + 1]); + sections.put(TcfCaV1.NAME, section); + } else if (sectionIds.get(i).equals(UspV1.ID)) { + UspV1 section = new UspV1(encodedSections[i + 1]); + sections.put(UspV1.NAME, section); + } else if (sectionIds.get(i).equals(UsCa.ID)) { + UsCa section = new UsCa(encodedSections[i + 1]); + sections.put(UsCa.NAME, section); + } else if (sectionIds.get(i).equals(UsNat.ID)) { + UsNat section = new UsNat(encodedSections[i + 1]); + sections.put(UsNat.NAME, section); + } else if (sectionIds.get(i).equals(UsVa.ID)) { + UsVa section = new UsVa(encodedSections[i + 1]); + sections.put(UsVa.NAME, section); + } else if (sectionIds.get(i).equals(UsCo.ID)) { + UsCo section = new UsCo(encodedSections[i + 1]); + sections.put(UsCo.NAME, section); + } else if (sectionIds.get(i).equals(UsUt.ID)) { + UsUt section = new UsUt(encodedSections[i + 1]); + sections.put(UsUt.NAME, section); + } else if (sectionIds.get(i).equals(UsCt.ID)) { + UsCt section = new UsCt(encodedSections[i + 1]); + sections.put(UsCt.NAME, section); + } else if (sectionIds.get(i).equals(UsFl.ID)) { + UsFl section = new UsFl(encodedSections[i + 1]); + sections.put(UsFl.NAME, section); + } else if (sectionIds.get(i).equals(UsMt.ID)) { + UsMt section = new UsMt(encodedSections[i + 1]); + sections.put(UsMt.NAME, section); + } else if (sectionIds.get(i).equals(UsOr.ID)) { + UsOr section = new UsOr(encodedSections[i + 1]); + sections.put(UsOr.NAME, section); + } else if (sectionIds.get(i).equals(UsTx.ID)) { + UsTx section = new UsTx(encodedSections[i + 1]); + sections.put(UsTx.NAME, section); + } else if (sectionIds.get(i).equals(UsDe.ID)) { + UsDe section = new UsDe(encodedSections[i + 1]); + sections.put(UsDe.NAME, section); + } else if (sectionIds.get(i).equals(UsIa.ID)) { + UsIa section = new UsIa(encodedSections[i + 1]); + sections.put(UsIa.NAME, section); + } else if (sectionIds.get(i).equals(UsNe.ID)) { + UsNe section = new UsNe(encodedSections[i + 1]); + sections.put(UsNe.NAME, section); + } else if (sectionIds.get(i).equals(UsNh.ID)) { + UsNh section = new UsNh(encodedSections[i + 1]); + sections.put(UsNh.NAME, section); + } else if (sectionIds.get(i).equals(UsNj.ID)) { + UsNj section = new UsNj(encodedSections[i + 1]); + sections.put(UsNj.NAME, section); + } else if (sectionIds.get(i).equals(UsTn.ID)) { + UsTn section = new UsTn(encodedSections[i + 1]); + sections.put(UsTn.NAME, section); + } + } } + + return sections; + } else if (str.startsWith("C")) { + // old tcfeu only string + Map sections = new HashMap<>(); + + TcfEuV2 section = new TcfEuV2(str); + sections.put(TcfEuV2.NAME, section); + + HeaderV1 header = new HeaderV1(); + header.setFieldValue(HeaderV1Field.SECTION_IDS, Arrays.asList(2)); + sections.put(HeaderV1.NAME, section); + + return sections; + } else { + throw new DecodingException("Unable to decode '" + str + "'"); } } - public String encodeSection(String sectionName) throws EncodingException { + public String encodeSection(int sectionId) { + return encodeSection(Sections.SECTION_ID_NAME_MAP.get(sectionId)); + } + + public String encodeSection(String sectionName) { + if (!this.decoded) { + this.sections = this.decodeModel(this.encodedString); + this.dirty = false; + this.decoded = true; + } + if (this.sections.containsKey(sectionName)) { return this.sections.get(sectionName).encode(); } else { @@ -160,18 +467,76 @@ public String encodeSection(String sectionName) throws EncodingException { } } - public void decodeSection(String sectionName, String encodedString) throws DecodingException { + public void decodeSection(int sectionId, String encodedString) { + decodeSection(Sections.SECTION_ID_NAME_MAP.get(sectionId), encodedString); + } + + public void decodeSection(String sectionName, String encodedString) { + if (!this.decoded) { + this.sections = this.decodeModel(this.encodedString); + this.dirty = false; + this.decoded = true; + } + EncodableSection section = null; if (!this.sections.containsKey(sectionName)) { if (sectionName.equals(TcfEuV2.NAME)) { section = new TcfEuV2(); this.sections.put(TcfEuV2.NAME, section); - } else if (sectionName.equals(TcfCaV2.NAME)) { - section = new TcfCaV2(); - this.sections.put(TcfCaV2.NAME, section); + } else if (sectionName.equals(TcfCaV1.NAME)) { + section = new TcfCaV1(); + this.sections.put(TcfCaV1.NAME, section); } else if (sectionName.equals(UspV1.NAME)) { section = new UspV1(); this.sections.put(UspV1.NAME, section); + } else if (sectionName.equals(UsNat.NAME)) { + section = new UsNat(); + this.sections.put(UsNat.NAME, section); + } else if (sectionName.equals(UsCa.NAME)) { + section = new UsCa(); + this.sections.put(UsCa.NAME, section); + } else if (sectionName.equals(UsVa.NAME)) { + section = new UsVa(); + this.sections.put(UsVa.NAME, section); + } else if (sectionName.equals(UsCo.NAME)) { + section = new UsCo(); + this.sections.put(UsCo.NAME, section); + } else if (sectionName.equals(UsUt.NAME)) { + section = new UsUt(); + this.sections.put(UsUt.NAME, section); + } else if (sectionName.equals(UsCt.NAME)) { + section = new UsCt(); + this.sections.put(UsCt.NAME, section); + } else if (sectionName.equals(UsFl.NAME)) { + section = new UsFl(); + this.sections.put(UsFl.NAME, section); + } else if (sectionName.equals(UsMt.NAME)) { + section = new UsMt(); + this.sections.put(UsMt.NAME, section); + } else if (sectionName.equals(UsOr.NAME)) { + section = new UsOr(); + this.sections.put(UsOr.NAME, section); + } else if (sectionName.equals(UsTx.NAME)) { + section = new UsTx(); + this.sections.put(UsTx.NAME, section); + }else if (sectionName.equals(UsDe.NAME)) { + section = new UsDe(); + this.sections.put(UsDe.NAME, section); + }else if (sectionName.equals(UsIa.NAME)) { + section = new UsIa(); + this.sections.put(UsIa.NAME, section); + }else if (sectionName.equals(UsNe.NAME)) { + section = new UsNe(); + this.sections.put(UsNe.NAME, section); + }else if (sectionName.equals(UsNh.NAME)) { + section = new UsNh(); + this.sections.put(UsNh.NAME, section); + }else if (sectionName.equals(UsNj.NAME)) { + section = new UsNj(); + this.sections.put(UsNj.NAME, section); + }else if (sectionName.equals(UsTn.NAME)) { + section = new UsTn(); + this.sections.put(UsTn.NAME, section); } } else { section = this.sections.get(sectionName); @@ -179,6 +544,25 @@ public void decodeSection(String sectionName, String encodedString) throws Decod if (section != null) { section.decode(encodedString); + this.dirty = true; + } + } + + public String encode() { + if (this.encodedString == null || this.encodedString.isEmpty() || this.dirty) { + this.encodedString = encodeModel(this.sections); + this.dirty = false; + this.decoded = true; } + + return this.encodedString; + } + + public void decode(String encodedString) { + this.encodedString = encodedString; + this.dirty = false; + this.decoded = false; } + + } diff --git a/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/datatype/encoder/Base64UrlEncoder.java b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/base64/AbstractBase64UrlEncoder.java similarity index 84% rename from iabgpp-encoder/src/main/java/com/iab/gpp/encoder/datatype/encoder/Base64UrlEncoder.java rename to iabgpp-encoder/src/main/java/com/iab/gpp/encoder/base64/AbstractBase64UrlEncoder.java index a141ecea..a5434073 100644 --- a/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/datatype/encoder/Base64UrlEncoder.java +++ b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/base64/AbstractBase64UrlEncoder.java @@ -1,13 +1,17 @@ -package com.iab.gpp.encoder.datatype.encoder; +package com.iab.gpp.encoder.base64; import java.util.Map; import java.util.regex.Pattern; import java.util.stream.Collectors; import java.util.stream.Stream; +import com.iab.gpp.encoder.datatype.encoder.FixedIntegerEncoder; import com.iab.gpp.encoder.error.DecodingException; import com.iab.gpp.encoder.error.EncodingException; -public class Base64UrlEncoder { +public abstract class AbstractBase64UrlEncoder { + + abstract protected String pad(String bitString); + /** * Base 64 URL character set. Different from standard Base64 char set in that '+' and '/' are * replaced with '-' and '_'. @@ -28,19 +32,13 @@ public class Base64UrlEncoder { private static Pattern BASE64URL_VERIFICATION_PATTERN = Pattern.compile("^[A-Za-z0-9\\-_]*$", Pattern.CASE_INSENSITIVE); - public static String encode(String bitString) throws EncodingException { + public String encode(String bitString) { // should only be 0 or 1 if (!BITSTRING_VERIFICATION_PATTERN.matcher(bitString).matches()) { throw new EncodingException("Unencodable Base64Url '" + bitString + "'"); } - while (bitString.length() % 8 > 0) { - bitString += "0"; - } - - while (bitString.length() % 6 > 0) { - bitString += "0"; - } + bitString = pad(bitString); String str = ""; @@ -50,7 +48,7 @@ public static String encode(String bitString) throws EncodingException { try { int n = FixedIntegerEncoder.decode(s); - Character c = Base64UrlEncoder.DICT.charAt(n); + Character c = AbstractBase64UrlEncoder.DICT.charAt(n); str += c; index += 6; } catch (DecodingException e) { @@ -61,7 +59,7 @@ public static String encode(String bitString) throws EncodingException { return str; } - public static String decode(String str) throws DecodingException { + public String decode(String str) { // should contain only characters from the base64url set if (!BASE64URL_VERIFICATION_PATTERN.matcher(str).matches()) { throw new DecodingException("Undecodable Base64URL string"); @@ -71,7 +69,7 @@ public static String decode(String str) throws DecodingException { for (int i = 0; i < str.length(); i++) { char c = str.charAt(i); - Integer n = Base64UrlEncoder.REVERSE_DICT.get(c); + Integer n = AbstractBase64UrlEncoder.REVERSE_DICT.get(c); String s = FixedIntegerEncoder.encode(n, 6); bitString += s; } diff --git a/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/base64/CompressedBase64UrlEncoder.java b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/base64/CompressedBase64UrlEncoder.java new file mode 100644 index 00000000..638b4d7d --- /dev/null +++ b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/base64/CompressedBase64UrlEncoder.java @@ -0,0 +1,31 @@ +package com.iab.gpp.encoder.base64; + +import java.util.Arrays; + +public class CompressedBase64UrlEncoder extends AbstractBase64UrlEncoder { + + private static CompressedBase64UrlEncoder instance = new CompressedBase64UrlEncoder(); + + private CompressedBase64UrlEncoder() { + + } + + public static CompressedBase64UrlEncoder getInstance() { + return instance; + } + + @Override + protected String pad(String bitString) { + // https://github.com/InteractiveAdvertisingBureau/Global-Privacy-Platform/blob/main/Core/Consent%20String%20Specification.md#creating-a-gpp-string + char[] chars1 = null; + if(bitString.length() % 6 > 0) { + chars1 = new char[6 - (bitString.length() % 6)]; + } else { + chars1 = new char[0]; + } + Arrays.fill(chars1, '0'); + + return bitString + new String(chars1); + } + +} diff --git a/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/base64/TraditionalBase64UrlEncoder.java b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/base64/TraditionalBase64UrlEncoder.java new file mode 100644 index 00000000..78ffe719 --- /dev/null +++ b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/base64/TraditionalBase64UrlEncoder.java @@ -0,0 +1,28 @@ +package com.iab.gpp.encoder.base64; + +import java.util.Arrays; + +public class TraditionalBase64UrlEncoder extends AbstractBase64UrlEncoder { + + private static TraditionalBase64UrlEncoder instance = new TraditionalBase64UrlEncoder(); + + private TraditionalBase64UrlEncoder() { + + } + + public static TraditionalBase64UrlEncoder getInstance() { + return instance; + } + + @Override + protected String pad(String bitString) { + if(bitString.length() % 24 > 0) { + char[] chars = new char[24 - (bitString.length() % 24)]; + Arrays.fill(chars, '0'); + return bitString + new String(chars); + } else { + return bitString; + } + } + +} diff --git a/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/bitstring/BitStringEncoder.java b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/bitstring/BitStringEncoder.java new file mode 100644 index 00000000..12bcb182 --- /dev/null +++ b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/bitstring/BitStringEncoder.java @@ -0,0 +1,61 @@ +package com.iab.gpp.encoder.bitstring; + +import java.util.List; +import com.iab.gpp.encoder.datatype.AbstractEncodableBitStringDataType; +import com.iab.gpp.encoder.datatype.SubstringException; +import com.iab.gpp.encoder.error.DecodingException; +import com.iab.gpp.encoder.error.EncodingException; +import com.iab.gpp.encoder.field.EncodableBitStringFields; + +public class BitStringEncoder { + + private static BitStringEncoder instance = new BitStringEncoder(); + + private BitStringEncoder() { + + } + + public static BitStringEncoder getInstance() { + return instance; + } + + public String encode(EncodableBitStringFields fields, List fieldNames) { + String bitString = ""; + for (int i = 0; i < fieldNames.size(); i++) { + String fieldName = fieldNames.get(i); + if (fields.containsKey(fieldName)) { + AbstractEncodableBitStringDataType field = fields.get(fieldName); + bitString += field.encode(); + } else { + throw new EncodingException("Field not found: '" + fieldName + "'"); + } + } + + return bitString; + } + + public void decode(String bitString, List fieldNames, EncodableBitStringFields fields) { + int index = 0; + for (int i = 0; i < fieldNames.size(); i++) { + String fieldName = fieldNames.get(i); + if (fields.containsKey(fieldName)) { + AbstractEncodableBitStringDataType field = fields.get(fieldName); + try { + String substring = field.substring(bitString, index); + field.decode(substring); + index += substring.length(); + } catch (SubstringException e) { + if(field.getHardFailIfMissing()) { + throw new DecodingException("Unable to decode " + fieldName, e); + } else { + return; + } + } catch (Exception e) { + throw new DecodingException("Unable to decode " + fieldName, e); + } + } else { + throw new DecodingException("Field not found: '" + fieldName + "'"); + } + } + } +} diff --git a/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/datatype/AbstractEncodableBitStringDataType.java b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/datatype/AbstractEncodableBitStringDataType.java index d8c3dcfc..07d9588c 100644 --- a/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/datatype/AbstractEncodableBitStringDataType.java +++ b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/datatype/AbstractEncodableBitStringDataType.java @@ -1,19 +1,25 @@ package com.iab.gpp.encoder.datatype; -import com.iab.gpp.encoder.error.DecodingException; -import com.iab.gpp.encoder.error.EncodingException; - -public abstract class AbstractEncodableBitStringDataType { +import java.util.Collection; +import java.util.function.Predicate; +import java.util.stream.Collectors; +import com.iab.gpp.encoder.error.ValidationException; + +public abstract class AbstractEncodableBitStringDataType implements EncodableDataType { + //this if for backwards compatibility with the newer fields + protected boolean hardFailIfMissing = true; + protected Predicate validator = null; protected T value; - public AbstractEncodableBitStringDataType() { - + protected AbstractEncodableBitStringDataType(boolean hardFailIfMissing) { + this.hardFailIfMissing = hardFailIfMissing; } - - public AbstractEncodableBitStringDataType(T value) { - this.value = value; + + public AbstractEncodableBitStringDataType withValidator(Predicate validator) { + this.validator = validator; + return this; } - + public boolean hasValue() { return this.value != null; } @@ -24,12 +30,28 @@ public T getValue() { @SuppressWarnings("unchecked") public void setValue(Object value) { - this.value = (T) value; + T v = (T) value; + if (validator == null || validator.test(v)) { + this.value = v; + } else { + if (v instanceof Collection) { + throw new ValidationException("Invalid value '" + + ((Collection) v).stream().map(i -> i.toString()).collect(Collectors.joining(",")) + "'"); + } else { + throw new ValidationException("Invalid value '" + v + "'"); + } + } + + } + + public boolean getHardFailIfMissing() { + return this.hardFailIfMissing; } - public abstract String encode() throws EncodingException; + public abstract String encode(); + + public abstract void decode(String bitString); - public abstract void decode(String bitString) throws DecodingException; + public abstract String substring(String bitString, int fromIndex) throws SubstringException; - public abstract String substring(String bitString, int fromIndex) throws DecodingException; } diff --git a/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/datatype/DataType.java b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/datatype/DataType.java new file mode 100644 index 00000000..8a0d2c07 --- /dev/null +++ b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/datatype/DataType.java @@ -0,0 +1,7 @@ +package com.iab.gpp.encoder.datatype; + +public interface DataType { + boolean hasValue(); + T getValue(); + void setValue(Object value); +} diff --git a/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/datatype/EncodableArrayOfFixedIntegerRanges.java b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/datatype/EncodableArrayOfFixedIntegerRanges.java new file mode 100644 index 00000000..699e0d26 --- /dev/null +++ b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/datatype/EncodableArrayOfFixedIntegerRanges.java @@ -0,0 +1,110 @@ +package com.iab.gpp.encoder.datatype; + +import java.util.ArrayList; +import java.util.List; +import com.iab.gpp.encoder.datatype.encoder.FixedIntegerEncoder; +import com.iab.gpp.encoder.datatype.encoder.FixedIntegerRangeEncoder; +import com.iab.gpp.encoder.error.DecodingException; +import com.iab.gpp.encoder.error.EncodingException; + +public class EncodableArrayOfFixedIntegerRanges extends AbstractEncodableBitStringDataType> { + + private int keyBitStringLength; + private int typeBitStringLength; + + protected EncodableArrayOfFixedIntegerRanges(int keyBitStringLength, int typeBitStringLength) { + super(true); + this.keyBitStringLength = keyBitStringLength; + this.typeBitStringLength = typeBitStringLength; + } + + public EncodableArrayOfFixedIntegerRanges(int keyBitStringLength, int typeBitStringLength, List value) { + super(true); + this.keyBitStringLength = keyBitStringLength; + this.typeBitStringLength = typeBitStringLength; + setValue(value); + } + + public EncodableArrayOfFixedIntegerRanges(int keyBitStringLength, int typeBitStringLength, List value, boolean hardFailIfMissing) { + super(hardFailIfMissing); + this.keyBitStringLength = keyBitStringLength; + this.typeBitStringLength = typeBitStringLength; + setValue(value); + } + + @Override + public String encode() { + try { + List entries = this.value; + + StringBuilder sb = new StringBuilder(); + sb.append(FixedIntegerEncoder.encode(entries.size(), 12)); + for (RangeEntry entry : entries) { + sb.append(FixedIntegerEncoder.encode(entry.getKey(), keyBitStringLength)) + .append(FixedIntegerEncoder.encode(entry.getType(), typeBitStringLength)) + .append(FixedIntegerRangeEncoder.encode(entry.getIds())); + } + + return sb.toString(); + } catch (Exception e) { + throw new EncodingException(e); + } + } + + @Override + public void decode(String bitString) { + try { + List entries = new ArrayList<>(); + + int size = FixedIntegerEncoder.decode(bitString.substring(0, 12)); + int index = 12; + for (int i = 0; i < size; i++) { + int key = FixedIntegerEncoder.decode(bitString.substring(index, index + keyBitStringLength)); + index += keyBitStringLength; + + int type = FixedIntegerEncoder.decode(bitString.substring(index, index + typeBitStringLength)); + index += typeBitStringLength; + + String substring = new EncodableFixedIntegerRange().substring(bitString, index); + List ids = FixedIntegerRangeEncoder.decode(substring); + index += substring.length(); + + entries.add(new RangeEntry(key, type, ids)); + } + + this.value = entries; + } catch (Exception e) { + throw new DecodingException(e); + } + } + + @Override + public String substring(String bitString, int fromIndex) throws SubstringException { + try { + StringBuilder sb = new StringBuilder(); + sb.append(bitString.substring(fromIndex, fromIndex + 12)); + + int size = FixedIntegerEncoder.decode(sb.toString()); + + int index = fromIndex + sb.length(); + for (int i = 0; i < size; i++) { + String keySubstring = bitString.substring(index, index + keyBitStringLength); + index += keySubstring.length(); + sb.append(keySubstring); + + String typeSubstring = bitString.substring(index, index + typeBitStringLength); + index += typeSubstring.length(); + sb.append(typeSubstring); + + String rangeSubstring = new EncodableFixedIntegerRange().substring(bitString, index); + index += rangeSubstring.length(); + sb.append(rangeSubstring); + } + + return sb.toString(); + } catch (Exception e) { + throw new SubstringException(e); + } + } + +} diff --git a/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/datatype/EncodableBoolean.java b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/datatype/EncodableBoolean.java index bdb29bb1..340be3ab 100644 --- a/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/datatype/EncodableBoolean.java +++ b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/datatype/EncodableBoolean.java @@ -6,24 +6,41 @@ public class EncodableBoolean extends AbstractEncodableBitStringDataType { - public EncodableBoolean() { - super(); + protected EncodableBoolean() { + super(true); } public EncodableBoolean(Boolean value) { - super(value); + super(true); + setValue(value); } - public String encode() throws EncodingException { - return BooleanEncoder.encode(this.value); + public EncodableBoolean(Boolean value, boolean hardFailIfMissing) { + super(hardFailIfMissing); + setValue(value); } - public void decode(String bitString) throws DecodingException { - this.value = BooleanEncoder.decode(bitString); + public String encode() { + try { + return BooleanEncoder.encode(this.value); + } catch (Exception e) { + throw new EncodingException(e); + } } - public String substring(String bitString, int fromIndex) { - // TODO: validate - return bitString.substring(fromIndex, fromIndex + 1); + public void decode(String bitString) { + try { + this.value = BooleanEncoder.decode(bitString); + } catch (Exception e) { + throw new DecodingException(e); + } + } + + public String substring(String bitString, int fromIndex) throws SubstringException { + try { + return bitString.substring(fromIndex, fromIndex + 1); + } catch (Exception e) { + throw new SubstringException(e); + } } } diff --git a/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/datatype/EncodableDataType.java b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/datatype/EncodableDataType.java new file mode 100644 index 00000000..94d416a6 --- /dev/null +++ b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/datatype/EncodableDataType.java @@ -0,0 +1,7 @@ +package com.iab.gpp.encoder.datatype; + +public interface EncodableDataType extends DataType { + String encode(); + + void decode(String str); +} diff --git a/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/datatype/EncodableDatetime.java b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/datatype/EncodableDatetime.java index ad42a95a..a96c46f4 100644 --- a/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/datatype/EncodableDatetime.java +++ b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/datatype/EncodableDatetime.java @@ -3,27 +3,45 @@ import java.time.ZonedDateTime; import com.iab.gpp.encoder.datatype.encoder.DatetimeEncoder; import com.iab.gpp.encoder.error.DecodingException; +import com.iab.gpp.encoder.error.EncodingException; public class EncodableDatetime extends AbstractEncodableBitStringDataType { - public EncodableDatetime() { - super(); + protected EncodableDatetime() { + super(true); } public EncodableDatetime(ZonedDateTime value) { - super(value); + super(true); + setValue(value); + } + + public EncodableDatetime(ZonedDateTime value, boolean hardFailIfMissing) { + super(hardFailIfMissing); + setValue(value); } public String encode() { - return DatetimeEncoder.encode(this.value); + try { + return DatetimeEncoder.encode(this.value); + } catch (Exception e) { + throw new EncodingException(e); + } } - public void decode(String bitString) throws DecodingException { - this.value = DatetimeEncoder.decode(bitString); + public void decode(String bitString) { + try { + this.value = DatetimeEncoder.decode(bitString); + } catch (Exception e) { + throw new DecodingException(e); + } } - public String substring(String bitString, int fromIndex) { - // TODO: validate - return bitString.substring(fromIndex, fromIndex + 36); + public String substring(String bitString, int fromIndex) throws SubstringException { + try { + return bitString.substring(fromIndex, fromIndex + 36); + } catch (Exception e) { + throw new SubstringException(e); + } } } diff --git a/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/datatype/EncodableFibonacciInteger.java b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/datatype/EncodableFibonacciInteger.java index b9d9187e..3da64a15 100644 --- a/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/datatype/EncodableFibonacciInteger.java +++ b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/datatype/EncodableFibonacciInteger.java @@ -2,31 +2,50 @@ import com.iab.gpp.encoder.datatype.encoder.FibonacciIntegerEncoder; import com.iab.gpp.encoder.error.DecodingException; +import com.iab.gpp.encoder.error.EncodingException; public class EncodableFibonacciInteger extends AbstractEncodableBitStringDataType { - public EncodableFibonacciInteger() { - super(); + protected EncodableFibonacciInteger() { + super(true); } public EncodableFibonacciInteger(Integer value) { - super(value); + super(true); + setValue(value); + } + + public EncodableFibonacciInteger(Integer value, boolean hardFailIfMissing) { + super(hardFailIfMissing); + setValue(value); } public String encode() { - return FibonacciIntegerEncoder.encode(this.value); + try { + return FibonacciIntegerEncoder.encode(this.value); + } catch (Exception e) { + throw new EncodingException(e); + } } - public void decode(String bitString) throws DecodingException { - this.value = FibonacciIntegerEncoder.decode(bitString); + public void decode(String bitString) { + try { + this.value = FibonacciIntegerEncoder.decode(bitString); + } catch (Exception e) { + throw new DecodingException(e); + } } - public String substring(String bitString, int fromIndex) { - int index = bitString.indexOf("11", fromIndex); - if (index > 0) { - return bitString.substring(fromIndex, index + 2); - } else { - return bitString; + public String substring(String bitString, int fromIndex) throws SubstringException { + try { + int index = bitString.indexOf("11", fromIndex); + if (index > 0) { + return bitString.substring(fromIndex, index + 2); + } else { + return bitString; + } + } catch (Exception e) { + throw new SubstringException(e); } } } diff --git a/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/datatype/EncodableFibonacciIntegerRange.java b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/datatype/EncodableFibonacciIntegerRange.java index e0ec7c64..53ab2eb2 100644 --- a/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/datatype/EncodableFibonacciIntegerRange.java +++ b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/datatype/EncodableFibonacciIntegerRange.java @@ -1,39 +1,70 @@ package com.iab.gpp.encoder.datatype; +import java.util.ArrayList; import java.util.List; +import java.util.TreeSet; import com.iab.gpp.encoder.datatype.encoder.FibonacciIntegerRangeEncoder; import com.iab.gpp.encoder.datatype.encoder.FixedIntegerEncoder; import com.iab.gpp.encoder.error.DecodingException; +import com.iab.gpp.encoder.error.EncodingException; public class EncodableFibonacciIntegerRange extends AbstractEncodableBitStringDataType> { - public EncodableFibonacciIntegerRange() { - super(); + protected EncodableFibonacciIntegerRange() { + super(true); } public EncodableFibonacciIntegerRange(List value) { - super(value); + super(true); + setValue(value); } + public EncodableFibonacciIntegerRange(List value, boolean hardFailIfMissing) { + super(hardFailIfMissing); + setValue(value); + } + public String encode() { - return FibonacciIntegerRangeEncoder.encode(this.value); + try { + return FibonacciIntegerRangeEncoder.encode(this.value); + } catch (Exception e) { + throw new EncodingException(e); + } } - public void decode(String bitString) throws DecodingException { - this.value = FibonacciIntegerRangeEncoder.decode(bitString); + public void decode(String bitString) { + try { + this.value = FibonacciIntegerRangeEncoder.decode(bitString); + } catch (Exception e) { + throw new DecodingException(e); + } } - public String substring(String bitString, int fromIndex) throws DecodingException { - // TODO: add some validation - int count = FixedIntegerEncoder.decode(bitString.substring(fromIndex, fromIndex + 12)); - int index = fromIndex + 12; - for (int i = 0; i < count; i++) { - if (bitString.charAt(index) == '1') { - index = bitString.indexOf("11", bitString.indexOf("11", index + 1) + 2) + 2; - } else { - index = bitString.indexOf("11", index + 1) + 2; + public String substring(String bitString, int fromIndex) throws SubstringException { + try { + int count = FixedIntegerEncoder.decode(bitString.substring(fromIndex, fromIndex + 12)); + int index = fromIndex + 12; + for (int i = 0; i < count; i++) { + if (bitString.charAt(index) == '1') { + index = bitString.indexOf("11", bitString.indexOf("11", index + 1) + 2) + 2; + } else { + index = bitString.indexOf("11", index + 1) + 2; + } } + return bitString.substring(fromIndex, index); + } catch (Exception e) { + throw new SubstringException(e); } - return bitString.substring(fromIndex, index); + } + + @SuppressWarnings("unchecked") + @Override + public void setValue(Object value) { + super.setValue(new ArrayList<>(new TreeSet<>((List) value))); + } + + @Override + public List getValue() { + return new ArrayList<>(super.getValue()); } } diff --git a/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/datatype/EncodableFixedBitfield.java b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/datatype/EncodableFixedBitfield.java index 581d5ff1..5e6890d9 100644 --- a/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/datatype/EncodableFixedBitfield.java +++ b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/datatype/EncodableFixedBitfield.java @@ -1,5 +1,6 @@ package com.iab.gpp.encoder.datatype; +import java.util.ArrayList; import java.util.List; import com.iab.gpp.encoder.datatype.encoder.FixedBitfieldEncoder; import com.iab.gpp.encoder.error.DecodingException; @@ -7,28 +8,69 @@ public class EncodableFixedBitfield extends AbstractEncodableBitStringDataType> { - private int bitStringLength; + private int numElements; - public EncodableFixedBitfield(int bitStringLength) { - super(); - this.bitStringLength = bitStringLength; + protected EncodableFixedBitfield(int numElements) { + super(true); + this.numElements = numElements; } - public EncodableFixedBitfield(int bitStringLength, List value) { - super(value); - this.bitStringLength = bitStringLength; + protected EncodableFixedBitfield(int numElements, boolean hardFailIfMissing) { + super(hardFailIfMissing); + this.numElements = numElements; } - public String encode() throws EncodingException { - return FixedBitfieldEncoder.encode(this.value, this.bitStringLength); + public EncodableFixedBitfield(List value) { + super(true); + this.numElements = value.size(); + setValue(value); } - public void decode(String bitString) throws DecodingException { - this.value = FixedBitfieldEncoder.decode(bitString); + public EncodableFixedBitfield(List value, boolean hardFailIfMissing) { + super(hardFailIfMissing); + this.numElements = value.size(); + setValue(value); } - public String substring(String bitString, int fromIndex) { - // TODO: validate - return bitString.substring(fromIndex, fromIndex + this.bitStringLength); + public String encode() { + try { + return FixedBitfieldEncoder.encode(this.value, this.numElements); + } catch (Exception e) { + throw new EncodingException(e); + } + } + + public void decode(String bitString) { + try { + this.value = FixedBitfieldEncoder.decode(bitString); + } catch (Exception e) { + throw new DecodingException(e); + } + } + + public String substring(String bitString, int fromIndex) throws SubstringException { + try { + return bitString.substring(fromIndex, fromIndex + this.numElements); + } catch (Exception e) { + throw new SubstringException(e); + } + } + + @SuppressWarnings("unchecked") + @Override + public void setValue(Object value) { + List v = new ArrayList<>((List) value); + for (int i = v.size(); i < numElements; i++) { + v.add(false); + } + if (v.size() > numElements) { + v = v.subList(0, numElements); + } + super.setValue(v); + } + + @Override + public List getValue() { + return new ArrayList<>(super.getValue()); } } diff --git a/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/datatype/EncodableFixedInteger.java b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/datatype/EncodableFixedInteger.java index 90340f29..9fd25fb0 100644 --- a/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/datatype/EncodableFixedInteger.java +++ b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/datatype/EncodableFixedInteger.java @@ -2,31 +2,50 @@ import com.iab.gpp.encoder.datatype.encoder.FixedIntegerEncoder; import com.iab.gpp.encoder.error.DecodingException; +import com.iab.gpp.encoder.error.EncodingException; public class EncodableFixedInteger extends AbstractEncodableBitStringDataType { private int bitStringLength; - public EncodableFixedInteger(int bitStringLength) { - super(); + protected EncodableFixedInteger(int bitStringLength) { + super(true); this.bitStringLength = bitStringLength; } public EncodableFixedInteger(int bitStringLength, Integer value) { - super(value); + super(true); this.bitStringLength = bitStringLength; + setValue(value); + } + + public EncodableFixedInteger(int bitStringLength, Integer value, boolean hardFailIfMissing) { + super(hardFailIfMissing); + this.bitStringLength = bitStringLength; + setValue(value); } public String encode() { - return FixedIntegerEncoder.encode(this.value, this.bitStringLength); + try { + return FixedIntegerEncoder.encode(this.value, this.bitStringLength); + } catch (Exception e) { + throw new EncodingException(e); + } } - public void decode(String bitString) throws DecodingException { - this.value = FixedIntegerEncoder.decode(bitString); + public void decode(String bitString) { + try { + this.value = FixedIntegerEncoder.decode(bitString); + } catch (Exception e) { + throw new DecodingException(e); + } } - public String substring(String bitString, int fromIndex) { - // TODO: validate - return bitString.substring(fromIndex, fromIndex + this.bitStringLength); + public String substring(String bitString, int fromIndex) throws SubstringException { + try { + return bitString.substring(fromIndex, fromIndex + this.bitStringLength); + } catch (Exception e) { + throw new SubstringException(e); + } } } diff --git a/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/datatype/EncodableFixedIntegerList.java b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/datatype/EncodableFixedIntegerList.java new file mode 100644 index 00000000..f491e5ee --- /dev/null +++ b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/datatype/EncodableFixedIntegerList.java @@ -0,0 +1,75 @@ +package com.iab.gpp.encoder.datatype; + +import java.util.ArrayList; +import java.util.List; +import com.iab.gpp.encoder.datatype.encoder.FixedIntegerListEncoder; +import com.iab.gpp.encoder.error.DecodingException; +import com.iab.gpp.encoder.error.EncodingException; + +public class EncodableFixedIntegerList extends AbstractEncodableBitStringDataType> { + + private int elementBitStringLength; + private int numElements; + + protected EncodableFixedIntegerList(int elementBitStringLength, int numElements) { + super(true); + this.elementBitStringLength = elementBitStringLength; + this.numElements = numElements; + } + + public EncodableFixedIntegerList(int elementBitStringLength, List value) { + super(true); + this.elementBitStringLength = elementBitStringLength; + this.numElements = value.size(); + setValue(value); + } + + public EncodableFixedIntegerList(int elementBitStringLength, List value, boolean hardFailIfMissing) { + super(hardFailIfMissing); + this.elementBitStringLength = elementBitStringLength; + this.numElements = value.size(); + setValue(value); + } + + public String encode() { + try { + return FixedIntegerListEncoder.encode(this.value, this.elementBitStringLength, this.numElements); + } catch (Exception e) { + throw new EncodingException(e); + } + } + + public void decode(String bitString) { + try { + this.value = FixedIntegerListEncoder.decode(bitString, this.elementBitStringLength, this.numElements); + } catch (Exception e) { + throw new DecodingException(e); + } + } + + public String substring(String bitString, int fromIndex) throws SubstringException { + try { + return bitString.substring(fromIndex, fromIndex + (this.elementBitStringLength * numElements)); + } catch (Exception e) { + throw new SubstringException(e); + } + } + + @SuppressWarnings("unchecked") + @Override + public void setValue(Object value) { + List v = new ArrayList<>((List) value); + for (int i = v.size(); i < numElements; i++) { + v.add(0); + } + if (v.size() > numElements) { + v = v.subList(0, numElements); + } + super.setValue(v); + } + + @Override + public List getValue() { + return new ArrayList<>(super.getValue()); + } +} diff --git a/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/datatype/EncodableFixedIntegerRange.java b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/datatype/EncodableFixedIntegerRange.java index 84409d9c..7fdbd5a8 100644 --- a/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/datatype/EncodableFixedIntegerRange.java +++ b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/datatype/EncodableFixedIntegerRange.java @@ -1,40 +1,70 @@ package com.iab.gpp.encoder.datatype; +import java.util.ArrayList; import java.util.List; +import java.util.TreeSet; import com.iab.gpp.encoder.datatype.encoder.FixedIntegerEncoder; import com.iab.gpp.encoder.datatype.encoder.FixedIntegerRangeEncoder; import com.iab.gpp.encoder.error.DecodingException; +import com.iab.gpp.encoder.error.EncodingException; public class EncodableFixedIntegerRange extends AbstractEncodableBitStringDataType> { - public EncodableFixedIntegerRange() { - super(); + protected EncodableFixedIntegerRange() { + super(true); } public EncodableFixedIntegerRange(List value) { - super(value); + super(true); + setValue(value); + } + + public EncodableFixedIntegerRange(List value, boolean hardFailIfMissing) { + super(hardFailIfMissing); + setValue(value); } public String encode() { - return FixedIntegerRangeEncoder.encode(this.value); + try { + return FixedIntegerRangeEncoder.encode(this.value); + } catch (Exception e) { + throw new EncodingException(e); + } } - public void decode(String bitString) throws DecodingException { - this.value = FixedIntegerRangeEncoder.decode(bitString); + public void decode(String bitString) { + try { + this.value = FixedIntegerRangeEncoder.decode(bitString); + } catch (Exception e) { + throw new DecodingException(e); + } } - public String substring(String bitString, int fromIndex) throws DecodingException { - // TODO: add some validation - int count = FixedIntegerEncoder.decode(bitString.substring(fromIndex, fromIndex + 12)); - int index = fromIndex + 12; - for (int i = 0; i < count; i++) { - if (bitString.charAt(index) == '1') { - index += 33; - } else { - index += 17; + public String substring(String bitString, int fromIndex) throws SubstringException { + try { + int count = FixedIntegerEncoder.decode(bitString.substring(fromIndex, fromIndex + 12)); + int index = fromIndex + 12; + for (int i = 0; i < count; i++) { + if (bitString.charAt(index) == '1') { + index += 33; + } else { + index += 17; + } } + return bitString.substring(fromIndex, index); + } catch (Exception e) { + throw new SubstringException(e); } - return bitString.substring(fromIndex, index); } + @SuppressWarnings("unchecked") + @Override + public void setValue(Object value) { + super.setValue(new ArrayList<>(new TreeSet<>((List) value))); + } + + @Override + public List getValue() { + return new ArrayList<>(super.getValue()); + } } diff --git a/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/datatype/EncodableFixedString.java b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/datatype/EncodableFixedString.java index 8ae8035b..4cea9b48 100644 --- a/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/datatype/EncodableFixedString.java +++ b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/datatype/EncodableFixedString.java @@ -8,26 +8,44 @@ public class EncodableFixedString extends AbstractEncodableBitStringDataType value) { - super(value); + super(true); this.getLengthSupplier = getLengthSupplier; + this.setValue(value); } - public String encode() throws EncodingException { - return FixedBitfieldEncoder.encode(this.value, this.getLengthSupplier.getAsInt()); + public EncodableFlexibleBitfield(IntSupplier getLengthSupplier, List value, boolean hardFailIfMissing) { + super(hardFailIfMissing); + this.getLengthSupplier = getLengthSupplier; + this.setValue(value); + } + + public String encode() { + try { + return FixedBitfieldEncoder.encode(this.value, this.getLengthSupplier.getAsInt()); + } catch (Exception e) { + throw new EncodingException(e); + } + } + + public void decode(String bitString) { + try { + this.value = FixedBitfieldEncoder.decode(bitString); + } catch (Exception e) { + throw new DecodingException(e); + } + } + + public String substring(String bitString, int fromIndex) throws SubstringException { + try { + return bitString.substring(fromIndex, fromIndex + this.getLengthSupplier.getAsInt()); + } catch (Exception e) { + throw new SubstringException(e); + } } - public void decode(String bitString) throws DecodingException { - this.value = FixedBitfieldEncoder.decode(bitString); + @SuppressWarnings("unchecked") + @Override + public void setValue(Object value) { + int numElements = this.getLengthSupplier.getAsInt(); + List v = new ArrayList<>((List) value); + for (int i = v.size(); i < numElements; i++) { + v.add(false); + } + if (v.size() > numElements) { + v = v.subList(0, numElements); + } + super.setValue(v); } - public String substring(String bitString, int fromIndex) { - // TODO: validate - return bitString.substring(fromIndex, fromIndex + this.getLengthSupplier.getAsInt()); + @Override + public List getValue() { + return new ArrayList<>(super.getValue()); } } diff --git a/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/datatype/EncodableOptimizedFibonacciRange.java b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/datatype/EncodableOptimizedFibonacciRange.java index 43dcf112..2e49855f 100644 --- a/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/datatype/EncodableOptimizedFibonacciRange.java +++ b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/datatype/EncodableOptimizedFibonacciRange.java @@ -2,69 +2,66 @@ import java.util.ArrayList; import java.util.List; -import com.iab.gpp.encoder.datatype.encoder.FibonacciIntegerRangeEncoder; -import com.iab.gpp.encoder.datatype.encoder.FixedBitfieldEncoder; +import java.util.TreeSet; import com.iab.gpp.encoder.datatype.encoder.FixedIntegerEncoder; +import com.iab.gpp.encoder.datatype.encoder.OptimizedFibonacciRangeEncoder; import com.iab.gpp.encoder.error.DecodingException; import com.iab.gpp.encoder.error.EncodingException; public class EncodableOptimizedFibonacciRange extends AbstractEncodableBitStringDataType> { - public EncodableOptimizedFibonacciRange() { - super(); + protected EncodableOptimizedFibonacciRange() { + super(true); } public EncodableOptimizedFibonacciRange(List value) { - super(value); + super(true); + setValue(value); } - public String encode() throws EncodingException { - // TODO: encoding the range before choosing the shortest is inefficient. There is probably a way - // to identify in advance which will be shorter based on the array length and values - int max = this.value.size() > 0 ? this.value.get(this.value.size() - 1) : 0; - String rangeBitString = FibonacciIntegerRangeEncoder.encode(this.value); - int rangeLength = rangeBitString.length(); - int bitFieldLength = max; + public EncodableOptimizedFibonacciRange(List value, boolean hardFailIfMissing) { + super(hardFailIfMissing); + setValue(value); + } - if (rangeLength <= bitFieldLength) { - return "1" + FixedIntegerEncoder.encode(max, 16) + rangeBitString; - } else { - List bits = new ArrayList<>(); - int index = 0; - for (int i = 0; i < max; i++) { - if (i == this.value.get(index) - 1) { - bits.add(true); - index++; - } else { - bits.add(false); - } - } - return "0" + FixedIntegerEncoder.encode(max, 16) + FixedBitfieldEncoder.encode(bits, bitFieldLength); + public String encode() { + try { + return OptimizedFibonacciRangeEncoder.encode(this.value); + } catch (Exception e) { + throw new EncodingException(e); } } - public void decode(String bitString) throws DecodingException { - if (bitString.charAt(16) == '1') { - this.value = FibonacciIntegerRangeEncoder.decode(bitString.substring(17)); - } else { - List value = new ArrayList<>(); - List bits = FixedBitfieldEncoder.decode(bitString.substring(17)); - for (int i = 0; i < bits.size(); i++) { - if (bits.get(i) == true) { - value.add(i + 1); - } - } - this.value = value; + public void decode(String bitString) { + try { + this.value = OptimizedFibonacciRangeEncoder.decode(bitString); + } catch (Exception e) { + throw new DecodingException(e); } } - public String substring(String bitString, int fromIndex) throws DecodingException { - int max = FixedIntegerEncoder.decode(bitString.substring(fromIndex, fromIndex + 16)); - if (bitString.charAt(fromIndex + 16) == '1') { - return (bitString.substring(fromIndex, 17) - + new EncodableFibonacciIntegerRange().substring(bitString, fromIndex + 17)); - } else { - return bitString.substring(fromIndex, fromIndex + 17 + max); + public String substring(String bitString, int fromIndex) throws SubstringException { + try { + int max = FixedIntegerEncoder.decode(bitString.substring(fromIndex, fromIndex + 16)); + if (bitString.charAt(fromIndex + 16) == '1') { + return (bitString.substring(fromIndex, fromIndex + 17) + + new EncodableFibonacciIntegerRange().substring(bitString, fromIndex + 17)); + } else { + return bitString.substring(fromIndex, fromIndex + 17 + max); + } + } catch (Exception e) { + throw new SubstringException(e); } } + + @SuppressWarnings("unchecked") + @Override + public void setValue(Object value) { + super.setValue(new ArrayList<>(new TreeSet<>((List) value))); + } + + @Override + public List getValue() { + return new ArrayList<>(super.getValue()); + } } diff --git a/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/datatype/EncodableOptimizedFixedRange.java b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/datatype/EncodableOptimizedFixedRange.java index 0fb2b7d3..57f4b8e9 100644 --- a/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/datatype/EncodableOptimizedFixedRange.java +++ b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/datatype/EncodableOptimizedFixedRange.java @@ -2,68 +2,67 @@ import java.util.ArrayList; import java.util.List; -import com.iab.gpp.encoder.datatype.encoder.FixedBitfieldEncoder; +import java.util.TreeSet; import com.iab.gpp.encoder.datatype.encoder.FixedIntegerEncoder; -import com.iab.gpp.encoder.datatype.encoder.FixedIntegerRangeEncoder; +import com.iab.gpp.encoder.datatype.encoder.OptimizedFixedRangeEncoder; import com.iab.gpp.encoder.error.DecodingException; import com.iab.gpp.encoder.error.EncodingException; + public class EncodableOptimizedFixedRange extends AbstractEncodableBitStringDataType> { - public EncodableOptimizedFixedRange() { - super(); + protected EncodableOptimizedFixedRange() { + super(true); } public EncodableOptimizedFixedRange(List value) { - super(value); + super(true); + setValue(value); } - public String encode() throws EncodingException { - // TODO: encoding the range before choosing the shortest is inefficient. There is probably a way - // to identify in advance which will be shorter based on the array length and values - int max = this.value.size() > 0 ? this.value.get(this.value.size() - 1) : 0; - String rangeBitString = FixedIntegerRangeEncoder.encode(this.value); - int rangeLength = rangeBitString.length(); - int bitFieldLength = max; + public EncodableOptimizedFixedRange(List value, boolean hardFailIfMissing) { + super(hardFailIfMissing); + setValue(value); + } - if (rangeLength <= bitFieldLength) { - return "1" + FixedIntegerEncoder.encode(max, 16) + rangeBitString; - } else { - List bits = new ArrayList<>(); - int index = 0; - for (int i = 0; i < max; i++) { - if (i == this.value.get(index) - 1) { - bits.add(true); - index++; - } else { - bits.add(false); - } - } - return "0" + FixedIntegerEncoder.encode(max, 16) + FixedBitfieldEncoder.encode(bits, bitFieldLength); + public String encode() { + try { + return OptimizedFixedRangeEncoder.encode(this.value); + } catch (Exception e) { + throw new EncodingException(e); } } - public void decode(String bitString) throws DecodingException { - if (bitString.charAt(16) == '1') { - this.value = FixedIntegerRangeEncoder.decode(bitString.substring(17)); - } else { - List value = new ArrayList<>(); - List bits = FixedBitfieldEncoder.decode(bitString.substring(17)); - for (int i = 0; i < bits.size(); i++) { - if (bits.get(i) == true) { - value.add(i + 1); - } - } - this.value = value; + public void decode(String bitString) { + try { + this.value = OptimizedFixedRangeEncoder.decode(bitString); + } catch (Exception e) { + throw new DecodingException(e); } } - public String substring(String bitString, int fromIndex) throws DecodingException { - int max = FixedIntegerEncoder.decode(bitString.substring(fromIndex, fromIndex + 16)); - if (bitString.charAt(fromIndex + 16) == '1') { - return bitString.substring(fromIndex, 17) + new EncodableFixedIntegerRange().substring(bitString, fromIndex + 17); - } else { - return bitString.substring(fromIndex, fromIndex + 17 + max); + public String substring(String bitString, int fromIndex) throws SubstringException { + try { + int max = FixedIntegerEncoder.decode(bitString.substring(fromIndex, fromIndex + 16)); + if (bitString.charAt(fromIndex + 16) == '1') { + return bitString.substring(fromIndex, fromIndex + 17) + + new EncodableFixedIntegerRange().substring(bitString, fromIndex + 17); + } else { + return bitString.substring(fromIndex, fromIndex + 17 + max); + } + } catch (Exception e) { + throw new SubstringException(e); } } + + @SuppressWarnings("unchecked") + @Override + public void setValue(Object value) { + super.setValue(new ArrayList<>(new TreeSet<>((List) value))); + } + + @Override + public List getValue() { + return new ArrayList<>(super.getValue()); + } } diff --git a/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/datatype/RangeEntry.java b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/datatype/RangeEntry.java new file mode 100644 index 00000000..0237ed18 --- /dev/null +++ b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/datatype/RangeEntry.java @@ -0,0 +1,42 @@ +package com.iab.gpp.encoder.datatype; + +import java.util.List; + +public class RangeEntry { + + private int key; + private int type; + private List ids; + + public RangeEntry(int key, int type, List ids) { + super(); + this.key = key; + this.type = type; + this.ids = ids; + } + + public int getKey() { + return key; + } + + public void setKey(int key) { + this.key = key; + } + + public int getType() { + return type; + } + + public void setType(int type) { + this.type = type; + } + + public List getIds() { + return ids; + } + + public void setIds(List ids) { + this.ids = ids; + } + +} diff --git a/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/datatype/SubstringException.java b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/datatype/SubstringException.java new file mode 100644 index 00000000..e9df8ca6 --- /dev/null +++ b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/datatype/SubstringException.java @@ -0,0 +1,18 @@ +package com.iab.gpp.encoder.datatype; + +public class SubstringException extends Exception { + + private static final long serialVersionUID = 1825100490468259890L; + + public SubstringException(String msg) { + super(msg); + } + + public SubstringException(Exception e) { + super(e); + } + + public SubstringException(String msg, Exception e) { + super(msg, e); + } +} diff --git a/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/datatype/UnencodableCharacter.java b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/datatype/UnencodableCharacter.java new file mode 100644 index 00000000..4ef9c256 --- /dev/null +++ b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/datatype/UnencodableCharacter.java @@ -0,0 +1,49 @@ +package com.iab.gpp.encoder.datatype; + +import java.util.function.Predicate; +import com.iab.gpp.encoder.error.ValidationException; + +public class UnencodableCharacter implements DataType { + + private Predicate validator; + private Character value = null; + + public UnencodableCharacter() { + this.validator = v -> true; + } + + public UnencodableCharacter(Character value) { + this.validator = v -> true; + setValue(value); + } + + public UnencodableCharacter(Character value, Predicate validator) { + this.validator = validator; + setValue(value); + } + + public void setValidator(Predicate validator) { + this.validator = validator; + } + + @Override + public boolean hasValue() { + return this.value != null; + } + + @Override + public Character getValue() { + return this.value; + } + + @Override + public void setValue(Object value) { + Character c = (Character)value.toString().charAt(0); + if(validator.test(c)) { + this.value = c; + } else { + throw new ValidationException("Invalid value '" + c + "'"); + } + } + +} diff --git a/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/datatype/UnencodableInteger.java b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/datatype/UnencodableInteger.java new file mode 100644 index 00000000..60dcddfd --- /dev/null +++ b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/datatype/UnencodableInteger.java @@ -0,0 +1,49 @@ +package com.iab.gpp.encoder.datatype; + +import java.util.function.Predicate; +import com.iab.gpp.encoder.error.ValidationException; + +public class UnencodableInteger implements DataType { + + private Predicate validator; + private Integer value = null; + + public UnencodableInteger() { + this.validator = v -> true; + } + + public UnencodableInteger(Integer value) { + this.validator = v -> true; + setValue(value); + } + + public UnencodableInteger(Integer value, Predicate validator) { + this.validator = validator; + setValue(value); + } + + public void setValidator(Predicate validator) { + this.validator = validator; + } + + @Override + public boolean hasValue() { + return this.value != null; + } + + @Override + public Integer getValue() { + return this.value; + } + + @Override + public void setValue(Object value) { + Integer i = (Integer)value; + if(validator.test(i)) { + this.value = i; + } else { + throw new ValidationException("Invalid value '" + i + "'"); + } + } + +} diff --git a/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/datatype/encoder/ArrayOfRangesEntryEncoder.java b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/datatype/encoder/ArrayOfRangesEntryEncoder.java new file mode 100644 index 00000000..de1449b3 --- /dev/null +++ b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/datatype/encoder/ArrayOfRangesEntryEncoder.java @@ -0,0 +1,43 @@ +package com.iab.gpp.encoder.datatype.encoder; + +import java.util.regex.Pattern; +import com.iab.gpp.encoder.error.DecodingException; + +public class ArrayOfRangesEntryEncoder { + + private static Pattern BITSTRING_VERIFICATION_PATTERN = Pattern.compile("^[0-1]*$", Pattern.CASE_INSENSITIVE); + + public static String encode(long value, int bitStringLength) { + String bitString = ""; + while (value > 0) { + if ((value & 1) == 1) { + bitString = "1" + bitString; + } else { + bitString = "0" + bitString; + } + value = value >> 1; + } + + while (bitString.length() < bitStringLength) { + bitString = "0" + bitString; + } + + return bitString; + } + + public static long decode(String bitString) throws DecodingException { + if (!BITSTRING_VERIFICATION_PATTERN.matcher(bitString).matches()) { + throw new DecodingException("Undecodable FixedLong '" + bitString + "'"); + } + + long value = 0; + + for (int i = 0; i < bitString.length(); i++) { + if (bitString.charAt(bitString.length() - (i + 1)) == '1') { + value += 1L << i; + } + } + + return value; + } +} diff --git a/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/datatype/encoder/BooleanEncoder.java b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/datatype/encoder/BooleanEncoder.java index b49ff391..20e6cbd0 100644 --- a/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/datatype/encoder/BooleanEncoder.java +++ b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/datatype/encoder/BooleanEncoder.java @@ -4,7 +4,7 @@ import com.iab.gpp.encoder.error.EncodingException; public class BooleanEncoder { - public static String encode(Boolean value) throws EncodingException { + public static String encode(Boolean value) { if (value == true) { return "1"; } else if (value == false) { @@ -14,7 +14,7 @@ public static String encode(Boolean value) throws EncodingException { } } - public static boolean decode(String bitString) throws DecodingException { + public static boolean decode(String bitString) { if (bitString.equals("1")) { return true; } else if (bitString.equals("0")) { diff --git a/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/datatype/encoder/FixedBitfieldEncoder.java b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/datatype/encoder/FixedBitfieldEncoder.java index 20a71c13..6c922263 100644 --- a/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/datatype/encoder/FixedBitfieldEncoder.java +++ b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/datatype/encoder/FixedBitfieldEncoder.java @@ -10,7 +10,11 @@ public class FixedBitfieldEncoder { private static Pattern BITSTRING_VERIFICATION_PATTERN = Pattern.compile("^[0-1]*$", Pattern.CASE_INSENSITIVE); - public static String encode(List value, int bitStringLength) throws EncodingException { + public static String encode(List value, int bitStringLength) { + if (value.size() > bitStringLength) { + throw new EncodingException("Too many values '" + value.size() + "'"); + } + String bitString = ""; for (int i = 0; i < value.size(); i++) { bitString += BooleanEncoder.encode(value.get(i)); @@ -23,7 +27,7 @@ public static String encode(List value, int bitStringLength) throws Enc return bitString; } - public static List decode(String bitString) throws DecodingException { + public static List decode(String bitString) { if (!BITSTRING_VERIFICATION_PATTERN.matcher(bitString).matches()) { throw new DecodingException("Undecodable FixedBitfield '" + bitString + "'"); } diff --git a/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/datatype/encoder/FixedIntegerEncoder.java b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/datatype/encoder/FixedIntegerEncoder.java index 2870af60..dfc6802f 100644 --- a/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/datatype/encoder/FixedIntegerEncoder.java +++ b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/datatype/encoder/FixedIntegerEncoder.java @@ -2,6 +2,7 @@ import java.util.regex.Pattern; import com.iab.gpp.encoder.error.DecodingException; +import com.iab.gpp.encoder.error.EncodingException; public class FixedIntegerEncoder { @@ -20,6 +21,11 @@ public static String encode(int value, int bitStringLength) { value = value >> 1; } + if (bitString.length() > bitStringLength) { + throw new EncodingException( + "Numeric value '" + value + "' is too large for a bit string length of '" + bitStringLength + "'"); + } + while (bitString.length() < bitStringLength) { bitString = "0" + bitString; } @@ -31,9 +37,6 @@ public static int decode(String bitString) throws DecodingException { if (!BITSTRING_VERIFICATION_PATTERN.matcher(bitString).matches()) { throw new DecodingException("Undecodable FixedInteger '" + bitString + "'"); } - - // return parseInt(bitString, 2); - int value = 0; for (int i = 0; i < bitString.length(); i++) { diff --git a/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/datatype/encoder/FixedIntegerListEncoder.java b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/datatype/encoder/FixedIntegerListEncoder.java new file mode 100644 index 00000000..044dfe26 --- /dev/null +++ b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/datatype/encoder/FixedIntegerListEncoder.java @@ -0,0 +1,63 @@ +package com.iab.gpp.encoder.datatype.encoder; + +import java.util.ArrayList; +import java.util.List; +import java.util.regex.Pattern; +import com.iab.gpp.encoder.error.DecodingException; +import com.iab.gpp.encoder.error.EncodingException; + +public class FixedIntegerListEncoder { + + private static Pattern BITSTRING_VERIFICATION_PATTERN = Pattern.compile("^[0-1]*$", Pattern.CASE_INSENSITIVE); + + public static String encode(List value, int elementBitStringLength, int numElements) { + if(value.size() > numElements) { + throw new EncodingException("Too many values '" + value.size() + "'"); + } + + String bitString = ""; + for (int i = 0; i < value.size(); i++) { + bitString += FixedIntegerEncoder.encode(value.get(i), elementBitStringLength); + } + + while (bitString.length() < elementBitStringLength * numElements) { + bitString += "0"; + } + + return bitString; + } + + public static List decode(String bitString, int elementBitStringLength, int numElements) + throws DecodingException { + if (!BITSTRING_VERIFICATION_PATTERN.matcher(bitString).matches()) { + throw new DecodingException("Undecodable FixedIntegerList '" + bitString + "'"); + } + + if (bitString.length() > elementBitStringLength * numElements) { + throw new DecodingException("Undecodable FixedIntegerList '" + bitString + "'"); + } + + if (bitString.length() % elementBitStringLength != 0) { + throw new DecodingException("Undecodable FixedIntegerList '" + bitString + "'"); + } + + while (bitString.length() < elementBitStringLength * numElements) { + bitString += "0"; + } + + if (bitString.length() > elementBitStringLength * numElements) { + bitString = bitString.substring(0, elementBitStringLength * numElements); + } + + List value = new ArrayList<>(); + for (int i = 0; i < bitString.length(); i += elementBitStringLength) { + value.add(FixedIntegerEncoder.decode(bitString.substring(i, i + elementBitStringLength))); + } + + while (value.size() < numElements) { + value.add(0); + } + + return value; + } +} diff --git a/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/datatype/encoder/FixedLongEncoder.java b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/datatype/encoder/FixedLongEncoder.java index 76ef8baf..c244a601 100644 --- a/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/datatype/encoder/FixedLongEncoder.java +++ b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/datatype/encoder/FixedLongEncoder.java @@ -2,6 +2,7 @@ import java.util.regex.Pattern; import com.iab.gpp.encoder.error.DecodingException; +import com.iab.gpp.encoder.error.EncodingException; public class FixedLongEncoder { @@ -18,6 +19,11 @@ public static String encode(long value, int bitStringLength) { value = value >> 1; } + if (bitString.length() > bitStringLength) { + throw new EncodingException( + "Numeric value '" + value + "' is too large for a bit string length of '" + bitStringLength + "'"); + } + while (bitString.length() < bitStringLength) { bitString = "0" + bitString; } diff --git a/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/datatype/encoder/FixedStringEncoder.java b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/datatype/encoder/FixedStringEncoder.java index 5cb8762a..38db681e 100644 --- a/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/datatype/encoder/FixedStringEncoder.java +++ b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/datatype/encoder/FixedStringEncoder.java @@ -8,7 +8,7 @@ public class FixedStringEncoder { private static Pattern BITSTRING_VERIFICATION_PATTERN = Pattern.compile("^[0-1]*$", Pattern.CASE_INSENSITIVE); - public static String encode(String value, int stringLength) throws EncodingException { + public static String encode(String value, int stringLength) { while (value.length() < stringLength) { value += " "; } @@ -29,7 +29,7 @@ public static String encode(String value, int stringLength) throws EncodingExcep return bitString; } - public static String decode(String bitString) throws DecodingException { + public static String decode(String bitString) { if (!BITSTRING_VERIFICATION_PATTERN.matcher(bitString).matches() || bitString.length() % 6 != 0) { throw new DecodingException("Undecodable FixedString '" + bitString + "'"); } diff --git a/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/datatype/encoder/OptimizedFibonacciRangeEncoder.java b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/datatype/encoder/OptimizedFibonacciRangeEncoder.java new file mode 100644 index 00000000..3492fbcc --- /dev/null +++ b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/datatype/encoder/OptimizedFibonacciRangeEncoder.java @@ -0,0 +1,56 @@ +package com.iab.gpp.encoder.datatype.encoder; + +import java.util.ArrayList; +import java.util.List; +import java.util.regex.Pattern; +import com.iab.gpp.encoder.error.DecodingException; +import com.iab.gpp.encoder.error.EncodingException; + +public class OptimizedFibonacciRangeEncoder { + + private static Pattern BITSTRING_VERIFICATION_PATTERN = Pattern.compile("^[0-1]*$", Pattern.CASE_INSENSITIVE); + + public static String encode(List value) throws EncodingException { + // TODO: encoding the range before choosing the shortest is inefficient. There is probably a way + // to identify in advance which will be shorter based on the array length and values + int max = value.size() > 0 ? value.get(value.size() - 1) : 0; + String rangeBitString = FibonacciIntegerRangeEncoder.encode(value); + int rangeLength = rangeBitString.length(); + int bitFieldLength = max; + + if (rangeLength <= bitFieldLength) { + return FixedIntegerEncoder.encode(max, 16) + "1" + rangeBitString; + } else { + List bits = new ArrayList<>(); + int index = 0; + for (int i = 0; i < max; i++) { + if (i == value.get(index) - 1) { + bits.add(true); + index++; + } else { + bits.add(false); + } + } + return FixedIntegerEncoder.encode(max, 16) + "0" + FixedBitfieldEncoder.encode(bits, bitFieldLength); + } + } + + public static List decode(String bitString) throws DecodingException { + if (!BITSTRING_VERIFICATION_PATTERN.matcher(bitString).matches() || bitString.length() < 12) { + throw new DecodingException("Undecodable FibonacciIntegerRange '" + bitString + "'"); + } + + if (bitString.charAt(16) == '1') { + return FibonacciIntegerRangeEncoder.decode(bitString.substring(17)); + } else { + List value = new ArrayList<>(); + List bits = FixedBitfieldEncoder.decode(bitString.substring(17)); + for (int i = 0; i < bits.size(); i++) { + if (bits.get(i) == true) { + value.add(i + 1); + } + } + return value; + } + } +} diff --git a/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/datatype/encoder/OptimizedFixedRangeEncoder.java b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/datatype/encoder/OptimizedFixedRangeEncoder.java new file mode 100644 index 00000000..73fb5e68 --- /dev/null +++ b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/datatype/encoder/OptimizedFixedRangeEncoder.java @@ -0,0 +1,57 @@ +package com.iab.gpp.encoder.datatype.encoder; + +import java.util.ArrayList; +import java.util.List; +import java.util.regex.Pattern; +import com.iab.gpp.encoder.error.DecodingException; +import com.iab.gpp.encoder.error.EncodingException; + +public class OptimizedFixedRangeEncoder { + + private static Pattern BITSTRING_VERIFICATION_PATTERN = Pattern.compile("^[0-1]*$", Pattern.CASE_INSENSITIVE); + + public static String encode(List value) throws EncodingException { + // TODO: encoding the range before choosing the shortest is inefficient. There is probably a way + // to identify in advance which will be shorter based on the array length and values + int max = value.size() > 0 ? value.get(value.size() - 1) : 0; + String rangeBitString = FixedIntegerRangeEncoder.encode(value); + int rangeLength = rangeBitString.length(); + int bitFieldLength = max; + + if (rangeLength <= bitFieldLength) { + return FixedIntegerEncoder.encode(max, 16) + "1" + rangeBitString; + } else { + List bits = new ArrayList<>(); + int index = 0; + for (int i = 0; i < max; i++) { + if (i == value.get(index) - 1) { + bits.add(true); + index++; + } else { + bits.add(false); + } + } + + return FixedIntegerEncoder.encode(max, 16) + "0" + FixedBitfieldEncoder.encode(bits, bitFieldLength); + } + } + + public static List decode(String bitString) throws DecodingException { + if (!BITSTRING_VERIFICATION_PATTERN.matcher(bitString).matches() || bitString.length() < 12) { + throw new DecodingException("Undecodable FixedIntegerRange '" + bitString + "'"); + } + + if (bitString.charAt(16) == '1') { + return FixedIntegerRangeEncoder.decode(bitString.substring(17)); + } else { + List value = new ArrayList<>(); + List bits = FixedBitfieldEncoder.decode(bitString.substring(17)); + for (int i = 0; i < bits.size(); i++) { + if (bits.get(i) == true) { + value.add(i + 1); + } + } + return value; + } + } +} diff --git a/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/error/DecodingException.java b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/error/DecodingException.java index 9ea130c1..d60c3459 100644 --- a/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/error/DecodingException.java +++ b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/error/DecodingException.java @@ -1,10 +1,18 @@ package com.iab.gpp.encoder.error; -public class DecodingException extends Exception { +public class DecodingException extends RuntimeException { private static final long serialVersionUID = 2098268445119981680L; public DecodingException(String msg) { super(msg); } + + public DecodingException(Exception e) { + super(e); + } + + public DecodingException(String msg, Exception e) { + super(msg, e); + } } diff --git a/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/error/EncodingException.java b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/error/EncodingException.java index 57ec5efb..a7f19355 100644 --- a/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/error/EncodingException.java +++ b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/error/EncodingException.java @@ -1,10 +1,18 @@ package com.iab.gpp.encoder.error; -public class EncodingException extends Exception { +public class EncodingException extends RuntimeException { private static final long serialVersionUID = 1161321945571871601L; public EncodingException(String msg) { super(msg); } + + public EncodingException(Exception e) { + super(e); + } + + public EncodingException(String msg, Exception e) { + super(msg, e); + } } diff --git a/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/error/InvalidFieldException.java b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/error/InvalidFieldException.java new file mode 100644 index 00000000..22113280 --- /dev/null +++ b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/error/InvalidFieldException.java @@ -0,0 +1,18 @@ +package com.iab.gpp.encoder.error; + +public class InvalidFieldException extends RuntimeException { + + private static final long serialVersionUID = 2098268445119981680L; + + public InvalidFieldException(String msg) { + super(msg); + } + + public InvalidFieldException(Exception e) { + super(e); + } + + public InvalidFieldException(String msg, Exception e) { + super(msg, e); + } +} diff --git a/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/error/ValidationException.java b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/error/ValidationException.java new file mode 100644 index 00000000..733a740b --- /dev/null +++ b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/error/ValidationException.java @@ -0,0 +1,18 @@ +package com.iab.gpp.encoder.error; + +public class ValidationException extends DecodingException { + + private static final long serialVersionUID = 2098268445119981680L; + + public ValidationException(String msg) { + super(msg); + } + + public ValidationException(Exception e) { + super(e); + } + + public ValidationException(String msg, Exception e) { + super(msg, e); + } +} diff --git a/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/field/EncodableBitStringFields.java b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/field/EncodableBitStringFields.java new file mode 100644 index 00000000..d2ac0f43 --- /dev/null +++ b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/field/EncodableBitStringFields.java @@ -0,0 +1,31 @@ +package com.iab.gpp.encoder.field; + +import java.util.HashMap; +import java.util.Map; +import com.iab.gpp.encoder.datatype.AbstractEncodableBitStringDataType; + +public class EncodableBitStringFields implements Fields> { + + private Map> fields = new HashMap<>(); + + public boolean containsKey(String key) { + return this.fields.containsKey(key); + } + + public void put(String key, AbstractEncodableBitStringDataType value) { + this.fields.put(key, value); + } + + public AbstractEncodableBitStringDataType get(String key) { + return this.fields.get(key); + } + + public Map> getAll() { + return new HashMap<>(this.fields); + } + + public void reset(Fields> fields) { + this.fields.clear(); + this.fields.putAll(fields.getAll()); + } +} diff --git a/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/field/Fields.java b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/field/Fields.java new file mode 100644 index 00000000..ca091e7f --- /dev/null +++ b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/field/Fields.java @@ -0,0 +1,14 @@ +package com.iab.gpp.encoder.field; + +import java.util.Map; +import com.iab.gpp.encoder.datatype.DataType; + +public interface Fields> { + + boolean containsKey(String key); + void put(String key, T value); + T get(String key); + Map getAll(); + void reset(Fields fields); + +} diff --git a/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/field/GenericFields.java b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/field/GenericFields.java new file mode 100644 index 00000000..00263e55 --- /dev/null +++ b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/field/GenericFields.java @@ -0,0 +1,31 @@ +package com.iab.gpp.encoder.field; + +import java.util.HashMap; +import java.util.Map; +import com.iab.gpp.encoder.datatype.DataType; + +public class GenericFields implements Fields> { + + private Map> fields = new HashMap<>(); + + public boolean containsKey(String key) { + return this.fields.containsKey(key); + } + + public void put(String key, DataType value) { + this.fields.put(key, value); + } + + public DataType get(String key) { + return this.fields.get(key); + } + + public Map> getAll() { + return new HashMap<>(this.fields); + } + + public void reset(Fields> fields) { + this.fields.clear(); + this.fields.putAll(fields.getAll()); + } +} diff --git a/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/field/HeaderV1Field.java b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/field/HeaderV1Field.java index 384befab..17f1f5d9 100644 --- a/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/field/HeaderV1Field.java +++ b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/field/HeaderV1Field.java @@ -1,9 +1,21 @@ package com.iab.gpp.encoder.field; +import java.util.Arrays; +import java.util.List; + public class HeaderV1Field { public static String ID = "Id"; public static String VERSION = "Version"; public static String SECTION_IDS = "SectionIds"; + //@formatter:off + public static List HEADER_CORE_SEGMENT_FIELD_NAMES = Arrays.asList(new String[] { + HeaderV1Field.ID, + HeaderV1Field.VERSION, + HeaderV1Field.SECTION_IDS + }); + //@formatter:on + + } diff --git a/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/field/TcfCaV1Field.java b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/field/TcfCaV1Field.java new file mode 100644 index 00000000..c87e886d --- /dev/null +++ b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/field/TcfCaV1Field.java @@ -0,0 +1,73 @@ +package com.iab.gpp.encoder.field; + +import java.util.Arrays; +import java.util.List; + +public class TcfCaV1Field { + + public static String VERSION = "Version"; + public static String CREATED = "Created"; + public static String LAST_UPDATED = "LastUpdated"; + public static String CMP_ID = "CmpId"; + public static String CMP_VERSION = "CmpVersion"; + public static String CONSENT_SCREEN = "ConsentScreen"; + public static String CONSENT_LANGUAGE = "ConsentLanguage"; + public static String VENDOR_LIST_VERSION = "VendorListVersion"; + public static String TCF_POLICY_VERSION = "TcfPolicyVersion"; + public static String USE_NON_STANDARD_STACKS = "UseNonStandardStacks"; + public static String SPECIAL_FEATURE_EXPRESS_CONSENT = "SpecialFeatureExpressConsent"; + public static String PURPOSES_EXPRESS_CONSENT = "PurposesExpressConsent"; + public static String PURPOSES_IMPLIED_CONSENT = "PurposesImpliedConsent"; + public static String VENDOR_EXPRESS_CONSENT = "VendorExpressConsent"; + public static String VENDOR_IMPLIED_CONSENT = "VendorImpliedConsent"; + public static String PUB_RESTRICTIONS = "PubRestrictions"; + + public static String PUB_PURPOSES_SEGMENT_TYPE = "PubPurposesSegmentType"; + public static String PUB_PURPOSES_EXPRESS_CONSENT = "PubPurposesExpressConsent"; + public static String PUB_PURPOSES_IMPLIED_CONSENT = "PubPurposesImpliedConsent"; + public static String NUM_CUSTOM_PURPOSES = "NumCustomPurposes"; + public static String CUSTOM_PURPOSES_EXPRESS_CONSENT = "CustomPurposesExpressConsent"; + public static String CUSTOM_PURPOSES_IMPLIED_CONSENT = "CustomPurposesImpliedConsent"; + + public static String DISCLOSED_VENDORS_SEGMENT_TYPE = "DisclosedVendorsSegmentType"; + public static String DISCLOSED_VENDORS = "DisclosedVendors"; + + //@formatter:off + public static List TCFCAV1_CORE_SEGMENT_FIELD_NAMES = Arrays.asList(new String[] { + TcfCaV1Field.VERSION, + TcfCaV1Field.CREATED, + TcfCaV1Field.LAST_UPDATED, + TcfCaV1Field.CMP_ID, + TcfCaV1Field.CMP_VERSION, + TcfCaV1Field.CONSENT_SCREEN, + TcfCaV1Field.CONSENT_LANGUAGE, + TcfCaV1Field.VENDOR_LIST_VERSION, + TcfCaV1Field.TCF_POLICY_VERSION, + TcfCaV1Field.USE_NON_STANDARD_STACKS, + TcfCaV1Field.SPECIAL_FEATURE_EXPRESS_CONSENT, + TcfCaV1Field.PURPOSES_EXPRESS_CONSENT, + TcfCaV1Field.PURPOSES_IMPLIED_CONSENT, + TcfCaV1Field.VENDOR_EXPRESS_CONSENT, + TcfCaV1Field.VENDOR_IMPLIED_CONSENT, + TcfCaV1Field.PUB_RESTRICTIONS + }); + //@formatter:on + + //@formatter:off + public static List TCFCAV1_PUBLISHER_PURPOSES_SEGMENT_FIELD_NAMES = Arrays.asList(new String[] { + TcfCaV1Field.PUB_PURPOSES_SEGMENT_TYPE, + TcfCaV1Field.PUB_PURPOSES_EXPRESS_CONSENT, + TcfCaV1Field.PUB_PURPOSES_IMPLIED_CONSENT, + TcfCaV1Field.NUM_CUSTOM_PURPOSES, + TcfCaV1Field.CUSTOM_PURPOSES_EXPRESS_CONSENT, + TcfCaV1Field.CUSTOM_PURPOSES_IMPLIED_CONSENT, + }); + //@formatter:on + + //@formatter:off + public static List TCFCAV1_DISCLOSED_VENDORS_SEGMENT_FIELD_NAMES = Arrays.asList(new String[] { + TcfCaV1Field.DISCLOSED_VENDORS_SEGMENT_TYPE, + TcfCaV1Field.DISCLOSED_VENDORS, + }); + //@formatter:on +} diff --git a/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/field/TcfCaV2Field.java b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/field/TcfCaV2Field.java deleted file mode 100644 index 2aeba45b..00000000 --- a/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/field/TcfCaV2Field.java +++ /dev/null @@ -1,27 +0,0 @@ -package com.iab.gpp.encoder.field; - -public class TcfCaV2Field { - - public static String VERSION = "Version"; - public static String CREATED = "Created"; - public static String LAST_UPDATED = "LastUpdated"; - public static String CMP_ID = "CmpId"; - public static String CMP_VERSION = "CmpVersion"; - public static String CONSENT_SCREEN = "ConsentScreen"; - public static String CONSENT_LANGUAGE = "ConsentLanguage"; - public static String VENDOR_LIST_VERSION = "VendorListVersion"; - public static String TCF_POLICY_VERSION = "TcfPolicyVersion"; - public static String USE_NON_STANDARD_STACKS = "UseNonStandardStacks"; - public static String SPECIAL_FEATURE_EXPRESS_CONSENT = "SpecialFeatureExpressConsent"; - public static String PURPOSES_EXPRESS_CONSENT = "PurposesExpressConsent"; - public static String PURPOSES_IMPLIED_CONSENT = "PurposesImpliedConsent"; - public static String VENDOR_EXPRESS_CONSENT = "VendorExpressConsent"; - public static String VENDOR_IMPLIED_CONSENT = "VendorImpliedConsent"; - public static String SEGMENT_TYPE = "SegmentType"; - public static String PUB_PURPOSES_EXPRESS_CONSENT = "PubPurposesExpressConsent"; - public static String PUB_PURPOSES_IMPLIED_CONSENT = "PubPurposesImpliedConsent"; - public static String NUM_CUSTOM_PURPOSES = "NumCustomPurposes"; - public static String CUSTOM_PURPOSES_EXPRESS_CONSENT = "CustomPurposesExpressConsent"; - public static String CUSTOM_PURPOSES_IMPLIED_CONSENT = "CustomPurposesImpliedConsent"; - -} diff --git a/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/field/TcfEuV2Field.java b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/field/TcfEuV2Field.java index 660443c3..fedb510f 100644 --- a/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/field/TcfEuV2Field.java +++ b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/field/TcfEuV2Field.java @@ -1,5 +1,8 @@ package com.iab.gpp.encoder.field; +import java.util.Arrays; +import java.util.List; + public class TcfEuV2Field { public static String VERSION = "Version"; @@ -32,4 +35,52 @@ public class TcfEuV2Field { public static String VENDORS_DISCLOSED_SEGMENT_TYPE = "VendorsDisclosedSegmentType"; public static String VENDORS_DISCLOSED = "VendorsDisclosed"; + //@formatter:off + public static List TCFEUV2_CORE_SEGMENT_FIELD_NAMES = Arrays.asList(new String[] { + TcfEuV2Field.VERSION, + TcfEuV2Field.CREATED, + TcfEuV2Field.LAST_UPDATED, + TcfEuV2Field.CMP_ID, + TcfEuV2Field.CMP_VERSION, + TcfEuV2Field.CONSENT_SCREEN, + TcfEuV2Field.CONSENT_LANGUAGE, + TcfEuV2Field.VENDOR_LIST_VERSION, + TcfEuV2Field.POLICY_VERSION, + TcfEuV2Field.IS_SERVICE_SPECIFIC, + TcfEuV2Field.USE_NON_STANDARD_STACKS, + TcfEuV2Field.SPECIAL_FEATURE_OPTINS, + TcfEuV2Field.PURPOSE_CONSENTS, + TcfEuV2Field.PURPOSE_LEGITIMATE_INTERESTS, + TcfEuV2Field.PURPOSE_ONE_TREATMENT, + TcfEuV2Field.PUBLISHER_COUNTRY_CODE, + TcfEuV2Field.VENDOR_CONSENTS, + TcfEuV2Field.VENDOR_LEGITIMATE_INTERESTS, + TcfEuV2Field.PUBLISHER_RESTRICTIONS + }); + //@formatter:on + + //@formatter:off + public static List TCFEUV2_PUBLISHER_PURPOSES_SEGMENT_FIELD_NAMES = Arrays.asList(new String[] { + TcfEuV2Field.PUBLISHER_PURPOSES_SEGMENT_TYPE, + TcfEuV2Field.PUBLISHER_CONSENTS, + TcfEuV2Field.PUBLISHER_LEGITIMATE_INTERESTS, + TcfEuV2Field.NUM_CUSTOM_PURPOSES, + TcfEuV2Field.PUBLISHER_CUSTOM_CONSENTS, + TcfEuV2Field.PUBLISHER_CUSTOM_LEGITIMATE_INTERESTS, + }); + //@formatter:on + + //@formatter:off + public static List TCFEUV2_VENDORS_ALLOWED_SEGMENT_FIELD_NAMES = Arrays.asList(new String[] { + TcfEuV2Field.VENDORS_ALLOWED_SEGMENT_TYPE, + TcfEuV2Field.VENDORS_ALLOWED, + }); + //@formatter:on + + //@formatter:off + public static List TCFEUV2_VENDORS_DISCLOSED_SEGMENT_FIELD_NAMES = Arrays.asList(new String[] { + TcfEuV2Field.VENDORS_DISCLOSED_SEGMENT_TYPE, + TcfEuV2Field.VENDORS_DISCLOSED, + }); + //@formatter:on } diff --git a/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/field/UsCaField.java b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/field/UsCaField.java new file mode 100644 index 00000000..934f57ac --- /dev/null +++ b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/field/UsCaField.java @@ -0,0 +1,48 @@ +package com.iab.gpp.encoder.field; + +import java.util.Arrays; +import java.util.List; + +public class UsCaField { + + public static String VERSION = "Version"; + public static String SALE_OPT_OUT_NOTICE = "SaleOptOutNotice"; + public static String SHARING_OPT_OUT_NOTICE = "SharingOptOutNotice"; + public static String SENSITIVE_DATA_LIMIT_USE_NOTICE = "SensitiveDataLimitUseNotice"; + public static String SALE_OPT_OUT = "SaleOptOut"; + public static String SHARING_OPT_OUT = "SharingOptOut"; + public static String SENSITIVE_DATA_PROCESSING = "SensitiveDataProcessing"; + public static String KNOWN_CHILD_SENSITIVE_DATA_CONSENTS = "KnownChildSensitiveDataConsents"; + public static String PERSONAL_DATA_CONSENTS = "PersonalDataConsents"; + public static String MSPA_COVERED_TRANSACTION = "MspaCoveredTransaction"; + public static String MSPA_OPT_OUT_OPTION_MODE = "MspaOptOutOptionMode"; + public static String MSPA_SERVICE_PROVIDER_MODE = "MspaServiceProviderMode"; + + public static String GPC_SEGMENT_TYPE = "GpcSegmentType"; + public static String GPC_SEGMENT_INCLUDED = "GpcSegmentIncluded"; + public static String GPC = "Gpc"; + + //@formatter:off + public static List USCA_CORE_SEGMENT_FIELD_NAMES = Arrays.asList(new String[] { + UsCaField.VERSION, + UsCaField.SALE_OPT_OUT_NOTICE, + UsCaField.SHARING_OPT_OUT_NOTICE, + UsCaField.SENSITIVE_DATA_LIMIT_USE_NOTICE, + UsCaField.SALE_OPT_OUT, + UsCaField.SHARING_OPT_OUT, + UsCaField.SENSITIVE_DATA_PROCESSING, + UsCaField.KNOWN_CHILD_SENSITIVE_DATA_CONSENTS, + UsCaField.PERSONAL_DATA_CONSENTS, + UsCaField.MSPA_COVERED_TRANSACTION, + UsCaField.MSPA_OPT_OUT_OPTION_MODE, + UsCaField.MSPA_SERVICE_PROVIDER_MODE + }); + //@formatter:on + + //@formatter:off + public static List USCA_GPC_SEGMENT_FIELD_NAMES = Arrays.asList(new String[] { + UsCaField.GPC_SEGMENT_TYPE, + UsCaField.GPC + }); + //@formatter:on +} diff --git a/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/field/UsCoField.java b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/field/UsCoField.java new file mode 100644 index 00000000..cae4e769 --- /dev/null +++ b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/field/UsCoField.java @@ -0,0 +1,46 @@ +package com.iab.gpp.encoder.field; + +import java.util.Arrays; +import java.util.List; + +public class UsCoField { + + public static String VERSION = "Version"; + public static String SHARING_NOTICE = "SharingNotice"; + public static String SALE_OPT_OUT_NOTICE = "SaleOptOutNotice"; + public static String TARGETED_ADVERTISING_OPT_OUT_NOTICE = "TargetedAdvertisingOptOutNotice"; + public static String SALE_OPT_OUT = "SaleOptOut"; + public static String TARGETED_ADVERTISING_OPT_OUT = "TargetedAdvertisingOptOut"; + public static String SENSITIVE_DATA_PROCESSING = "SensitiveDataProcessing"; + public static String KNOWN_CHILD_SENSITIVE_DATA_CONSENTS = "KnownChildSensitiveDataConsents"; + public static String MSPA_COVERED_TRANSACTION = "MspaCoveredTransaction"; + public static String MSPA_OPT_OUT_OPTION_MODE = "MspaOptOutOptionMode"; + public static String MSPA_SERVICE_PROVIDER_MODE = "MspaServiceProviderMode"; + + public static String GPC_SEGMENT_TYPE = "GpcSegmentType"; + public static String GPC_SEGMENT_INCLUDED = "GpcSegmentIncluded"; + public static String GPC = "Gpc"; + + //@formatter:off + public static List USCO_CORE_SEGMENT_FIELD_NAMES = Arrays.asList(new String[] { + UsCoField.VERSION, + UsCoField.SHARING_NOTICE, + UsCoField.SALE_OPT_OUT_NOTICE, + UsCoField.TARGETED_ADVERTISING_OPT_OUT_NOTICE, + UsCoField.SALE_OPT_OUT, + UsCoField.TARGETED_ADVERTISING_OPT_OUT, + UsCoField.SENSITIVE_DATA_PROCESSING, + UsCoField.KNOWN_CHILD_SENSITIVE_DATA_CONSENTS, + UsCoField.MSPA_COVERED_TRANSACTION, + UsCoField.MSPA_OPT_OUT_OPTION_MODE, + UsCoField.MSPA_SERVICE_PROVIDER_MODE + }); + //@formatter:on + + //@formatter:off + public static List USCO_GPC_SEGMENT_FIELD_NAMES = Arrays.asList(new String[] { + UsCoField.GPC_SEGMENT_TYPE, + UsCoField.GPC + }); + //@formatter:on +} diff --git a/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/field/UsCtField.java b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/field/UsCtField.java new file mode 100644 index 00000000..9662e1e3 --- /dev/null +++ b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/field/UsCtField.java @@ -0,0 +1,46 @@ +package com.iab.gpp.encoder.field; + +import java.util.Arrays; +import java.util.List; + +public class UsCtField { + + public static String VERSION = "Version"; + public static String SHARING_NOTICE = "SharingNotice"; + public static String SALE_OPT_OUT_NOTICE = "SaleOptOutNotice"; + public static String TARGETED_ADVERTISING_OPT_OUT_NOTICE = "TargetedAdvertisingOptOutNotice"; + public static String SALE_OPT_OUT = "SaleOptOut"; + public static String TARGETED_ADVERTISING_OPT_OUT = "TargetedAdvertisingOptOut"; + public static String SENSITIVE_DATA_PROCESSING = "SensitiveDataProcessing"; + public static String KNOWN_CHILD_SENSITIVE_DATA_CONSENTS = "KnownChildSensitiveDataConsents"; + public static String MSPA_COVERED_TRANSACTION = "MspaCoveredTransaction"; + public static String MSPA_OPT_OUT_OPTION_MODE = "MspaOptOutOptionMode"; + public static String MSPA_SERVICE_PROVIDER_MODE = "MspaServiceProviderMode"; + + public static String GPC_SEGMENT_TYPE = "GpcSegmentType"; + public static String GPC_SEGMENT_INCLUDED = "GpcSegmentIncluded"; + public static String GPC = "Gpc"; + + //@formatter:off + public static List USCT_CORE_SEGMENT_FIELD_NAMES = Arrays.asList(new String[] { + UsCtField.VERSION, + UsCtField.SHARING_NOTICE, + UsCtField.SALE_OPT_OUT_NOTICE, + UsCtField.TARGETED_ADVERTISING_OPT_OUT_NOTICE, + UsCtField.SALE_OPT_OUT, + UsCtField.TARGETED_ADVERTISING_OPT_OUT, + UsCtField.SENSITIVE_DATA_PROCESSING, + UsCtField.KNOWN_CHILD_SENSITIVE_DATA_CONSENTS, + UsCtField.MSPA_COVERED_TRANSACTION, + UsCtField.MSPA_OPT_OUT_OPTION_MODE, + UsCtField.MSPA_SERVICE_PROVIDER_MODE + }); + //@formatter:on + + //@formatter:off + public static List USCT_GPC_SEGMENT_FIELD_NAMES = Arrays.asList(new String[] { + UsCtField.GPC_SEGMENT_TYPE, + UsCtField.GPC + }); + //@formatter:on +} diff --git a/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/field/UsDeField.java b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/field/UsDeField.java new file mode 100644 index 00000000..2979f9b6 --- /dev/null +++ b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/field/UsDeField.java @@ -0,0 +1,48 @@ +package com.iab.gpp.encoder.field; + +import java.util.Arrays; +import java.util.List; + +public class UsDeField { + + public static String VERSION = "Version"; + public static String PROCESSING_NOTICE = "ProcessingNotice"; + public static String SALE_OPT_OUT_NOTICE = "SaleOptOutNotice"; + public static String TARGETED_ADVERTISING_OPT_OUT_NOTICE = "TargetedAdvertisingOptOutNotice"; + public static String SALE_OPT_OUT = "SaleOptOut"; + public static String TARGETED_ADVERTISING_OPT_OUT = "TargetedAdvertisingOptOut"; + public static String SENSITIVE_DATA_PROCESSING = "SensitiveDataProcessing"; + public static String KNOWN_CHILD_SENSITIVE_DATA_CONSENTS = "KnownChildSensitiveDataConsents"; + public static String ADDITIONAL_DATA_PROCESSING_CONSENT = "AdditionalDataProcessingConsent"; + public static String MSPA_COVERED_TRANSACTION = "MspaCoveredTransaction"; + public static String MSPA_OPT_OUT_OPTION_MODE = "MspaOptOutOptionMode"; + public static String MSPA_SERVICE_PROVIDER_MODE = "MspaServiceProviderMode"; + + public static String GPC_SEGMENT_TYPE = "GpcSegmentType"; + public static String GPC_SEGMENT_INCLUDED = "GpcSegmentIncluded"; + public static String GPC = "Gpc"; + + //@formatter:off + public static List USDE_CORE_SEGMENT_FIELD_NAMES = Arrays.asList(new String[] { + UsDeField.VERSION, + UsDeField.PROCESSING_NOTICE, + UsDeField.SALE_OPT_OUT_NOTICE, + UsDeField.TARGETED_ADVERTISING_OPT_OUT_NOTICE, + UsDeField.SALE_OPT_OUT, + UsDeField.TARGETED_ADVERTISING_OPT_OUT, + UsDeField.SENSITIVE_DATA_PROCESSING, + UsDeField.KNOWN_CHILD_SENSITIVE_DATA_CONSENTS, + UsDeField.ADDITIONAL_DATA_PROCESSING_CONSENT, + UsDeField.MSPA_COVERED_TRANSACTION, + UsDeField.MSPA_OPT_OUT_OPTION_MODE, + UsDeField.MSPA_SERVICE_PROVIDER_MODE + }); + //@formatter:on + + //@formatter:off + public static List USDE_GPC_SEGMENT_FIELD_NAMES = Arrays.asList(new String[] { + UsDeField.GPC_SEGMENT_TYPE, + UsDeField.GPC + }); + //@formatter:on +} diff --git a/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/field/UsFlField.java b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/field/UsFlField.java new file mode 100644 index 00000000..f3647a79 --- /dev/null +++ b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/field/UsFlField.java @@ -0,0 +1,37 @@ +package com.iab.gpp.encoder.field; + +import java.util.Arrays; +import java.util.List; + +public class UsFlField { + + public static String VERSION = "Version"; + public static String PROCESSING_NOTICE = "ProcessingNotice"; + public static String SALE_OPT_OUT_NOTICE = "SaleOptOutNotice"; + public static String TARGETED_ADVERTISING_OPT_OUT_NOTICE = "TargetedAdvertisingOptOutNotice"; + public static String SALE_OPT_OUT = "SaleOptOut"; + public static String TARGETED_ADVERTISING_OPT_OUT = "TargetedAdvertisingOptOut"; + public static String SENSITIVE_DATA_PROCESSING = "SensitiveDataProcessing"; + public static String KNOWN_CHILD_SENSITIVE_DATA_CONSENTS = "KnownChildSensitiveDataConsents"; + public static String ADDITIONAL_DATA_PROCESSING_CONSENT = "AdditionalDataProcessingConsent"; + public static String MSPA_COVERED_TRANSACTION = "MspaCoveredTransaction"; + public static String MSPA_OPT_OUT_OPTION_MODE = "MspaOptOutOptionMode"; + public static String MSPA_SERVICE_PROVIDER_MODE = "MspaServiceProviderMode"; + + //@formatter:off + public static List USFL_CORE_SEGMENT_FIELD_NAMES = Arrays.asList(new String[] { + UsFlField.VERSION, + UsFlField.PROCESSING_NOTICE, + UsFlField.SALE_OPT_OUT_NOTICE, + UsFlField.TARGETED_ADVERTISING_OPT_OUT_NOTICE, + UsFlField.SALE_OPT_OUT, + UsFlField.TARGETED_ADVERTISING_OPT_OUT, + UsFlField.SENSITIVE_DATA_PROCESSING, + UsFlField.KNOWN_CHILD_SENSITIVE_DATA_CONSENTS, + UsFlField.ADDITIONAL_DATA_PROCESSING_CONSENT, + UsFlField.MSPA_COVERED_TRANSACTION, + UsFlField.MSPA_OPT_OUT_OPTION_MODE, + UsFlField.MSPA_SERVICE_PROVIDER_MODE + }); + //@formatter:on +} diff --git a/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/field/UsIaField.java b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/field/UsIaField.java new file mode 100644 index 00000000..f0c8d523 --- /dev/null +++ b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/field/UsIaField.java @@ -0,0 +1,48 @@ +package com.iab.gpp.encoder.field; + +import java.util.Arrays; +import java.util.List; + +public class UsIaField { + + public static String VERSION = "Version"; + public static String PROCESSING_NOTICE = "ProcessingNotice"; + public static String SALE_OPT_OUT_NOTICE = "SaleOptOutNotice"; + public static String TARGETED_ADVERTISING_OPT_OUT_NOTICE = "TargetedAdvertisingOptOutNotice"; + public static String SENSITIVE_DATA_OPT_OUT_NOTICE = "SensitiveDataOptOutNotice"; + public static String SALE_OPT_OUT = "SaleOptOut"; + public static String TARGETED_ADVERTISING_OPT_OUT = "TargetedAdvertisingOptOut"; + public static String SENSITIVE_DATA_PROCESSING = "SensitiveDataProcessing"; + public static String KNOWN_CHILD_SENSITIVE_DATA_CONSENTS = "KnownChildSensitiveDataConsents"; + public static String MSPA_COVERED_TRANSACTION = "MspaCoveredTransaction"; + public static String MSPA_OPT_OUT_OPTION_MODE = "MspaOptOutOptionMode"; + public static String MSPA_SERVICE_PROVIDER_MODE = "MspaServiceProviderMode"; + + public static String GPC_SEGMENT_TYPE = "GpcSegmentType"; + public static String GPC_SEGMENT_INCLUDED = "GpcSegmentIncluded"; + public static String GPC = "Gpc"; + + //@formatter:off + public static List USIA_CORE_SEGMENT_FIELD_NAMES = Arrays.asList(new String[] { + UsIaField.VERSION, + UsIaField.PROCESSING_NOTICE, + UsIaField.SALE_OPT_OUT_NOTICE, + UsIaField.TARGETED_ADVERTISING_OPT_OUT_NOTICE, + UsIaField.SENSITIVE_DATA_OPT_OUT_NOTICE, + UsIaField.SALE_OPT_OUT, + UsIaField.TARGETED_ADVERTISING_OPT_OUT, + UsIaField.SENSITIVE_DATA_PROCESSING, + UsIaField.KNOWN_CHILD_SENSITIVE_DATA_CONSENTS, + UsIaField.MSPA_COVERED_TRANSACTION, + UsIaField.MSPA_OPT_OUT_OPTION_MODE, + UsIaField.MSPA_SERVICE_PROVIDER_MODE + }); + //@formatter:on + + //@formatter:off + public static List USIA_GPC_SEGMENT_FIELD_NAMES = Arrays.asList(new String[] { + UsIaField.GPC_SEGMENT_TYPE, + UsIaField.GPC + }); + //@formatter:on +} diff --git a/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/field/UsMtField.java b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/field/UsMtField.java new file mode 100644 index 00000000..6b785f73 --- /dev/null +++ b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/field/UsMtField.java @@ -0,0 +1,48 @@ +package com.iab.gpp.encoder.field; + +import java.util.Arrays; +import java.util.List; + +public class UsMtField { + + public static String VERSION = "Version"; + public static String SHARING_NOTICE = "SharingNotice"; + public static String SALE_OPT_OUT_NOTICE = "SaleOptOutNotice"; + public static String TARGETED_ADVERTISING_OPT_OUT_NOTICE = "TargetedAdvertisingOptOutNotice"; + public static String SALE_OPT_OUT = "SaleOptOut"; + public static String TARGETED_ADVERTISING_OPT_OUT = "TargetedAdvertisingOptOut"; + public static String SENSITIVE_DATA_PROCESSING = "SensitiveDataProcessing"; + public static String KNOWN_CHILD_SENSITIVE_DATA_CONSENTS = "KnownChildSensitiveDataConsents"; + public static String ADDITIONAL_DATA_PROCESSING_CONSENT = "AdditionalDataProcessingConsent"; + public static String MSPA_COVERED_TRANSACTION = "MspaCoveredTransaction"; + public static String MSPA_OPT_OUT_OPTION_MODE = "MspaOptOutOptionMode"; + public static String MSPA_SERVICE_PROVIDER_MODE = "MspaServiceProviderMode"; + + public static String GPC_SEGMENT_TYPE = "GpcSegmentType"; + public static String GPC_SEGMENT_INCLUDED = "GpcSegmentIncluded"; + public static String GPC = "Gpc"; + + //@formatter:off + public static List USMT_CORE_SEGMENT_FIELD_NAMES = Arrays.asList(new String[] { + UsMtField.VERSION, + UsMtField.SHARING_NOTICE, + UsMtField.SALE_OPT_OUT_NOTICE, + UsMtField.TARGETED_ADVERTISING_OPT_OUT_NOTICE, + UsMtField.SALE_OPT_OUT, + UsMtField.TARGETED_ADVERTISING_OPT_OUT, + UsMtField.SENSITIVE_DATA_PROCESSING, + UsMtField.KNOWN_CHILD_SENSITIVE_DATA_CONSENTS, + UsMtField.ADDITIONAL_DATA_PROCESSING_CONSENT, + UsMtField.MSPA_COVERED_TRANSACTION, + UsMtField.MSPA_OPT_OUT_OPTION_MODE, + UsMtField.MSPA_SERVICE_PROVIDER_MODE + }); + //@formatter:on + + //@formatter:off + public static List USMT_GPC_SEGMENT_FIELD_NAMES = Arrays.asList(new String[] { + UsMtField.GPC_SEGMENT_TYPE, + UsMtField.GPC + }); + //@formatter:on +} diff --git a/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/field/UsNatField.java b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/field/UsNatField.java new file mode 100644 index 00000000..e18427b1 --- /dev/null +++ b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/field/UsNatField.java @@ -0,0 +1,56 @@ +package com.iab.gpp.encoder.field; + +import java.util.Arrays; +import java.util.List; + +public class UsNatField { + + public static String VERSION = "Version"; + public static String SHARING_NOTICE = "SharingNotice"; + public static String SALE_OPT_OUT_NOTICE = "SaleOptOutNotice"; + public static String SHARING_OPT_OUT_NOTICE = "SharingOptOutNotice"; + public static String TARGETED_ADVERTISING_OPT_OUT_NOTICE = "TargetedAdvertisingOptOutNotice"; + public static String SENSITIVE_DATA_PROCESSING_OPT_OUT_NOTICE = "SensitiveDataProcessingOptOutNotice"; + public static String SENSITIVE_DATA_LIMIT_USE_NOTICE = "SensitiveDataLimitUseNotice"; + public static String SALE_OPT_OUT = "SaleOptOut"; + public static String SHARING_OPT_OUT = "SharingOptOut"; + public static String TARGETED_ADVERTISING_OPT_OUT = "TargetedAdvertisingOptOut"; + public static String SENSITIVE_DATA_PROCESSING = "SensitiveDataProcessing"; + public static String KNOWN_CHILD_SENSITIVE_DATA_CONSENTS = "KnownChildSensitiveDataConsents"; + public static String PERSONAL_DATA_CONSENTS = "PersonalDataConsents"; + public static String MSPA_COVERED_TRANSACTION = "MspaCoveredTransaction"; + public static String MSPA_OPT_OUT_OPTION_MODE = "MspaOptOutOptionMode"; + public static String MSPA_SERVICE_PROVIDER_MODE = "MspaServiceProviderMode"; + + public static String GPC_SEGMENT_TYPE = "GpcSegmentType"; + public static String GPC_SEGMENT_INCLUDED = "GpcSegmentIncluded"; + public static String GPC = "Gpc"; + + //@formatter:off + public static List USNAT_CORE_SEGMENT_FIELD_NAMES = Arrays.asList(new String[] { + UsNatField.VERSION, + UsNatField.SHARING_NOTICE, + UsNatField.SALE_OPT_OUT_NOTICE, + UsNatField.SHARING_OPT_OUT_NOTICE, + UsNatField.TARGETED_ADVERTISING_OPT_OUT_NOTICE, + UsNatField.SENSITIVE_DATA_PROCESSING_OPT_OUT_NOTICE, + UsNatField.SENSITIVE_DATA_LIMIT_USE_NOTICE, + UsNatField.SALE_OPT_OUT, + UsNatField.SHARING_OPT_OUT, + UsNatField.TARGETED_ADVERTISING_OPT_OUT, + UsNatField.SENSITIVE_DATA_PROCESSING, + UsNatField.KNOWN_CHILD_SENSITIVE_DATA_CONSENTS, + UsNatField.PERSONAL_DATA_CONSENTS, + UsNatField.MSPA_COVERED_TRANSACTION, + UsNatField.MSPA_OPT_OUT_OPTION_MODE, + UsNatField.MSPA_SERVICE_PROVIDER_MODE + }); + //@formatter:on + + //@formatter:off + public static List USNAT_GPC_SEGMENT_FIELD_NAMES = Arrays.asList(new String[] { + UsNatField.GPC_SEGMENT_TYPE, + UsNatField.GPC + }); + //@formatter:on +} diff --git a/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/field/UsNeField.java b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/field/UsNeField.java new file mode 100644 index 00000000..a4479a87 --- /dev/null +++ b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/field/UsNeField.java @@ -0,0 +1,48 @@ +package com.iab.gpp.encoder.field; + +import java.util.Arrays; +import java.util.List; + +public class UsNeField { + + public static String VERSION = "Version"; + public static String PROCESSING_NOTICE = "ProcessingNotice"; + public static String SALE_OPT_OUT_NOTICE = "SaleOptOutNotice"; + public static String TARGETED_ADVERTISING_OPT_OUT_NOTICE = "TargetedAdvertisingOptOutNotice"; + public static String SALE_OPT_OUT = "SaleOptOut"; + public static String TARGETED_ADVERTISING_OPT_OUT = "TargetedAdvertisingOptOut"; + public static String SENSITIVE_DATA_PROCESSING = "SensitiveDataProcessing"; + public static String KNOWN_CHILD_SENSITIVE_DATA_CONSENTS = "KnownChildSensitiveDataConsents"; + public static String ADDITIONAL_DATA_PROCESSING_CONSENT = "AdditionalDataProcessingConsent"; + public static String MSPA_COVERED_TRANSACTION = "MspaCoveredTransaction"; + public static String MSPA_OPT_OUT_OPTION_MODE = "MspaOptOutOptionMode"; + public static String MSPA_SERVICE_PROVIDER_MODE = "MspaServiceProviderMode"; + + public static String GPC_SEGMENT_TYPE = "GpcSegmentType"; + public static String GPC_SEGMENT_INCLUDED = "GpcSegmentIncluded"; + public static String GPC = "Gpc"; + + //@formatter:off + public static List USNE_CORE_SEGMENT_FIELD_NAMES = Arrays.asList(new String[] { + UsNeField.VERSION, + UsNeField.PROCESSING_NOTICE, + UsNeField.SALE_OPT_OUT_NOTICE, + UsNeField.TARGETED_ADVERTISING_OPT_OUT_NOTICE, + UsNeField.SALE_OPT_OUT, + UsNeField.TARGETED_ADVERTISING_OPT_OUT, + UsNeField.SENSITIVE_DATA_PROCESSING, + UsNeField.KNOWN_CHILD_SENSITIVE_DATA_CONSENTS, + UsNeField.ADDITIONAL_DATA_PROCESSING_CONSENT, + UsNeField.MSPA_COVERED_TRANSACTION, + UsNeField.MSPA_OPT_OUT_OPTION_MODE, + UsNeField.MSPA_SERVICE_PROVIDER_MODE + }); + //@formatter:on + + //@formatter:off + public static List USNE_GPC_SEGMENT_FIELD_NAMES = Arrays.asList(new String[] { + UsNeField.GPC_SEGMENT_TYPE, + UsNeField.GPC + }); + //@formatter:on +} diff --git a/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/field/UsNhField.java b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/field/UsNhField.java new file mode 100644 index 00000000..8381dc9b --- /dev/null +++ b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/field/UsNhField.java @@ -0,0 +1,48 @@ +package com.iab.gpp.encoder.field; + +import java.util.Arrays; +import java.util.List; + +public class UsNhField { + + public static String VERSION = "Version"; + public static String PROCESSING_NOTICE = "ProcessingNotice"; + public static String SALE_OPT_OUT_NOTICE = "SaleOptOutNotice"; + public static String TARGETED_ADVERTISING_OPT_OUT_NOTICE = "TargetedAdvertisingOptOutNotice"; + public static String SALE_OPT_OUT = "SaleOptOut"; + public static String TARGETED_ADVERTISING_OPT_OUT = "TargetedAdvertisingOptOut"; + public static String SENSITIVE_DATA_PROCESSING = "SensitiveDataProcessing"; + public static String KNOWN_CHILD_SENSITIVE_DATA_CONSENTS = "KnownChildSensitiveDataConsents"; + public static String ADDITIONAL_DATA_PROCESSING_CONSENT = "AdditionalDataProcessingConsent"; + public static String MSPA_COVERED_TRANSACTION = "MspaCoveredTransaction"; + public static String MSPA_OPT_OUT_OPTION_MODE = "MspaOptOutOptionMode"; + public static String MSPA_SERVICE_PROVIDER_MODE = "MspaServiceProviderMode"; + + public static String GPC_SEGMENT_TYPE = "GpcSegmentType"; + public static String GPC_SEGMENT_INCLUDED = "GpcSegmentIncluded"; + public static String GPC = "Gpc"; + + //@formatter:off + public static List USNH_CORE_SEGMENT_FIELD_NAMES = Arrays.asList(new String[] { + UsNhField.VERSION, + UsNhField.PROCESSING_NOTICE, + UsNhField.SALE_OPT_OUT_NOTICE, + UsNhField.TARGETED_ADVERTISING_OPT_OUT_NOTICE, + UsNhField.SALE_OPT_OUT, + UsNhField.TARGETED_ADVERTISING_OPT_OUT, + UsNhField.SENSITIVE_DATA_PROCESSING, + UsNhField.KNOWN_CHILD_SENSITIVE_DATA_CONSENTS, + UsNhField.ADDITIONAL_DATA_PROCESSING_CONSENT, + UsNhField.MSPA_COVERED_TRANSACTION, + UsNhField.MSPA_OPT_OUT_OPTION_MODE, + UsNhField.MSPA_SERVICE_PROVIDER_MODE + }); + //@formatter:on + + //@formatter:off + public static List USNH_GPC_SEGMENT_FIELD_NAMES = Arrays.asList(new String[] { + UsNhField.GPC_SEGMENT_TYPE, + UsNhField.GPC + }); + //@formatter:on +} diff --git a/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/field/UsNjField.java b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/field/UsNjField.java new file mode 100644 index 00000000..2acba850 --- /dev/null +++ b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/field/UsNjField.java @@ -0,0 +1,48 @@ +package com.iab.gpp.encoder.field; + +import java.util.Arrays; +import java.util.List; + +public class UsNjField { + + public static String VERSION = "Version"; + public static String PROCESSING_NOTICE = "ProcessingNotice"; + public static String SALE_OPT_OUT_NOTICE = "SaleOptOutNotice"; + public static String TARGETED_ADVERTISING_OPT_OUT_NOTICE = "TargetedAdvertisingOptOutNotice"; + public static String SALE_OPT_OUT = "SaleOptOut"; + public static String TARGETED_ADVERTISING_OPT_OUT = "TargetedAdvertisingOptOut"; + public static String SENSITIVE_DATA_PROCESSING = "SensitiveDataProcessing"; + public static String KNOWN_CHILD_SENSITIVE_DATA_CONSENTS = "KnownChildSensitiveDataConsents"; + public static String ADDITIONAL_DATA_PROCESSING_CONSENT = "AdditionalDataProcessingConsent"; + public static String MSPA_COVERED_TRANSACTION = "MspaCoveredTransaction"; + public static String MSPA_OPT_OUT_OPTION_MODE = "MspaOptOutOptionMode"; + public static String MSPA_SERVICE_PROVIDER_MODE = "MspaServiceProviderMode"; + + public static String GPC_SEGMENT_TYPE = "GpcSegmentType"; + public static String GPC_SEGMENT_INCLUDED = "GpcSegmentIncluded"; + public static String GPC = "Gpc"; + + //@formatter:off + public static List USNJ_CORE_SEGMENT_FIELD_NAMES = Arrays.asList(new String[] { + UsNjField.VERSION, + UsNjField.PROCESSING_NOTICE, + UsNjField.SALE_OPT_OUT_NOTICE, + UsNjField.TARGETED_ADVERTISING_OPT_OUT_NOTICE, + UsNjField.SALE_OPT_OUT, + UsNjField.TARGETED_ADVERTISING_OPT_OUT, + UsNjField.SENSITIVE_DATA_PROCESSING, + UsNjField.KNOWN_CHILD_SENSITIVE_DATA_CONSENTS, + UsNjField.ADDITIONAL_DATA_PROCESSING_CONSENT, + UsNjField.MSPA_COVERED_TRANSACTION, + UsNjField.MSPA_OPT_OUT_OPTION_MODE, + UsNjField.MSPA_SERVICE_PROVIDER_MODE + }); + //@formatter:on + + //@formatter:off + public static List USNJ_GPC_SEGMENT_FIELD_NAMES = Arrays.asList(new String[] { + UsNjField.GPC_SEGMENT_TYPE, + UsNjField.GPC + }); + //@formatter:on +} diff --git a/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/field/UsOrField.java b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/field/UsOrField.java new file mode 100644 index 00000000..3e9021c2 --- /dev/null +++ b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/field/UsOrField.java @@ -0,0 +1,48 @@ +package com.iab.gpp.encoder.field; + +import java.util.Arrays; +import java.util.List; + +public class UsOrField { + + public static String VERSION = "Version"; + public static String PROCESSING_NOTICE = "ProcessingNotice"; + public static String SALE_OPT_OUT_NOTICE = "SaleOptOutNotice"; + public static String TARGETED_ADVERTISING_OPT_OUT_NOTICE = "TargetedAdvertisingOptOutNotice"; + public static String SALE_OPT_OUT = "SaleOptOut"; + public static String TARGETED_ADVERTISING_OPT_OUT = "TargetedAdvertisingOptOut"; + public static String SENSITIVE_DATA_PROCESSING = "SensitiveDataProcessing"; + public static String KNOWN_CHILD_SENSITIVE_DATA_CONSENTS = "KnownChildSensitiveDataConsents"; + public static String ADDITIONAL_DATA_PROCESSING_CONSENT = "AdditionalDataProcessingConsent"; + public static String MSPA_COVERED_TRANSACTION = "MspaCoveredTransaction"; + public static String MSPA_OPT_OUT_OPTION_MODE = "MspaOptOutOptionMode"; + public static String MSPA_SERVICE_PROVIDER_MODE = "MspaServiceProviderMode"; + + public static String GPC_SEGMENT_TYPE = "GpcSegmentType"; + public static String GPC_SEGMENT_INCLUDED = "GpcSegmentIncluded"; + public static String GPC = "Gpc"; + + //@formatter:off + public static List USOR_CORE_SEGMENT_FIELD_NAMES = Arrays.asList(new String[] { + UsOrField.VERSION, + UsOrField.PROCESSING_NOTICE, + UsOrField.SALE_OPT_OUT_NOTICE, + UsOrField.TARGETED_ADVERTISING_OPT_OUT_NOTICE, + UsOrField.SALE_OPT_OUT, + UsOrField.TARGETED_ADVERTISING_OPT_OUT, + UsOrField.SENSITIVE_DATA_PROCESSING, + UsOrField.KNOWN_CHILD_SENSITIVE_DATA_CONSENTS, + UsOrField.ADDITIONAL_DATA_PROCESSING_CONSENT, + UsOrField.MSPA_COVERED_TRANSACTION, + UsOrField.MSPA_OPT_OUT_OPTION_MODE, + UsOrField.MSPA_SERVICE_PROVIDER_MODE + }); + //@formatter:on + + //@formatter:off + public static List USOR_GPC_SEGMENT_FIELD_NAMES = Arrays.asList(new String[] { + UsOrField.GPC_SEGMENT_TYPE, + UsOrField.GPC + }); + //@formatter:on +} diff --git a/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/field/UsTnField.java b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/field/UsTnField.java new file mode 100644 index 00000000..7ef8c75d --- /dev/null +++ b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/field/UsTnField.java @@ -0,0 +1,48 @@ +package com.iab.gpp.encoder.field; + +import java.util.Arrays; +import java.util.List; + +public class UsTnField { + + public static String VERSION = "Version"; + public static String PROCESSING_NOTICE = "ProcessingNotice"; + public static String SALE_OPT_OUT_NOTICE = "SaleOptOutNotice"; + public static String TARGETED_ADVERTISING_OPT_OUT_NOTICE = "TargetedAdvertisingOptOutNotice"; + public static String SALE_OPT_OUT = "SaleOptOut"; + public static String TARGETED_ADVERTISING_OPT_OUT = "TargetedAdvertisingOptOut"; + public static String SENSITIVE_DATA_PROCESSING = "SensitiveDataProcessing"; + public static String KNOWN_CHILD_SENSITIVE_DATA_CONSENTS = "KnownChildSensitiveDataConsents"; + public static String ADDITIONAL_DATA_PROCESSING_CONSENT = "AdditionalDataProcessingConsent"; + public static String MSPA_COVERED_TRANSACTION = "MspaCoveredTransaction"; + public static String MSPA_OPT_OUT_OPTION_MODE = "MspaOptOutOptionMode"; + public static String MSPA_SERVICE_PROVIDER_MODE = "MspaServiceProviderMode"; + + public static String GPC_SEGMENT_TYPE = "GpcSegmentType"; + public static String GPC_SEGMENT_INCLUDED = "GpcSegmentIncluded"; + public static String GPC = "Gpc"; + + //@formatter:off + public static List USTN_CORE_SEGMENT_FIELD_NAMES = Arrays.asList(new String[] { + UsTnField.VERSION, + UsTnField.PROCESSING_NOTICE, + UsTnField.SALE_OPT_OUT_NOTICE, + UsTnField.TARGETED_ADVERTISING_OPT_OUT_NOTICE, + UsTnField.SALE_OPT_OUT, + UsTnField.TARGETED_ADVERTISING_OPT_OUT, + UsTnField.SENSITIVE_DATA_PROCESSING, + UsTnField.KNOWN_CHILD_SENSITIVE_DATA_CONSENTS, + UsTnField.ADDITIONAL_DATA_PROCESSING_CONSENT, + UsTnField.MSPA_COVERED_TRANSACTION, + UsTnField.MSPA_OPT_OUT_OPTION_MODE, + UsTnField.MSPA_SERVICE_PROVIDER_MODE + }); + //@formatter:on + + //@formatter:off + public static List USTN_GPC_SEGMENT_FIELD_NAMES = Arrays.asList(new String[] { + UsTnField.GPC_SEGMENT_TYPE, + UsTnField.GPC + }); + //@formatter:on +} diff --git a/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/field/UsTxField.java b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/field/UsTxField.java new file mode 100644 index 00000000..44ec7d69 --- /dev/null +++ b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/field/UsTxField.java @@ -0,0 +1,48 @@ +package com.iab.gpp.encoder.field; + +import java.util.Arrays; +import java.util.List; + +public class UsTxField { + + public static String VERSION = "Version"; + public static String PROCESSING_NOTICE = "ProcessingNotice"; + public static String SALE_OPT_OUT_NOTICE = "SaleOptOutNotice"; + public static String TARGETED_ADVERTISING_OPT_OUT_NOTICE = "TargetedAdvertisingOptOutNotice"; + public static String SALE_OPT_OUT = "SaleOptOut"; + public static String TARGETED_ADVERTISING_OPT_OUT = "TargetedAdvertisingOptOut"; + public static String SENSITIVE_DATA_PROCESSING = "SensitiveDataProcessing"; + public static String KNOWN_CHILD_SENSITIVE_DATA_CONSENTS = "KnownChildSensitiveDataConsents"; + public static String ADDITIONAL_DATA_PROCESSING_CONSENT = "AdditionalDataProcessingConsent"; + public static String MSPA_COVERED_TRANSACTION = "MspaCoveredTransaction"; + public static String MSPA_OPT_OUT_OPTION_MODE = "MspaOptOutOptionMode"; + public static String MSPA_SERVICE_PROVIDER_MODE = "MspaServiceProviderMode"; + + public static String GPC_SEGMENT_TYPE = "GpcSegmentType"; + public static String GPC_SEGMENT_INCLUDED = "GpcSegmentIncluded"; + public static String GPC = "Gpc"; + + //@formatter:off + public static List USTX_CORE_SEGMENT_FIELD_NAMES = Arrays.asList(new String[] { + UsTxField.VERSION, + UsTxField.PROCESSING_NOTICE, + UsTxField.SALE_OPT_OUT_NOTICE, + UsTxField.TARGETED_ADVERTISING_OPT_OUT_NOTICE, + UsTxField.SALE_OPT_OUT, + UsTxField.TARGETED_ADVERTISING_OPT_OUT, + UsTxField.SENSITIVE_DATA_PROCESSING, + UsTxField.KNOWN_CHILD_SENSITIVE_DATA_CONSENTS, + UsTxField.ADDITIONAL_DATA_PROCESSING_CONSENT, + UsTxField.MSPA_COVERED_TRANSACTION, + UsTxField.MSPA_OPT_OUT_OPTION_MODE, + UsTxField.MSPA_SERVICE_PROVIDER_MODE + }); + //@formatter:on + + //@formatter:off + public static List USTX_GPC_SEGMENT_FIELD_NAMES = Arrays.asList(new String[] { + UsTxField.GPC_SEGMENT_TYPE, + UsTxField.GPC + }); + //@formatter:on +} diff --git a/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/field/UsUtField.java b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/field/UsUtField.java new file mode 100644 index 00000000..01cedc67 --- /dev/null +++ b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/field/UsUtField.java @@ -0,0 +1,37 @@ +package com.iab.gpp.encoder.field; + +import java.util.Arrays; +import java.util.List; + +public class UsUtField { + + public static String VERSION = "Version"; + public static String SHARING_NOTICE = "SharingNotice"; + public static String SALE_OPT_OUT_NOTICE = "SaleOptOutNotice"; + public static String TARGETED_ADVERTISING_OPT_OUT_NOTICE = "TargetedAdvertisingOptOutNotice"; + public static String SENSITIVE_DATA_PROCESSING_OPT_OUT_NOTICE = "SensitiveDataProcessingOptOutNotice"; + public static String SALE_OPT_OUT = "SaleOptOut"; + public static String TARGETED_ADVERTISING_OPT_OUT = "TargetedAdvertisingOptOut"; + public static String SENSITIVE_DATA_PROCESSING = "SensitiveDataProcessing"; + public static String KNOWN_CHILD_SENSITIVE_DATA_CONSENTS = "KnownChildSensitiveDataConsents"; + public static String MSPA_COVERED_TRANSACTION = "MspaCoveredTransaction"; + public static String MSPA_OPT_OUT_OPTION_MODE = "MspaOptOutOptionMode"; + public static String MSPA_SERVICE_PROVIDER_MODE = "MspaServiceProviderMode"; + + //@formatter:off + public static List USUT_CORE_SEGMENT_FIELD_NAMES = Arrays.asList(new String[] { + UsUtField.VERSION, + UsUtField.SHARING_NOTICE, + UsUtField.SALE_OPT_OUT_NOTICE, + UsUtField.TARGETED_ADVERTISING_OPT_OUT_NOTICE, + UsUtField.SENSITIVE_DATA_PROCESSING_OPT_OUT_NOTICE, + UsUtField.SALE_OPT_OUT, + UsUtField.TARGETED_ADVERTISING_OPT_OUT, + UsUtField.SENSITIVE_DATA_PROCESSING, + UsUtField.KNOWN_CHILD_SENSITIVE_DATA_CONSENTS, + UsUtField.MSPA_COVERED_TRANSACTION, + UsUtField.MSPA_OPT_OUT_OPTION_MODE, + UsUtField.MSPA_SERVICE_PROVIDER_MODE + }); + //@formatter:on +} diff --git a/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/field/UsVaField.java b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/field/UsVaField.java new file mode 100644 index 00000000..46cb4dbb --- /dev/null +++ b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/field/UsVaField.java @@ -0,0 +1,35 @@ +package com.iab.gpp.encoder.field; + +import java.util.Arrays; +import java.util.List; + +public class UsVaField { + + public static String VERSION = "Version"; + public static String SHARING_NOTICE = "SharingNotice"; + public static String SALE_OPT_OUT_NOTICE = "SaleOptOutNotice"; + public static String TARGETED_ADVERTISING_OPT_OUT_NOTICE = "TargetedAdvertisingOptOutNotice"; + public static String SALE_OPT_OUT = "SaleOptOut"; + public static String TARGETED_ADVERTISING_OPT_OUT = "TargetedAdvertisingOptOut"; + public static String SENSITIVE_DATA_PROCESSING = "SensitiveDataProcessing"; + public static String KNOWN_CHILD_SENSITIVE_DATA_CONSENTS = "KnownChildSensitiveDataConsents"; + public static String MSPA_COVERED_TRANSACTION = "MspaCoveredTransaction"; + public static String MSPA_OPT_OUT_OPTION_MODE = "MspaOptOutOptionMode"; + public static String MSPA_SERVICE_PROVIDER_MODE = "MspaServiceProviderMode"; + + //@formatter:off + public static List USVA_CORE_SEGMENT_FIELD_NAMES = Arrays.asList(new String[] { + UsVaField.VERSION, + UsVaField.SHARING_NOTICE, + UsVaField.SALE_OPT_OUT_NOTICE, + UsVaField.TARGETED_ADVERTISING_OPT_OUT_NOTICE, + UsVaField.SALE_OPT_OUT, + UsVaField.TARGETED_ADVERTISING_OPT_OUT, + UsVaField.SENSITIVE_DATA_PROCESSING, + UsVaField.KNOWN_CHILD_SENSITIVE_DATA_CONSENTS, + UsVaField.MSPA_COVERED_TRANSACTION, + UsVaField.MSPA_OPT_OUT_OPTION_MODE, + UsVaField.MSPA_SERVICE_PROVIDER_MODE + }); + //@formatter:on +} diff --git a/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/field/UspV1Field.java b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/field/UspV1Field.java index c5346823..2551632c 100644 --- a/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/field/UspV1Field.java +++ b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/field/UspV1Field.java @@ -1,5 +1,8 @@ package com.iab.gpp.encoder.field; +import java.util.Arrays; +import java.util.List; + public class UspV1Field { public static String VERSION = "Version"; @@ -7,4 +10,12 @@ public class UspV1Field { public static String OPT_OUT_SALE = "OptOutSale"; public static String LSPA_COVERED = "LspaCovered"; + //@formatter:off + public static List USPV1_CORE_SEGMENT_FIELD_NAMES = Arrays.asList(new String[] { + UspV1Field.VERSION, + UspV1Field.NOTICE, + UspV1Field.OPT_OUT_SALE, + UspV1Field.LSPA_COVERED + }); + //@formatter:on } diff --git a/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/field/UspV1LegacyField.java b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/field/UspV1LegacyField.java deleted file mode 100644 index 3b1642c1..00000000 --- a/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/field/UspV1LegacyField.java +++ /dev/null @@ -1,10 +0,0 @@ -package com.iab.gpp.encoder.field; - -public class UspV1LegacyField { - - public static String VERSION = "Version"; - public static String NOTICE = "Notice"; - public static String OPT_OUT_SALE = "OptOutSale"; - public static String LSPA_COVERED = "LspaCovered"; - -} diff --git a/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/section/AbstractEncodableBitStringSection.java b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/section/AbstractEncodableBitStringSection.java deleted file mode 100644 index e5648f6c..00000000 --- a/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/section/AbstractEncodableBitStringSection.java +++ /dev/null @@ -1,80 +0,0 @@ -package com.iab.gpp.encoder.section; - -import java.util.Map; -import com.iab.gpp.encoder.error.DecodingException; -import com.iab.gpp.encoder.error.EncodingException; -import com.iab.gpp.encoder.datatype.AbstractEncodableBitStringDataType; - -public abstract class AbstractEncodableBitStringSection implements EncodableSection { - protected Map> fields; - protected String[] fieldOrder; - - @Override - public boolean hasField(String fieldName) { - return this.fields.containsKey(fieldName); - } - - @Override - public Object getFieldValue(String fieldName) { - if (this.fields.containsKey(fieldName)) { - return this.fields.get(fieldName).getValue(); - } else { - return null; - } - } - - @Override - public void setFieldValue(String fieldName, Object value) { - if (this.fields.containsKey(fieldName)) { - this.fields.get(fieldName).setValue(value); - } else { - throw new Error(fieldName + " not found"); - } - } - - public String[] getFieldOrder() { - return this.fieldOrder; - } - - public String encodeToBitString() throws EncodingException { - String bitString = ""; - for (int i = 0; i < this.fieldOrder.length; i++) { - String fieldName = this.fieldOrder[i]; - if (this.fields.containsKey(fieldName)) { - AbstractEncodableBitStringDataType field = this.fields.get(fieldName); - bitString += field.encode(); - } else { - throw new Error("Field not found: '" + fieldName + "'"); - } - } - - return bitString; - } - - public void decodeFromBitString(String bitString) throws DecodingException { - int index = 0; - for (int i = 0; i < this.fieldOrder.length; i++) { - String fieldName = this.fieldOrder[i]; - if (this.fields.containsKey(fieldName)) { - AbstractEncodableBitStringDataType field = this.fields.get(fieldName); - String substring = field.substring(bitString, index); - field.decode(substring); - index += substring.length(); - } else { - throw new Error("Field not found: '" + fieldName + "'"); - } - } - } - - @Override - public abstract String encode() throws EncodingException; - - @Override - public abstract void decode(String encodedString) throws DecodingException; - - @Override - public abstract int getId(); - - @Override - public abstract String getName(); -} diff --git a/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/section/AbstractEncodableSegmentedBitStringSection.java b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/section/AbstractEncodableSegmentedBitStringSection.java index 2b796fbf..eb5d5459 100644 --- a/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/section/AbstractEncodableSegmentedBitStringSection.java +++ b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/section/AbstractEncodableSegmentedBitStringSection.java @@ -3,9 +3,11 @@ import java.util.ArrayList; import java.util.List; import java.util.Map; +import com.iab.gpp.encoder.datatype.AbstractEncodableBitStringDataType; +import com.iab.gpp.encoder.datatype.SubstringException; import com.iab.gpp.encoder.error.DecodingException; import com.iab.gpp.encoder.error.EncodingException; -import com.iab.gpp.encoder.datatype.AbstractEncodableBitStringDataType; +import com.iab.gpp.encoder.error.InvalidFieldException; public abstract class AbstractEncodableSegmentedBitStringSection implements EncodableSection { protected Map> fields; @@ -26,11 +28,11 @@ public Object getFieldValue(String fieldName) { } @Override - public void setFieldValue(String fieldName, Object value) { + public void setFieldValue(String fieldName, Object value) throws InvalidFieldException { if (this.fields.containsKey(fieldName)) { this.fields.get(fieldName).setValue(value); } else { - throw new Error(fieldName + " not found"); + throw new InvalidFieldException(fieldName + " not found"); } } @@ -45,10 +47,14 @@ public List encodeSegmentsToBitStrings() throws EncodingException { for (int j = 0; j < this.segments[i].length; j++) { String fieldName = this.segments[i][j]; if (this.fields.containsKey(fieldName)) { - AbstractEncodableBitStringDataType field = this.fields.get(fieldName); - segmentBitString += field.encode(); + try { + AbstractEncodableBitStringDataType field = this.fields.get(fieldName); + segmentBitString += field.encode(); + } catch (Exception e) { + throw new EncodingException("Unable to encode " + fieldName, e); + } } else { - throw new Error("Field not found: '" + fieldName + "'"); + throw new EncodingException("Field not found: '" + fieldName + "'"); } } segmentBitStrings.add(segmentBitString); @@ -59,24 +65,37 @@ public List encodeSegmentsToBitStrings() throws EncodingException { public void decodeSegmentsFromBitStrings(List segmentBitStrings) throws DecodingException { for (int i = 0; i < this.segments.length && i < segmentBitStrings.size(); i++) { - String segmentBitString = segmentBitStrings.get(i); - if (segmentBitString != null && segmentBitString.length() > 0) { - int index = 0; - for (int j = 0; j < this.segments[i].length; j++) { - String fieldName = this.segments[i][j]; - if (this.fields.containsKey(fieldName)) { - AbstractEncodableBitStringDataType field = this.fields.get(fieldName); + decodeSegmentFromBitString(segments[i], segmentBitStrings.get(i)); + } + } + + private void decodeSegmentFromBitString(String[] segment, String segmentBitString) throws DecodingException { + if (segmentBitString != null && segmentBitString.length() > 0) { + int index = 0; + for (int j = 0; j < segment.length; j++) { + String fieldName = segment[j]; + AbstractEncodableBitStringDataType field = this.fields.get(fieldName); + if (this.fields.containsKey(fieldName)) { + try { String substring = field.substring(segmentBitString, index); field.decode(substring); index += substring.length(); - } else { - throw new Error("Field not found: '" + fieldName + "'"); + } catch (SubstringException e) { + if(field.getHardFailIfMissing()) { + throw new DecodingException("Unable to decode " + fieldName, e); + } else { + return; + } + } catch (Exception e) { + throw new DecodingException("Unable to decode " + fieldName, e); } + } else { + throw new DecodingException("Field not found: '" + fieldName + "'"); } } } } - + @Override public abstract String encode() throws EncodingException; diff --git a/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/section/AbstractLazilyEncodableSection.java b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/section/AbstractLazilyEncodableSection.java new file mode 100644 index 00000000..1f31a592 --- /dev/null +++ b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/section/AbstractLazilyEncodableSection.java @@ -0,0 +1,92 @@ +package com.iab.gpp.encoder.section; + +import java.util.List; +import com.iab.gpp.encoder.error.InvalidFieldException; +import com.iab.gpp.encoder.segment.EncodableSegment; + +public abstract class AbstractLazilyEncodableSection implements EncodableSection { + + private List segments; + + private String encodedString = null; + + private boolean dirty = false; + private boolean decoded = true; + + public AbstractLazilyEncodableSection() { + this.segments = initializeSegments(); + } + + protected abstract List initializeSegments(); + + protected abstract String encodeSection(List segments); + + protected abstract List decodeSection(String encodedString); + + public boolean hasField(String fieldName) { + if (!this.decoded) { + this.segments = this.decodeSection(this.encodedString); + this.dirty = false; + this.decoded = true; + } + + for(EncodableSegment segment : segments) { + if(segment.getFieldNames().contains(fieldName)) { + return segment.hasField(fieldName); + } + } + + return false; + } + + public Object getFieldValue(String fieldName) { + if (!this.decoded) { + this.segments = this.decodeSection(this.encodedString); + this.dirty = false; + this.decoded = true; + } + + for(EncodableSegment segment : segments) { + if(segment.hasField(fieldName)) { + return segment.getFieldValue(fieldName); + } + } + + throw new InvalidFieldException("Invalid field: '" + fieldName + "'"); + } + + public void setFieldValue(String fieldName, Object value) { + if (!this.decoded) { + this.segments = this.decodeSection(this.encodedString); + this.dirty = false; + this.decoded = true; + } + + for(EncodableSegment segment : segments) { + if(segment.hasField(fieldName)) { + segment.setFieldValue(fieldName, value); + this.dirty = true; + return; + } + } + + throw new InvalidFieldException("Invalid field: '" + fieldName + "'"); + } + + public String encode() { + if (this.encodedString == null || this.encodedString.isEmpty() || this.dirty) { + this.encodedString = this.encodeSection(this.segments); + this.dirty = false; + this.decoded = true; + } + + return this.encodedString; + } + + public void decode(String encodedString) { + this.encodedString = encodedString; + this.dirty = false; + this.decoded = false; + } + +} diff --git a/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/section/EncodableSection.java b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/section/EncodableSection.java index 9891c5a6..e1f0a854 100644 --- a/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/section/EncodableSection.java +++ b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/section/EncodableSection.java @@ -1,21 +1,20 @@ package com.iab.gpp.encoder.section; -import com.iab.gpp.encoder.error.DecodingException; -import com.iab.gpp.encoder.error.EncodingException; - public interface EncodableSection { int getId(); String getName(); + int getVersion(); + boolean hasField(String fieldName); Object getFieldValue(String fieldName); void setFieldValue(String fieldName, Object value); - String encode() throws EncodingException; + String encode(); - void decode(String encodedString) throws DecodingException; + void decode(String encodedString); } diff --git a/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/section/HeaderV1.java b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/section/HeaderV1.java index cd2d9bf8..fd5d991c 100644 --- a/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/section/HeaderV1.java +++ b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/section/HeaderV1.java @@ -1,76 +1,79 @@ package com.iab.gpp.encoder.section; import java.util.ArrayList; -import java.util.HashMap; import java.util.List; -import com.iab.gpp.encoder.datatype.encoder.Base64UrlEncoder; -import com.iab.gpp.encoder.error.DecodingException; -import com.iab.gpp.encoder.error.EncodingException; -import com.iab.gpp.encoder.datatype.EncodableFibonacciIntegerRange; -import com.iab.gpp.encoder.datatype.EncodableFixedInteger; import com.iab.gpp.encoder.field.HeaderV1Field; +import com.iab.gpp.encoder.segment.EncodableSegment; +import com.iab.gpp.encoder.segment.HeaderV1CoreSegment; -public class HeaderV1 extends AbstractEncodableBitStringSection { +public class HeaderV1 extends AbstractLazilyEncodableSection { + public static int ID = 3; public static int VERSION = 1; public static String NAME = "header"; public HeaderV1() { - initFields(); + super(); } - public HeaderV1(String encodedString) throws DecodingException { - initFields(); - - if (encodedString != null && encodedString.length() > 0) { - this.decode(encodedString); - } + public HeaderV1(String encodedString) { + super(); + decode(encodedString); } - private void initFields() { - fields = new HashMap<>(); - fields.put(HeaderV1Field.ID, new EncodableFixedInteger(6, HeaderV1.ID)); - fields.put(HeaderV1Field.VERSION, new EncodableFixedInteger(6, HeaderV1.VERSION)); - fields.put(HeaderV1Field.SECTION_IDS, new EncodableFibonacciIntegerRange(new ArrayList<>())); - - //@formatter:off - fieldOrder = new String[] { - HeaderV1Field.ID, - HeaderV1Field.VERSION, - HeaderV1Field.SECTION_IDS - }; - //@formatter:on + @Override + public int getId() { + return HeaderV1.ID; } @Override - public String encode() throws EncodingException { - String bitString = this.encodeToBitString(); - String encodedString = Base64UrlEncoder.encode(bitString); - return encodedString; + public String getName() { + return HeaderV1.NAME; } @Override - public void decode(String encodedString) throws DecodingException { - String bitString = Base64UrlEncoder.decode(encodedString); - this.decodeFromBitString(bitString); + public int getVersion() { + return HeaderV1.VERSION; } @Override - public int getId() { - return HeaderV1.ID; + protected List initializeSegments() { + List segments = new ArrayList<>(); + segments.add(new HeaderV1CoreSegment()); + return segments; } - + @Override - public String getName() { - return HeaderV1.NAME; + protected List decodeSection(String encodedString) { + List segments = initializeSegments(); + + if(encodedString != null && !encodedString.isEmpty()) { + String[] encodedSegments = encodedString.split("\\."); + + for(int i=0; i i) { + segments.get(i).decode(encodedSegments[i]); + } + } + } + + return segments; } - public Integer getVersion() { - return (Integer) this.fields.get(HeaderV1Field.VERSION).getValue(); + @Override + protected String encodeSection(List segments) { + List encodedSegments = new ArrayList<>(); + for(EncodableSegment segment : segments) { + encodedSegments.add(segment.encode()); + } + return String.join(".", encodedSegments); } + @SuppressWarnings("unchecked") public List getSectionsIds() { - return (List) this.fields.get(HeaderV1Field.SECTION_IDS).getValue(); + return (List) this.getFieldValue(HeaderV1Field.SECTION_IDS); } + + } diff --git a/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/section/Sections.java b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/section/Sections.java new file mode 100644 index 00000000..976805d3 --- /dev/null +++ b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/section/Sections.java @@ -0,0 +1,41 @@ +package com.iab.gpp.encoder.section; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; + +public class Sections { + + public static List SECTION_ORDER; + + public static Map SECTION_ID_NAME_MAP; + + static { + SECTION_ID_NAME_MAP = new HashMap<>(); + + SECTION_ID_NAME_MAP.put(TcfEuV2.ID, TcfEuV2.NAME); + SECTION_ID_NAME_MAP.put(TcfCaV1.ID, TcfCaV1.NAME); + SECTION_ID_NAME_MAP.put(UspV1.ID, UspV1.NAME); + SECTION_ID_NAME_MAP.put(UsNat.ID, UsNat.NAME); + SECTION_ID_NAME_MAP.put(UsCa.ID, UsCa.NAME); + SECTION_ID_NAME_MAP.put(UsVa.ID, UsVa.NAME); + SECTION_ID_NAME_MAP.put(UsCo.ID, UsCo.NAME); + SECTION_ID_NAME_MAP.put(UsUt.ID, UsUt.NAME); + SECTION_ID_NAME_MAP.put(UsCt.ID, UsCt.NAME); + SECTION_ID_NAME_MAP.put(UsFl.ID, UsFl.NAME); + SECTION_ID_NAME_MAP.put(UsMt.ID, UsMt.NAME); + SECTION_ID_NAME_MAP.put(UsOr.ID, UsOr.NAME); + SECTION_ID_NAME_MAP.put(UsTx.ID, UsTx.NAME); + SECTION_ID_NAME_MAP.put(UsDe.ID, UsDe.NAME); + SECTION_ID_NAME_MAP.put(UsIa.ID, UsIa.NAME); + SECTION_ID_NAME_MAP.put(UsNe.ID, UsNe.NAME); + SECTION_ID_NAME_MAP.put(UsNh.ID, UsNh.NAME); + SECTION_ID_NAME_MAP.put(UsNj.ID, UsNj.NAME); + SECTION_ID_NAME_MAP.put(UsTn.ID, UsTn.NAME); + + SECTION_ORDER = new ArrayList(SECTION_ID_NAME_MAP.keySet()).stream().sorted() + .map(id -> SECTION_ID_NAME_MAP.get(id)).collect(Collectors.toList()); + } +} diff --git a/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/section/TcfCaV1.java b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/section/TcfCaV1.java new file mode 100644 index 00000000..194a82dc --- /dev/null +++ b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/section/TcfCaV1.java @@ -0,0 +1,223 @@ +package com.iab.gpp.encoder.section; + +import java.time.ZoneId; +import java.time.ZonedDateTime; +import java.util.ArrayList; +import java.util.List; +import com.iab.gpp.encoder.datatype.RangeEntry; +import com.iab.gpp.encoder.error.DecodingException; +import com.iab.gpp.encoder.error.InvalidFieldException; +import com.iab.gpp.encoder.field.TcfCaV1Field; +import com.iab.gpp.encoder.segment.EncodableSegment; +import com.iab.gpp.encoder.segment.TcfCaV1CoreSegment; +import com.iab.gpp.encoder.segment.TcfCaV1DisclosedVendorsSegment; +import com.iab.gpp.encoder.segment.TcfCaV1PublisherPurposesSegment; + +public class TcfCaV1 extends AbstractLazilyEncodableSection { + + public static int ID = 5; + public static int VERSION = 1; + public static String NAME = "tcfcav1"; + + public TcfCaV1() { + super(); + } + + public TcfCaV1(String encodedString) { + super(); + decode(encodedString); + } + + @Override + public int getId() { + return TcfCaV1.ID; + } + + @Override + public String getName() { + return TcfCaV1.NAME; + } + + @Override + public int getVersion() { + return TcfCaV1.VERSION; + } + + @Override + protected List initializeSegments() { + List segments = new ArrayList<>(); + segments.add(new TcfCaV1CoreSegment()); + segments.add(new TcfCaV1PublisherPurposesSegment()); + segments.add(new TcfCaV1DisclosedVendorsSegment()); + return segments; + } + + @Override + public List decodeSection(String encodedString) { + List segments = initializeSegments(); + + if(encodedString != null && !encodedString.isEmpty()) { + String[] encodedSegments = encodedString.split("\\."); + for (int i = 0; i < encodedSegments.length; i++) { + + /** + * The first 3 bits contain the segment id. Rather than decode the entire string, just check the first character. + * + * A-H = '000' = 0 + * I-P = '001' = 1 + * Y-Z,a-f = '011' = 3 + * + * Note that there is no segment id field for the core segment. Instead the first 6 bits are reserved + * for the encoding version which only coincidentally works here because the version value is less than 8. + */ + + String encodedSegment = encodedSegments[i]; + if(!encodedSegment.isEmpty()) { + char firstChar = encodedSegment.charAt(0); + + if(firstChar >= 'A' && firstChar <= 'H') { + segments.get(0).decode(encodedSegments[i]); + } else if(firstChar >= 'I' && firstChar <= 'P') { + segments.get(2).decode(encodedSegments[i]); + } else if((firstChar >= 'Y' && firstChar <= 'Z') || (firstChar >= 'a' && firstChar <= 'f')) { + segments.get(1).decode(encodedSegments[i]); + } else { + throw new DecodingException("Invalid segment '" + encodedSegment + "'"); + } + } + } + } + + return segments; + } + + @Override + public String encodeSection(List segments) { + List encodedSegments = new ArrayList<>(); + + encodedSegments.add(segments.get(0).encode()); + encodedSegments.add(segments.get(1).encode()); + if(!this.getDisclosedVendors().isEmpty()) { + encodedSegments.add(segments.get(2).encode()); + } + + return String.join(".", encodedSegments); + } + + @Override + public void setFieldValue(String fieldName, Object value) throws InvalidFieldException { + super.setFieldValue(fieldName, value); + + if (!fieldName.equals(TcfCaV1Field.CREATED) && !fieldName.equals(TcfCaV1Field.LAST_UPDATED)) { + ZonedDateTime utcDateTime = ZonedDateTime.now(ZoneId.of("UTC")); + + super.setFieldValue(TcfCaV1Field.CREATED, utcDateTime); + super.setFieldValue(TcfCaV1Field.LAST_UPDATED, utcDateTime); + } + } + + + public ZonedDateTime getCreated() { + return (ZonedDateTime) this.getFieldValue(TcfCaV1Field.CREATED); + } + + public ZonedDateTime getLastUpdated() { + return (ZonedDateTime) this.getFieldValue(TcfCaV1Field.LAST_UPDATED); + } + + public Integer getCmpId() { + return (Integer) this.getFieldValue(TcfCaV1Field.CMP_ID); + } + + public Integer getCmpVersion() { + return (Integer) this.getFieldValue(TcfCaV1Field.CMP_VERSION); + } + + public Integer getConsentScreen() { + return (Integer) this.getFieldValue(TcfCaV1Field.CONSENT_SCREEN); + } + + public String getConsentLanguage() { + return (String) this.getFieldValue(TcfCaV1Field.CONSENT_LANGUAGE); + } + + public Integer getVendorListVersion() { + return (Integer) this.getFieldValue(TcfCaV1Field.VENDOR_LIST_VERSION); + } + + public Integer getPolicyVersion() { + return (Integer) this.getFieldValue(TcfCaV1Field.TCF_POLICY_VERSION); + } + + public Boolean getUseNonStandardStacks() { + return (Boolean) this.getFieldValue(TcfCaV1Field.USE_NON_STANDARD_STACKS); + } + + @SuppressWarnings("unchecked") + public List getSpecialFeatureExpressConsent() { + return (List) this.getFieldValue(TcfCaV1Field.SPECIAL_FEATURE_EXPRESS_CONSENT); + } + + @SuppressWarnings("unchecked") + public List getPurposesExpressConsent() { + return (List) this.getFieldValue(TcfCaV1Field.PURPOSES_EXPRESS_CONSENT); + } + + @SuppressWarnings("unchecked") + public List getPurposesImpliedConsent() { + return (List) this.getFieldValue(TcfCaV1Field.PURPOSES_IMPLIED_CONSENT); + } + + @SuppressWarnings("unchecked") + public List getVendorExpressConsent() { + return (List) this.getFieldValue(TcfCaV1Field.VENDOR_EXPRESS_CONSENT); + } + + @SuppressWarnings("unchecked") + public List getVendorImpliedConsent() { + return (List) this.getFieldValue(TcfCaV1Field.VENDOR_IMPLIED_CONSENT); + } + + @SuppressWarnings("unchecked") + public List getPubRestrictions() { + return (List) this.getFieldValue(TcfCaV1Field.PUB_RESTRICTIONS); + } + + public Integer getPubPurposesSegmentType() { + return (Integer) this.getFieldValue(TcfCaV1Field.PUB_PURPOSES_SEGMENT_TYPE); + } + + @SuppressWarnings("unchecked") + public List getPubPurposesExpressConsent() { + return (List) this.getFieldValue(TcfCaV1Field.PUB_PURPOSES_EXPRESS_CONSENT); + } + + @SuppressWarnings("unchecked") + public List getPubPurposesImpliedConsent() { + return (List) this.getFieldValue(TcfCaV1Field.PUB_PURPOSES_IMPLIED_CONSENT); + } + + public Integer getNumCustomPurposes() { + return (Integer) this.getFieldValue(TcfCaV1Field.NUM_CUSTOM_PURPOSES); + } + + @SuppressWarnings("unchecked") + public List getCustomPurposesExpressConsent() { + return (List) this.getFieldValue(TcfCaV1Field.CUSTOM_PURPOSES_EXPRESS_CONSENT); + } + + @SuppressWarnings("unchecked") + public List getCustomPurposesImpliedConsent() { + return (List) this.getFieldValue(TcfCaV1Field.CUSTOM_PURPOSES_IMPLIED_CONSENT); + } + + public Integer getDisclosedVendorsSegmentType() { + return (Integer) this.getFieldValue(TcfCaV1Field.DISCLOSED_VENDORS_SEGMENT_TYPE); + } + + @SuppressWarnings("unchecked") + public List getDisclosedVendors() { + return (List) this.getFieldValue(TcfCaV1Field.DISCLOSED_VENDORS); + } + +} diff --git a/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/section/TcfCaV2.java b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/section/TcfCaV2.java deleted file mode 100644 index a5c27280..00000000 --- a/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/section/TcfCaV2.java +++ /dev/null @@ -1,278 +0,0 @@ -package com.iab.gpp.encoder.section; - -import java.time.ZoneId; -import java.time.ZonedDateTime; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.HashMap; -import java.util.List; -import java.util.function.IntSupplier; -import java.util.stream.Collectors; -import com.iab.gpp.encoder.datatype.EncodableBoolean; -import com.iab.gpp.encoder.datatype.EncodableDatetime; -import com.iab.gpp.encoder.datatype.EncodableFixedBitfield; -import com.iab.gpp.encoder.datatype.EncodableFixedInteger; -import com.iab.gpp.encoder.datatype.EncodableFixedIntegerRange; -import com.iab.gpp.encoder.datatype.EncodableFixedString; -import com.iab.gpp.encoder.datatype.EncodableFlexibleBitfield; -import com.iab.gpp.encoder.datatype.encoder.Base64UrlEncoder; -import com.iab.gpp.encoder.error.DecodingException; -import com.iab.gpp.encoder.error.EncodingException; -import com.iab.gpp.encoder.field.TcfCaV2Field; - -public class TcfCaV2 extends AbstractEncodableSegmentedBitStringSection { - public static int ID = 5; - public static int VERSION = 2; - public static String NAME = "tcfcav2"; - - public TcfCaV2() { - initFields(); - } - - public TcfCaV2(String encodedString) throws DecodingException { - initFields(); - - if (encodedString != null && encodedString.length() > 0) { - this.decode(encodedString); - } - } - - private void initFields() { - fields = new HashMap<>(); - - // core section - fields.put(TcfCaV2Field.VERSION, new EncodableFixedInteger(6, TcfCaV2.VERSION)); - fields.put(TcfCaV2Field.CREATED, new EncodableDatetime()); - fields.put(TcfCaV2Field.LAST_UPDATED, new EncodableDatetime()); - fields.put(TcfCaV2Field.CMP_ID, new EncodableFixedInteger(12, 0)); - fields.put(TcfCaV2Field.CMP_VERSION, new EncodableFixedInteger(12, 0)); - fields.put(TcfCaV2Field.CONSENT_SCREEN, new EncodableFixedInteger(6, 0)); - fields.put(TcfCaV2Field.CONSENT_LANGUAGE, new EncodableFixedString(2, "EN")); - fields.put(TcfCaV2Field.VENDOR_LIST_VERSION, new EncodableFixedInteger(12, 0)); - fields.put(TcfCaV2Field.TCF_POLICY_VERSION, new EncodableFixedInteger(6, 2)); - fields.put(TcfCaV2Field.USE_NON_STANDARD_STACKS, new EncodableBoolean(false)); - fields.put(TcfCaV2Field.SPECIAL_FEATURE_EXPRESS_CONSENT, new EncodableFixedBitfield(12, new ArrayList<>())); - fields.put(TcfCaV2Field.PURPOSES_EXPRESS_CONSENT, new EncodableFixedBitfield(24, new ArrayList<>())); - fields.put(TcfCaV2Field.PURPOSES_IMPLIED_CONSENT, new EncodableFixedBitfield(24, new ArrayList<>())); - fields.put(TcfCaV2Field.VENDOR_EXPRESS_CONSENT, new EncodableFixedIntegerRange(new ArrayList<>())); - fields.put(TcfCaV2Field.VENDOR_IMPLIED_CONSENT, new EncodableFixedIntegerRange(new ArrayList<>())); - - // publisher purposes segment - fields.put(TcfCaV2Field.SEGMENT_TYPE, new EncodableFixedInteger(3, 3)); - fields.put(TcfCaV2Field.PUB_PURPOSES_EXPRESS_CONSENT, new EncodableFixedBitfield(24, new ArrayList<>())); - fields.put(TcfCaV2Field.PUB_PURPOSES_IMPLIED_CONSENT, new EncodableFixedBitfield(24, new ArrayList<>())); - - EncodableFixedInteger numCustomPurposes = new EncodableFixedInteger(6, 0); - fields.put(TcfCaV2Field.NUM_CUSTOM_PURPOSES, numCustomPurposes); - - IntSupplier getLengthSupplier = new IntSupplier() { - - @Override - public int getAsInt() { - return numCustomPurposes.getValue(); - } - - }; - - fields.put(TcfCaV2Field.CUSTOM_PURPOSES_EXPRESS_CONSENT, - new EncodableFlexibleBitfield(getLengthSupplier, new ArrayList<>())); - - fields.put(TcfCaV2Field.CUSTOM_PURPOSES_IMPLIED_CONSENT, - new EncodableFlexibleBitfield(getLengthSupplier, new ArrayList<>())); - - //@formatter:off - String[] coreSegment = new String[] { - TcfCaV2Field.VERSION, - TcfCaV2Field.CREATED, - TcfCaV2Field.LAST_UPDATED, - TcfCaV2Field.CMP_ID, - TcfCaV2Field.CMP_VERSION, - TcfCaV2Field.CONSENT_SCREEN, - TcfCaV2Field.CONSENT_LANGUAGE, - TcfCaV2Field.VENDOR_LIST_VERSION, - TcfCaV2Field.TCF_POLICY_VERSION, - TcfCaV2Field.USE_NON_STANDARD_STACKS, - TcfCaV2Field.SPECIAL_FEATURE_EXPRESS_CONSENT, - TcfCaV2Field.PURPOSES_EXPRESS_CONSENT, - TcfCaV2Field.PURPOSES_IMPLIED_CONSENT, - TcfCaV2Field.VENDOR_EXPRESS_CONSENT, - TcfCaV2Field.VENDOR_IMPLIED_CONSENT - }; - - String[] publisherPurposesSegment = new String[] { - TcfCaV2Field.SEGMENT_TYPE, - TcfCaV2Field.PUB_PURPOSES_EXPRESS_CONSENT, - TcfCaV2Field.PUB_PURPOSES_IMPLIED_CONSENT, - TcfCaV2Field.NUM_CUSTOM_PURPOSES, - TcfCaV2Field.CUSTOM_PURPOSES_EXPRESS_CONSENT, - TcfCaV2Field.CUSTOM_PURPOSES_IMPLIED_CONSENT, - }; - - segments = new String[][] { - coreSegment, - publisherPurposesSegment - }; - //@formatter:on - } - - @Override - public String encode() throws EncodingException { - List segmentBitStrings = this.encodeSegmentsToBitStrings(); - List encodedSegments = new ArrayList<>(); - if (segmentBitStrings.size() >= 1) { - encodedSegments.add(Base64UrlEncoder.encode(segmentBitStrings.get(0))); - - if (segmentBitStrings.size() >= 2) { - encodedSegments.add(Base64UrlEncoder.encode(segmentBitStrings.get(1))); - } - } - - return encodedSegments.stream().collect(Collectors.joining(".")); - } - - @Override - public void decode(String encodedSection) throws DecodingException { - String[] encodedSegments = encodedSection.split("\\."); - String[] segmentBitStrings = new String[4]; - for (int i = 0; i < encodedSegments.length; i++) { - /** - * first char will contain 6 bits, we only need the first 3. In version 1 and 2 of the TC string - * there is no segment type for the CORE string. Instead the first 6 bits are reserved for the - * encoding version, but because we're only on a maximum of encoding version 2 the first 3 bits in - * the core segment will evaluate to 0. - */ - String segmentBitString = Base64UrlEncoder.decode(encodedSegments[i]); - switch (segmentBitString.substring(0, 3)) { - // unfortunately, the segment ordering doesn't match the segment ids - case "000": { - segmentBitStrings[0] = segmentBitString; - break; - } - case "011": { - segmentBitStrings[1] = segmentBitString; - break; - } - default: { - throw new DecodingException("Unable to decode segment '" + encodedSegments[i] + "'"); - } - } - } - this.decodeSegmentsFromBitStrings(Arrays.asList(segmentBitStrings)); - } - - @Override - public void setFieldValue(String fieldName, Object value) { - super.setFieldValue(fieldName, value); - - if (!fieldName.equals(TcfCaV2Field.CREATED) && !fieldName.equals(TcfCaV2Field.LAST_UPDATED)) { - ZonedDateTime utcDateTime = ZonedDateTime.now(ZoneId.of("UTC")); - - super.setFieldValue(TcfCaV2Field.CREATED, utcDateTime); - super.setFieldValue(TcfCaV2Field.LAST_UPDATED, utcDateTime); - } - } - - @Override - public int getId() { - return TcfCaV2.ID; - } - - @Override - public String getName() { - return TcfCaV2.NAME; - } - - public Integer getVersion() { - return (Integer) this.fields.get(TcfCaV2Field.VERSION).getValue(); - } - - public ZonedDateTime getCreated() { - return (ZonedDateTime) this.fields.get(TcfCaV2Field.CREATED).getValue(); - } - - public ZonedDateTime getLastUpdated() { - return (ZonedDateTime) this.fields.get(TcfCaV2Field.LAST_UPDATED).getValue(); - } - - public Integer getCmpId() { - return (Integer) this.fields.get(TcfCaV2Field.CMP_ID).getValue(); - } - - public Integer getCmpVersion() { - return (Integer) this.fields.get(TcfCaV2Field.CMP_VERSION).getValue(); - } - - public Integer getConsentScreen() { - return (Integer) this.fields.get(TcfCaV2Field.CONSENT_SCREEN).getValue(); - } - - public String getConsentLanguage() { - return (String) this.fields.get(TcfCaV2Field.CONSENT_LANGUAGE).getValue(); - } - - public Integer getVendorListVersion() { - return (Integer) this.fields.get(TcfCaV2Field.VENDOR_LIST_VERSION).getValue(); - } - - public Integer getPolicyVersion() { - return (Integer) this.fields.get(TcfCaV2Field.TCF_POLICY_VERSION).getValue(); - } - - public Boolean getUseNonStandardStacks() { - return (Boolean) this.fields.get(TcfCaV2Field.USE_NON_STANDARD_STACKS).getValue(); - } - - @SuppressWarnings("unchecked") - public List getSpecialFeatureExpressConsent() { - return (List) this.fields.get(TcfCaV2Field.SPECIAL_FEATURE_EXPRESS_CONSENT).getValue(); - } - - @SuppressWarnings("unchecked") - public List getPurposesExpressConsent() { - return (List) this.fields.get(TcfCaV2Field.PURPOSES_EXPRESS_CONSENT).getValue(); - } - - @SuppressWarnings("unchecked") - public List getPurposesImpliedConsent() { - return (List) this.fields.get(TcfCaV2Field.PURPOSES_IMPLIED_CONSENT).getValue(); - } - - @SuppressWarnings("unchecked") - public List getVendorExpressConsent() { - return (List) this.fields.get(TcfCaV2Field.VENDOR_EXPRESS_CONSENT).getValue(); - } - - @SuppressWarnings("unchecked") - public List getVendorImpliedConsent() { - return (List) this.fields.get(TcfCaV2Field.VENDOR_IMPLIED_CONSENT).getValue(); - } - - public Integer getSegmentType() { - return (Integer) this.fields.get(TcfCaV2Field.SEGMENT_TYPE).getValue(); - } - - @SuppressWarnings("unchecked") - public List getPubPurposesExpressConsent() { - return (List) this.fields.get(TcfCaV2Field.PUB_PURPOSES_EXPRESS_CONSENT).getValue(); - } - - @SuppressWarnings("unchecked") - public List getPubPurposesImpliedConsent() { - return (List) this.fields.get(TcfCaV2Field.PUB_PURPOSES_IMPLIED_CONSENT).getValue(); - } - - public Integer getNumCustomPurposes() { - return (Integer) this.fields.get(TcfCaV2Field.NUM_CUSTOM_PURPOSES).getValue(); - } - - @SuppressWarnings("unchecked") - public List getCustomPurposesExpressConsent() { - return (List) this.fields.get(TcfCaV2Field.CUSTOM_PURPOSES_EXPRESS_CONSENT).getValue(); - } - - @SuppressWarnings("unchecked") - public List getCustomPurposesImpliedConsent() { - return (List) this.fields.get(TcfCaV2Field.CUSTOM_PURPOSES_IMPLIED_CONSENT).getValue(); - } - -} diff --git a/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/section/TcfEuV2.java b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/section/TcfEuV2.java index 498ae46b..1f7f2b1e 100644 --- a/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/section/TcfEuV2.java +++ b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/section/TcfEuV2.java @@ -3,212 +3,127 @@ import java.time.ZoneId; import java.time.ZonedDateTime; import java.util.ArrayList; -import java.util.Arrays; -import java.util.HashMap; import java.util.List; -import java.util.function.IntSupplier; -import java.util.stream.Collectors; -import com.iab.gpp.encoder.datatype.encoder.Base64UrlEncoder; +import com.iab.gpp.encoder.datatype.RangeEntry; import com.iab.gpp.encoder.error.DecodingException; -import com.iab.gpp.encoder.error.EncodingException; -import com.iab.gpp.encoder.datatype.EncodableBoolean; -import com.iab.gpp.encoder.datatype.EncodableDatetime; -import com.iab.gpp.encoder.datatype.EncodableFixedBitfield; -import com.iab.gpp.encoder.datatype.EncodableFixedInteger; -import com.iab.gpp.encoder.datatype.EncodableFixedIntegerRange; -import com.iab.gpp.encoder.datatype.EncodableFixedString; -import com.iab.gpp.encoder.datatype.EncodableFlexibleBitfield; -import com.iab.gpp.encoder.datatype.EncodableOptimizedFixedRange; +import com.iab.gpp.encoder.error.InvalidFieldException; import com.iab.gpp.encoder.field.TcfEuV2Field; - -public class TcfEuV2 extends AbstractEncodableSegmentedBitStringSection { +import com.iab.gpp.encoder.segment.EncodableSegment; +import com.iab.gpp.encoder.segment.TcfEuV2CoreSegment; +import com.iab.gpp.encoder.segment.TcfEuV2PublisherPurposesSegment; +import com.iab.gpp.encoder.segment.TcfEuV2VendorsAllowedSegment; +import com.iab.gpp.encoder.segment.TcfEuV2VendorsDisclosedSegment; + +public class TcfEuV2 extends AbstractLazilyEncodableSection { + public static int ID = 2; public static int VERSION = 2; public static String NAME = "tcfeuv2"; public TcfEuV2() { - initFields(); + super(); } - public TcfEuV2(String encodedString) throws DecodingException { - initFields(); + public TcfEuV2(String encodedString) { + super(); + decode(encodedString); + } - if (encodedString != null && encodedString.length() > 0) { - this.decode(encodedString); - } + @Override + public int getId() { + return TcfEuV2.ID; } - private void initFields() { - fields = new HashMap<>(); - - // core section - fields.put(TcfEuV2Field.VERSION, new EncodableFixedInteger(6, TcfEuV2.VERSION)); - fields.put(TcfEuV2Field.CREATED, new EncodableDatetime()); - fields.put(TcfEuV2Field.LAST_UPDATED, new EncodableDatetime()); - fields.put(TcfEuV2Field.CMP_ID, new EncodableFixedInteger(12, 0)); - fields.put(TcfEuV2Field.CMP_VERSION, new EncodableFixedInteger(12, 0)); - fields.put(TcfEuV2Field.CONSENT_SCREEN, new EncodableFixedInteger(6, 0)); - fields.put(TcfEuV2Field.CONSENT_LANGUAGE, new EncodableFixedString(2, "EN")); - fields.put(TcfEuV2Field.VENDOR_LIST_VERSION, new EncodableFixedInteger(12, 0)); - fields.put(TcfEuV2Field.POLICY_VERSION, new EncodableFixedInteger(6, 2)); - fields.put(TcfEuV2Field.IS_SERVICE_SPECIFIC, new EncodableBoolean(false)); - fields.put(TcfEuV2Field.USE_NON_STANDARD_STACKS, new EncodableBoolean(false)); - fields.put(TcfEuV2Field.SPECIAL_FEATURE_OPTINS, new EncodableFixedBitfield(12, new ArrayList<>())); - fields.put(TcfEuV2Field.PURPOSE_CONSENTS, new EncodableFixedBitfield(24, new ArrayList<>())); - fields.put(TcfEuV2Field.PURPOSE_LEGITIMATE_INTERESTS, new EncodableFixedBitfield(24, new ArrayList<>())); - fields.put(TcfEuV2Field.PURPOSE_ONE_TREATMENT, new EncodableBoolean(false)); - fields.put(TcfEuV2Field.PUBLISHER_COUNTRY_CODE, new EncodableFixedString(2, "AA")); - fields.put(TcfEuV2Field.VENDOR_CONSENTS, new EncodableFixedIntegerRange(new ArrayList<>())); - fields.put(TcfEuV2Field.VENDOR_LEGITIMATE_INTERESTS, new EncodableFixedIntegerRange(new ArrayList<>())); - - fields.put(TcfEuV2Field.PUBLISHER_RESTRICTIONS, new EncodableFixedIntegerRange(new ArrayList<>())); - - // publisher purposes segment - fields.put(TcfEuV2Field.PUBLISHER_PURPOSES_SEGMENT_TYPE, new EncodableFixedInteger(3, 3)); - fields.put(TcfEuV2Field.PUBLISHER_CONSENTS, new EncodableFixedBitfield(24, new ArrayList<>())); - fields.put(TcfEuV2Field.PUBLISHER_LEGITIMATE_INTERESTS, new EncodableFixedBitfield(24, new ArrayList<>())); - - EncodableFixedInteger numCustomPurposes = new EncodableFixedInteger(6, 0); - fields.put(TcfEuV2Field.NUM_CUSTOM_PURPOSES, numCustomPurposes); - - IntSupplier getLengthSupplier = new IntSupplier() { - - @Override - public int getAsInt() { - return numCustomPurposes.getValue(); - } + @Override + public String getName() { + return TcfEuV2.NAME; + } - }; - - fields.put(TcfEuV2Field.PUBLISHER_CUSTOM_CONSENTS, - new EncodableFlexibleBitfield(getLengthSupplier, new ArrayList<>())); - - fields.put(TcfEuV2Field.PUBLISHER_CUSTOM_LEGITIMATE_INTERESTS, - new EncodableFlexibleBitfield(getLengthSupplier, new ArrayList<>())); - - fields.put(TcfEuV2Field.VENDORS_ALLOWED_SEGMENT_TYPE, new EncodableFixedInteger(3, 2)); - fields.put(TcfEuV2Field.VENDORS_ALLOWED, new EncodableOptimizedFixedRange(new ArrayList<>())); - - fields.put(TcfEuV2Field.VENDORS_DISCLOSED_SEGMENT_TYPE, new EncodableFixedInteger(3, 1)); - fields.put(TcfEuV2Field.VENDORS_DISCLOSED, new EncodableOptimizedFixedRange(new ArrayList<>())); - - //@formatter:off - String[] coreSegment = new String[] { - TcfEuV2Field.VERSION, - TcfEuV2Field.CREATED, - TcfEuV2Field.LAST_UPDATED, - TcfEuV2Field.CMP_ID, - TcfEuV2Field.CMP_VERSION, - TcfEuV2Field.CONSENT_SCREEN, - TcfEuV2Field.CONSENT_LANGUAGE, - TcfEuV2Field.VENDOR_LIST_VERSION, - TcfEuV2Field.POLICY_VERSION, - TcfEuV2Field.IS_SERVICE_SPECIFIC, - TcfEuV2Field.USE_NON_STANDARD_STACKS, - TcfEuV2Field.SPECIAL_FEATURE_OPTINS, - TcfEuV2Field.PURPOSE_CONSENTS, - TcfEuV2Field.PURPOSE_LEGITIMATE_INTERESTS, - TcfEuV2Field.PURPOSE_ONE_TREATMENT, - TcfEuV2Field.PUBLISHER_COUNTRY_CODE, - TcfEuV2Field.VENDOR_CONSENTS, - TcfEuV2Field.VENDOR_LEGITIMATE_INTERESTS, - TcfEuV2Field.PUBLISHER_RESTRICTIONS - }; - - String[] publisherPurposesSegment = new String[] { - TcfEuV2Field.PUBLISHER_PURPOSES_SEGMENT_TYPE, - TcfEuV2Field.PUBLISHER_CONSENTS, - TcfEuV2Field.PUBLISHER_LEGITIMATE_INTERESTS, - TcfEuV2Field.NUM_CUSTOM_PURPOSES, - TcfEuV2Field.PUBLISHER_CUSTOM_CONSENTS, - TcfEuV2Field.PUBLISHER_CUSTOM_LEGITIMATE_INTERESTS, - }; - - String[] vendorsAllowedSegment = new String[] { - TcfEuV2Field.VENDORS_ALLOWED_SEGMENT_TYPE, - TcfEuV2Field.VENDORS_ALLOWED, - }; - - String[] vendorsDisclosedSegment = new String[] { - TcfEuV2Field.VENDORS_DISCLOSED_SEGMENT_TYPE, - TcfEuV2Field.VENDORS_DISCLOSED, - }; - - segments = new String[][] { - coreSegment, - publisherPurposesSegment, - vendorsAllowedSegment, - vendorsDisclosedSegment - }; - //@formatter:on + @Override + public int getVersion() { + return TcfEuV2.VERSION; } @Override - public String encode() throws EncodingException { - List segmentBitStrings = this.encodeSegmentsToBitStrings(); + protected List initializeSegments() { + List segments = new ArrayList<>(); + segments.add(new TcfEuV2CoreSegment()); + segments.add(new TcfEuV2PublisherPurposesSegment()); + segments.add(new TcfEuV2VendorsAllowedSegment()); + segments.add(new TcfEuV2VendorsDisclosedSegment()); + return segments; + } + + @Override + public List decodeSection(String encodedString) { + List segments = initializeSegments(); + + if(encodedString != null && !encodedString.isEmpty()) { + String[] encodedSegments = encodedString.split("\\."); + for (int i = 0; i < encodedSegments.length; i++) { + + /** + * The first 3 bits contain the segment id. Rather than decode the entire string, just check the first character. + * + * A-H = '000' = 0 + * I-P = '001' = 1 + * Q-X = '010' = 2 + * Y-Z,a-f = '011' = 3 + * + * Note that there is no segment id field for the core segment. Instead the first 6 bits are reserved + * for the encoding version which only coincidentally works here because the version value is less than 8. + */ + + String encodedSegment = encodedSegments[i]; + if(!encodedSegment.isEmpty()) { + char firstChar = encodedSegment.charAt(0); + + // unfortunately, the segment ordering doesn't match the segment ids + if(firstChar >= 'A' && firstChar <= 'H') { + segments.get(0).decode(encodedSegments[i]); + } else if(firstChar >= 'I' && firstChar <= 'P') { + segments.get(3).decode(encodedSegments[i]); + } else if(firstChar >= 'Q' && firstChar <= 'X') { + segments.get(2).decode(encodedSegments[i]); + } else if((firstChar >= 'Y' && firstChar <= 'Z') || (firstChar >= 'a' && firstChar <= 'f')) { + segments.get(1).decode(encodedSegments[i]); + } else { + throw new DecodingException("Invalid segment '" + encodedSegment + "'"); + } + } + } + } + + return segments; + } + + @Override + public String encodeSection(List segments) { List encodedSegments = new ArrayList<>(); - if (segmentBitStrings.size() >= 1) { - encodedSegments.add(Base64UrlEncoder.encode(segmentBitStrings.get(0))); + if (segments.size() >= 1) { + encodedSegments.add(segments.get(0).encode()); Boolean isServiceSpecific = (Boolean) this.getFieldValue(TcfEuV2Field.IS_SERVICE_SPECIFIC); if (isServiceSpecific) { - if (segmentBitStrings.size() >= 2) { - encodedSegments.add(Base64UrlEncoder.encode(segmentBitStrings.get(1))); + if (segments.size() >= 2) { + encodedSegments.add(segments.get(1).encode()); } } else { - if (segmentBitStrings.size() >= 2) { - encodedSegments.add(Base64UrlEncoder.encode(segmentBitStrings.get(2))); + if (segments.size() >= 2) { + encodedSegments.add(segments.get(2).encode()); - if (segmentBitStrings.size() >= 3) { - encodedSegments.add(Base64UrlEncoder.encode(segmentBitStrings.get(3))); + if (segments.size() >= 3) { + encodedSegments.add(segments.get(3).encode()); } } } } - return encodedSegments.stream().collect(Collectors.joining(".")); + return String.join(".", encodedSegments); } @Override - public void decode(String encodedSection) throws DecodingException { - String[] encodedSegments = encodedSection.split("\\."); - String[] segmentBitStrings = new String[4]; - for (int i = 0; i < encodedSegments.length; i++) { - /** - * first char will contain 6 bits, we only need the first 3. In version 1 and 2 of the TC string - * there is no segment type for the CORE string. Instead the first 6 bits are reserved for the - * encoding version, but because we're only on a maximum of encoding version 2 the first 3 bits in - * the core segment will evaluate to 0. - */ - String segmentBitString = Base64UrlEncoder.decode(encodedSegments[i]); - switch (segmentBitString.substring(0, 3)) { - // unfortunately, the segment ordering doesn't match the segment ids - case "000": { - segmentBitStrings[0] = segmentBitString; - break; - } - case "001": { - segmentBitStrings[3] = segmentBitString; - break; - } - case "010": { - segmentBitStrings[2] = segmentBitString; - break; - } - case "011": { - segmentBitStrings[1] = segmentBitString; - break; - } - default: { - throw new DecodingException("Unable to decode segment '" + encodedSegments[i] + "'"); - } - } - } - this.decodeSegmentsFromBitStrings(Arrays.asList(segmentBitStrings)); - } - - @Override - public void setFieldValue(String fieldName, Object value) { + public void setFieldValue(String fieldName, Object value) throws InvalidFieldException { super.setFieldValue(fieldName, value); if (!fieldName.equals(TcfEuV2Field.CREATED) && !fieldName.equals(TcfEuV2Field.LAST_UPDATED)) { @@ -219,144 +134,130 @@ public void setFieldValue(String fieldName, Object value) { } } - @Override - public int getId() { - return TcfEuV2.ID; - } - - @Override - public String getName() { - return TcfEuV2.NAME; - } - - public Integer getVersion() { - return (Integer) this.fields.get(TcfEuV2Field.VERSION).getValue(); - } - + public ZonedDateTime getCreated() { - return (ZonedDateTime) this.fields.get(TcfEuV2Field.CREATED).getValue(); + return (ZonedDateTime) this.getFieldValue(TcfEuV2Field.CREATED); } public ZonedDateTime getLastUpdated() { - return (ZonedDateTime) this.fields.get(TcfEuV2Field.LAST_UPDATED).getValue(); + return (ZonedDateTime) this.getFieldValue(TcfEuV2Field.LAST_UPDATED); } public Integer getCmpId() { - return (Integer) this.fields.get(TcfEuV2Field.CMP_ID).getValue(); + return (Integer) this.getFieldValue(TcfEuV2Field.CMP_ID); } public Integer getCmpVersion() { - return (Integer) this.fields.get(TcfEuV2Field.CMP_VERSION).getValue(); + return (Integer) this.getFieldValue(TcfEuV2Field.CMP_VERSION); } public Integer getConsentScreen() { - return (Integer) this.fields.get(TcfEuV2Field.CONSENT_SCREEN).getValue(); + return (Integer) this.getFieldValue(TcfEuV2Field.CONSENT_SCREEN); } public String getConsentLanguage() { - return (String) this.fields.get(TcfEuV2Field.CONSENT_LANGUAGE).getValue(); + return (String) this.getFieldValue(TcfEuV2Field.CONSENT_LANGUAGE); } public Integer getVendorListVersion() { - return (Integer) this.fields.get(TcfEuV2Field.VENDOR_LIST_VERSION).getValue(); + return (Integer) this.getFieldValue(TcfEuV2Field.VENDOR_LIST_VERSION); } public Integer getPolicyVersion() { - return (Integer) this.fields.get(TcfEuV2Field.POLICY_VERSION).getValue(); + return (Integer) this.getFieldValue(TcfEuV2Field.POLICY_VERSION); } public Boolean getIsServiceSpecific() { - return (Boolean) this.fields.get(TcfEuV2Field.IS_SERVICE_SPECIFIC).getValue(); + return (Boolean) this.getFieldValue(TcfEuV2Field.IS_SERVICE_SPECIFIC); } public Boolean getUseNonStandardStacks() { - return (Boolean) this.fields.get(TcfEuV2Field.USE_NON_STANDARD_STACKS).getValue(); + return (Boolean) this.getFieldValue(TcfEuV2Field.USE_NON_STANDARD_STACKS); } @SuppressWarnings("unchecked") - public List getSpecialFeatureOptins() { - return (List) this.fields.get(TcfEuV2Field.SPECIAL_FEATURE_OPTINS).getValue(); + public List getSpecialFeatureOptins() { + return (List) this.getFieldValue(TcfEuV2Field.SPECIAL_FEATURE_OPTINS); } @SuppressWarnings("unchecked") - public List getPurposeConsents() { - return (List) this.fields.get(TcfEuV2Field.PURPOSE_CONSENTS).getValue(); + public List getPurposeConsents() { + return (List) this.getFieldValue(TcfEuV2Field.PURPOSE_CONSENTS); } @SuppressWarnings("unchecked") - public List getPurposeLegitimateInterests() { - return (List) this.fields.get(TcfEuV2Field.PURPOSE_LEGITIMATE_INTERESTS).getValue(); + public List getPurposeLegitimateInterests() { + return (List) this.getFieldValue(TcfEuV2Field.PURPOSE_LEGITIMATE_INTERESTS); } public Boolean getPurposeOneTreatment() { - return (Boolean) this.fields.get(TcfEuV2Field.PURPOSE_ONE_TREATMENT).getValue(); + return (Boolean) this.getFieldValue(TcfEuV2Field.PURPOSE_ONE_TREATMENT); } public String getPublisherCountryCode() { - return (String) this.fields.get(TcfEuV2Field.PUBLISHER_COUNTRY_CODE).getValue(); + return (String) this.getFieldValue(TcfEuV2Field.PUBLISHER_COUNTRY_CODE); } @SuppressWarnings("unchecked") public List getVendorConsents() { - return (List) this.fields.get(TcfEuV2Field.VENDOR_CONSENTS).getValue(); + return (List) this.getFieldValue(TcfEuV2Field.VENDOR_CONSENTS); } @SuppressWarnings("unchecked") public List getVendorLegitimateInterests() { - return (List) this.fields.get(TcfEuV2Field.VENDOR_LEGITIMATE_INTERESTS).getValue(); + return (List) this.getFieldValue(TcfEuV2Field.VENDOR_LEGITIMATE_INTERESTS); } @SuppressWarnings("unchecked") - public List getPublisherRestrictions() { - return (List) this.fields.get(TcfEuV2Field.PUBLISHER_RESTRICTIONS).getValue(); + public List getPublisherRestrictions() { + return (List) this.getFieldValue(TcfEuV2Field.PUBLISHER_RESTRICTIONS); } public Integer getPublisherPurposesSegmentType() { - return (Integer) this.fields.get(TcfEuV2Field.PUBLISHER_PURPOSES_SEGMENT_TYPE).getValue(); + return (Integer) this.getFieldValue(TcfEuV2Field.PUBLISHER_PURPOSES_SEGMENT_TYPE); } @SuppressWarnings("unchecked") - public List getPublisherConsents() { - return (List) this.fields.get(TcfEuV2Field.PUBLISHER_CONSENTS).getValue(); + public List getPublisherConsents() { + return (List) this.getFieldValue(TcfEuV2Field.PUBLISHER_CONSENTS); } @SuppressWarnings("unchecked") - public List getPublisherLegitimateInterests() { - return (List) this.fields.get(TcfEuV2Field.PUBLISHER_LEGITIMATE_INTERESTS).getValue(); + public List getPublisherLegitimateInterests() { + return (List) this.getFieldValue(TcfEuV2Field.PUBLISHER_LEGITIMATE_INTERESTS); } public Integer getNumCustomPurposes() { - return (Integer) this.fields.get(TcfEuV2Field.NUM_CUSTOM_PURPOSES).getValue(); + return (Integer) this.getFieldValue(TcfEuV2Field.NUM_CUSTOM_PURPOSES); } @SuppressWarnings("unchecked") public List getPublisherCustomConsents() { - return (List) this.fields.get(TcfEuV2Field.PUBLISHER_CUSTOM_CONSENTS).getValue(); + return (List) this.getFieldValue(TcfEuV2Field.PUBLISHER_CUSTOM_CONSENTS); } @SuppressWarnings("unchecked") public List getPublisherCustomLegitimateInterests() { - return (List) this.fields.get(TcfEuV2Field.PUBLISHER_CUSTOM_LEGITIMATE_INTERESTS).getValue(); + return (List) this.getFieldValue(TcfEuV2Field.PUBLISHER_CUSTOM_LEGITIMATE_INTERESTS); } public Integer getVendorsAllowedSegmentType() { - return (Integer) this.fields.get(TcfEuV2Field.VENDORS_ALLOWED_SEGMENT_TYPE).getValue(); + return (Integer) this.getFieldValue(TcfEuV2Field.VENDORS_ALLOWED_SEGMENT_TYPE); } @SuppressWarnings("unchecked") public List getVendorsAllowed() { - return (List) this.fields.get(TcfEuV2Field.VENDORS_ALLOWED).getValue(); + return (List) this.getFieldValue(TcfEuV2Field.VENDORS_ALLOWED); } public Integer getVendorsDisclosedSegmentType() { - return (Integer) this.fields.get(TcfEuV2Field.VENDORS_DISCLOSED_SEGMENT_TYPE).getValue(); + return (Integer) this.getFieldValue(TcfEuV2Field.VENDORS_DISCLOSED_SEGMENT_TYPE); } @SuppressWarnings("unchecked") public List getVendorsDisclosed() { - return (List) this.fields.get(TcfEuV2Field.VENDORS_DISCLOSED).getValue(); + return (List) this.getFieldValue(TcfEuV2Field.VENDORS_DISCLOSED); } - - - + + } diff --git a/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/section/UsCa.java b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/section/UsCa.java new file mode 100644 index 00000000..e80c4680 --- /dev/null +++ b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/section/UsCa.java @@ -0,0 +1,142 @@ +package com.iab.gpp.encoder.section; + +import java.util.ArrayList; +import java.util.List; +import com.iab.gpp.encoder.field.UsCaField; +import com.iab.gpp.encoder.segment.EncodableSegment; +import com.iab.gpp.encoder.segment.UsCaCoreSegment; +import com.iab.gpp.encoder.segment.UsCaGpcSegment; + +public class UsCa extends AbstractLazilyEncodableSection { + + public static int ID = 8; + public static int VERSION = 1; + public static String NAME = "usca"; + + public UsCa() { + super(); + } + + public UsCa(String encodedString) { + super(); + decode(encodedString); + } + + @Override + public int getId() { + return UsCa.ID; + } + + @Override + public String getName() { + return UsCa.NAME; + } + + @Override + public int getVersion() { + return UsCa.VERSION; + } + + @Override + protected List initializeSegments() { + List segments = new ArrayList<>(); + segments.add(new UsCaCoreSegment()); + segments.add(new UsCaGpcSegment()); + return segments; + } + + @Override + protected List decodeSection(String encodedString) { + List segments = initializeSegments(); + + if(encodedString != null && !encodedString.isEmpty()) { + String[] encodedSegments = encodedString.split("\\."); + + if(encodedSegments.length > 0) { + segments.get(0).decode(encodedSegments[0]); + } + + if(encodedSegments.length > 1) { + segments.get(1).setFieldValue(UsCaField.GPC_SEGMENT_INCLUDED, true); + segments.get(1).decode(encodedSegments[1]); + } else { + segments.get(1).setFieldValue(UsCaField.GPC_SEGMENT_INCLUDED, false); + } + } + + return segments; + } + + @Override + protected String encodeSection(List segments) { + List encodedSegments = new ArrayList<>(); + + if(!segments.isEmpty()) { + encodedSegments.add(segments.get(0).encode()); + if(segments.size() >= 2 && segments.get(1).getFieldValue(UsCaField.GPC_SEGMENT_INCLUDED).equals(true)) { + encodedSegments.add(segments.get(1).encode()); + } + } + + return String.join(".", encodedSegments); + } + + + public Integer getSaleOptOutNotice() { + return (Integer) this.getFieldValue(UsCaField.SALE_OPT_OUT_NOTICE); + } + + public Integer getSensitiveDataLimitUseNotice() { + return (Integer) this.getFieldValue(UsCaField.SENSITIVE_DATA_LIMIT_USE_NOTICE); + } + + public Integer getSharingOptOutNotice() { + return (Integer) this.getFieldValue(UsCaField.SHARING_OPT_OUT_NOTICE); + } + + public Integer getSaleOptOut() { + return (Integer) this.getFieldValue(UsCaField.SALE_OPT_OUT); + } + + public Integer getSharingOptOut() { + return (Integer) this.getFieldValue(UsCaField.SHARING_OPT_OUT); + } + + @SuppressWarnings("unchecked") + public List getSensitiveDataProcessing() { + return (List) this.getFieldValue(UsCaField.SENSITIVE_DATA_PROCESSING); + } + + @SuppressWarnings("unchecked") + public List getKnownChildSensitiveDataConsents() { + return (List) this.getFieldValue(UsCaField.KNOWN_CHILD_SENSITIVE_DATA_CONSENTS); + } + + public Integer getPersonalDataConsents() { + return (Integer) this.getFieldValue(UsCaField.PERSONAL_DATA_CONSENTS); + } + + public Integer getMspaCoveredTransaction() { + return (Integer) this.getFieldValue(UsCaField.MSPA_COVERED_TRANSACTION); + } + + public Integer getMspaOptOutOptionMode() { + return (Integer) this.getFieldValue(UsCaField.MSPA_OPT_OUT_OPTION_MODE); + } + + public Integer getMspaServiceProviderMode() { + return (Integer) this.getFieldValue(UsCaField.MSPA_SERVICE_PROVIDER_MODE); + } + + public Integer getGpcSegmentType() { + return (Integer) this.getFieldValue(UsCaField.GPC_SEGMENT_TYPE); + } + + public Boolean getGpcSegmentIncluded() { + return (Boolean) this.getFieldValue(UsCaField.GPC_SEGMENT_INCLUDED); + } + + public Boolean getGpc() { + return (Boolean) this.getFieldValue(UsCaField.GPC); + } +} diff --git a/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/section/UsCo.java b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/section/UsCo.java new file mode 100644 index 00000000..9e5495c0 --- /dev/null +++ b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/section/UsCo.java @@ -0,0 +1,137 @@ +package com.iab.gpp.encoder.section; + +import java.util.ArrayList; +import java.util.List; +import com.iab.gpp.encoder.field.UsCoField; +import com.iab.gpp.encoder.segment.EncodableSegment; +import com.iab.gpp.encoder.segment.UsCoCoreSegment; +import com.iab.gpp.encoder.segment.UsCoGpcSegment; + +public class UsCo extends AbstractLazilyEncodableSection { + + public static int ID = 10; + public static int VERSION = 1; + public static String NAME = "usco"; + + public UsCo() { + super(); + } + + public UsCo(String encodedString) { + super(); + decode(encodedString); + } + + @Override + public int getId() { + return UsCo.ID; + } + + @Override + public String getName() { + return UsCo.NAME; + } + + @Override + public int getVersion() { + return UsCo.VERSION; + } + + @Override + protected List initializeSegments() { + List segments = new ArrayList<>(); + segments.add(new UsCoCoreSegment()); + segments.add(new UsCoGpcSegment()); + return segments; + } + + @Override + protected List decodeSection(String encodedString) { + List segments = initializeSegments(); + + if(encodedString != null && !encodedString.isEmpty()) { + String[] encodedSegments = encodedString.split("\\."); + + if(encodedSegments.length > 0) { + segments.get(0).decode(encodedSegments[0]); + } + + if(encodedSegments.length > 1) { + segments.get(1).setFieldValue(UsCoField.GPC_SEGMENT_INCLUDED, true); + segments.get(1).decode(encodedSegments[1]); + } else { + segments.get(1).setFieldValue(UsCoField.GPC_SEGMENT_INCLUDED, false); + } + } + + return segments; + } + + @Override + protected String encodeSection(List segments) { + List encodedSegments = new ArrayList<>(); + + if(!segments.isEmpty()) { + encodedSegments.add(segments.get(0).encode()); + if(segments.size() >= 2 && segments.get(1).getFieldValue(UsCoField.GPC_SEGMENT_INCLUDED).equals(true)) { + encodedSegments.add(segments.get(1).encode()); + } + } + + return String.join(".", encodedSegments); + } + + + public Integer getSharingNotice() { + return (Integer) this.getFieldValue(UsCoField.SHARING_NOTICE); + } + + public Integer getSaleOptOutNotice() { + return (Integer) this.getFieldValue(UsCoField.SALE_OPT_OUT_NOTICE); + } + + public Integer getTargetedAdvertisingOptOutNotice() { + return (Integer) this.getFieldValue(UsCoField.TARGETED_ADVERTISING_OPT_OUT_NOTICE); + } + + public Integer getSaleOptOut() { + return (Integer) this.getFieldValue(UsCoField.SALE_OPT_OUT); + } + + public Integer getTargetedAdvertisingOptOut() { + return (Integer) this.getFieldValue(UsCoField.TARGETED_ADVERTISING_OPT_OUT); + } + + @SuppressWarnings("unchecked") + public List getSensitiveDataProcessing() { + return (List) this.getFieldValue(UsCoField.SENSITIVE_DATA_PROCESSING); + } + + public Integer getKnownChildSensitiveDataConsents() { + return (Integer) this.getFieldValue(UsCoField.KNOWN_CHILD_SENSITIVE_DATA_CONSENTS); + } + + public Integer getMspaCoveredTransaction() { + return (Integer) this.getFieldValue(UsCoField.MSPA_COVERED_TRANSACTION); + } + + public Integer getMspaOptOutOptionMode() { + return (Integer) this.getFieldValue(UsCoField.MSPA_OPT_OUT_OPTION_MODE); + } + + public Integer getMspaServiceProviderMode() { + return (Integer) this.getFieldValue(UsCoField.MSPA_SERVICE_PROVIDER_MODE); + } + + public Integer getGpcSegmentType() { + return (Integer) this.getFieldValue(UsCoField.GPC_SEGMENT_TYPE); + } + + public Boolean getGpcSegmentIncluded() { + return (Boolean) this.getFieldValue(UsCoField.GPC_SEGMENT_INCLUDED); + } + + public Boolean getGpc() { + return (Boolean) this.getFieldValue(UsCoField.GPC); + } +} diff --git a/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/section/UsCt.java b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/section/UsCt.java new file mode 100644 index 00000000..0f2f9569 --- /dev/null +++ b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/section/UsCt.java @@ -0,0 +1,138 @@ +package com.iab.gpp.encoder.section; + +import java.util.ArrayList; +import java.util.List; +import com.iab.gpp.encoder.field.UsCtField; +import com.iab.gpp.encoder.segment.EncodableSegment; +import com.iab.gpp.encoder.segment.UsCtCoreSegment; +import com.iab.gpp.encoder.segment.UsCtGpcSegment; + +public class UsCt extends AbstractLazilyEncodableSection { + + public static int ID = 12; + public static int VERSION = 1; + public static String NAME = "usct"; + + public UsCt() { + super(); + } + + public UsCt(String encodedString) { + super(); + decode(encodedString); + } + + @Override + public int getId() { + return UsCt.ID; + } + + @Override + public String getName() { + return UsCt.NAME; + } + + @Override + public int getVersion() { + return UsCt.VERSION; + } + + @Override + protected List initializeSegments() { + List segments = new ArrayList<>(); + segments.add(new UsCtCoreSegment()); + segments.add(new UsCtGpcSegment()); + return segments; + } + + @Override + protected List decodeSection(String encodedString) { + List segments = initializeSegments(); + + if(encodedString != null && !encodedString.isEmpty()) { + String[] encodedSegments = encodedString.split("\\."); + + if(encodedSegments.length > 0) { + segments.get(0).decode(encodedSegments[0]); + } + + if(encodedSegments.length > 1) { + segments.get(1).setFieldValue(UsCtField.GPC_SEGMENT_INCLUDED, true); + segments.get(1).decode(encodedSegments[1]); + } else { + segments.get(1).setFieldValue(UsCtField.GPC_SEGMENT_INCLUDED, false); + } + } + + return segments; + } + + @Override + protected String encodeSection(List segments) { + List encodedSegments = new ArrayList<>(); + + if(!segments.isEmpty()) { + encodedSegments.add(segments.get(0).encode()); + if(segments.size() >= 2 && segments.get(1).getFieldValue(UsCtField.GPC_SEGMENT_INCLUDED).equals(true)) { + encodedSegments.add(segments.get(1).encode()); + } + } + + return String.join(".", encodedSegments); + } + + + public Integer getSharingNotice() { + return (Integer) this.getFieldValue(UsCtField.SHARING_NOTICE); + } + + public Integer getSaleOptOutNotice() { + return (Integer) this.getFieldValue(UsCtField.SALE_OPT_OUT_NOTICE); + } + + public Integer getTargetedAdvertisingOptOutNotice() { + return (Integer) this.getFieldValue(UsCtField.TARGETED_ADVERTISING_OPT_OUT_NOTICE); + } + + public Integer getSaleOptOut() { + return (Integer) this.getFieldValue(UsCtField.SALE_OPT_OUT); + } + + public Integer getTargetedAdvertisingOptOut() { + return (Integer) this.getFieldValue(UsCtField.TARGETED_ADVERTISING_OPT_OUT); + } + + @SuppressWarnings("unchecked") + public List getSensitiveDataProcessing() { + return (List) this.getFieldValue(UsCtField.SENSITIVE_DATA_PROCESSING); + } + + @SuppressWarnings("unchecked") + public List getKnownChildSensitiveDataConsents() { + return (List) this.getFieldValue(UsCtField.KNOWN_CHILD_SENSITIVE_DATA_CONSENTS); + } + + public Integer getMspaCoveredTransaction() { + return (Integer) this.getFieldValue(UsCtField.MSPA_COVERED_TRANSACTION); + } + + public Integer getMspaOptOutOptionMode() { + return (Integer) this.getFieldValue(UsCtField.MSPA_OPT_OUT_OPTION_MODE); + } + + public Integer getMspaServiceProviderMode() { + return (Integer) this.getFieldValue(UsCtField.MSPA_SERVICE_PROVIDER_MODE); + } + + public Integer getGpcSegmentType() { + return (Integer) this.getFieldValue(UsCtField.GPC_SEGMENT_TYPE); + } + + public Boolean getGpcSegmentIncluded() { + return (Boolean) this.getFieldValue(UsCtField.GPC_SEGMENT_INCLUDED); + } + + public Boolean getGpc() { + return (Boolean) this.getFieldValue(UsCtField.GPC); + } +} diff --git a/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/section/UsDe.java b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/section/UsDe.java new file mode 100644 index 00000000..82538ee7 --- /dev/null +++ b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/section/UsDe.java @@ -0,0 +1,142 @@ +package com.iab.gpp.encoder.section; + +import java.util.ArrayList; +import java.util.List; +import com.iab.gpp.encoder.field.UsDeField; +import com.iab.gpp.encoder.segment.EncodableSegment; +import com.iab.gpp.encoder.segment.UsDeCoreSegment; +import com.iab.gpp.encoder.segment.UsDeGpcSegment; + +public class UsDe extends AbstractLazilyEncodableSection { + + public static int ID = 17; + public static int VERSION = 1; + public static String NAME = "usde"; + + public UsDe() { + super(); + } + + public UsDe(String encodedString) { + super(); + decode(encodedString); + } + + @Override + public int getId() { + return UsDe.ID; + } + + @Override + public String getName() { + return UsDe.NAME; + } + + @Override + public int getVersion() { + return UsDe.VERSION; + } + + @Override + protected List initializeSegments() { + List segments = new ArrayList<>(); + segments.add(new UsDeCoreSegment()); + segments.add(new UsDeGpcSegment()); + return segments; + } + + @Override + protected List decodeSection(String encodedString) { + List segments = initializeSegments(); + + if (encodedString != null && !encodedString.isEmpty()) { + String[] encodedSegments = encodedString.split("\\."); + + if (encodedSegments.length > 0) { + segments.get(0).decode(encodedSegments[0]); + } + + if (encodedSegments.length > 1) { + segments.get(1).setFieldValue(UsDeField.GPC_SEGMENT_INCLUDED, true); + segments.get(1).decode(encodedSegments[1]); + } else { + segments.get(1).setFieldValue(UsDeField.GPC_SEGMENT_INCLUDED, false); + } + } + + return segments; + } + + @Override + protected String encodeSection(List segments) { + List encodedSegments = new ArrayList<>(); + + if (!segments.isEmpty()) { + encodedSegments.add(segments.get(0).encode()); + if (segments.size() >= 2 && segments.get(1).getFieldValue(UsDeField.GPC_SEGMENT_INCLUDED).equals(true)) { + encodedSegments.add(segments.get(1).encode()); + } + } + + return String.join(".", encodedSegments); + } + + + public Integer getProcessingNotice() { + return (Integer) this.getFieldValue(UsDeField.PROCESSING_NOTICE); + } + + public Integer getSaleOptOutNotice() { + return (Integer) this.getFieldValue(UsDeField.SALE_OPT_OUT_NOTICE); + } + + public Integer getTargetedAdvertisingOptOutNotice() { + return (Integer) this.getFieldValue(UsDeField.TARGETED_ADVERTISING_OPT_OUT_NOTICE); + } + + public Integer getSaleOptOut() { + return (Integer) this.getFieldValue(UsDeField.SALE_OPT_OUT); + } + + public Integer getTargetedAdvertisingOptOut() { + return (Integer) this.getFieldValue(UsDeField.TARGETED_ADVERTISING_OPT_OUT); + } + + @SuppressWarnings("unchecked") + public List getSensitiveDataProcessing() { + return (List) this.getFieldValue(UsDeField.SENSITIVE_DATA_PROCESSING); + } + + @SuppressWarnings("unchecked") + public List getKnownChildSensitiveDataConsents() { + return (List) this.getFieldValue(UsDeField.KNOWN_CHILD_SENSITIVE_DATA_CONSENTS); + } + + public Integer getAdditionalDataProcessingConsent() { + return (Integer) this.getFieldValue(UsDeField.ADDITIONAL_DATA_PROCESSING_CONSENT); + } + + public Integer getMspaCoveredTransaction() { + return (Integer) this.getFieldValue(UsDeField.MSPA_COVERED_TRANSACTION); + } + + public Integer getMspaOptOutOptionMode() { + return (Integer) this.getFieldValue(UsDeField.MSPA_OPT_OUT_OPTION_MODE); + } + + public Integer getMspaServiceProviderMode() { + return (Integer) this.getFieldValue(UsDeField.MSPA_SERVICE_PROVIDER_MODE); + } + + public Integer getGpcSegmentType() { + return (Integer) this.getFieldValue(UsDeField.GPC_SEGMENT_TYPE); + } + + public Boolean getGpcSegmentIncluded() { + return (Boolean) this.getFieldValue(UsDeField.GPC_SEGMENT_INCLUDED); + } + + public Boolean getGpc() { + return (Boolean) this.getFieldValue(UsDeField.GPC); + } +} diff --git a/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/section/UsFl.java b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/section/UsFl.java new file mode 100644 index 00000000..8c568479 --- /dev/null +++ b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/section/UsFl.java @@ -0,0 +1,118 @@ +package com.iab.gpp.encoder.section; + +import java.util.ArrayList; +import java.util.List; +import com.iab.gpp.encoder.field.UsFlField; +import com.iab.gpp.encoder.segment.EncodableSegment; +import com.iab.gpp.encoder.segment.UsFlCoreSegment; + +public class UsFl extends AbstractLazilyEncodableSection { + + public static int ID = 13; + public static int VERSION = 1; + public static String NAME = "usfl"; + + public UsFl() { + super(); + } + + public UsFl(String encodedString) { + super(); + decode(encodedString); + } + + @Override + public int getId() { + return UsFl.ID; + } + + @Override + public String getName() { + return UsFl.NAME; + } + + @Override + public int getVersion() { + return UsFl.VERSION; + } + + @Override + protected List initializeSegments() { + List segments = new ArrayList<>(); + segments.add(new UsFlCoreSegment()); + return segments; + } + + @Override + protected List decodeSection(String encodedString) { + List segments = initializeSegments(); + + if(encodedString != null && !encodedString.isEmpty()) { + String[] encodedSegments = encodedString.split("\\."); + + for (int i = 0; i < segments.size(); i++) { + if (encodedSegments.length > i) { + segments.get(i).decode(encodedSegments[i]); + } + } + } + + return segments; + } + + @Override + protected String encodeSection(List segments) { + List encodedSegments = new ArrayList<>(); + for (EncodableSegment segment : segments) { + encodedSegments.add(segment.encode()); + } + return String.join(".", encodedSegments); + } + + + public Integer getProcessingNotice() { + return (Integer) this.getFieldValue(UsFlField.PROCESSING_NOTICE); + } + + public Integer getSaleOptOutNotice() { + return (Integer) this.getFieldValue(UsFlField.SALE_OPT_OUT_NOTICE); + } + + public Integer getTargetedAdvertisingOptOutNotice() { + return (Integer) this.getFieldValue(UsFlField.TARGETED_ADVERTISING_OPT_OUT_NOTICE); + } + + public Integer getSaleOptOut() { + return (Integer) this.getFieldValue(UsFlField.SALE_OPT_OUT); + } + + public Integer getTargetedAdvertisingOptOut() { + return (Integer) this.getFieldValue(UsFlField.TARGETED_ADVERTISING_OPT_OUT); + } + + @SuppressWarnings("unchecked") + public List getSensitiveDataProcessing() { + return (List) this.getFieldValue(UsFlField.SENSITIVE_DATA_PROCESSING); + } + + @SuppressWarnings("unchecked") + public List getKnownChildSensitiveDataConsents() { + return (List) this.getFieldValue(UsFlField.KNOWN_CHILD_SENSITIVE_DATA_CONSENTS); + } + + public Integer getAdditionalDataProcessingConsent() { + return (Integer) this.getFieldValue(UsFlField.ADDITIONAL_DATA_PROCESSING_CONSENT); + } + + public Integer getMspaCoveredTransaction() { + return (Integer) this.getFieldValue(UsFlField.MSPA_COVERED_TRANSACTION); + } + + public Integer getMspaOptOutOptionMode() { + return (Integer) this.getFieldValue(UsFlField.MSPA_OPT_OUT_OPTION_MODE); + } + + public Integer getMspaServiceProviderMode() { + return (Integer) this.getFieldValue(UsFlField.MSPA_SERVICE_PROVIDER_MODE); + } +} diff --git a/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/section/UsIa.java b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/section/UsIa.java new file mode 100644 index 00000000..a3ab88e3 --- /dev/null +++ b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/section/UsIa.java @@ -0,0 +1,141 @@ +package com.iab.gpp.encoder.section; + +import java.util.ArrayList; +import java.util.List; +import com.iab.gpp.encoder.field.UsIaField; +import com.iab.gpp.encoder.segment.EncodableSegment; +import com.iab.gpp.encoder.segment.UsIaCoreSegment; +import com.iab.gpp.encoder.segment.UsIaGpcSegment; + +public class UsIa extends AbstractLazilyEncodableSection { + + public static int ID = 18; + public static int VERSION = 1; + public static String NAME = "usia"; + + public UsIa() { + super(); + } + + public UsIa(String encodedString) { + super(); + decode(encodedString); + } + + @Override + public int getId() { + return UsIa.ID; + } + + @Override + public String getName() { + return UsIa.NAME; + } + + @Override + public int getVersion() { + return UsIa.VERSION; + } + + @Override + protected List initializeSegments() { + List segments = new ArrayList<>(); + segments.add(new UsIaCoreSegment()); + segments.add(new UsIaGpcSegment()); + return segments; + } + + @Override + protected List decodeSection(String encodedString) { + List segments = initializeSegments(); + + if (encodedString != null && !encodedString.isEmpty()) { + String[] encodedSegments = encodedString.split("\\."); + + if (encodedSegments.length > 0) { + segments.get(0).decode(encodedSegments[0]); + } + + if (encodedSegments.length > 1) { + segments.get(1).setFieldValue(UsIaField.GPC_SEGMENT_INCLUDED, true); + segments.get(1).decode(encodedSegments[1]); + } else { + segments.get(1).setFieldValue(UsIaField.GPC_SEGMENT_INCLUDED, false); + } + } + + return segments; + } + + @Override + protected String encodeSection(List segments) { + List encodedSegments = new ArrayList<>(); + + if (!segments.isEmpty()) { + encodedSegments.add(segments.get(0).encode()); + if (segments.size() >= 2 && segments.get(1).getFieldValue(UsIaField.GPC_SEGMENT_INCLUDED).equals(true)) { + encodedSegments.add(segments.get(1).encode()); + } + } + + return String.join(".", encodedSegments); + } + + + public Integer getProcessingNotice() { + return (Integer) this.getFieldValue(UsIaField.PROCESSING_NOTICE); + } + + public Integer getSaleOptOutNotice() { + return (Integer) this.getFieldValue(UsIaField.SALE_OPT_OUT_NOTICE); + } + + public Integer getTargetedAdvertisingOptOutNotice() { + return (Integer) this.getFieldValue(UsIaField.TARGETED_ADVERTISING_OPT_OUT_NOTICE); + } + + public Integer getSensitiveDataOptOutNotice() { + return (Integer) this.getFieldValue(UsIaField.SENSITIVE_DATA_OPT_OUT_NOTICE); + } + + public Integer getSaleOptOut() { + return (Integer) this.getFieldValue(UsIaField.SALE_OPT_OUT); + } + + public Integer getTargetedAdvertisingOptOut() { + return (Integer) this.getFieldValue(UsIaField.TARGETED_ADVERTISING_OPT_OUT); + } + + @SuppressWarnings("unchecked") + public List getSensitiveDataProcessing() { + return (List) this.getFieldValue(UsIaField.SENSITIVE_DATA_PROCESSING); + } + + public Integer getKnownChildSensitiveDataConsents() { + return (Integer) this.getFieldValue(UsIaField.KNOWN_CHILD_SENSITIVE_DATA_CONSENTS); + } + + public Integer getMspaCoveredTransaction() { + return (Integer) this.getFieldValue(UsIaField.MSPA_COVERED_TRANSACTION); + } + + public Integer getMspaOptOutOptionMode() { + return (Integer) this.getFieldValue(UsIaField.MSPA_OPT_OUT_OPTION_MODE); + } + + public Integer getMspaServiceProviderMode() { + return (Integer) this.getFieldValue(UsIaField.MSPA_SERVICE_PROVIDER_MODE); + } + + public Integer getGpcSegmentType() { + return (Integer) this.getFieldValue(UsIaField.GPC_SEGMENT_TYPE); + } + + public Boolean getGpcSegmentIncluded() { + return (Boolean) this.getFieldValue(UsIaField.GPC_SEGMENT_INCLUDED); + } + + public Boolean getGpc() { + return (Boolean) this.getFieldValue(UsIaField.GPC); + } +} diff --git a/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/section/UsMt.java b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/section/UsMt.java new file mode 100644 index 00000000..faf5a235 --- /dev/null +++ b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/section/UsMt.java @@ -0,0 +1,142 @@ +package com.iab.gpp.encoder.section; + +import java.util.ArrayList; +import java.util.List; +import com.iab.gpp.encoder.field.UsMtField; +import com.iab.gpp.encoder.segment.EncodableSegment; +import com.iab.gpp.encoder.segment.UsMtCoreSegment; +import com.iab.gpp.encoder.segment.UsMtGpcSegment; + +public class UsMt extends AbstractLazilyEncodableSection { + + public static int ID = 14; + public static int VERSION = 1; + public static String NAME = "usmt"; + + public UsMt() { + super(); + } + + public UsMt(String encodedString) { + super(); + decode(encodedString); + } + + @Override + public int getId() { + return UsMt.ID; + } + + @Override + public String getName() { + return UsMt.NAME; + } + + @Override + public int getVersion() { + return UsMt.VERSION; + } + + @Override + protected List initializeSegments() { + List segments = new ArrayList<>(); + segments.add(new UsMtCoreSegment()); + segments.add(new UsMtGpcSegment()); + return segments; + } + + @Override + protected List decodeSection(String encodedString) { + List segments = initializeSegments(); + + if(encodedString != null && !encodedString.isEmpty()) { + String[] encodedSegments = encodedString.split("\\."); + + if(encodedSegments.length > 0) { + segments.get(0).decode(encodedSegments[0]); + } + + if(encodedSegments.length > 1) { + segments.get(1).setFieldValue(UsMtField.GPC_SEGMENT_INCLUDED, true); + segments.get(1).decode(encodedSegments[1]); + } else { + segments.get(1).setFieldValue(UsMtField.GPC_SEGMENT_INCLUDED, false); + } + } + + return segments; + } + + @Override + protected String encodeSection(List segments) { + List encodedSegments = new ArrayList<>(); + + if(!segments.isEmpty()) { + encodedSegments.add(segments.get(0).encode()); + if(segments.size() >= 2 && segments.get(1).getFieldValue(UsMtField.GPC_SEGMENT_INCLUDED).equals(true)) { + encodedSegments.add(segments.get(1).encode()); + } + } + + return String.join(".", encodedSegments); + } + + + public Integer getSharingNotice() { + return (Integer) this.getFieldValue(UsMtField.SHARING_NOTICE); + } + + public Integer getSaleOptOutNotice() { + return (Integer) this.getFieldValue(UsMtField.SALE_OPT_OUT_NOTICE); + } + + public Integer getTargetedAdvertisingOptOutNotice() { + return (Integer) this.getFieldValue(UsMtField.TARGETED_ADVERTISING_OPT_OUT_NOTICE); + } + + public Integer getSaleOptOut() { + return (Integer) this.getFieldValue(UsMtField.SALE_OPT_OUT); + } + + public Integer getTargetedAdvertisingOptOut() { + return (Integer) this.getFieldValue(UsMtField.TARGETED_ADVERTISING_OPT_OUT); + } + + @SuppressWarnings("unchecked") + public List getSensitiveDataProcessing() { + return (List) this.getFieldValue(UsMtField.SENSITIVE_DATA_PROCESSING); + } + + @SuppressWarnings("unchecked") + public List getKnownChildSensitiveDataConsents() { + return (List) this.getFieldValue(UsMtField.KNOWN_CHILD_SENSITIVE_DATA_CONSENTS); + } + + public Integer getAdditionalDataProcessingConsent() { + return (Integer) this.getFieldValue(UsMtField.ADDITIONAL_DATA_PROCESSING_CONSENT); + } + + public Integer getMspaCoveredTransaction() { + return (Integer) this.getFieldValue(UsMtField.MSPA_COVERED_TRANSACTION); + } + + public Integer getMspaOptOutOptionMode() { + return (Integer) this.getFieldValue(UsMtField.MSPA_OPT_OUT_OPTION_MODE); + } + + public Integer getMspaServiceProviderMode() { + return (Integer) this.getFieldValue(UsMtField.MSPA_SERVICE_PROVIDER_MODE); + } + + public Integer getGpcSegmentType() { + return (Integer) this.getFieldValue(UsMtField.GPC_SEGMENT_TYPE); + } + + public Boolean getGpcSegmentIncluded() { + return (Boolean) this.getFieldValue(UsMtField.GPC_SEGMENT_INCLUDED); + } + + public Boolean getGpc() { + return (Boolean) this.getFieldValue(UsMtField.GPC); + } +} diff --git a/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/section/UsNat.java b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/section/UsNat.java new file mode 100644 index 00000000..a32950d8 --- /dev/null +++ b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/section/UsNat.java @@ -0,0 +1,158 @@ +package com.iab.gpp.encoder.section; + +import java.util.ArrayList; +import java.util.List; +import com.iab.gpp.encoder.field.UsNatField; +import com.iab.gpp.encoder.segment.EncodableSegment; +import com.iab.gpp.encoder.segment.UsNatCoreSegment; +import com.iab.gpp.encoder.segment.UsNatGpcSegment; + +public class UsNat extends AbstractLazilyEncodableSection { + + public static int ID = 7; + public static int VERSION = 1; + public static String NAME = "usnat"; + + public UsNat() { + super(); + } + + public UsNat(String encodedString) { + super(); + decode(encodedString); + } + + @Override + public int getId() { + return UsNat.ID; + } + + @Override + public String getName() { + return UsNat.NAME; + } + + @Override + public int getVersion() { + return UsNat.VERSION; + } + + @Override + protected List initializeSegments() { + List segments = new ArrayList<>(); + segments.add(new UsNatCoreSegment()); + segments.add(new UsNatGpcSegment()); + return segments; + } + + @Override + protected List decodeSection(String encodedString) { + List segments = initializeSegments(); + + if(encodedString != null && !encodedString.isEmpty()) { + String[] encodedSegments = encodedString.split("\\."); + + if(encodedSegments.length > 0) { + segments.get(0).decode(encodedSegments[0]); + } + + if(encodedSegments.length > 1) { + segments.get(1).setFieldValue(UsNatField.GPC_SEGMENT_INCLUDED, true); + segments.get(1).decode(encodedSegments[1]); + } else { + segments.get(1).setFieldValue(UsNatField.GPC_SEGMENT_INCLUDED, false); + } + } + + return segments; + } + + @Override + protected String encodeSection(List segments) { + List encodedSegments = new ArrayList<>(); + + if(!segments.isEmpty()) { + encodedSegments.add(segments.get(0).encode()); + if(segments.size() >= 2 && segments.get(1).getFieldValue(UsNatField.GPC_SEGMENT_INCLUDED).equals(true)) { + encodedSegments.add(segments.get(1).encode()); + } + } + + return String.join(".", encodedSegments); + } + + + public Integer getSharingNotice() { + return (Integer) this.getFieldValue(UsNatField.SHARING_NOTICE); + } + + public Integer getSaleOptOutNotice() { + return (Integer) this.getFieldValue(UsNatField.SALE_OPT_OUT_NOTICE); + } + + public Integer getSharingOptOutNotice() { + return (Integer) this.getFieldValue(UsNatField.SHARING_OPT_OUT_NOTICE); + } + + public Integer getTargetedAdvertisingOptOutNotice() { + return (Integer) this.getFieldValue(UsNatField.TARGETED_ADVERTISING_OPT_OUT_NOTICE); + } + + public Integer getSensitiveDataProcessingOptOutNotice() { + return (Integer) this.getFieldValue(UsNatField.SENSITIVE_DATA_PROCESSING_OPT_OUT_NOTICE); + } + + public Integer getSensitiveDataLimitUseNotice() { + return (Integer) this.getFieldValue(UsNatField.SENSITIVE_DATA_LIMIT_USE_NOTICE); + } + + public Integer getSaleOptOut() { + return (Integer) this.getFieldValue(UsNatField.SALE_OPT_OUT); + } + + public Integer getSharingOptOut() { + return (Integer) this.getFieldValue(UsNatField.SHARING_OPT_OUT); + } + + public Integer getTargetedAdvertisingOptOut() { + return (Integer) this.getFieldValue(UsNatField.TARGETED_ADVERTISING_OPT_OUT); + } + + @SuppressWarnings("unchecked") + public List getSensitiveDataProcessing() { + return (List) this.getFieldValue(UsNatField.SENSITIVE_DATA_PROCESSING); + } + + @SuppressWarnings("unchecked") + public List getKnownChildSensitiveDataConsents() { + return (List) this.getFieldValue(UsNatField.KNOWN_CHILD_SENSITIVE_DATA_CONSENTS); + } + + public Integer getPersonalDataConsents() { + return (Integer) this.getFieldValue(UsNatField.PERSONAL_DATA_CONSENTS); + } + + public Integer getMspaCoveredTransaction() { + return (Integer) this.getFieldValue(UsNatField.MSPA_COVERED_TRANSACTION); + } + + public Integer getMspaOptOutOptionMode() { + return (Integer) this.getFieldValue(UsNatField.MSPA_OPT_OUT_OPTION_MODE); + } + + public Integer getMspaServiceProviderMode() { + return (Integer) this.getFieldValue(UsNatField.MSPA_SERVICE_PROVIDER_MODE); + } + + public Integer getGpcSegmentType() { + return (Integer) this.getFieldValue(UsNatField.GPC_SEGMENT_TYPE); + } + + public Boolean getGpcSegmentIncluded() { + return (Boolean) this.getFieldValue(UsNatField.GPC_SEGMENT_INCLUDED); + } + + public Boolean getGpc() { + return (Boolean) this.getFieldValue(UsNatField.GPC); + } +} diff --git a/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/section/UsNe.java b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/section/UsNe.java new file mode 100644 index 00000000..e8b7b882 --- /dev/null +++ b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/section/UsNe.java @@ -0,0 +1,141 @@ +package com.iab.gpp.encoder.section; + +import java.util.ArrayList; +import java.util.List; +import com.iab.gpp.encoder.field.UsNeField; +import com.iab.gpp.encoder.segment.EncodableSegment; +import com.iab.gpp.encoder.segment.UsNeCoreSegment; +import com.iab.gpp.encoder.segment.UsNeGpcSegment; + +public class UsNe extends AbstractLazilyEncodableSection { + + public static int ID = 19; + public static int VERSION = 1; + public static String NAME = "usne"; + + public UsNe() { + super(); + } + + public UsNe(String encodedString) { + super(); + decode(encodedString); + } + + @Override + public int getId() { + return UsNe.ID; + } + + @Override + public String getName() { + return UsNe.NAME; + } + + @Override + public int getVersion() { + return UsNe.VERSION; + } + + @Override + protected List initializeSegments() { + List segments = new ArrayList<>(); + segments.add(new UsNeCoreSegment()); + segments.add(new UsNeGpcSegment()); + return segments; + } + + @Override + protected List decodeSection(String encodedString) { + List segments = initializeSegments(); + + if(encodedString != null && !encodedString.isEmpty()) { + String[] encodedSegments = encodedString.split("\\."); + + if(encodedSegments.length > 0) { + segments.get(0).decode(encodedSegments[0]); + } + + if(encodedSegments.length > 1) { + segments.get(1).setFieldValue(UsNeField.GPC_SEGMENT_INCLUDED, true); + segments.get(1).decode(encodedSegments[1]); + } else { + segments.get(1).setFieldValue(UsNeField.GPC_SEGMENT_INCLUDED, false); + } + } + + return segments; + } + + @Override + protected String encodeSection(List segments) { + List encodedSegments = new ArrayList<>(); + + if(!segments.isEmpty()) { + encodedSegments.add(segments.get(0).encode()); + if(segments.size() >= 2 && segments.get(1).getFieldValue(UsNeField.GPC_SEGMENT_INCLUDED).equals(true)) { + encodedSegments.add(segments.get(1).encode()); + } + } + + return String.join(".", encodedSegments); + } + + + public Integer getProcessingNotice() { + return (Integer) this.getFieldValue(UsNeField.PROCESSING_NOTICE); + } + + public Integer getSaleOptOutNotice() { + return (Integer) this.getFieldValue(UsNeField.SALE_OPT_OUT_NOTICE); + } + + public Integer getTargetedAdvertisingOptOutNotice() { + return (Integer) this.getFieldValue(UsNeField.TARGETED_ADVERTISING_OPT_OUT_NOTICE); + } + + public Integer getSaleOptOut() { + return (Integer) this.getFieldValue(UsNeField.SALE_OPT_OUT); + } + + public Integer getTargetedAdvertisingOptOut() { + return (Integer) this.getFieldValue(UsNeField.TARGETED_ADVERTISING_OPT_OUT); + } + + @SuppressWarnings("unchecked") + public List getSensitiveDataProcessing() { + return (List) this.getFieldValue(UsNeField.SENSITIVE_DATA_PROCESSING); + } + + public Integer getKnownChildSensitiveDataConsents() { + return (Integer) this.getFieldValue(UsNeField.KNOWN_CHILD_SENSITIVE_DATA_CONSENTS); + } + + public Integer getAdditionalDataProcessingConsent() { + return (Integer) this.getFieldValue(UsNeField.ADDITIONAL_DATA_PROCESSING_CONSENT); + } + + public Integer getMspaCoveredTransaction() { + return (Integer) this.getFieldValue(UsNeField.MSPA_COVERED_TRANSACTION); + } + + public Integer getMspaOptOutOptionMode() { + return (Integer) this.getFieldValue(UsNeField.MSPA_OPT_OUT_OPTION_MODE); + } + + public Integer getMspaServiceProviderMode() { + return (Integer) this.getFieldValue(UsNeField.MSPA_SERVICE_PROVIDER_MODE); + } + + public Integer getGpcSegmentType() { + return (Integer) this.getFieldValue(UsNeField.GPC_SEGMENT_TYPE); + } + + public Boolean getGpcSegmentIncluded() { + return (Boolean) this.getFieldValue(UsNeField.GPC_SEGMENT_INCLUDED); + } + + public Boolean getGpc() { + return (Boolean) this.getFieldValue(UsNeField.GPC); + } +} diff --git a/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/section/UsNh.java b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/section/UsNh.java new file mode 100644 index 00000000..7bf40fe2 --- /dev/null +++ b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/section/UsNh.java @@ -0,0 +1,142 @@ +package com.iab.gpp.encoder.section; + +import java.util.ArrayList; +import java.util.List; +import com.iab.gpp.encoder.field.UsNhField; +import com.iab.gpp.encoder.segment.EncodableSegment; +import com.iab.gpp.encoder.segment.UsNhCoreSegment; +import com.iab.gpp.encoder.segment.UsNhGpcSegment; + +public class UsNh extends AbstractLazilyEncodableSection { + + public static int ID = 20; + public static int VERSION = 1; + public static String NAME = "usnh"; + + public UsNh() { + super(); + } + + public UsNh(String encodedString) { + super(); + decode(encodedString); + } + + @Override + public int getId() { + return UsNh.ID; + } + + @Override + public String getName() { + return UsNh.NAME; + } + + @Override + public int getVersion() { + return UsNh.VERSION; + } + + @Override + protected List initializeSegments() { + List segments = new ArrayList<>(); + segments.add(new UsNhCoreSegment()); + segments.add(new UsNhGpcSegment()); + return segments; + } + + @Override + protected List decodeSection(String encodedString) { + List segments = initializeSegments(); + + if(encodedString != null && !encodedString.isEmpty()) { + String[] encodedSegments = encodedString.split("\\."); + + if(encodedSegments.length > 0) { + segments.get(0).decode(encodedSegments[0]); + } + + if(encodedSegments.length > 1) { + segments.get(1).setFieldValue(UsNhField.GPC_SEGMENT_INCLUDED, true); + segments.get(1).decode(encodedSegments[1]); + } else { + segments.get(1).setFieldValue(UsNhField.GPC_SEGMENT_INCLUDED, false); + } + } + + return segments; + } + + @Override + protected String encodeSection(List segments) { + List encodedSegments = new ArrayList<>(); + + if(!segments.isEmpty()) { + encodedSegments.add(segments.get(0).encode()); + if(segments.size() >= 2 && segments.get(1).getFieldValue(UsNhField.GPC_SEGMENT_INCLUDED).equals(true)) { + encodedSegments.add(segments.get(1).encode()); + } + } + + return String.join(".", encodedSegments); + } + + + public Integer getProcessingNotice() { + return (Integer) this.getFieldValue(UsNhField.PROCESSING_NOTICE); + } + + public Integer getSaleOptOutNotice() { + return (Integer) this.getFieldValue(UsNhField.SALE_OPT_OUT_NOTICE); + } + + public Integer getTargetedAdvertisingOptOutNotice() { + return (Integer) this.getFieldValue(UsNhField.TARGETED_ADVERTISING_OPT_OUT_NOTICE); + } + + public Integer getSaleOptOut() { + return (Integer) this.getFieldValue(UsNhField.SALE_OPT_OUT); + } + + public Integer getTargetedAdvertisingOptOut() { + return (Integer) this.getFieldValue(UsNhField.TARGETED_ADVERTISING_OPT_OUT); + } + + @SuppressWarnings("unchecked") + public List getSensitiveDataProcessing() { + return (List) this.getFieldValue(UsNhField.SENSITIVE_DATA_PROCESSING); + } + + @SuppressWarnings("unchecked") + public List getKnownChildSensitiveDataConsents() { + return (List) this.getFieldValue(UsNhField.KNOWN_CHILD_SENSITIVE_DATA_CONSENTS); + } + + public Integer getAdditionalDataProcessingConsent() { + return (Integer) this.getFieldValue(UsNhField.ADDITIONAL_DATA_PROCESSING_CONSENT); + } + + public Integer getMspaCoveredTransaction() { + return (Integer) this.getFieldValue(UsNhField.MSPA_COVERED_TRANSACTION); + } + + public Integer getMspaOptOutOptionMode() { + return (Integer) this.getFieldValue(UsNhField.MSPA_OPT_OUT_OPTION_MODE); + } + + public Integer getMspaServiceProviderMode() { + return (Integer) this.getFieldValue(UsNhField.MSPA_SERVICE_PROVIDER_MODE); + } + + public Integer getGpcSegmentType() { + return (Integer) this.getFieldValue(UsNhField.GPC_SEGMENT_TYPE); + } + + public Boolean getGpcSegmentIncluded() { + return (Boolean) this.getFieldValue(UsNhField.GPC_SEGMENT_INCLUDED); + } + + public Boolean getGpc() { + return (Boolean) this.getFieldValue(UsNhField.GPC); + } +} diff --git a/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/section/UsNj.java b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/section/UsNj.java new file mode 100644 index 00000000..f24e043f --- /dev/null +++ b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/section/UsNj.java @@ -0,0 +1,142 @@ +package com.iab.gpp.encoder.section; + +import java.util.ArrayList; +import java.util.List; +import com.iab.gpp.encoder.field.UsNjField; +import com.iab.gpp.encoder.segment.EncodableSegment; +import com.iab.gpp.encoder.segment.UsNjCoreSegment; +import com.iab.gpp.encoder.segment.UsNjGpcSegment; + +public class UsNj extends AbstractLazilyEncodableSection { + + public static int ID = 21; + public static int VERSION = 1; + public static String NAME = "usnj"; + + public UsNj() { + super(); + } + + public UsNj(String encodedString) { + super(); + decode(encodedString); + } + + @Override + public int getId() { + return UsNj.ID; + } + + @Override + public String getName() { + return UsNj.NAME; + } + + @Override + public int getVersion() { + return UsNj.VERSION; + } + + @Override + protected List initializeSegments() { + List segments = new ArrayList<>(); + segments.add(new UsNjCoreSegment()); + segments.add(new UsNjGpcSegment()); + return segments; + } + + @Override + protected List decodeSection(String encodedString) { + List segments = initializeSegments(); + + if(encodedString != null && !encodedString.isEmpty()) { + String[] encodedSegments = encodedString.split("\\."); + + if(encodedSegments.length > 0) { + segments.get(0).decode(encodedSegments[0]); + } + + if(encodedSegments.length > 1) { + segments.get(1).setFieldValue(UsNjField.GPC_SEGMENT_INCLUDED, true); + segments.get(1).decode(encodedSegments[1]); + } else { + segments.get(1).setFieldValue(UsNjField.GPC_SEGMENT_INCLUDED, false); + } + } + + return segments; + } + + @Override + protected String encodeSection(List segments) { + List encodedSegments = new ArrayList<>(); + + if(!segments.isEmpty()) { + encodedSegments.add(segments.get(0).encode()); + if(segments.size() >= 2 && segments.get(1).getFieldValue(UsNjField.GPC_SEGMENT_INCLUDED).equals(true)) { + encodedSegments.add(segments.get(1).encode()); + } + } + + return String.join(".", encodedSegments); + } + + + public Integer getProcessingNotice() { + return (Integer) this.getFieldValue(UsNjField.PROCESSING_NOTICE); + } + + public Integer getSaleOptOutNotice() { + return (Integer) this.getFieldValue(UsNjField.SALE_OPT_OUT_NOTICE); + } + + public Integer getTargetedAdvertisingOptOutNotice() { + return (Integer) this.getFieldValue(UsNjField.TARGETED_ADVERTISING_OPT_OUT_NOTICE); + } + + public Integer getSaleOptOut() { + return (Integer) this.getFieldValue(UsNjField.SALE_OPT_OUT); + } + + public Integer getTargetedAdvertisingOptOut() { + return (Integer) this.getFieldValue(UsNjField.TARGETED_ADVERTISING_OPT_OUT); + } + + @SuppressWarnings("unchecked") + public List getSensitiveDataProcessing() { + return (List) this.getFieldValue(UsNjField.SENSITIVE_DATA_PROCESSING); + } + + @SuppressWarnings("unchecked") + public List getKnownChildSensitiveDataConsents() { + return (List) this.getFieldValue(UsNjField.KNOWN_CHILD_SENSITIVE_DATA_CONSENTS); + } + + public Integer getAdditionalDataProcessingConsent() { + return (Integer) this.getFieldValue(UsNjField.ADDITIONAL_DATA_PROCESSING_CONSENT); + } + + public Integer getMspaCoveredTransaction() { + return (Integer) this.getFieldValue(UsNjField.MSPA_COVERED_TRANSACTION); + } + + public Integer getMspaOptOutOptionMode() { + return (Integer) this.getFieldValue(UsNjField.MSPA_OPT_OUT_OPTION_MODE); + } + + public Integer getMspaServiceProviderMode() { + return (Integer) this.getFieldValue(UsNjField.MSPA_SERVICE_PROVIDER_MODE); + } + + public Integer getGpcSegmentType() { + return (Integer) this.getFieldValue(UsNjField.GPC_SEGMENT_TYPE); + } + + public Boolean getGpcSegmentIncluded() { + return (Boolean) this.getFieldValue(UsNjField.GPC_SEGMENT_INCLUDED); + } + + public Boolean getGpc() { + return (Boolean) this.getFieldValue(UsNjField.GPC); + } +} diff --git a/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/section/UsOr.java b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/section/UsOr.java new file mode 100644 index 00000000..632e455f --- /dev/null +++ b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/section/UsOr.java @@ -0,0 +1,142 @@ +package com.iab.gpp.encoder.section; + +import java.util.ArrayList; +import java.util.List; +import com.iab.gpp.encoder.field.UsOrField; +import com.iab.gpp.encoder.segment.EncodableSegment; +import com.iab.gpp.encoder.segment.UsOrCoreSegment; +import com.iab.gpp.encoder.segment.UsOrGpcSegment; + +public class UsOr extends AbstractLazilyEncodableSection { + + public static int ID = 15; + public static int VERSION = 1; + public static String NAME = "usor"; + + public UsOr() { + super(); + } + + public UsOr(String encodedString) { + super(); + decode(encodedString); + } + + @Override + public int getId() { + return UsOr.ID; + } + + @Override + public String getName() { + return UsOr.NAME; + } + + @Override + public int getVersion() { + return UsOr.VERSION; + } + + @Override + protected List initializeSegments() { + List segments = new ArrayList<>(); + segments.add(new UsOrCoreSegment()); + segments.add(new UsOrGpcSegment()); + return segments; + } + + @Override + protected List decodeSection(String encodedString) { + List segments = initializeSegments(); + + if(encodedString != null && !encodedString.isEmpty()) { + String[] encodedSegments = encodedString.split("\\."); + + if(encodedSegments.length > 0) { + segments.get(0).decode(encodedSegments[0]); + } + + if(encodedSegments.length > 1) { + segments.get(1).setFieldValue(UsOrField.GPC_SEGMENT_INCLUDED, true); + segments.get(1).decode(encodedSegments[1]); + } else { + segments.get(1).setFieldValue(UsOrField.GPC_SEGMENT_INCLUDED, false); + } + } + + return segments; + } + + @Override + protected String encodeSection(List segments) { + List encodedSegments = new ArrayList<>(); + + if(!segments.isEmpty()) { + encodedSegments.add(segments.get(0).encode()); + if(segments.size() >= 2 && segments.get(1).getFieldValue(UsOrField.GPC_SEGMENT_INCLUDED).equals(true)) { + encodedSegments.add(segments.get(1).encode()); + } + } + + return String.join(".", encodedSegments); + } + + + public Integer getProcessingNotice() { + return (Integer) this.getFieldValue(UsOrField.PROCESSING_NOTICE); + } + + public Integer getSaleOptOutNotice() { + return (Integer) this.getFieldValue(UsOrField.SALE_OPT_OUT_NOTICE); + } + + public Integer getTargetedAdvertisingOptOutNotice() { + return (Integer) this.getFieldValue(UsOrField.TARGETED_ADVERTISING_OPT_OUT_NOTICE); + } + + public Integer getSaleOptOut() { + return (Integer) this.getFieldValue(UsOrField.SALE_OPT_OUT); + } + + public Integer getTargetedAdvertisingOptOut() { + return (Integer) this.getFieldValue(UsOrField.TARGETED_ADVERTISING_OPT_OUT); + } + + @SuppressWarnings("unchecked") + public List getSensitiveDataProcessing() { + return (List) this.getFieldValue(UsOrField.SENSITIVE_DATA_PROCESSING); + } + + @SuppressWarnings("unchecked") + public List getKnownChildSensitiveDataConsents() { + return (List) this.getFieldValue(UsOrField.KNOWN_CHILD_SENSITIVE_DATA_CONSENTS); + } + + public Integer getAdditionalDataProcessingConsent() { + return (Integer) this.getFieldValue(UsOrField.ADDITIONAL_DATA_PROCESSING_CONSENT); + } + + public Integer getMspaCoveredTransaction() { + return (Integer) this.getFieldValue(UsOrField.MSPA_COVERED_TRANSACTION); + } + + public Integer getMspaOptOutOptionMode() { + return (Integer) this.getFieldValue(UsOrField.MSPA_OPT_OUT_OPTION_MODE); + } + + public Integer getMspaServiceProviderMode() { + return (Integer) this.getFieldValue(UsOrField.MSPA_SERVICE_PROVIDER_MODE); + } + + public Integer getGpcSegmentType() { + return (Integer) this.getFieldValue(UsOrField.GPC_SEGMENT_TYPE); + } + + public Boolean getGpcSegmentIncluded() { + return (Boolean) this.getFieldValue(UsOrField.GPC_SEGMENT_INCLUDED); + } + + public Boolean getGpc() { + return (Boolean) this.getFieldValue(UsOrField.GPC); + } +} diff --git a/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/section/UsTn.java b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/section/UsTn.java new file mode 100644 index 00000000..2403f09d --- /dev/null +++ b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/section/UsTn.java @@ -0,0 +1,141 @@ +package com.iab.gpp.encoder.section; + +import java.util.ArrayList; +import java.util.List; +import com.iab.gpp.encoder.field.UsTnField; +import com.iab.gpp.encoder.segment.EncodableSegment; +import com.iab.gpp.encoder.segment.UsTnCoreSegment; +import com.iab.gpp.encoder.segment.UsTnGpcSegment; + +public class UsTn extends AbstractLazilyEncodableSection { + + public static int ID = 22; + public static int VERSION = 1; + public static String NAME = "ustn"; + + public UsTn() { + super(); + } + + public UsTn(String encodedString) { + super(); + decode(encodedString); + } + + @Override + public int getId() { + return UsTn.ID; + } + + @Override + public String getName() { + return UsTn.NAME; + } + + @Override + public int getVersion() { + return UsTn.VERSION; + } + + @Override + protected List initializeSegments() { + List segments = new ArrayList<>(); + segments.add(new UsTnCoreSegment()); + segments.add(new UsTnGpcSegment()); + return segments; + } + + @Override + protected List decodeSection(String encodedString) { + List segments = initializeSegments(); + + if(encodedString != null && !encodedString.isEmpty()) { + String[] encodedSegments = encodedString.split("\\."); + + if(encodedSegments.length > 0) { + segments.get(0).decode(encodedSegments[0]); + } + + if(encodedSegments.length > 1) { + segments.get(1).setFieldValue(UsTnField.GPC_SEGMENT_INCLUDED, true); + segments.get(1).decode(encodedSegments[1]); + } else { + segments.get(1).setFieldValue(UsTnField.GPC_SEGMENT_INCLUDED, false); + } + } + + return segments; + } + + @Override + protected String encodeSection(List segments) { + List encodedSegments = new ArrayList<>(); + + if(!segments.isEmpty()) { + encodedSegments.add(segments.get(0).encode()); + if(segments.size() >= 2 && segments.get(1).getFieldValue(UsTnField.GPC_SEGMENT_INCLUDED).equals(true)) { + encodedSegments.add(segments.get(1).encode()); + } + } + + return String.join(".", encodedSegments); + } + + + public Integer getProcessingNotice() { + return (Integer) this.getFieldValue(UsTnField.PROCESSING_NOTICE); + } + + public Integer getSaleOptOutNotice() { + return (Integer) this.getFieldValue(UsTnField.SALE_OPT_OUT_NOTICE); + } + + public Integer getTargetedAdvertisingOptOutNotice() { + return (Integer) this.getFieldValue(UsTnField.TARGETED_ADVERTISING_OPT_OUT_NOTICE); + } + + public Integer getSaleOptOut() { + return (Integer) this.getFieldValue(UsTnField.SALE_OPT_OUT); + } + + public Integer getTargetedAdvertisingOptOut() { + return (Integer) this.getFieldValue(UsTnField.TARGETED_ADVERTISING_OPT_OUT); + } + + @SuppressWarnings("unchecked") + public List getSensitiveDataProcessing() { + return (List) this.getFieldValue(UsTnField.SENSITIVE_DATA_PROCESSING); + } + + public Integer getKnownChildSensitiveDataConsents() { + return (Integer) this.getFieldValue(UsTnField.KNOWN_CHILD_SENSITIVE_DATA_CONSENTS); + } + + public Integer getAdditionalDataProcessingConsent() { + return (Integer) this.getFieldValue(UsTnField.ADDITIONAL_DATA_PROCESSING_CONSENT); + } + + public Integer getMspaCoveredTransaction() { + return (Integer) this.getFieldValue(UsTnField.MSPA_COVERED_TRANSACTION); + } + + public Integer getMspaOptOutOptionMode() { + return (Integer) this.getFieldValue(UsTnField.MSPA_OPT_OUT_OPTION_MODE); + } + + public Integer getMspaServiceProviderMode() { + return (Integer) this.getFieldValue(UsTnField.MSPA_SERVICE_PROVIDER_MODE); + } + + public Integer getGpcSegmentType() { + return (Integer) this.getFieldValue(UsTnField.GPC_SEGMENT_TYPE); + } + + public Boolean getGpcSegmentIncluded() { + return (Boolean) this.getFieldValue(UsTnField.GPC_SEGMENT_INCLUDED); + } + + public Boolean getGpc() { + return (Boolean) this.getFieldValue(UsTnField.GPC); + } +} diff --git a/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/section/UsTx.java b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/section/UsTx.java new file mode 100644 index 00000000..ea4fc86e --- /dev/null +++ b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/section/UsTx.java @@ -0,0 +1,141 @@ +package com.iab.gpp.encoder.section; + +import java.util.ArrayList; +import java.util.List; +import com.iab.gpp.encoder.field.UsTxField; +import com.iab.gpp.encoder.segment.EncodableSegment; +import com.iab.gpp.encoder.segment.UsTxCoreSegment; +import com.iab.gpp.encoder.segment.UsTxGpcSegment; + +public class UsTx extends AbstractLazilyEncodableSection { + + public static int ID = 16; + public static int VERSION = 1; + public static String NAME = "ustx"; + + public UsTx() { + super(); + } + + public UsTx(String encodedString) { + super(); + decode(encodedString); + } + + @Override + public int getId() { + return UsTx.ID; + } + + @Override + public String getName() { + return UsTx.NAME; + } + + @Override + public int getVersion() { + return UsTx.VERSION; + } + + @Override + protected List initializeSegments() { + List segments = new ArrayList<>(); + segments.add(new UsTxCoreSegment()); + segments.add(new UsTxGpcSegment()); + return segments; + } + + @Override + protected List decodeSection(String encodedString) { + List segments = initializeSegments(); + + if(encodedString != null && !encodedString.isEmpty()) { + String[] encodedSegments = encodedString.split("\\."); + + if(encodedSegments.length > 0) { + segments.get(0).decode(encodedSegments[0]); + } + + if(encodedSegments.length > 1) { + segments.get(1).setFieldValue(UsTxField.GPC_SEGMENT_INCLUDED, true); + segments.get(1).decode(encodedSegments[1]); + } else { + segments.get(1).setFieldValue(UsTxField.GPC_SEGMENT_INCLUDED, false); + } + } + + return segments; + } + + @Override + protected String encodeSection(List segments) { + List encodedSegments = new ArrayList<>(); + + if(!segments.isEmpty()) { + encodedSegments.add(segments.get(0).encode()); + if(segments.size() >= 2 && segments.get(1).getFieldValue(UsTxField.GPC_SEGMENT_INCLUDED).equals(true)) { + encodedSegments.add(segments.get(1).encode()); + } + } + + return String.join(".", encodedSegments); + } + + + public Integer getProcessingNotice() { + return (Integer) this.getFieldValue(UsTxField.PROCESSING_NOTICE); + } + + public Integer getSaleOptOutNotice() { + return (Integer) this.getFieldValue(UsTxField.SALE_OPT_OUT_NOTICE); + } + + public Integer getTargetedAdvertisingOptOutNotice() { + return (Integer) this.getFieldValue(UsTxField.TARGETED_ADVERTISING_OPT_OUT_NOTICE); + } + + public Integer getSaleOptOut() { + return (Integer) this.getFieldValue(UsTxField.SALE_OPT_OUT); + } + + public Integer getTargetedAdvertisingOptOut() { + return (Integer) this.getFieldValue(UsTxField.TARGETED_ADVERTISING_OPT_OUT); + } + + @SuppressWarnings("unchecked") + public List getSensitiveDataProcessing() { + return (List) this.getFieldValue(UsTxField.SENSITIVE_DATA_PROCESSING); + } + + public Integer getKnownChildSensitiveDataConsents() { + return (Integer) this.getFieldValue(UsTxField.KNOWN_CHILD_SENSITIVE_DATA_CONSENTS); + } + + public Integer getAdditionalDataProcessingConsent() { + return (Integer) this.getFieldValue(UsTxField.ADDITIONAL_DATA_PROCESSING_CONSENT); + } + + public Integer getMspaCoveredTransaction() { + return (Integer) this.getFieldValue(UsTxField.MSPA_COVERED_TRANSACTION); + } + + public Integer getMspaOptOutOptionMode() { + return (Integer) this.getFieldValue(UsTxField.MSPA_OPT_OUT_OPTION_MODE); + } + + public Integer getMspaServiceProviderMode() { + return (Integer) this.getFieldValue(UsTxField.MSPA_SERVICE_PROVIDER_MODE); + } + + public Integer getGpcSegmentType() { + return (Integer) this.getFieldValue(UsTxField.GPC_SEGMENT_TYPE); + } + + public Boolean getGpcSegmentIncluded() { + return (Boolean) this.getFieldValue(UsTxField.GPC_SEGMENT_INCLUDED); + } + + public Boolean getGpc() { + return (Boolean) this.getFieldValue(UsTxField.GPC); + } +} diff --git a/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/section/UsUt.java b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/section/UsUt.java new file mode 100644 index 00000000..1c605fec --- /dev/null +++ b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/section/UsUt.java @@ -0,0 +1,119 @@ +package com.iab.gpp.encoder.section; + +import java.util.ArrayList; +import java.util.List; +import com.iab.gpp.encoder.field.UsUtField; +import com.iab.gpp.encoder.segment.EncodableSegment; +import com.iab.gpp.encoder.segment.UsUtCoreSegment; + +public class UsUt extends AbstractLazilyEncodableSection { + + public static int ID = 11; + public static int VERSION = 1; + public static String NAME = "usut"; + + public UsUt() { + super(); + } + + public UsUt(String encodedString) { + super(); + decode(encodedString); + } + + @Override + public int getId() { + return UsUt.ID; + } + + @Override + public String getName() { + return UsUt.NAME; + } + + @Override + public int getVersion() { + return UsUt.VERSION; + } + + @Override + protected List initializeSegments() { + List segments = new ArrayList<>(); + segments.add(new UsUtCoreSegment()); + return segments; + } + + @Override + protected List decodeSection(String encodedString) { + List segments = initializeSegments(); + + if(encodedString != null && !encodedString.isEmpty()) { + String[] encodedSegments = encodedString.split("\\."); + + for(int i=0; i i) { + segments.get(i).decode(encodedSegments[i]); + } + } + } + + return segments; + } + + @Override + protected String encodeSection(List segments) { + List encodedSegments = new ArrayList<>(); + for(EncodableSegment segment : segments) { + encodedSegments.add(segment.encode()); + } + return String.join(".", encodedSegments); + } + + + public Integer getSharingNotice() { + return (Integer) this.getFieldValue(UsUtField.SHARING_NOTICE); + } + + public Integer getSaleOptOutNotice() { + return (Integer) this.getFieldValue(UsUtField.SALE_OPT_OUT_NOTICE); + } + + public Integer getTargetedAdvertisingOptOutNotice() { + return (Integer) this.getFieldValue(UsUtField.TARGETED_ADVERTISING_OPT_OUT_NOTICE); + } + + public Integer getSensitiveDataProcessingOptOutNotice() { + return (Integer) this.getFieldValue(UsUtField.SENSITIVE_DATA_PROCESSING_OPT_OUT_NOTICE); + } + + public Integer getSaleOptOut() { + return (Integer) this.getFieldValue(UsUtField.SALE_OPT_OUT); + } + + public Integer getTargetedAdvertisingOptOut() { + return (Integer) this.getFieldValue(UsUtField.TARGETED_ADVERTISING_OPT_OUT); + } + + @SuppressWarnings("unchecked") + public List getSensitiveDataProcessing() { + return (List) this.getFieldValue(UsUtField.SENSITIVE_DATA_PROCESSING); + } + + public Integer getKnownChildSensitiveDataConsents() { + return (Integer) this.getFieldValue(UsUtField.KNOWN_CHILD_SENSITIVE_DATA_CONSENTS); + } + + public Integer getMspaCoveredTransaction() { + return (Integer) this.getFieldValue(UsUtField.MSPA_COVERED_TRANSACTION); + } + + public Integer getMspaOptOutOptionMode() { + return (Integer) this.getFieldValue(UsUtField.MSPA_OPT_OUT_OPTION_MODE); + } + + public Integer getMspaServiceProviderMode() { + return (Integer) this.getFieldValue(UsUtField.MSPA_SERVICE_PROVIDER_MODE); + } + + +} diff --git a/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/section/UsVa.java b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/section/UsVa.java new file mode 100644 index 00000000..568c6575 --- /dev/null +++ b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/section/UsVa.java @@ -0,0 +1,113 @@ +package com.iab.gpp.encoder.section; + +import java.util.ArrayList; +import java.util.List; +import com.iab.gpp.encoder.field.UsVaField; +import com.iab.gpp.encoder.segment.EncodableSegment; +import com.iab.gpp.encoder.segment.UsVaCoreSegment; + +public class UsVa extends AbstractLazilyEncodableSection { + + public static int ID = 9; + public static int VERSION = 1; + public static String NAME = "usva"; + + public UsVa() { + super(); + } + + public UsVa(String encodedString) { + super(); + decode(encodedString); + } + + @Override + public int getId() { + return UsVa.ID; + } + + @Override + public String getName() { + return UsVa.NAME; + } + + @Override + public int getVersion() { + return UsVa.VERSION; + } + + @Override + protected List initializeSegments() { + List segments = new ArrayList<>(); + segments.add(new UsVaCoreSegment()); + return segments; + } + + @Override + protected List decodeSection(String encodedString) { + List segments = initializeSegments(); + + if(encodedString != null && !encodedString.isEmpty()) { + String[] encodedSegments = encodedString.split("\\."); + + for (int i = 0; i < segments.size(); i++) { + if (encodedSegments.length > i) { + segments.get(i).decode(encodedSegments[i]); + } + } + } + + return segments; + } + + @Override + protected String encodeSection(List segments) { + List encodedSegments = new ArrayList<>(); + for (EncodableSegment segment : segments) { + encodedSegments.add(segment.encode()); + } + return String.join(".", encodedSegments); + } + + + public Integer getSharingNotice() { + return (Integer) this.getFieldValue(UsVaField.SHARING_NOTICE); + } + + public Integer getSaleOptOutNotice() { + return (Integer) this.getFieldValue(UsVaField.SALE_OPT_OUT_NOTICE); + } + + public Integer getTargetedAdvertisingOptOutNotice() { + return (Integer) this.getFieldValue(UsVaField.TARGETED_ADVERTISING_OPT_OUT_NOTICE); + } + + public Integer getSaleOptOut() { + return (Integer) this.getFieldValue(UsVaField.SALE_OPT_OUT); + } + + public Integer getTargetedAdvertisingOptOut() { + return (Integer) this.getFieldValue(UsVaField.TARGETED_ADVERTISING_OPT_OUT); + } + + @SuppressWarnings("unchecked") + public List getSensitiveDataProcessing() { + return (List) this.getFieldValue(UsVaField.SENSITIVE_DATA_PROCESSING); + } + + public Integer getKnownChildSensitiveDataConsents() { + return (Integer) this.getFieldValue(UsVaField.KNOWN_CHILD_SENSITIVE_DATA_CONSENTS); + } + + public Integer getMspaCoveredTransaction() { + return (Integer) this.getFieldValue(UsVaField.MSPA_COVERED_TRANSACTION); + } + + public Integer getMspaOptOutOptionMode() { + return (Integer) this.getFieldValue(UsVaField.MSPA_OPT_OUT_OPTION_MODE); + } + + public Integer getMspaServiceProviderMode() { + return (Integer) this.getFieldValue(UsVaField.MSPA_SERVICE_PROVIDER_MODE); + } +} diff --git a/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/section/UspV1.java b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/section/UspV1.java index 2ef2e4bc..e70261e4 100644 --- a/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/section/UspV1.java +++ b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/section/UspV1.java @@ -1,82 +1,84 @@ package com.iab.gpp.encoder.section; -import java.util.HashMap; -import com.iab.gpp.encoder.datatype.encoder.Base64UrlEncoder; -import com.iab.gpp.encoder.error.DecodingException; -import com.iab.gpp.encoder.error.EncodingException; -import com.iab.gpp.encoder.datatype.EncodableFixedInteger; +import java.util.ArrayList; +import java.util.List; import com.iab.gpp.encoder.field.UspV1Field; +import com.iab.gpp.encoder.segment.EncodableSegment; +import com.iab.gpp.encoder.segment.UspV1CoreSegment; -public class UspV1 extends AbstractEncodableBitStringSection { +public class UspV1 extends AbstractLazilyEncodableSection { + public static int ID = 6; public static int VERSION = 1; public static String NAME = "uspv1"; public UspV1() { - initFields(); + super(); } - public UspV1(String encodedString) throws DecodingException { - initFields(); - - if (encodedString != null && encodedString.length() > 0) { - this.decode(encodedString); - } + public UspV1(String encodedString) { + super(); + decode(encodedString); } - private void initFields() { - fields = new HashMap<>(); - fields.put(UspV1Field.VERSION, new EncodableFixedInteger(6, UspV1.VERSION)); - fields.put(UspV1Field.NOTICE, new EncodableFixedInteger(2)); - fields.put(UspV1Field.OPT_OUT_SALE, new EncodableFixedInteger(2)); - fields.put(UspV1Field.LSPA_COVERED, new EncodableFixedInteger(2)); - - //@formatter:off - fieldOrder = new String[] { - UspV1Field.VERSION, - UspV1Field.NOTICE, - UspV1Field.OPT_OUT_SALE, - UspV1Field.LSPA_COVERED, - }; - //@formatter:on + @Override + public int getId() { + return UspV1.ID; } @Override - public String encode() throws EncodingException { - String bitString = this.encodeToBitString(); - String encodedString = Base64UrlEncoder.encode(bitString); - return encodedString; + public String getName() { + return UspV1.NAME; } @Override - public void decode(String encodedString) throws DecodingException { - String bitString = Base64UrlEncoder.decode(encodedString); - this.decodeFromBitString(bitString); + public int getVersion() { + return UspV1.VERSION; } @Override - public int getId() { - return UspV1.ID; + protected List initializeSegments() { + List segments = new ArrayList<>(); + segments.add(new UspV1CoreSegment()); + return segments; } - + @Override - public String getName() { - return UspV1.NAME; + protected List decodeSection(String encodedString) { + List segments = initializeSegments(); + + if(encodedString != null && !encodedString.isEmpty()) { + String[] encodedSegments = encodedString.split("\\."); + + for(int i=0; i i) { + segments.get(i).decode(encodedSegments[i]); + } + } + } + + return segments; } - public Integer getVersion() { - return (Integer) this.fields.get(UspV1Field.VERSION).getValue(); + @Override + protected String encodeSection(List segments) { + List encodedSegments = new ArrayList<>(); + for(EncodableSegment segment : segments) { + encodedSegments.add(segment.encode()); + } + return String.join(".", encodedSegments); } - public Integer getNotice() { - return (Integer) fields.get(UspV1Field.NOTICE).getValue(); + + public Character getNotice() { + return (Character) this.getFieldValue(UspV1Field.NOTICE); } - public Integer getOptOutSale() { - return (Integer) fields.get(UspV1Field.OPT_OUT_SALE).getValue(); + public Character getOptOutSale() { + return (Character) this.getFieldValue(UspV1Field.OPT_OUT_SALE); } - public Integer getLspaCovered() { - return (Integer) fields.get(UspV1Field.LSPA_COVERED).getValue(); + public Character getLspaCovered() { + return (Character) this.getFieldValue(UspV1Field.LSPA_COVERED); } } diff --git a/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/section/UspV1Legacy.java b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/section/UspV1Legacy.java deleted file mode 100644 index d7fd7b33..00000000 --- a/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/section/UspV1Legacy.java +++ /dev/null @@ -1,101 +0,0 @@ -package com.iab.gpp.encoder.section; - -import java.util.HashMap; -import java.util.Map; -import com.iab.gpp.encoder.field.UspV1LegacyField; - -public class UspV1Legacy implements EncodableSection { - public static int ID = 6; - public static int VERSION = 1; - public static String NAME = "uspv1"; - - protected Map fields; - - public UspV1Legacy() { - initFields(); - } - - public UspV1Legacy(String encodedString) { - initFields(); - - if (encodedString != null && encodedString.length() > 0) { - this.decode(encodedString); - } - } - - private void initFields() { - fields = new HashMap<>(); - fields.put(UspV1LegacyField.VERSION, UspV1Legacy.VERSION); - fields.put(UspV1LegacyField.NOTICE, "-"); - fields.put(UspV1LegacyField.OPT_OUT_SALE, "-"); - fields.put(UspV1LegacyField.LSPA_COVERED, "-"); - } - - @Override - public boolean hasField(String fieldName) { - return this.fields.containsKey(fieldName); - } - - @Override - public Object getFieldValue(String fieldName) { - if (this.fields.containsKey(fieldName)) { - return this.fields.get(fieldName); - } else { - return null; - } - } - - @Override - public void setFieldValue(String fieldName, Object value) { - if (this.fields.containsKey(fieldName)) { - this.fields.put(fieldName, value); - } else { - throw new Error(fieldName + " not found"); - } - } - - @Override - public String encode() { - String str = ""; - str += this.getFieldValue(UspV1LegacyField.VERSION); - str += this.getFieldValue(UspV1LegacyField.NOTICE); - str += this.getFieldValue(UspV1LegacyField.OPT_OUT_SALE); - str += this.getFieldValue(UspV1LegacyField.LSPA_COVERED); - return str; - } - - @Override - public void decode(String encodedString) { - // TODO: validate - this.setFieldValue(UspV1LegacyField.VERSION, Integer.parseInt(String.valueOf(encodedString.charAt(0)))); - this.setFieldValue(UspV1LegacyField.NOTICE, String.valueOf(encodedString.charAt(1))); - this.setFieldValue(UspV1LegacyField.OPT_OUT_SALE, String.valueOf(encodedString.charAt(2))); - this.setFieldValue(UspV1LegacyField.LSPA_COVERED, String.valueOf(encodedString.charAt(3))); - } - - @Override - public int getId() { - return UspV1Legacy.ID; - } - - @Override - public String getName() { - return UspV1Legacy.NAME; - } - - public Integer getVersion() { - return (Integer) this.fields.get(UspV1LegacyField.VERSION); - } - - public String getNotice() { - return (String) fields.get(UspV1LegacyField.NOTICE); - } - - public String getOptOutSale() { - return (String) fields.get(UspV1LegacyField.OPT_OUT_SALE); - } - - public String getLspaCovered() { - return (String) fields.get(UspV1LegacyField.LSPA_COVERED); - } -} diff --git a/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/segment/AbstractLazilyEncodableSegment.java b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/segment/AbstractLazilyEncodableSegment.java new file mode 100644 index 00000000..8726e16d --- /dev/null +++ b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/segment/AbstractLazilyEncodableSegment.java @@ -0,0 +1,76 @@ +package com.iab.gpp.encoder.segment; + +import com.iab.gpp.encoder.error.InvalidFieldException; +import com.iab.gpp.encoder.field.Fields; + +public abstract class AbstractLazilyEncodableSegment> implements EncodableSegment { + + protected T fields; + + private String encodedString = null; + + private boolean dirty = false; + private boolean decoded = true; + + public AbstractLazilyEncodableSegment() { + this.fields = initializeFields(); + } + + protected abstract T initializeFields(); + + protected abstract String encodeSegment(T fields); + + protected abstract void decodeSegment(String encodedString, T Fields); + + public boolean hasField(String fieldName) { + return this.fields.containsKey(fieldName); + } + + public Object getFieldValue(String fieldName) { + if (!this.decoded) { + this.decodeSegment(this.encodedString, this.fields); + this.dirty = false; + this.decoded = true; + } + + if (this.fields.containsKey(fieldName)) { + return this.fields.get(fieldName).getValue(); + } else { + throw new InvalidFieldException("Invalid field: '" + fieldName + "'"); + } + } + + public void setFieldValue(String fieldName, Object value) { + if (!this.decoded) { + this.decodeSegment(this.encodedString, this.fields); + this.dirty = false; + this.decoded = true; + } + + if (this.fields.containsKey(fieldName)) { + this.fields.get(fieldName).setValue(value); + this.dirty = true; + } else { + throw new InvalidFieldException(fieldName + " not found"); + } + } + + public String encode() { + if (this.encodedString == null || this.encodedString.isEmpty() || this.dirty) { + this.validate(); + this.encodedString = encodeSegment(this.fields); + this.dirty = false; + this.decoded = true; + } + + return this.encodedString; + } + + public void decode(String encodedString) { + this.encodedString = encodedString; + this.dirty = false; + this.decoded = false; + } + + +} diff --git a/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/segment/EncodableSegment.java b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/segment/EncodableSegment.java new file mode 100644 index 00000000..d2363a82 --- /dev/null +++ b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/segment/EncodableSegment.java @@ -0,0 +1,20 @@ +package com.iab.gpp.encoder.segment; + +import java.util.List; + +public interface EncodableSegment { + + List getFieldNames(); + + boolean hasField(String fieldName); + + Object getFieldValue(String fieldName); + + void setFieldValue(String fieldName, Object value); + + String encode(); + + void decode(String encodedString); + + default void validate() {}; +} diff --git a/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/segment/HeaderV1CoreSegment.java b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/segment/HeaderV1CoreSegment.java new file mode 100644 index 00000000..5f944d90 --- /dev/null +++ b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/segment/HeaderV1CoreSegment.java @@ -0,0 +1,63 @@ +package com.iab.gpp.encoder.segment; + +import java.util.ArrayList; +import java.util.List; +import com.iab.gpp.encoder.base64.AbstractBase64UrlEncoder; +import com.iab.gpp.encoder.base64.CompressedBase64UrlEncoder; +import com.iab.gpp.encoder.bitstring.BitStringEncoder; +import com.iab.gpp.encoder.datatype.EncodableFibonacciIntegerRange; +import com.iab.gpp.encoder.datatype.EncodableFixedInteger; +import com.iab.gpp.encoder.error.DecodingException; +import com.iab.gpp.encoder.field.EncodableBitStringFields; +import com.iab.gpp.encoder.field.HeaderV1Field; +import com.iab.gpp.encoder.section.HeaderV1; + +public class HeaderV1CoreSegment extends AbstractLazilyEncodableSegment { + + private AbstractBase64UrlEncoder base64UrlEncoder = CompressedBase64UrlEncoder.getInstance(); + private BitStringEncoder bitStringEncoder = BitStringEncoder.getInstance(); + + public HeaderV1CoreSegment() { + super(); + } + + public HeaderV1CoreSegment(String encodedString) { + super(); + this.decode(encodedString); + } + + @Override + public List getFieldNames() { + return HeaderV1Field.HEADER_CORE_SEGMENT_FIELD_NAMES; + } + + @Override + protected EncodableBitStringFields initializeFields() { + EncodableBitStringFields fields = new EncodableBitStringFields(); + fields.put(HeaderV1Field.ID, new EncodableFixedInteger(6, HeaderV1.ID)); + fields.put(HeaderV1Field.VERSION, new EncodableFixedInteger(6, HeaderV1.VERSION)); + fields.put(HeaderV1Field.SECTION_IDS, new EncodableFibonacciIntegerRange(new ArrayList<>())); + return fields; + } + + @Override + protected String encodeSegment(EncodableBitStringFields fields) { + String bitString = bitStringEncoder.encode(fields, getFieldNames()); + String encodedString = base64UrlEncoder.encode(bitString); + return encodedString; + } + + @Override + protected void decodeSegment(String encodedString, EncodableBitStringFields fields) { + if(encodedString == null || encodedString.isEmpty()) { + this.fields.reset(fields); + } + try { + String bitString = base64UrlEncoder.decode(encodedString); + bitStringEncoder.decode(bitString, getFieldNames(), fields); + } catch (Exception e) { + throw new DecodingException("Unable to decode HeaderV1CoreSegment '" + encodedString + "'", e); + } + } + +} diff --git a/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/segment/TcfCaV1CoreSegment.java b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/segment/TcfCaV1CoreSegment.java new file mode 100644 index 00000000..fbdc9479 --- /dev/null +++ b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/segment/TcfCaV1CoreSegment.java @@ -0,0 +1,89 @@ +package com.iab.gpp.encoder.segment; + +import java.time.ZonedDateTime; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import com.iab.gpp.encoder.base64.AbstractBase64UrlEncoder; +import com.iab.gpp.encoder.base64.CompressedBase64UrlEncoder; +import com.iab.gpp.encoder.bitstring.BitStringEncoder; +import com.iab.gpp.encoder.datatype.EncodableArrayOfFixedIntegerRanges; +import com.iab.gpp.encoder.datatype.EncodableBoolean; +import com.iab.gpp.encoder.datatype.EncodableDatetime; +import com.iab.gpp.encoder.datatype.EncodableFixedBitfield; +import com.iab.gpp.encoder.datatype.EncodableFixedInteger; +import com.iab.gpp.encoder.datatype.EncodableFixedString; +import com.iab.gpp.encoder.datatype.EncodableOptimizedFixedRange; +import com.iab.gpp.encoder.error.DecodingException; +import com.iab.gpp.encoder.field.EncodableBitStringFields; +import com.iab.gpp.encoder.field.TcfCaV1Field; +import com.iab.gpp.encoder.section.TcfCaV1; + +public class TcfCaV1CoreSegment extends AbstractLazilyEncodableSegment { + + private AbstractBase64UrlEncoder base64UrlEncoder = CompressedBase64UrlEncoder.getInstance(); + private BitStringEncoder bitStringEncoder = BitStringEncoder.getInstance(); + + public TcfCaV1CoreSegment() { + super(); + } + + public TcfCaV1CoreSegment(String encodedString) { + super(); + this.decode(encodedString); + } + + @Override + public List getFieldNames() { + return TcfCaV1Field.TCFCAV1_CORE_SEGMENT_FIELD_NAMES; + } + + @Override + protected EncodableBitStringFields initializeFields() { + ZonedDateTime date = ZonedDateTime.now(); + + EncodableBitStringFields fields = new EncodableBitStringFields(); + fields.put(TcfCaV1Field.VERSION, new EncodableFixedInteger(6, TcfCaV1.VERSION)); + fields.put(TcfCaV1Field.CREATED, new EncodableDatetime(date)); + fields.put(TcfCaV1Field.LAST_UPDATED, new EncodableDatetime(date)); + fields.put(TcfCaV1Field.CMP_ID, new EncodableFixedInteger(12, 0)); + fields.put(TcfCaV1Field.CMP_VERSION, new EncodableFixedInteger(12, 0)); + fields.put(TcfCaV1Field.CONSENT_SCREEN, new EncodableFixedInteger(6, 0)); + fields.put(TcfCaV1Field.CONSENT_LANGUAGE, new EncodableFixedString(2, "EN")); + fields.put(TcfCaV1Field.VENDOR_LIST_VERSION, new EncodableFixedInteger(12, 0)); + fields.put(TcfCaV1Field.TCF_POLICY_VERSION, new EncodableFixedInteger(6, 2)); + fields.put(TcfCaV1Field.USE_NON_STANDARD_STACKS, new EncodableBoolean(false)); + fields.put(TcfCaV1Field.SPECIAL_FEATURE_EXPRESS_CONSENT, new EncodableFixedBitfield( + Arrays.asList(false, false, false, false, false, false, false, false, false, false, false, false))); + fields.put(TcfCaV1Field.PURPOSES_EXPRESS_CONSENT, + new EncodableFixedBitfield(Arrays.asList(false, false, false, false, false, false, false, false, false, false, + false, false, false, false, false, false, false, false, false, false, false, false, false, false))); + fields.put(TcfCaV1Field.PURPOSES_IMPLIED_CONSENT, + new EncodableFixedBitfield(Arrays.asList(false, false, false, false, false, false, false, false, false, false, + false, false, false, false, false, false, false, false, false, false, false, false, false, false))); + fields.put(TcfCaV1Field.VENDOR_EXPRESS_CONSENT, new EncodableOptimizedFixedRange(new ArrayList<>())); + fields.put(TcfCaV1Field.VENDOR_IMPLIED_CONSENT, new EncodableOptimizedFixedRange(new ArrayList<>())); + fields.put(TcfCaV1Field.PUB_RESTRICTIONS, new EncodableArrayOfFixedIntegerRanges(6, 2, new ArrayList<>(), false)); + return fields; + } + + @Override + protected String encodeSegment(EncodableBitStringFields fields) { + String bitString = bitStringEncoder.encode(fields, getFieldNames()); + String encodedString = base64UrlEncoder.encode(bitString); + return encodedString; + } + + @Override + protected void decodeSegment(String encodedString, EncodableBitStringFields fields) { + if(encodedString == null || encodedString.isEmpty()) { + this.fields.reset(fields); + } + try { + String bitString = base64UrlEncoder.decode(encodedString); + bitStringEncoder.decode(bitString, getFieldNames(), fields); + } catch (Exception e) { + throw new DecodingException("Unable to decode TcfCaV1CoreSegment '" + encodedString + "'", e); + } + } +} diff --git a/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/segment/TcfCaV1DisclosedVendorsSegment.java b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/segment/TcfCaV1DisclosedVendorsSegment.java new file mode 100644 index 00000000..cbd7e90f --- /dev/null +++ b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/segment/TcfCaV1DisclosedVendorsSegment.java @@ -0,0 +1,60 @@ +package com.iab.gpp.encoder.segment; + +import java.util.ArrayList; +import java.util.List; +import com.iab.gpp.encoder.base64.AbstractBase64UrlEncoder; +import com.iab.gpp.encoder.base64.CompressedBase64UrlEncoder; +import com.iab.gpp.encoder.bitstring.BitStringEncoder; +import com.iab.gpp.encoder.datatype.EncodableFixedInteger; +import com.iab.gpp.encoder.datatype.EncodableOptimizedFixedRange; +import com.iab.gpp.encoder.error.DecodingException; +import com.iab.gpp.encoder.field.EncodableBitStringFields; +import com.iab.gpp.encoder.field.TcfCaV1Field; + +public class TcfCaV1DisclosedVendorsSegment extends AbstractLazilyEncodableSegment { + + private AbstractBase64UrlEncoder base64UrlEncoder = CompressedBase64UrlEncoder.getInstance(); + private BitStringEncoder bitStringEncoder = BitStringEncoder.getInstance(); + + public TcfCaV1DisclosedVendorsSegment() { + super(); + } + + public TcfCaV1DisclosedVendorsSegment(String encodedString) { + super(); + this.decode(encodedString); + } + + @Override + public List getFieldNames() { + return TcfCaV1Field.TCFCAV1_DISCLOSED_VENDORS_SEGMENT_FIELD_NAMES; + } + + @Override + protected EncodableBitStringFields initializeFields() { + EncodableBitStringFields fields = new EncodableBitStringFields(); + fields.put(TcfCaV1Field.DISCLOSED_VENDORS_SEGMENT_TYPE, new EncodableFixedInteger(3, 1)); + fields.put(TcfCaV1Field.DISCLOSED_VENDORS, new EncodableOptimizedFixedRange(new ArrayList<>())); + return fields; + } + + @Override + protected String encodeSegment(EncodableBitStringFields fields) { + String bitString = bitStringEncoder.encode(fields, getFieldNames()); + String encodedString = base64UrlEncoder.encode(bitString); + return encodedString; + } + + @Override + protected void decodeSegment(String encodedString, EncodableBitStringFields fields) { + if (encodedString == null || encodedString.isEmpty()) { + this.fields.reset(fields); + } + try { + String bitString = base64UrlEncoder.decode(encodedString); + bitStringEncoder.decode(bitString, getFieldNames(), fields); + } catch (Exception e) { + throw new DecodingException("Unable to decode TcfCaV1DisclosedVendorsSegment '" + encodedString + "'", e); + } + } +} diff --git a/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/segment/TcfCaV1PublisherPurposesSegment.java b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/segment/TcfCaV1PublisherPurposesSegment.java new file mode 100644 index 00000000..1ab89c0b --- /dev/null +++ b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/segment/TcfCaV1PublisherPurposesSegment.java @@ -0,0 +1,86 @@ +package com.iab.gpp.encoder.segment; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.function.IntSupplier; +import com.iab.gpp.encoder.base64.AbstractBase64UrlEncoder; +import com.iab.gpp.encoder.base64.CompressedBase64UrlEncoder; +import com.iab.gpp.encoder.bitstring.BitStringEncoder; +import com.iab.gpp.encoder.datatype.EncodableFixedBitfield; +import com.iab.gpp.encoder.datatype.EncodableFixedInteger; +import com.iab.gpp.encoder.datatype.EncodableFlexibleBitfield; +import com.iab.gpp.encoder.error.DecodingException; +import com.iab.gpp.encoder.field.EncodableBitStringFields; +import com.iab.gpp.encoder.field.TcfCaV1Field; + +public class TcfCaV1PublisherPurposesSegment extends AbstractLazilyEncodableSegment { + + private AbstractBase64UrlEncoder base64UrlEncoder = CompressedBase64UrlEncoder.getInstance(); + private BitStringEncoder bitStringEncoder = BitStringEncoder.getInstance(); + + public TcfCaV1PublisherPurposesSegment() { + super(); + } + + public TcfCaV1PublisherPurposesSegment(String encodedString) { + super(); + this.decode(encodedString); + } + + @Override + public List getFieldNames() { + return TcfCaV1Field.TCFCAV1_PUBLISHER_PURPOSES_SEGMENT_FIELD_NAMES; + } + + @Override + protected EncodableBitStringFields initializeFields() { + EncodableBitStringFields fields = new EncodableBitStringFields(); + fields.put(TcfCaV1Field.PUB_PURPOSES_SEGMENT_TYPE, new EncodableFixedInteger(3, 3)); + fields.put(TcfCaV1Field.PUB_PURPOSES_EXPRESS_CONSENT, + new EncodableFixedBitfield(Arrays.asList(false, false, false, false, false, false, false, false, false, false, + false, false, false, false, false, false, false, false, false, false, false, false, false, false))); + fields.put(TcfCaV1Field.PUB_PURPOSES_IMPLIED_CONSENT, + new EncodableFixedBitfield(Arrays.asList(false, false, false, false, false, false, false, false, false, false, + false, false, false, false, false, false, false, false, false, false, false, false, false, false))); + + EncodableFixedInteger numCustomPurposes = new EncodableFixedInteger(6, 0); + fields.put(TcfCaV1Field.NUM_CUSTOM_PURPOSES, numCustomPurposes); + + IntSupplier getLengthSupplier = new IntSupplier() { + + @Override + public int getAsInt() { + return numCustomPurposes.getValue(); + } + + }; + + fields.put(TcfCaV1Field.CUSTOM_PURPOSES_EXPRESS_CONSENT, + new EncodableFlexibleBitfield(getLengthSupplier, new ArrayList<>())); + + fields.put(TcfCaV1Field.CUSTOM_PURPOSES_IMPLIED_CONSENT, + new EncodableFlexibleBitfield(getLengthSupplier, new ArrayList<>())); + return fields; + } + + @Override + protected String encodeSegment(EncodableBitStringFields fields) { + String bitString = bitStringEncoder.encode(fields, getFieldNames()); + String encodedString = base64UrlEncoder.encode(bitString); + return encodedString; + } + + @Override + protected void decodeSegment(String encodedString, EncodableBitStringFields fields) { + if(encodedString == null || encodedString.isEmpty()) { + this.fields.reset(fields); + } + try { + String bitString = base64UrlEncoder.decode(encodedString); + bitStringEncoder.decode(bitString, getFieldNames(), fields); + } catch (Exception e) { + throw new DecodingException("Unable to decode TcfCaV1PublisherPurposesSegment '" + encodedString + "'", e); + } + } +} diff --git a/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/segment/TcfEuV2CoreSegment.java b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/segment/TcfEuV2CoreSegment.java new file mode 100644 index 00000000..5b516bde --- /dev/null +++ b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/segment/TcfEuV2CoreSegment.java @@ -0,0 +1,93 @@ +package com.iab.gpp.encoder.segment; + +import java.time.ZonedDateTime; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import com.iab.gpp.encoder.base64.AbstractBase64UrlEncoder; +import com.iab.gpp.encoder.base64.TraditionalBase64UrlEncoder; +import com.iab.gpp.encoder.bitstring.BitStringEncoder; +import com.iab.gpp.encoder.datatype.EncodableArrayOfFixedIntegerRanges; +import com.iab.gpp.encoder.datatype.EncodableBoolean; +import com.iab.gpp.encoder.datatype.EncodableDatetime; +import com.iab.gpp.encoder.datatype.EncodableFixedBitfield; +import com.iab.gpp.encoder.datatype.EncodableFixedInteger; +import com.iab.gpp.encoder.datatype.EncodableFixedString; +import com.iab.gpp.encoder.datatype.EncodableOptimizedFixedRange; +import com.iab.gpp.encoder.error.DecodingException; +import com.iab.gpp.encoder.field.EncodableBitStringFields; +import com.iab.gpp.encoder.field.TcfEuV2Field; +import com.iab.gpp.encoder.section.TcfEuV2; + +public class TcfEuV2CoreSegment extends AbstractLazilyEncodableSegment { + + private AbstractBase64UrlEncoder base64UrlEncoder = TraditionalBase64UrlEncoder.getInstance(); + private BitStringEncoder bitStringEncoder = BitStringEncoder.getInstance(); + + public TcfEuV2CoreSegment() { + super(); + } + + public TcfEuV2CoreSegment(String encodedString) { + super(); + this.decode(encodedString); + } + + @Override + public List getFieldNames() { + return TcfEuV2Field.TCFEUV2_CORE_SEGMENT_FIELD_NAMES; + } + + @Override + protected EncodableBitStringFields initializeFields() { + ZonedDateTime date = ZonedDateTime.now(); + + EncodableBitStringFields fields = new EncodableBitStringFields(); + fields.put(TcfEuV2Field.VERSION, new EncodableFixedInteger(6, TcfEuV2.VERSION)); + fields.put(TcfEuV2Field.CREATED, new EncodableDatetime(date)); + fields.put(TcfEuV2Field.LAST_UPDATED, new EncodableDatetime(date)); + fields.put(TcfEuV2Field.CMP_ID, new EncodableFixedInteger(12, 0)); + fields.put(TcfEuV2Field.CMP_VERSION, new EncodableFixedInteger(12, 0)); + fields.put(TcfEuV2Field.CONSENT_SCREEN, new EncodableFixedInteger(6, 0)); + fields.put(TcfEuV2Field.CONSENT_LANGUAGE, new EncodableFixedString(2, "EN")); + fields.put(TcfEuV2Field.VENDOR_LIST_VERSION, new EncodableFixedInteger(12, 0)); + fields.put(TcfEuV2Field.POLICY_VERSION, new EncodableFixedInteger(6, 2)); + fields.put(TcfEuV2Field.IS_SERVICE_SPECIFIC, new EncodableBoolean(false)); + fields.put(TcfEuV2Field.USE_NON_STANDARD_STACKS, new EncodableBoolean(false)); + fields.put(TcfEuV2Field.SPECIAL_FEATURE_OPTINS, new EncodableFixedBitfield( + Arrays.asList(false, false, false, false, false, false, false, false, false, false, false, false))); + fields.put(TcfEuV2Field.PURPOSE_CONSENTS, + new EncodableFixedBitfield(Arrays.asList(false, false, false, false, false, false, false, false, false, false, + false, false, false, false, false, false, false, false, false, false, false, false, false, false))); + fields.put(TcfEuV2Field.PURPOSE_LEGITIMATE_INTERESTS, + new EncodableFixedBitfield(Arrays.asList(false, false, false, false, false, false, false, false, false, false, + false, false, false, false, false, false, false, false, false, false, false, false, false, false))); + fields.put(TcfEuV2Field.PURPOSE_ONE_TREATMENT, new EncodableBoolean(false)); + fields.put(TcfEuV2Field.PUBLISHER_COUNTRY_CODE, new EncodableFixedString(2, "AA")); + fields.put(TcfEuV2Field.VENDOR_CONSENTS, new EncodableOptimizedFixedRange(new ArrayList<>())); + fields.put(TcfEuV2Field.VENDOR_LEGITIMATE_INTERESTS, new EncodableOptimizedFixedRange(new ArrayList<>())); + + fields.put(TcfEuV2Field.PUBLISHER_RESTRICTIONS, new EncodableArrayOfFixedIntegerRanges(6, 2, new ArrayList<>(), false)); + return fields; + } + + @Override + protected String encodeSegment(EncodableBitStringFields fields) { + String bitString = bitStringEncoder.encode(fields, getFieldNames()); + String encodedString = base64UrlEncoder.encode(bitString); + return encodedString; + } + + @Override + protected void decodeSegment(String encodedString, EncodableBitStringFields fields) { + if(encodedString == null || encodedString.isEmpty()) { + this.fields.reset(fields); + } + try { + String bitString = base64UrlEncoder.decode(encodedString); + bitStringEncoder.decode(bitString, getFieldNames(), fields); + } catch (Exception e) { + throw new DecodingException("Unable to decode TcfEuV2CoreSegment '" + encodedString + "'", e); + } + } +} diff --git a/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/segment/TcfEuV2PublisherPurposesSegment.java b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/segment/TcfEuV2PublisherPurposesSegment.java new file mode 100644 index 00000000..0b751017 --- /dev/null +++ b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/segment/TcfEuV2PublisherPurposesSegment.java @@ -0,0 +1,86 @@ +package com.iab.gpp.encoder.segment; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.function.IntSupplier; +import com.iab.gpp.encoder.base64.AbstractBase64UrlEncoder; +import com.iab.gpp.encoder.base64.TraditionalBase64UrlEncoder; +import com.iab.gpp.encoder.bitstring.BitStringEncoder; +import com.iab.gpp.encoder.datatype.EncodableFixedBitfield; +import com.iab.gpp.encoder.datatype.EncodableFixedInteger; +import com.iab.gpp.encoder.datatype.EncodableFlexibleBitfield; +import com.iab.gpp.encoder.error.DecodingException; +import com.iab.gpp.encoder.field.EncodableBitStringFields; +import com.iab.gpp.encoder.field.TcfEuV2Field; + +public class TcfEuV2PublisherPurposesSegment extends AbstractLazilyEncodableSegment { + + private AbstractBase64UrlEncoder base64UrlEncoder = TraditionalBase64UrlEncoder.getInstance(); + private BitStringEncoder bitStringEncoder = BitStringEncoder.getInstance(); + + public TcfEuV2PublisherPurposesSegment() { + super(); + } + + public TcfEuV2PublisherPurposesSegment(String encodedString) { + super(); + this.decode(encodedString); + } + + @Override + public List getFieldNames() { + return TcfEuV2Field.TCFEUV2_PUBLISHER_PURPOSES_SEGMENT_FIELD_NAMES; + } + + @Override + protected EncodableBitStringFields initializeFields() { + EncodableBitStringFields fields = new EncodableBitStringFields(); + fields.put(TcfEuV2Field.PUBLISHER_PURPOSES_SEGMENT_TYPE, new EncodableFixedInteger(3, 3)); + fields.put(TcfEuV2Field.PUBLISHER_CONSENTS, + new EncodableFixedBitfield(Arrays.asList(false, false, false, false, false, false, false, false, false, false, + false, false, false, false, false, false, false, false, false, false, false, false, false, false))); + fields.put(TcfEuV2Field.PUBLISHER_LEGITIMATE_INTERESTS, + new EncodableFixedBitfield(Arrays.asList(false, false, false, false, false, false, false, false, false, false, + false, false, false, false, false, false, false, false, false, false, false, false, false, false))); + + EncodableFixedInteger numCustomPurposes = new EncodableFixedInteger(6, 0); + fields.put(TcfEuV2Field.NUM_CUSTOM_PURPOSES, numCustomPurposes); + + IntSupplier getLengthSupplier = new IntSupplier() { + + @Override + public int getAsInt() { + return numCustomPurposes.getValue(); + } + + }; + + fields.put(TcfEuV2Field.PUBLISHER_CUSTOM_CONSENTS, + new EncodableFlexibleBitfield(getLengthSupplier, new ArrayList<>())); + + fields.put(TcfEuV2Field.PUBLISHER_CUSTOM_LEGITIMATE_INTERESTS, + new EncodableFlexibleBitfield(getLengthSupplier, new ArrayList<>())); + return fields; + } + + @Override + protected String encodeSegment(EncodableBitStringFields fields) { + String bitString = bitStringEncoder.encode(fields, getFieldNames()); + String encodedString = base64UrlEncoder.encode(bitString); + return encodedString; + } + + @Override + protected void decodeSegment(String encodedString, EncodableBitStringFields fields) { + if(encodedString == null || encodedString.isEmpty()) { + this.fields.reset(fields); + } + try { + String bitString = base64UrlEncoder.decode(encodedString); + bitStringEncoder.decode(bitString, getFieldNames(), fields); + } catch (Exception e) { + throw new DecodingException("Unable to decode TcfEuV2PublisherPurposesSegment '" + encodedString + "'", e); + } + } +} diff --git a/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/segment/TcfEuV2VendorsAllowedSegment.java b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/segment/TcfEuV2VendorsAllowedSegment.java new file mode 100644 index 00000000..e09b48bb --- /dev/null +++ b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/segment/TcfEuV2VendorsAllowedSegment.java @@ -0,0 +1,60 @@ +package com.iab.gpp.encoder.segment; + +import java.util.ArrayList; +import java.util.List; +import com.iab.gpp.encoder.base64.AbstractBase64UrlEncoder; +import com.iab.gpp.encoder.base64.TraditionalBase64UrlEncoder; +import com.iab.gpp.encoder.bitstring.BitStringEncoder; +import com.iab.gpp.encoder.datatype.EncodableFixedInteger; +import com.iab.gpp.encoder.datatype.EncodableOptimizedFixedRange; +import com.iab.gpp.encoder.error.DecodingException; +import com.iab.gpp.encoder.field.EncodableBitStringFields; +import com.iab.gpp.encoder.field.TcfEuV2Field; + +public class TcfEuV2VendorsAllowedSegment extends AbstractLazilyEncodableSegment { + + private AbstractBase64UrlEncoder base64UrlEncoder = TraditionalBase64UrlEncoder.getInstance(); + private BitStringEncoder bitStringEncoder = BitStringEncoder.getInstance(); + + public TcfEuV2VendorsAllowedSegment() { + super(); + } + + public TcfEuV2VendorsAllowedSegment(String encodedString) { + super(); + this.decode(encodedString); + } + + @Override + public List getFieldNames() { + return TcfEuV2Field.TCFEUV2_VENDORS_ALLOWED_SEGMENT_FIELD_NAMES; + } + + @Override + protected EncodableBitStringFields initializeFields() { + EncodableBitStringFields fields = new EncodableBitStringFields(); + fields.put(TcfEuV2Field.VENDORS_ALLOWED_SEGMENT_TYPE, new EncodableFixedInteger(3, 2)); + fields.put(TcfEuV2Field.VENDORS_ALLOWED, new EncodableOptimizedFixedRange(new ArrayList<>())); + return fields; + } + + @Override + protected String encodeSegment(EncodableBitStringFields fields) { + String bitString = bitStringEncoder.encode(fields, getFieldNames()); + String encodedString = base64UrlEncoder.encode(bitString); + return encodedString; + } + + @Override + protected void decodeSegment(String encodedString, EncodableBitStringFields fields) { + if(encodedString == null || encodedString.isEmpty()) { + this.fields.reset(fields); + } + try { + String bitString = base64UrlEncoder.decode(encodedString); + bitStringEncoder.decode(bitString, getFieldNames(), fields); + } catch (Exception e) { + throw new DecodingException("Unable to decode TcfEuV2VendorsAllowedSegment '" + encodedString + "'", e); + } + } +} diff --git a/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/segment/TcfEuV2VendorsDisclosedSegment.java b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/segment/TcfEuV2VendorsDisclosedSegment.java new file mode 100644 index 00000000..c66b012d --- /dev/null +++ b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/segment/TcfEuV2VendorsDisclosedSegment.java @@ -0,0 +1,60 @@ +package com.iab.gpp.encoder.segment; + +import java.util.ArrayList; +import java.util.List; +import com.iab.gpp.encoder.base64.AbstractBase64UrlEncoder; +import com.iab.gpp.encoder.base64.TraditionalBase64UrlEncoder; +import com.iab.gpp.encoder.bitstring.BitStringEncoder; +import com.iab.gpp.encoder.datatype.EncodableFixedInteger; +import com.iab.gpp.encoder.datatype.EncodableOptimizedFixedRange; +import com.iab.gpp.encoder.error.DecodingException; +import com.iab.gpp.encoder.field.EncodableBitStringFields; +import com.iab.gpp.encoder.field.TcfEuV2Field; + +public class TcfEuV2VendorsDisclosedSegment extends AbstractLazilyEncodableSegment { + + private AbstractBase64UrlEncoder base64UrlEncoder = TraditionalBase64UrlEncoder.getInstance(); + private BitStringEncoder bitStringEncoder = BitStringEncoder.getInstance(); + + public TcfEuV2VendorsDisclosedSegment() { + super(); + } + + public TcfEuV2VendorsDisclosedSegment(String encodedString) { + super(); + this.decode(encodedString); + } + + @Override + public List getFieldNames() { + return TcfEuV2Field.TCFEUV2_VENDORS_DISCLOSED_SEGMENT_FIELD_NAMES; + } + + @Override + protected EncodableBitStringFields initializeFields() { + EncodableBitStringFields fields = new EncodableBitStringFields(); + fields.put(TcfEuV2Field.VENDORS_DISCLOSED_SEGMENT_TYPE, new EncodableFixedInteger(3, 1)); + fields.put(TcfEuV2Field.VENDORS_DISCLOSED, new EncodableOptimizedFixedRange(new ArrayList<>())); + return fields; + } + + @Override + protected String encodeSegment(EncodableBitStringFields fields) { + String bitString = bitStringEncoder.encode(fields, getFieldNames()); + String encodedString = base64UrlEncoder.encode(bitString); + return encodedString; + } + + @Override + protected void decodeSegment(String encodedString, EncodableBitStringFields fields) { + if(encodedString == null || encodedString.isEmpty()) { + this.fields.reset(fields); + } + try { + String bitString = base64UrlEncoder.decode(encodedString); + bitStringEncoder.decode(bitString, getFieldNames(), fields); + } catch (Exception e) { + throw new DecodingException("Unable to decode TcfEuV2VendorsDisclosedSegment '" + encodedString + "'", e); + } + } +} diff --git a/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/segment/UsCaCoreSegment.java b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/segment/UsCaCoreSegment.java new file mode 100644 index 00000000..25584c00 --- /dev/null +++ b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/segment/UsCaCoreSegment.java @@ -0,0 +1,96 @@ +package com.iab.gpp.encoder.segment; + +import java.util.Arrays; +import java.util.List; +import java.util.function.Predicate; +import com.iab.gpp.encoder.base64.AbstractBase64UrlEncoder; +import com.iab.gpp.encoder.base64.CompressedBase64UrlEncoder; +import com.iab.gpp.encoder.bitstring.BitStringEncoder; +import com.iab.gpp.encoder.datatype.EncodableFixedInteger; +import com.iab.gpp.encoder.datatype.EncodableFixedIntegerList; +import com.iab.gpp.encoder.error.DecodingException; +import com.iab.gpp.encoder.field.EncodableBitStringFields; +import com.iab.gpp.encoder.field.UsCaField; +import com.iab.gpp.encoder.section.UsCa; + +public class UsCaCoreSegment extends AbstractLazilyEncodableSegment { + + private AbstractBase64UrlEncoder base64UrlEncoder = CompressedBase64UrlEncoder.getInstance(); + private BitStringEncoder bitStringEncoder = BitStringEncoder.getInstance(); + + public UsCaCoreSegment() { + super(); + } + + public UsCaCoreSegment(String encodedString) { + super(); + this.decode(encodedString); + } + + @Override + public List getFieldNames() { + return UsCaField.USCA_CORE_SEGMENT_FIELD_NAMES; + } + + @Override + protected EncodableBitStringFields initializeFields() { + Predicate nullableBooleanAsTwoBitIntegerValidator = (n -> n >= 0 && n <= 2); + Predicate nonNullableBooleanAsTwoBitIntegerValidator = (n -> n >= 1 && n <= 2); + Predicate> nullableBooleanAsTwoBitIntegerListValidator = (l -> { + for (int n : l) { + if (n < 0 || n > 2) { + return false; + } + } + return true; + }); + + EncodableBitStringFields fields = new EncodableBitStringFields(); + fields.put(UsCaField.VERSION, new EncodableFixedInteger(6, UsCa.VERSION)); + fields.put(UsCaField.SALE_OPT_OUT_NOTICE, + new EncodableFixedInteger(2, 0).withValidator(nullableBooleanAsTwoBitIntegerValidator)); + fields.put(UsCaField.SHARING_OPT_OUT_NOTICE, + new EncodableFixedInteger(2, 0).withValidator(nullableBooleanAsTwoBitIntegerValidator)); + fields.put(UsCaField.SENSITIVE_DATA_LIMIT_USE_NOTICE, + new EncodableFixedInteger(2, 0).withValidator(nullableBooleanAsTwoBitIntegerValidator)); + fields.put(UsCaField.SALE_OPT_OUT, + new EncodableFixedInteger(2, 0).withValidator(nullableBooleanAsTwoBitIntegerValidator)); + fields.put(UsCaField.SHARING_OPT_OUT, + new EncodableFixedInteger(2, 0).withValidator(nullableBooleanAsTwoBitIntegerValidator)); + fields.put(UsCaField.SENSITIVE_DATA_PROCESSING, + new EncodableFixedIntegerList(2, Arrays.asList(0, 0, 0, 0, 0, 0, 0, 0, 0)) + .withValidator(nullableBooleanAsTwoBitIntegerListValidator)); + fields.put(UsCaField.KNOWN_CHILD_SENSITIVE_DATA_CONSENTS, new EncodableFixedIntegerList(2, Arrays.asList(0, 0)) + .withValidator(nullableBooleanAsTwoBitIntegerListValidator)); + fields.put(UsCaField.PERSONAL_DATA_CONSENTS, + new EncodableFixedInteger(2, 0).withValidator(nullableBooleanAsTwoBitIntegerValidator)); + fields.put(UsCaField.MSPA_COVERED_TRANSACTION, + new EncodableFixedInteger(2, 1).withValidator(nonNullableBooleanAsTwoBitIntegerValidator)); + fields.put(UsCaField.MSPA_OPT_OUT_OPTION_MODE, + new EncodableFixedInteger(2, 0).withValidator(nullableBooleanAsTwoBitIntegerValidator)); + fields.put(UsCaField.MSPA_SERVICE_PROVIDER_MODE, + new EncodableFixedInteger(2, 0).withValidator(nullableBooleanAsTwoBitIntegerValidator)); + return fields; + } + + @Override + protected String encodeSegment(EncodableBitStringFields fields) { + String bitString = bitStringEncoder.encode(fields, getFieldNames()); + String encodedString = base64UrlEncoder.encode(bitString); + return encodedString; + } + + @Override + protected void decodeSegment(String encodedString, EncodableBitStringFields fields) { + if (encodedString == null || encodedString.isEmpty()) { + this.fields.reset(fields); + } + try { + String bitString = base64UrlEncoder.decode(encodedString); + bitStringEncoder.decode(bitString, getFieldNames(), fields); + } catch (Exception e) { + throw new DecodingException("Unable to decode UsCaCoreSegment '" + encodedString + "'", e); + } + } + +} diff --git a/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/segment/UsCaGpcSegment.java b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/segment/UsCaGpcSegment.java new file mode 100644 index 00000000..19a36702 --- /dev/null +++ b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/segment/UsCaGpcSegment.java @@ -0,0 +1,60 @@ +package com.iab.gpp.encoder.segment; + +import java.util.List; +import com.iab.gpp.encoder.base64.AbstractBase64UrlEncoder; +import com.iab.gpp.encoder.base64.CompressedBase64UrlEncoder; +import com.iab.gpp.encoder.bitstring.BitStringEncoder; +import com.iab.gpp.encoder.datatype.EncodableBoolean; +import com.iab.gpp.encoder.datatype.EncodableFixedInteger; +import com.iab.gpp.encoder.error.DecodingException; +import com.iab.gpp.encoder.field.EncodableBitStringFields; +import com.iab.gpp.encoder.field.UsCaField; + +public class UsCaGpcSegment extends AbstractLazilyEncodableSegment { + + private AbstractBase64UrlEncoder base64UrlEncoder = CompressedBase64UrlEncoder.getInstance(); + private BitStringEncoder bitStringEncoder = BitStringEncoder.getInstance(); + + public UsCaGpcSegment() { + super(); + } + + public UsCaGpcSegment(String encodedString) { + super(); + this.decode(encodedString); + } + + @Override + public List getFieldNames() { + return UsCaField.USCA_GPC_SEGMENT_FIELD_NAMES; + } + + @Override + protected EncodableBitStringFields initializeFields() { + EncodableBitStringFields fields = new EncodableBitStringFields(); + fields.put(UsCaField.GPC_SEGMENT_TYPE, new EncodableFixedInteger(2, 1)); + fields.put(UsCaField.GPC_SEGMENT_INCLUDED, new EncodableBoolean(true)); + fields.put(UsCaField.GPC, new EncodableBoolean(false)); + return fields; + } + + @Override + protected String encodeSegment(EncodableBitStringFields fields) { + String bitString = bitStringEncoder.encode(fields, getFieldNames()); + String encodedString = base64UrlEncoder.encode(bitString); + return encodedString; + } + + @Override + protected void decodeSegment(String encodedString, EncodableBitStringFields fields) { + if(encodedString == null || encodedString.isEmpty()) { + this.fields.reset(fields); + } + try { + String bitString = base64UrlEncoder.decode(encodedString); + bitStringEncoder.decode(bitString, getFieldNames(), fields); + } catch (Exception e) { + throw new DecodingException("Unable to decode UsCaGpcSegment '" + encodedString + "'", e); + } + } +} diff --git a/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/segment/UsCoCoreSegment.java b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/segment/UsCoCoreSegment.java new file mode 100644 index 00000000..1f6c14c7 --- /dev/null +++ b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/segment/UsCoCoreSegment.java @@ -0,0 +1,93 @@ +package com.iab.gpp.encoder.segment; + +import java.util.Arrays; +import java.util.List; +import java.util.function.Predicate; +import com.iab.gpp.encoder.base64.AbstractBase64UrlEncoder; +import com.iab.gpp.encoder.base64.CompressedBase64UrlEncoder; +import com.iab.gpp.encoder.bitstring.BitStringEncoder; +import com.iab.gpp.encoder.datatype.EncodableFixedInteger; +import com.iab.gpp.encoder.datatype.EncodableFixedIntegerList; +import com.iab.gpp.encoder.error.DecodingException; +import com.iab.gpp.encoder.field.EncodableBitStringFields; +import com.iab.gpp.encoder.field.UsCoField; +import com.iab.gpp.encoder.section.UsCo; + +public class UsCoCoreSegment extends AbstractLazilyEncodableSegment { + + private AbstractBase64UrlEncoder base64UrlEncoder = CompressedBase64UrlEncoder.getInstance(); + private BitStringEncoder bitStringEncoder = BitStringEncoder.getInstance(); + + public UsCoCoreSegment() { + super(); + } + + public UsCoCoreSegment(String encodedString) { + super(); + this.decode(encodedString); + } + + @Override + public List getFieldNames() { + return UsCoField.USCO_CORE_SEGMENT_FIELD_NAMES; + } + + @Override + protected EncodableBitStringFields initializeFields() { + Predicate nullableBooleanAsTwoBitIntegerValidator = (n -> n >= 0 && n <= 2); + Predicate nonNullableBooleanAsTwoBitIntegerValidator = (n -> n >= 1 && n <= 2); + Predicate> nullableBooleanAsTwoBitIntegerListValidator = (l -> { + for (int n : l) { + if (n < 0 || n > 2) { + return false; + } + } + return true; + }); + + EncodableBitStringFields fields = new EncodableBitStringFields(); + fields.put(UsCoField.VERSION, new EncodableFixedInteger(6, UsCo.VERSION)); + fields.put(UsCoField.SHARING_NOTICE, + new EncodableFixedInteger(2, 0).withValidator(nullableBooleanAsTwoBitIntegerValidator)); + fields.put(UsCoField.SALE_OPT_OUT_NOTICE, + new EncodableFixedInteger(2, 0).withValidator(nullableBooleanAsTwoBitIntegerValidator)); + fields.put(UsCoField.TARGETED_ADVERTISING_OPT_OUT_NOTICE, + new EncodableFixedInteger(2, 0).withValidator(nullableBooleanAsTwoBitIntegerValidator)); + fields.put(UsCoField.SALE_OPT_OUT, + new EncodableFixedInteger(2, 0).withValidator(nullableBooleanAsTwoBitIntegerValidator)); + fields.put(UsCoField.TARGETED_ADVERTISING_OPT_OUT, + new EncodableFixedInteger(2, 0).withValidator(nullableBooleanAsTwoBitIntegerValidator)); + fields.put(UsCoField.SENSITIVE_DATA_PROCESSING, new EncodableFixedIntegerList(2, Arrays.asList(0, 0, 0, 0, 0, 0, 0)) + .withValidator(nullableBooleanAsTwoBitIntegerListValidator)); + fields.put(UsCoField.KNOWN_CHILD_SENSITIVE_DATA_CONSENTS, + new EncodableFixedInteger(2, 0).withValidator(nullableBooleanAsTwoBitIntegerValidator)); + fields.put(UsCoField.MSPA_COVERED_TRANSACTION, + new EncodableFixedInteger(2, 1).withValidator(nonNullableBooleanAsTwoBitIntegerValidator)); + fields.put(UsCoField.MSPA_OPT_OUT_OPTION_MODE, + new EncodableFixedInteger(2, 0).withValidator(nullableBooleanAsTwoBitIntegerValidator)); + fields.put(UsCoField.MSPA_SERVICE_PROVIDER_MODE, + new EncodableFixedInteger(2, 0).withValidator(nullableBooleanAsTwoBitIntegerValidator)); + return fields; + } + + @Override + protected String encodeSegment(EncodableBitStringFields fields) { + String bitString = bitStringEncoder.encode(fields, getFieldNames()); + String encodedString = base64UrlEncoder.encode(bitString); + return encodedString; + } + + @Override + protected void decodeSegment(String encodedString, EncodableBitStringFields fields) { + if (encodedString == null || encodedString.isEmpty()) { + this.fields.reset(fields); + } + try { + String bitString = base64UrlEncoder.decode(encodedString); + bitStringEncoder.decode(bitString, getFieldNames(), fields); + } catch (Exception e) { + throw new DecodingException("Unable to decode UsCoCoreSegment '" + encodedString + "'", e); + } + } + +} diff --git a/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/segment/UsCoGpcSegment.java b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/segment/UsCoGpcSegment.java new file mode 100644 index 00000000..7be0d974 --- /dev/null +++ b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/segment/UsCoGpcSegment.java @@ -0,0 +1,60 @@ +package com.iab.gpp.encoder.segment; + +import java.util.List; +import com.iab.gpp.encoder.base64.AbstractBase64UrlEncoder; +import com.iab.gpp.encoder.base64.CompressedBase64UrlEncoder; +import com.iab.gpp.encoder.bitstring.BitStringEncoder; +import com.iab.gpp.encoder.datatype.EncodableBoolean; +import com.iab.gpp.encoder.datatype.EncodableFixedInteger; +import com.iab.gpp.encoder.error.DecodingException; +import com.iab.gpp.encoder.field.EncodableBitStringFields; +import com.iab.gpp.encoder.field.UsCoField; + +public class UsCoGpcSegment extends AbstractLazilyEncodableSegment { + + private AbstractBase64UrlEncoder base64UrlEncoder = CompressedBase64UrlEncoder.getInstance(); + private BitStringEncoder bitStringEncoder = BitStringEncoder.getInstance(); + + public UsCoGpcSegment() { + super(); + } + + public UsCoGpcSegment(String encodedString) { + super(); + this.decode(encodedString); + } + + @Override + public List getFieldNames() { + return UsCoField.USCO_GPC_SEGMENT_FIELD_NAMES; + } + + @Override + protected EncodableBitStringFields initializeFields() { + EncodableBitStringFields fields = new EncodableBitStringFields(); + fields.put(UsCoField.GPC_SEGMENT_TYPE, new EncodableFixedInteger(2, 1)); + fields.put(UsCoField.GPC_SEGMENT_INCLUDED, new EncodableBoolean(true)); + fields.put(UsCoField.GPC, new EncodableBoolean(false)); + return fields; + } + + @Override + protected String encodeSegment(EncodableBitStringFields fields) { + String bitString = bitStringEncoder.encode(fields, getFieldNames()); + String encodedString = base64UrlEncoder.encode(bitString); + return encodedString; + } + + @Override + protected void decodeSegment(String encodedString, EncodableBitStringFields fields) { + if(encodedString == null || encodedString.isEmpty()) { + this.fields.reset(fields); + } + try { + String bitString = base64UrlEncoder.decode(encodedString); + bitStringEncoder.decode(bitString, getFieldNames(), fields); + } catch (Exception e) { + throw new DecodingException("Unable to decode UsCoGpcSegment '" + encodedString + "'", e); + } + } +} diff --git a/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/segment/UsCtCoreSegment.java b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/segment/UsCtCoreSegment.java new file mode 100644 index 00000000..066ad749 --- /dev/null +++ b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/segment/UsCtCoreSegment.java @@ -0,0 +1,94 @@ +package com.iab.gpp.encoder.segment; + +import java.util.Arrays; +import java.util.List; +import java.util.function.Predicate; +import com.iab.gpp.encoder.base64.AbstractBase64UrlEncoder; +import com.iab.gpp.encoder.base64.CompressedBase64UrlEncoder; +import com.iab.gpp.encoder.bitstring.BitStringEncoder; +import com.iab.gpp.encoder.datatype.EncodableFixedInteger; +import com.iab.gpp.encoder.datatype.EncodableFixedIntegerList; +import com.iab.gpp.encoder.error.DecodingException; +import com.iab.gpp.encoder.field.EncodableBitStringFields; +import com.iab.gpp.encoder.field.UsCtField; +import com.iab.gpp.encoder.section.UsCt; + +public class UsCtCoreSegment extends AbstractLazilyEncodableSegment { + + private AbstractBase64UrlEncoder base64UrlEncoder = CompressedBase64UrlEncoder.getInstance(); + private BitStringEncoder bitStringEncoder = BitStringEncoder.getInstance(); + + public UsCtCoreSegment() { + super(); + } + + public UsCtCoreSegment(String encodedString) { + super(); + this.decode(encodedString); + } + + @Override + public List getFieldNames() { + return UsCtField.USCT_CORE_SEGMENT_FIELD_NAMES; + } + + @Override + protected EncodableBitStringFields initializeFields() { + Predicate nullableBooleanAsTwoBitIntegerValidator = (n -> n >= 0 && n <= 2); + Predicate nonNullableBooleanAsTwoBitIntegerValidator = (n -> n >= 1 && n <= 2); + Predicate> nullableBooleanAsTwoBitIntegerListValidator = (l -> { + for (int n : l) { + if (n < 0 || n > 2) { + return false; + } + } + return true; + }); + + EncodableBitStringFields fields = new EncodableBitStringFields(); + fields.put(UsCtField.VERSION, new EncodableFixedInteger(6, UsCt.VERSION)); + fields.put(UsCtField.SHARING_NOTICE, + new EncodableFixedInteger(2, 0).withValidator(nullableBooleanAsTwoBitIntegerValidator)); + fields.put(UsCtField.SALE_OPT_OUT_NOTICE, + new EncodableFixedInteger(2, 0).withValidator(nullableBooleanAsTwoBitIntegerValidator)); + fields.put(UsCtField.TARGETED_ADVERTISING_OPT_OUT_NOTICE, + new EncodableFixedInteger(2, 0).withValidator(nullableBooleanAsTwoBitIntegerValidator)); + fields.put(UsCtField.SALE_OPT_OUT, + new EncodableFixedInteger(2, 0).withValidator(nullableBooleanAsTwoBitIntegerValidator)); + fields.put(UsCtField.TARGETED_ADVERTISING_OPT_OUT, + new EncodableFixedInteger(2, 0).withValidator(nullableBooleanAsTwoBitIntegerValidator)); + fields.put(UsCtField.SENSITIVE_DATA_PROCESSING, + new EncodableFixedIntegerList(2, Arrays.asList(0, 0, 0, 0, 0, 0, 0, 0)) + .withValidator(nullableBooleanAsTwoBitIntegerListValidator)); + fields.put(UsCtField.KNOWN_CHILD_SENSITIVE_DATA_CONSENTS, new EncodableFixedIntegerList(2, Arrays.asList(0, 0, 0)) + .withValidator(nullableBooleanAsTwoBitIntegerListValidator)); + fields.put(UsCtField.MSPA_COVERED_TRANSACTION, + new EncodableFixedInteger(2, 1).withValidator(nonNullableBooleanAsTwoBitIntegerValidator)); + fields.put(UsCtField.MSPA_OPT_OUT_OPTION_MODE, + new EncodableFixedInteger(2, 0).withValidator(nullableBooleanAsTwoBitIntegerValidator)); + fields.put(UsCtField.MSPA_SERVICE_PROVIDER_MODE, + new EncodableFixedInteger(2, 0).withValidator(nullableBooleanAsTwoBitIntegerValidator)); + return fields; + } + + @Override + protected String encodeSegment(EncodableBitStringFields fields) { + String bitString = bitStringEncoder.encode(fields, getFieldNames()); + String encodedString = base64UrlEncoder.encode(bitString); + return encodedString; + } + + @Override + protected void decodeSegment(String encodedString, EncodableBitStringFields fields) { + if (encodedString == null || encodedString.isEmpty()) { + this.fields.reset(fields); + } + try { + String bitString = base64UrlEncoder.decode(encodedString); + bitStringEncoder.decode(bitString, getFieldNames(), fields); + } catch (Exception e) { + throw new DecodingException("Unable to decode UsCtCoreSegment '" + encodedString + "'", e); + } + } + +} diff --git a/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/segment/UsCtGpcSegment.java b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/segment/UsCtGpcSegment.java new file mode 100644 index 00000000..fb009c89 --- /dev/null +++ b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/segment/UsCtGpcSegment.java @@ -0,0 +1,60 @@ +package com.iab.gpp.encoder.segment; + +import java.util.List; +import com.iab.gpp.encoder.base64.AbstractBase64UrlEncoder; +import com.iab.gpp.encoder.base64.CompressedBase64UrlEncoder; +import com.iab.gpp.encoder.bitstring.BitStringEncoder; +import com.iab.gpp.encoder.datatype.EncodableBoolean; +import com.iab.gpp.encoder.datatype.EncodableFixedInteger; +import com.iab.gpp.encoder.error.DecodingException; +import com.iab.gpp.encoder.field.EncodableBitStringFields; +import com.iab.gpp.encoder.field.UsCtField; + +public class UsCtGpcSegment extends AbstractLazilyEncodableSegment { + + private AbstractBase64UrlEncoder base64UrlEncoder = CompressedBase64UrlEncoder.getInstance(); + private BitStringEncoder bitStringEncoder = BitStringEncoder.getInstance(); + + public UsCtGpcSegment() { + super(); + } + + public UsCtGpcSegment(String encodedString) { + super(); + this.decode(encodedString); + } + + @Override + public List getFieldNames() { + return UsCtField.USCT_GPC_SEGMENT_FIELD_NAMES; + } + + @Override + protected EncodableBitStringFields initializeFields() { + EncodableBitStringFields fields = new EncodableBitStringFields(); + fields.put(UsCtField.GPC_SEGMENT_TYPE, new EncodableFixedInteger(2, 1)); + fields.put(UsCtField.GPC_SEGMENT_INCLUDED, new EncodableBoolean(true)); + fields.put(UsCtField.GPC, new EncodableBoolean(false)); + return fields; + } + + @Override + protected String encodeSegment(EncodableBitStringFields fields) { + String bitString = bitStringEncoder.encode(fields, getFieldNames()); + String encodedString = base64UrlEncoder.encode(bitString); + return encodedString; + } + + @Override + protected void decodeSegment(String encodedString, EncodableBitStringFields fields) { + if(encodedString == null || encodedString.isEmpty()) { + this.fields.reset(fields); + } + try { + String bitString = base64UrlEncoder.decode(encodedString); + bitStringEncoder.decode(bitString, getFieldNames(), fields); + } catch (Exception e) { + throw new DecodingException("Unable to decode UsCtGpcSegment '" + encodedString + "'", e); + } + } +} diff --git a/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/segment/UsDeCoreSegment.java b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/segment/UsDeCoreSegment.java new file mode 100644 index 00000000..a011faa0 --- /dev/null +++ b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/segment/UsDeCoreSegment.java @@ -0,0 +1,98 @@ +package com.iab.gpp.encoder.segment; + +import java.util.Arrays; +import java.util.List; +import java.util.function.Predicate; +import com.iab.gpp.encoder.base64.AbstractBase64UrlEncoder; +import com.iab.gpp.encoder.base64.CompressedBase64UrlEncoder; +import com.iab.gpp.encoder.bitstring.BitStringEncoder; +import com.iab.gpp.encoder.datatype.EncodableFixedInteger; +import com.iab.gpp.encoder.datatype.EncodableFixedIntegerList; +import com.iab.gpp.encoder.error.DecodingException; +import com.iab.gpp.encoder.field.EncodableBitStringFields; +import com.iab.gpp.encoder.field.UsDeField; +import com.iab.gpp.encoder.field.UsVaField; +import com.iab.gpp.encoder.section.UsDe; + +public class UsDeCoreSegment extends AbstractLazilyEncodableSegment { + + private AbstractBase64UrlEncoder base64UrlEncoder = CompressedBase64UrlEncoder.getInstance(); + private BitStringEncoder bitStringEncoder = BitStringEncoder.getInstance(); + + public UsDeCoreSegment() { + super(); + } + + public UsDeCoreSegment(String encodedString) { + super(); + this.decode(encodedString); + } + + @Override + public List getFieldNames() { + return UsDeField.USDE_CORE_SEGMENT_FIELD_NAMES; + } + + @Override + protected EncodableBitStringFields initializeFields() { + Predicate nullableBooleanAsTwoBitIntegerValidator = (n -> n >= 0 && n <= 2); + Predicate nonNullableBooleanAsTwoBitIntegerValidator = (n -> n >= 1 && n <= 2); + Predicate> nullableBooleanAsTwoBitIntegerListValidator = (l -> { + for (int n : l) { + if (n < 0 || n > 2) { + return false; + } + } + return true; + }); + + EncodableBitStringFields fields = new EncodableBitStringFields(); + fields.put(UsDeField.VERSION, new EncodableFixedInteger(6, UsDe.VERSION)); + fields.put(UsDeField.PROCESSING_NOTICE, + new EncodableFixedInteger(2, 0).withValidator(nullableBooleanAsTwoBitIntegerValidator)); + fields.put(UsDeField.SALE_OPT_OUT_NOTICE, + new EncodableFixedInteger(2, 0).withValidator(nullableBooleanAsTwoBitIntegerValidator)); + fields.put(UsDeField.TARGETED_ADVERTISING_OPT_OUT_NOTICE, + new EncodableFixedInteger(2, 0).withValidator(nullableBooleanAsTwoBitIntegerValidator)); + fields.put(UsDeField.SALE_OPT_OUT, + new EncodableFixedInteger(2, 0).withValidator(nullableBooleanAsTwoBitIntegerValidator)); + fields.put(UsDeField.TARGETED_ADVERTISING_OPT_OUT, + new EncodableFixedInteger(2, 0).withValidator(nullableBooleanAsTwoBitIntegerValidator)); + fields.put(UsDeField.SENSITIVE_DATA_PROCESSING, + new EncodableFixedIntegerList(2, Arrays.asList(0, 0, 0, 0, 0, 0, 0, 0, 0)) + .withValidator(nullableBooleanAsTwoBitIntegerListValidator)); + fields.put(UsVaField.KNOWN_CHILD_SENSITIVE_DATA_CONSENTS, + new EncodableFixedIntegerList(2, Arrays.asList(0, 0, 0, 0, 0)) + .withValidator(nullableBooleanAsTwoBitIntegerListValidator)); + fields.put(UsDeField.ADDITIONAL_DATA_PROCESSING_CONSENT, + new EncodableFixedInteger(2, 0).withValidator(nullableBooleanAsTwoBitIntegerValidator)); + fields.put(UsDeField.MSPA_COVERED_TRANSACTION, + new EncodableFixedInteger(2, 1).withValidator(nonNullableBooleanAsTwoBitIntegerValidator)); + fields.put(UsDeField.MSPA_OPT_OUT_OPTION_MODE, + new EncodableFixedInteger(2, 0).withValidator(nullableBooleanAsTwoBitIntegerValidator)); + fields.put(UsDeField.MSPA_SERVICE_PROVIDER_MODE, + new EncodableFixedInteger(2, 0).withValidator(nullableBooleanAsTwoBitIntegerValidator)); + return fields; + } + + @Override + protected String encodeSegment(EncodableBitStringFields fields) { + String bitString = bitStringEncoder.encode(fields, getFieldNames()); + String encodedString = base64UrlEncoder.encode(bitString); + return encodedString; + } + + @Override + protected void decodeSegment(String encodedString, EncodableBitStringFields fields) { + if (encodedString == null || encodedString.isEmpty()) { + this.fields.reset(fields); + } + try { + String bitString = base64UrlEncoder.decode(encodedString); + bitStringEncoder.decode(bitString, getFieldNames(), fields); + } catch (Exception e) { + throw new DecodingException("Unable to decode UsDeCoreSegment '" + encodedString + "'", e); + } + } + +} diff --git a/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/segment/UsDeGpcSegment.java b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/segment/UsDeGpcSegment.java new file mode 100644 index 00000000..66fe0431 --- /dev/null +++ b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/segment/UsDeGpcSegment.java @@ -0,0 +1,60 @@ +package com.iab.gpp.encoder.segment; + +import java.util.List; +import com.iab.gpp.encoder.base64.AbstractBase64UrlEncoder; +import com.iab.gpp.encoder.base64.CompressedBase64UrlEncoder; +import com.iab.gpp.encoder.bitstring.BitStringEncoder; +import com.iab.gpp.encoder.datatype.EncodableBoolean; +import com.iab.gpp.encoder.datatype.EncodableFixedInteger; +import com.iab.gpp.encoder.error.DecodingException; +import com.iab.gpp.encoder.field.EncodableBitStringFields; +import com.iab.gpp.encoder.field.UsDeField; + +public class UsDeGpcSegment extends AbstractLazilyEncodableSegment { + + private AbstractBase64UrlEncoder base64UrlEncoder = CompressedBase64UrlEncoder.getInstance(); + private BitStringEncoder bitStringEncoder = BitStringEncoder.getInstance(); + + public UsDeGpcSegment() { + super(); + } + + public UsDeGpcSegment(String encodedString) { + super(); + this.decode(encodedString); + } + + @Override + public List getFieldNames() { + return UsDeField.USDE_GPC_SEGMENT_FIELD_NAMES; + } + + @Override + protected EncodableBitStringFields initializeFields() { + EncodableBitStringFields fields = new EncodableBitStringFields(); + fields.put(UsDeField.GPC_SEGMENT_TYPE, new EncodableFixedInteger(2, 1)); + fields.put(UsDeField.GPC_SEGMENT_INCLUDED, new EncodableBoolean(true)); + fields.put(UsDeField.GPC, new EncodableBoolean(false)); + return fields; + } + + @Override + protected String encodeSegment(EncodableBitStringFields fields) { + String bitString = bitStringEncoder.encode(fields, getFieldNames()); + String encodedString = base64UrlEncoder.encode(bitString); + return encodedString; + } + + @Override + protected void decodeSegment(String encodedString, EncodableBitStringFields fields) { + if(encodedString == null || encodedString.isEmpty()) { + this.fields.reset(fields); + } + try { + String bitString = base64UrlEncoder.decode(encodedString); + bitStringEncoder.decode(bitString, getFieldNames(), fields); + } catch (Exception e) { + throw new DecodingException("Unable to decode UsDeGpcSegment '" + encodedString + "'", e); + } + } +} diff --git a/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/segment/UsFlCoreSegment.java b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/segment/UsFlCoreSegment.java new file mode 100644 index 00000000..02c480aa --- /dev/null +++ b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/segment/UsFlCoreSegment.java @@ -0,0 +1,95 @@ +package com.iab.gpp.encoder.segment; + +import java.util.Arrays; +import java.util.List; +import java.util.function.Predicate; +import com.iab.gpp.encoder.base64.AbstractBase64UrlEncoder; +import com.iab.gpp.encoder.base64.CompressedBase64UrlEncoder; +import com.iab.gpp.encoder.bitstring.BitStringEncoder; +import com.iab.gpp.encoder.datatype.EncodableFixedInteger; +import com.iab.gpp.encoder.datatype.EncodableFixedIntegerList; +import com.iab.gpp.encoder.error.DecodingException; +import com.iab.gpp.encoder.field.EncodableBitStringFields; +import com.iab.gpp.encoder.field.UsFlField; +import com.iab.gpp.encoder.section.UsFl; + +public class UsFlCoreSegment extends AbstractLazilyEncodableSegment { + + private AbstractBase64UrlEncoder base64UrlEncoder = CompressedBase64UrlEncoder.getInstance(); + private BitStringEncoder bitStringEncoder = BitStringEncoder.getInstance(); + + public UsFlCoreSegment() { + super(); + } + + public UsFlCoreSegment(String encodedString) { + super(); + this.decode(encodedString); + } + + @Override + public List getFieldNames() { + return UsFlField.USFL_CORE_SEGMENT_FIELD_NAMES; + } + + @Override + protected EncodableBitStringFields initializeFields() { + Predicate nullableBooleanAsTwoBitIntegerValidator = (n -> n >= 0 && n <= 2); + Predicate nonNullableBooleanAsTwoBitIntegerValidator = (n -> n >= 1 && n <= 2); + Predicate> nullableBooleanAsTwoBitIntegerListValidator = (l -> { + for (int n : l) { + if (n < 0 || n > 2) { + return false; + } + } + return true; + }); + + EncodableBitStringFields fields = new EncodableBitStringFields(); + fields.put(UsFlField.VERSION, new EncodableFixedInteger(6, UsFl.VERSION)); + fields.put(UsFlField.PROCESSING_NOTICE, + new EncodableFixedInteger(2, 0).withValidator(nullableBooleanAsTwoBitIntegerValidator)); + fields.put(UsFlField.SALE_OPT_OUT_NOTICE, + new EncodableFixedInteger(2, 0).withValidator(nullableBooleanAsTwoBitIntegerValidator)); + fields.put(UsFlField.TARGETED_ADVERTISING_OPT_OUT_NOTICE, + new EncodableFixedInteger(2, 0).withValidator(nullableBooleanAsTwoBitIntegerValidator)); + fields.put(UsFlField.SALE_OPT_OUT, + new EncodableFixedInteger(2, 0).withValidator(nullableBooleanAsTwoBitIntegerValidator)); + fields.put(UsFlField.TARGETED_ADVERTISING_OPT_OUT, + new EncodableFixedInteger(2, 0).withValidator(nullableBooleanAsTwoBitIntegerValidator)); + fields.put(UsFlField.SENSITIVE_DATA_PROCESSING, + new EncodableFixedIntegerList(2, Arrays.asList(0, 0, 0, 0, 0, 0, 0, 0)) + .withValidator(nullableBooleanAsTwoBitIntegerListValidator)); + fields.put(UsFlField.KNOWN_CHILD_SENSITIVE_DATA_CONSENTS, new EncodableFixedIntegerList(2, Arrays.asList(0, 0, 0)) + .withValidator(nullableBooleanAsTwoBitIntegerListValidator)); + fields.put(UsFlField.ADDITIONAL_DATA_PROCESSING_CONSENT, + new EncodableFixedInteger(2, 0).withValidator(nullableBooleanAsTwoBitIntegerValidator)); + fields.put(UsFlField.MSPA_COVERED_TRANSACTION, + new EncodableFixedInteger(2, 1).withValidator(nonNullableBooleanAsTwoBitIntegerValidator)); + fields.put(UsFlField.MSPA_OPT_OUT_OPTION_MODE, + new EncodableFixedInteger(2, 0).withValidator(nullableBooleanAsTwoBitIntegerValidator)); + fields.put(UsFlField.MSPA_SERVICE_PROVIDER_MODE, + new EncodableFixedInteger(2, 0).withValidator(nullableBooleanAsTwoBitIntegerValidator)); + return fields; + } + + @Override + protected String encodeSegment(EncodableBitStringFields fields) { + String bitString = bitStringEncoder.encode(fields, getFieldNames()); + String encodedString = base64UrlEncoder.encode(bitString); + return encodedString; + } + + @Override + protected void decodeSegment(String encodedString, EncodableBitStringFields fields) { + if (encodedString == null || encodedString.isEmpty()) { + this.fields.reset(fields); + } + try { + String bitString = base64UrlEncoder.decode(encodedString); + bitStringEncoder.decode(bitString, getFieldNames(), fields); + } catch (Exception e) { + throw new DecodingException("Unable to decode UsFlCoreSegment '" + encodedString + "'", e); + } + } +} diff --git a/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/segment/UsIaCoreSegment.java b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/segment/UsIaCoreSegment.java new file mode 100644 index 00000000..9cd9a917 --- /dev/null +++ b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/segment/UsIaCoreSegment.java @@ -0,0 +1,97 @@ +package com.iab.gpp.encoder.segment; + +import java.util.Arrays; +import java.util.List; +import java.util.function.Predicate; +import com.iab.gpp.encoder.base64.AbstractBase64UrlEncoder; +import com.iab.gpp.encoder.base64.CompressedBase64UrlEncoder; +import com.iab.gpp.encoder.bitstring.BitStringEncoder; +import com.iab.gpp.encoder.datatype.EncodableFixedInteger; +import com.iab.gpp.encoder.datatype.EncodableFixedIntegerList; +import com.iab.gpp.encoder.error.DecodingException; +import com.iab.gpp.encoder.field.EncodableBitStringFields; +import com.iab.gpp.encoder.field.UsIaField; +import com.iab.gpp.encoder.field.UsVaField; +import com.iab.gpp.encoder.section.UsIa; + +public class UsIaCoreSegment extends AbstractLazilyEncodableSegment { + + private AbstractBase64UrlEncoder base64UrlEncoder = CompressedBase64UrlEncoder.getInstance(); + private BitStringEncoder bitStringEncoder = BitStringEncoder.getInstance(); + + public UsIaCoreSegment() { + super(); + } + + public UsIaCoreSegment(String encodedString) { + super(); + this.decode(encodedString); + } + + @Override + public List getFieldNames() { + return UsIaField.USIA_CORE_SEGMENT_FIELD_NAMES; + } + + @Override + protected EncodableBitStringFields initializeFields() { + Predicate nullableBooleanAsTwoBitIntegerValidator = (n -> n >= 0 && n <= 2); + Predicate nonNullableBooleanAsTwoBitIntegerValidator = (n -> n >= 1 && n <= 2); + Predicate> nullableBooleanAsTwoBitIntegerListValidator = (l -> { + for (int n : l) { + if (n < 0 || n > 2) { + return false; + } + } + return true; + }); + + EncodableBitStringFields fields = new EncodableBitStringFields(); + fields.put(UsIaField.VERSION, new EncodableFixedInteger(6, UsIa.VERSION)); + fields.put(UsIaField.PROCESSING_NOTICE, + new EncodableFixedInteger(2, 0).withValidator(nullableBooleanAsTwoBitIntegerValidator)); + fields.put(UsIaField.SALE_OPT_OUT_NOTICE, + new EncodableFixedInteger(2, 0).withValidator(nullableBooleanAsTwoBitIntegerValidator)); + fields.put(UsIaField.TARGETED_ADVERTISING_OPT_OUT_NOTICE, + new EncodableFixedInteger(2, 0).withValidator(nullableBooleanAsTwoBitIntegerValidator)); + fields.put(UsIaField.SENSITIVE_DATA_OPT_OUT_NOTICE, + new EncodableFixedInteger(2, 0).withValidator(nullableBooleanAsTwoBitIntegerValidator)); + fields.put(UsIaField.SALE_OPT_OUT, + new EncodableFixedInteger(2, 0).withValidator(nullableBooleanAsTwoBitIntegerValidator)); + fields.put(UsIaField.TARGETED_ADVERTISING_OPT_OUT, + new EncodableFixedInteger(2, 0).withValidator(nullableBooleanAsTwoBitIntegerValidator)); + fields.put(UsIaField.SENSITIVE_DATA_PROCESSING, + new EncodableFixedIntegerList(2, Arrays.asList(0, 0, 0, 0, 0, 0, 0, 0)) + .withValidator(nullableBooleanAsTwoBitIntegerListValidator)); + fields.put(UsVaField.KNOWN_CHILD_SENSITIVE_DATA_CONSENTS, + new EncodableFixedInteger(2, 0).withValidator(nullableBooleanAsTwoBitIntegerValidator)); + fields.put(UsIaField.MSPA_COVERED_TRANSACTION, + new EncodableFixedInteger(2, 1).withValidator(nonNullableBooleanAsTwoBitIntegerValidator)); + fields.put(UsIaField.MSPA_OPT_OUT_OPTION_MODE, + new EncodableFixedInteger(2, 0).withValidator(nullableBooleanAsTwoBitIntegerValidator)); + fields.put(UsIaField.MSPA_SERVICE_PROVIDER_MODE, + new EncodableFixedInteger(2, 0).withValidator(nullableBooleanAsTwoBitIntegerValidator)); + return fields; + } + + @Override + protected String encodeSegment(EncodableBitStringFields fields) { + String bitString = bitStringEncoder.encode(fields, getFieldNames()); + String encodedString = base64UrlEncoder.encode(bitString); + return encodedString; + } + + @Override + protected void decodeSegment(String encodedString, EncodableBitStringFields fields) { + if (encodedString == null || encodedString.isEmpty()) { + this.fields.reset(fields); + } + try { + String bitString = base64UrlEncoder.decode(encodedString); + bitStringEncoder.decode(bitString, getFieldNames(), fields); + } catch (Exception e) { + throw new DecodingException("Unable to decode UsIaCoreSegment '" + encodedString + "'", e); + } + } + +} diff --git a/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/segment/UsIaGpcSegment.java b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/segment/UsIaGpcSegment.java new file mode 100644 index 00000000..12cb0bd6 --- /dev/null +++ b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/segment/UsIaGpcSegment.java @@ -0,0 +1,60 @@ +package com.iab.gpp.encoder.segment; + +import java.util.List; +import com.iab.gpp.encoder.base64.AbstractBase64UrlEncoder; +import com.iab.gpp.encoder.base64.CompressedBase64UrlEncoder; +import com.iab.gpp.encoder.bitstring.BitStringEncoder; +import com.iab.gpp.encoder.datatype.EncodableBoolean; +import com.iab.gpp.encoder.datatype.EncodableFixedInteger; +import com.iab.gpp.encoder.error.DecodingException; +import com.iab.gpp.encoder.field.EncodableBitStringFields; +import com.iab.gpp.encoder.field.UsIaField; + +public class UsIaGpcSegment extends AbstractLazilyEncodableSegment { + + private AbstractBase64UrlEncoder base64UrlEncoder = CompressedBase64UrlEncoder.getInstance(); + private BitStringEncoder bitStringEncoder = BitStringEncoder.getInstance(); + + public UsIaGpcSegment() { + super(); + } + + public UsIaGpcSegment(String encodedString) { + super(); + this.decode(encodedString); + } + + @Override + public List getFieldNames() { + return UsIaField.USIA_GPC_SEGMENT_FIELD_NAMES; + } + + @Override + protected EncodableBitStringFields initializeFields() { + EncodableBitStringFields fields = new EncodableBitStringFields(); + fields.put(UsIaField.GPC_SEGMENT_TYPE, new EncodableFixedInteger(2, 1)); + fields.put(UsIaField.GPC_SEGMENT_INCLUDED, new EncodableBoolean(true)); + fields.put(UsIaField.GPC, new EncodableBoolean(false)); + return fields; + } + + @Override + protected String encodeSegment(EncodableBitStringFields fields) { + String bitString = bitStringEncoder.encode(fields, getFieldNames()); + String encodedString = base64UrlEncoder.encode(bitString); + return encodedString; + } + + @Override + protected void decodeSegment(String encodedString, EncodableBitStringFields fields) { + if(encodedString == null || encodedString.isEmpty()) { + this.fields.reset(fields); + } + try { + String bitString = base64UrlEncoder.decode(encodedString); + bitStringEncoder.decode(bitString, getFieldNames(), fields); + } catch (Exception e) { + throw new DecodingException("Unable to decode UsIaGpcSegment '" + encodedString + "'", e); + } + } +} diff --git a/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/segment/UsMtCoreSegment.java b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/segment/UsMtCoreSegment.java new file mode 100644 index 00000000..4daa1872 --- /dev/null +++ b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/segment/UsMtCoreSegment.java @@ -0,0 +1,96 @@ +package com.iab.gpp.encoder.segment; + +import java.util.Arrays; +import java.util.List; +import java.util.function.Predicate; +import com.iab.gpp.encoder.base64.AbstractBase64UrlEncoder; +import com.iab.gpp.encoder.base64.CompressedBase64UrlEncoder; +import com.iab.gpp.encoder.bitstring.BitStringEncoder; +import com.iab.gpp.encoder.datatype.EncodableFixedInteger; +import com.iab.gpp.encoder.datatype.EncodableFixedIntegerList; +import com.iab.gpp.encoder.error.DecodingException; +import com.iab.gpp.encoder.field.EncodableBitStringFields; +import com.iab.gpp.encoder.field.UsMtField; +import com.iab.gpp.encoder.section.UsMt; + +public class UsMtCoreSegment extends AbstractLazilyEncodableSegment { + + private AbstractBase64UrlEncoder base64UrlEncoder = CompressedBase64UrlEncoder.getInstance(); + private BitStringEncoder bitStringEncoder = BitStringEncoder.getInstance(); + + public UsMtCoreSegment() { + super(); + } + + public UsMtCoreSegment(String encodedString) { + super(); + this.decode(encodedString); + } + + @Override + public List getFieldNames() { + return UsMtField.USMT_CORE_SEGMENT_FIELD_NAMES; + } + + @Override + protected EncodableBitStringFields initializeFields() { + Predicate nullableBooleanAsTwoBitIntegerValidator = (n -> n >= 0 && n <= 2); + Predicate nonNullableBooleanAsTwoBitIntegerValidator = (n -> n >= 1 && n <= 2); + Predicate> nullableBooleanAsTwoBitIntegerListValidator = (l -> { + for (int n : l) { + if (n < 0 || n > 2) { + return false; + } + } + return true; + }); + + EncodableBitStringFields fields = new EncodableBitStringFields(); + fields.put(UsMtField.VERSION, new EncodableFixedInteger(6, UsMt.VERSION)); + fields.put(UsMtField.SHARING_NOTICE, + new EncodableFixedInteger(2, 0).withValidator(nullableBooleanAsTwoBitIntegerValidator)); + fields.put(UsMtField.SALE_OPT_OUT_NOTICE, + new EncodableFixedInteger(2, 0).withValidator(nullableBooleanAsTwoBitIntegerValidator)); + fields.put(UsMtField.TARGETED_ADVERTISING_OPT_OUT_NOTICE, + new EncodableFixedInteger(2, 0).withValidator(nullableBooleanAsTwoBitIntegerValidator)); + fields.put(UsMtField.SALE_OPT_OUT, + new EncodableFixedInteger(2, 0).withValidator(nullableBooleanAsTwoBitIntegerValidator)); + fields.put(UsMtField.TARGETED_ADVERTISING_OPT_OUT, + new EncodableFixedInteger(2, 0).withValidator(nullableBooleanAsTwoBitIntegerValidator)); + fields.put(UsMtField.SENSITIVE_DATA_PROCESSING, + new EncodableFixedIntegerList(2, Arrays.asList(0, 0, 0, 0, 0, 0, 0, 0)) + .withValidator(nullableBooleanAsTwoBitIntegerListValidator)); + fields.put(UsMtField.KNOWN_CHILD_SENSITIVE_DATA_CONSENTS, new EncodableFixedIntegerList(2, Arrays.asList(0, 0, 0)) + .withValidator(nullableBooleanAsTwoBitIntegerListValidator)); + fields.put(UsMtField.ADDITIONAL_DATA_PROCESSING_CONSENT, + new EncodableFixedInteger(2, 0).withValidator(nullableBooleanAsTwoBitIntegerValidator)); + fields.put(UsMtField.MSPA_COVERED_TRANSACTION, + new EncodableFixedInteger(2, 1).withValidator(nonNullableBooleanAsTwoBitIntegerValidator)); + fields.put(UsMtField.MSPA_OPT_OUT_OPTION_MODE, + new EncodableFixedInteger(2, 0).withValidator(nullableBooleanAsTwoBitIntegerValidator)); + fields.put(UsMtField.MSPA_SERVICE_PROVIDER_MODE, + new EncodableFixedInteger(2, 0).withValidator(nullableBooleanAsTwoBitIntegerValidator)); + return fields; + } + + @Override + protected String encodeSegment(EncodableBitStringFields fields) { + String bitString = bitStringEncoder.encode(fields, getFieldNames()); + String encodedString = base64UrlEncoder.encode(bitString); + return encodedString; + } + + @Override + protected void decodeSegment(String encodedString, EncodableBitStringFields fields) { + if (encodedString == null || encodedString.isEmpty()) { + this.fields.reset(fields); + } + try { + String bitString = base64UrlEncoder.decode(encodedString); + bitStringEncoder.decode(bitString, getFieldNames(), fields); + } catch (Exception e) { + throw new DecodingException("Unable to decode UsMtCoreSegment '" + encodedString + "'", e); + } + } + +} diff --git a/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/segment/UsMtGpcSegment.java b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/segment/UsMtGpcSegment.java new file mode 100644 index 00000000..99be5310 --- /dev/null +++ b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/segment/UsMtGpcSegment.java @@ -0,0 +1,60 @@ +package com.iab.gpp.encoder.segment; + +import java.util.List; +import com.iab.gpp.encoder.base64.AbstractBase64UrlEncoder; +import com.iab.gpp.encoder.base64.CompressedBase64UrlEncoder; +import com.iab.gpp.encoder.bitstring.BitStringEncoder; +import com.iab.gpp.encoder.datatype.EncodableBoolean; +import com.iab.gpp.encoder.datatype.EncodableFixedInteger; +import com.iab.gpp.encoder.error.DecodingException; +import com.iab.gpp.encoder.field.EncodableBitStringFields; +import com.iab.gpp.encoder.field.UsMtField; + +public class UsMtGpcSegment extends AbstractLazilyEncodableSegment { + + private AbstractBase64UrlEncoder base64UrlEncoder = CompressedBase64UrlEncoder.getInstance(); + private BitStringEncoder bitStringEncoder = BitStringEncoder.getInstance(); + + public UsMtGpcSegment() { + super(); + } + + public UsMtGpcSegment(String encodedString) { + super(); + this.decode(encodedString); + } + + @Override + public List getFieldNames() { + return UsMtField.USMT_GPC_SEGMENT_FIELD_NAMES; + } + + @Override + protected EncodableBitStringFields initializeFields() { + EncodableBitStringFields fields = new EncodableBitStringFields(); + fields.put(UsMtField.GPC_SEGMENT_TYPE, new EncodableFixedInteger(2, 1)); + fields.put(UsMtField.GPC_SEGMENT_INCLUDED, new EncodableBoolean(true)); + fields.put(UsMtField.GPC, new EncodableBoolean(false)); + return fields; + } + + @Override + protected String encodeSegment(EncodableBitStringFields fields) { + String bitString = bitStringEncoder.encode(fields, getFieldNames()); + String encodedString = base64UrlEncoder.encode(bitString); + return encodedString; + } + + @Override + protected void decodeSegment(String encodedString, EncodableBitStringFields fields) { + if(encodedString == null || encodedString.isEmpty()) { + this.fields.reset(fields); + } + try { + String bitString = base64UrlEncoder.decode(encodedString); + bitStringEncoder.decode(bitString, getFieldNames(), fields); + } catch (Exception e) { + throw new DecodingException("Unable to decode UsMtGpcSegment '" + encodedString + "'", e); + } + } +} diff --git a/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/segment/UsNatCoreSegment.java b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/segment/UsNatCoreSegment.java new file mode 100644 index 00000000..6c7a7945 --- /dev/null +++ b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/segment/UsNatCoreSegment.java @@ -0,0 +1,113 @@ +package com.iab.gpp.encoder.segment; + +import java.util.Arrays; +import java.util.List; +import java.util.function.Predicate; +import com.iab.gpp.encoder.base64.AbstractBase64UrlEncoder; +import com.iab.gpp.encoder.base64.CompressedBase64UrlEncoder; +import com.iab.gpp.encoder.bitstring.BitStringEncoder; +import com.iab.gpp.encoder.datatype.EncodableFixedInteger; +import com.iab.gpp.encoder.datatype.EncodableFixedIntegerList; +import com.iab.gpp.encoder.error.DecodingException; +import com.iab.gpp.encoder.field.EncodableBitStringFields; +import com.iab.gpp.encoder.field.UsNatField; +import com.iab.gpp.encoder.section.UsNat; + +public class UsNatCoreSegment extends AbstractLazilyEncodableSegment { + + private AbstractBase64UrlEncoder base64UrlEncoder = CompressedBase64UrlEncoder.getInstance(); + private BitStringEncoder bitStringEncoder = BitStringEncoder.getInstance(); + + public UsNatCoreSegment() { + super(); + } + + public UsNatCoreSegment(String encodedString) { + super(); + this.decode(encodedString); + } + + @Override + public List getFieldNames() { + return UsNatField.USNAT_CORE_SEGMENT_FIELD_NAMES; + } + + @Override + protected EncodableBitStringFields initializeFields() { + Predicate nullableBooleanAsTwoBitIntegerValidator = (n -> n >= 0 && n <= 2); + Predicate nonNullableBooleanAsTwoBitIntegerValidator = (n -> n >= 1 && n <= 2); + Predicate> nullableBooleanAsTwoBitIntegerListValidator = (l -> { + for (int n : l) { + if (n < 0 || n > 2) { + return false; + } + } + return true; + }); + + EncodableBitStringFields fields = new EncodableBitStringFields(); + fields.put(UsNatField.VERSION, new EncodableFixedInteger(6, UsNat.VERSION)); + fields.put(UsNatField.SHARING_NOTICE, + new EncodableFixedInteger(2, 0).withValidator(nullableBooleanAsTwoBitIntegerValidator)); + fields.put(UsNatField.SALE_OPT_OUT_NOTICE, + new EncodableFixedInteger(2, 0).withValidator(nullableBooleanAsTwoBitIntegerValidator)); + fields.put(UsNatField.SHARING_OPT_OUT_NOTICE, + new EncodableFixedInteger(2, 0).withValidator(nullableBooleanAsTwoBitIntegerValidator)); + fields.put(UsNatField.TARGETED_ADVERTISING_OPT_OUT_NOTICE, + new EncodableFixedInteger(2, 0).withValidator(nullableBooleanAsTwoBitIntegerValidator)); + fields.put(UsNatField.SENSITIVE_DATA_PROCESSING_OPT_OUT_NOTICE, + new EncodableFixedInteger(2, 0).withValidator(nullableBooleanAsTwoBitIntegerValidator)); + fields.put(UsNatField.SENSITIVE_DATA_LIMIT_USE_NOTICE, + new EncodableFixedInteger(2, 0).withValidator(nullableBooleanAsTwoBitIntegerValidator)); + fields.put(UsNatField.SALE_OPT_OUT, + new EncodableFixedInteger(2, 0).withValidator(nullableBooleanAsTwoBitIntegerValidator)); + fields.put(UsNatField.SHARING_OPT_OUT, + new EncodableFixedInteger(2, 0).withValidator(nullableBooleanAsTwoBitIntegerValidator)); + fields.put(UsNatField.TARGETED_ADVERTISING_OPT_OUT, + new EncodableFixedInteger(2, 0).withValidator(nullableBooleanAsTwoBitIntegerValidator)); + fields.put(UsNatField.SENSITIVE_DATA_PROCESSING, + new EncodableFixedIntegerList(2, Arrays.asList(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)) + .withValidator(nullableBooleanAsTwoBitIntegerListValidator)); + fields.put(UsNatField.KNOWN_CHILD_SENSITIVE_DATA_CONSENTS, new EncodableFixedIntegerList(2, Arrays.asList(0, 0, 0)) + .withValidator(nullableBooleanAsTwoBitIntegerListValidator)); + fields.put(UsNatField.PERSONAL_DATA_CONSENTS, + new EncodableFixedInteger(2, 0).withValidator(nullableBooleanAsTwoBitIntegerValidator)); + fields.put(UsNatField.MSPA_COVERED_TRANSACTION, + new EncodableFixedInteger(2, 1).withValidator(nonNullableBooleanAsTwoBitIntegerValidator)); + fields.put(UsNatField.MSPA_OPT_OUT_OPTION_MODE, + new EncodableFixedInteger(2, 0).withValidator(nullableBooleanAsTwoBitIntegerValidator)); + fields.put(UsNatField.MSPA_SERVICE_PROVIDER_MODE, + new EncodableFixedInteger(2, 0).withValidator(nullableBooleanAsTwoBitIntegerValidator)); + return fields; + } + + @Override + protected String encodeSegment(EncodableBitStringFields fields) { + String bitString = bitStringEncoder.encode(fields, getFieldNames()); + String encodedString = base64UrlEncoder.encode(bitString); + return encodedString; + } + + @Override + protected void decodeSegment(String encodedString, EncodableBitStringFields fields) { + if (encodedString == null || encodedString.isEmpty()) { + this.fields.reset(fields); + } + try { + String bitString = base64UrlEncoder.decode(encodedString); + + // Necessary to maintain backwards compatibility when sensitive data processing changed from a + // length of 12 to 16 and known child sensitive data consents changed from a length of 2 to 3 in the + // DE, IA, NE, NH, NJ, TN release + if (bitString.length() == 66) { + bitString = + bitString.substring(0, 48) + "00000000" + bitString.substring(48, 52) + "00" + bitString.substring(52, 62); + } + + bitStringEncoder.decode(bitString, getFieldNames(), fields); + } catch (Exception e) { + throw new DecodingException("Unable to decode UsNatCoreSegment '" + encodedString + "'", e); + } + } + +} diff --git a/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/segment/UsNatGpcSegment.java b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/segment/UsNatGpcSegment.java new file mode 100644 index 00000000..54fc1d40 --- /dev/null +++ b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/segment/UsNatGpcSegment.java @@ -0,0 +1,60 @@ +package com.iab.gpp.encoder.segment; + +import java.util.List; +import com.iab.gpp.encoder.base64.AbstractBase64UrlEncoder; +import com.iab.gpp.encoder.base64.CompressedBase64UrlEncoder; +import com.iab.gpp.encoder.bitstring.BitStringEncoder; +import com.iab.gpp.encoder.datatype.EncodableBoolean; +import com.iab.gpp.encoder.datatype.EncodableFixedInteger; +import com.iab.gpp.encoder.error.DecodingException; +import com.iab.gpp.encoder.field.EncodableBitStringFields; +import com.iab.gpp.encoder.field.UsNatField; + +public class UsNatGpcSegment extends AbstractLazilyEncodableSegment { + + private AbstractBase64UrlEncoder base64UrlEncoder = CompressedBase64UrlEncoder.getInstance(); + private BitStringEncoder bitStringEncoder = BitStringEncoder.getInstance(); + + public UsNatGpcSegment() { + super(); + } + + public UsNatGpcSegment(String encodedString) { + super(); + this.decode(encodedString); + } + + @Override + public List getFieldNames() { + return UsNatField.USNAT_GPC_SEGMENT_FIELD_NAMES; + } + + @Override + protected EncodableBitStringFields initializeFields() { + EncodableBitStringFields fields = new EncodableBitStringFields(); + fields.put(UsNatField.GPC_SEGMENT_TYPE, new EncodableFixedInteger(2, 1)); + fields.put(UsNatField.GPC_SEGMENT_INCLUDED, new EncodableBoolean(true)); + fields.put(UsNatField.GPC, new EncodableBoolean(false)); + return fields; + } + + @Override + protected String encodeSegment(EncodableBitStringFields fields) { + String bitString = bitStringEncoder.encode(fields, getFieldNames()); + String encodedString = base64UrlEncoder.encode(bitString); + return encodedString; + } + + @Override + protected void decodeSegment(String encodedString, EncodableBitStringFields fields) { + if(encodedString == null || encodedString.isEmpty()) { + this.fields.reset(fields); + } + try { + String bitString = base64UrlEncoder.decode(encodedString); + bitStringEncoder.decode(bitString, getFieldNames(), fields); + } catch (Exception e) { + throw new DecodingException("Unable to decode UsNatGpcSegment '" + encodedString + "'", e); + } + } +} diff --git a/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/segment/UsNeCoreSegment.java b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/segment/UsNeCoreSegment.java new file mode 100644 index 00000000..7a98c30f --- /dev/null +++ b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/segment/UsNeCoreSegment.java @@ -0,0 +1,97 @@ +package com.iab.gpp.encoder.segment; + +import java.util.Arrays; +import java.util.List; +import java.util.function.Predicate; +import com.iab.gpp.encoder.base64.AbstractBase64UrlEncoder; +import com.iab.gpp.encoder.base64.CompressedBase64UrlEncoder; +import com.iab.gpp.encoder.bitstring.BitStringEncoder; +import com.iab.gpp.encoder.datatype.EncodableFixedInteger; +import com.iab.gpp.encoder.datatype.EncodableFixedIntegerList; +import com.iab.gpp.encoder.error.DecodingException; +import com.iab.gpp.encoder.field.EncodableBitStringFields; +import com.iab.gpp.encoder.field.UsNeField; +import com.iab.gpp.encoder.field.UsVaField; +import com.iab.gpp.encoder.section.UsNe; + +public class UsNeCoreSegment extends AbstractLazilyEncodableSegment { + + private AbstractBase64UrlEncoder base64UrlEncoder = CompressedBase64UrlEncoder.getInstance(); + private BitStringEncoder bitStringEncoder = BitStringEncoder.getInstance(); + + public UsNeCoreSegment() { + super(); + } + + public UsNeCoreSegment(String encodedString) { + super(); + this.decode(encodedString); + } + + @Override + public List getFieldNames() { + return UsNeField.USNE_CORE_SEGMENT_FIELD_NAMES; + } + + @Override + protected EncodableBitStringFields initializeFields() { + Predicate nullableBooleanAsTwoBitIntegerValidator = (n -> n >= 0 && n <= 2); + Predicate nonNullableBooleanAsTwoBitIntegerValidator = (n -> n >= 1 && n <= 2); + Predicate> nullableBooleanAsTwoBitIntegerListValidator = (l -> { + for (int n : l) { + if (n < 0 || n > 2) { + return false; + } + } + return true; + }); + + EncodableBitStringFields fields = new EncodableBitStringFields(); + fields.put(UsNeField.VERSION, new EncodableFixedInteger(6, UsNe.VERSION)); + fields.put(UsNeField.PROCESSING_NOTICE, + new EncodableFixedInteger(2, 0).withValidator(nullableBooleanAsTwoBitIntegerValidator)); + fields.put(UsNeField.SALE_OPT_OUT_NOTICE, + new EncodableFixedInteger(2, 0).withValidator(nullableBooleanAsTwoBitIntegerValidator)); + fields.put(UsNeField.TARGETED_ADVERTISING_OPT_OUT_NOTICE, + new EncodableFixedInteger(2, 0).withValidator(nullableBooleanAsTwoBitIntegerValidator)); + fields.put(UsNeField.SALE_OPT_OUT, + new EncodableFixedInteger(2, 0).withValidator(nullableBooleanAsTwoBitIntegerValidator)); + fields.put(UsNeField.TARGETED_ADVERTISING_OPT_OUT, + new EncodableFixedInteger(2, 0).withValidator(nullableBooleanAsTwoBitIntegerValidator)); + fields.put(UsNeField.SENSITIVE_DATA_PROCESSING, + new EncodableFixedIntegerList(2, Arrays.asList(0, 0, 0, 0, 0, 0, 0, 0)) + .withValidator(nullableBooleanAsTwoBitIntegerListValidator)); + fields.put(UsVaField.KNOWN_CHILD_SENSITIVE_DATA_CONSENTS, + new EncodableFixedInteger(2, 0).withValidator(nullableBooleanAsTwoBitIntegerValidator)); + fields.put(UsNeField.ADDITIONAL_DATA_PROCESSING_CONSENT, + new EncodableFixedInteger(2, 0).withValidator(nullableBooleanAsTwoBitIntegerValidator)); + fields.put(UsNeField.MSPA_COVERED_TRANSACTION, + new EncodableFixedInteger(2, 1).withValidator(nonNullableBooleanAsTwoBitIntegerValidator)); + fields.put(UsNeField.MSPA_OPT_OUT_OPTION_MODE, + new EncodableFixedInteger(2, 0).withValidator(nullableBooleanAsTwoBitIntegerValidator)); + fields.put(UsNeField.MSPA_SERVICE_PROVIDER_MODE, + new EncodableFixedInteger(2, 0).withValidator(nullableBooleanAsTwoBitIntegerValidator)); + return fields; + } + + @Override + protected String encodeSegment(EncodableBitStringFields fields) { + String bitString = bitStringEncoder.encode(fields, getFieldNames()); + String encodedString = base64UrlEncoder.encode(bitString); + return encodedString; + } + + @Override + protected void decodeSegment(String encodedString, EncodableBitStringFields fields) { + if (encodedString == null || encodedString.isEmpty()) { + this.fields.reset(fields); + } + try { + String bitString = base64UrlEncoder.decode(encodedString); + bitStringEncoder.decode(bitString, getFieldNames(), fields); + } catch (Exception e) { + throw new DecodingException("Unable to decode UsNeCoreSegment '" + encodedString + "'", e); + } + } + +} diff --git a/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/segment/UsNeGpcSegment.java b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/segment/UsNeGpcSegment.java new file mode 100644 index 00000000..6d050371 --- /dev/null +++ b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/segment/UsNeGpcSegment.java @@ -0,0 +1,60 @@ +package com.iab.gpp.encoder.segment; + +import java.util.List; +import com.iab.gpp.encoder.base64.AbstractBase64UrlEncoder; +import com.iab.gpp.encoder.base64.CompressedBase64UrlEncoder; +import com.iab.gpp.encoder.bitstring.BitStringEncoder; +import com.iab.gpp.encoder.datatype.EncodableBoolean; +import com.iab.gpp.encoder.datatype.EncodableFixedInteger; +import com.iab.gpp.encoder.error.DecodingException; +import com.iab.gpp.encoder.field.EncodableBitStringFields; +import com.iab.gpp.encoder.field.UsNeField; + +public class UsNeGpcSegment extends AbstractLazilyEncodableSegment { + + private AbstractBase64UrlEncoder base64UrlEncoder = CompressedBase64UrlEncoder.getInstance(); + private BitStringEncoder bitStringEncoder = BitStringEncoder.getInstance(); + + public UsNeGpcSegment() { + super(); + } + + public UsNeGpcSegment(String encodedString) { + super(); + this.decode(encodedString); + } + + @Override + public List getFieldNames() { + return UsNeField.USNE_GPC_SEGMENT_FIELD_NAMES; + } + + @Override + protected EncodableBitStringFields initializeFields() { + EncodableBitStringFields fields = new EncodableBitStringFields(); + fields.put(UsNeField.GPC_SEGMENT_TYPE, new EncodableFixedInteger(2, 1)); + fields.put(UsNeField.GPC_SEGMENT_INCLUDED, new EncodableBoolean(true)); + fields.put(UsNeField.GPC, new EncodableBoolean(false)); + return fields; + } + + @Override + protected String encodeSegment(EncodableBitStringFields fields) { + String bitString = bitStringEncoder.encode(fields, getFieldNames()); + String encodedString = base64UrlEncoder.encode(bitString); + return encodedString; + } + + @Override + protected void decodeSegment(String encodedString, EncodableBitStringFields fields) { + if(encodedString == null || encodedString.isEmpty()) { + this.fields.reset(fields); + } + try { + String bitString = base64UrlEncoder.decode(encodedString); + bitStringEncoder.decode(bitString, getFieldNames(), fields); + } catch (Exception e) { + throw new DecodingException("Unable to decode UsNeGpcSegment '" + encodedString + "'", e); + } + } +} diff --git a/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/segment/UsNhCoreSegment.java b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/segment/UsNhCoreSegment.java new file mode 100644 index 00000000..76fedd66 --- /dev/null +++ b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/segment/UsNhCoreSegment.java @@ -0,0 +1,96 @@ +package com.iab.gpp.encoder.segment; + +import java.util.Arrays; +import java.util.List; +import java.util.function.Predicate; +import com.iab.gpp.encoder.base64.AbstractBase64UrlEncoder; +import com.iab.gpp.encoder.base64.CompressedBase64UrlEncoder; +import com.iab.gpp.encoder.bitstring.BitStringEncoder; +import com.iab.gpp.encoder.datatype.EncodableFixedInteger; +import com.iab.gpp.encoder.datatype.EncodableFixedIntegerList; +import com.iab.gpp.encoder.error.DecodingException; +import com.iab.gpp.encoder.field.EncodableBitStringFields; +import com.iab.gpp.encoder.field.UsNhField; +import com.iab.gpp.encoder.section.UsNh; + +public class UsNhCoreSegment extends AbstractLazilyEncodableSegment { + + private AbstractBase64UrlEncoder base64UrlEncoder = CompressedBase64UrlEncoder.getInstance(); + private BitStringEncoder bitStringEncoder = BitStringEncoder.getInstance(); + + public UsNhCoreSegment() { + super(); + } + + public UsNhCoreSegment(String encodedString) { + super(); + this.decode(encodedString); + } + + @Override + public List getFieldNames() { + return UsNhField.USNH_CORE_SEGMENT_FIELD_NAMES; + } + + @Override + protected EncodableBitStringFields initializeFields() { + Predicate nullableBooleanAsTwoBitIntegerValidator = (n -> n >= 0 && n <= 2); + Predicate nonNullableBooleanAsTwoBitIntegerValidator = (n -> n >= 1 && n <= 2); + Predicate> nullableBooleanAsTwoBitIntegerListValidator = (l -> { + for (int n : l) { + if (n < 0 || n > 2) { + return false; + } + } + return true; + }); + + EncodableBitStringFields fields = new EncodableBitStringFields(); + fields.put(UsNhField.VERSION, new EncodableFixedInteger(6, UsNh.VERSION)); + fields.put(UsNhField.PROCESSING_NOTICE, + new EncodableFixedInteger(2, 0).withValidator(nullableBooleanAsTwoBitIntegerValidator)); + fields.put(UsNhField.SALE_OPT_OUT_NOTICE, + new EncodableFixedInteger(2, 0).withValidator(nullableBooleanAsTwoBitIntegerValidator)); + fields.put(UsNhField.TARGETED_ADVERTISING_OPT_OUT_NOTICE, + new EncodableFixedInteger(2, 0).withValidator(nullableBooleanAsTwoBitIntegerValidator)); + fields.put(UsNhField.SALE_OPT_OUT, + new EncodableFixedInteger(2, 0).withValidator(nullableBooleanAsTwoBitIntegerValidator)); + fields.put(UsNhField.TARGETED_ADVERTISING_OPT_OUT, + new EncodableFixedInteger(2, 0).withValidator(nullableBooleanAsTwoBitIntegerValidator)); + fields.put(UsNhField.SENSITIVE_DATA_PROCESSING, + new EncodableFixedIntegerList(2, Arrays.asList(0, 0, 0, 0, 0, 0, 0, 0)) + .withValidator(nullableBooleanAsTwoBitIntegerListValidator)); + fields.put(UsNhField.KNOWN_CHILD_SENSITIVE_DATA_CONSENTS, new EncodableFixedIntegerList(2, Arrays.asList(0, 0, 0)) + .withValidator(nullableBooleanAsTwoBitIntegerListValidator)); + fields.put(UsNhField.ADDITIONAL_DATA_PROCESSING_CONSENT, + new EncodableFixedInteger(2, 0).withValidator(nullableBooleanAsTwoBitIntegerValidator)); + fields.put(UsNhField.MSPA_COVERED_TRANSACTION, + new EncodableFixedInteger(2, 1).withValidator(nonNullableBooleanAsTwoBitIntegerValidator)); + fields.put(UsNhField.MSPA_OPT_OUT_OPTION_MODE, + new EncodableFixedInteger(2, 0).withValidator(nullableBooleanAsTwoBitIntegerValidator)); + fields.put(UsNhField.MSPA_SERVICE_PROVIDER_MODE, + new EncodableFixedInteger(2, 0).withValidator(nullableBooleanAsTwoBitIntegerValidator)); + return fields; + } + + @Override + protected String encodeSegment(EncodableBitStringFields fields) { + String bitString = bitStringEncoder.encode(fields, getFieldNames()); + String encodedString = base64UrlEncoder.encode(bitString); + return encodedString; + } + + @Override + protected void decodeSegment(String encodedString, EncodableBitStringFields fields) { + if (encodedString == null || encodedString.isEmpty()) { + this.fields.reset(fields); + } + try { + String bitString = base64UrlEncoder.decode(encodedString); + bitStringEncoder.decode(bitString, getFieldNames(), fields); + } catch (Exception e) { + throw new DecodingException("Unable to decode UsNhCoreSegment '" + encodedString + "'", e); + } + } + +} diff --git a/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/segment/UsNhGpcSegment.java b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/segment/UsNhGpcSegment.java new file mode 100644 index 00000000..86587dd0 --- /dev/null +++ b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/segment/UsNhGpcSegment.java @@ -0,0 +1,60 @@ +package com.iab.gpp.encoder.segment; + +import java.util.List; +import com.iab.gpp.encoder.base64.AbstractBase64UrlEncoder; +import com.iab.gpp.encoder.base64.CompressedBase64UrlEncoder; +import com.iab.gpp.encoder.bitstring.BitStringEncoder; +import com.iab.gpp.encoder.datatype.EncodableBoolean; +import com.iab.gpp.encoder.datatype.EncodableFixedInteger; +import com.iab.gpp.encoder.error.DecodingException; +import com.iab.gpp.encoder.field.EncodableBitStringFields; +import com.iab.gpp.encoder.field.UsNhField; + +public class UsNhGpcSegment extends AbstractLazilyEncodableSegment { + + private AbstractBase64UrlEncoder base64UrlEncoder = CompressedBase64UrlEncoder.getInstance(); + private BitStringEncoder bitStringEncoder = BitStringEncoder.getInstance(); + + public UsNhGpcSegment() { + super(); + } + + public UsNhGpcSegment(String encodedString) { + super(); + this.decode(encodedString); + } + + @Override + public List getFieldNames() { + return UsNhField.USNH_GPC_SEGMENT_FIELD_NAMES; + } + + @Override + protected EncodableBitStringFields initializeFields() { + EncodableBitStringFields fields = new EncodableBitStringFields(); + fields.put(UsNhField.GPC_SEGMENT_TYPE, new EncodableFixedInteger(2, 1)); + fields.put(UsNhField.GPC_SEGMENT_INCLUDED, new EncodableBoolean(true)); + fields.put(UsNhField.GPC, new EncodableBoolean(false)); + return fields; + } + + @Override + protected String encodeSegment(EncodableBitStringFields fields) { + String bitString = bitStringEncoder.encode(fields, getFieldNames()); + String encodedString = base64UrlEncoder.encode(bitString); + return encodedString; + } + + @Override + protected void decodeSegment(String encodedString, EncodableBitStringFields fields) { + if(encodedString == null || encodedString.isEmpty()) { + this.fields.reset(fields); + } + try { + String bitString = base64UrlEncoder.decode(encodedString); + bitStringEncoder.decode(bitString, getFieldNames(), fields); + } catch (Exception e) { + throw new DecodingException("Unable to decode UsNhGpcSegment '" + encodedString + "'", e); + } + } +} diff --git a/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/segment/UsNjCoreSegment.java b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/segment/UsNjCoreSegment.java new file mode 100644 index 00000000..e71fecc1 --- /dev/null +++ b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/segment/UsNjCoreSegment.java @@ -0,0 +1,96 @@ +package com.iab.gpp.encoder.segment; + +import java.util.Arrays; +import java.util.List; +import java.util.function.Predicate; +import com.iab.gpp.encoder.base64.AbstractBase64UrlEncoder; +import com.iab.gpp.encoder.base64.CompressedBase64UrlEncoder; +import com.iab.gpp.encoder.bitstring.BitStringEncoder; +import com.iab.gpp.encoder.datatype.EncodableFixedInteger; +import com.iab.gpp.encoder.datatype.EncodableFixedIntegerList; +import com.iab.gpp.encoder.error.DecodingException; +import com.iab.gpp.encoder.field.EncodableBitStringFields; +import com.iab.gpp.encoder.field.UsNjField; +import com.iab.gpp.encoder.section.UsNj; + +public class UsNjCoreSegment extends AbstractLazilyEncodableSegment { + + private AbstractBase64UrlEncoder base64UrlEncoder = CompressedBase64UrlEncoder.getInstance(); + private BitStringEncoder bitStringEncoder = BitStringEncoder.getInstance(); + + public UsNjCoreSegment() { + super(); + } + + public UsNjCoreSegment(String encodedString) { + super(); + this.decode(encodedString); + } + + @Override + public List getFieldNames() { + return UsNjField.USNJ_CORE_SEGMENT_FIELD_NAMES; + } + + @Override + protected EncodableBitStringFields initializeFields() { + Predicate nullableBooleanAsTwoBitIntegerValidator = (n -> n >= 0 && n <= 2); + Predicate nonNullableBooleanAsTwoBitIntegerValidator = (n -> n >= 1 && n <= 2); + Predicate> nullableBooleanAsTwoBitIntegerListValidator = (l -> { + for (int n : l) { + if (n < 0 || n > 2) { + return false; + } + } + return true; + }); + + EncodableBitStringFields fields = new EncodableBitStringFields(); + fields.put(UsNjField.VERSION, new EncodableFixedInteger(6, UsNj.VERSION)); + fields.put(UsNjField.PROCESSING_NOTICE, + new EncodableFixedInteger(2, 0).withValidator(nullableBooleanAsTwoBitIntegerValidator)); + fields.put(UsNjField.SALE_OPT_OUT_NOTICE, + new EncodableFixedInteger(2, 0).withValidator(nullableBooleanAsTwoBitIntegerValidator)); + fields.put(UsNjField.TARGETED_ADVERTISING_OPT_OUT_NOTICE, + new EncodableFixedInteger(2, 0).withValidator(nullableBooleanAsTwoBitIntegerValidator)); + fields.put(UsNjField.SALE_OPT_OUT, + new EncodableFixedInteger(2, 0).withValidator(nullableBooleanAsTwoBitIntegerValidator)); + fields.put(UsNjField.TARGETED_ADVERTISING_OPT_OUT, + new EncodableFixedInteger(2, 0).withValidator(nullableBooleanAsTwoBitIntegerValidator)); + fields.put(UsNjField.SENSITIVE_DATA_PROCESSING, + new EncodableFixedIntegerList(2, Arrays.asList(0, 0, 0, 0, 0, 0, 0, 0, 0, 0)) + .withValidator(nullableBooleanAsTwoBitIntegerListValidator)); + fields.put(UsNjField.KNOWN_CHILD_SENSITIVE_DATA_CONSENTS, new EncodableFixedIntegerList(2, Arrays.asList(0, 0, 0, 0, 0)) + .withValidator(nullableBooleanAsTwoBitIntegerListValidator)); + fields.put(UsNjField.ADDITIONAL_DATA_PROCESSING_CONSENT, + new EncodableFixedInteger(2, 0).withValidator(nullableBooleanAsTwoBitIntegerValidator)); + fields.put(UsNjField.MSPA_COVERED_TRANSACTION, + new EncodableFixedInteger(2, 1).withValidator(nonNullableBooleanAsTwoBitIntegerValidator)); + fields.put(UsNjField.MSPA_OPT_OUT_OPTION_MODE, + new EncodableFixedInteger(2, 0).withValidator(nullableBooleanAsTwoBitIntegerValidator)); + fields.put(UsNjField.MSPA_SERVICE_PROVIDER_MODE, + new EncodableFixedInteger(2, 0).withValidator(nullableBooleanAsTwoBitIntegerValidator)); + return fields; + } + + @Override + protected String encodeSegment(EncodableBitStringFields fields) { + String bitString = bitStringEncoder.encode(fields, getFieldNames()); + String encodedString = base64UrlEncoder.encode(bitString); + return encodedString; + } + + @Override + protected void decodeSegment(String encodedString, EncodableBitStringFields fields) { + if (encodedString == null || encodedString.isEmpty()) { + this.fields.reset(fields); + } + try { + String bitString = base64UrlEncoder.decode(encodedString); + bitStringEncoder.decode(bitString, getFieldNames(), fields); + } catch (Exception e) { + throw new DecodingException("Unable to decode UsNjCoreSegment '" + encodedString + "'", e); + } + } + +} diff --git a/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/segment/UsNjGpcSegment.java b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/segment/UsNjGpcSegment.java new file mode 100644 index 00000000..37ee7d34 --- /dev/null +++ b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/segment/UsNjGpcSegment.java @@ -0,0 +1,60 @@ +package com.iab.gpp.encoder.segment; + +import java.util.List; +import com.iab.gpp.encoder.base64.AbstractBase64UrlEncoder; +import com.iab.gpp.encoder.base64.CompressedBase64UrlEncoder; +import com.iab.gpp.encoder.bitstring.BitStringEncoder; +import com.iab.gpp.encoder.datatype.EncodableBoolean; +import com.iab.gpp.encoder.datatype.EncodableFixedInteger; +import com.iab.gpp.encoder.error.DecodingException; +import com.iab.gpp.encoder.field.EncodableBitStringFields; +import com.iab.gpp.encoder.field.UsNjField; + +public class UsNjGpcSegment extends AbstractLazilyEncodableSegment { + + private AbstractBase64UrlEncoder base64UrlEncoder = CompressedBase64UrlEncoder.getInstance(); + private BitStringEncoder bitStringEncoder = BitStringEncoder.getInstance(); + + public UsNjGpcSegment() { + super(); + } + + public UsNjGpcSegment(String encodedString) { + super(); + this.decode(encodedString); + } + + @Override + public List getFieldNames() { + return UsNjField.USNJ_GPC_SEGMENT_FIELD_NAMES; + } + + @Override + protected EncodableBitStringFields initializeFields() { + EncodableBitStringFields fields = new EncodableBitStringFields(); + fields.put(UsNjField.GPC_SEGMENT_TYPE, new EncodableFixedInteger(2, 1)); + fields.put(UsNjField.GPC_SEGMENT_INCLUDED, new EncodableBoolean(true)); + fields.put(UsNjField.GPC, new EncodableBoolean(false)); + return fields; + } + + @Override + protected String encodeSegment(EncodableBitStringFields fields) { + String bitString = bitStringEncoder.encode(fields, getFieldNames()); + String encodedString = base64UrlEncoder.encode(bitString); + return encodedString; + } + + @Override + protected void decodeSegment(String encodedString, EncodableBitStringFields fields) { + if(encodedString == null || encodedString.isEmpty()) { + this.fields.reset(fields); + } + try { + String bitString = base64UrlEncoder.decode(encodedString); + bitStringEncoder.decode(bitString, getFieldNames(), fields); + } catch (Exception e) { + throw new DecodingException("Unable to decode UsNjGpcSegment '" + encodedString + "'", e); + } + } +} diff --git a/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/segment/UsOrCoreSegment.java b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/segment/UsOrCoreSegment.java new file mode 100644 index 00000000..c09ebd15 --- /dev/null +++ b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/segment/UsOrCoreSegment.java @@ -0,0 +1,96 @@ +package com.iab.gpp.encoder.segment; + +import java.util.Arrays; +import java.util.List; +import java.util.function.Predicate; +import com.iab.gpp.encoder.base64.AbstractBase64UrlEncoder; +import com.iab.gpp.encoder.base64.CompressedBase64UrlEncoder; +import com.iab.gpp.encoder.bitstring.BitStringEncoder; +import com.iab.gpp.encoder.datatype.EncodableFixedInteger; +import com.iab.gpp.encoder.datatype.EncodableFixedIntegerList; +import com.iab.gpp.encoder.error.DecodingException; +import com.iab.gpp.encoder.field.EncodableBitStringFields; +import com.iab.gpp.encoder.field.UsOrField; +import com.iab.gpp.encoder.section.UsOr; + +public class UsOrCoreSegment extends AbstractLazilyEncodableSegment { + + private AbstractBase64UrlEncoder base64UrlEncoder = CompressedBase64UrlEncoder.getInstance(); + private BitStringEncoder bitStringEncoder = BitStringEncoder.getInstance(); + + public UsOrCoreSegment() { + super(); + } + + public UsOrCoreSegment(String encodedString) { + super(); + this.decode(encodedString); + } + + @Override + public List getFieldNames() { + return UsOrField.USOR_CORE_SEGMENT_FIELD_NAMES; + } + + @Override + protected EncodableBitStringFields initializeFields() { + Predicate nullableBooleanAsTwoBitIntegerValidator = (n -> n >= 0 && n <= 2); + Predicate nonNullableBooleanAsTwoBitIntegerValidator = (n -> n >= 1 && n <= 2); + Predicate> nullableBooleanAsTwoBitIntegerListValidator = (l -> { + for (int n : l) { + if (n < 0 || n > 2) { + return false; + } + } + return true; + }); + + EncodableBitStringFields fields = new EncodableBitStringFields(); + fields.put(UsOrField.VERSION, new EncodableFixedInteger(6, UsOr.VERSION)); + fields.put(UsOrField.PROCESSING_NOTICE, + new EncodableFixedInteger(2, 0).withValidator(nullableBooleanAsTwoBitIntegerValidator)); + fields.put(UsOrField.SALE_OPT_OUT_NOTICE, + new EncodableFixedInteger(2, 0).withValidator(nullableBooleanAsTwoBitIntegerValidator)); + fields.put(UsOrField.TARGETED_ADVERTISING_OPT_OUT_NOTICE, + new EncodableFixedInteger(2, 0).withValidator(nullableBooleanAsTwoBitIntegerValidator)); + fields.put(UsOrField.SALE_OPT_OUT, + new EncodableFixedInteger(2, 0).withValidator(nullableBooleanAsTwoBitIntegerValidator)); + fields.put(UsOrField.TARGETED_ADVERTISING_OPT_OUT, + new EncodableFixedInteger(2, 0).withValidator(nullableBooleanAsTwoBitIntegerValidator)); + fields.put(UsOrField.SENSITIVE_DATA_PROCESSING, + new EncodableFixedIntegerList(2, Arrays.asList(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)) + .withValidator(nullableBooleanAsTwoBitIntegerListValidator)); + fields.put(UsOrField.KNOWN_CHILD_SENSITIVE_DATA_CONSENTS, new EncodableFixedIntegerList(2, Arrays.asList(0, 0, 0)) + .withValidator(nullableBooleanAsTwoBitIntegerListValidator)); + fields.put(UsOrField.ADDITIONAL_DATA_PROCESSING_CONSENT, + new EncodableFixedInteger(2, 0).withValidator(nullableBooleanAsTwoBitIntegerValidator)); + fields.put(UsOrField.MSPA_COVERED_TRANSACTION, + new EncodableFixedInteger(2, 1).withValidator(nonNullableBooleanAsTwoBitIntegerValidator)); + fields.put(UsOrField.MSPA_OPT_OUT_OPTION_MODE, + new EncodableFixedInteger(2, 0).withValidator(nullableBooleanAsTwoBitIntegerValidator)); + fields.put(UsOrField.MSPA_SERVICE_PROVIDER_MODE, + new EncodableFixedInteger(2, 0).withValidator(nullableBooleanAsTwoBitIntegerValidator)); + return fields; + } + + @Override + protected String encodeSegment(EncodableBitStringFields fields) { + String bitString = bitStringEncoder.encode(fields, getFieldNames()); + String encodedString = base64UrlEncoder.encode(bitString); + return encodedString; + } + + @Override + protected void decodeSegment(String encodedString, EncodableBitStringFields fields) { + if (encodedString == null || encodedString.isEmpty()) { + this.fields.reset(fields); + } + try { + String bitString = base64UrlEncoder.decode(encodedString); + bitStringEncoder.decode(bitString, getFieldNames(), fields); + } catch (Exception e) { + throw new DecodingException("Unable to decode UsOrCoreSegment '" + encodedString + "'", e); + } + } + +} diff --git a/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/segment/UsOrGpcSegment.java b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/segment/UsOrGpcSegment.java new file mode 100644 index 00000000..6818e7de --- /dev/null +++ b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/segment/UsOrGpcSegment.java @@ -0,0 +1,60 @@ +package com.iab.gpp.encoder.segment; + +import java.util.List; +import com.iab.gpp.encoder.base64.AbstractBase64UrlEncoder; +import com.iab.gpp.encoder.base64.CompressedBase64UrlEncoder; +import com.iab.gpp.encoder.bitstring.BitStringEncoder; +import com.iab.gpp.encoder.datatype.EncodableBoolean; +import com.iab.gpp.encoder.datatype.EncodableFixedInteger; +import com.iab.gpp.encoder.error.DecodingException; +import com.iab.gpp.encoder.field.EncodableBitStringFields; +import com.iab.gpp.encoder.field.UsOrField; + +public class UsOrGpcSegment extends AbstractLazilyEncodableSegment { + + private AbstractBase64UrlEncoder base64UrlEncoder = CompressedBase64UrlEncoder.getInstance(); + private BitStringEncoder bitStringEncoder = BitStringEncoder.getInstance(); + + public UsOrGpcSegment() { + super(); + } + + public UsOrGpcSegment(String encodedString) { + super(); + this.decode(encodedString); + } + + @Override + public List getFieldNames() { + return UsOrField.USOR_GPC_SEGMENT_FIELD_NAMES; + } + + @Override + protected EncodableBitStringFields initializeFields() { + EncodableBitStringFields fields = new EncodableBitStringFields(); + fields.put(UsOrField.GPC_SEGMENT_TYPE, new EncodableFixedInteger(2, 1)); + fields.put(UsOrField.GPC_SEGMENT_INCLUDED, new EncodableBoolean(true)); + fields.put(UsOrField.GPC, new EncodableBoolean(false)); + return fields; + } + + @Override + protected String encodeSegment(EncodableBitStringFields fields) { + String bitString = bitStringEncoder.encode(fields, getFieldNames()); + String encodedString = base64UrlEncoder.encode(bitString); + return encodedString; + } + + @Override + protected void decodeSegment(String encodedString, EncodableBitStringFields fields) { + if(encodedString == null || encodedString.isEmpty()) { + this.fields.reset(fields); + } + try { + String bitString = base64UrlEncoder.decode(encodedString); + bitStringEncoder.decode(bitString, getFieldNames(), fields); + } catch (Exception e) { + throw new DecodingException("Unable to decode UsOrGpcSegment '" + encodedString + "'", e); + } + } +} diff --git a/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/segment/UsTnCoreSegment.java b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/segment/UsTnCoreSegment.java new file mode 100644 index 00000000..425f1305 --- /dev/null +++ b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/segment/UsTnCoreSegment.java @@ -0,0 +1,96 @@ +package com.iab.gpp.encoder.segment; + +import java.util.Arrays; +import java.util.List; +import java.util.function.Predicate; +import com.iab.gpp.encoder.base64.AbstractBase64UrlEncoder; +import com.iab.gpp.encoder.base64.CompressedBase64UrlEncoder; +import com.iab.gpp.encoder.bitstring.BitStringEncoder; +import com.iab.gpp.encoder.datatype.EncodableFixedInteger; +import com.iab.gpp.encoder.datatype.EncodableFixedIntegerList; +import com.iab.gpp.encoder.error.DecodingException; +import com.iab.gpp.encoder.field.EncodableBitStringFields; +import com.iab.gpp.encoder.field.UsTnField; +import com.iab.gpp.encoder.section.UsTn; + +public class UsTnCoreSegment extends AbstractLazilyEncodableSegment { + + private AbstractBase64UrlEncoder base64UrlEncoder = CompressedBase64UrlEncoder.getInstance(); + private BitStringEncoder bitStringEncoder = BitStringEncoder.getInstance(); + + public UsTnCoreSegment() { + super(); + } + + public UsTnCoreSegment(String encodedString) { + super(); + this.decode(encodedString); + } + + @Override + public List getFieldNames() { + return UsTnField.USTN_CORE_SEGMENT_FIELD_NAMES; + } + + @Override + protected EncodableBitStringFields initializeFields() { + Predicate nullableBooleanAsTwoBitIntegerValidator = (n -> n >= 0 && n <= 2); + Predicate nonNullableBooleanAsTwoBitIntegerValidator = (n -> n >= 1 && n <= 2); + Predicate> nullableBooleanAsTwoBitIntegerListValidator = (l -> { + for (int n : l) { + if (n < 0 || n > 2) { + return false; + } + } + return true; + }); + + EncodableBitStringFields fields = new EncodableBitStringFields(); + fields.put(UsTnField.VERSION, new EncodableFixedInteger(6, UsTn.VERSION)); + fields.put(UsTnField.PROCESSING_NOTICE, + new EncodableFixedInteger(2, 0).withValidator(nullableBooleanAsTwoBitIntegerValidator)); + fields.put(UsTnField.SALE_OPT_OUT_NOTICE, + new EncodableFixedInteger(2, 0).withValidator(nullableBooleanAsTwoBitIntegerValidator)); + fields.put(UsTnField.TARGETED_ADVERTISING_OPT_OUT_NOTICE, + new EncodableFixedInteger(2, 0).withValidator(nullableBooleanAsTwoBitIntegerValidator)); + fields.put(UsTnField.SALE_OPT_OUT, + new EncodableFixedInteger(2, 0).withValidator(nullableBooleanAsTwoBitIntegerValidator)); + fields.put(UsTnField.TARGETED_ADVERTISING_OPT_OUT, + new EncodableFixedInteger(2, 0).withValidator(nullableBooleanAsTwoBitIntegerValidator)); + fields.put(UsTnField.SENSITIVE_DATA_PROCESSING, + new EncodableFixedIntegerList(2, Arrays.asList(0, 0, 0, 0, 0, 0, 0, 0)) + .withValidator(nullableBooleanAsTwoBitIntegerListValidator)); + fields.put(UsTnField.KNOWN_CHILD_SENSITIVE_DATA_CONSENTS, + new EncodableFixedInteger(2, 0).withValidator(nullableBooleanAsTwoBitIntegerValidator)); + fields.put(UsTnField.ADDITIONAL_DATA_PROCESSING_CONSENT, + new EncodableFixedInteger(2, 0).withValidator(nullableBooleanAsTwoBitIntegerValidator)); + fields.put(UsTnField.MSPA_COVERED_TRANSACTION, + new EncodableFixedInteger(2, 1).withValidator(nonNullableBooleanAsTwoBitIntegerValidator)); + fields.put(UsTnField.MSPA_OPT_OUT_OPTION_MODE, + new EncodableFixedInteger(2, 0).withValidator(nullableBooleanAsTwoBitIntegerValidator)); + fields.put(UsTnField.MSPA_SERVICE_PROVIDER_MODE, + new EncodableFixedInteger(2, 0).withValidator(nullableBooleanAsTwoBitIntegerValidator)); + return fields; + } + + @Override + protected String encodeSegment(EncodableBitStringFields fields) { + String bitString = bitStringEncoder.encode(fields, getFieldNames()); + String encodedString = base64UrlEncoder.encode(bitString); + return encodedString; + } + + @Override + protected void decodeSegment(String encodedString, EncodableBitStringFields fields) { + if (encodedString == null || encodedString.isEmpty()) { + this.fields.reset(fields); + } + try { + String bitString = base64UrlEncoder.decode(encodedString); + bitStringEncoder.decode(bitString, getFieldNames(), fields); + } catch (Exception e) { + throw new DecodingException("Unable to decode UsTnCoreSegment '" + encodedString + "'", e); + } + } + +} diff --git a/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/segment/UsTnGpcSegment.java b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/segment/UsTnGpcSegment.java new file mode 100644 index 00000000..f4a0b32c --- /dev/null +++ b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/segment/UsTnGpcSegment.java @@ -0,0 +1,60 @@ +package com.iab.gpp.encoder.segment; + +import java.util.List; +import com.iab.gpp.encoder.base64.AbstractBase64UrlEncoder; +import com.iab.gpp.encoder.base64.CompressedBase64UrlEncoder; +import com.iab.gpp.encoder.bitstring.BitStringEncoder; +import com.iab.gpp.encoder.datatype.EncodableBoolean; +import com.iab.gpp.encoder.datatype.EncodableFixedInteger; +import com.iab.gpp.encoder.error.DecodingException; +import com.iab.gpp.encoder.field.EncodableBitStringFields; +import com.iab.gpp.encoder.field.UsTnField; + +public class UsTnGpcSegment extends AbstractLazilyEncodableSegment { + + private AbstractBase64UrlEncoder base64UrlEncoder = CompressedBase64UrlEncoder.getInstance(); + private BitStringEncoder bitStringEncoder = BitStringEncoder.getInstance(); + + public UsTnGpcSegment() { + super(); + } + + public UsTnGpcSegment(String encodedString) { + super(); + this.decode(encodedString); + } + + @Override + public List getFieldNames() { + return UsTnField.USTN_GPC_SEGMENT_FIELD_NAMES; + } + + @Override + protected EncodableBitStringFields initializeFields() { + EncodableBitStringFields fields = new EncodableBitStringFields(); + fields.put(UsTnField.GPC_SEGMENT_TYPE, new EncodableFixedInteger(2, 1)); + fields.put(UsTnField.GPC_SEGMENT_INCLUDED, new EncodableBoolean(true)); + fields.put(UsTnField.GPC, new EncodableBoolean(false)); + return fields; + } + + @Override + protected String encodeSegment(EncodableBitStringFields fields) { + String bitString = bitStringEncoder.encode(fields, getFieldNames()); + String encodedString = base64UrlEncoder.encode(bitString); + return encodedString; + } + + @Override + protected void decodeSegment(String encodedString, EncodableBitStringFields fields) { + if(encodedString == null || encodedString.isEmpty()) { + this.fields.reset(fields); + } + try { + String bitString = base64UrlEncoder.decode(encodedString); + bitStringEncoder.decode(bitString, getFieldNames(), fields); + } catch (Exception e) { + throw new DecodingException("Unable to decode UsTnGpcSegment '" + encodedString + "'", e); + } + } +} diff --git a/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/segment/UsTxCoreSegment.java b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/segment/UsTxCoreSegment.java new file mode 100644 index 00000000..53463d20 --- /dev/null +++ b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/segment/UsTxCoreSegment.java @@ -0,0 +1,97 @@ +package com.iab.gpp.encoder.segment; + +import java.util.Arrays; +import java.util.List; +import java.util.function.Predicate; +import com.iab.gpp.encoder.base64.AbstractBase64UrlEncoder; +import com.iab.gpp.encoder.base64.CompressedBase64UrlEncoder; +import com.iab.gpp.encoder.bitstring.BitStringEncoder; +import com.iab.gpp.encoder.datatype.EncodableFixedInteger; +import com.iab.gpp.encoder.datatype.EncodableFixedIntegerList; +import com.iab.gpp.encoder.error.DecodingException; +import com.iab.gpp.encoder.field.EncodableBitStringFields; +import com.iab.gpp.encoder.field.UsTxField; +import com.iab.gpp.encoder.field.UsVaField; +import com.iab.gpp.encoder.section.UsTx; + +public class UsTxCoreSegment extends AbstractLazilyEncodableSegment { + + private AbstractBase64UrlEncoder base64UrlEncoder = CompressedBase64UrlEncoder.getInstance(); + private BitStringEncoder bitStringEncoder = BitStringEncoder.getInstance(); + + public UsTxCoreSegment() { + super(); + } + + public UsTxCoreSegment(String encodedString) { + super(); + this.decode(encodedString); + } + + @Override + public List getFieldNames() { + return UsTxField.USTX_CORE_SEGMENT_FIELD_NAMES; + } + + @Override + protected EncodableBitStringFields initializeFields() { + Predicate nullableBooleanAsTwoBitIntegerValidator = (n -> n >= 0 && n <= 2); + Predicate nonNullableBooleanAsTwoBitIntegerValidator = (n -> n >= 1 && n <= 2); + Predicate> nullableBooleanAsTwoBitIntegerListValidator = (l -> { + for (int n : l) { + if (n < 0 || n > 2) { + return false; + } + } + return true; + }); + + EncodableBitStringFields fields = new EncodableBitStringFields(); + fields.put(UsTxField.VERSION, new EncodableFixedInteger(6, UsTx.VERSION)); + fields.put(UsTxField.PROCESSING_NOTICE, + new EncodableFixedInteger(2, 0).withValidator(nullableBooleanAsTwoBitIntegerValidator)); + fields.put(UsTxField.SALE_OPT_OUT_NOTICE, + new EncodableFixedInteger(2, 0).withValidator(nullableBooleanAsTwoBitIntegerValidator)); + fields.put(UsTxField.TARGETED_ADVERTISING_OPT_OUT_NOTICE, + new EncodableFixedInteger(2, 0).withValidator(nullableBooleanAsTwoBitIntegerValidator)); + fields.put(UsTxField.SALE_OPT_OUT, + new EncodableFixedInteger(2, 0).withValidator(nullableBooleanAsTwoBitIntegerValidator)); + fields.put(UsTxField.TARGETED_ADVERTISING_OPT_OUT, + new EncodableFixedInteger(2, 0).withValidator(nullableBooleanAsTwoBitIntegerValidator)); + fields.put(UsTxField.SENSITIVE_DATA_PROCESSING, + new EncodableFixedIntegerList(2, Arrays.asList(0, 0, 0, 0, 0, 0, 0, 0)) + .withValidator(nullableBooleanAsTwoBitIntegerListValidator)); + fields.put(UsVaField.KNOWN_CHILD_SENSITIVE_DATA_CONSENTS, + new EncodableFixedInteger(2, 0).withValidator(nullableBooleanAsTwoBitIntegerValidator)); + fields.put(UsTxField.ADDITIONAL_DATA_PROCESSING_CONSENT, + new EncodableFixedInteger(2, 0).withValidator(nullableBooleanAsTwoBitIntegerValidator)); + fields.put(UsTxField.MSPA_COVERED_TRANSACTION, + new EncodableFixedInteger(2, 1).withValidator(nonNullableBooleanAsTwoBitIntegerValidator)); + fields.put(UsTxField.MSPA_OPT_OUT_OPTION_MODE, + new EncodableFixedInteger(2, 0).withValidator(nullableBooleanAsTwoBitIntegerValidator)); + fields.put(UsTxField.MSPA_SERVICE_PROVIDER_MODE, + new EncodableFixedInteger(2, 0).withValidator(nullableBooleanAsTwoBitIntegerValidator)); + return fields; + } + + @Override + protected String encodeSegment(EncodableBitStringFields fields) { + String bitString = bitStringEncoder.encode(fields, getFieldNames()); + String encodedString = base64UrlEncoder.encode(bitString); + return encodedString; + } + + @Override + protected void decodeSegment(String encodedString, EncodableBitStringFields fields) { + if (encodedString == null || encodedString.isEmpty()) { + this.fields.reset(fields); + } + try { + String bitString = base64UrlEncoder.decode(encodedString); + bitStringEncoder.decode(bitString, getFieldNames(), fields); + } catch (Exception e) { + throw new DecodingException("Unable to decode UsTxCoreSegment '" + encodedString + "'", e); + } + } + +} diff --git a/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/segment/UsTxGpcSegment.java b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/segment/UsTxGpcSegment.java new file mode 100644 index 00000000..df936b51 --- /dev/null +++ b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/segment/UsTxGpcSegment.java @@ -0,0 +1,60 @@ +package com.iab.gpp.encoder.segment; + +import java.util.List; +import com.iab.gpp.encoder.base64.AbstractBase64UrlEncoder; +import com.iab.gpp.encoder.base64.CompressedBase64UrlEncoder; +import com.iab.gpp.encoder.bitstring.BitStringEncoder; +import com.iab.gpp.encoder.datatype.EncodableBoolean; +import com.iab.gpp.encoder.datatype.EncodableFixedInteger; +import com.iab.gpp.encoder.error.DecodingException; +import com.iab.gpp.encoder.field.EncodableBitStringFields; +import com.iab.gpp.encoder.field.UsTxField; + +public class UsTxGpcSegment extends AbstractLazilyEncodableSegment { + + private AbstractBase64UrlEncoder base64UrlEncoder = CompressedBase64UrlEncoder.getInstance(); + private BitStringEncoder bitStringEncoder = BitStringEncoder.getInstance(); + + public UsTxGpcSegment() { + super(); + } + + public UsTxGpcSegment(String encodedString) { + super(); + this.decode(encodedString); + } + + @Override + public List getFieldNames() { + return UsTxField.USTX_GPC_SEGMENT_FIELD_NAMES; + } + + @Override + protected EncodableBitStringFields initializeFields() { + EncodableBitStringFields fields = new EncodableBitStringFields(); + fields.put(UsTxField.GPC_SEGMENT_TYPE, new EncodableFixedInteger(2, 1)); + fields.put(UsTxField.GPC_SEGMENT_INCLUDED, new EncodableBoolean(true)); + fields.put(UsTxField.GPC, new EncodableBoolean(false)); + return fields; + } + + @Override + protected String encodeSegment(EncodableBitStringFields fields) { + String bitString = bitStringEncoder.encode(fields, getFieldNames()); + String encodedString = base64UrlEncoder.encode(bitString); + return encodedString; + } + + @Override + protected void decodeSegment(String encodedString, EncodableBitStringFields fields) { + if(encodedString == null || encodedString.isEmpty()) { + this.fields.reset(fields); + } + try { + String bitString = base64UrlEncoder.decode(encodedString); + bitStringEncoder.decode(bitString, getFieldNames(), fields); + } catch (Exception e) { + throw new DecodingException("Unable to decode UsTxGpcSegment '" + encodedString + "'", e); + } + } +} diff --git a/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/segment/UsUtCoreSegment.java b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/segment/UsUtCoreSegment.java new file mode 100644 index 00000000..1b394443 --- /dev/null +++ b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/segment/UsUtCoreSegment.java @@ -0,0 +1,96 @@ +package com.iab.gpp.encoder.segment; + +import java.util.Arrays; +import java.util.List; +import java.util.function.Predicate; +import com.iab.gpp.encoder.base64.AbstractBase64UrlEncoder; +import com.iab.gpp.encoder.base64.CompressedBase64UrlEncoder; +import com.iab.gpp.encoder.bitstring.BitStringEncoder; +import com.iab.gpp.encoder.datatype.EncodableFixedInteger; +import com.iab.gpp.encoder.datatype.EncodableFixedIntegerList; +import com.iab.gpp.encoder.error.DecodingException; +import com.iab.gpp.encoder.field.EncodableBitStringFields; +import com.iab.gpp.encoder.field.UsUtField; +import com.iab.gpp.encoder.section.UsUt; + +public class UsUtCoreSegment extends AbstractLazilyEncodableSegment { + + private AbstractBase64UrlEncoder base64UrlEncoder = CompressedBase64UrlEncoder.getInstance(); + private BitStringEncoder bitStringEncoder = BitStringEncoder.getInstance(); + + public UsUtCoreSegment() { + super(); + } + + public UsUtCoreSegment(String encodedString) { + super(); + this.decode(encodedString); + } + + @Override + public List getFieldNames() { + return UsUtField.USUT_CORE_SEGMENT_FIELD_NAMES; + } + + @Override + protected EncodableBitStringFields initializeFields() { + Predicate nullableBooleanAsTwoBitIntegerValidator = (n -> n >= 0 && n <= 2); + Predicate nonNullableBooleanAsTwoBitIntegerValidator = (n -> n >= 1 && n <= 2); + Predicate> nullableBooleanAsTwoBitIntegerListValidator = (l -> { + for (int n : l) { + if (n < 0 || n > 2) { + return false; + } + } + return true; + }); + + EncodableBitStringFields fields = new EncodableBitStringFields(); + fields.put(UsUtField.VERSION, new EncodableFixedInteger(6, UsUt.VERSION)); + fields.put(UsUtField.SHARING_NOTICE, + new EncodableFixedInteger(2, 0).withValidator(nullableBooleanAsTwoBitIntegerValidator)); + fields.put(UsUtField.SALE_OPT_OUT_NOTICE, + new EncodableFixedInteger(2, 0).withValidator(nullableBooleanAsTwoBitIntegerValidator)); + fields.put(UsUtField.TARGETED_ADVERTISING_OPT_OUT_NOTICE, + new EncodableFixedInteger(2, 0).withValidator(nullableBooleanAsTwoBitIntegerValidator)); + fields.put(UsUtField.SENSITIVE_DATA_PROCESSING_OPT_OUT_NOTICE, + new EncodableFixedInteger(2, 0).withValidator(nullableBooleanAsTwoBitIntegerValidator)); + fields.put(UsUtField.SALE_OPT_OUT, + new EncodableFixedInteger(2, 0).withValidator(nullableBooleanAsTwoBitIntegerValidator)); + fields.put(UsUtField.TARGETED_ADVERTISING_OPT_OUT, + new EncodableFixedInteger(2, 0).withValidator(nullableBooleanAsTwoBitIntegerValidator)); + fields.put(UsUtField.SENSITIVE_DATA_PROCESSING, + new EncodableFixedIntegerList(2, Arrays.asList(0, 0, 0, 0, 0, 0, 0, 0)) + .withValidator(nullableBooleanAsTwoBitIntegerListValidator)); + fields.put(UsUtField.KNOWN_CHILD_SENSITIVE_DATA_CONSENTS, + new EncodableFixedInteger(2, 0).withValidator(nullableBooleanAsTwoBitIntegerValidator)); + fields.put(UsUtField.MSPA_COVERED_TRANSACTION, + new EncodableFixedInteger(2, 1).withValidator(nonNullableBooleanAsTwoBitIntegerValidator)); + fields.put(UsUtField.MSPA_OPT_OUT_OPTION_MODE, + new EncodableFixedInteger(2, 0).withValidator(nullableBooleanAsTwoBitIntegerValidator)); + fields.put(UsUtField.MSPA_SERVICE_PROVIDER_MODE, + new EncodableFixedInteger(2, 0).withValidator(nullableBooleanAsTwoBitIntegerValidator)); + return fields; + } + + @Override + protected String encodeSegment(EncodableBitStringFields fields) { + String bitString = bitStringEncoder.encode(fields, getFieldNames()); + String encodedString = base64UrlEncoder.encode(bitString); + return encodedString; + } + + @Override + protected void decodeSegment(String encodedString, EncodableBitStringFields fields) { + if (encodedString == null || encodedString.isEmpty()) { + this.fields.reset(fields); + } + try { + String bitString = base64UrlEncoder.decode(encodedString); + bitStringEncoder.decode(bitString, getFieldNames(), fields); + } catch (Exception e) { + throw new DecodingException("Unable to decode UsUtCoreSegment '" + encodedString + "'", e); + } + } + +} diff --git a/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/segment/UsVaCoreSegment.java b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/segment/UsVaCoreSegment.java new file mode 100644 index 00000000..cb57fb92 --- /dev/null +++ b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/segment/UsVaCoreSegment.java @@ -0,0 +1,94 @@ +package com.iab.gpp.encoder.segment; + +import java.util.Arrays; +import java.util.List; +import java.util.function.Predicate; +import com.iab.gpp.encoder.base64.AbstractBase64UrlEncoder; +import com.iab.gpp.encoder.base64.CompressedBase64UrlEncoder; +import com.iab.gpp.encoder.bitstring.BitStringEncoder; +import com.iab.gpp.encoder.datatype.EncodableFixedInteger; +import com.iab.gpp.encoder.datatype.EncodableFixedIntegerList; +import com.iab.gpp.encoder.error.DecodingException; +import com.iab.gpp.encoder.field.EncodableBitStringFields; +import com.iab.gpp.encoder.field.UsVaField; +import com.iab.gpp.encoder.section.UsVa; + +public class UsVaCoreSegment extends AbstractLazilyEncodableSegment { + + private AbstractBase64UrlEncoder base64UrlEncoder = CompressedBase64UrlEncoder.getInstance(); + private BitStringEncoder bitStringEncoder = BitStringEncoder.getInstance(); + + public UsVaCoreSegment() { + super(); + } + + public UsVaCoreSegment(String encodedString) { + super(); + this.decode(encodedString); + } + + @Override + public List getFieldNames() { + return UsVaField.USVA_CORE_SEGMENT_FIELD_NAMES; + } + + @Override + protected EncodableBitStringFields initializeFields() { + Predicate nullableBooleanAsTwoBitIntegerValidator = (n -> n >= 0 && n <= 2); + Predicate nonNullableBooleanAsTwoBitIntegerValidator = (n -> n >= 1 && n <= 2); + Predicate> nullableBooleanAsTwoBitIntegerListValidator = (l -> { + for (int n : l) { + if (n < 0 || n > 2) { + return false; + } + } + return true; + }); + + EncodableBitStringFields fields = new EncodableBitStringFields(); + fields.put(UsVaField.VERSION, new EncodableFixedInteger(6, UsVa.VERSION)); + fields.put(UsVaField.SHARING_NOTICE, + new EncodableFixedInteger(2, 0).withValidator(nullableBooleanAsTwoBitIntegerValidator)); + fields.put(UsVaField.SALE_OPT_OUT_NOTICE, + new EncodableFixedInteger(2, 0).withValidator(nullableBooleanAsTwoBitIntegerValidator)); + fields.put(UsVaField.TARGETED_ADVERTISING_OPT_OUT_NOTICE, + new EncodableFixedInteger(2, 0).withValidator(nullableBooleanAsTwoBitIntegerValidator)); + fields.put(UsVaField.SALE_OPT_OUT, + new EncodableFixedInteger(2, 0).withValidator(nullableBooleanAsTwoBitIntegerValidator)); + fields.put(UsVaField.TARGETED_ADVERTISING_OPT_OUT, + new EncodableFixedInteger(2, 0).withValidator(nullableBooleanAsTwoBitIntegerValidator)); + fields.put(UsVaField.SENSITIVE_DATA_PROCESSING, + new EncodableFixedIntegerList(2, Arrays.asList(0, 0, 0, 0, 0, 0, 0, 0)) + .withValidator(nullableBooleanAsTwoBitIntegerListValidator)); + fields.put(UsVaField.KNOWN_CHILD_SENSITIVE_DATA_CONSENTS, + new EncodableFixedInteger(2, 0).withValidator(nullableBooleanAsTwoBitIntegerValidator)); + fields.put(UsVaField.MSPA_COVERED_TRANSACTION, + new EncodableFixedInteger(2, 1).withValidator(nonNullableBooleanAsTwoBitIntegerValidator)); + fields.put(UsVaField.MSPA_OPT_OUT_OPTION_MODE, + new EncodableFixedInteger(2, 0).withValidator(nullableBooleanAsTwoBitIntegerValidator)); + fields.put(UsVaField.MSPA_SERVICE_PROVIDER_MODE, + new EncodableFixedInteger(2, 0).withValidator(nullableBooleanAsTwoBitIntegerValidator)); + return fields; + } + + @Override + protected String encodeSegment(EncodableBitStringFields fields) { + String bitString = bitStringEncoder.encode(fields, getFieldNames()); + String encodedString = base64UrlEncoder.encode(bitString); + return encodedString; + } + + @Override + protected void decodeSegment(String encodedString, EncodableBitStringFields fields) { + if (encodedString == null || encodedString.isEmpty()) { + this.fields.reset(fields); + } + try { + String bitString = base64UrlEncoder.decode(encodedString); + bitStringEncoder.decode(bitString, getFieldNames(), fields); + } catch (Exception e) { + throw new DecodingException("Unable to decode UsVaCoreSegment '" + encodedString + "'", e); + } + } + +} diff --git a/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/segment/UspV1CoreSegment.java b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/segment/UspV1CoreSegment.java new file mode 100644 index 00000000..59b3c557 --- /dev/null +++ b/iabgpp-encoder/src/main/java/com/iab/gpp/encoder/segment/UspV1CoreSegment.java @@ -0,0 +1,64 @@ +package com.iab.gpp.encoder.segment; + +import java.util.List; +import com.iab.gpp.encoder.datatype.UnencodableCharacter; +import com.iab.gpp.encoder.datatype.UnencodableInteger; +import com.iab.gpp.encoder.error.DecodingException; +import com.iab.gpp.encoder.field.GenericFields; +import com.iab.gpp.encoder.field.UspV1Field; +import com.iab.gpp.encoder.section.UspV1; + +public class UspV1CoreSegment extends AbstractLazilyEncodableSegment { + + public UspV1CoreSegment() { + super(); + } + + public UspV1CoreSegment(String encodedString) { + super(); + this.decode(encodedString); + } + + @Override + public List getFieldNames() { + return UspV1Field.USPV1_CORE_SEGMENT_FIELD_NAMES; + } + + @Override + protected GenericFields initializeFields() { + GenericFields fields = new GenericFields(); + fields.put(UspV1Field.VERSION, new UnencodableInteger(UspV1.VERSION)); + fields.put(UspV1Field.NOTICE, new UnencodableCharacter('-', (v -> v == 'Y' || v == 'N' || v == '-'))); + fields.put(UspV1Field.OPT_OUT_SALE, new UnencodableCharacter('-', (v -> v == 'Y' || v == 'N' || v == '-'))); + fields.put(UspV1Field.LSPA_COVERED, new UnencodableCharacter('-', (v -> v == 'Y' || v == 'N' || v == '-'))); + return fields; + } + + @Override + protected String encodeSegment(GenericFields fields) { + String str = ""; + str += fields.get(UspV1Field.VERSION).getValue(); + str += fields.get(UspV1Field.NOTICE).getValue(); + str += fields.get(UspV1Field.OPT_OUT_SALE).getValue(); + str += fields.get(UspV1Field.LSPA_COVERED).getValue(); + return str; + } + + @Override + protected void decodeSegment(String encodedString, GenericFields fields) { + if (encodedString == null || encodedString.length() != 4) { + throw new DecodingException("Invalid uspv1 string: '" + encodedString + "'"); + } + + try { + fields.get(UspV1Field.VERSION).setValue(Integer.parseInt(encodedString.substring(0, 1))); + fields.get(UspV1Field.NOTICE).setValue(encodedString.charAt(1)); + fields.get(UspV1Field.OPT_OUT_SALE).setValue(encodedString.charAt(2)); + fields.get(UspV1Field.LSPA_COVERED).setValue(encodedString.charAt(3)); + } catch (Exception e) { + throw new DecodingException("Unable to decode UspV1CoreSegment '" + encodedString + "'", e); + } + } + +} + diff --git a/iabgpp-encoder/src/test/java/com/iab/gpp/encoder/GppModelTest.java b/iabgpp-encoder/src/test/java/com/iab/gpp/encoder/GppModelTest.java index 247736f4..003ed030 100644 --- a/iabgpp-encoder/src/test/java/com/iab/gpp/encoder/GppModelTest.java +++ b/iabgpp-encoder/src/test/java/com/iab/gpp/encoder/GppModelTest.java @@ -7,67 +7,209 @@ import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.Test; import com.iab.gpp.encoder.error.DecodingException; -import com.iab.gpp.encoder.error.EncodingException; -import com.iab.gpp.encoder.field.TcfCaV2Field; +import com.iab.gpp.encoder.field.TcfCaV1Field; import com.iab.gpp.encoder.field.TcfEuV2Field; +import com.iab.gpp.encoder.field.UsCaField; +import com.iab.gpp.encoder.field.UsCoField; +import com.iab.gpp.encoder.field.UsCtField; +import com.iab.gpp.encoder.field.UsFlField; +import com.iab.gpp.encoder.field.UsMtField; +import com.iab.gpp.encoder.field.UsNatField; +import com.iab.gpp.encoder.field.UsOrField; +import com.iab.gpp.encoder.field.UsTxField; +import com.iab.gpp.encoder.field.UsUtField; +import com.iab.gpp.encoder.field.UsVaField; import com.iab.gpp.encoder.field.UspV1Field; -import com.iab.gpp.encoder.section.TcfCaV2; +import com.iab.gpp.encoder.section.TcfCaV1; import com.iab.gpp.encoder.section.TcfEuV2; +import com.iab.gpp.encoder.section.UsCa; +import com.iab.gpp.encoder.section.UsCo; +import com.iab.gpp.encoder.section.UsCt; +import com.iab.gpp.encoder.section.UsDe; +import com.iab.gpp.encoder.section.UsFl; +import com.iab.gpp.encoder.section.UsIa; +import com.iab.gpp.encoder.section.UsMt; +import com.iab.gpp.encoder.section.UsNat; +import com.iab.gpp.encoder.section.UsNe; +import com.iab.gpp.encoder.section.UsNh; +import com.iab.gpp.encoder.section.UsNj; +import com.iab.gpp.encoder.section.UsOr; +import com.iab.gpp.encoder.section.UsTn; +import com.iab.gpp.encoder.section.UsTx; +import com.iab.gpp.encoder.section.UsUt; +import com.iab.gpp.encoder.section.UsVa; import com.iab.gpp.encoder.section.UspV1; -class GppModelTest { +public class GppModelTest { private ZonedDateTime utcDateTime = ZonedDateTime.of(2022, 1, 1, 0, 0, 0, 0, ZoneId.of("UTC")); @Test - public void testEncodeDefault() throws EncodingException { + public void testEncodeDefault() { GppModel gppModel = new GppModel(); + Assertions.assertEquals(false, gppModel.hasSection(UspV1.ID)); + Assertions.assertEquals(false, gppModel.hasSection(TcfEuV2.ID)); + Assertions.assertEquals(false, gppModel.hasSection(TcfCaV1.ID)); + Assertions.assertEquals(false, gppModel.hasSection(UspV1.NAME)); Assertions.assertEquals(false, gppModel.hasSection(TcfEuV2.NAME)); - Assertions.assertEquals(false, gppModel.hasSection(TcfCaV2.NAME)); + Assertions.assertEquals(false, gppModel.hasSection(TcfCaV1.NAME)); String gppString = gppModel.encode(); Assertions.assertEquals("DBAA", gppString); Assertions.assertEquals(new ArrayList<>(), gppModel.getSectionIds()); + Assertions.assertEquals(false, gppModel.hasSection(UspV1.ID)); + Assertions.assertEquals(false, gppModel.hasSection(TcfEuV2.ID)); + Assertions.assertEquals(false, gppModel.hasSection(TcfCaV1.ID)); + Assertions.assertEquals(false, gppModel.hasSection(UspV1.NAME)); Assertions.assertEquals(false, gppModel.hasSection(TcfEuV2.NAME)); - Assertions.assertEquals(false, gppModel.hasSection(TcfCaV2.NAME)); + Assertions.assertEquals(false, gppModel.hasSection(TcfCaV1.NAME)); + + } + + @Test + public void testDecodingException() { + Assertions.assertThrows(DecodingException.class, () -> { + new GppModel("invalid gpp string").getHeader(); + }); + } + + @Test() + public void testDecodeGarbage() { + Assertions.assertThrows(DecodingException.class, () -> { + new GppModel("z").getUsCtSection(); + }); + } + + @Test + public void testEncodeDefaultAll() { + GppModel gppModel = new GppModel(); + + Assertions.assertEquals(false, gppModel.hasSection(TcfEuV2.NAME)); + Assertions.assertEquals(false, gppModel.hasSection(TcfCaV1.NAME)); + Assertions.assertEquals(false, gppModel.hasSection(UspV1.NAME)); + Assertions.assertEquals(false, gppModel.hasSection(UsNat.NAME)); + Assertions.assertEquals(false, gppModel.hasSection(UsCa.NAME)); + Assertions.assertEquals(false, gppModel.hasSection(UsVa.NAME)); + Assertions.assertEquals(false, gppModel.hasSection(UsCo.NAME)); + Assertions.assertEquals(false, gppModel.hasSection(UsUt.NAME)); + Assertions.assertEquals(false, gppModel.hasSection(UsCt.NAME)); + Assertions.assertEquals(false, gppModel.hasSection(UsFl.NAME)); + Assertions.assertEquals(false, gppModel.hasSection(UsMt.NAME)); + Assertions.assertEquals(false, gppModel.hasSection(UsOr.NAME)); + Assertions.assertEquals(false, gppModel.hasSection(UsTx.NAME)); + Assertions.assertEquals(false, gppModel.hasSection(UsDe.NAME)); + Assertions.assertEquals(false, gppModel.hasSection(UsIa.NAME)); + Assertions.assertEquals(false, gppModel.hasSection(UsNe.NAME)); + Assertions.assertEquals(false, gppModel.hasSection(UsNh.NAME)); + Assertions.assertEquals(false, gppModel.hasSection(UsNj.NAME)); + Assertions.assertEquals(false, gppModel.hasSection(UsTn.NAME)); + + gppModel.setFieldValue(TcfEuV2.NAME, TcfEuV2Field.VERSION, TcfEuV2.VERSION); + gppModel.setFieldValue(TcfEuV2.NAME, TcfCaV1Field.CREATED, utcDateTime); + gppModel.setFieldValue(TcfEuV2.NAME, TcfCaV1Field.LAST_UPDATED, utcDateTime); + gppModel.setFieldValue(TcfCaV1.NAME, TcfCaV1Field.VERSION, TcfCaV1.VERSION); + gppModel.setFieldValue(TcfCaV1.NAME, TcfCaV1Field.CREATED, utcDateTime); + gppModel.setFieldValue(TcfCaV1.NAME, TcfCaV1Field.LAST_UPDATED, utcDateTime); + gppModel.setFieldValue(UspV1.NAME, UspV1Field.VERSION, UspV1.VERSION); + gppModel.setFieldValue(UsNat.NAME, UsNatField.VERSION, UsNat.VERSION); + gppModel.setFieldValue(UsCa.NAME, UsCaField.VERSION, UsCa.VERSION); + gppModel.setFieldValue(UsVa.NAME, UsVaField.VERSION, UsVa.VERSION); + gppModel.setFieldValue(UsCo.NAME, UsCoField.VERSION, UsCo.VERSION); + gppModel.setFieldValue(UsUt.NAME, UsUtField.VERSION, UsUt.VERSION); + gppModel.setFieldValue(UsCt.NAME, UsCtField.VERSION, UsCt.VERSION); + gppModel.setFieldValue(UsFl.NAME, UsFlField.VERSION, UsFl.VERSION); + gppModel.setFieldValue(UsMt.NAME, UsMtField.VERSION, UsMt.VERSION); + gppModel.setFieldValue(UsOr.NAME, UsOrField.VERSION, UsOr.VERSION); + gppModel.setFieldValue(UsTx.NAME, UsTxField.VERSION, UsTx.VERSION); + gppModel.setFieldValue(UsDe.NAME, UsTxField.VERSION, UsTx.VERSION); + gppModel.setFieldValue(UsIa.NAME, UsTxField.VERSION, UsTx.VERSION); + gppModel.setFieldValue(UsNe.NAME, UsTxField.VERSION, UsTx.VERSION); + gppModel.setFieldValue(UsNh.NAME, UsTxField.VERSION, UsTx.VERSION); + gppModel.setFieldValue(UsNj.NAME, UsTxField.VERSION, UsTx.VERSION); + gppModel.setFieldValue(UsTn.NAME, UsTxField.VERSION, UsTx.VERSION); + + + + Assertions.assertEquals(true, gppModel.hasSection(TcfEuV2.NAME)); + Assertions.assertEquals(true, gppModel.hasSection(TcfCaV1.NAME)); + Assertions.assertEquals(true, gppModel.hasSection(UspV1.NAME)); + Assertions.assertEquals(true, gppModel.hasSection(UsNat.NAME)); + Assertions.assertEquals(true, gppModel.hasSection(UsCa.NAME)); + Assertions.assertEquals(true, gppModel.hasSection(UsVa.NAME)); + Assertions.assertEquals(true, gppModel.hasSection(UsCo.NAME)); + Assertions.assertEquals(true, gppModel.hasSection(UsUt.NAME)); + Assertions.assertEquals(true, gppModel.hasSection(UsCt.NAME)); + Assertions.assertEquals(true, gppModel.hasSection(UsFl.NAME)); + Assertions.assertEquals(true, gppModel.hasSection(UsMt.NAME)); + Assertions.assertEquals(true, gppModel.hasSection(UsOr.NAME)); + Assertions.assertEquals(true, gppModel.hasSection(UsTx.NAME)); + Assertions.assertEquals(true, gppModel.hasSection(UsDe.NAME)); + Assertions.assertEquals(true, gppModel.hasSection(UsIa.NAME)); + Assertions.assertEquals(true, gppModel.hasSection(UsNe.NAME)); + Assertions.assertEquals(true, gppModel.hasSection(UsNh.NAME)); + Assertions.assertEquals(true, gppModel.hasSection(UsNj.NAME)); + Assertions.assertEquals(true, gppModel.hasSection(UsTn.NAME)); + + String gppString = gppModel.encode(); + Assertions.assertEquals( + "DBACOdM~CPSG_8APSG_8AAAAAAENAACAAAAAAAAAAAAAAAAAAAAA.QAAA.IAAA~BPSG_8APSG_8AAAAAAENAACAAAAAAAAAAAAAAAAAA.YAAAAAAAAA~1---~BAAAAAAAAABA.Q~BAAAAABA.Q~BAAAABA~BAAAAEA.Q~BAAAAAQ~BAAAAAEA.Q~BAAAAABA~BAAAAABA.Q~BAAAAAABA.Q~BAAAAAQ.Q~BAAAAAABA.Q~BAAAAAQ.Q~BAAAAAQ.Q~BAAAAABA.Q~BAAAAAAAQ.Q~BAAAAAQ.Q", + gppString); } @Test - public void testEncodeUspv1() throws EncodingException { + public void testEncodeUspv1() { GppModel gppModel = new GppModel(); + Assertions.assertEquals(false, gppModel.hasSection(UspV1.ID)); + Assertions.assertEquals(false, gppModel.hasSection(TcfEuV2.ID)); + Assertions.assertEquals(false, gppModel.hasSection(TcfCaV1.ID)); + Assertions.assertEquals(false, gppModel.hasSection(UspV1.NAME)); Assertions.assertEquals(false, gppModel.hasSection(TcfEuV2.NAME)); - Assertions.assertEquals(false, gppModel.hasSection(TcfCaV2.NAME)); + Assertions.assertEquals(false, gppModel.hasSection(TcfCaV1.NAME)); - gppModel.setFieldValue(UspV1.NAME, UspV1Field.NOTICE, 1); - gppModel.setFieldValue(UspV1.NAME, UspV1Field.OPT_OUT_SALE, 2); - gppModel.setFieldValue(UspV1.NAME, UspV1Field.LSPA_COVERED, 3); + gppModel.setFieldValue(UspV1.NAME, UspV1Field.NOTICE, 'Y'); + gppModel.setFieldValue(UspV1.NAME, UspV1Field.OPT_OUT_SALE, 'N'); + gppModel.setFieldValue(UspV1.NAME, UspV1Field.LSPA_COVERED, 'N'); Assertions.assertEquals(Arrays.asList(6), gppModel.getSectionIds()); + Assertions.assertEquals(true, gppModel.hasSection(UspV1.ID)); + Assertions.assertEquals(false, gppModel.hasSection(TcfEuV2.ID)); + Assertions.assertEquals(false, gppModel.hasSection(TcfCaV1.ID)); + Assertions.assertEquals(true, gppModel.hasSection(UspV1.NAME)); Assertions.assertEquals(false, gppModel.hasSection(TcfEuV2.NAME)); - Assertions.assertEquals(false, gppModel.hasSection(TcfCaV2.NAME)); + Assertions.assertEquals(false, gppModel.hasSection(TcfCaV1.NAME)); + + String gppString = gppModel.encode(); - Assertions.assertEquals("DBABTA~BbA", gppString); + Assertions.assertEquals("DBABT~1YNN", gppString); Assertions.assertEquals(Arrays.asList(6), gppModel.getSectionIds()); + Assertions.assertEquals(true, gppModel.hasSection(UspV1.ID)); + Assertions.assertEquals(false, gppModel.hasSection(TcfEuV2.ID)); + Assertions.assertEquals(false, gppModel.hasSection(TcfCaV1.ID)); + Assertions.assertEquals(true, gppModel.hasSection(UspV1.NAME)); Assertions.assertEquals(false, gppModel.hasSection(TcfEuV2.NAME)); - Assertions.assertEquals(false, gppModel.hasSection(TcfCaV2.NAME)); + Assertions.assertEquals(false, gppModel.hasSection(TcfCaV1.NAME)); } @Test - public void testEncodeTcfEuV2() throws EncodingException { + public void testEncodeTcfEuV2() { GppModel gppModel = new GppModel(); + Assertions.assertEquals(false, gppModel.hasSection(UspV1.ID)); + Assertions.assertEquals(false, gppModel.hasSection(TcfEuV2.ID)); + Assertions.assertEquals(false, gppModel.hasSection(TcfCaV1.ID)); + Assertions.assertEquals(false, gppModel.hasSection(UspV1.NAME)); Assertions.assertEquals(false, gppModel.hasSection(TcfEuV2.NAME)); - Assertions.assertEquals(false, gppModel.hasSection(TcfCaV2.NAME)); + Assertions.assertEquals(false, gppModel.hasSection(TcfCaV1.NAME)); gppModel.setFieldValue(TcfEuV2.NAME, TcfEuV2Field.CMP_ID, 880); gppModel.setFieldValue(TcfEuV2.NAME, TcfEuV2Field.CMP_VERSION, 0); @@ -79,28 +221,37 @@ public void testEncodeTcfEuV2() throws EncodingException { gppModel.setFieldValue(TcfEuV2.NAME, TcfEuV2Field.USE_NON_STANDARD_STACKS, false); gppModel.setFieldValue(TcfEuV2.NAME, TcfEuV2Field.PURPOSE_ONE_TREATMENT, false); gppModel.setFieldValue(TcfEuV2.NAME, TcfEuV2Field.PUBLISHER_COUNTRY_CODE, "AA"); - gppModel.setFieldValue(TcfEuV2.NAME, TcfCaV2Field.CREATED, utcDateTime); - gppModel.setFieldValue(TcfEuV2.NAME, TcfCaV2Field.LAST_UPDATED, utcDateTime); + gppModel.setFieldValue(TcfEuV2.NAME, TcfCaV1Field.CREATED, utcDateTime); + gppModel.setFieldValue(TcfEuV2.NAME, TcfCaV1Field.LAST_UPDATED, utcDateTime); Assertions.assertEquals(Arrays.asList(2), gppModel.getSectionIds()); + Assertions.assertEquals(false, gppModel.hasSection(UspV1.ID)); + Assertions.assertEquals(true, gppModel.hasSection(TcfEuV2.ID)); + Assertions.assertEquals(false, gppModel.hasSection(TcfCaV1.ID)); + Assertions.assertEquals(false, gppModel.hasSection(UspV1.NAME)); Assertions.assertEquals(true, gppModel.hasSection(TcfEuV2.NAME)); - Assertions.assertEquals(false, gppModel.hasSection(TcfCaV2.NAME)); + Assertions.assertEquals(false, gppModel.hasSection(TcfCaV1.NAME)); + String gppString = gppModel.encode(); - Assertions.assertEquals("DBABMA~CPSG_8APSG_8ANwAAAENAwCAAAAAAAAAAAAAAAAAAAA.QAAA.IAAA", gppString); + Assertions.assertEquals("DBABM~CPSG_8APSG_8ANwAAAENAwCAAAAAAAAAAAAAAAAAAAAA.QAAA.IAAA", gppString); Assertions.assertEquals(2, gppString.split("~").length); Assertions.assertEquals(Arrays.asList(2), gppModel.getSectionIds()); + Assertions.assertEquals(false, gppModel.hasSection(UspV1.ID)); + Assertions.assertEquals(true, gppModel.hasSection(TcfEuV2.ID)); + Assertions.assertEquals(false, gppModel.hasSection(TcfCaV1.ID)); + Assertions.assertEquals(false, gppModel.hasSection(UspV1.NAME)); Assertions.assertEquals(true, gppModel.hasSection(TcfEuV2.NAME)); - Assertions.assertEquals(false, gppModel.hasSection(TcfCaV2.NAME)); + Assertions.assertEquals(false, gppModel.hasSection(TcfCaV1.NAME)); } @Test - public void testEncodeUspV1AndTcfEuV2() throws EncodingException { + public void testEncodeUspV1AndTcfEuV2() { GppModel gppModel = new GppModel(); Assertions.assertEquals(false, gppModel.hasSection(UspV1.NAME)); Assertions.assertEquals(false, gppModel.hasSection(TcfEuV2.NAME)); @@ -116,40 +267,45 @@ public void testEncodeUspV1AndTcfEuV2() throws EncodingException { gppModel.setFieldValue(TcfEuV2.NAME, TcfEuV2Field.USE_NON_STANDARD_STACKS, false); gppModel.setFieldValue(TcfEuV2.NAME, TcfEuV2Field.PURPOSE_ONE_TREATMENT, false); gppModel.setFieldValue(TcfEuV2.NAME, TcfEuV2Field.PUBLISHER_COUNTRY_CODE, "AA"); - gppModel.setFieldValue(TcfEuV2.NAME, TcfCaV2Field.CREATED, utcDateTime); - gppModel.setFieldValue(TcfEuV2.NAME, TcfCaV2Field.LAST_UPDATED, utcDateTime); + gppModel.setFieldValue(TcfEuV2.NAME, TcfCaV1Field.CREATED, utcDateTime); + gppModel.setFieldValue(TcfEuV2.NAME, TcfCaV1Field.LAST_UPDATED, utcDateTime); Assertions.assertEquals(Arrays.asList(2), gppModel.getSectionIds()); Assertions.assertEquals(false, gppModel.hasSection(UspV1.NAME)); Assertions.assertEquals(true, gppModel.hasSection(TcfEuV2.NAME)); - Assertions.assertEquals(false, gppModel.hasSection(TcfCaV2.NAME)); + Assertions.assertEquals(false, gppModel.hasSection(TcfCaV1.NAME)); - gppModel.setFieldValue(UspV1.NAME, UspV1Field.NOTICE, 1); - gppModel.setFieldValue(UspV1.NAME, UspV1Field.OPT_OUT_SALE, 2); - gppModel.setFieldValue(UspV1.NAME, UspV1Field.LSPA_COVERED, 3); + gppModel.setFieldValue(UspV1.NAME, UspV1Field.NOTICE, 'Y'); + gppModel.setFieldValue(UspV1.NAME, UspV1Field.OPT_OUT_SALE, 'N'); + gppModel.setFieldValue(UspV1.NAME, UspV1Field.LSPA_COVERED, 'N'); Assertions.assertEquals(true, gppModel.hasSection(UspV1.NAME)); Assertions.assertEquals(true, gppModel.hasSection(TcfEuV2.NAME)); - Assertions.assertEquals(false, gppModel.hasSection(TcfCaV2.NAME)); + Assertions.assertEquals(false, gppModel.hasSection(TcfCaV1.NAME)); String gppString = gppModel.encode(); - Assertions.assertEquals("DBACNYA~CPSG_8APSG_8ANwAAAENAwCAAAAAAAAAAAAAAAAAAAA.QAAA.IAAA~BbA", gppString); + Assertions.assertEquals("DBACNY~CPSG_8APSG_8ANwAAAENAwCAAAAAAAAAAAAAAAAAAAAA.QAAA.IAAA~1YNN", gppString); Assertions.assertEquals(3, gppString.split("~").length); Assertions.assertEquals(Arrays.asList(2, 6), gppModel.getSectionIds()); Assertions.assertEquals(true, gppModel.hasSection(UspV1.NAME)); Assertions.assertEquals(true, gppModel.hasSection(TcfEuV2.NAME)); - Assertions.assertEquals(false, gppModel.hasSection(TcfCaV2.NAME)); + Assertions.assertEquals(false, gppModel.hasSection(TcfCaV1.NAME)); } @Test - public void testEncodeUspV1AndTcfEuV2AndTcfCaV2() throws EncodingException { + public void testEncodeUspV1AndTcfEuV2AndTcfCaV1() { GppModel gppModel = new GppModel(); + Assertions.assertEquals(false, gppModel.hasSection(UspV1.ID)); + Assertions.assertEquals(false, gppModel.hasSection(TcfEuV2.ID)); + Assertions.assertEquals(false, gppModel.hasSection(TcfCaV1.ID)); + Assertions.assertEquals(false, gppModel.hasSection(UspV1.NAME)); Assertions.assertEquals(false, gppModel.hasSection(TcfEuV2.NAME)); - Assertions.assertEquals(false, gppModel.hasSection(TcfCaV2.NAME)); + Assertions.assertEquals(false, gppModel.hasSection(TcfCaV1.NAME)); + gppModel.setFieldValue(TcfEuV2.NAME, TcfEuV2Field.CMP_ID, 880); gppModel.setFieldValue(TcfEuV2.NAME, TcfEuV2Field.CMP_VERSION, 0); @@ -161,105 +317,178 @@ public void testEncodeUspV1AndTcfEuV2AndTcfCaV2() throws EncodingException { gppModel.setFieldValue(TcfEuV2.NAME, TcfEuV2Field.USE_NON_STANDARD_STACKS, false); gppModel.setFieldValue(TcfEuV2.NAME, TcfEuV2Field.PURPOSE_ONE_TREATMENT, false); gppModel.setFieldValue(TcfEuV2.NAME, TcfEuV2Field.PUBLISHER_COUNTRY_CODE, "AA"); - gppModel.setFieldValue(TcfEuV2.NAME, TcfCaV2Field.CREATED, utcDateTime); - gppModel.setFieldValue(TcfEuV2.NAME, TcfCaV2Field.LAST_UPDATED, utcDateTime); + gppModel.setFieldValue(TcfEuV2.NAME, TcfCaV1Field.CREATED, utcDateTime); + gppModel.setFieldValue(TcfEuV2.NAME, TcfCaV1Field.LAST_UPDATED, utcDateTime); Assertions.assertEquals(Arrays.asList(2), gppModel.getSectionIds()); + Assertions.assertEquals(false, gppModel.hasSection(UspV1.ID)); + Assertions.assertEquals(true, gppModel.hasSection(TcfEuV2.ID)); + Assertions.assertEquals(false, gppModel.hasSection(TcfCaV1.ID)); + Assertions.assertEquals(false, gppModel.hasSection(UspV1.NAME)); Assertions.assertEquals(true, gppModel.hasSection(TcfEuV2.NAME)); - Assertions.assertEquals(false, gppModel.hasSection(TcfCaV2.NAME)); + Assertions.assertEquals(false, gppModel.hasSection(TcfCaV1.NAME)); + + gppModel.setFieldValue(UspV1.NAME, UspV1Field.NOTICE, 'Y'); + gppModel.setFieldValue(UspV1.NAME, UspV1Field.OPT_OUT_SALE, 'N'); + gppModel.setFieldValue(UspV1.NAME, UspV1Field.LSPA_COVERED, 'N'); - gppModel.setFieldValue(UspV1.NAME, UspV1Field.NOTICE, 1); - gppModel.setFieldValue(UspV1.NAME, UspV1Field.OPT_OUT_SALE, 2); - gppModel.setFieldValue(UspV1.NAME, UspV1Field.LSPA_COVERED, 3); + Assertions.assertEquals(true, gppModel.hasSection(UspV1.ID)); + Assertions.assertEquals(true, gppModel.hasSection(TcfEuV2.ID)); + Assertions.assertEquals(false, gppModel.hasSection(TcfCaV1.ID)); Assertions.assertEquals(true, gppModel.hasSection(UspV1.NAME)); Assertions.assertEquals(true, gppModel.hasSection(TcfEuV2.NAME)); - Assertions.assertEquals(false, gppModel.hasSection(TcfCaV2.NAME)); + Assertions.assertEquals(false, gppModel.hasSection(TcfCaV1.NAME)); - gppModel.setFieldValue(TcfCaV2.NAME, TcfCaV2Field.CMP_ID, 50); - gppModel.setFieldValue(TcfCaV2.NAME, TcfCaV2Field.CMP_VERSION, 2); - gppModel.setFieldValue(TcfCaV2.NAME, TcfCaV2Field.VENDOR_LIST_VERSION, 413); - gppModel.setFieldValue(TcfCaV2.NAME, TcfCaV2Field.USE_NON_STANDARD_STACKS, true); - gppModel.setFieldValue(TcfCaV2.NAME, TcfCaV2Field.SPECIAL_FEATURE_EXPRESS_CONSENT, + gppModel.setFieldValue(TcfCaV1.NAME, TcfCaV1Field.CMP_ID, 50); + gppModel.setFieldValue(TcfCaV1.NAME, TcfCaV1Field.CMP_VERSION, 2); + gppModel.setFieldValue(TcfCaV1.NAME, TcfCaV1Field.VENDOR_LIST_VERSION, 413); + gppModel.setFieldValue(TcfCaV1.NAME, TcfCaV1Field.USE_NON_STANDARD_STACKS, true); + gppModel.setFieldValue(TcfCaV1.NAME, TcfCaV1Field.SPECIAL_FEATURE_EXPRESS_CONSENT, Arrays.asList(false, false, false, false, false, false, true, true, true, true, true, true)); - gppModel.setFieldValue(TcfCaV2.NAME, TcfCaV2Field.PURPOSES_EXPRESS_CONSENT, + gppModel.setFieldValue(TcfCaV1.NAME, TcfCaV1Field.PURPOSES_EXPRESS_CONSENT, Arrays.asList(true, true, true, true, true, true, false, false, false, false, false, false, true, true, true, true, true, true, false, false, false, false, false, false)); - gppModel.setFieldValue(TcfCaV2.NAME, TcfCaV2Field.PURPOSES_IMPLIED_CONSENT, + gppModel.setFieldValue(TcfCaV1.NAME, TcfCaV1Field.PURPOSES_IMPLIED_CONSENT, Arrays.asList(false, false, false, false, false, false, true, true, true, true, true, true, false, false, false, false, false, false, true, true, true, true, true, true)); - gppModel.setFieldValue(TcfCaV2.NAME, TcfCaV2Field.VENDOR_EXPRESS_CONSENT, Arrays.asList(12, 24, 48)); - gppModel.setFieldValue(TcfCaV2.NAME, TcfCaV2Field.VENDOR_IMPLIED_CONSENT, Arrays.asList(18, 30)); - gppModel.setFieldValue(TcfCaV2.NAME, TcfCaV2Field.PUB_PURPOSES_EXPRESS_CONSENT, + gppModel.setFieldValue(TcfCaV1.NAME, TcfCaV1Field.VENDOR_EXPRESS_CONSENT, Arrays.asList(12, 24, 48)); + gppModel.setFieldValue(TcfCaV1.NAME, TcfCaV1Field.VENDOR_IMPLIED_CONSENT, Arrays.asList(18, 30)); + gppModel.setFieldValue(TcfCaV1.NAME, TcfCaV1Field.PUB_PURPOSES_EXPRESS_CONSENT, Arrays.asList(true, true, true, false, false, false, true, true, true, false, false, false, true, true, true, false, false, false, true, true, true, false, false, false)); - gppModel.setFieldValue(TcfCaV2.NAME, TcfCaV2Field.PUB_PURPOSES_IMPLIED_CONSENT, + gppModel.setFieldValue(TcfCaV1.NAME, TcfCaV1Field.PUB_PURPOSES_IMPLIED_CONSENT, Arrays.asList(false, false, false, true, true, true, false, false, false, true, true, true, false, false, false, true, true, true, false, false, false, true, true, true)); - gppModel.setFieldValue(TcfCaV2.NAME, TcfCaV2Field.NUM_CUSTOM_PURPOSES, 3); - gppModel.setFieldValue(TcfCaV2.NAME, TcfCaV2Field.CUSTOM_PURPOSES_EXPRESS_CONSENT, + gppModel.setFieldValue(TcfCaV1.NAME, TcfCaV1Field.NUM_CUSTOM_PURPOSES, 3); + gppModel.setFieldValue(TcfCaV1.NAME, TcfCaV1Field.CUSTOM_PURPOSES_EXPRESS_CONSENT, Arrays.asList(false, true, false)); - gppModel.setFieldValue(TcfCaV2.NAME, TcfCaV2Field.CUSTOM_PURPOSES_IMPLIED_CONSENT, + gppModel.setFieldValue(TcfCaV1.NAME, TcfCaV1Field.CUSTOM_PURPOSES_IMPLIED_CONSENT, Arrays.asList(true, false, true)); - gppModel.setFieldValue(TcfCaV2.NAME, TcfCaV2Field.CREATED, utcDateTime); - gppModel.setFieldValue(TcfCaV2.NAME, TcfCaV2Field.LAST_UPDATED, utcDateTime); + gppModel.setFieldValue(TcfCaV1.NAME, TcfCaV1Field.CREATED, utcDateTime); + gppModel.setFieldValue(TcfCaV1.NAME, TcfCaV1Field.LAST_UPDATED, utcDateTime); + + Assertions.assertEquals(true, gppModel.hasSection(UspV1.ID)); + Assertions.assertEquals(true, gppModel.hasSection(TcfEuV2.ID)); + Assertions.assertEquals(true, gppModel.hasSection(TcfCaV1.ID)); Assertions.assertEquals(true, gppModel.hasSection(UspV1.NAME)); Assertions.assertEquals(true, gppModel.hasSection(TcfEuV2.NAME)); - Assertions.assertEquals(true, gppModel.hasSection(TcfCaV2.NAME)); + Assertions.assertEquals(true, gppModel.hasSection(TcfCaV1.NAME)); String gppString = gppModel.encode(); Assertions.assertEquals( - "DBACOeA~CPSG_8APSG_8ANwAAAENAwCAAAAAAAAAAAAAAAAAAAA.QAAA.IAAA~CPSG_8APSG_8AAyACAENGdCgf_gfgAfgfgBgAMAAwADAAIACQAHg.fHHHA4444ao~BbA", + "DBACOe~CPSG_8APSG_8ANwAAAENAwCAAAAAAAAAAAAAAAAAAAAA.QAAA.IAAA~BPSG_8APSG_8AAyACAENGdCgf_gfgAfgfgBgABABAAABAB4AACACAA.fHHHA4444ao~1YNN", gppString); Assertions.assertEquals(4, gppString.split("~").length); Assertions.assertEquals(Arrays.asList(2, 5, 6), gppModel.getSectionIds()); + Assertions.assertEquals(true, gppModel.hasSection(UspV1.ID)); + Assertions.assertEquals(true, gppModel.hasSection(TcfEuV2.ID)); + Assertions.assertEquals(true, gppModel.hasSection(TcfCaV1.ID)); + Assertions.assertEquals(true, gppModel.hasSection(UspV1.NAME)); Assertions.assertEquals(true, gppModel.hasSection(TcfEuV2.NAME)); - Assertions.assertEquals(true, gppModel.hasSection(TcfCaV2.NAME)); + Assertions.assertEquals(true, gppModel.hasSection(TcfCaV1.NAME)); } @Test - public void testDecodeDefaults() throws DecodingException { + public void testDecodeDefaults() { String gppString = "DBAA"; GppModel gppModel = new GppModel(gppString); + Assertions.assertEquals(false, gppModel.hasSection(UspV1.ID)); + Assertions.assertEquals(false, gppModel.hasSection(TcfEuV2.ID)); + Assertions.assertEquals(false, gppModel.hasSection(TcfCaV1.ID)); + Assertions.assertEquals(false, gppModel.hasSection(UspV1.NAME)); Assertions.assertEquals(false, gppModel.hasSection(TcfEuV2.NAME)); - Assertions.assertEquals(false, gppModel.hasSection(TcfCaV2.NAME)); + Assertions.assertEquals(false, gppModel.hasSection(TcfCaV1.NAME)); } @Test - public void testDecodeUspv1() throws DecodingException { - String gppString = "DBABTA~BbA"; + public void testDecodeDefaultsAll() { + String gppString = + "DBACOdM~CPSG_8APSG_8AAAAAAENAACAAAAAAAAAAAAAAAAAAAAA.QAAA.IAAA~BPSG_8APSG_8AAAAAAENAACAAAAAAAAAAAAAAAAAA.YAAAAAAAAA~1---~BAAAAAAAAABA.Q~BAAAAABA.Q~BAAAABA~BAAAAEA.Q~BAAAAAQ~BAAAAAEA.Q~BAAAAABA~BAAAAABA.Q~BAAAAAABA.Q~BAAAAAQ.Q~BAAAAAABA.Q~BAAAAAQ.Q~BAAAAAQ.Q~BAAAAABA.Q~BAAAAAAAQ.Q~BAAAAAQ.Q"; + GppModel gppModel = new GppModel(gppString); + + Assertions.assertEquals(true, gppModel.hasSection(TcfEuV2.NAME)); + Assertions.assertEquals(true, gppModel.hasSection(TcfCaV1.NAME)); + Assertions.assertEquals(true, gppModel.hasSection(UspV1.NAME)); + Assertions.assertEquals(true, gppModel.hasSection(UsNat.NAME)); + Assertions.assertEquals(true, gppModel.hasSection(UsCa.NAME)); + Assertions.assertEquals(true, gppModel.hasSection(UsVa.NAME)); + Assertions.assertEquals(true, gppModel.hasSection(UsCo.NAME)); + Assertions.assertEquals(true, gppModel.hasSection(UsUt.NAME)); + Assertions.assertEquals(true, gppModel.hasSection(UsCt.NAME)); + Assertions.assertEquals(true, gppModel.hasSection(UsFl.NAME)); + Assertions.assertEquals(true, gppModel.hasSection(UsMt.NAME)); + Assertions.assertEquals(true, gppModel.hasSection(UsOr.NAME)); + Assertions.assertEquals(true, gppModel.hasSection(UsTx.NAME)); + Assertions.assertEquals(true, gppModel.hasSection(UsDe.NAME)); + Assertions.assertEquals(true, gppModel.hasSection(UsIa.NAME)); + Assertions.assertEquals(true, gppModel.hasSection(UsNe.NAME)); + Assertions.assertEquals(true, gppModel.hasSection(UsNh.NAME)); + Assertions.assertEquals(true, gppModel.hasSection(UsNj.NAME)); + Assertions.assertEquals(true, gppModel.hasSection(UsTn.NAME)); + } + + @Test + public void testDecodeUspv1() { + String gppString = "DBABT~1YNN"; GppModel gppModel = new GppModel(gppString); Assertions.assertEquals(Arrays.asList(6), gppModel.getSectionIds()); + Assertions.assertEquals(true, gppModel.hasSection(UspV1.ID)); + Assertions.assertEquals(false, gppModel.hasSection(TcfEuV2.ID)); + Assertions.assertEquals(false, gppModel.hasSection(TcfCaV1.ID)); + Assertions.assertEquals(true, gppModel.hasSection(UspV1.NAME)); Assertions.assertEquals(false, gppModel.hasSection(TcfEuV2.NAME)); - Assertions.assertEquals(false, gppModel.hasSection(TcfCaV2.NAME)); + Assertions.assertEquals(false, gppModel.hasSection(TcfCaV1.NAME)); + + Assertions.assertEquals('Y', gppModel.getFieldValue(UspV1.ID, UspV1Field.NOTICE)); + Assertions.assertEquals('N', gppModel.getFieldValue(UspV1.ID, UspV1Field.OPT_OUT_SALE)); + Assertions.assertEquals('N', gppModel.getFieldValue(UspV1.ID, UspV1Field.LSPA_COVERED)); - Assertions.assertEquals(1, gppModel.getFieldValue(UspV1.NAME, UspV1Field.NOTICE)); - Assertions.assertEquals(2, gppModel.getFieldValue(UspV1.NAME, UspV1Field.OPT_OUT_SALE)); - Assertions.assertEquals(3, gppModel.getFieldValue(UspV1.NAME, UspV1Field.LSPA_COVERED)); + Assertions.assertEquals('Y', gppModel.getFieldValue(UspV1.NAME, UspV1Field.NOTICE)); + Assertions.assertEquals('N', gppModel.getFieldValue(UspV1.NAME, UspV1Field.OPT_OUT_SALE)); + Assertions.assertEquals('N', gppModel.getFieldValue(UspV1.NAME, UspV1Field.LSPA_COVERED)); } @Test - public void testDecodeTcfEuV2() throws DecodingException { - String gppString = "DBABMA~CPSG_8APSG_8ANwAAAENAwCAAAAAAAAAAAAAAAAAAAA.QAAA.IAAA"; + public void testDecodeTcfEuV2() { + String gppString = "DBABM~CPSG_8APSG_8ANwAAAENAwCAAAAAAAAAAAAAAAAAAAAA.QAAA.IAAA"; GppModel gppModel = new GppModel(gppString); Assertions.assertEquals(Arrays.asList(2), gppModel.getSectionIds()); + Assertions.assertEquals(false, gppModel.hasSection(UspV1.ID)); + Assertions.assertEquals(true, gppModel.hasSection(TcfEuV2.ID)); + Assertions.assertEquals(false, gppModel.hasSection(TcfCaV1.ID)); + Assertions.assertEquals(false, gppModel.hasSection(UspV1.NAME)); Assertions.assertEquals(true, gppModel.hasSection(TcfEuV2.NAME)); - Assertions.assertEquals(false, gppModel.hasSection(TcfCaV2.NAME)); + Assertions.assertEquals(false, gppModel.hasSection(TcfCaV1.NAME)); + + Assertions.assertEquals(2, gppModel.getFieldValue(TcfEuV2.ID, TcfEuV2Field.VERSION)); + Assertions.assertEquals(880, gppModel.getFieldValue(TcfEuV2.ID, TcfEuV2Field.CMP_ID)); + Assertions.assertEquals(0, gppModel.getFieldValue(TcfEuV2.ID, TcfEuV2Field.CMP_VERSION)); + Assertions.assertEquals(0, gppModel.getFieldValue(TcfEuV2.ID, TcfEuV2Field.CONSENT_SCREEN)); + Assertions.assertEquals("EN", gppModel.getFieldValue(TcfEuV2.ID, TcfEuV2Field.CONSENT_LANGUAGE)); + Assertions.assertEquals(48, gppModel.getFieldValue(TcfEuV2.ID, TcfEuV2Field.VENDOR_LIST_VERSION)); + Assertions.assertEquals(2, gppModel.getFieldValue(TcfEuV2.ID, TcfEuV2Field.POLICY_VERSION)); + Assertions.assertEquals(false, gppModel.getFieldValue(TcfEuV2.ID, TcfEuV2Field.IS_SERVICE_SPECIFIC)); + Assertions.assertEquals(false, gppModel.getFieldValue(TcfEuV2.ID, TcfEuV2Field.USE_NON_STANDARD_STACKS)); + Assertions.assertEquals(false, gppModel.getFieldValue(TcfEuV2.ID, TcfEuV2Field.PURPOSE_ONE_TREATMENT)); + Assertions.assertEquals("AA", gppModel.getFieldValue(TcfEuV2.ID, TcfEuV2Field.PUBLISHER_COUNTRY_CODE)); + Assertions.assertEquals(utcDateTime, gppModel.getFieldValue(TcfEuV2.ID, TcfEuV2Field.CREATED)); + Assertions.assertEquals(utcDateTime, gppModel.getFieldValue(TcfEuV2.ID, TcfEuV2Field.LAST_UPDATED)); Assertions.assertEquals(2, gppModel.getFieldValue(TcfEuV2.NAME, TcfEuV2Field.VERSION)); Assertions.assertEquals(880, gppModel.getFieldValue(TcfEuV2.NAME, TcfEuV2Field.CMP_ID)); @@ -277,18 +506,41 @@ public void testDecodeTcfEuV2() throws DecodingException { } @Test - public void testDecodeUspv1AndTcfEuV2() throws DecodingException { - String gppString = "DBACNYA~CPSG_8APSG_8ANwAAAENAwCAAAAAAAAAAAAAAAAAAAA.QAAA.IAAA~BbA"; + public void testDecodeUspv1AndTcfEuV2() { + String gppString = "DBACNY~CPSG_8APSG_8ANwAAAENAwCAAAAAAAAAAAAAAAAAAAAA.QAAA.IAAA~1YNN"; GppModel gppModel = new GppModel(gppString); Assertions.assertEquals(Arrays.asList(2, 6), gppModel.getSectionIds()); + Assertions.assertEquals(true, gppModel.hasSection(UspV1.ID)); + Assertions.assertEquals(true, gppModel.hasSection(TcfEuV2.ID)); + Assertions.assertEquals(false, gppModel.hasSection(TcfCaV1.ID)); + Assertions.assertEquals(true, gppModel.hasSection(UspV1.NAME)); Assertions.assertEquals(true, gppModel.hasSection(TcfEuV2.NAME)); - Assertions.assertEquals(false, gppModel.hasSection(TcfCaV2.NAME)); - - Assertions.assertEquals(1, gppModel.getFieldValue(UspV1.NAME, UspV1Field.NOTICE)); - Assertions.assertEquals(2, gppModel.getFieldValue(UspV1.NAME, UspV1Field.OPT_OUT_SALE)); - Assertions.assertEquals(3, gppModel.getFieldValue(UspV1.NAME, UspV1Field.LSPA_COVERED)); + Assertions.assertEquals(false, gppModel.hasSection(TcfCaV1.NAME)); + + + Assertions.assertEquals('Y', gppModel.getFieldValue(UspV1.ID, UspV1Field.NOTICE)); + Assertions.assertEquals('N', gppModel.getFieldValue(UspV1.ID, UspV1Field.OPT_OUT_SALE)); + Assertions.assertEquals('N', gppModel.getFieldValue(UspV1.ID, UspV1Field.LSPA_COVERED)); + + Assertions.assertEquals('Y', gppModel.getFieldValue(UspV1.NAME, UspV1Field.NOTICE)); + Assertions.assertEquals('N', gppModel.getFieldValue(UspV1.NAME, UspV1Field.OPT_OUT_SALE)); + Assertions.assertEquals('N', gppModel.getFieldValue(UspV1.NAME, UspV1Field.LSPA_COVERED)); + + Assertions.assertEquals(2, gppModel.getFieldValue(TcfEuV2.ID, TcfEuV2Field.VERSION)); + Assertions.assertEquals(880, gppModel.getFieldValue(TcfEuV2.ID, TcfEuV2Field.CMP_ID)); + Assertions.assertEquals(0, gppModel.getFieldValue(TcfEuV2.ID, TcfEuV2Field.CMP_VERSION)); + Assertions.assertEquals(0, gppModel.getFieldValue(TcfEuV2.ID, TcfEuV2Field.CONSENT_SCREEN)); + Assertions.assertEquals("EN", gppModel.getFieldValue(TcfEuV2.ID, TcfEuV2Field.CONSENT_LANGUAGE)); + Assertions.assertEquals(48, gppModel.getFieldValue(TcfEuV2.ID, TcfEuV2Field.VENDOR_LIST_VERSION)); + Assertions.assertEquals(2, gppModel.getFieldValue(TcfEuV2.ID, TcfEuV2Field.POLICY_VERSION)); + Assertions.assertEquals(false, gppModel.getFieldValue(TcfEuV2.ID, TcfEuV2Field.IS_SERVICE_SPECIFIC)); + Assertions.assertEquals(false, gppModel.getFieldValue(TcfEuV2.ID, TcfEuV2Field.USE_NON_STANDARD_STACKS)); + Assertions.assertEquals(false, gppModel.getFieldValue(TcfEuV2.ID, TcfEuV2Field.PURPOSE_ONE_TREATMENT)); + Assertions.assertEquals("AA", gppModel.getFieldValue(TcfEuV2.ID, TcfEuV2Field.PUBLISHER_COUNTRY_CODE)); + Assertions.assertEquals(utcDateTime, gppModel.getFieldValue(TcfEuV2.ID, TcfEuV2Field.CREATED)); + Assertions.assertEquals(utcDateTime, gppModel.getFieldValue(TcfEuV2.ID, TcfEuV2Field.LAST_UPDATED)); Assertions.assertEquals(2, gppModel.getFieldValue(TcfEuV2.NAME, TcfEuV2Field.VERSION)); Assertions.assertEquals(880, gppModel.getFieldValue(TcfEuV2.NAME, TcfEuV2Field.CMP_ID)); @@ -312,25 +564,25 @@ public void testDecodeUspv1AndTcfEuV2() throws DecodingException { UspV1 uspV1Section = (UspV1) gppModel.getSection(UspV1.NAME); Integer uspV1Version = uspV1Section.getVersion(); - Integer notice = uspV1Section.getNotice(); + Character notice = uspV1Section.getNotice(); Assertions.assertEquals(1, uspV1Version); - Assertions.assertEquals(1, notice); + Assertions.assertEquals('Y', notice); } @Test - public void testDecodeUspv1AndTcfEuV2AndTcfCaV2() throws DecodingException { + public void testDecodeUspv1AndTcfEuV2AndTcfCaV1() { String gppString = - "DBACOeA~CPSG_8APSG_8ANwAAAENAwCAAAAAAAAAAAAAAAAAAAA.QAAA.IAAA~CPSG_8APSG_8AAyACAENGdCgf_gfgAfgfgBgAMAAwADAAIACQAHg.fHHHA4444ao~BbA"; + "DBACOe~CPSG_8APSG_8ANwAAAENAwCAAAAAAAAAAAAAAAAAAAAA.QAAA.IAAA~BPSG_8APSG_8AAyACAENGdCgf_gfgAfgfgBgABABAAABAB4AACACAA.fHHHA4444ao~1YNN"; GppModel gppModel = new GppModel(gppString); Assertions.assertEquals(Arrays.asList(2, 5, 6), gppModel.getSectionIds()); Assertions.assertEquals(true, gppModel.hasSection(UspV1.NAME)); Assertions.assertEquals(true, gppModel.hasSection(TcfEuV2.NAME)); - Assertions.assertEquals(true, gppModel.hasSection(TcfCaV2.NAME)); + Assertions.assertEquals(true, gppModel.hasSection(TcfCaV1.NAME)); - Assertions.assertEquals(1, gppModel.getFieldValue(UspV1.NAME, UspV1Field.NOTICE)); - Assertions.assertEquals(2, gppModel.getFieldValue(UspV1.NAME, UspV1Field.OPT_OUT_SALE)); - Assertions.assertEquals(3, gppModel.getFieldValue(UspV1.NAME, UspV1Field.LSPA_COVERED)); + Assertions.assertEquals('Y', gppModel.getFieldValue(UspV1.NAME, UspV1Field.NOTICE)); + Assertions.assertEquals('N', gppModel.getFieldValue(UspV1.NAME, UspV1Field.OPT_OUT_SALE)); + Assertions.assertEquals('N', gppModel.getFieldValue(UspV1.NAME, UspV1Field.LSPA_COVERED)); Assertions.assertEquals(2, gppModel.getFieldValue(TcfEuV2.NAME, TcfEuV2Field.VERSION)); Assertions.assertEquals(880, gppModel.getFieldValue(TcfEuV2.NAME, TcfEuV2Field.CMP_ID)); @@ -354,47 +606,221 @@ public void testDecodeUspv1AndTcfEuV2AndTcfCaV2() throws DecodingException { UspV1 uspV1Section = (UspV1) gppModel.getSection(UspV1.NAME); Integer uspV1Version = uspV1Section.getVersion(); - Integer notice = uspV1Section.getNotice(); + Character notice = uspV1Section.getNotice(); Assertions.assertEquals(1, uspV1Version); - Assertions.assertEquals(1, notice); + Assertions.assertEquals('Y', notice); - TcfCaV2 tcfCaV2Section = (TcfCaV2) gppModel.getSection(TcfCaV2.NAME); - Assertions.assertEquals(50, tcfCaV2Section.getCmpId()); - Assertions.assertEquals(2, tcfCaV2Section.getCmpVersion()); - Assertions.assertEquals(413, tcfCaV2Section.getVendorListVersion()); - Assertions.assertEquals(true, tcfCaV2Section.getUseNonStandardStacks()); + TcfCaV1 tcfCaV1Section = (TcfCaV1) gppModel.getSection(TcfCaV1.NAME); + Assertions.assertEquals(50, tcfCaV1Section.getCmpId()); + Assertions.assertEquals(2, tcfCaV1Section.getCmpVersion()); + Assertions.assertEquals(413, tcfCaV1Section.getVendorListVersion()); + Assertions.assertEquals(true, tcfCaV1Section.getUseNonStandardStacks()); Assertions.assertEquals(Arrays.asList(false, false, false, false, false, false, true, true, true, true, true, true), - tcfCaV2Section.getSpecialFeatureExpressConsent()); + tcfCaV1Section.getSpecialFeatureExpressConsent()); Assertions .assertEquals( Arrays.asList(true, true, true, true, true, true, false, false, false, false, false, false, true, true, true, true, true, true, false, false, false, false, false, false), - tcfCaV2Section.getPurposesExpressConsent()); + tcfCaV1Section.getPurposesExpressConsent()); Assertions .assertEquals( Arrays.asList(false, false, false, false, false, false, true, true, true, true, true, true, false, false, false, false, false, false, true, true, true, true, true, true), - tcfCaV2Section.getPurposesImpliedConsent()); - Assertions.assertEquals(Arrays.asList(12, 24, 48), tcfCaV2Section.getVendorExpressConsent()); - Assertions.assertEquals(Arrays.asList(18, 30), tcfCaV2Section.getVendorImpliedConsent()); + tcfCaV1Section.getPurposesImpliedConsent()); + Assertions.assertEquals(Arrays.asList(12, 24, 48), tcfCaV1Section.getVendorExpressConsent()); + Assertions.assertEquals(Arrays.asList(18, 30), tcfCaV1Section.getVendorImpliedConsent()); Assertions .assertEquals( Arrays.asList(true, true, true, false, false, false, true, true, true, false, false, false, true, true, true, false, false, false, true, true, true, false, false, false), - tcfCaV2Section.getPubPurposesExpressConsent()); + tcfCaV1Section.getPubPurposesExpressConsent()); Assertions .assertEquals( Arrays.asList(false, false, false, true, true, true, false, false, false, true, true, true, false, false, false, true, true, true, false, false, false, true, true, true), - tcfCaV2Section.getPubPurposesImpliedConsent()); - Assertions.assertEquals(3, tcfCaV2Section.getNumCustomPurposes()); - Assertions.assertEquals(Arrays.asList(false, true, false), tcfCaV2Section.getCustomPurposesExpressConsent()); - Assertions.assertEquals(Arrays.asList(true, false, true), tcfCaV2Section.getCustomPurposesImpliedConsent()); - Assertions.assertEquals(utcDateTime, tcfCaV2Section.getCreated()); - Assertions.assertEquals(utcDateTime, tcfCaV2Section.getLastUpdated()); - - Assertions.assertEquals("EN", tcfCaV2Section.getConsentLanguage()); - Assertions.assertEquals(5, tcfCaV2Section.getId()); - Assertions.assertEquals(3, tcfCaV2Section.getSegmentType()); + tcfCaV1Section.getPubPurposesImpliedConsent()); + Assertions.assertEquals(3, tcfCaV1Section.getNumCustomPurposes()); + Assertions.assertEquals(Arrays.asList(false, true, false), tcfCaV1Section.getCustomPurposesExpressConsent()); + Assertions.assertEquals(Arrays.asList(true, false, true), tcfCaV1Section.getCustomPurposesImpliedConsent()); + Assertions.assertEquals(utcDateTime, tcfCaV1Section.getCreated()); + Assertions.assertEquals(utcDateTime, tcfCaV1Section.getLastUpdated()); + + Assertions.assertEquals("EN", tcfCaV1Section.getConsentLanguage()); + Assertions.assertEquals(5, tcfCaV1Section.getId()); + Assertions.assertEquals(3, tcfCaV1Section.getPubPurposesSegmentType()); + } + + @Test + public void testEncode1() { + GppModel gppModel = new GppModel(); + + gppModel.setFieldValue(TcfEuV2.NAME, TcfEuV2Field.VENDOR_CONSENTS, Arrays.asList(28)); + gppModel.setFieldValue(TcfEuV2.NAME, TcfEuV2Field.CREATED, utcDateTime); + gppModel.setFieldValue(TcfEuV2.NAME, TcfEuV2Field.LAST_UPDATED, utcDateTime); + + Assertions.assertEquals("DBABM~CPSG_8APSG_8AAAAAAENAACAAAAAAAAAAAAAAOAAAABAAAAA.QAAA.IAAA", gppModel.encode()); + } + + @Test + public void testEncode2() { + GppModel gppModel = new GppModel(); + + gppModel.setFieldValue(TcfEuV2.NAME, TcfEuV2Field.VENDOR_CONSENTS, Arrays.asList(29)); + gppModel.setFieldValue(TcfEuV2.NAME, TcfEuV2Field.CREATED, utcDateTime); + gppModel.setFieldValue(TcfEuV2.NAME, TcfEuV2Field.LAST_UPDATED, utcDateTime); + + Assertions.assertEquals("DBABM~CPSG_8APSG_8AAAAAAENAACAAAAAAAAAAAAAAOwAQAOgAAAA.QAAA.IAAA", gppModel.encode()); + } + + @Test + public void testEncode3() { + GppModel gppModel = new GppModel(); + + gppModel.setFieldValue(TcfEuV2.NAME, TcfEuV2Field.VENDOR_CONSENTS, Arrays.asList(1, 173, 722)); + gppModel.setFieldValue(TcfEuV2.NAME, TcfEuV2Field.CREATED, utcDateTime); + gppModel.setFieldValue(TcfEuV2.NAME, TcfEuV2Field.LAST_UPDATED, utcDateTime); + + Assertions.assertEquals("DBABM~CPSG_8APSG_8AAAAAAENAACAAAAAAAAAAAAAFpQAwAAgCtAWkAAAAAAA.QAAA.IAAA", + gppModel.encode()); + } + + @Test + public void testDecode1() { + GppModel gppModel = new GppModel("DBABM~CPSG_8APSG_8AAAAAAENAACAAAAAAAAAAAAAAOAAAABAAAAA.QAAA.IAAA"); + Assertions.assertEquals(Arrays.asList(28), gppModel.getFieldValue(TcfEuV2.NAME, TcfEuV2Field.VENDOR_CONSENTS)); + } + + @Test + public void testDecode2() { + GppModel gppModel = new GppModel("DBABM~CPSG_8APSG_8AAAAAAENAACAAAAAAAAAAAAAAOwAQAOgAAAA.QAAA.IAAA"); + Assertions.assertEquals(Arrays.asList(29), gppModel.getFieldValue(TcfEuV2.NAME, TcfEuV2Field.VENDOR_CONSENTS)); + } + + @Test + public void testDecode3() { + GppModel gppModel = new GppModel("DBABM~CPSG_8APSG_8AAAAAAENAACAAAAAAAAAAAAAFpQAwAAgCtAWkAAAAAAA.QAAA.IAAA"); + Assertions.assertEquals(Arrays.asList(1, 173, 722), + gppModel.getFieldValue(TcfEuV2.NAME, TcfEuV2Field.VENDOR_CONSENTS)); + } + + @Test + public void testDecode4() { + GppModel gppModel = new GppModel("DBABTA~1YYN"); + gppModel.getFieldValue(UspV1.NAME, UspV1Field.VERSION); + + } + + @Test + public void testDecode5() { + GppModel gppModel = new GppModel("DBABLA~BVQqAAAAAgA.QA"); + gppModel.getFieldValue(UsNat.NAME, UspV1Field.VERSION); + } + + @Test + public void testDecode6() { + GppModel gppModel = new GppModel("DBABLA~BAAAAAAAAQA.QA"); + gppModel.getFieldValue(UsNat.NAME, UspV1Field.VERSION); + Assertions.assertEquals(Arrays.asList(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0), + gppModel.getFieldValue(UsNat.NAME, UsNatField.SENSITIVE_DATA_PROCESSING)); + Assertions.assertEquals(Arrays.asList(0, 0, 0), + gppModel.getFieldValue(UsNat.NAME, UsNatField.KNOWN_CHILD_SENSITIVE_DATA_CONSENTS)); + } + + @Test + public void testDecode7() { + GppModel gppModel = new GppModel("DBABLA~BAAAAAAAAABA.QA"); + gppModel.getFieldValue(UsNat.NAME, UspV1Field.VERSION); + Assertions.assertEquals(Arrays.asList(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0), + gppModel.getFieldValue(UsNat.NAME, UsNatField.SENSITIVE_DATA_PROCESSING)); + Assertions.assertEquals(Arrays.asList(0, 0, 0), + gppModel.getFieldValue(UsNat.NAME, UsNatField.KNOWN_CHILD_SENSITIVE_DATA_CONSENTS)); + } + + @Test + public void testDecode8() { + GppModel gppModel = new GppModel("DBABLA~BAAAAAABEQA.QA"); + gppModel.getFieldValue(UsNat.NAME, UspV1Field.VERSION); + Assertions.assertEquals(Arrays.asList(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0), + gppModel.getFieldValue(UsNat.NAME, UsNatField.SENSITIVE_DATA_PROCESSING)); + Assertions.assertEquals(Arrays.asList(0, 1, 0), + gppModel.getFieldValue(UsNat.NAME, UsNatField.KNOWN_CHILD_SENSITIVE_DATA_CONSENTS)); + } + + @Test + public void testDecode9() { + GppModel gppModel = new GppModel("DBABLA~BAAAAAAAAQRA.QA"); + gppModel.getFieldValue(UsNat.NAME, UspV1Field.VERSION); + Assertions.assertEquals(Arrays.asList(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1), + gppModel.getFieldValue(UsNat.NAME, UsNatField.SENSITIVE_DATA_PROCESSING)); + Assertions.assertEquals(Arrays.asList(0, 0, 1), + gppModel.getFieldValue(UsNat.NAME, UsNatField.KNOWN_CHILD_SENSITIVE_DATA_CONSENTS)); + } + + @Test + public void testConsistency() { + GppModel fromObjectModel = new GppModel(); + + fromObjectModel.setFieldValue(TcfEuV2.NAME, TcfEuV2Field.PURPOSE_CONSENTS, + Arrays.asList(true, true, true, true, true, true, true, true, true, true)); + fromObjectModel.setFieldValue(TcfEuV2.NAME, TcfEuV2Field.VENDOR_CONSENTS, + Arrays.asList(32, 128, 81, 210, 755, 21, 173, 238)); + + Assertions.assertEquals(fromObjectModel.getSection(TcfEuV2.NAME).encode(), + fromObjectModel.getSection(TcfEuV2.NAME).encode()); + Assertions.assertEquals(fromObjectModel.encode(), fromObjectModel.encode()); + + GppModel decodedModel = new GppModel(fromObjectModel.encode()); + + Assertions.assertEquals( + Arrays.asList(true, true, true, true, true, true, true, true, true, true, false, false, false, false, false, + false, false, false, false, false, false, false, false, false), + decodedModel.getFieldValue(TcfEuV2.NAME, TcfEuV2Field.PURPOSE_CONSENTS)); + Assertions.assertEquals(Arrays.asList(21, 32, 81, 128, 173, 210, 238, 755), + decodedModel.getFieldValue(TcfEuV2.NAME, TcfEuV2Field.VENDOR_CONSENTS)); + + } + + @Test + public void testNullConstructor() { + GppModel gppModel = new GppModel(null); + Assertions.assertEquals("DBAA", gppModel.encode()); + + gppModel.setFieldValue("uspv1", UspV1Field.NOTICE, 'Y'); + Assertions.assertEquals("DBABT~1Y--", gppModel.encode()); + } + + @Test + public void testEmptyStringConstructor() { + GppModel gppModel = new GppModel(""); + Assertions.assertEquals("DBAA", gppModel.encode()); + + gppModel.setFieldValue("uspv1", UspV1Field.NOTICE, 'Y'); + Assertions.assertEquals("DBABT~1Y--", gppModel.encode()); + } + + @Test + public void testDecodingNull() { + GppModel gppModel = new GppModel("DBABTA~1---"); + Assertions.assertEquals("DBABTA~1---", gppModel.encode()); + + gppModel.decode(null); + Assertions.assertEquals("DBAA", gppModel.encode()); + + gppModel.setFieldValue("uspv1", UspV1Field.NOTICE, 'Y'); + Assertions.assertEquals("DBABT~1Y--", gppModel.encode()); + } + + @Test + public void testDecodingEmptyString() { + GppModel gppModel = new GppModel("DBABTA~1---"); + Assertions.assertEquals("DBABTA~1---", gppModel.encode()); + + gppModel.decode(null); + Assertions.assertEquals("DBAA", gppModel.encode()); + + gppModel.setFieldValue("uspv1", UspV1Field.NOTICE, 'Y'); + Assertions.assertEquals("DBABT~1Y--", gppModel.encode()); } + + } diff --git a/iabgpp-encoder/src/test/java/com/iab/gpp/encoder/base64/TraditionalBase64UrlEncoderTest.java b/iabgpp-encoder/src/test/java/com/iab/gpp/encoder/base64/TraditionalBase64UrlEncoderTest.java new file mode 100644 index 00000000..bd154790 --- /dev/null +++ b/iabgpp-encoder/src/test/java/com/iab/gpp/encoder/base64/TraditionalBase64UrlEncoderTest.java @@ -0,0 +1,40 @@ +package com.iab.gpp.encoder.base64; + +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; + +public class TraditionalBase64UrlEncoderTest { + + private TraditionalBase64UrlEncoder base64UrlEncoder = TraditionalBase64UrlEncoder.getInstance(); + + @Test + public void testEncode1() { + Assertions.assertEquals("DBABMAAA", base64UrlEncoder.encode("0000110000010000000000010011")); + } + + @Test + public void testEncode2() { + Assertions.assertEquals("DBACNYAA", base64UrlEncoder.encode("000011000001000000000010001101011")); + } + + @Test + public void testEncode3() { + Assertions.assertEquals("DBABjwAA", base64UrlEncoder.encode("00001100000100000000000110001111")); + } + + @Test + public void testDecode1() { + Assertions.assertEquals("000011000001000000000001001100000000000000000000", base64UrlEncoder.decode("DBABMAAA")); + } + + @Test + public void testDecode2() { + Assertions.assertEquals("000011000001000000000010001101011000000000000000", base64UrlEncoder.decode("DBACNYAA")); + } + + @Test + public void testDecode3() { + Assertions.assertEquals("000011000001000000000001100011110000000000000000", base64UrlEncoder.decode("DBABjwAA")); + } + +} diff --git a/iabgpp-encoder/src/test/java/com/iab/gpp/encoder/datatype/EncodableBooleanTest.java b/iabgpp-encoder/src/test/java/com/iab/gpp/encoder/datatype/EncodableBooleanTest.java index c6b7ab45..d015acd1 100644 --- a/iabgpp-encoder/src/test/java/com/iab/gpp/encoder/datatype/EncodableBooleanTest.java +++ b/iabgpp-encoder/src/test/java/com/iab/gpp/encoder/datatype/EncodableBooleanTest.java @@ -3,16 +3,16 @@ import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.Test; -class EncodableBooleanTest { +public class EncodableBooleanTest { @Test - void testSubstring1() { + public void testSubstring1() throws SubstringException { Assertions.assertEquals("000000000000000000000000000000000000", new EncodableDatetime().substring("10000000000000000000000000000000000001", 1)); } @Test - void testSubstring2() { + public void testSubstring2() throws SubstringException { Assertions.assertEquals("111111111111111111111111111111111111", new EncodableDatetime().substring("01111111111111111111111111111111111110", 1)); } diff --git a/iabgpp-encoder/src/test/java/com/iab/gpp/encoder/datatype/EncodableDatetimeTest.java b/iabgpp-encoder/src/test/java/com/iab/gpp/encoder/datatype/EncodableDatetimeTest.java index a607bd6f..43d271ba 100644 --- a/iabgpp-encoder/src/test/java/com/iab/gpp/encoder/datatype/EncodableDatetimeTest.java +++ b/iabgpp-encoder/src/test/java/com/iab/gpp/encoder/datatype/EncodableDatetimeTest.java @@ -4,16 +4,16 @@ import org.junit.jupiter.api.Test; import com.iab.gpp.encoder.error.DecodingException; -class EncodableDatetimeTest { +public class EncodableDatetimeTest { @Test - void testSubstring1() throws DecodingException { + public void testSubstring1() throws DecodingException, SubstringException { Assertions.assertEquals("000000000000000000000000000000000000", new EncodableDatetime().substring("10000000000000000000000000000000000001", 1)); } @Test - void testSubstring2() throws DecodingException { + public void testSubstring2() throws DecodingException, SubstringException { Assertions.assertEquals("111111111111111111111111111111111111", new EncodableDatetime().substring("01111111111111111111111111111111111110", 1)); } diff --git a/iabgpp-encoder/src/test/java/com/iab/gpp/encoder/datatype/EncodableFibonacciIntegerRangeTest.java b/iabgpp-encoder/src/test/java/com/iab/gpp/encoder/datatype/EncodableFibonacciIntegerRangeTest.java index c99ed18e..765d5154 100644 --- a/iabgpp-encoder/src/test/java/com/iab/gpp/encoder/datatype/EncodableFibonacciIntegerRangeTest.java +++ b/iabgpp-encoder/src/test/java/com/iab/gpp/encoder/datatype/EncodableFibonacciIntegerRangeTest.java @@ -4,10 +4,10 @@ import org.junit.jupiter.api.Test; import com.iab.gpp.encoder.error.DecodingException; -class EncodableFibonacciIntegerRangeTest { +public class EncodableFibonacciIntegerRangeTest { @Test - void testSubstring1() throws DecodingException { + public void testSubstring1() throws DecodingException, SubstringException { Assertions.assertEquals("0000000000100001110110011", new EncodableFibonacciIntegerRange().substring("100000000001000011101100110", 1)); } diff --git a/iabgpp-encoder/src/test/java/com/iab/gpp/encoder/datatype/EncodableFibonacciIntegerTest.java b/iabgpp-encoder/src/test/java/com/iab/gpp/encoder/datatype/EncodableFibonacciIntegerTest.java index b78d4a12..61dd7d0a 100644 --- a/iabgpp-encoder/src/test/java/com/iab/gpp/encoder/datatype/EncodableFibonacciIntegerTest.java +++ b/iabgpp-encoder/src/test/java/com/iab/gpp/encoder/datatype/EncodableFibonacciIntegerTest.java @@ -4,10 +4,10 @@ import org.junit.jupiter.api.Test; import com.iab.gpp.encoder.error.DecodingException; -class EncodableFibonacciIntegerTest { +public class EncodableFibonacciIntegerTest { @Test - void testSubstring1() throws DecodingException { + public void testSubstring1() throws DecodingException, SubstringException { Assertions.assertEquals("0011", new EncodableFibonacciInteger().substring("100111", 1)); } diff --git a/iabgpp-encoder/src/test/java/com/iab/gpp/encoder/datatype/EncodableFixedBitfieldTest.java b/iabgpp-encoder/src/test/java/com/iab/gpp/encoder/datatype/EncodableFixedBitfieldTest.java index e57e292b..89ad98af 100644 --- a/iabgpp-encoder/src/test/java/com/iab/gpp/encoder/datatype/EncodableFixedBitfieldTest.java +++ b/iabgpp-encoder/src/test/java/com/iab/gpp/encoder/datatype/EncodableFixedBitfieldTest.java @@ -3,15 +3,15 @@ import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.Test; -class EncodableFixedBitfieldTest { +public class EncodableFixedBitfieldTest { @Test - void testSubstring1() { + public void testSubstring1() throws SubstringException { Assertions.assertEquals("000", new EncodableFixedBitfield(3).substring("10001", 1)); } @Test - void testSubstring2() { + public void testSubstring2() throws SubstringException { Assertions.assertEquals("111", new EncodableFixedBitfield(3).substring("01110", 1)); } diff --git a/iabgpp-encoder/src/test/java/com/iab/gpp/encoder/datatype/EncodableFixedIntegerListTest.java b/iabgpp-encoder/src/test/java/com/iab/gpp/encoder/datatype/EncodableFixedIntegerListTest.java new file mode 100644 index 00000000..7146cc01 --- /dev/null +++ b/iabgpp-encoder/src/test/java/com/iab/gpp/encoder/datatype/EncodableFixedIntegerListTest.java @@ -0,0 +1,18 @@ +package com.iab.gpp.encoder.datatype; + +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; + +public class EncodableFixedIntegerListTest { + + @Test + public void testSubstring1() throws SubstringException { + Assertions.assertEquals("1000", new EncodableFixedIntegerList(2, 2).substring("10001", 0)); + } + + @Test + public void testSubstring2() throws SubstringException { + Assertions.assertEquals("1110", new EncodableFixedIntegerList(2, 2).substring("01110", 1)); + } + +} diff --git a/iabgpp-encoder/src/test/java/com/iab/gpp/encoder/datatype/EncodableFixedIntegerRangeTest.java b/iabgpp-encoder/src/test/java/com/iab/gpp/encoder/datatype/EncodableFixedIntegerRangeTest.java index e9c6dcf2..0982aa40 100644 --- a/iabgpp-encoder/src/test/java/com/iab/gpp/encoder/datatype/EncodableFixedIntegerRangeTest.java +++ b/iabgpp-encoder/src/test/java/com/iab/gpp/encoder/datatype/EncodableFixedIntegerRangeTest.java @@ -1,16 +1,53 @@ package com.iab.gpp.encoder.datatype; +import java.util.Arrays; import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.Test; import com.iab.gpp.encoder.error.DecodingException; +import com.iab.gpp.encoder.error.EncodingException; -class EncodableFixedIntegerRangeTest { +public class EncodableFixedIntegerRangeTest { @Test - void testSubstring1() throws DecodingException { + public void testSubstring1() throws DecodingException, SubstringException { Assertions.assertEquals("00000000001000000000000000011100000000000001010000000000001000", new EncodableFixedIntegerRange().substring("1000000000010000000000000000111000000000000010100000000000010001", 1)); } + @Test + public void testSubstring2() throws DecodingException, SubstringException { + Assertions.assertEquals("00000000000100000000000011101", new EncodableFixedIntegerRange().substring( + "000010001111010010000110111111111100000000001111010010000110111111111100000000000000000000000000000000000000000100001101000000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000001110110000000000010000000000001110100000000000000000000000000000", + 230)); + } + + @Test + public void testEncode1() throws EncodingException { + EncodableFixedIntegerRange encodableFixedIntegerRange = new EncodableFixedIntegerRange(); + encodableFixedIntegerRange.setValue(Arrays.asList(28)); + Assertions.assertEquals("00000000000100000000000011100", encodableFixedIntegerRange.encode()); + } + + @Test + public void testEncode2() throws EncodingException { + EncodableFixedIntegerRange encodableFixedIntegerRange = new EncodableFixedIntegerRange(); + encodableFixedIntegerRange.setValue(Arrays.asList(29)); + Assertions.assertEquals("00000000000100000000000011101", encodableFixedIntegerRange.encode()); + } + + @Test + public void testDecode1() throws DecodingException { + EncodableFixedIntegerRange encodableFixedIntegerRange = new EncodableFixedIntegerRange(); + encodableFixedIntegerRange.decode("00000000000100000000000011100"); + Assertions.assertEquals(Arrays.asList(28), encodableFixedIntegerRange.getValue()); + } + + @Test + public void testDecode2() throws DecodingException { + EncodableFixedIntegerRange encodableFixedIntegerRange = new EncodableFixedIntegerRange(); + encodableFixedIntegerRange.decode("00000000000100000000000011101"); + Assertions.assertEquals(Arrays.asList(29), encodableFixedIntegerRange.getValue()); + } + } diff --git a/iabgpp-encoder/src/test/java/com/iab/gpp/encoder/datatype/EncodableFixedIntegerTest.java b/iabgpp-encoder/src/test/java/com/iab/gpp/encoder/datatype/EncodableFixedIntegerTest.java index a39987a9..709fd156 100644 --- a/iabgpp-encoder/src/test/java/com/iab/gpp/encoder/datatype/EncodableFixedIntegerTest.java +++ b/iabgpp-encoder/src/test/java/com/iab/gpp/encoder/datatype/EncodableFixedIntegerTest.java @@ -3,15 +3,15 @@ import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.Test; -class EncodableFixedIntegerTest { +public class EncodableFixedIntegerTest { @Test - void testSubstring1() { + public void testSubstring1() throws SubstringException { Assertions.assertEquals("000", new EncodableFixedInteger(3).substring("10001", 1)); } @Test - void testSubstring2() { + public void testSubstring2() throws SubstringException { Assertions.assertEquals("111", new EncodableFixedInteger(3).substring("01110", 1)); } diff --git a/iabgpp-encoder/src/test/java/com/iab/gpp/encoder/datatype/EncodableFixedStringTest.java b/iabgpp-encoder/src/test/java/com/iab/gpp/encoder/datatype/EncodableFixedStringTest.java index 8305f9c4..969a6c15 100644 --- a/iabgpp-encoder/src/test/java/com/iab/gpp/encoder/datatype/EncodableFixedStringTest.java +++ b/iabgpp-encoder/src/test/java/com/iab/gpp/encoder/datatype/EncodableFixedStringTest.java @@ -3,15 +3,15 @@ import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.Test; -class EncodableFixedStringTest { +public class EncodableFixedStringTest { @Test - void testSubstring1() { + public void testSubstring1() throws SubstringException { Assertions.assertEquals("000000000000", new EncodableFixedString(2).substring("10000000000001", 1)); } @Test - void testSubstring2() { + public void testSubstring2() throws SubstringException { Assertions.assertEquals("111111111111", new EncodableFixedString(2).substring("01111111111110", 1)); } diff --git a/iabgpp-encoder/src/test/java/com/iab/gpp/encoder/datatype/EncodableOptimizedFixedRangeTest.java b/iabgpp-encoder/src/test/java/com/iab/gpp/encoder/datatype/EncodableOptimizedFixedRangeTest.java new file mode 100644 index 00000000..5551b3e4 --- /dev/null +++ b/iabgpp-encoder/src/test/java/com/iab/gpp/encoder/datatype/EncodableOptimizedFixedRangeTest.java @@ -0,0 +1,73 @@ +package com.iab.gpp.encoder.datatype; + +import java.util.Arrays; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; + +public class EncodableOptimizedFixedRangeTest { + + private EncodableOptimizedFixedRange encodableOptimizedFixedRange = new EncodableOptimizedFixedRange(); + + @Test + public void testEncode1() { + encodableOptimizedFixedRange.setValue(Arrays.asList(12, 24, 48)); + Assertions.assertEquals("00000000001100000000000000001000000000001000000000000000000000001", + encodableOptimizedFixedRange.encode()); + } + + @Test + public void testEncode2() { + encodableOptimizedFixedRange.setValue(Arrays.asList(18, 30)); + Assertions.assertEquals("00000000000111100000000000000000001000000000001", encodableOptimizedFixedRange.encode()); + } + + @Test + public void testEncode3() { + encodableOptimizedFixedRange.setValue(Arrays.asList(28)); + Assertions.assertEquals("000000000001110000000000000000000000000000001", encodableOptimizedFixedRange.encode()); + } + + @Test + public void testEncode4() { + encodableOptimizedFixedRange.setValue(Arrays.asList(29)); + Assertions.assertEquals("0000000000011101100000000000100000000000011101", encodableOptimizedFixedRange.encode()); + } + + @Test + public void testDecode1() { + encodableOptimizedFixedRange.decode("00000000001100000000000000001000000000001000000000000000000000001"); + Assertions.assertEquals(Arrays.asList(12, 24, 48), encodableOptimizedFixedRange.getValue()); + } + + @Test + public void testDecode2() { + encodableOptimizedFixedRange.decode("00000000000111100000000000000000001000000000001"); + Assertions.assertEquals(Arrays.asList(18, 30), encodableOptimizedFixedRange.getValue()); + } + + @Test + public void testDecode3() { + encodableOptimizedFixedRange.decode("000000000001110000000000000000000000000000001"); + Assertions.assertEquals(Arrays.asList(28), encodableOptimizedFixedRange.getValue()); + } + + @Test + public void testDecode4() { + encodableOptimizedFixedRange.decode("0000000000011101100000000000100000000000011101"); + Assertions.assertEquals(Arrays.asList(29), encodableOptimizedFixedRange.getValue()); + } + + @Test + public void testSubstring1() throws SubstringException { + Assertions.assertEquals("000000000001110000000000000000000000000000001", encodableOptimizedFixedRange.substring( + "000010001111010010000110111111111100000000001111010010000110111111111100000000000000000000000000000000000000000100001101000000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000001110000000000000000000000000000001000000000000000000000000000000", + 213)); + } + + @Test + public void testSubstring2() throws SubstringException { + Assertions.assertEquals("0000000000011101100000000000100000000000011101", encodableOptimizedFixedRange.substring( + "000010001111010010000110111111111100000000001111010010000110111111111100000000000000000000000000000000000000000100001101000000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000001110110000000000010000000000001110100000000000000000000000000000", + 213)); + } +} diff --git a/iabgpp-encoder/src/test/java/com/iab/gpp/encoder/datatype/encoder/Base64UrlEncoderTest.java b/iabgpp-encoder/src/test/java/com/iab/gpp/encoder/datatype/encoder/Base64UrlEncoderTest.java deleted file mode 100644 index 5f2f8b9f..00000000 --- a/iabgpp-encoder/src/test/java/com/iab/gpp/encoder/datatype/encoder/Base64UrlEncoderTest.java +++ /dev/null @@ -1,40 +0,0 @@ -package com.iab.gpp.encoder.datatype.encoder; - -import org.junit.jupiter.api.Assertions; -import org.junit.jupiter.api.Test; -import com.iab.gpp.encoder.error.DecodingException; -import com.iab.gpp.encoder.error.EncodingException; - -class Base64UrlEncoderTest { - - @Test - void testEncode1() throws EncodingException { - Assertions.assertEquals("DBABMA", Base64UrlEncoder.encode("0000110000010000000000010011")); - } - - @Test - void testEncode2() throws EncodingException { - Assertions.assertEquals("DBACNYA", Base64UrlEncoder.encode("000011000001000000000010001101011")); - } - - @Test - void testEncode3() throws EncodingException { - Assertions.assertEquals("DBABjw", Base64UrlEncoder.encode("00001100000100000000000110001111")); - } - - @Test - void testDecode1() throws DecodingException { - Assertions.assertEquals("000011000001000000000001001100000000", Base64UrlEncoder.decode("DBABMA")); - } - - @Test - void testDecode2() throws DecodingException { - Assertions.assertEquals("000011000001000000000010001101011000000000", Base64UrlEncoder.decode("DBACNYA")); - } - - @Test - void testDecode3() throws DecodingException { - Assertions.assertEquals("000011000001000000000001100011110000", Base64UrlEncoder.decode("DBABjw")); - } - -} diff --git a/iabgpp-encoder/src/test/java/com/iab/gpp/encoder/datatype/encoder/BooleanEncoderTest.java b/iabgpp-encoder/src/test/java/com/iab/gpp/encoder/datatype/encoder/BooleanEncoderTest.java index e7af9742..fea6ee70 100644 --- a/iabgpp-encoder/src/test/java/com/iab/gpp/encoder/datatype/encoder/BooleanEncoderTest.java +++ b/iabgpp-encoder/src/test/java/com/iab/gpp/encoder/datatype/encoder/BooleanEncoderTest.java @@ -3,32 +3,31 @@ import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.Test; import com.iab.gpp.encoder.error.DecodingException; -import com.iab.gpp.encoder.error.EncodingException; -class BooleanEncoderTest { +public class BooleanEncoderTest { @Test - void testEncode1() throws EncodingException { + public void testEncode1() { Assertions.assertEquals("0", BooleanEncoder.encode(false)); } @Test - void testEncode2() throws EncodingException { + public void testEncode2() { Assertions.assertEquals("1", BooleanEncoder.encode(true)); } @Test - void testDecode1() throws DecodingException { + public void testDecode1() { Assertions.assertEquals(false, BooleanEncoder.decode("0")); } @Test - void testDecode2() throws DecodingException { + public void testDecode2() { Assertions.assertEquals(true, BooleanEncoder.decode("1")); } @Test - void testDecode3() { + public void testDecode3() { try { BooleanEncoder.decode(""); Assertions.fail("DecodingException expected"); @@ -38,7 +37,7 @@ void testDecode3() { } @Test - void testDecode4() { + public void testDecode4() { try { BooleanEncoder.decode("2"); Assertions.fail("DecodingException expected"); @@ -48,7 +47,7 @@ void testDecode4() { } @Test - void testDecode5() { + public void testDecode5() { try { BooleanEncoder.decode("00"); Assertions.fail("DecodingException expected"); @@ -58,7 +57,7 @@ void testDecode5() { } @Test - void testDecode6() { + public void testDecode6() { try { BooleanEncoder.decode("01"); Assertions.fail("DecodingException expected"); @@ -68,7 +67,7 @@ void testDecode6() { } @Test - void testDecode7() { + public void testDecode7() { try { BooleanEncoder.decode("10"); Assertions.fail("DecodingException expected"); diff --git a/iabgpp-encoder/src/test/java/com/iab/gpp/encoder/datatype/encoder/DatetimeEncoderTest.java b/iabgpp-encoder/src/test/java/com/iab/gpp/encoder/datatype/encoder/DatetimeEncoderTest.java index ec67d019..ec75a122 100644 --- a/iabgpp-encoder/src/test/java/com/iab/gpp/encoder/datatype/encoder/DatetimeEncoderTest.java +++ b/iabgpp-encoder/src/test/java/com/iab/gpp/encoder/datatype/encoder/DatetimeEncoderTest.java @@ -6,10 +6,10 @@ import org.junit.jupiter.api.Test; import com.iab.gpp.encoder.error.DecodingException; -class DatetimeEncoderTest { +public class DatetimeEncoderTest { @Test - void test1() throws DecodingException { + public void test1() throws DecodingException { ZonedDateTime date1 = ZonedDateTime.now(ZoneId.of("UTC")); String encodedDate1 = DatetimeEncoder.encode(date1); ZonedDateTime date2 = DatetimeEncoder.decode(encodedDate1); diff --git a/iabgpp-encoder/src/test/java/com/iab/gpp/encoder/datatype/encoder/FibonacciIntegerEncoderTest.java b/iabgpp-encoder/src/test/java/com/iab/gpp/encoder/datatype/encoder/FibonacciIntegerEncoderTest.java index b951c7d3..2948b035 100644 --- a/iabgpp-encoder/src/test/java/com/iab/gpp/encoder/datatype/encoder/FibonacciIntegerEncoderTest.java +++ b/iabgpp-encoder/src/test/java/com/iab/gpp/encoder/datatype/encoder/FibonacciIntegerEncoderTest.java @@ -4,74 +4,74 @@ import org.junit.jupiter.api.Test; import com.iab.gpp.encoder.error.DecodingException; -class FibonacciIntegerEncoderTest { +public class FibonacciIntegerEncoderTest { @Test - void testEncode1() { + public void testEncode1() { Assertions.assertEquals("11", FibonacciIntegerEncoder.encode(1)); } - void testEncode2() { + public void testEncode2() { Assertions.assertEquals("011", FibonacciIntegerEncoder.encode(2)); } - void testEncode3() { + public void testEncode3() { Assertions.assertEquals("0011", FibonacciIntegerEncoder.encode(3)); } - void testEncode4() { + public void testEncode4() { Assertions.assertEquals("1011", FibonacciIntegerEncoder.encode(4)); } - void testEncode5() { + public void testEncode5() { Assertions.assertEquals("00011", FibonacciIntegerEncoder.encode(5)); } - void testEncode6() { + public void testEncode6() { Assertions.assertEquals("10011", FibonacciIntegerEncoder.encode(6)); } - void testEncode7() { + public void testEncode7() { Assertions.assertEquals("01011", FibonacciIntegerEncoder.encode(7)); } @Test - void testDecode1() throws DecodingException { + public void testDecode1() throws DecodingException { Assertions.assertEquals(1, FibonacciIntegerEncoder.decode("11")); } @Test - void testDecode2() throws DecodingException { + public void testDecode2() throws DecodingException { Assertions.assertEquals(2, FibonacciIntegerEncoder.decode("011")); } @Test - void testDecode3() throws DecodingException { + public void testDecode3() throws DecodingException { Assertions.assertEquals(3, FibonacciIntegerEncoder.decode("0011")); } @Test - void testDecode4() throws DecodingException { + public void testDecode4() throws DecodingException { Assertions.assertEquals(4, FibonacciIntegerEncoder.decode("1011")); } @Test - void testDecode5() throws DecodingException { + public void testDecode5() throws DecodingException { Assertions.assertEquals(5, FibonacciIntegerEncoder.decode("00011")); } @Test - void testDecode6() throws DecodingException { + public void testDecode6() throws DecodingException { Assertions.assertEquals(6, FibonacciIntegerEncoder.decode("10011")); } @Test - void testDecode7() throws DecodingException { + public void testDecode7() throws DecodingException { Assertions.assertEquals(7, FibonacciIntegerEncoder.decode("01011")); } @Test - void testDecode8() { + public void testDecode8() { try { FibonacciIntegerEncoder.decode("110"); Assertions.fail("DecodingException expected"); @@ -81,7 +81,7 @@ void testDecode8() { } @Test - void testDecode9() { + public void testDecode9() { try { FibonacciIntegerEncoder.decode("1100"); Assertions.fail("DecodingException expected"); @@ -91,7 +91,7 @@ void testDecode9() { } @Test - void testDecode10() { + public void testDecode10() { try { FibonacciIntegerEncoder.decode("0110000000"); Assertions.fail("DecodingException expected"); diff --git a/iabgpp-encoder/src/test/java/com/iab/gpp/encoder/datatype/encoder/FibonacciIntegerRangeEncoderTest.java b/iabgpp-encoder/src/test/java/com/iab/gpp/encoder/datatype/encoder/FibonacciIntegerRangeEncoderTest.java index 55cfc97b..5e00de2f 100644 --- a/iabgpp-encoder/src/test/java/com/iab/gpp/encoder/datatype/encoder/FibonacciIntegerRangeEncoderTest.java +++ b/iabgpp-encoder/src/test/java/com/iab/gpp/encoder/datatype/encoder/FibonacciIntegerRangeEncoderTest.java @@ -6,67 +6,79 @@ import org.junit.jupiter.api.Test; import com.iab.gpp.encoder.error.DecodingException; -class FibonacciIntegerRangeEncoderTest { +public class FibonacciIntegerRangeEncoderTest { @Test - void testEncode1() { + public void testEncode1() { Assertions.assertEquals("000000000000", FibonacciIntegerRangeEncoder.encode(new ArrayList<>())); } @Test - void testEncode2() { + public void testEncode2() { Assertions.assertEquals("0000000000010011", FibonacciIntegerRangeEncoder.encode(Arrays.asList(2))); } @Test - void testEncode3() { + public void testEncode3() { Assertions.assertEquals("00000000000110111011", FibonacciIntegerRangeEncoder.encode(Arrays.asList(2, 3, 4, 5, 6))); } @Test - void testEncode4() { + public void testEncode4() { Assertions.assertEquals("000000000010001110011011", FibonacciIntegerRangeEncoder.encode(Arrays.asList(2, 5, 6, 7))); } @Test - void testEncode5() { + public void testEncode5() { Assertions.assertEquals("000000000010001110011011", FibonacciIntegerRangeEncoder.encode(Arrays.asList(6, 7, 2, 5))); } @Test - void testEncode6() { + public void testEncode6() { Assertions.assertEquals("0000000000100001110110011", FibonacciIntegerRangeEncoder.encode(Arrays.asList(3, 5, 6, 7, 8))); } @Test - void testDecode1() throws DecodingException { + public void testEncode7() { + Assertions.assertEquals("00000000001000111001101011", + FibonacciIntegerRangeEncoder.encode(Arrays.asList(2, 5, 6, 7, 8, 9, 10, 11, 12))); + } + + @Test + public void testDecode1() throws DecodingException { Assertions.assertEquals(new ArrayList<>(), FibonacciIntegerRangeEncoder.decode("000000000000")); } @Test - void testDecode2() throws DecodingException { + public void testDecode2() throws DecodingException { Assertions.assertEquals(Arrays.asList(2), FibonacciIntegerRangeEncoder.decode("0000000000010011")); } @Test - void testDecode3() throws DecodingException { + public void testDecode3() throws DecodingException { Assertions.assertEquals(Arrays.asList(2, 3, 4, 5, 6), FibonacciIntegerRangeEncoder.decode("00000000000110111011")); } @Test - void testDecode4() throws DecodingException { + public void testDecode4() throws DecodingException { Assertions.assertEquals(Arrays.asList(2, 5, 6, 7), FibonacciIntegerRangeEncoder.decode("000000000010001110011011")); } @Test - void testDecode5() throws DecodingException { + public void testDecode5() throws DecodingException { Assertions.assertEquals(Arrays.asList(3, 5, 6, 7, 8), FibonacciIntegerRangeEncoder.decode("0000000000100001110110011")); } @Test - void testDecode6() { + public void testDecode6() throws DecodingException { + Assertions.assertEquals(Arrays.asList(2, 5, 6, 7, 8, 9, 10, 11, 12), + FibonacciIntegerRangeEncoder.decode("00000000001000111001101011")); + } + + @Test + public void testDecode7() { try { FibonacciIntegerRangeEncoder.decode("0011"); Assertions.fail("DecodingException expected"); @@ -76,7 +88,7 @@ void testDecode6() { } @Test - void testDecode7() { + public void testDecode8() { try { FibonacciIntegerRangeEncoder.decode("000000000002"); Assertions.fail("DecodingException expected"); diff --git a/iabgpp-encoder/src/test/java/com/iab/gpp/encoder/datatype/encoder/FixedBitfieldEncoderTest.java b/iabgpp-encoder/src/test/java/com/iab/gpp/encoder/datatype/encoder/FixedBitfieldEncoderTest.java index 8714e273..d66e3538 100644 --- a/iabgpp-encoder/src/test/java/com/iab/gpp/encoder/datatype/encoder/FixedBitfieldEncoderTest.java +++ b/iabgpp-encoder/src/test/java/com/iab/gpp/encoder/datatype/encoder/FixedBitfieldEncoderTest.java @@ -7,80 +7,90 @@ import com.iab.gpp.encoder.error.DecodingException; import com.iab.gpp.encoder.error.EncodingException; -class FixedBitfieldEncoderTest { +public class FixedBitfieldEncoderTest { @Test - void testEncode1() throws EncodingException { + public void testEncode1() { Assertions.assertEquals("00", FixedBitfieldEncoder.encode(new ArrayList<>(), 2)); } @Test - void testEncode2() throws EncodingException { + public void testEncode2() { Assertions.assertEquals("0", FixedBitfieldEncoder.encode(Arrays.asList(false), 1)); } @Test - void testEncode3() throws EncodingException { + public void testEncode3() { Assertions.assertEquals("1", FixedBitfieldEncoder.encode(Arrays.asList(true), 1)); } @Test - void testEncode4() throws EncodingException { + public void testEncode4() { Assertions.assertEquals("00", FixedBitfieldEncoder.encode(Arrays.asList(false, false), 2)); } @Test - void testEncode5() throws EncodingException { + public void testEncode5() { Assertions.assertEquals("01", FixedBitfieldEncoder.encode(Arrays.asList(false, true), 2)); } @Test - void testEncode6() throws EncodingException { + public void testEncode6() { Assertions.assertEquals("10", FixedBitfieldEncoder.encode(Arrays.asList(true, false), 2)); } @Test - void testEncode7() throws EncodingException { + public void testEncode7() { Assertions.assertEquals("11", FixedBitfieldEncoder.encode(Arrays.asList(true, true), 2)); } @Test - void testDecode1() throws DecodingException { + public void testEncode8() { + try { + FixedBitfieldEncoder.encode(Arrays.asList(true, true, true), 2); + Assertions.fail("EncodingException expected"); + } catch (EncodingException e) { + + } + } + + @Test + public void testDecode1() { Assertions.assertEquals(new ArrayList<>(), FixedBitfieldEncoder.decode("")); } @Test - void testDecode2() throws DecodingException { + public void testDecode2() { Assertions.assertEquals(Arrays.asList(false), FixedBitfieldEncoder.decode("0")); } @Test - void testDecode3() throws DecodingException { + public void testDecode3() { Assertions.assertEquals(Arrays.asList(true), FixedBitfieldEncoder.decode("1")); } @Test - void testDecode4() throws DecodingException { + public void testDecode4() { Assertions.assertEquals(Arrays.asList(false, false), FixedBitfieldEncoder.decode("00")); } @Test - void testDecode5() throws DecodingException { + public void testDecode5() { Assertions.assertEquals(Arrays.asList(false, true), FixedBitfieldEncoder.decode("01")); } @Test - void testDecode6() throws DecodingException { + public void testDecode6() { Assertions.assertEquals(Arrays.asList(true, false), FixedBitfieldEncoder.decode("10")); } @Test - void testDecode7() throws DecodingException { + public void testDecode7() { Assertions.assertEquals(Arrays.asList(true, true), FixedBitfieldEncoder.decode("11")); } @Test - void testDecode8() { + public void testDecode8() { try { FixedBitfieldEncoder.decode("2"); Assertions.fail("DecodingException expected"); diff --git a/iabgpp-encoder/src/test/java/com/iab/gpp/encoder/datatype/encoder/FixedIntegerEncoderTest.java b/iabgpp-encoder/src/test/java/com/iab/gpp/encoder/datatype/encoder/FixedIntegerEncoderTest.java index 77069188..a30b882b 100644 --- a/iabgpp-encoder/src/test/java/com/iab/gpp/encoder/datatype/encoder/FixedIntegerEncoderTest.java +++ b/iabgpp-encoder/src/test/java/com/iab/gpp/encoder/datatype/encoder/FixedIntegerEncoderTest.java @@ -3,66 +3,77 @@ import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.Test; import com.iab.gpp.encoder.error.DecodingException; +import com.iab.gpp.encoder.error.EncodingException; -class FixedIntegerEncoderTest { +public class FixedIntegerEncoderTest { @Test - void testEncode1() { + public void testEncode1() { Assertions.assertEquals("0", FixedIntegerEncoder.encode(0, 1)); } @Test - void testEncode2() { + public void testEncode2() { Assertions.assertEquals("000000", FixedIntegerEncoder.encode(0, 6)); } @Test - void testEncode3() { + public void testEncode3() { Assertions.assertEquals("1", FixedIntegerEncoder.encode(1, 1)); } @Test - void testEncode4() { + public void testEncode4() { Assertions.assertEquals("0001", FixedIntegerEncoder.encode(1, 4)); } @Test - void testEncode5() { + public void testEncode5() { Assertions.assertEquals("00000111", FixedIntegerEncoder.encode(7, 8)); } + + @Test + public void testEncode6() { + try { + FixedIntegerEncoder.encode(8, 1); + Assertions.fail("EncodingException expected"); + } catch (EncodingException e) { + + } + } @Test - void testDecode1() throws DecodingException { + public void testDecode1() throws DecodingException { Assertions.assertEquals(0, FixedIntegerEncoder.decode("")); } @Test - void testDecode2() throws DecodingException { + public void testDecode2() throws DecodingException { Assertions.assertEquals(0, FixedIntegerEncoder.decode("0")); } @Test - void testDecode3() throws DecodingException { + public void testDecode3() throws DecodingException { Assertions.assertEquals(0, FixedIntegerEncoder.decode("000000")); } @Test - void testDecode4() throws DecodingException { + public void testDecode4() throws DecodingException { Assertions.assertEquals(1, FixedIntegerEncoder.decode("1")); } @Test - void testDecode5() throws DecodingException { + public void testDecode5() throws DecodingException { Assertions.assertEquals(1, FixedIntegerEncoder.decode("000001")); } @Test - void testDecode6() throws DecodingException { + public void testDecode6() throws DecodingException { Assertions.assertEquals(8, FixedIntegerEncoder.decode("1000")); } @Test - void testDecode7() throws DecodingException { + public void testDecode7() throws DecodingException { Assertions.assertEquals(8, FixedIntegerEncoder.decode("0000001000")); } } diff --git a/iabgpp-encoder/src/test/java/com/iab/gpp/encoder/datatype/encoder/FixedIntegerListEncoderTest.java b/iabgpp-encoder/src/test/java/com/iab/gpp/encoder/datatype/encoder/FixedIntegerListEncoderTest.java new file mode 100644 index 00000000..25de7e17 --- /dev/null +++ b/iabgpp-encoder/src/test/java/com/iab/gpp/encoder/datatype/encoder/FixedIntegerListEncoderTest.java @@ -0,0 +1,226 @@ +package com.iab.gpp.encoder.datatype.encoder; + +import java.util.ArrayList; +import java.util.Arrays; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; +import com.iab.gpp.encoder.error.DecodingException; +import com.iab.gpp.encoder.error.EncodingException; + +public class FixedIntegerListEncoderTest { + + @Test + public void testEncode1() { + Assertions.assertEquals("0000", FixedIntegerListEncoder.encode(new ArrayList<>(), 2, 2)); + } + + @Test + public void testEncode2() { + Assertions.assertEquals("0000", FixedIntegerListEncoder.encode(Arrays.asList(0), 2, 2)); + } + + @Test + public void testEncode3() { + Assertions.assertEquals("0000", FixedIntegerListEncoder.encode(Arrays.asList(0, 0), 2, 2)); + } + + @Test + public void testEncode4() { + Assertions.assertEquals("0001", FixedIntegerListEncoder.encode(Arrays.asList(0, 1), 2, 2)); + } + + @Test + public void testEncode5() { + Assertions.assertEquals("0010", FixedIntegerListEncoder.encode(Arrays.asList(0, 2), 2, 2)); + } + + @Test + public void testEncode6() { + Assertions.assertEquals("0011", FixedIntegerListEncoder.encode(Arrays.asList(0, 3), 2, 2)); + } + + @Test + public void testEncode7() { + Assertions.assertEquals("0100", FixedIntegerListEncoder.encode(Arrays.asList(1, 0), 2, 2)); + } + + @Test + public void testEncode8() { + Assertions.assertEquals("0101", FixedIntegerListEncoder.encode(Arrays.asList(1, 1), 2, 2)); + } + + @Test + public void testEncode9() { + Assertions.assertEquals("0110", FixedIntegerListEncoder.encode(Arrays.asList(1, 2), 2, 2)); + } + + @Test + public void testEncode10() { + Assertions.assertEquals("0111", FixedIntegerListEncoder.encode(Arrays.asList(1, 3), 2, 2)); + } + + @Test + public void testEncode11() { + Assertions.assertEquals("1000", FixedIntegerListEncoder.encode(Arrays.asList(2, 0), 2, 2)); + } + + @Test + public void testEncode12() { + Assertions.assertEquals("1001", FixedIntegerListEncoder.encode(Arrays.asList(2, 1), 2, 2)); + } + + @Test + public void testEncode13() { + Assertions.assertEquals("1010", FixedIntegerListEncoder.encode(Arrays.asList(2, 2), 2, 2)); + } + + @Test + public void testEncode14() { + Assertions.assertEquals("1011", FixedIntegerListEncoder.encode(Arrays.asList(2, 3), 2, 2)); + } + + @Test + public void testEncode15() { + Assertions.assertEquals("1100", FixedIntegerListEncoder.encode(Arrays.asList(3, 0), 2, 2)); + } + + @Test + public void testEncode16() { + Assertions.assertEquals("1101", FixedIntegerListEncoder.encode(Arrays.asList(3, 1), 2, 2)); + } + + @Test + public void testEncode17() { + Assertions.assertEquals("1110", FixedIntegerListEncoder.encode(Arrays.asList(3, 2), 2, 2)); + } + + @Test + public void testEncode18() { + Assertions.assertEquals("1111", FixedIntegerListEncoder.encode(Arrays.asList(3, 3), 2, 2)); + } + + @Test + public void testEncode19() { + try { + FixedIntegerListEncoder.encode(Arrays.asList(3, 3), 1, 1); + Assertions.fail("EncodingException expected"); + } catch (EncodingException e) { + + } + } + + @Test + public void testDecode1() { + Assertions.assertEquals(Arrays.asList(0, 0), FixedIntegerListEncoder.decode("", 2, 2)); + } + + @Test + public void testDecode2() { + Assertions.assertEquals(Arrays.asList(0, 0), FixedIntegerListEncoder.decode("0000", 2, 2)); + } + + @Test + public void testDecode3() { + Assertions.assertEquals(Arrays.asList(0, 1), FixedIntegerListEncoder.decode("0001", 2, 2)); + } + + @Test + public void testDecode4() { + Assertions.assertEquals(Arrays.asList(0, 2), FixedIntegerListEncoder.decode("0010", 2, 2)); + } + + @Test + public void testDecode5() { + Assertions.assertEquals(Arrays.asList(0, 3), FixedIntegerListEncoder.decode("0011", 2, 2)); + } + + @Test + public void testDecode6() { + Assertions.assertEquals(Arrays.asList(1, 0), FixedIntegerListEncoder.decode("0100", 2, 2)); + } + + @Test + public void testDecode7() { + Assertions.assertEquals(Arrays.asList(1, 1), FixedIntegerListEncoder.decode("0101", 2, 2)); + } + + @Test + public void testDecode8() { + Assertions.assertEquals(Arrays.asList(1, 2), FixedIntegerListEncoder.decode("0110", 2, 2)); + } + + @Test + public void testDecode9() { + Assertions.assertEquals(Arrays.asList(1, 3), FixedIntegerListEncoder.decode("0111", 2, 2)); + } + + @Test + public void testDecode10() { + Assertions.assertEquals(Arrays.asList(2, 0), FixedIntegerListEncoder.decode("1000", 2, 2)); + } + + @Test + public void testDecode11() { + Assertions.assertEquals(Arrays.asList(2, 1), FixedIntegerListEncoder.decode("1001", 2, 2)); + } + + @Test + public void testDecode12() { + Assertions.assertEquals(Arrays.asList(2, 2), FixedIntegerListEncoder.decode("1010", 2, 2)); + } + + @Test + public void testDecode13() { + Assertions.assertEquals(Arrays.asList(2, 3), FixedIntegerListEncoder.decode("1011", 2, 2)); + } + + @Test + public void testDecode14() { + Assertions.assertEquals(Arrays.asList(3, 0), FixedIntegerListEncoder.decode("1100", 2, 2)); + } + + @Test + public void testDecode15() { + Assertions.assertEquals(Arrays.asList(3, 1), FixedIntegerListEncoder.decode("1101", 2, 2)); + } + + @Test + public void testDecode16() { + Assertions.assertEquals(Arrays.asList(3, 2), FixedIntegerListEncoder.decode("1110", 2, 2)); + } + + @Test + public void testDecode17() { + Assertions.assertEquals(Arrays.asList(3, 3), FixedIntegerListEncoder.decode("1111", 2, 2)); + } + + @Test + public void testDecode18() { + try { + FixedIntegerListEncoder.decode("111111", 2, 2); + Assertions.fail("DecodingException expected"); + } catch (DecodingException e) { + + } + } + + @Test + public void testDecode19() { + try { + FixedIntegerListEncoder.decode("2", 2, 2); + Assertions.fail("DecodingException expected"); + } catch (DecodingException e) { + + } + } + + @Test + public void testDecode20() { + try { + FixedIntegerListEncoder.decode("111", 2, 2); + Assertions.fail("DecodingException expected"); + } catch (DecodingException e) { + + } + } +} diff --git a/iabgpp-encoder/src/test/java/com/iab/gpp/encoder/datatype/encoder/FixedIntegerRangeEncoderTest.java b/iabgpp-encoder/src/test/java/com/iab/gpp/encoder/datatype/encoder/FixedIntegerRangeEncoderTest.java index 5e3a2798..a2f11e2d 100644 --- a/iabgpp-encoder/src/test/java/com/iab/gpp/encoder/datatype/encoder/FixedIntegerRangeEncoderTest.java +++ b/iabgpp-encoder/src/test/java/com/iab/gpp/encoder/datatype/encoder/FixedIntegerRangeEncoderTest.java @@ -6,72 +6,109 @@ import org.junit.jupiter.api.Test; import com.iab.gpp.encoder.error.DecodingException; -class FixedIntegerRangeEncoderTest { +public class FixedIntegerRangeEncoderTest { @Test - void testEncode1() { + public void testEncode1() { Assertions.assertEquals("000000000000", FixedIntegerRangeEncoder.encode(new ArrayList<>())); } @Test - void testEncode2() { + public void testEncode2() { Assertions.assertEquals("00000000000100000000000000010", FixedIntegerRangeEncoder.encode(Arrays.asList(2))); } @Test - void testEncode3() { + public void testEncode3() { Assertions.assertEquals("000000000001100000000000000100000000000000110", FixedIntegerRangeEncoder.encode(Arrays.asList(2, 3, 4, 5, 6))); } @Test - void testEncode4() { + public void testEncode4() { Assertions.assertEquals("00000000001000000000000000010100000000000001010000000000000111", FixedIntegerRangeEncoder.encode(Arrays.asList(2, 5, 6, 7))); } @Test - void testEncode5() { + public void testEncode5() { Assertions.assertEquals("00000000001000000000000000010100000000000001010000000000000111", FixedIntegerRangeEncoder.encode(Arrays.asList(5, 2, 7, 6))); } @Test - void testEncode6() { + public void testEncode6() { Assertions.assertEquals("00000000001000000000000000011100000000000001010000000000001000", FixedIntegerRangeEncoder.encode(Arrays.asList(3, 5, 6, 7, 8))); } @Test - void testDecode1() throws DecodingException { + public void testEncode7() { + Assertions.assertEquals("000000000011000000000000011000000000000001100000000000000110000", + FixedIntegerRangeEncoder.encode(Arrays.asList(12, 24, 48))); + } + + @Test + public void testEncode8() { + Assertions.assertEquals("0000000000110000000000000110000000000000011000100000000001100000000000000110001", + FixedIntegerRangeEncoder.encode(Arrays.asList(12, 24, 48, 49))); + } + + @Test + public void testEncode9() { + Assertions.assertEquals( + "00000000100000000000000000010000000000000001100000000000000100000000000000001100000000000000100101000000000001011100000000000110010000000000010010100000000000101010", + FixedIntegerRangeEncoder.encode(Arrays.asList(2, 6, 8, 12, 18, 23, 24, 25, 37, 42))); + } + + @Test + public void testDecode1() throws DecodingException { Assertions.assertEquals(new ArrayList<>(), FixedIntegerRangeEncoder.decode("000000000000")); } @Test - void testDecode2() throws DecodingException { + public void testDecode2() throws DecodingException { Assertions.assertEquals(Arrays.asList(2), FixedIntegerRangeEncoder.decode("00000000000100000000000000010")); } @Test - void testDecode3() throws DecodingException { + public void testDecode3() throws DecodingException { Assertions.assertEquals(Arrays.asList(2, 3, 4, 5, 6), FixedIntegerRangeEncoder.decode("000000000001100000000000000100000000000000110")); } @Test - void testDecode4() throws DecodingException { + public void testDecode4() throws DecodingException { Assertions.assertEquals(Arrays.asList(2, 5, 6, 7), FixedIntegerRangeEncoder.decode("00000000001000000000000000010100000000000001010000000000000111")); } @Test - void testDecode5() throws DecodingException { + public void testDecode5() throws DecodingException { Assertions.assertEquals(Arrays.asList(3, 5, 6, 7, 8), FixedIntegerRangeEncoder.decode("00000000001000000000000000011100000000000001010000000000001000")); } @Test - void testDecode6() { + public void testDecode6() throws DecodingException { + Assertions.assertEquals(Arrays.asList(12, 24, 48), + FixedIntegerRangeEncoder.decode("000000000011000000000000011000000000000001100000000000000110000")); + } + + @Test + public void testDecode7() throws DecodingException { + Assertions.assertEquals(Arrays.asList(12, 24, 48, 49), FixedIntegerRangeEncoder + .decode("0000000000110000000000000110000000000000011000100000000001100000000000000110001")); + } + + @Test + public void testDecode8() throws DecodingException { + Assertions.assertEquals(Arrays.asList(2, 6, 8, 12, 18, 23, 24, 25, 37, 42), FixedIntegerRangeEncoder.decode( + "00000000100000000000000000010000000000000001100000000000000100000000000000001100000000000000100101000000000001011100000000000110010000000000010010100000000000101010")); + } + + @Test + public void testDecode9() { try { FixedIntegerRangeEncoder.decode("0011"); Assertions.fail("DecodingException expected"); @@ -81,7 +118,7 @@ void testDecode6() { } @Test - void testDecode7() { + public void testDecode10() { try { FixedIntegerRangeEncoder.decode("000000000002"); Assertions.fail("DecodingException expected"); diff --git a/iabgpp-encoder/src/test/java/com/iab/gpp/encoder/datatype/encoder/FixedLongEncoderTest.java b/iabgpp-encoder/src/test/java/com/iab/gpp/encoder/datatype/encoder/FixedLongEncoderTest.java index 2c9a65c7..9a90a6dd 100644 --- a/iabgpp-encoder/src/test/java/com/iab/gpp/encoder/datatype/encoder/FixedLongEncoderTest.java +++ b/iabgpp-encoder/src/test/java/com/iab/gpp/encoder/datatype/encoder/FixedLongEncoderTest.java @@ -3,76 +3,88 @@ import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.Test; import com.iab.gpp.encoder.error.DecodingException; +import com.iab.gpp.encoder.error.EncodingException; -class FixedLongEncoderTest { +public class FixedLongEncoderTest { @Test - void testEncode1() { + public void testEncode1() { Assertions.assertEquals("0", FixedLongEncoder.encode(0, 1)); } @Test - void testEncode2() { + public void testEncode2() { Assertions.assertEquals("000000", FixedLongEncoder.encode(0, 6)); } @Test - void testEncode3() { + public void testEncode3() { Assertions.assertEquals("1", FixedLongEncoder.encode(1, 1)); } @Test - void testEncode4() { + public void testEncode4() { Assertions.assertEquals("0001", FixedLongEncoder.encode(1, 4)); } @Test - void testEncode5() { + public void testEncode5() { Assertions.assertEquals("00000111", FixedLongEncoder.encode(7, 8)); } + @Test - void testEncode6() { + public void testEncode6() { Assertions.assertEquals("001111011111010001110101111011110101", FixedLongEncoder.encode(16630898421L, 36)); } + + @Test + public void testEncode7() { + try { + FixedIntegerEncoder.encode(8, 1); + Assertions.fail("EncodingException expected"); + } catch (EncodingException e) { + + } + } @Test - void testDecode1() throws DecodingException { + public void testDecode1() throws DecodingException { Assertions.assertEquals(0, FixedLongEncoder.decode("")); } @Test - void testDecode2() throws DecodingException { + public void testDecode2() throws DecodingException { Assertions.assertEquals(0, FixedLongEncoder.decode("0")); } @Test - void testDecode3() throws DecodingException { + public void testDecode3() throws DecodingException { Assertions.assertEquals(0, FixedLongEncoder.decode("000000")); } @Test - void testDecode4() throws DecodingException { + public void testDecode4() throws DecodingException { Assertions.assertEquals(1, FixedLongEncoder.decode("1")); } @Test - void testDecode5() throws DecodingException { + public void testDecode5() throws DecodingException { Assertions.assertEquals(1, FixedLongEncoder.decode("000001")); } @Test - void testDecode6() throws DecodingException { + public void testDecode6() throws DecodingException { Assertions.assertEquals(16630898421L, FixedLongEncoder.decode("001111011111010001110101111011110101")); } @Test - void testDecode7() throws DecodingException { + public void testDecode7() throws DecodingException { Assertions.assertEquals(8, FixedLongEncoder.decode("1000")); } @Test - void testDecode8() throws DecodingException { + public void testDecode8() throws DecodingException { Assertions.assertEquals(8, FixedLongEncoder.decode("0000001000")); } } diff --git a/iabgpp-encoder/src/test/java/com/iab/gpp/encoder/datatype/encoder/FixedStringEncoderTest.java b/iabgpp-encoder/src/test/java/com/iab/gpp/encoder/datatype/encoder/FixedStringEncoderTest.java index 6c5be081..4fef7dcc 100644 --- a/iabgpp-encoder/src/test/java/com/iab/gpp/encoder/datatype/encoder/FixedStringEncoderTest.java +++ b/iabgpp-encoder/src/test/java/com/iab/gpp/encoder/datatype/encoder/FixedStringEncoderTest.java @@ -5,20 +5,20 @@ import com.iab.gpp.encoder.error.DecodingException; import com.iab.gpp.encoder.error.EncodingException; -class FixedStringEncoderTest { +public class FixedStringEncoderTest { @Test - void testEncode1() throws EncodingException { + public void testEncode1() { Assertions.assertEquals("000000000001", FixedStringEncoder.encode("AB", 2)); } @Test - void testEncode2() throws EncodingException { + public void testEncode2() { Assertions.assertEquals("100000111111", FixedStringEncoder.encode("a", 2)); } @Test - void testEncode3() { + public void testEncode3() { try { FixedStringEncoder.encode("1", 2); Assertions.fail("DecodingException expected"); @@ -28,17 +28,17 @@ void testEncode3() { } @Test - void testDecode1() throws DecodingException { + public void testDecode1() { Assertions.assertEquals("AB", FixedStringEncoder.decode("000000000001")); } @Test - void testDecode2() throws DecodingException { + public void testDecode2() { Assertions.assertEquals("a", FixedStringEncoder.decode("100000111111")); } @Test - void testDecode3() { + public void testDecode3() { try { FixedStringEncoder.decode("2"); Assertions.fail("DecodingException expected"); diff --git a/iabgpp-encoder/src/test/java/com/iab/gpp/encoder/section/.UsNatV1Test.java.swp b/iabgpp-encoder/src/test/java/com/iab/gpp/encoder/section/.UsNatV1Test.java.swp new file mode 100644 index 00000000..686ae751 Binary files /dev/null and b/iabgpp-encoder/src/test/java/com/iab/gpp/encoder/section/.UsNatV1Test.java.swp differ diff --git a/iabgpp-encoder/src/test/java/com/iab/gpp/encoder/section/HeaderV1Test.java b/iabgpp-encoder/src/test/java/com/iab/gpp/encoder/section/HeaderV1Test.java index 056251f6..bdd4978b 100644 --- a/iabgpp-encoder/src/test/java/com/iab/gpp/encoder/section/HeaderV1Test.java +++ b/iabgpp-encoder/src/test/java/com/iab/gpp/encoder/section/HeaderV1Test.java @@ -5,101 +5,79 @@ import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.Test; import com.iab.gpp.encoder.error.DecodingException; -import com.iab.gpp.encoder.error.EncodingException; -class HeaderV1Test { +public class HeaderV1Test { @Test - public void testEncodeToBitString1() throws EncodingException { + public void testEncode1() { HeaderV1 headerV1 = new HeaderV1(); headerV1.setFieldValue("SectionIds", new ArrayList<>()); - Assertions.assertEquals("000011000001000000000000", headerV1.encodeToBitString()); + Assertions.assertEquals("DBAA", headerV1.encode()); } @Test - public void testEncodeToBitString2() throws EncodingException { + public void testEncode2() { HeaderV1 headerV1 = new HeaderV1(); headerV1.setFieldValue("SectionIds", Arrays.asList(2)); - Assertions.assertEquals("0000110000010000000000010011", headerV1.encodeToBitString()); + Assertions.assertEquals("DBABM", headerV1.encode()); } @Test - public void testEncodeToBitString3() throws EncodingException { + public void testEncode3() { HeaderV1 headerV1 = new HeaderV1(); headerV1.setFieldValue("SectionIds", Arrays.asList(2, 6)); - Assertions.assertEquals("000011000001000000000010001101011", headerV1.encodeToBitString()); + Assertions.assertEquals("DBACNY", headerV1.encode()); } @Test - public void testDecodeFromBitString1() throws DecodingException { + public void testDecode1() { HeaderV1 headerV1 = new HeaderV1(); - headerV1.decodeFromBitString("000011000001000000000000"); + headerV1.decode("DBAA"); Assertions.assertEquals(new ArrayList<>(), headerV1.getFieldValue("SectionIds")); + Assertions.assertEquals(headerV1.getFieldValue("Version"), headerV1.getVersion()); Assertions.assertEquals(headerV1.getFieldValue("SectionIds"), headerV1.getSectionsIds()); } @Test - public void testDecodeFromBitString2() throws DecodingException { + public void testDecode2() { HeaderV1 headerV1 = new HeaderV1(); - headerV1.decodeFromBitString("0000110000010000000000010011"); + headerV1.decode("DBABM"); Assertions.assertEquals(Arrays.asList(2), headerV1.getFieldValue("SectionIds")); + Assertions.assertEquals(headerV1.getFieldValue("Version"), headerV1.getVersion()); Assertions.assertEquals(headerV1.getFieldValue("SectionIds"), headerV1.getSectionsIds()); } @Test - public void testDecodeFromBitString3() throws DecodingException { - HeaderV1 headerV1 = new HeaderV1(); - headerV1.decodeFromBitString("000001000011000000000010001101011"); - Assertions.assertEquals(Arrays.asList(2, 6), headerV1.getFieldValue("SectionIds")); - Assertions.assertEquals(headerV1.getFieldValue("SectionIds"), headerV1.getSectionsIds()); - } - - @Test - public void testEncode1() throws EncodingException { - HeaderV1 headerV1 = new HeaderV1(); - headerV1.setFieldValue("SectionIds", new ArrayList<>()); - Assertions.assertEquals("DBAA", headerV1.encode()); - } - - @Test - public void testEncode2() throws EncodingException { - HeaderV1 headerV1 = new HeaderV1(); - headerV1.setFieldValue("SectionIds", Arrays.asList(2)); - Assertions.assertEquals("DBABMA", headerV1.encode()); - } - - @Test - public void testEncode3() throws EncodingException { + public void testDecode3() { HeaderV1 headerV1 = new HeaderV1(); - headerV1.setFieldValue("SectionIds", Arrays.asList(2, 7)); - Assertions.assertEquals("DBACMMA", headerV1.encode()); - } - - @Test - public void testDecode1() throws DecodingException { - HeaderV1 headerV1 = new HeaderV1(); - headerV1.decode("DBAA"); - Assertions.assertEquals(new ArrayList<>(), headerV1.getFieldValue("SectionIds")); + headerV1.decode("DBABMA"); + Assertions.assertEquals(Arrays.asList(2), headerV1.getFieldValue("SectionIds")); Assertions.assertEquals(headerV1.getFieldValue("Version"), headerV1.getVersion()); Assertions.assertEquals(headerV1.getFieldValue("SectionIds"), headerV1.getSectionsIds()); } @Test - public void testDecode2() throws DecodingException { + public void testDecode4() { HeaderV1 headerV1 = new HeaderV1(); - headerV1.decode("DBABMA"); - Assertions.assertEquals(Arrays.asList(2), headerV1.getFieldValue("SectionIds")); + headerV1.decode("DBACNY"); + Assertions.assertEquals(Arrays.asList(2, 6), headerV1.getFieldValue("SectionIds")); Assertions.assertEquals(headerV1.getFieldValue("Version"), headerV1.getVersion()); Assertions.assertEquals(headerV1.getFieldValue("SectionIds"), headerV1.getSectionsIds()); } @Test - public void testDecode3() throws DecodingException { + public void testDecode5() { HeaderV1 headerV1 = new HeaderV1(); - headerV1.decode("BDACNYA"); + headerV1.decode("DBACNYA"); Assertions.assertEquals(Arrays.asList(2, 6), headerV1.getFieldValue("SectionIds")); Assertions.assertEquals(headerV1.getFieldValue("Version"), headerV1.getVersion()); Assertions.assertEquals(headerV1.getFieldValue("SectionIds"), headerV1.getSectionsIds()); } - + + @Test() + public void testDecodeGarbage() { + Assertions.assertThrows(DecodingException.class, () -> { + new HeaderV1("z").getSectionsIds(); + }); + } } diff --git a/iabgpp-encoder/src/test/java/com/iab/gpp/encoder/section/TcfCaV1Test.java b/iabgpp-encoder/src/test/java/com/iab/gpp/encoder/section/TcfCaV1Test.java new file mode 100644 index 00000000..32ee2686 --- /dev/null +++ b/iabgpp-encoder/src/test/java/com/iab/gpp/encoder/section/TcfCaV1Test.java @@ -0,0 +1,201 @@ +package com.iab.gpp.encoder.section; + + +import java.time.ZoneId; +import java.time.ZonedDateTime; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; +import com.iab.gpp.encoder.datatype.RangeEntry; +import com.iab.gpp.encoder.error.DecodingException; +import com.iab.gpp.encoder.error.EncodingException; +import com.iab.gpp.encoder.error.InvalidFieldException; +import com.iab.gpp.encoder.field.TcfCaV1Field; + +public class TcfCaV1Test { + + @Test + public void testEncode1() { + + TcfCaV1 tcfCaV1 = new TcfCaV1(); + tcfCaV1.setFieldValue(TcfCaV1Field.CREATED, ZonedDateTime.of(2022, 1, 1, 0, 0, 0, 0, ZoneId.of("UTC"))); + tcfCaV1.setFieldValue(TcfCaV1Field.LAST_UPDATED, ZonedDateTime.of(2022, 1, 1, 0, 0, 0, 0, ZoneId.of("UTC"))); + Assertions.assertEquals("BPSG_8APSG_8AAAAAAENAACAAAAAAAAAAAAAAAAAA.YAAAAAAAAA", tcfCaV1.encode()); + } + + @Test + public void testEncode2() { + + TcfCaV1 tcfCaV1 = new TcfCaV1(); + tcfCaV1.setFieldValue(TcfCaV1Field.CMP_ID, 50); + tcfCaV1.setFieldValue(TcfCaV1Field.CMP_VERSION, 2); + tcfCaV1.setFieldValue(TcfCaV1Field.VENDOR_LIST_VERSION, 413); + tcfCaV1.setFieldValue(TcfCaV1Field.USE_NON_STANDARD_STACKS, true); + tcfCaV1.setFieldValue(TcfCaV1Field.SPECIAL_FEATURE_EXPRESS_CONSENT, + Arrays.asList(false, false, false, false, false, false, true, true, true, true, true, true)); + tcfCaV1.setFieldValue(TcfCaV1Field.PURPOSES_EXPRESS_CONSENT, + Arrays.asList(true, true, true, true, true, true, false, false, false, false, false, false, true, true, true, + true, true, true, false, false, false, false, false, false)); + tcfCaV1.setFieldValue(TcfCaV1Field.PURPOSES_IMPLIED_CONSENT, + Arrays.asList(false, false, false, false, false, false, true, true, true, true, true, true, false, false, false, + false, false, false, true, true, true, true, true, true)); + tcfCaV1.setFieldValue(TcfCaV1Field.VENDOR_EXPRESS_CONSENT, Arrays.asList(12, 24, 48)); + tcfCaV1.setFieldValue(TcfCaV1Field.VENDOR_IMPLIED_CONSENT, Arrays.asList(18, 30)); + tcfCaV1.setFieldValue(TcfCaV1Field.PUB_PURPOSES_EXPRESS_CONSENT, + Arrays.asList(true, true, true, false, false, false, true, true, true, false, false, false, true, true, true, + false, false, false, true, true, true, false, false, false)); + tcfCaV1.setFieldValue(TcfCaV1Field.PUB_PURPOSES_IMPLIED_CONSENT, + Arrays.asList(false, false, false, true, true, true, false, false, false, true, true, true, false, false, false, + true, true, true, false, false, false, true, true, true)); + tcfCaV1.setFieldValue(TcfCaV1Field.NUM_CUSTOM_PURPOSES, 3); + tcfCaV1.setFieldValue(TcfCaV1Field.CUSTOM_PURPOSES_EXPRESS_CONSENT, Arrays.asList(false, true, false)); + tcfCaV1.setFieldValue(TcfCaV1Field.CUSTOM_PURPOSES_IMPLIED_CONSENT, Arrays.asList(true, false, true)); + + tcfCaV1.setFieldValue(TcfCaV1Field.CREATED, ZonedDateTime.of(2022, 1, 1, 0, 0, 0, 0, ZoneId.of("UTC"))); + tcfCaV1.setFieldValue(TcfCaV1Field.LAST_UPDATED, ZonedDateTime.of(2022, 1, 1, 0, 0, 0, 0, ZoneId.of("UTC"))); + + Assertions.assertEquals("BPSG_8APSG_8AAyACAENGdCgf_gfgAfgfgBgABABAAABAB4AACACAA.fHHHA4444ao", tcfCaV1.encode()); + } + + @Test + public void testEncode3() throws EncodingException, InvalidFieldException { + + TcfCaV1 tcfCaV1 = new TcfCaV1(); + tcfCaV1.setFieldValue(TcfCaV1Field.DISCLOSED_VENDORS, Arrays.asList(1, 2, 3, 5, 6, 7, 10, 11, 12)); + + tcfCaV1.setFieldValue(TcfCaV1Field.CREATED, ZonedDateTime.of(2022, 1, 1, 0, 0, 0, 0, ZoneId.of("UTC"))); + tcfCaV1.setFieldValue(TcfCaV1Field.LAST_UPDATED, ZonedDateTime.of(2022, 1, 1, 0, 0, 0, 0, ZoneId.of("UTC"))); + + Assertions.assertEquals("BPSG_8APSG_8AAAAAAENAACAAAAAAAAAAAAAAAAAA.YAAAAAAAAA.IAGO5w", tcfCaV1.encode()); + } + + @Test + public void testEncode4() throws EncodingException, InvalidFieldException { + + List pubRestrictions = new ArrayList<>(); + pubRestrictions.add(new RangeEntry(1, 1, Arrays.asList(1, 2, 3, 5, 6, 7, 9))); + + TcfCaV1 tcfCaV1 = new TcfCaV1(); + tcfCaV1.setFieldValue(TcfCaV1Field.PUB_RESTRICTIONS, pubRestrictions); + + tcfCaV1.setFieldValue(TcfCaV1Field.CREATED, ZonedDateTime.of(2022, 1, 1, 0, 0, 0, 0, ZoneId.of("UTC"))); + tcfCaV1.setFieldValue(TcfCaV1Field.LAST_UPDATED, ZonedDateTime.of(2022, 1, 1, 0, 0, 0, 0, ZoneId.of("UTC"))); + Assertions.assertEquals("BPSG_8APSG_8AAAAAAENAACAAAAAAAAAAAAAAAAACCgBwABAAOAAoADgAJ.YAAAAAAAAA", tcfCaV1.encode()); + } + + @Test + public void testDecode1() { + TcfCaV1 tcfCaV1 = new TcfCaV1("BPSG_8APSG_8AAAAAAENAACAAAAAAAAAAAAAAAAAA.YAAAAAAAAA"); + + Assertions.assertEquals(0, tcfCaV1.getCmpId()); + Assertions.assertEquals(0, tcfCaV1.getCmpVersion()); + Assertions.assertEquals(0, tcfCaV1.getVendorListVersion()); + Assertions.assertEquals(false, tcfCaV1.getUseNonStandardStacks()); + Assertions.assertEquals( + Arrays.asList(false, false, false, false, false, false, false, false, false, false, false, false), + tcfCaV1.getSpecialFeatureExpressConsent()); + Assertions + .assertEquals( + Arrays.asList(false, false, false, false, false, false, false, false, false, false, false, false, false, + false, false, false, false, false, false, false, false, false, false, false), + tcfCaV1.getPurposesExpressConsent()); + Assertions + .assertEquals( + Arrays.asList(false, false, false, false, false, false, false, false, false, false, false, false, false, + false, false, false, false, false, false, false, false, false, false, false), + tcfCaV1.getPurposesImpliedConsent()); + Assertions.assertEquals(Arrays.asList(), tcfCaV1.getVendorExpressConsent()); + Assertions.assertEquals(Arrays.asList(), tcfCaV1.getVendorImpliedConsent()); + Assertions.assertEquals( + Arrays.asList(false, false, false, false, false, false, false, false, false, false, false, false, false, false, + false, false, false, false, false, false, false, false, false, false), + tcfCaV1.getPubPurposesExpressConsent()); + Assertions.assertEquals( + Arrays.asList(false, false, false, false, false, false, false, false, false, false, false, false, false, false, + false, false, false, false, false, false, false, false, false, false), + tcfCaV1.getPubPurposesImpliedConsent()); + Assertions.assertEquals(0, tcfCaV1.getNumCustomPurposes()); + Assertions.assertEquals(Arrays.asList(), tcfCaV1.getCustomPurposesExpressConsent()); + Assertions.assertEquals(Arrays.asList(), tcfCaV1.getCustomPurposesImpliedConsent()); + Assertions.assertEquals(ZonedDateTime.of(2022, 1, 1, 0, 0, 0, 0, ZoneId.of("UTC")), tcfCaV1.getCreated()); + Assertions.assertEquals(ZonedDateTime.of(2022, 1, 1, 0, 0, 0, 0, ZoneId.of("UTC")), tcfCaV1.getLastUpdated()); + + Assertions.assertEquals("EN", tcfCaV1.getConsentLanguage()); + Assertions.assertEquals(5, tcfCaV1.getId()); + Assertions.assertEquals(3, tcfCaV1.getPubPurposesSegmentType()); + } + + @Test + public void testDecode2() { + TcfCaV1 tcfCaV1 = new TcfCaV1("BPSG_8APSG_8AAyACAENGdCgf_gfgAfgfgBgABABAAABAB4AACACAA.fHHHA4444ao"); + + Assertions.assertEquals(50, tcfCaV1.getCmpId()); + Assertions.assertEquals(2, tcfCaV1.getCmpVersion()); + Assertions.assertEquals(413, tcfCaV1.getVendorListVersion()); + Assertions.assertEquals(true, tcfCaV1.getUseNonStandardStacks()); + Assertions.assertEquals(Arrays.asList(false, false, false, false, false, false, true, true, true, true, true, true), + tcfCaV1.getSpecialFeatureExpressConsent()); + Assertions.assertEquals(Arrays.asList(true, true, true, true, true, true, false, false, false, false, false, false, + true, true, true, true, true, true, false, false, false, false, false, false), + tcfCaV1.getPurposesExpressConsent()); + Assertions.assertEquals(Arrays.asList(false, false, false, false, false, false, true, true, true, true, true, true, + false, false, false, false, false, false, true, true, true, true, true, true), + tcfCaV1.getPurposesImpliedConsent()); + Assertions.assertEquals(Arrays.asList(12, 24, 48), tcfCaV1.getVendorExpressConsent()); + Assertions.assertEquals(Arrays.asList(18, 30), tcfCaV1.getVendorImpliedConsent()); + Assertions + .assertEquals( + Arrays.asList(true, true, true, false, false, false, true, true, true, false, false, false, true, true, + true, false, false, false, true, true, true, false, false, false), + tcfCaV1.getPubPurposesExpressConsent()); + Assertions + .assertEquals( + Arrays.asList(false, false, false, true, true, true, false, false, false, true, true, true, false, false, + false, true, true, true, false, false, false, true, true, true), + tcfCaV1.getPubPurposesImpliedConsent()); + Assertions.assertEquals(3, tcfCaV1.getNumCustomPurposes()); + Assertions.assertEquals(Arrays.asList(false, true, false), tcfCaV1.getCustomPurposesExpressConsent()); + Assertions.assertEquals(Arrays.asList(true, false, true), tcfCaV1.getCustomPurposesImpliedConsent()); + Assertions.assertEquals(ZonedDateTime.of(2022, 1, 1, 0, 0, 0, 0, ZoneId.of("UTC")), tcfCaV1.getCreated()); + Assertions.assertEquals(ZonedDateTime.of(2022, 1, 1, 0, 0, 0, 0, ZoneId.of("UTC")), tcfCaV1.getLastUpdated()); + + Assertions.assertEquals("EN", tcfCaV1.getConsentLanguage()); + Assertions.assertEquals(5, tcfCaV1.getId()); + Assertions.assertEquals(3, tcfCaV1.getPubPurposesSegmentType()); + } + + @Test + public void testDecode3() throws DecodingException { + TcfCaV1 tcfCaV1 = new TcfCaV1("BPSG_8APSG_8AAAAAAENAACAAAAAAAAAAAAAAAAAA.YAAAAAAAAA.IAGO5w"); + + Assertions.assertEquals(1, tcfCaV1.getDisclosedVendorsSegmentType()); + Assertions.assertEquals(Arrays.asList(1, 2, 3, 5, 6, 7, 10, 11, 12), tcfCaV1.getDisclosedVendors()); + } + + @Test + public void testDecode4() throws DecodingException { + TcfCaV1 tcfCaV1 = new TcfCaV1("BPSG_8APSG_8AAAAAAENAACAAAAAAAAAAAAAAAAACCgBwABAAOAAoADgAJ.YAAAAAAAAA"); + + List pubRestictions = tcfCaV1.getPubRestrictions(); + Assertions.assertEquals(1, pubRestictions.size()); + Assertions.assertEquals(1, pubRestictions.get(0).getKey()); + Assertions.assertEquals(1, pubRestictions.get(0).getType()); + Assertions.assertEquals(Arrays.asList(1, 2, 3, 5, 6, 7, 9), pubRestictions.get(0).getIds()); + } + + @Test() + public void testDecodeGarbage1() { + Assertions.assertThrows(DecodingException.class, () -> { + new TcfCaV1("A").getPubRestrictions(); + }); + } + + @Test() + public void testDecodeGarbage2() { + Assertions.assertThrows(DecodingException.class, () -> { + new TcfCaV1("z").getPubRestrictions(); + }); + } +} diff --git a/iabgpp-encoder/src/test/java/com/iab/gpp/encoder/section/TcfCaV2Test.java b/iabgpp-encoder/src/test/java/com/iab/gpp/encoder/section/TcfCaV2Test.java deleted file mode 100644 index a80c640a..00000000 --- a/iabgpp-encoder/src/test/java/com/iab/gpp/encoder/section/TcfCaV2Test.java +++ /dev/null @@ -1,136 +0,0 @@ -package com.iab.gpp.encoder.section; - - -import java.time.ZoneId; -import java.time.ZonedDateTime; -import java.util.Arrays; -import org.junit.jupiter.api.Assertions; -import org.junit.jupiter.api.Test; -import com.iab.gpp.encoder.error.DecodingException; -import com.iab.gpp.encoder.error.EncodingException; -import com.iab.gpp.encoder.field.TcfCaV2Field; - -public class TcfCaV2Test { - - @Test - public void testEncode1() throws EncodingException { - - TcfCaV2 tcfCaV2 = new TcfCaV2(); - Assertions.assertEquals("CAAAAAAAAAAAAAAAAAENAACAAAAAAAAAAAAAAA.YAAAAAAAAAA", tcfCaV2.encode()); - } - - @Test - public void testEncode2() throws EncodingException { - - TcfCaV2 tcfCaV2 = new TcfCaV2(); - tcfCaV2.setFieldValue(TcfCaV2Field.CMP_ID, 50); - tcfCaV2.setFieldValue(TcfCaV2Field.CMP_VERSION, 2); - tcfCaV2.setFieldValue(TcfCaV2Field.VENDOR_LIST_VERSION, 413); - tcfCaV2.setFieldValue(TcfCaV2Field.USE_NON_STANDARD_STACKS, true); - tcfCaV2.setFieldValue(TcfCaV2Field.SPECIAL_FEATURE_EXPRESS_CONSENT, - Arrays.asList(false, false, false, false, false, false, true, true, true, true, true, true)); - tcfCaV2.setFieldValue(TcfCaV2Field.PURPOSES_EXPRESS_CONSENT, - Arrays.asList(true, true, true, true, true, true, false, false, false, false, false, false, true, true, true, - true, true, true, false, false, false, false, false, false)); - tcfCaV2.setFieldValue(TcfCaV2Field.PURPOSES_IMPLIED_CONSENT, - Arrays.asList(false, false, false, false, false, false, true, true, true, true, true, true, false, false, false, - false, false, false, true, true, true, true, true, true)); - tcfCaV2.setFieldValue(TcfCaV2Field.VENDOR_EXPRESS_CONSENT, Arrays.asList(12, 24, 48)); - tcfCaV2.setFieldValue(TcfCaV2Field.VENDOR_IMPLIED_CONSENT, Arrays.asList(18, 30)); - tcfCaV2.setFieldValue(TcfCaV2Field.PUB_PURPOSES_EXPRESS_CONSENT, - Arrays.asList(true, true, true, false, false, false, true, true, true, false, false, false, true, true, true, - false, false, false, true, true, true, false, false, false)); - tcfCaV2.setFieldValue(TcfCaV2Field.PUB_PURPOSES_IMPLIED_CONSENT, - Arrays.asList(false, false, false, true, true, true, false, false, false, true, true, true, false, false, false, - true, true, true, false, false, false, true, true, true)); - tcfCaV2.setFieldValue(TcfCaV2Field.NUM_CUSTOM_PURPOSES, 3); - tcfCaV2.setFieldValue(TcfCaV2Field.CUSTOM_PURPOSES_EXPRESS_CONSENT, Arrays.asList(false, true, false)); - tcfCaV2.setFieldValue(TcfCaV2Field.CUSTOM_PURPOSES_IMPLIED_CONSENT, Arrays.asList(true, false, true)); - - tcfCaV2.setFieldValue(TcfCaV2Field.CREATED, ZonedDateTime.of(2022, 1, 1, 0, 0, 0, 0, ZoneId.of("UTC"))); - tcfCaV2.setFieldValue(TcfCaV2Field.LAST_UPDATED, ZonedDateTime.of(2022, 1, 1, 0, 0, 0, 0, ZoneId.of("UTC"))); - - Assertions.assertEquals("CPSG_8APSG_8AAyACAENGdCgf_gfgAfgfgBgAMAAwADAAIACQAHg.fHHHA4444ao", tcfCaV2.encode()); - } - - @Test - public void testDecode1() throws DecodingException { - TcfCaV2 tcfCaV2 = new TcfCaV2("CAAAAAAAAAAAAAAAAAENAACAAAAAAAAAAAAAAA.YAAAAAAAAAA"); - - Assertions.assertEquals(0, tcfCaV2.getCmpId()); - Assertions.assertEquals(0, tcfCaV2.getCmpVersion()); - Assertions.assertEquals(0, tcfCaV2.getVendorListVersion()); - Assertions.assertEquals(false, tcfCaV2.getUseNonStandardStacks()); - Assertions.assertEquals( - Arrays.asList(false, false, false, false, false, false, false, false, false, false, false, false), - tcfCaV2.getSpecialFeatureExpressConsent()); - Assertions - .assertEquals( - Arrays.asList(false, false, false, false, false, false, false, false, false, false, false, false, false, - false, false, false, false, false, false, false, false, false, false, false), - tcfCaV2.getPurposesExpressConsent()); - Assertions - .assertEquals( - Arrays.asList(false, false, false, false, false, false, false, false, false, false, false, false, false, - false, false, false, false, false, false, false, false, false, false, false), - tcfCaV2.getPurposesImpliedConsent()); - Assertions.assertEquals(Arrays.asList(), tcfCaV2.getVendorExpressConsent()); - Assertions.assertEquals(Arrays.asList(), tcfCaV2.getVendorImpliedConsent()); - Assertions.assertEquals( - Arrays.asList(false, false, false, false, false, false, false, false, false, false, false, false, false, false, - false, false, false, false, false, false, false, false, false, false), - tcfCaV2.getPubPurposesExpressConsent()); - Assertions.assertEquals( - Arrays.asList(false, false, false, false, false, false, false, false, false, false, false, false, false, false, - false, false, false, false, false, false, false, false, false, false), - tcfCaV2.getPubPurposesImpliedConsent()); - Assertions.assertEquals(0, tcfCaV2.getNumCustomPurposes()); - Assertions.assertEquals(Arrays.asList(), tcfCaV2.getCustomPurposesExpressConsent()); - Assertions.assertEquals(Arrays.asList(), tcfCaV2.getCustomPurposesImpliedConsent()); - Assertions.assertEquals(ZonedDateTime.of(1970, 1, 1, 0, 0, 0, 0, ZoneId.of("UTC")), tcfCaV2.getCreated()); - Assertions.assertEquals(ZonedDateTime.of(1970, 1, 1, 0, 0, 0, 0, ZoneId.of("UTC")), tcfCaV2.getLastUpdated()); - - Assertions.assertEquals("EN", tcfCaV2.getConsentLanguage()); - Assertions.assertEquals(5, tcfCaV2.getId()); - Assertions.assertEquals(3, tcfCaV2.getSegmentType()); - } - - @Test - public void testDecode2() throws DecodingException { - TcfCaV2 tcfCaV2 = new TcfCaV2("CPSG_8APSG_8AAyACAENGdCgf_gfgAfgfgBgAMAAwADAAIACQAHg.fHHHA4444ao.fHHHA4444ao"); - - Assertions.assertEquals(50, tcfCaV2.getCmpId()); - Assertions.assertEquals(2, tcfCaV2.getCmpVersion()); - Assertions.assertEquals(413, tcfCaV2.getVendorListVersion()); - Assertions.assertEquals(true, tcfCaV2.getUseNonStandardStacks()); - Assertions.assertEquals(Arrays.asList(false, false, false, false, false, false, true, true, true, true, true, true), - tcfCaV2.getSpecialFeatureExpressConsent()); - Assertions.assertEquals(Arrays.asList(true, true, true, true, true, true, false, false, false, false, false, false, - true, true, true, true, true, true, false, false, false, false, false, false), - tcfCaV2.getPurposesExpressConsent()); - Assertions.assertEquals(Arrays.asList(false, false, false, false, false, false, true, true, true, true, true, true, - false, false, false, false, false, false, true, true, true, true, true, true), - tcfCaV2.getPurposesImpliedConsent()); - Assertions.assertEquals(Arrays.asList(12, 24, 48), tcfCaV2.getVendorExpressConsent()); - Assertions.assertEquals(Arrays.asList(18, 30), tcfCaV2.getVendorImpliedConsent()); - Assertions - .assertEquals( - Arrays.asList(true, true, true, false, false, false, true, true, true, false, false, false, true, true, - true, false, false, false, true, true, true, false, false, false), - tcfCaV2.getPubPurposesExpressConsent()); - Assertions - .assertEquals( - Arrays.asList(false, false, false, true, true, true, false, false, false, true, true, true, false, false, - false, true, true, true, false, false, false, true, true, true), - tcfCaV2.getPubPurposesImpliedConsent()); - Assertions.assertEquals(3, tcfCaV2.getNumCustomPurposes()); - Assertions.assertEquals(Arrays.asList(false, true, false), tcfCaV2.getCustomPurposesExpressConsent()); - Assertions.assertEquals(Arrays.asList(true, false, true), tcfCaV2.getCustomPurposesImpliedConsent()); - Assertions.assertEquals(ZonedDateTime.of(2022, 1, 1, 0, 0, 0, 0, ZoneId.of("UTC")), tcfCaV2.getCreated()); - Assertions.assertEquals(ZonedDateTime.of(2022, 1, 1, 0, 0, 0, 0, ZoneId.of("UTC")), tcfCaV2.getLastUpdated()); - - Assertions.assertEquals("EN", tcfCaV2.getConsentLanguage()); - Assertions.assertEquals(5, tcfCaV2.getId()); - Assertions.assertEquals(3, tcfCaV2.getSegmentType()); - } -} diff --git a/iabgpp-encoder/src/test/java/com/iab/gpp/encoder/section/TcfEuV2Test.java b/iabgpp-encoder/src/test/java/com/iab/gpp/encoder/section/TcfEuV2Test.java index ed480997..945f7468 100644 --- a/iabgpp-encoder/src/test/java/com/iab/gpp/encoder/section/TcfEuV2Test.java +++ b/iabgpp-encoder/src/test/java/com/iab/gpp/encoder/section/TcfEuV2Test.java @@ -6,30 +6,46 @@ import java.util.List; import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.Test; +import com.iab.gpp.encoder.datatype.RangeEntry; import com.iab.gpp.encoder.error.DecodingException; -import com.iab.gpp.encoder.error.EncodingException; import com.iab.gpp.encoder.field.TcfEuV2Field; public class TcfEuV2Test { @Test - public void testEncode1() throws EncodingException { + public void testEncode1() { TcfEuV2 tcfEuV2 = new TcfEuV2(); - Assertions.assertEquals("CAAAAAAAAAAAAAAAAAENAACAAAAAAAAAAAAAAAAAAAA.QAAA.IAAA", tcfEuV2.encode()); + tcfEuV2.setFieldValue(TcfEuV2Field.CREATED, ZonedDateTime.of(2022, 1, 1, 0, 0, 0, 0, ZoneId.of("UTC"))); + tcfEuV2.setFieldValue(TcfEuV2Field.LAST_UPDATED, ZonedDateTime.of(2022, 1, 1, 0, 0, 0, 0, ZoneId.of("UTC"))); + Assertions.assertEquals("CPSG_8APSG_8AAAAAAENAACAAAAAAAAAAAAAAAAAAAAA.QAAA.IAAA", tcfEuV2.encode()); } @Test - public void testEncode2() throws EncodingException { + public void testEncode2() { TcfEuV2 tcfEuV2 = new TcfEuV2(); tcfEuV2.setFieldValue(TcfEuV2Field.IS_SERVICE_SPECIFIC, true); tcfEuV2.setFieldValue(TcfEuV2Field.CREATED, ZonedDateTime.of(2022, 1, 1, 0, 0, 0, 0, ZoneId.of("UTC"))); tcfEuV2.setFieldValue(TcfEuV2Field.LAST_UPDATED, ZonedDateTime.of(2022, 1, 1, 0, 0, 0, 0, ZoneId.of("UTC"))); - Assertions.assertEquals("CPSG_8APSG_8AAAAAAENAACgAAAAAAAAAAAAAAAAAAA.YAAAAAAAAAA", tcfEuV2.encode()); + + Assertions.assertEquals(3, tcfEuV2.getFieldValue(TcfEuV2Field.PUBLISHER_PURPOSES_SEGMENT_TYPE)); + Assertions.assertEquals( + Arrays.asList(false, false, false, false, false, false, false, false, false, false, false, false, false, false, + false, false, false, false, false, false, false, false, false, false), + tcfEuV2.getFieldValue(TcfEuV2Field.PUBLISHER_CONSENTS)); + Assertions.assertEquals( + Arrays.asList(false, false, false, false, false, false, false, false, false, false, false, false, false, false, + false, false, false, false, false, false, false, false, false, false), + tcfEuV2.getFieldValue(TcfEuV2Field.PUBLISHER_LEGITIMATE_INTERESTS)); + Assertions.assertEquals(0, tcfEuV2.getFieldValue(TcfEuV2Field.NUM_CUSTOM_PURPOSES)); + Assertions.assertEquals(Arrays.asList(), tcfEuV2.getFieldValue(TcfEuV2Field.PUBLISHER_CUSTOM_CONSENTS)); + Assertions.assertEquals(Arrays.asList(), tcfEuV2.getFieldValue(TcfEuV2Field.PUBLISHER_CUSTOM_LEGITIMATE_INTERESTS)); + + Assertions.assertEquals("CPSG_8APSG_8AAAAAAENAACgAAAAAAAAAAAAAAAAAAAA.YAAAAAAAAAAA", tcfEuV2.encode()); } @Test - public void testDecode1() throws DecodingException { - TcfEuV2 tcfEuV2 = new TcfEuV2("CAAAAAAAAAAAAAAAAAENAACAAAAAAAAAAAAAAAAAAAA.QAAA.IAAA"); + public void testDecode1() { + TcfEuV2 tcfEuV2 = new TcfEuV2("CAAAAAAAAAAAAAAAAAENAACAAAAAAAAAAAAAAAAAAAAA.QAAA.IAAA"); Assertions.assertEquals(2, tcfEuV2.getVersion()); Assertions.assertEquals(ZonedDateTime.of(1970, 1, 1, 0, 0, 0, 0, ZoneId.of("UTC")), tcfEuV2.getCreated()); @@ -60,8 +76,15 @@ public void testDecode1() throws DecodingException { Assertions.assertEquals(Arrays.asList(), tcfEuV2.getVendorLegitimateInterests()); Assertions.assertEquals(Arrays.asList(), tcfEuV2.getPublisherRestrictions()); Assertions.assertEquals(3, tcfEuV2.getPublisherPurposesSegmentType()); - Assertions.assertEquals(Arrays.asList(), tcfEuV2.getPublisherConsents()); - Assertions.assertEquals(Arrays.asList(), tcfEuV2.getPublisherLegitimateInterests()); + Assertions + .assertEquals( + Arrays.asList(false, false, false, false, false, false, false, false, false, false, false, false, false, + false, false, false, false, false, false, false, false, false, false, false), + tcfEuV2.getPublisherConsents()); + Assertions.assertEquals( + Arrays.asList(false, false, false, false, false, false, false, false, false, false, false, false, false, false, + false, false, false, false, false, false, false, false, false, false), + tcfEuV2.getPublisherLegitimateInterests()); Assertions.assertEquals(0, tcfEuV2.getNumCustomPurposes()); Assertions.assertEquals(Arrays.asList(), tcfEuV2.getPublisherCustomConsents()); Assertions.assertEquals(Arrays.asList(), tcfEuV2.getPublisherCustomLegitimateInterests()); @@ -74,8 +97,8 @@ public void testDecode1() throws DecodingException { } @Test - public void testDecode2() throws DecodingException { - TcfEuV2 tcfEuV2 = new TcfEuV2("CPSG_8APSG_8AAAAAAENAACgAAAAAAAAAAAAAAAAAAA.YAAAAAAAAAA"); + public void testDecode2() { + TcfEuV2 tcfEuV2 = new TcfEuV2("CPSG_8APSG_8AAAAAAENAACgAAAAAAAAAAAAAAAAAAAA.YAAAAAAAAAAA"); Assertions.assertEquals(2, tcfEuV2.getVersion()); Assertions.assertEquals(ZonedDateTime.of(2022, 1, 1, 0, 0, 0, 0, ZoneId.of("UTC")), tcfEuV2.getCreated()); @@ -128,7 +151,7 @@ public void testDecode2() throws DecodingException { @SuppressWarnings("unchecked") @Test - public void testDecode3() throws DecodingException { + public void testDecode3() { TcfEuV2 tcfEuV2 = new TcfEuV2( "CPcqBNJPcqBNJNwAAAENAwCAAAAAAAAAAAAAAAAAAAAA.YAAAAAAAAAA.QGLtV_T9fb2vj-_Z99_tkeYwf95y3p-wzhheMs-8NyZeH_B4Wv2MyvBX4JiQKGRgksjLBAQdtHGlcTQgBwIlViTLMYk2MjzNKJrJEilsbO2dYGD9Pn8HT3ZCY70-vv__7v3ff_3g.IGLtV_T9fb2vj-_Z99_tkeYwf95y3p-wzhheMs-8NyZeH_B4Wv2MyvBX4JiQKGRgksjLBAQdtHGlcTQgBwIlViTLMYk2MjzNKJrJEilsbO2dYGD9Pn8HT3ZCY70-vv__7v3ff_3g"); @@ -228,4 +251,171 @@ public void testDecode3() throws DecodingException { tcfEuV2.getVendorsDisclosedSegmentType()); Assertions.assertEquals(tcfEuV2.getFieldValue("VendorsDisclosed"), tcfEuV2.getVendorsDisclosed()); } + + @SuppressWarnings("unchecked") + @Test + public void testDecode4() { + TcfEuV2 tcfEuV2 = new TcfEuV2( + "CPi8wgAPi8wgAAOACBENCuCoAP_AAEfAACiQJHNd_H__bX9n-f7_6ft0eY1f9_r37uQzDhfNk-8F3L_W_LwX_2E7NF36tq4KmR4ku1LBIUNtHMnUDUmxaokVrzHsak2cpzNKJ_BkknsZe2dYGF9vm5tj-QKZ7_5_d3f52T_9_9v-39z33913v3d93-_13LjdV5_9H_v9fR_b8_Kf9_5-_4v8_____3_e______8AEEggCTDVuIAuxLHAm0DCKBECMKwkKoFABBQDC0QGADg4KdlYBPrCBAAgFAEYEQIcAUYEAgAAAgCQiACQIsEAAAIgEAAIAEQiEABAwCCgAsDAIAAQDQMUQoABAkIMiAiKUwICIEggJbKhBKC6Q0wgCrLACgkRsFAAiAAAUgACAsHAMESAlYsECTFG-QAjBCgFEqFaAGGgAwABBI4RABgACCRwqADAAEEjgA"); + + Assertions.assertEquals(2, tcfEuV2.getFieldValue("Version")); + Assertions.assertEquals(14, tcfEuV2.getFieldValue("CmpId")); + Assertions.assertEquals(2, tcfEuV2.getFieldValue("CmpVersion")); + Assertions.assertEquals(1, tcfEuV2.getFieldValue("ConsentScreen")); + Assertions.assertEquals("EN", tcfEuV2.getFieldValue("ConsentLanguage")); + Assertions.assertEquals(174, tcfEuV2.getFieldValue("VendorListVersion")); + Assertions.assertEquals(2, tcfEuV2.getFieldValue("PolicyVersion")); + Assertions.assertEquals(true, tcfEuV2.getFieldValue("IsServiceSpecific")); + Assertions.assertEquals(false, tcfEuV2.getFieldValue("UseNonStandardStacks")); + + Assertions.assertEquals( + Arrays.asList(true, false, false, false, false, false, false, false, false, false, false, false), + tcfEuV2.getFieldValue("SpecialFeatureOptins")); + Assertions + .assertEquals( + Arrays.asList(true, true, true, true, true, true, true, true, true, true, false, false, false, false, false, + false, false, false, false, false, false, false, false, false), + tcfEuV2.getFieldValue("PurposeConsents")); + Assertions.assertEquals( + Arrays.asList(false, true, false, false, false, true, true, true, true, true, false, false, false, false, false, + false, false, false, false, false, false, false, false, false), + tcfEuV2.getFieldValue("PurposeLegitimateInterests")); + + Assertions.assertEquals(false, tcfEuV2.getFieldValue("PurposeOneTreatment")); + Assertions.assertEquals("US", tcfEuV2.getFieldValue("PublisherCountryCode")); + + Assertions.assertEquals(772, ((List) tcfEuV2.getFieldValue("VendorConsents")).size()); + + Assertions.assertEquals(280, ((List) tcfEuV2.getFieldValue("VendorLegitimateInterests")).size()); + } + + @SuppressWarnings("unchecked") + @Test + public void testDecode5() { + TcfEuV2 tcfEuV2 = new TcfEuV2( + "CPgA5EAPgA5EAAOACBENCuCoAP_AAEfAACiQI0Nd_H__bX9n-f7_6Pt0cY1f9_r3ruQzDhfFk-8F3L_W3LwX32E7NF36pq4KmR4ku1LBIQFtHMnUDUmxaokVrzHsak2cpyNKI7BkknsZe2dYGF9Pm5lD-QKZ7_5_d3f52T_9_9v-39z339V3v3d93-_12PjdV599H_v9fR_b8_Kf9_5-_4v8___4IQAAAAQQ_AJMNW4gC7EscCbQMIoAQIwrCQqAUAEFAMLRAYAODgpmVgEusIEACAUARgRAhxBRgQCAAACAJCIAJAiwQAIAiAQAAgARAIQAEDAIKACwMAgABANAxACgAECQgyICIpTAgIgSCAlsqEEoKpDTCAKssAKARGwUACIAABSAAICwcAwRICViwQJMUbwAw0AGAAIJHCIAMAAQSOFQAYAAgkcA"); + + Assertions.assertEquals(2, tcfEuV2.getFieldValue("Version")); + Assertions.assertEquals(14, tcfEuV2.getFieldValue("CmpId")); + Assertions.assertEquals(2, tcfEuV2.getFieldValue("CmpVersion")); + Assertions.assertEquals(1, tcfEuV2.getFieldValue("ConsentScreen")); + Assertions.assertEquals("EN", tcfEuV2.getFieldValue("ConsentLanguage")); + Assertions.assertEquals(174, tcfEuV2.getFieldValue("VendorListVersion")); + Assertions.assertEquals(2, tcfEuV2.getFieldValue("PolicyVersion")); + Assertions.assertEquals(true, tcfEuV2.getFieldValue("IsServiceSpecific")); + Assertions.assertEquals(false, tcfEuV2.getFieldValue("UseNonStandardStacks")); + + Assertions.assertEquals( + Arrays.asList(true, false, false, false, false, false, false, false, false, false, false, false), + tcfEuV2.getFieldValue("SpecialFeatureOptins")); + Assertions + .assertEquals( + Arrays.asList(true, true, true, true, true, true, true, true, true, true, false, false, false, false, false, + false, false, false, false, false, false, false, false, false), + tcfEuV2.getFieldValue("PurposeConsents")); + Assertions.assertEquals( + Arrays.asList(false, true, false, false, false, true, true, true, true, true, false, false, false, false, false, + false, false, false, false, false, false, false, false, false), + tcfEuV2.getFieldValue("PurposeLegitimateInterests")); + + Assertions.assertEquals(false, tcfEuV2.getFieldValue("PurposeOneTreatment")); + Assertions.assertEquals("US", tcfEuV2.getFieldValue("PublisherCountryCode")); + + Assertions.assertEquals(693, ((List) tcfEuV2.getFieldValue("VendorConsents")).size()); + + Assertions.assertEquals(254, ((List) tcfEuV2.getFieldValue("VendorLegitimateInterests")).size()); + } + + @Test + public void testDecode6() { + TcfEuV2 tcfEuV2 = new TcfEuV2("COv_eg6Ov_eg6AOADBENAaCgAP_AAH_AACiQAVEUQQoAIQAqIoghAAQgAA.YAAAAAAAAAAAAAAAAAA"); + + Assertions.assertEquals(2, tcfEuV2.getFieldValue("Version")); + Assertions.assertEquals(14, tcfEuV2.getFieldValue("CmpId")); + Assertions.assertEquals(3, tcfEuV2.getFieldValue("CmpVersion")); + Assertions.assertEquals(1, tcfEuV2.getFieldValue("ConsentScreen")); + Assertions.assertEquals("EN", tcfEuV2.getFieldValue("ConsentLanguage")); + Assertions.assertEquals(26, tcfEuV2.getFieldValue("VendorListVersion")); + Assertions.assertEquals(2, tcfEuV2.getFieldValue("PolicyVersion")); + Assertions.assertEquals(true, tcfEuV2.getFieldValue("IsServiceSpecific")); + Assertions.assertEquals(false, tcfEuV2.getFieldValue("UseNonStandardStacks")); + + Assertions.assertEquals( + Arrays.asList(false, false, false, false, false, false, false, false, false, false, false, false), + tcfEuV2.getFieldValue("SpecialFeatureOptins")); + Assertions + .assertEquals( + Arrays.asList(true, true, true, true, true, true, true, true, true, true, false, false, false, false, false, + false, false, false, false, false, false, false, false, false), + tcfEuV2.getFieldValue("PurposeConsents")); + Assertions.assertEquals( + Arrays.asList(false, true, true, true, true, true, true, true, true, true, false, false, false, false, false, + false, false, false, false, false, false, false, false, false), + tcfEuV2.getFieldValue("PurposeLegitimateInterests")); + + Assertions.assertEquals(false, tcfEuV2.getFieldValue("PurposeOneTreatment")); + Assertions.assertEquals("US", tcfEuV2.getFieldValue("PublisherCountryCode")); + + Assertions.assertEquals(Arrays.asList(2, 6, 8, 12, 18, 23, 25, 37, 42), tcfEuV2.getFieldValue("VendorConsents")); + + Assertions.assertEquals(Arrays.asList(2, 6, 8, 12, 18, 23, 37, 42), + tcfEuV2.getFieldValue("VendorLegitimateInterests")); + } + + @Test + public void testDecode7() throws DecodingException { + TcfEuV2 tcfEuV2 = new TcfEuV2("COoC-kUOoC-kUAHABAENAwCoAIAAAELAAAwIF5wAoAAgAGAvMACX_ABBAAQAFA"); + + Assertions.assertEquals(2, tcfEuV2.getFieldValue("Version")); + Assertions.assertEquals("2019-10-07T05:17:54Z[UTC]", tcfEuV2.getFieldValue("Created").toString()); + Assertions.assertEquals("2019-10-07T05:17:54Z[UTC]", tcfEuV2.getFieldValue("LastUpdated").toString()); + Assertions.assertEquals(7, tcfEuV2.getFieldValue("CmpId")); + Assertions.assertEquals(1, tcfEuV2.getFieldValue("CmpVersion")); + Assertions.assertEquals(0, tcfEuV2.getFieldValue("ConsentScreen")); + Assertions.assertEquals("EN", tcfEuV2.getFieldValue("ConsentLanguage")); + Assertions.assertEquals(48, tcfEuV2.getFieldValue("VendorListVersion")); + Assertions.assertEquals(2, tcfEuV2.getFieldValue("PolicyVersion")); + Assertions.assertEquals(true, tcfEuV2.getFieldValue("IsServiceSpecific")); + Assertions.assertEquals(false, tcfEuV2.getFieldValue("UseNonStandardStacks")); + + Assertions.assertEquals( + Arrays.asList(true, false, false, false, false, false, false, false, false, false, false, false), + tcfEuV2.getFieldValue("SpecialFeatureOptins")); + Assertions.assertEquals( + Arrays.asList(true, false, false, false, false, false, false, false, false, false, false, false, false, false, + false, false, false, false, false, false, false, false, false, false), + tcfEuV2.getFieldValue("PurposeConsents")); + Assertions.assertEquals( + Arrays.asList(false, true, false, false, false, false, true, false, true, true, false, false, false, false, + false, false, false, false, false, false, false, false, false, false), + tcfEuV2.getFieldValue("PurposeLegitimateInterests")); + + Assertions.assertEquals(false, tcfEuV2.getFieldValue("PurposeOneTreatment")); + Assertions.assertEquals("GB", tcfEuV2.getFieldValue("PublisherCountryCode")); + + Assertions.assertEquals(Arrays.asList(1, 2, 3, 755), tcfEuV2.getFieldValue("VendorConsents")); + + Assertions.assertEquals(Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9), + tcfEuV2.getFieldValue("VendorLegitimateInterests")); + + Assertions.assertEquals(1, ((List)tcfEuV2.getFieldValue("PublisherRestrictions")).size()); + RangeEntry rangeEntry = ((List)tcfEuV2.getFieldValue("PublisherRestrictions")).get(0); + Assertions.assertEquals(1, rangeEntry.getKey()); + Assertions.assertEquals(0, rangeEntry.getType()); + Assertions.assertEquals(Arrays.asList(10), rangeEntry.getIds()); + } + + @Test() + public void testDecodeGarbage1() { + Assertions.assertThrows(DecodingException.class, () -> { + new TcfEuV2("A").getCreated(); + }); + } + + @Test() + public void testDecodeGarbage2() { + Assertions.assertThrows(DecodingException.class, () -> { + new TcfEuV2("z").getCreated(); + }); + } } diff --git a/iabgpp-encoder/src/test/java/com/iab/gpp/encoder/section/UsCaTest.java b/iabgpp-encoder/src/test/java/com/iab/gpp/encoder/section/UsCaTest.java new file mode 100644 index 00000000..18fe5abc --- /dev/null +++ b/iabgpp-encoder/src/test/java/com/iab/gpp/encoder/section/UsCaTest.java @@ -0,0 +1,210 @@ +package com.iab.gpp.encoder.section; + + +import java.util.Arrays; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; +import com.iab.gpp.encoder.error.DecodingException; +import com.iab.gpp.encoder.error.ValidationException; +import com.iab.gpp.encoder.field.UsCaField; + +public class UsCaTest { + + @Test + public void testEncode1() { + + UsCa usCa = new UsCa(); + Assertions.assertEquals("BAAAAABA.Q", usCa.encode()); + } + + @Test + public void testEncode2() { + UsCa usCa = new UsCa(); + + usCa.setFieldValue(UsCaField.SALE_OPT_OUT_NOTICE, 1); + usCa.setFieldValue(UsCaField.SHARING_OPT_OUT_NOTICE, 1); + usCa.setFieldValue(UsCaField.SENSITIVE_DATA_LIMIT_USE_NOTICE, 1); + usCa.setFieldValue(UsCaField.SALE_OPT_OUT, 1); + usCa.setFieldValue(UsCaField.SHARING_OPT_OUT, 1); + usCa.setFieldValue(UsCaField.SENSITIVE_DATA_PROCESSING, Arrays.asList(2, 1, 0, 2, 1, 0, 2, 1, 0)); + usCa.setFieldValue(UsCaField.KNOWN_CHILD_SENSITIVE_DATA_CONSENTS, Arrays.asList(2, 1)); + usCa.setFieldValue(UsCaField.PERSONAL_DATA_CONSENTS, 1); + usCa.setFieldValue(UsCaField.MSPA_COVERED_TRANSACTION, 1); + usCa.setFieldValue(UsCaField.MSPA_OPT_OUT_OPTION_MODE, 1); + usCa.setFieldValue(UsCaField.MSPA_SERVICE_PROVIDER_MODE, 2); + usCa.setFieldValue(UsCaField.GPC, true); + + Assertions.assertEquals("BVWSSSVY.Y", usCa.encode()); + } + + @Test + public void testEncode3() { + UsCa usCa = new UsCa(); + + usCa.setFieldValue(UsCaField.SALE_OPT_OUT_NOTICE, 1); + usCa.setFieldValue(UsCaField.SHARING_OPT_OUT_NOTICE, 1); + usCa.setFieldValue(UsCaField.SENSITIVE_DATA_LIMIT_USE_NOTICE, 1); + usCa.setFieldValue(UsCaField.SALE_OPT_OUT, 1); + usCa.setFieldValue(UsCaField.SHARING_OPT_OUT, 1); + usCa.setFieldValue(UsCaField.SENSITIVE_DATA_PROCESSING, Arrays.asList(2, 1, 0, 2, 1, 0, 2, 1, 0)); + usCa.setFieldValue(UsCaField.KNOWN_CHILD_SENSITIVE_DATA_CONSENTS, Arrays.asList(2, 1)); + usCa.setFieldValue(UsCaField.PERSONAL_DATA_CONSENTS, 1); + usCa.setFieldValue(UsCaField.MSPA_COVERED_TRANSACTION, 1); + usCa.setFieldValue(UsCaField.MSPA_OPT_OUT_OPTION_MODE, 1); + usCa.setFieldValue(UsCaField.MSPA_SERVICE_PROVIDER_MODE, 2); + usCa.setFieldValue(UsCaField.GPC, true); + + Assertions.assertEquals("BVWSSSVY.Y", usCa.encode()); + } + + @Test + public void testSetInvalidValues() { + UsCa usCa = new UsCa(); + + try { + usCa.setFieldValue(UsCaField.SALE_OPT_OUT_NOTICE, 3); + Assertions.fail("Expected ValidationException"); + } catch (ValidationException e) { + + } + + try { + usCa.setFieldValue(UsCaField.SHARING_OPT_OUT_NOTICE, 3); + Assertions.fail("Expected ValidationException"); + } catch (ValidationException e) { + + } + + try { + usCa.setFieldValue(UsCaField.SENSITIVE_DATA_LIMIT_USE_NOTICE, -1); + Assertions.fail("Expected ValidationException"); + } catch (ValidationException e) { + + } + + try { + usCa.setFieldValue(UsCaField.SALE_OPT_OUT, 3); + Assertions.fail("Expected ValidationException"); + } catch (ValidationException e) { + + } + + try { + usCa.setFieldValue(UsCaField.SHARING_OPT_OUT, 3); + Assertions.fail("Expected ValidationException"); + } catch (ValidationException e) { + + } + + try { + usCa.setFieldValue(UsCaField.SENSITIVE_DATA_PROCESSING, Arrays.asList(0, 0, 0, 0, 3, 0, 0, 0, 0)); + Assertions.fail("Expected ValidationException"); + } catch (ValidationException e) { + + } + + try { + usCa.setFieldValue(UsCaField.KNOWN_CHILD_SENSITIVE_DATA_CONSENTS, Arrays.asList(0, 3)); + Assertions.fail("Expected ValidationException"); + } catch (ValidationException e) { + + } + + try { + usCa.setFieldValue(UsCaField.PERSONAL_DATA_CONSENTS, 3); + Assertions.fail("Expected ValidationException"); + } catch (ValidationException e) { + + } + + try { + usCa.setFieldValue(UsCaField.MSPA_COVERED_TRANSACTION, 0); + Assertions.fail("Expected ValidationException"); + } catch (ValidationException e) { + + } + + try { + usCa.setFieldValue(UsCaField.MSPA_OPT_OUT_OPTION_MODE, 3); + Assertions.fail("Expected ValidationException"); + } catch (ValidationException e) { + + } + + try { + usCa.setFieldValue(UsCaField.MSPA_SERVICE_PROVIDER_MODE, 3); + Assertions.fail("Expected ValidationException"); + } catch (ValidationException e) { + + } + } + + @Test + public void testEncodeWithGpcSegmentExcluded() { + + UsCa usCa = new UsCa(); + usCa.setFieldValue(UsCaField.GPC_SEGMENT_INCLUDED, false); + Assertions.assertEquals("BAAAAABA", usCa.encode()); + } + + @Test + public void testDecode1() { + UsCa usCa = new UsCa("BVWSSSVY.Y"); + + Assertions.assertEquals(1, usCa.getSaleOptOutNotice()); + Assertions.assertEquals(1, usCa.getSharingOptOut()); + Assertions.assertEquals(1, usCa.getSensitiveDataLimitUseNotice()); + Assertions.assertEquals(1, usCa.getSaleOptOut()); + Assertions.assertEquals(1, usCa.getSharingOptOut()); + Assertions.assertEquals(Arrays.asList(2, 1, 0, 2, 1, 0, 2, 1, 0), usCa.getSensitiveDataProcessing()); + Assertions.assertEquals(Arrays.asList(2, 1), usCa.getKnownChildSensitiveDataConsents()); + Assertions.assertEquals(1, usCa.getPersonalDataConsents()); + Assertions.assertEquals(1, usCa.getMspaCoveredTransaction()); + Assertions.assertEquals(1, usCa.getMspaOptOutOptionMode()); + Assertions.assertEquals(2, usCa.getMspaServiceProviderMode()); + Assertions.assertEquals(true, usCa.getGpc()); + } + + @Test + public void testDecode2() { + UsCa usCa = new UsCa("BVWSSSVY.YA"); + + Assertions.assertEquals(1, usCa.getSaleOptOutNotice()); + Assertions.assertEquals(1, usCa.getSharingOptOut()); + Assertions.assertEquals(1, usCa.getSensitiveDataLimitUseNotice()); + Assertions.assertEquals(1, usCa.getSaleOptOut()); + Assertions.assertEquals(1, usCa.getSharingOptOut()); + Assertions.assertEquals(Arrays.asList(2, 1, 0, 2, 1, 0, 2, 1, 0), usCa.getSensitiveDataProcessing()); + Assertions.assertEquals(Arrays.asList(2, 1), usCa.getKnownChildSensitiveDataConsents()); + Assertions.assertEquals(1, usCa.getPersonalDataConsents()); + Assertions.assertEquals(1, usCa.getMspaCoveredTransaction()); + Assertions.assertEquals(1, usCa.getMspaOptOutOptionMode()); + Assertions.assertEquals(2, usCa.getMspaServiceProviderMode()); + Assertions.assertEquals(true, usCa.getGpc()); + } + + @Test + public void testDecodeWithGpcSegmentExcluded() { + UsCa usCa = new UsCa("BVWSSSVY"); + + Assertions.assertEquals(1, usCa.getSaleOptOutNotice()); + Assertions.assertEquals(1, usCa.getSharingOptOut()); + Assertions.assertEquals(1, usCa.getSensitiveDataLimitUseNotice()); + Assertions.assertEquals(1, usCa.getSaleOptOut()); + Assertions.assertEquals(1, usCa.getSharingOptOut()); + Assertions.assertEquals(Arrays.asList(2, 1, 0, 2, 1, 0, 2, 1, 0), usCa.getSensitiveDataProcessing()); + Assertions.assertEquals(Arrays.asList(2, 1), usCa.getKnownChildSensitiveDataConsents()); + Assertions.assertEquals(1, usCa.getPersonalDataConsents()); + Assertions.assertEquals(1, usCa.getMspaCoveredTransaction()); + Assertions.assertEquals(1, usCa.getMspaOptOutOptionMode()); + Assertions.assertEquals(2, usCa.getMspaServiceProviderMode()); + Assertions.assertEquals(false, usCa.getGpcSegmentIncluded()); + } + + @Test() + public void testDecodeGarbage() { + Assertions.assertThrows(DecodingException.class, () -> { + new UsCa("z").getPersonalDataConsents(); + }); + } +} diff --git a/iabgpp-encoder/src/test/java/com/iab/gpp/encoder/section/UsCoTest.java b/iabgpp-encoder/src/test/java/com/iab/gpp/encoder/section/UsCoTest.java new file mode 100644 index 00000000..68ebac54 --- /dev/null +++ b/iabgpp-encoder/src/test/java/com/iab/gpp/encoder/section/UsCoTest.java @@ -0,0 +1,178 @@ +package com.iab.gpp.encoder.section; + + +import java.util.Arrays; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; +import com.iab.gpp.encoder.error.DecodingException; +import com.iab.gpp.encoder.error.ValidationException; +import com.iab.gpp.encoder.field.UsCoField; + +public class UsCoTest { + + @Test + public void testEncode1() { + UsCo usCo = new UsCo(); + Assertions.assertEquals("BAAAAEA.Q", usCo.encode()); + } + + @Test + public void testEncode2() { + UsCo usCo = new UsCo(); + + usCo.setFieldValue(UsCoField.SHARING_NOTICE, 1); + usCo.setFieldValue(UsCoField.SALE_OPT_OUT_NOTICE, 1); + usCo.setFieldValue(UsCoField.TARGETED_ADVERTISING_OPT_OUT_NOTICE, 1); + usCo.setFieldValue(UsCoField.SALE_OPT_OUT, 1); + usCo.setFieldValue(UsCoField.TARGETED_ADVERTISING_OPT_OUT, 1); + usCo.setFieldValue(UsCoField.SENSITIVE_DATA_PROCESSING, Arrays.asList(2, 1, 0, 2, 1, 0, 2)); + usCo.setFieldValue(UsCoField.KNOWN_CHILD_SENSITIVE_DATA_CONSENTS, 1); + usCo.setFieldValue(UsCoField.MSPA_COVERED_TRANSACTION, 1); + usCo.setFieldValue(UsCoField.MSPA_OPT_OUT_OPTION_MODE, 1); + usCo.setFieldValue(UsCoField.MSPA_SERVICE_PROVIDER_MODE, 2); + usCo.setFieldValue(UsCoField.GPC, true); + + Assertions.assertEquals("BVWSSVg.Y", usCo.encode()); + } + + @Test + public void testSetInvalidValues() { + UsCo usCo = new UsCo(); + + try { + usCo.setFieldValue(UsCoField.SHARING_NOTICE, 3); + Assertions.fail("Expected ValidationException"); + } catch (ValidationException e) { + + } + + try { + usCo.setFieldValue(UsCoField.SALE_OPT_OUT_NOTICE, 3); + Assertions.fail("Expected ValidationException"); + } catch (ValidationException e) { + + } + + try { + usCo.setFieldValue(UsCoField.TARGETED_ADVERTISING_OPT_OUT_NOTICE, 3); + Assertions.fail("Expected ValidationException"); + } catch (ValidationException e) { + + } + + try { + usCo.setFieldValue(UsCoField.SALE_OPT_OUT, 3); + Assertions.fail("Expected ValidationException"); + } catch (ValidationException e) { + + } + + try { + usCo.setFieldValue(UsCoField.TARGETED_ADVERTISING_OPT_OUT, 3); + Assertions.fail("Expected ValidationException"); + } catch (ValidationException e) { + + } + + try { + usCo.setFieldValue(UsCoField.SENSITIVE_DATA_PROCESSING, Arrays.asList(0, 1, 2, 3, 0, 1, 2)); + Assertions.fail("Expected ValidationException"); + } catch (ValidationException e) { + + } + + try { + usCo.setFieldValue(UsCoField.KNOWN_CHILD_SENSITIVE_DATA_CONSENTS, 3); + Assertions.fail("Expected ValidationException"); + } catch (ValidationException e) { + + } + + try { + usCo.setFieldValue(UsCoField.MSPA_COVERED_TRANSACTION, 0); + Assertions.fail("Expected ValidationException"); + } catch (ValidationException e) { + + } + + try { + usCo.setFieldValue(UsCoField.MSPA_OPT_OUT_OPTION_MODE, -1); + Assertions.fail("Expected ValidationException"); + } catch (ValidationException e) { + + } + + try { + usCo.setFieldValue(UsCoField.MSPA_SERVICE_PROVIDER_MODE, 5); + Assertions.fail("Expected ValidationException"); + } catch (ValidationException e) { + + } + + } + + @Test + public void testEncodeWithGpcSegmentExcluded() { + UsCo usCo = new UsCo(); + usCo.setFieldValue(UsCoField.GPC_SEGMENT_INCLUDED, false); + Assertions.assertEquals("BAAAAEA", usCo.encode()); + } + + @Test + public void testDecode1() { + UsCo usCo = new UsCo("BVWSSVg.Y"); + + Assertions.assertEquals(1, usCo.getSharingNotice()); + Assertions.assertEquals(1, usCo.getSaleOptOutNotice()); + Assertions.assertEquals(1, usCo.getTargetedAdvertisingOptOutNotice()); + Assertions.assertEquals(1, usCo.getSaleOptOut()); + Assertions.assertEquals(1, usCo.getTargetedAdvertisingOptOut()); + Assertions.assertEquals(Arrays.asList(2, 1, 0, 2, 1, 0, 2), usCo.getSensitiveDataProcessing()); + Assertions.assertEquals(1, usCo.getKnownChildSensitiveDataConsents()); + Assertions.assertEquals(1, usCo.getMspaCoveredTransaction()); + Assertions.assertEquals(1, usCo.getMspaOptOutOptionMode()); + Assertions.assertEquals(2, usCo.getMspaServiceProviderMode()); + Assertions.assertEquals(true, usCo.getGpc()); + } + + @Test + public void testDecode2() { + UsCo usCo = new UsCo("BVWSSVg.YA"); + + Assertions.assertEquals(1, usCo.getSharingNotice()); + Assertions.assertEquals(1, usCo.getSaleOptOutNotice()); + Assertions.assertEquals(1, usCo.getTargetedAdvertisingOptOutNotice()); + Assertions.assertEquals(1, usCo.getSaleOptOut()); + Assertions.assertEquals(1, usCo.getTargetedAdvertisingOptOut()); + Assertions.assertEquals(Arrays.asList(2, 1, 0, 2, 1, 0, 2), usCo.getSensitiveDataProcessing()); + Assertions.assertEquals(1, usCo.getKnownChildSensitiveDataConsents()); + Assertions.assertEquals(1, usCo.getMspaCoveredTransaction()); + Assertions.assertEquals(1, usCo.getMspaOptOutOptionMode()); + Assertions.assertEquals(2, usCo.getMspaServiceProviderMode()); + Assertions.assertEquals(true, usCo.getGpc()); + } + + @Test + public void testDecodeWithGpcSegmentExcluded() { + UsCo usCo = new UsCo("BVWSSVg"); + + Assertions.assertEquals(1, usCo.getSharingNotice()); + Assertions.assertEquals(1, usCo.getSaleOptOutNotice()); + Assertions.assertEquals(1, usCo.getTargetedAdvertisingOptOutNotice()); + Assertions.assertEquals(1, usCo.getSaleOptOut()); + Assertions.assertEquals(1, usCo.getTargetedAdvertisingOptOut()); + Assertions.assertEquals(Arrays.asList(2, 1, 0, 2, 1, 0, 2), usCo.getSensitiveDataProcessing()); + Assertions.assertEquals(1, usCo.getKnownChildSensitiveDataConsents()); + Assertions.assertEquals(1, usCo.getMspaCoveredTransaction()); + Assertions.assertEquals(1, usCo.getMspaOptOutOptionMode()); + Assertions.assertEquals(2, usCo.getMspaServiceProviderMode()); + Assertions.assertEquals(false, usCo.getGpcSegmentIncluded()); + } + + @Test() + public void testDecodeGarbage() { + Assertions.assertThrows(DecodingException.class, () -> { + new UsCo("z").getTargetedAdvertisingOptOut(); + }); + } +} diff --git a/iabgpp-encoder/src/test/java/com/iab/gpp/encoder/section/UsCtTest.java b/iabgpp-encoder/src/test/java/com/iab/gpp/encoder/section/UsCtTest.java new file mode 100644 index 00000000..53d213cd --- /dev/null +++ b/iabgpp-encoder/src/test/java/com/iab/gpp/encoder/section/UsCtTest.java @@ -0,0 +1,177 @@ +package com.iab.gpp.encoder.section; + + +import java.util.Arrays; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; +import com.iab.gpp.encoder.error.DecodingException; +import com.iab.gpp.encoder.error.ValidationException; +import com.iab.gpp.encoder.field.UsCtField; + +public class UsCtTest { + + @Test + public void testEncode1() { + UsCt usCt = new UsCt(); + Assertions.assertEquals("BAAAAAEA.Q", usCt.encode()); + } + + @Test + public void testEncode2() { + UsCt usCt = new UsCt(); + + usCt.setFieldValue(UsCtField.SHARING_NOTICE, 1); + usCt.setFieldValue(UsCtField.SALE_OPT_OUT_NOTICE, 1); + usCt.setFieldValue(UsCtField.TARGETED_ADVERTISING_OPT_OUT_NOTICE, 1); + usCt.setFieldValue(UsCtField.SALE_OPT_OUT, 1); + usCt.setFieldValue(UsCtField.TARGETED_ADVERTISING_OPT_OUT, 1); + usCt.setFieldValue(UsCtField.SENSITIVE_DATA_PROCESSING, Arrays.asList(2, 1, 0, 2, 1, 0, 2, 1)); + usCt.setFieldValue(UsCtField.KNOWN_CHILD_SENSITIVE_DATA_CONSENTS, Arrays.asList(2, 1, 0)); + usCt.setFieldValue(UsCtField.MSPA_COVERED_TRANSACTION, 1); + usCt.setFieldValue(UsCtField.MSPA_OPT_OUT_OPTION_MODE, 1); + usCt.setFieldValue(UsCtField.MSPA_SERVICE_PROVIDER_MODE, 2); + usCt.setFieldValue(UsCtField.GPC, true); + + Assertions.assertEquals("BVWSSZFg.Y", usCt.encode()); + } + + @Test + public void testSetInvalidValues() { + UsCt usCt = new UsCt(); + + try { + usCt.setFieldValue(UsCtField.SHARING_NOTICE, 3); + Assertions.fail("Expected ValidationException"); + } catch (ValidationException e) { + + } + + try { + usCt.setFieldValue(UsCtField.SALE_OPT_OUT_NOTICE, 3); + Assertions.fail("Expected ValidationException"); + } catch (ValidationException e) { + + } + + try { + usCt.setFieldValue(UsCtField.TARGETED_ADVERTISING_OPT_OUT_NOTICE, 3); + Assertions.fail("Expected ValidationException"); + } catch (ValidationException e) { + + } + + try { + usCt.setFieldValue(UsCtField.SALE_OPT_OUT, 3); + Assertions.fail("Expected ValidationException"); + } catch (ValidationException e) { + + } + + try { + usCt.setFieldValue(UsCtField.TARGETED_ADVERTISING_OPT_OUT, -1); + Assertions.fail("Expected ValidationException"); + } catch (ValidationException e) { + + } + + try { + usCt.setFieldValue(UsCtField.SENSITIVE_DATA_PROCESSING, Arrays.asList(0, 1, 2, 3, 1, 2, 0, 1)); + Assertions.fail("Expected ValidationException"); + } catch (ValidationException e) { + + } + + try { + usCt.setFieldValue(UsCtField.KNOWN_CHILD_SENSITIVE_DATA_CONSENTS, Arrays.asList(1, 2, 3)); + Assertions.fail("Expected ValidationException"); + } catch (ValidationException e) { + + } + + try { + usCt.setFieldValue(UsCtField.MSPA_COVERED_TRANSACTION, 0); + Assertions.fail("Expected ValidationException"); + } catch (ValidationException e) { + + } + + try { + usCt.setFieldValue(UsCtField.MSPA_OPT_OUT_OPTION_MODE, 4); + Assertions.fail("Expected ValidationException"); + } catch (ValidationException e) { + + } + + try { + usCt.setFieldValue(UsCtField.MSPA_SERVICE_PROVIDER_MODE, -1); + Assertions.fail("Expected ValidationException"); + } catch (ValidationException e) { + + } + } + + @Test + public void testEncodeWithGpcSegmentExcluded() { + UsCt usCt = new UsCt(); + usCt.setFieldValue(UsCtField.GPC_SEGMENT_INCLUDED, false); + Assertions.assertEquals("BAAAAAEA", usCt.encode()); + } + + @Test + public void testDecode1() throws DecodingException { + UsCt usCt = new UsCt("BVWSSZFg.Y"); + + Assertions.assertEquals(1, usCt.getSharingNotice()); + Assertions.assertEquals(1, usCt.getSaleOptOutNotice()); + Assertions.assertEquals(1, usCt.getTargetedAdvertisingOptOutNotice()); + Assertions.assertEquals(1, usCt.getSaleOptOut()); + Assertions.assertEquals(1, usCt.getTargetedAdvertisingOptOut()); + Assertions.assertEquals(Arrays.asList(2, 1, 0, 2, 1, 0, 2, 1), usCt.getSensitiveDataProcessing()); + Assertions.assertEquals(Arrays.asList(2, 1, 0), usCt.getKnownChildSensitiveDataConsents()); + Assertions.assertEquals(1, usCt.getMspaCoveredTransaction()); + Assertions.assertEquals(1, usCt.getMspaOptOutOptionMode()); + Assertions.assertEquals(2, usCt.getMspaServiceProviderMode()); + Assertions.assertEquals(true, usCt.getGpc()); + } + + @Test + public void testDecode2() throws DecodingException { + UsCt usCt = new UsCt("BVWSSZFg.YA"); + + Assertions.assertEquals(1, usCt.getSharingNotice()); + Assertions.assertEquals(1, usCt.getSaleOptOutNotice()); + Assertions.assertEquals(1, usCt.getTargetedAdvertisingOptOutNotice()); + Assertions.assertEquals(1, usCt.getSaleOptOut()); + Assertions.assertEquals(1, usCt.getTargetedAdvertisingOptOut()); + Assertions.assertEquals(Arrays.asList(2, 1, 0, 2, 1, 0, 2, 1), usCt.getSensitiveDataProcessing()); + Assertions.assertEquals(Arrays.asList(2, 1, 0), usCt.getKnownChildSensitiveDataConsents()); + Assertions.assertEquals(1, usCt.getMspaCoveredTransaction()); + Assertions.assertEquals(1, usCt.getMspaOptOutOptionMode()); + Assertions.assertEquals(2, usCt.getMspaServiceProviderMode()); + Assertions.assertEquals(true, usCt.getGpc()); + } + + @Test + public void testDecodeWithGpcSegmentExcluded() throws DecodingException { + UsCt usCt = new UsCt("BVWSSZFg"); + + Assertions.assertEquals(1, usCt.getSharingNotice()); + Assertions.assertEquals(1, usCt.getSaleOptOutNotice()); + Assertions.assertEquals(1, usCt.getTargetedAdvertisingOptOutNotice()); + Assertions.assertEquals(1, usCt.getSaleOptOut()); + Assertions.assertEquals(1, usCt.getTargetedAdvertisingOptOut()); + Assertions.assertEquals(Arrays.asList(2, 1, 0, 2, 1, 0, 2, 1), usCt.getSensitiveDataProcessing()); + Assertions.assertEquals(Arrays.asList(2, 1, 0), usCt.getKnownChildSensitiveDataConsents()); + Assertions.assertEquals(1, usCt.getMspaCoveredTransaction()); + Assertions.assertEquals(1, usCt.getMspaOptOutOptionMode()); + Assertions.assertEquals(2, usCt.getMspaServiceProviderMode()); + Assertions.assertEquals(false, usCt.getGpcSegmentIncluded()); + } + + @Test() + public void testDecodeGarbage() { + Assertions.assertThrows(DecodingException.class, () -> { + new UsCt("z").getSharingNotice(); + }); + } +} diff --git a/iabgpp-encoder/src/test/java/com/iab/gpp/encoder/section/UsDeTest.java b/iabgpp-encoder/src/test/java/com/iab/gpp/encoder/section/UsDeTest.java new file mode 100644 index 00000000..9fe24d18 --- /dev/null +++ b/iabgpp-encoder/src/test/java/com/iab/gpp/encoder/section/UsDeTest.java @@ -0,0 +1,189 @@ +package com.iab.gpp.encoder.section; + + +import java.util.Arrays; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; +import com.iab.gpp.encoder.error.DecodingException; +import com.iab.gpp.encoder.error.ValidationException; +import com.iab.gpp.encoder.field.UsDeField; + +public class UsDeTest { + + @Test + public void testEncode1() { + UsDe usDe = new UsDe(); + Assertions.assertEquals("BAAAAAABA.Q", usDe.encode()); + } + + @Test + public void testEncode2() { + UsDe usDe = new UsDe(); + + usDe.setFieldValue(UsDeField.PROCESSING_NOTICE, 1); + usDe.setFieldValue(UsDeField.SALE_OPT_OUT_NOTICE, 1); + usDe.setFieldValue(UsDeField.TARGETED_ADVERTISING_OPT_OUT_NOTICE, 1); + usDe.setFieldValue(UsDeField.SALE_OPT_OUT, 1); + usDe.setFieldValue(UsDeField.TARGETED_ADVERTISING_OPT_OUT, 1); + usDe.setFieldValue(UsDeField.SENSITIVE_DATA_PROCESSING, Arrays.asList(2, 1, 0, 2, 1, 0, 2, 1, 0)); + usDe.setFieldValue(UsDeField.KNOWN_CHILD_SENSITIVE_DATA_CONSENTS, Arrays.asList(2, 1, 0, 2, 1)); + usDe.setFieldValue(UsDeField.ADDITIONAL_DATA_PROCESSING_CONSENT, 1); + usDe.setFieldValue(UsDeField.MSPA_COVERED_TRANSACTION, 1); + usDe.setFieldValue(UsDeField.MSPA_OPT_OUT_OPTION_MODE, 1); + usDe.setFieldValue(UsDeField.MSPA_SERVICE_PROVIDER_MODE, 2); + usDe.setFieldValue(UsDeField.GPC, true); + + Assertions.assertEquals("BVWSSSSVY.Y", usDe.encode()); + } + + @Test + public void testSetInvalidValues() { + UsDe usDe = new UsDe(); + + try { + usDe.setFieldValue(UsDeField.PROCESSING_NOTICE, 3); + Assertions.fail("Expected ValidationException"); + } catch (ValidationException e) { + + } + + try { + usDe.setFieldValue(UsDeField.SALE_OPT_OUT_NOTICE, 3); + Assertions.fail("Expected ValidationException"); + } catch (ValidationException e) { + + } + + try { + usDe.setFieldValue(UsDeField.TARGETED_ADVERTISING_OPT_OUT_NOTICE, 3); + Assertions.fail("Expected ValidationException"); + } catch (ValidationException e) { + + } + + try { + usDe.setFieldValue(UsDeField.SALE_OPT_OUT, 3); + Assertions.fail("Expected ValidationException"); + } catch (ValidationException e) { + + } + + try { + usDe.setFieldValue(UsDeField.TARGETED_ADVERTISING_OPT_OUT, -1); + Assertions.fail("Expected ValidationException"); + } catch (ValidationException e) { + + } + + try { + usDe.setFieldValue(UsDeField.SENSITIVE_DATA_PROCESSING, Arrays.asList(0, 1, 2, 3, 1, 2, 0, 1)); + Assertions.fail("Expected ValidationException"); + } catch (ValidationException e) { + + } + + try { + usDe.setFieldValue(UsDeField.KNOWN_CHILD_SENSITIVE_DATA_CONSENTS, Arrays.asList(1, 2, 3)); + Assertions.fail("Expected ValidationException"); + } catch (ValidationException e) { + + } + + try { + usDe.setFieldValue(UsDeField.ADDITIONAL_DATA_PROCESSING_CONSENT, 3); + Assertions.fail("Expected ValidationException"); + } catch (ValidationException e) { + + } + + try { + usDe.setFieldValue(UsDeField.MSPA_COVERED_TRANSACTION, 0); + Assertions.fail("Expected ValidationException"); + } catch (ValidationException e) { + + } + + try { + usDe.setFieldValue(UsDeField.MSPA_OPT_OUT_OPTION_MODE, 4); + Assertions.fail("Expected ValidationException"); + } catch (ValidationException e) { + + } + + try { + usDe.setFieldValue(UsDeField.MSPA_SERVICE_PROVIDER_MODE, -1); + Assertions.fail("Expected ValidationException"); + } catch (ValidationException e) { + + } + } + + @Test + public void testEncodeWithGpcSegmentExcluded() { + UsDe usDe = new UsDe(); + usDe.setFieldValue(UsDeField.GPC_SEGMENT_INCLUDED, false); + Assertions.assertEquals("BAAAAAABA", usDe.encode()); + } + + @Test + public void testDecode1() throws DecodingException { + UsDe usDe = new UsDe("BVWSSSSVY.Y"); + + Assertions.assertEquals(1, usDe.getProcessingNotice()); + Assertions.assertEquals(1, usDe.getSaleOptOutNotice()); + Assertions.assertEquals(1, usDe.getTargetedAdvertisingOptOutNotice()); + Assertions.assertEquals(1, usDe.getSaleOptOut()); + Assertions.assertEquals(1, usDe.getTargetedAdvertisingOptOut()); + Assertions.assertEquals(Arrays.asList(2, 1, 0, 2, 1, 0, 2, 1, 0), usDe.getSensitiveDataProcessing()); + Assertions.assertEquals(Arrays.asList(2, 1, 0, 2, 1), usDe.getKnownChildSensitiveDataConsents()); + Assertions.assertEquals(1, usDe.getAdditionalDataProcessingConsent()); + Assertions.assertEquals(1, usDe.getMspaCoveredTransaction()); + Assertions.assertEquals(1, usDe.getMspaOptOutOptionMode()); + Assertions.assertEquals(2, usDe.getMspaServiceProviderMode()); + Assertions.assertEquals(true, usDe.getGpc()); + } + + @Test + public void testDecode2() throws DecodingException { + UsDe usDe = new UsDe("BVWSSSSVYA.YA"); + + Assertions.assertEquals(1, usDe.getProcessingNotice()); + Assertions.assertEquals(1, usDe.getSaleOptOutNotice()); + Assertions.assertEquals(1, usDe.getTargetedAdvertisingOptOutNotice()); + Assertions.assertEquals(1, usDe.getSaleOptOut()); + Assertions.assertEquals(1, usDe.getTargetedAdvertisingOptOut()); + Assertions.assertEquals(Arrays.asList(2, 1, 0, 2, 1, 0, 2, 1, 0), usDe.getSensitiveDataProcessing()); + Assertions.assertEquals(Arrays.asList(2, 1, 0, 2, 1), usDe.getKnownChildSensitiveDataConsents()); + Assertions.assertEquals(1, usDe.getAdditionalDataProcessingConsent()); + Assertions.assertEquals(1, usDe.getMspaCoveredTransaction()); + Assertions.assertEquals(1, usDe.getMspaOptOutOptionMode()); + Assertions.assertEquals(2, usDe.getMspaServiceProviderMode()); + Assertions.assertEquals(true, usDe.getGpc()); + } + + + @Test + public void testDecodeWithGpcSegmentExcluded() throws DecodingException { + UsDe usDe = new UsDe("BVWSSSSVY"); + + Assertions.assertEquals(1, usDe.getProcessingNotice()); + Assertions.assertEquals(1, usDe.getSaleOptOutNotice()); + Assertions.assertEquals(1, usDe.getTargetedAdvertisingOptOutNotice()); + Assertions.assertEquals(1, usDe.getSaleOptOut()); + Assertions.assertEquals(1, usDe.getTargetedAdvertisingOptOut()); + Assertions.assertEquals(Arrays.asList(2, 1, 0, 2, 1, 0, 2, 1, 0), usDe.getSensitiveDataProcessing()); + Assertions.assertEquals(Arrays.asList(2, 1, 0, 2, 1), usDe.getKnownChildSensitiveDataConsents()); + Assertions.assertEquals(1, usDe.getAdditionalDataProcessingConsent()); + Assertions.assertEquals(1, usDe.getMspaCoveredTransaction()); + Assertions.assertEquals(1, usDe.getMspaOptOutOptionMode()); + Assertions.assertEquals(2, usDe.getMspaServiceProviderMode()); + Assertions.assertEquals(false, usDe.getGpcSegmentIncluded()); + } + + @Test() + public void testDecodeGarbage() { + Assertions.assertThrows(DecodingException.class, () -> { + new UsDe("z").getProcessingNotice(); + }); + } +} diff --git a/iabgpp-encoder/src/test/java/com/iab/gpp/encoder/section/UsFlTest.java b/iabgpp-encoder/src/test/java/com/iab/gpp/encoder/section/UsFlTest.java new file mode 100644 index 00000000..3882d962 --- /dev/null +++ b/iabgpp-encoder/src/test/java/com/iab/gpp/encoder/section/UsFlTest.java @@ -0,0 +1,150 @@ +package com.iab.gpp.encoder.section; + + +import java.util.Arrays; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; +import com.iab.gpp.encoder.error.DecodingException; +import com.iab.gpp.encoder.error.EncodingException; +import com.iab.gpp.encoder.error.InvalidFieldException; +import com.iab.gpp.encoder.error.ValidationException; +import com.iab.gpp.encoder.field.UsFlField; + +public class UsFlTest { + + @Test + public void testEncode1() { + UsFl usFl = new UsFl(); + Assertions.assertEquals("BAAAAABA", usFl.encode()); + } + + @Test + public void testEncode2() { + UsFl usFl = new UsFl(); + + try { + usFl.setFieldValue(UsFlField.PROCESSING_NOTICE, 1); + usFl.setFieldValue(UsFlField.SALE_OPT_OUT_NOTICE, 1); + usFl.setFieldValue(UsFlField.TARGETED_ADVERTISING_OPT_OUT_NOTICE, 1); + usFl.setFieldValue(UsFlField.SALE_OPT_OUT, 1); + usFl.setFieldValue(UsFlField.TARGETED_ADVERTISING_OPT_OUT, 1); + usFl.setFieldValue(UsFlField.SENSITIVE_DATA_PROCESSING, Arrays.asList(2, 1, 0, 2, 1, 0, 2, 1)); + usFl.setFieldValue(UsFlField.KNOWN_CHILD_SENSITIVE_DATA_CONSENTS, Arrays.asList(2, 1, 2)); + usFl.setFieldValue(UsFlField.ADDITIONAL_DATA_PROCESSING_CONSENT, 1); + usFl.setFieldValue(UsFlField.MSPA_COVERED_TRANSACTION, 1); + usFl.setFieldValue(UsFlField.MSPA_OPT_OUT_OPTION_MODE, 1); + usFl.setFieldValue(UsFlField.MSPA_SERVICE_PROVIDER_MODE, 2); + } catch (InvalidFieldException e) { + throw new EncodingException(e); + } + + Assertions.assertEquals("BVWSSZlY", usFl.encode()); + } + + @Test + public void testSetInvalidValues() { + UsFl usFl = new UsFl(); + + try { + usFl.setFieldValue(UsFlField.PROCESSING_NOTICE, 3); + Assertions.fail("Expected ValidationException"); + } catch (ValidationException e) { + + } + + try { + usFl.setFieldValue(UsFlField.SALE_OPT_OUT_NOTICE, -1); + Assertions.fail("Expected ValidationException"); + } catch (ValidationException e) { + + } + + try { + usFl.setFieldValue(UsFlField.TARGETED_ADVERTISING_OPT_OUT_NOTICE, 4); + Assertions.fail("Expected ValidationException"); + } catch (ValidationException e) { + + } + + try { + usFl.setFieldValue(UsFlField.SALE_OPT_OUT, 3); + Assertions.fail("Expected ValidationException"); + } catch (ValidationException e) { + + } + + try { + usFl.setFieldValue(UsFlField.TARGETED_ADVERTISING_OPT_OUT, 3); + Assertions.fail("Expected ValidationException"); + } catch (ValidationException e) { + + } + + try { + usFl.setFieldValue(UsFlField.SENSITIVE_DATA_PROCESSING, Arrays.asList(0, 1, 2, 3, 1, 2, 0, 1)); + Assertions.fail("Expected ValidationException"); + } catch (ValidationException e) { + + } + + try { + usFl.setFieldValue(UsFlField.KNOWN_CHILD_SENSITIVE_DATA_CONSENTS, Arrays.asList(0, 3, 0)); + Assertions.fail("Expected ValidationException"); + } catch (ValidationException e) { + + } + + try { + usFl.setFieldValue(UsFlField.ADDITIONAL_DATA_PROCESSING_CONSENT, 3); + Assertions.fail("Expected ValidationException"); + } catch (ValidationException e) { + + } + + try { + usFl.setFieldValue(UsFlField.MSPA_COVERED_TRANSACTION, 0); + Assertions.fail("Expected ValidationException"); + } catch (ValidationException e) { + + } + + try { + usFl.setFieldValue(UsFlField.MSPA_OPT_OUT_OPTION_MODE, 3); + Assertions.fail("Expected ValidationException"); + } catch (ValidationException e) { + + } + + try { + usFl.setFieldValue(UsFlField.MSPA_SERVICE_PROVIDER_MODE, 3); + Assertions.fail("Expected ValidationException"); + } catch (ValidationException e) { + + } + + } + + @Test + public void testDecode1() throws DecodingException { + UsFl usFl = new UsFl("BVWSSZlY"); + + Assertions.assertEquals(1, usFl.getProcessingNotice()); + Assertions.assertEquals(1, usFl.getSaleOptOutNotice()); + Assertions.assertEquals(1, usFl.getTargetedAdvertisingOptOutNotice()); + Assertions.assertEquals(1, usFl.getSaleOptOut()); + Assertions.assertEquals(1, usFl.getTargetedAdvertisingOptOut()); + Assertions.assertEquals(Arrays.asList(2, 1, 0, 2, 1, 0, 2, 1), usFl.getSensitiveDataProcessing()); + Assertions.assertEquals(Arrays.asList(2, 1, 2), usFl.getKnownChildSensitiveDataConsents()); + Assertions.assertEquals(1, usFl.getAdditionalDataProcessingConsent()); + Assertions.assertEquals(1, usFl.getMspaCoveredTransaction()); + Assertions.assertEquals(1, usFl.getMspaOptOutOptionMode()); + Assertions.assertEquals(2, usFl.getMspaServiceProviderMode()); + } + + @Test() + public void testDecodeGarbage() { + Assertions.assertThrows(DecodingException.class, () -> { + new UsFl("z").getMspaCoveredTransaction(); + }); + } +} diff --git a/iabgpp-encoder/src/test/java/com/iab/gpp/encoder/section/UsIaTest.java b/iabgpp-encoder/src/test/java/com/iab/gpp/encoder/section/UsIaTest.java new file mode 100644 index 00000000..352b723a --- /dev/null +++ b/iabgpp-encoder/src/test/java/com/iab/gpp/encoder/section/UsIaTest.java @@ -0,0 +1,188 @@ +package com.iab.gpp.encoder.section; + + +import java.util.Arrays; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; +import com.iab.gpp.encoder.error.DecodingException; +import com.iab.gpp.encoder.error.ValidationException; +import com.iab.gpp.encoder.field.UsIaField; + +public class UsIaTest { + + @Test + public void testEncode1() { + UsIa usIa = new UsIa(); + Assertions.assertEquals("BAAAAAQ.Q", usIa.encode()); + } + + @Test + public void testEncode2() { + UsIa usIa = new UsIa(); + + usIa.setFieldValue(UsIaField.PROCESSING_NOTICE, 1); + usIa.setFieldValue(UsIaField.SALE_OPT_OUT_NOTICE, 1); + usIa.setFieldValue(UsIaField.TARGETED_ADVERTISING_OPT_OUT_NOTICE, 1); + usIa.setFieldValue(UsIaField.SENSITIVE_DATA_OPT_OUT_NOTICE, 1); + usIa.setFieldValue(UsIaField.SALE_OPT_OUT, 1); + usIa.setFieldValue(UsIaField.TARGETED_ADVERTISING_OPT_OUT, 1); + usIa.setFieldValue(UsIaField.SENSITIVE_DATA_PROCESSING, Arrays.asList(2, 1, 0, 2, 1, 0, 2, 1)); + usIa.setFieldValue(UsIaField.KNOWN_CHILD_SENSITIVE_DATA_CONSENTS, 1); + usIa.setFieldValue(UsIaField.MSPA_COVERED_TRANSACTION, 1); + usIa.setFieldValue(UsIaField.MSPA_OPT_OUT_OPTION_MODE, 1); + usIa.setFieldValue(UsIaField.MSPA_SERVICE_PROVIDER_MODE, 2); + usIa.setFieldValue(UsIaField.GPC, true); + + Assertions.assertEquals("BVVkklW.Y", usIa.encode()); + } + + @Test + public void testSetInvalidValues() { + UsIa usIa = new UsIa(); + + try { + usIa.setFieldValue(UsIaField.PROCESSING_NOTICE, 3); + Assertions.fail("Expected ValidationException"); + } catch (ValidationException e) { + + } + + try { + usIa.setFieldValue(UsIaField.SALE_OPT_OUT_NOTICE, 3); + Assertions.fail("Expected ValidationException"); + } catch (ValidationException e) { + + } + + try { + usIa.setFieldValue(UsIaField.TARGETED_ADVERTISING_OPT_OUT_NOTICE, 3); + Assertions.fail("Expected ValidationException"); + } catch (ValidationException e) { + + } + + try { + usIa.setFieldValue(UsIaField.SENSITIVE_DATA_OPT_OUT_NOTICE, 3); + Assertions.fail("Expected ValidationException"); + } catch (ValidationException e) { + + } + + try { + usIa.setFieldValue(UsIaField.SALE_OPT_OUT, 3); + Assertions.fail("Expected ValidationException"); + } catch (ValidationException e) { + + } + + try { + usIa.setFieldValue(UsIaField.TARGETED_ADVERTISING_OPT_OUT, -1); + Assertions.fail("Expected ValidationException"); + } catch (ValidationException e) { + + } + + try { + usIa.setFieldValue(UsIaField.SENSITIVE_DATA_PROCESSING, Arrays.asList(0, 1, 2, 3, 1, 2, 0, 1)); + Assertions.fail("Expected ValidationException"); + } catch (ValidationException e) { + + } + + try { + usIa.setFieldValue(UsIaField.KNOWN_CHILD_SENSITIVE_DATA_CONSENTS, 3); + Assertions.fail("Expected ValidationException"); + } catch (ValidationException e) { + + } + + try { + usIa.setFieldValue(UsIaField.MSPA_COVERED_TRANSACTION, 0); + Assertions.fail("Expected ValidationException"); + } catch (ValidationException e) { + + } + + try { + usIa.setFieldValue(UsIaField.MSPA_OPT_OUT_OPTION_MODE, 4); + Assertions.fail("Expected ValidationException"); + } catch (ValidationException e) { + + } + + try { + usIa.setFieldValue(UsIaField.MSPA_SERVICE_PROVIDER_MODE, -1); + Assertions.fail("Expected ValidationException"); + } catch (ValidationException e) { + + } + } + + @Test + public void testEncodeWithGpcSegmentExcluded() { + UsIa usIa = new UsIa(); + usIa.setFieldValue(UsIaField.GPC_SEGMENT_INCLUDED, false); + Assertions.assertEquals("BAAAAAQ", usIa.encode()); + } + + @Test + public void testDecode1() throws DecodingException { + UsIa usIa = new UsIa("BVVkklW.Y"); + + Assertions.assertEquals(1, usIa.getProcessingNotice()); + Assertions.assertEquals(1, usIa.getSaleOptOutNotice()); + Assertions.assertEquals(1, usIa.getTargetedAdvertisingOptOutNotice()); + Assertions.assertEquals(1, usIa.getSensitiveDataOptOutNotice()); + Assertions.assertEquals(1, usIa.getSaleOptOut()); + Assertions.assertEquals(1, usIa.getTargetedAdvertisingOptOut()); + Assertions.assertEquals(Arrays.asList(2, 1, 0, 2, 1, 0, 2, 1), usIa.getSensitiveDataProcessing()); + Assertions.assertEquals(1, usIa.getKnownChildSensitiveDataConsents()); + Assertions.assertEquals(1, usIa.getMspaCoveredTransaction()); + Assertions.assertEquals(1, usIa.getMspaOptOutOptionMode()); + Assertions.assertEquals(2, usIa.getMspaServiceProviderMode()); + Assertions.assertEquals(true, usIa.getGpc()); + } + + @Test + public void testDecode2() throws DecodingException { + UsIa usIa = new UsIa("BVVkklWA.YA"); + + Assertions.assertEquals(1, usIa.getProcessingNotice()); + Assertions.assertEquals(1, usIa.getSaleOptOutNotice()); + Assertions.assertEquals(1, usIa.getTargetedAdvertisingOptOutNotice()); + Assertions.assertEquals(1, usIa.getSensitiveDataOptOutNotice()); + Assertions.assertEquals(1, usIa.getSaleOptOut()); + Assertions.assertEquals(1, usIa.getTargetedAdvertisingOptOut()); + Assertions.assertEquals(Arrays.asList(2, 1, 0, 2, 1, 0, 2, 1), usIa.getSensitiveDataProcessing()); + Assertions.assertEquals(1, usIa.getKnownChildSensitiveDataConsents()); + Assertions.assertEquals(1, usIa.getMspaCoveredTransaction()); + Assertions.assertEquals(1, usIa.getMspaOptOutOptionMode()); + Assertions.assertEquals(2, usIa.getMspaServiceProviderMode()); + Assertions.assertEquals(true, usIa.getGpc()); + } + + @Test + public void testDecodeWithGpcSegmentExcluded() throws DecodingException { + UsIa usIa = new UsIa("BVVkklWA"); + + Assertions.assertEquals(1, usIa.getProcessingNotice()); + Assertions.assertEquals(1, usIa.getSaleOptOutNotice()); + Assertions.assertEquals(1, usIa.getTargetedAdvertisingOptOutNotice()); + Assertions.assertEquals(1, usIa.getSensitiveDataOptOutNotice()); + Assertions.assertEquals(1, usIa.getSaleOptOut()); + Assertions.assertEquals(1, usIa.getTargetedAdvertisingOptOut()); + Assertions.assertEquals(Arrays.asList(2, 1, 0, 2, 1, 0, 2, 1), usIa.getSensitiveDataProcessing()); + Assertions.assertEquals(1, usIa.getKnownChildSensitiveDataConsents()); + Assertions.assertEquals(1, usIa.getMspaCoveredTransaction()); + Assertions.assertEquals(1, usIa.getMspaOptOutOptionMode()); + Assertions.assertEquals(2, usIa.getMspaServiceProviderMode()); + Assertions.assertEquals(false, usIa.getGpcSegmentIncluded()); + } + + @Test() + public void testDecodeGarbage() { + Assertions.assertThrows(DecodingException.class, () -> { + new UsIa("z").getProcessingNotice(); + }); + } +} diff --git a/iabgpp-encoder/src/test/java/com/iab/gpp/encoder/section/UsMtTest.java b/iabgpp-encoder/src/test/java/com/iab/gpp/encoder/section/UsMtTest.java new file mode 100644 index 00000000..f407dc54 --- /dev/null +++ b/iabgpp-encoder/src/test/java/com/iab/gpp/encoder/section/UsMtTest.java @@ -0,0 +1,188 @@ +package com.iab.gpp.encoder.section; + + +import java.util.Arrays; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; +import com.iab.gpp.encoder.error.DecodingException; +import com.iab.gpp.encoder.error.ValidationException; +import com.iab.gpp.encoder.field.UsMtField; + +public class UsMtTest { + + @Test + public void testEncode1() { + UsMt usMt = new UsMt(); + Assertions.assertEquals("BAAAAABA.Q", usMt.encode()); + } + + @Test + public void testEncode2() { + UsMt usMt = new UsMt(); + + usMt.setFieldValue(UsMtField.SHARING_NOTICE, 1); + usMt.setFieldValue(UsMtField.SALE_OPT_OUT_NOTICE, 1); + usMt.setFieldValue(UsMtField.TARGETED_ADVERTISING_OPT_OUT_NOTICE, 1); + usMt.setFieldValue(UsMtField.SALE_OPT_OUT, 1); + usMt.setFieldValue(UsMtField.TARGETED_ADVERTISING_OPT_OUT, 1); + usMt.setFieldValue(UsMtField.SENSITIVE_DATA_PROCESSING, Arrays.asList(2, 1, 0, 2, 1, 0, 2, 1)); + usMt.setFieldValue(UsMtField.KNOWN_CHILD_SENSITIVE_DATA_CONSENTS, Arrays.asList(2, 1, 0)); + usMt.setFieldValue(UsMtField.ADDITIONAL_DATA_PROCESSING_CONSENT, 1); + usMt.setFieldValue(UsMtField.MSPA_COVERED_TRANSACTION, 1); + usMt.setFieldValue(UsMtField.MSPA_OPT_OUT_OPTION_MODE, 1); + usMt.setFieldValue(UsMtField.MSPA_SERVICE_PROVIDER_MODE, 2); + usMt.setFieldValue(UsMtField.GPC, true); + + Assertions.assertEquals("BVWSSZFY.Y", usMt.encode()); + } + + @Test + public void testSetInvalidValues() { + UsMt usMt = new UsMt(); + + try { + usMt.setFieldValue(UsMtField.SHARING_NOTICE, 3); + Assertions.fail("Expected ValidationException"); + } catch (ValidationException e) { + + } + + try { + usMt.setFieldValue(UsMtField.SALE_OPT_OUT_NOTICE, 3); + Assertions.fail("Expected ValidationException"); + } catch (ValidationException e) { + + } + + try { + usMt.setFieldValue(UsMtField.TARGETED_ADVERTISING_OPT_OUT_NOTICE, 3); + Assertions.fail("Expected ValidationException"); + } catch (ValidationException e) { + + } + + try { + usMt.setFieldValue(UsMtField.SALE_OPT_OUT, 3); + Assertions.fail("Expected ValidationException"); + } catch (ValidationException e) { + + } + + try { + usMt.setFieldValue(UsMtField.TARGETED_ADVERTISING_OPT_OUT, -1); + Assertions.fail("Expected ValidationException"); + } catch (ValidationException e) { + + } + + try { + usMt.setFieldValue(UsMtField.SENSITIVE_DATA_PROCESSING, Arrays.asList(0, 1, 2, 3, 1, 2, 0, 1)); + Assertions.fail("Expected ValidationException"); + } catch (ValidationException e) { + + } + + try { + usMt.setFieldValue(UsMtField.KNOWN_CHILD_SENSITIVE_DATA_CONSENTS, Arrays.asList(1, 2, 3)); + Assertions.fail("Expected ValidationException"); + } catch (ValidationException e) { + + } + + try { + usMt.setFieldValue(UsMtField.ADDITIONAL_DATA_PROCESSING_CONSENT, 3); + Assertions.fail("Expected ValidationException"); + } catch (ValidationException e) { + + } + + try { + usMt.setFieldValue(UsMtField.MSPA_COVERED_TRANSACTION, 0); + Assertions.fail("Expected ValidationException"); + } catch (ValidationException e) { + + } + + try { + usMt.setFieldValue(UsMtField.MSPA_OPT_OUT_OPTION_MODE, 4); + Assertions.fail("Expected ValidationException"); + } catch (ValidationException e) { + + } + + try { + usMt.setFieldValue(UsMtField.MSPA_SERVICE_PROVIDER_MODE, -1); + Assertions.fail("Expected ValidationException"); + } catch (ValidationException e) { + + } + } + + @Test + public void testEncodeWithGpcSegmentExcluded() { + UsMt usMt = new UsMt(); + usMt.setFieldValue(UsMtField.GPC_SEGMENT_INCLUDED, false); + Assertions.assertEquals("BAAAAABA", usMt.encode()); + } + + @Test + public void testDecode1() throws DecodingException { + UsMt usMt = new UsMt("BVWSSZFY.Y"); + + Assertions.assertEquals(1, usMt.getSharingNotice()); + Assertions.assertEquals(1, usMt.getSaleOptOutNotice()); + Assertions.assertEquals(1, usMt.getTargetedAdvertisingOptOutNotice()); + Assertions.assertEquals(1, usMt.getSaleOptOut()); + Assertions.assertEquals(1, usMt.getTargetedAdvertisingOptOut()); + Assertions.assertEquals(Arrays.asList(2, 1, 0, 2, 1, 0, 2, 1), usMt.getSensitiveDataProcessing()); + Assertions.assertEquals(Arrays.asList(2, 1, 0), usMt.getKnownChildSensitiveDataConsents()); + Assertions.assertEquals(1, usMt.getAdditionalDataProcessingConsent()); + Assertions.assertEquals(1, usMt.getMspaCoveredTransaction()); + Assertions.assertEquals(1, usMt.getMspaOptOutOptionMode()); + Assertions.assertEquals(2, usMt.getMspaServiceProviderMode()); + Assertions.assertEquals(true, usMt.getGpc()); + } + + @Test + public void testDecode2() throws DecodingException { + UsMt usMt = new UsMt("BVWSSZFY.YA"); + + Assertions.assertEquals(1, usMt.getSharingNotice()); + Assertions.assertEquals(1, usMt.getSaleOptOutNotice()); + Assertions.assertEquals(1, usMt.getTargetedAdvertisingOptOutNotice()); + Assertions.assertEquals(1, usMt.getSaleOptOut()); + Assertions.assertEquals(1, usMt.getTargetedAdvertisingOptOut()); + Assertions.assertEquals(Arrays.asList(2, 1, 0, 2, 1, 0, 2, 1), usMt.getSensitiveDataProcessing()); + Assertions.assertEquals(Arrays.asList(2, 1, 0), usMt.getKnownChildSensitiveDataConsents()); + Assertions.assertEquals(1, usMt.getAdditionalDataProcessingConsent()); + Assertions.assertEquals(1, usMt.getMspaCoveredTransaction()); + Assertions.assertEquals(1, usMt.getMspaOptOutOptionMode()); + Assertions.assertEquals(2, usMt.getMspaServiceProviderMode()); + Assertions.assertEquals(true, usMt.getGpc()); + } + + @Test + public void testDecodeWithGpcSegmentExcluded() throws DecodingException { + UsMt usMt = new UsMt("BVWSSZFY"); + + Assertions.assertEquals(1, usMt.getSharingNotice()); + Assertions.assertEquals(1, usMt.getSaleOptOutNotice()); + Assertions.assertEquals(1, usMt.getTargetedAdvertisingOptOutNotice()); + Assertions.assertEquals(1, usMt.getSaleOptOut()); + Assertions.assertEquals(1, usMt.getTargetedAdvertisingOptOut()); + Assertions.assertEquals(Arrays.asList(2, 1, 0, 2, 1, 0, 2, 1), usMt.getSensitiveDataProcessing()); + Assertions.assertEquals(Arrays.asList(2, 1, 0), usMt.getKnownChildSensitiveDataConsents()); + Assertions.assertEquals(1, usMt.getAdditionalDataProcessingConsent()); + Assertions.assertEquals(1, usMt.getMspaCoveredTransaction()); + Assertions.assertEquals(1, usMt.getMspaOptOutOptionMode()); + Assertions.assertEquals(2, usMt.getMspaServiceProviderMode()); + Assertions.assertEquals(false, usMt.getGpcSegmentIncluded()); + } + + @Test() + public void testDecodeGarbage() { + Assertions.assertThrows(DecodingException.class, () -> { + new UsMt("z").getSharingNotice(); + }); + } +} diff --git a/iabgpp-encoder/src/test/java/com/iab/gpp/encoder/section/UsNatTest.java b/iabgpp-encoder/src/test/java/com/iab/gpp/encoder/section/UsNatTest.java new file mode 100644 index 00000000..94991c66 --- /dev/null +++ b/iabgpp-encoder/src/test/java/com/iab/gpp/encoder/section/UsNatTest.java @@ -0,0 +1,260 @@ +package com.iab.gpp.encoder.section; + + +import java.util.Arrays; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; +import com.iab.gpp.encoder.error.DecodingException; +import com.iab.gpp.encoder.error.ValidationException; +import com.iab.gpp.encoder.field.UsNatField; + +public class UsNatTest { + + @Test + public void testEncode1() { + + UsNat usNat = new UsNat(); + Assertions.assertEquals("BAAAAAAAAABA.Q", usNat.encode()); + } + + @Test + public void testEncode2() { + UsNat usNat = new UsNat(); + + usNat.setFieldValue(UsNatField.SHARING_NOTICE, 1); + usNat.setFieldValue(UsNatField.SALE_OPT_OUT_NOTICE, 1); + usNat.setFieldValue(UsNatField.SHARING_OPT_OUT_NOTICE, 1); + usNat.setFieldValue(UsNatField.TARGETED_ADVERTISING_OPT_OUT_NOTICE, 1); + usNat.setFieldValue(UsNatField.SENSITIVE_DATA_PROCESSING_OPT_OUT_NOTICE, 1); + usNat.setFieldValue(UsNatField.SENSITIVE_DATA_LIMIT_USE_NOTICE, 1); + usNat.setFieldValue(UsNatField.SALE_OPT_OUT, 1); + usNat.setFieldValue(UsNatField.SHARING_OPT_OUT, 1); + usNat.setFieldValue(UsNatField.TARGETED_ADVERTISING_OPT_OUT, 1); + usNat.setFieldValue(UsNatField.SENSITIVE_DATA_PROCESSING, Arrays.asList(2, 1, 0, 2, 1, 0, 2, 1, 0, 2, 1, 0, 2, 1, 0, 2)); + usNat.setFieldValue(UsNatField.KNOWN_CHILD_SENSITIVE_DATA_CONSENTS, Arrays.asList(2, 1, 0)); + usNat.setFieldValue(UsNatField.PERSONAL_DATA_CONSENTS, 1); + usNat.setFieldValue(UsNatField.MSPA_COVERED_TRANSACTION, 1); + usNat.setFieldValue(UsNatField.MSPA_OPT_OUT_OPTION_MODE, 1); + usNat.setFieldValue(UsNatField.MSPA_SERVICE_PROVIDER_MODE, 2); + usNat.setFieldValue(UsNatField.GPC, true); + + Assertions.assertEquals("BVVVkkkkkpFY.Y", usNat.encode()); + } + + @Test + public void testSetInvalidValues() { + UsNat usNat = new UsNat(); + + try { + usNat.setFieldValue(UsNatField.SHARING_NOTICE, -1); + Assertions.fail("Expected ValidationException"); + } catch (ValidationException e) { + + } + + try { + usNat.setFieldValue(UsNatField.SALE_OPT_OUT_NOTICE, 3); + Assertions.fail("Expected ValidationException"); + } catch (ValidationException e) { + + } + + try { + usNat.setFieldValue(UsNatField.SHARING_OPT_OUT_NOTICE, 3); + Assertions.fail("Expected ValidationException"); + } catch (ValidationException e) { + + } + + try { + usNat.setFieldValue(UsNatField.TARGETED_ADVERTISING_OPT_OUT_NOTICE, 4); + Assertions.fail("Expected ValidationException"); + } catch (ValidationException e) { + + } + + try { + usNat.setFieldValue(UsNatField.SENSITIVE_DATA_PROCESSING_OPT_OUT_NOTICE, 3); + Assertions.fail("Expected ValidationException"); + } catch (ValidationException e) { + + } + + try { + usNat.setFieldValue(UsNatField.SENSITIVE_DATA_LIMIT_USE_NOTICE, 3); + Assertions.fail("Expected ValidationException"); + } catch (ValidationException e) { + + } + + try { + usNat.setFieldValue(UsNatField.SALE_OPT_OUT, 3); + Assertions.fail("Expected ValidationException"); + } catch (ValidationException e) { + + } + + try { + usNat.setFieldValue(UsNatField.SHARING_OPT_OUT, 3); + Assertions.fail("Expected ValidationException"); + } catch (ValidationException e) { + + } + + try { + usNat.setFieldValue(UsNatField.TARGETED_ADVERTISING_OPT_OUT, 3); + Assertions.fail("Expected ValidationException"); + } catch (ValidationException e) { + + } + + try { + usNat.setFieldValue(UsNatField.SENSITIVE_DATA_PROCESSING, Arrays.asList(0, 1, 2, 3, 0, 1, 2, 0, 0, 1, 2, 0)); + Assertions.fail("Expected ValidationException"); + } catch (ValidationException e) { + + } + + try { + usNat.setFieldValue(UsNatField.KNOWN_CHILD_SENSITIVE_DATA_CONSENTS, Arrays.asList(0, 3)); + Assertions.fail("Expected ValidationException"); + } catch (ValidationException e) { + + } + + try { + usNat.setFieldValue(UsNatField.PERSONAL_DATA_CONSENTS, 3); + Assertions.fail("Expected ValidationException"); + } catch (ValidationException e) { + + } + + try { + usNat.setFieldValue(UsNatField.MSPA_COVERED_TRANSACTION, 0); + Assertions.fail("Expected ValidationException"); + } catch (ValidationException e) { + + } + + try { + usNat.setFieldValue(UsNatField.MSPA_OPT_OUT_OPTION_MODE, 3); + Assertions.fail("Expected ValidationException"); + } catch (ValidationException e) { + + } + + try { + usNat.setFieldValue(UsNatField.MSPA_SERVICE_PROVIDER_MODE, 3); + Assertions.fail("Expected ValidationException"); + } catch (ValidationException e) { + + } + + + } + + @Test + public void testEncode3() { + UsNat usNat = new UsNat(); + + usNat.setFieldValue(UsNatField.SHARING_NOTICE, 1); + usNat.setFieldValue(UsNatField.SALE_OPT_OUT_NOTICE, 1); + usNat.setFieldValue(UsNatField.SHARING_OPT_OUT_NOTICE, 1); + usNat.setFieldValue(UsNatField.TARGETED_ADVERTISING_OPT_OUT_NOTICE, 1); + usNat.setFieldValue(UsNatField.SENSITIVE_DATA_PROCESSING_OPT_OUT_NOTICE, 1); + usNat.setFieldValue(UsNatField.SENSITIVE_DATA_LIMIT_USE_NOTICE, 1); + usNat.setFieldValue(UsNatField.SALE_OPT_OUT, 1); + usNat.setFieldValue(UsNatField.SHARING_OPT_OUT, 1); + usNat.setFieldValue(UsNatField.TARGETED_ADVERTISING_OPT_OUT, 1); + usNat.setFieldValue(UsNatField.SENSITIVE_DATA_PROCESSING, Arrays.asList(2, 1, 0, 2, 1, 0, 2, 1, 0, 2, 1, 0, 2, 1, 0, 2)); + usNat.setFieldValue(UsNatField.KNOWN_CHILD_SENSITIVE_DATA_CONSENTS, Arrays.asList(2, 1, 0)); + usNat.setFieldValue(UsNatField.PERSONAL_DATA_CONSENTS, 1); + usNat.setFieldValue(UsNatField.MSPA_COVERED_TRANSACTION, 1); + usNat.setFieldValue(UsNatField.MSPA_OPT_OUT_OPTION_MODE, 1); + usNat.setFieldValue(UsNatField.MSPA_SERVICE_PROVIDER_MODE, 2); + usNat.setFieldValue(UsNatField.GPC, true); + + Assertions.assertEquals("BVVVkkkkkpFY.Y", usNat.encode()); + } + + @Test + public void testEncodeWithGpcSegmentIncluded() { + + UsNat usNat = new UsNat(); + usNat.setFieldValue(UsNatField.GPC_SEGMENT_INCLUDED, false); + Assertions.assertEquals("BAAAAAAAAABA", usNat.encode()); + } + + @Test + public void testDecode1() throws DecodingException { + UsNat usNat = new UsNat("BVVVkkkkkpFY.Y"); + + Assertions.assertEquals(1, usNat.getSharingNotice()); + Assertions.assertEquals(1, usNat.getSaleOptOutNotice()); + Assertions.assertEquals(1, usNat.getSharingOptOutNotice()); + Assertions.assertEquals(1, usNat.getTargetedAdvertisingOptOutNotice()); + Assertions.assertEquals(1, usNat.getSensitiveDataProcessingOptOutNotice()); + Assertions.assertEquals(1, usNat.getSensitiveDataLimitUseNotice()); + Assertions.assertEquals(1, usNat.getSaleOptOut()); + Assertions.assertEquals(1, usNat.getSharingOptOut()); + Assertions.assertEquals(1, usNat.getTargetedAdvertisingOptOut()); + Assertions.assertEquals(Arrays.asList(2, 1, 0, 2, 1, 0, 2, 1, 0, 2, 1, 0, 2, 1, 0, 2), usNat.getSensitiveDataProcessing()); + Assertions.assertEquals(Arrays.asList(2, 1, 0), usNat.getKnownChildSensitiveDataConsents()); + Assertions.assertEquals(1, usNat.getPersonalDataConsents()); + Assertions.assertEquals(1, usNat.getMspaCoveredTransaction()); + Assertions.assertEquals(1, usNat.getMspaOptOutOptionMode()); + Assertions.assertEquals(2, usNat.getMspaServiceProviderMode()); + Assertions.assertEquals(true, usNat.getGpc()); + } + + @Test + public void testDecode2() throws DecodingException { + UsNat usNat = new UsNat("BVVVkkkkkpFY.YA"); + + Assertions.assertEquals(1, usNat.getSharingNotice()); + Assertions.assertEquals(1, usNat.getSaleOptOutNotice()); + Assertions.assertEquals(1, usNat.getSharingOptOutNotice()); + Assertions.assertEquals(1, usNat.getTargetedAdvertisingOptOutNotice()); + Assertions.assertEquals(1, usNat.getSensitiveDataProcessingOptOutNotice()); + Assertions.assertEquals(1, usNat.getSensitiveDataLimitUseNotice()); + Assertions.assertEquals(1, usNat.getSaleOptOut()); + Assertions.assertEquals(1, usNat.getSharingOptOut()); + Assertions.assertEquals(1, usNat.getTargetedAdvertisingOptOut()); + Assertions.assertEquals(Arrays.asList(2, 1, 0, 2, 1, 0, 2, 1, 0, 2, 1, 0, 2, 1, 0, 2), usNat.getSensitiveDataProcessing()); + Assertions.assertEquals(Arrays.asList(2, 1, 0), usNat.getKnownChildSensitiveDataConsents()); + Assertions.assertEquals(1, usNat.getPersonalDataConsents()); + Assertions.assertEquals(1, usNat.getMspaCoveredTransaction()); + Assertions.assertEquals(1, usNat.getMspaOptOutOptionMode()); + Assertions.assertEquals(2, usNat.getMspaServiceProviderMode()); + Assertions.assertEquals(true, usNat.getGpc()); + } + + @Test + public void testDecodeWithGpcSegmentExcluded() throws DecodingException { + UsNat usNat = new UsNat("BVVVkkkkkpFY"); + + Assertions.assertEquals(1, usNat.getSharingNotice()); + Assertions.assertEquals(1, usNat.getSaleOptOutNotice()); + Assertions.assertEquals(1, usNat.getSharingOptOutNotice()); + Assertions.assertEquals(1, usNat.getTargetedAdvertisingOptOutNotice()); + Assertions.assertEquals(1, usNat.getSensitiveDataProcessingOptOutNotice()); + Assertions.assertEquals(1, usNat.getSensitiveDataLimitUseNotice()); + Assertions.assertEquals(1, usNat.getSaleOptOut()); + Assertions.assertEquals(1, usNat.getSharingOptOut()); + Assertions.assertEquals(1, usNat.getTargetedAdvertisingOptOut()); + Assertions.assertEquals(Arrays.asList(2, 1, 0, 2, 1, 0, 2, 1, 0, 2, 1, 0, 2, 1, 0, 2), usNat.getSensitiveDataProcessing()); + Assertions.assertEquals(Arrays.asList(2, 1, 0), usNat.getKnownChildSensitiveDataConsents()); + Assertions.assertEquals(1, usNat.getPersonalDataConsents()); + Assertions.assertEquals(1, usNat.getMspaCoveredTransaction()); + Assertions.assertEquals(1, usNat.getMspaOptOutOptionMode()); + Assertions.assertEquals(2, usNat.getMspaServiceProviderMode()); + Assertions.assertEquals(false, usNat.getGpcSegmentIncluded()); + } + + @Test() + public void testDecodeGarbage() { + Assertions.assertThrows(DecodingException.class, () -> { + new UsNat("z").getSharingNotice(); + }); + } +} diff --git a/iabgpp-encoder/src/test/java/com/iab/gpp/encoder/section/UsNeTest.java b/iabgpp-encoder/src/test/java/com/iab/gpp/encoder/section/UsNeTest.java new file mode 100644 index 00000000..f3de1924 --- /dev/null +++ b/iabgpp-encoder/src/test/java/com/iab/gpp/encoder/section/UsNeTest.java @@ -0,0 +1,188 @@ +package com.iab.gpp.encoder.section; + + +import java.util.Arrays; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; +import com.iab.gpp.encoder.error.DecodingException; +import com.iab.gpp.encoder.error.ValidationException; +import com.iab.gpp.encoder.field.UsNeField; + +public class UsNeTest { + + @Test + public void testEncode1() { + UsNe usNe = new UsNe(); + Assertions.assertEquals("BAAAAAQ.Q", usNe.encode()); + } + + @Test + public void testEncode2() { + UsNe usNe = new UsNe(); + + usNe.setFieldValue(UsNeField.PROCESSING_NOTICE, 1); + usNe.setFieldValue(UsNeField.SALE_OPT_OUT_NOTICE, 1); + usNe.setFieldValue(UsNeField.TARGETED_ADVERTISING_OPT_OUT_NOTICE, 1); + usNe.setFieldValue(UsNeField.SALE_OPT_OUT, 1); + usNe.setFieldValue(UsNeField.TARGETED_ADVERTISING_OPT_OUT, 1); + usNe.setFieldValue(UsNeField.SENSITIVE_DATA_PROCESSING, Arrays.asList(2, 1, 0, 2, 1, 0, 2, 1)); + usNe.setFieldValue(UsNeField.KNOWN_CHILD_SENSITIVE_DATA_CONSENTS, 1); + usNe.setFieldValue(UsNeField.ADDITIONAL_DATA_PROCESSING_CONSENT, 1); + usNe.setFieldValue(UsNeField.MSPA_COVERED_TRANSACTION, 1); + usNe.setFieldValue(UsNeField.MSPA_OPT_OUT_OPTION_MODE, 1); + usNe.setFieldValue(UsNeField.MSPA_SERVICE_PROVIDER_MODE, 2); + usNe.setFieldValue(UsNeField.GPC, true); + + Assertions.assertEquals("BVWSSVW.Y", usNe.encode()); + } + + @Test + public void testSetInvalidValues() { + UsNe usNe = new UsNe(); + + try { + usNe.setFieldValue(UsNeField.PROCESSING_NOTICE, 3); + Assertions.fail("Expected ValidationException"); + } catch (ValidationException e) { + + } + + try { + usNe.setFieldValue(UsNeField.SALE_OPT_OUT_NOTICE, 3); + Assertions.fail("Expected ValidationException"); + } catch (ValidationException e) { + + } + + try { + usNe.setFieldValue(UsNeField.TARGETED_ADVERTISING_OPT_OUT_NOTICE, 3); + Assertions.fail("Expected ValidationException"); + } catch (ValidationException e) { + + } + + try { + usNe.setFieldValue(UsNeField.SALE_OPT_OUT, 3); + Assertions.fail("Expected ValidationException"); + } catch (ValidationException e) { + + } + + try { + usNe.setFieldValue(UsNeField.TARGETED_ADVERTISING_OPT_OUT, -1); + Assertions.fail("Expected ValidationException"); + } catch (ValidationException e) { + + } + + try { + usNe.setFieldValue(UsNeField.SENSITIVE_DATA_PROCESSING, Arrays.asList(0, 1, 2, 3, 1, 2, 0, 1)); + Assertions.fail("Expected ValidationException"); + } catch (ValidationException e) { + + } + + try { + usNe.setFieldValue(UsNeField.KNOWN_CHILD_SENSITIVE_DATA_CONSENTS, 3); + Assertions.fail("Expected ValidationException"); + } catch (ValidationException e) { + + } + + try { + usNe.setFieldValue(UsNeField.ADDITIONAL_DATA_PROCESSING_CONSENT, 3); + Assertions.fail("Expected ValidationException"); + } catch (ValidationException e) { + + } + + try { + usNe.setFieldValue(UsNeField.MSPA_COVERED_TRANSACTION, 0); + Assertions.fail("Expected ValidationException"); + } catch (ValidationException e) { + + } + + try { + usNe.setFieldValue(UsNeField.MSPA_OPT_OUT_OPTION_MODE, 4); + Assertions.fail("Expected ValidationException"); + } catch (ValidationException e) { + + } + + try { + usNe.setFieldValue(UsNeField.MSPA_SERVICE_PROVIDER_MODE, -1); + Assertions.fail("Expected ValidationException"); + } catch (ValidationException e) { + + } + } + + @Test + public void testEncodeWithGpcSegmentExcluded() { + UsNe usNe = new UsNe(); + usNe.setFieldValue(UsNeField.GPC_SEGMENT_INCLUDED, false); + Assertions.assertEquals("BAAAAAQ", usNe.encode()); + } + + @Test + public void testDecode1() throws DecodingException { + UsNe usNe = new UsNe("BVWSSVWA.YA"); + + Assertions.assertEquals(1, usNe.getProcessingNotice()); + Assertions.assertEquals(1, usNe.getSaleOptOutNotice()); + Assertions.assertEquals(1, usNe.getTargetedAdvertisingOptOutNotice()); + Assertions.assertEquals(1, usNe.getSaleOptOut()); + Assertions.assertEquals(1, usNe.getTargetedAdvertisingOptOut()); + Assertions.assertEquals(Arrays.asList(2, 1, 0, 2, 1, 0, 2, 1), usNe.getSensitiveDataProcessing()); + Assertions.assertEquals(1, usNe.getKnownChildSensitiveDataConsents()); + Assertions.assertEquals(1, usNe.getAdditionalDataProcessingConsent()); + Assertions.assertEquals(1, usNe.getMspaCoveredTransaction()); + Assertions.assertEquals(1, usNe.getMspaOptOutOptionMode()); + Assertions.assertEquals(2, usNe.getMspaServiceProviderMode()); + Assertions.assertEquals(true, usNe.getGpc()); + } + + @Test + public void testDecode2() throws DecodingException { + UsNe usNe = new UsNe("BVWSSVW.Y"); + + Assertions.assertEquals(1, usNe.getProcessingNotice()); + Assertions.assertEquals(1, usNe.getSaleOptOutNotice()); + Assertions.assertEquals(1, usNe.getTargetedAdvertisingOptOutNotice()); + Assertions.assertEquals(1, usNe.getSaleOptOut()); + Assertions.assertEquals(1, usNe.getTargetedAdvertisingOptOut()); + Assertions.assertEquals(Arrays.asList(2, 1, 0, 2, 1, 0, 2, 1), usNe.getSensitiveDataProcessing()); + Assertions.assertEquals(1, usNe.getKnownChildSensitiveDataConsents()); + Assertions.assertEquals(1, usNe.getAdditionalDataProcessingConsent()); + Assertions.assertEquals(1, usNe.getMspaCoveredTransaction()); + Assertions.assertEquals(1, usNe.getMspaOptOutOptionMode()); + Assertions.assertEquals(2, usNe.getMspaServiceProviderMode()); + Assertions.assertEquals(true, usNe.getGpc()); + } + + @Test + public void testDecodeWithGpcSegmentExcluded() throws DecodingException { + UsNe usNe = new UsNe("BVWSSVW"); + + Assertions.assertEquals(1, usNe.getProcessingNotice()); + Assertions.assertEquals(1, usNe.getSaleOptOutNotice()); + Assertions.assertEquals(1, usNe.getTargetedAdvertisingOptOutNotice()); + Assertions.assertEquals(1, usNe.getSaleOptOut()); + Assertions.assertEquals(1, usNe.getTargetedAdvertisingOptOut()); + Assertions.assertEquals(Arrays.asList(2, 1, 0, 2, 1, 0, 2, 1), usNe.getSensitiveDataProcessing()); + Assertions.assertEquals(1, usNe.getKnownChildSensitiveDataConsents()); + Assertions.assertEquals(1, usNe.getAdditionalDataProcessingConsent()); + Assertions.assertEquals(1, usNe.getMspaCoveredTransaction()); + Assertions.assertEquals(1, usNe.getMspaOptOutOptionMode()); + Assertions.assertEquals(2, usNe.getMspaServiceProviderMode()); + Assertions.assertEquals(false, usNe.getGpcSegmentIncluded()); + } + + @Test() + public void testDecodeGarbage() { + Assertions.assertThrows(DecodingException.class, () -> { + new UsNe("z").getProcessingNotice(); + }); + } +} diff --git a/iabgpp-encoder/src/test/java/com/iab/gpp/encoder/section/UsNhTest.java b/iabgpp-encoder/src/test/java/com/iab/gpp/encoder/section/UsNhTest.java new file mode 100644 index 00000000..5eef593d --- /dev/null +++ b/iabgpp-encoder/src/test/java/com/iab/gpp/encoder/section/UsNhTest.java @@ -0,0 +1,188 @@ +package com.iab.gpp.encoder.section; + + +import java.util.Arrays; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; +import com.iab.gpp.encoder.error.DecodingException; +import com.iab.gpp.encoder.error.ValidationException; +import com.iab.gpp.encoder.field.UsNhField; + +public class UsNhTest { + + @Test + public void testEncode1() { + UsNh usNh = new UsNh(); + Assertions.assertEquals("BAAAAABA.Q", usNh.encode()); + } + + @Test + public void testEncode2() { + UsNh usNh = new UsNh(); + + usNh.setFieldValue(UsNhField.PROCESSING_NOTICE, 1); + usNh.setFieldValue(UsNhField.SALE_OPT_OUT_NOTICE, 1); + usNh.setFieldValue(UsNhField.TARGETED_ADVERTISING_OPT_OUT_NOTICE, 1); + usNh.setFieldValue(UsNhField.SALE_OPT_OUT, 1); + usNh.setFieldValue(UsNhField.TARGETED_ADVERTISING_OPT_OUT, 1); + usNh.setFieldValue(UsNhField.SENSITIVE_DATA_PROCESSING, Arrays.asList(2, 1, 0, 2, 1, 0, 2, 1)); + usNh.setFieldValue(UsNhField.KNOWN_CHILD_SENSITIVE_DATA_CONSENTS, Arrays.asList(2, 1, 0)); + usNh.setFieldValue(UsNhField.ADDITIONAL_DATA_PROCESSING_CONSENT, 1); + usNh.setFieldValue(UsNhField.MSPA_COVERED_TRANSACTION, 1); + usNh.setFieldValue(UsNhField.MSPA_OPT_OUT_OPTION_MODE, 1); + usNh.setFieldValue(UsNhField.MSPA_SERVICE_PROVIDER_MODE, 2); + usNh.setFieldValue(UsNhField.GPC, true); + + Assertions.assertEquals("BVWSSZFY.Y", usNh.encode()); + } + + @Test + public void testSetInvalidValues() { + UsNh usNh = new UsNh(); + + try { + usNh.setFieldValue(UsNhField.PROCESSING_NOTICE, 3); + Assertions.fail("Expected ValidationException"); + } catch (ValidationException e) { + + } + + try { + usNh.setFieldValue(UsNhField.SALE_OPT_OUT_NOTICE, 3); + Assertions.fail("Expected ValidationException"); + } catch (ValidationException e) { + + } + + try { + usNh.setFieldValue(UsNhField.TARGETED_ADVERTISING_OPT_OUT_NOTICE, 3); + Assertions.fail("Expected ValidationException"); + } catch (ValidationException e) { + + } + + try { + usNh.setFieldValue(UsNhField.SALE_OPT_OUT, 3); + Assertions.fail("Expected ValidationException"); + } catch (ValidationException e) { + + } + + try { + usNh.setFieldValue(UsNhField.TARGETED_ADVERTISING_OPT_OUT, -1); + Assertions.fail("Expected ValidationException"); + } catch (ValidationException e) { + + } + + try { + usNh.setFieldValue(UsNhField.SENSITIVE_DATA_PROCESSING, Arrays.asList(0, 1, 2, 3, 1, 2, 0, 1)); + Assertions.fail("Expected ValidationException"); + } catch (ValidationException e) { + + } + + try { + usNh.setFieldValue(UsNhField.KNOWN_CHILD_SENSITIVE_DATA_CONSENTS, Arrays.asList(1, 2, 3)); + Assertions.fail("Expected ValidationException"); + } catch (ValidationException e) { + + } + + try { + usNh.setFieldValue(UsNhField.ADDITIONAL_DATA_PROCESSING_CONSENT, 3); + Assertions.fail("Expected ValidationException"); + } catch (ValidationException e) { + + } + + try { + usNh.setFieldValue(UsNhField.MSPA_COVERED_TRANSACTION, 0); + Assertions.fail("Expected ValidationException"); + } catch (ValidationException e) { + + } + + try { + usNh.setFieldValue(UsNhField.MSPA_OPT_OUT_OPTION_MODE, 4); + Assertions.fail("Expected ValidationException"); + } catch (ValidationException e) { + + } + + try { + usNh.setFieldValue(UsNhField.MSPA_SERVICE_PROVIDER_MODE, -1); + Assertions.fail("Expected ValidationException"); + } catch (ValidationException e) { + + } + } + + @Test + public void testEncodeWithGpcSegmentExcluded() { + UsNh usNh = new UsNh(); + usNh.setFieldValue(UsNhField.GPC_SEGMENT_INCLUDED, false); + Assertions.assertEquals("BAAAAABA", usNh.encode()); + } + + @Test + public void testDecode1() throws DecodingException { + UsNh usNh = new UsNh("BVWSSZFY.Y"); + + Assertions.assertEquals(1, usNh.getProcessingNotice()); + Assertions.assertEquals(1, usNh.getSaleOptOutNotice()); + Assertions.assertEquals(1, usNh.getTargetedAdvertisingOptOutNotice()); + Assertions.assertEquals(1, usNh.getSaleOptOut()); + Assertions.assertEquals(1, usNh.getTargetedAdvertisingOptOut()); + Assertions.assertEquals(Arrays.asList(2, 1, 0, 2, 1, 0, 2, 1), usNh.getSensitiveDataProcessing()); + Assertions.assertEquals(Arrays.asList(2, 1, 0), usNh.getKnownChildSensitiveDataConsents()); + Assertions.assertEquals(1, usNh.getAdditionalDataProcessingConsent()); + Assertions.assertEquals(1, usNh.getMspaCoveredTransaction()); + Assertions.assertEquals(1, usNh.getMspaOptOutOptionMode()); + Assertions.assertEquals(2, usNh.getMspaServiceProviderMode()); + Assertions.assertEquals(true, usNh.getGpc()); + } + + @Test + public void testDecode2() throws DecodingException { + UsNh usNh = new UsNh("BVWSSZFY.YA"); + + Assertions.assertEquals(1, usNh.getProcessingNotice()); + Assertions.assertEquals(1, usNh.getSaleOptOutNotice()); + Assertions.assertEquals(1, usNh.getTargetedAdvertisingOptOutNotice()); + Assertions.assertEquals(1, usNh.getSaleOptOut()); + Assertions.assertEquals(1, usNh.getTargetedAdvertisingOptOut()); + Assertions.assertEquals(Arrays.asList(2, 1, 0, 2, 1, 0, 2, 1), usNh.getSensitiveDataProcessing()); + Assertions.assertEquals(Arrays.asList(2, 1, 0), usNh.getKnownChildSensitiveDataConsents()); + Assertions.assertEquals(1, usNh.getAdditionalDataProcessingConsent()); + Assertions.assertEquals(1, usNh.getMspaCoveredTransaction()); + Assertions.assertEquals(1, usNh.getMspaOptOutOptionMode()); + Assertions.assertEquals(2, usNh.getMspaServiceProviderMode()); + Assertions.assertEquals(true, usNh.getGpc()); + } + + @Test + public void testDecodeWithGpcSegmentExcluded() throws DecodingException { + UsNh usNh = new UsNh("BVWSSZFY"); + + Assertions.assertEquals(1, usNh.getProcessingNotice()); + Assertions.assertEquals(1, usNh.getSaleOptOutNotice()); + Assertions.assertEquals(1, usNh.getTargetedAdvertisingOptOutNotice()); + Assertions.assertEquals(1, usNh.getSaleOptOut()); + Assertions.assertEquals(1, usNh.getTargetedAdvertisingOptOut()); + Assertions.assertEquals(Arrays.asList(2, 1, 0, 2, 1, 0, 2, 1), usNh.getSensitiveDataProcessing()); + Assertions.assertEquals(Arrays.asList(2, 1, 0), usNh.getKnownChildSensitiveDataConsents()); + Assertions.assertEquals(1, usNh.getAdditionalDataProcessingConsent()); + Assertions.assertEquals(1, usNh.getMspaCoveredTransaction()); + Assertions.assertEquals(1, usNh.getMspaOptOutOptionMode()); + Assertions.assertEquals(2, usNh.getMspaServiceProviderMode()); + Assertions.assertEquals(false, usNh.getGpcSegmentIncluded()); + } + + @Test() + public void testDecodeGarbage() { + Assertions.assertThrows(DecodingException.class, () -> { + new UsNh("z").getProcessingNotice(); + }); + } +} diff --git a/iabgpp-encoder/src/test/java/com/iab/gpp/encoder/section/UsNjTest.java b/iabgpp-encoder/src/test/java/com/iab/gpp/encoder/section/UsNjTest.java new file mode 100644 index 00000000..835b92d3 --- /dev/null +++ b/iabgpp-encoder/src/test/java/com/iab/gpp/encoder/section/UsNjTest.java @@ -0,0 +1,188 @@ +package com.iab.gpp.encoder.section; + + +import java.util.Arrays; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; +import com.iab.gpp.encoder.error.DecodingException; +import com.iab.gpp.encoder.error.ValidationException; +import com.iab.gpp.encoder.field.UsNjField; + +public class UsNjTest { + + @Test + public void testEncode1() { + UsNj usNj = new UsNj(); + Assertions.assertEquals("BAAAAAAAQ.Q", usNj.encode()); + } + + @Test + public void testEncode2() { + UsNj usNj = new UsNj(); + + usNj.setFieldValue(UsNjField.PROCESSING_NOTICE, 1); + usNj.setFieldValue(UsNjField.SALE_OPT_OUT_NOTICE, 1); + usNj.setFieldValue(UsNjField.TARGETED_ADVERTISING_OPT_OUT_NOTICE, 1); + usNj.setFieldValue(UsNjField.SALE_OPT_OUT, 1); + usNj.setFieldValue(UsNjField.TARGETED_ADVERTISING_OPT_OUT, 1); + usNj.setFieldValue(UsNjField.SENSITIVE_DATA_PROCESSING, Arrays.asList(2, 1, 0, 2, 1, 0, 2, 1, 0, 1)); + usNj.setFieldValue(UsNjField.KNOWN_CHILD_SENSITIVE_DATA_CONSENTS, Arrays.asList(2, 1, 0, 2, 1)); + usNj.setFieldValue(UsNjField.ADDITIONAL_DATA_PROCESSING_CONSENT, 1); + usNj.setFieldValue(UsNjField.MSPA_COVERED_TRANSACTION, 1); + usNj.setFieldValue(UsNjField.MSPA_OPT_OUT_OPTION_MODE, 1); + usNj.setFieldValue(UsNjField.MSPA_SERVICE_PROVIDER_MODE, 2); + usNj.setFieldValue(UsNjField.GPC, true); + + Assertions.assertEquals("BVWSSRklW.Y", usNj.encode()); + } + + @Test + public void testSetInvalidValues() { + UsNj usNj = new UsNj(); + + try { + usNj.setFieldValue(UsNjField.PROCESSING_NOTICE, 3); + Assertions.fail("Expected ValidationException"); + } catch (ValidationException e) { + + } + + try { + usNj.setFieldValue(UsNjField.SALE_OPT_OUT_NOTICE, 3); + Assertions.fail("Expected ValidationException"); + } catch (ValidationException e) { + + } + + try { + usNj.setFieldValue(UsNjField.TARGETED_ADVERTISING_OPT_OUT_NOTICE, 3); + Assertions.fail("Expected ValidationException"); + } catch (ValidationException e) { + + } + + try { + usNj.setFieldValue(UsNjField.SALE_OPT_OUT, 3); + Assertions.fail("Expected ValidationException"); + } catch (ValidationException e) { + + } + + try { + usNj.setFieldValue(UsNjField.TARGETED_ADVERTISING_OPT_OUT, -1); + Assertions.fail("Expected ValidationException"); + } catch (ValidationException e) { + + } + + try { + usNj.setFieldValue(UsNjField.SENSITIVE_DATA_PROCESSING, Arrays.asList(0, 1, 2, 3, 1, 2, 0, 1)); + Assertions.fail("Expected ValidationException"); + } catch (ValidationException e) { + + } + + try { + usNj.setFieldValue(UsNjField.KNOWN_CHILD_SENSITIVE_DATA_CONSENTS, Arrays.asList(1, 2, 3)); + Assertions.fail("Expected ValidationException"); + } catch (ValidationException e) { + + } + + try { + usNj.setFieldValue(UsNjField.ADDITIONAL_DATA_PROCESSING_CONSENT, 3); + Assertions.fail("Expected ValidationException"); + } catch (ValidationException e) { + + } + + try { + usNj.setFieldValue(UsNjField.MSPA_COVERED_TRANSACTION, 0); + Assertions.fail("Expected ValidationException"); + } catch (ValidationException e) { + + } + + try { + usNj.setFieldValue(UsNjField.MSPA_OPT_OUT_OPTION_MODE, 4); + Assertions.fail("Expected ValidationException"); + } catch (ValidationException e) { + + } + + try { + usNj.setFieldValue(UsNjField.MSPA_SERVICE_PROVIDER_MODE, -1); + Assertions.fail("Expected ValidationException"); + } catch (ValidationException e) { + + } + } + + @Test + public void testEncodeWithGpcSegmentExcluded() { + UsNj usNj = new UsNj(); + usNj.setFieldValue(UsNjField.GPC_SEGMENT_INCLUDED, false); + Assertions.assertEquals("BAAAAAAAQ", usNj.encode()); + } + + @Test + public void testDecode1() throws DecodingException { + UsNj usNj = new UsNj("BVWSSRklW.Y"); + + Assertions.assertEquals(1, usNj.getProcessingNotice()); + Assertions.assertEquals(1, usNj.getSaleOptOutNotice()); + Assertions.assertEquals(1, usNj.getTargetedAdvertisingOptOutNotice()); + Assertions.assertEquals(1, usNj.getSaleOptOut()); + Assertions.assertEquals(1, usNj.getTargetedAdvertisingOptOut()); + Assertions.assertEquals(Arrays.asList(2, 1, 0, 2, 1, 0, 2, 1, 0, 1), usNj.getSensitiveDataProcessing()); + Assertions.assertEquals(Arrays.asList(2, 1, 0, 2, 1), usNj.getKnownChildSensitiveDataConsents()); + Assertions.assertEquals(1, usNj.getAdditionalDataProcessingConsent()); + Assertions.assertEquals(1, usNj.getMspaCoveredTransaction()); + Assertions.assertEquals(1, usNj.getMspaOptOutOptionMode()); + Assertions.assertEquals(2, usNj.getMspaServiceProviderMode()); + Assertions.assertEquals(true, usNj.getGpc()); + } + + @Test + public void testDecode2() throws DecodingException { + UsNj usNj = new UsNj("BVWSSRklWA.YA"); + + Assertions.assertEquals(1, usNj.getProcessingNotice()); + Assertions.assertEquals(1, usNj.getSaleOptOutNotice()); + Assertions.assertEquals(1, usNj.getTargetedAdvertisingOptOutNotice()); + Assertions.assertEquals(1, usNj.getSaleOptOut()); + Assertions.assertEquals(1, usNj.getTargetedAdvertisingOptOut()); + Assertions.assertEquals(Arrays.asList(2, 1, 0, 2, 1, 0, 2, 1, 0, 1), usNj.getSensitiveDataProcessing()); + Assertions.assertEquals(Arrays.asList(2, 1, 0, 2, 1), usNj.getKnownChildSensitiveDataConsents()); + Assertions.assertEquals(1, usNj.getAdditionalDataProcessingConsent()); + Assertions.assertEquals(1, usNj.getMspaCoveredTransaction()); + Assertions.assertEquals(1, usNj.getMspaOptOutOptionMode()); + Assertions.assertEquals(2, usNj.getMspaServiceProviderMode()); + Assertions.assertEquals(true, usNj.getGpc()); + } + + @Test + public void testDecodeWithGpcSegmentExcluded() throws DecodingException { + UsNj usNj = new UsNj("BVWSSRklW"); + + Assertions.assertEquals(1, usNj.getProcessingNotice()); + Assertions.assertEquals(1, usNj.getSaleOptOutNotice()); + Assertions.assertEquals(1, usNj.getTargetedAdvertisingOptOutNotice()); + Assertions.assertEquals(1, usNj.getSaleOptOut()); + Assertions.assertEquals(1, usNj.getTargetedAdvertisingOptOut()); + Assertions.assertEquals(Arrays.asList(2, 1, 0, 2, 1, 0, 2, 1, 0, 1), usNj.getSensitiveDataProcessing()); + Assertions.assertEquals(Arrays.asList(2, 1, 0, 2, 1), usNj.getKnownChildSensitiveDataConsents()); + Assertions.assertEquals(1, usNj.getAdditionalDataProcessingConsent()); + Assertions.assertEquals(1, usNj.getMspaCoveredTransaction()); + Assertions.assertEquals(1, usNj.getMspaOptOutOptionMode()); + Assertions.assertEquals(2, usNj.getMspaServiceProviderMode()); + Assertions.assertEquals(false, usNj.getGpcSegmentIncluded()); + } + + @Test() + public void testDecodeGarbage() { + Assertions.assertThrows(DecodingException.class, () -> { + new UsNj("z").getProcessingNotice(); + }); + } +} diff --git a/iabgpp-encoder/src/test/java/com/iab/gpp/encoder/section/UsOrTest.java b/iabgpp-encoder/src/test/java/com/iab/gpp/encoder/section/UsOrTest.java new file mode 100644 index 00000000..2149d23a --- /dev/null +++ b/iabgpp-encoder/src/test/java/com/iab/gpp/encoder/section/UsOrTest.java @@ -0,0 +1,188 @@ +package com.iab.gpp.encoder.section; + + +import java.util.Arrays; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; +import com.iab.gpp.encoder.error.DecodingException; +import com.iab.gpp.encoder.error.ValidationException; +import com.iab.gpp.encoder.field.UsOrField; + +public class UsOrTest { + + @Test + public void testEncode1() { + UsOr usOr = new UsOr(); + Assertions.assertEquals("BAAAAAABA.Q", usOr.encode()); + } + + @Test + public void testEncode2() { + UsOr usOr = new UsOr(); + + usOr.setFieldValue(UsOrField.PROCESSING_NOTICE, 1); + usOr.setFieldValue(UsOrField.SALE_OPT_OUT_NOTICE, 1); + usOr.setFieldValue(UsOrField.TARGETED_ADVERTISING_OPT_OUT_NOTICE, 1); + usOr.setFieldValue(UsOrField.SALE_OPT_OUT, 1); + usOr.setFieldValue(UsOrField.TARGETED_ADVERTISING_OPT_OUT, 1); + usOr.setFieldValue(UsOrField.SENSITIVE_DATA_PROCESSING, Arrays.asList(2, 1, 0, 2, 1, 0, 2, 1, 0, 1, 2)); + usOr.setFieldValue(UsOrField.KNOWN_CHILD_SENSITIVE_DATA_CONSENTS, Arrays.asList(2, 1, 0)); + usOr.setFieldValue(UsOrField.ADDITIONAL_DATA_PROCESSING_CONSENT, 1); + usOr.setFieldValue(UsOrField.MSPA_COVERED_TRANSACTION, 1); + usOr.setFieldValue(UsOrField.MSPA_OPT_OUT_OPTION_MODE, 1); + usOr.setFieldValue(UsOrField.MSPA_SERVICE_PROVIDER_MODE, 2); + usOr.setFieldValue(UsOrField.GPC, true); + + Assertions.assertEquals("BVWSSRpFY.Y", usOr.encode()); + } + + @Test + public void testSetInvalidValues() { + UsOr usOr = new UsOr(); + + try { + usOr.setFieldValue(UsOrField.PROCESSING_NOTICE, 3); + Assertions.fail("Expected ValidationException"); + } catch (ValidationException e) { + + } + + try { + usOr.setFieldValue(UsOrField.SALE_OPT_OUT_NOTICE, 3); + Assertions.fail("Expected ValidationException"); + } catch (ValidationException e) { + + } + + try { + usOr.setFieldValue(UsOrField.TARGETED_ADVERTISING_OPT_OUT_NOTICE, 3); + Assertions.fail("Expected ValidationException"); + } catch (ValidationException e) { + + } + + try { + usOr.setFieldValue(UsOrField.SALE_OPT_OUT, 3); + Assertions.fail("Expected ValidationException"); + } catch (ValidationException e) { + + } + + try { + usOr.setFieldValue(UsOrField.TARGETED_ADVERTISING_OPT_OUT, -1); + Assertions.fail("Expected ValidationException"); + } catch (ValidationException e) { + + } + + try { + usOr.setFieldValue(UsOrField.SENSITIVE_DATA_PROCESSING, Arrays.asList(0, 1, 2, 3, 1, 2, 0, 1)); + Assertions.fail("Expected ValidationException"); + } catch (ValidationException e) { + + } + + try { + usOr.setFieldValue(UsOrField.KNOWN_CHILD_SENSITIVE_DATA_CONSENTS, Arrays.asList(1, 2, 3)); + Assertions.fail("Expected ValidationException"); + } catch (ValidationException e) { + + } + + try { + usOr.setFieldValue(UsOrField.ADDITIONAL_DATA_PROCESSING_CONSENT, 3); + Assertions.fail("Expected ValidationException"); + } catch (ValidationException e) { + + } + + try { + usOr.setFieldValue(UsOrField.MSPA_COVERED_TRANSACTION, 0); + Assertions.fail("Expected ValidationException"); + } catch (ValidationException e) { + + } + + try { + usOr.setFieldValue(UsOrField.MSPA_OPT_OUT_OPTION_MODE, 4); + Assertions.fail("Expected ValidationException"); + } catch (ValidationException e) { + + } + + try { + usOr.setFieldValue(UsOrField.MSPA_SERVICE_PROVIDER_MODE, -1); + Assertions.fail("Expected ValidationException"); + } catch (ValidationException e) { + + } + } + + @Test + public void testEncodeWithGpcSegmentExcluded() { + UsOr usOr = new UsOr(); + usOr.setFieldValue(UsOrField.GPC_SEGMENT_INCLUDED, false); + Assertions.assertEquals("BAAAAAABA", usOr.encode()); + } + + @Test + public void testDecode1() throws DecodingException { + UsOr usOr = new UsOr("BVWSSRpFY.Y"); + + Assertions.assertEquals(1, usOr.getProcessingNotice()); + Assertions.assertEquals(1, usOr.getSaleOptOutNotice()); + Assertions.assertEquals(1, usOr.getTargetedAdvertisingOptOutNotice()); + Assertions.assertEquals(1, usOr.getSaleOptOut()); + Assertions.assertEquals(1, usOr.getTargetedAdvertisingOptOut()); + Assertions.assertEquals(Arrays.asList(2, 1, 0, 2, 1, 0, 2, 1, 0, 1, 2), usOr.getSensitiveDataProcessing()); + Assertions.assertEquals(Arrays.asList(2, 1, 0), usOr.getKnownChildSensitiveDataConsents()); + Assertions.assertEquals(1, usOr.getAdditionalDataProcessingConsent()); + Assertions.assertEquals(1, usOr.getMspaCoveredTransaction()); + Assertions.assertEquals(1, usOr.getMspaOptOutOptionMode()); + Assertions.assertEquals(2, usOr.getMspaServiceProviderMode()); + Assertions.assertEquals(true, usOr.getGpc()); + } + + @Test + public void testDecode2() throws DecodingException { + UsOr usOr = new UsOr("BVWSSRpFYA.YA"); + + Assertions.assertEquals(1, usOr.getProcessingNotice()); + Assertions.assertEquals(1, usOr.getSaleOptOutNotice()); + Assertions.assertEquals(1, usOr.getTargetedAdvertisingOptOutNotice()); + Assertions.assertEquals(1, usOr.getSaleOptOut()); + Assertions.assertEquals(1, usOr.getTargetedAdvertisingOptOut()); + Assertions.assertEquals(Arrays.asList(2, 1, 0, 2, 1, 0, 2, 1, 0, 1, 2), usOr.getSensitiveDataProcessing()); + Assertions.assertEquals(Arrays.asList(2, 1, 0), usOr.getKnownChildSensitiveDataConsents()); + Assertions.assertEquals(1, usOr.getAdditionalDataProcessingConsent()); + Assertions.assertEquals(1, usOr.getMspaCoveredTransaction()); + Assertions.assertEquals(1, usOr.getMspaOptOutOptionMode()); + Assertions.assertEquals(2, usOr.getMspaServiceProviderMode()); + Assertions.assertEquals(true, usOr.getGpc()); + } + + @Test + public void testDecodeWithGpcSegmentExcluded() throws DecodingException { + UsOr usOr = new UsOr("BVWSSRpFY"); + + Assertions.assertEquals(1, usOr.getProcessingNotice()); + Assertions.assertEquals(1, usOr.getSaleOptOutNotice()); + Assertions.assertEquals(1, usOr.getTargetedAdvertisingOptOutNotice()); + Assertions.assertEquals(1, usOr.getSaleOptOut()); + Assertions.assertEquals(1, usOr.getTargetedAdvertisingOptOut()); + Assertions.assertEquals(Arrays.asList(2, 1, 0, 2, 1, 0, 2, 1, 0, 1, 2), usOr.getSensitiveDataProcessing()); + Assertions.assertEquals(Arrays.asList(2, 1, 0), usOr.getKnownChildSensitiveDataConsents()); + Assertions.assertEquals(1, usOr.getAdditionalDataProcessingConsent()); + Assertions.assertEquals(1, usOr.getMspaCoveredTransaction()); + Assertions.assertEquals(1, usOr.getMspaOptOutOptionMode()); + Assertions.assertEquals(2, usOr.getMspaServiceProviderMode()); + Assertions.assertEquals(false, usOr.getGpcSegmentIncluded()); + } + + @Test() + public void testDecodeGarbage() { + Assertions.assertThrows(DecodingException.class, () -> { + new UsOr("z").getProcessingNotice(); + }); + } +} diff --git a/iabgpp-encoder/src/test/java/com/iab/gpp/encoder/section/UsTnTest.java b/iabgpp-encoder/src/test/java/com/iab/gpp/encoder/section/UsTnTest.java new file mode 100644 index 00000000..9c8f20e9 --- /dev/null +++ b/iabgpp-encoder/src/test/java/com/iab/gpp/encoder/section/UsTnTest.java @@ -0,0 +1,188 @@ +package com.iab.gpp.encoder.section; + + +import java.util.Arrays; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; +import com.iab.gpp.encoder.error.DecodingException; +import com.iab.gpp.encoder.error.ValidationException; +import com.iab.gpp.encoder.field.UsTnField; + +public class UsTnTest { + + @Test + public void testEncode1() { + UsTn usTn = new UsTn(); + Assertions.assertEquals("BAAAAAQ.Q", usTn.encode()); + } + + @Test + public void testEncode2() { + UsTn usTn = new UsTn(); + + usTn.setFieldValue(UsTnField.PROCESSING_NOTICE, 1); + usTn.setFieldValue(UsTnField.SALE_OPT_OUT_NOTICE, 1); + usTn.setFieldValue(UsTnField.TARGETED_ADVERTISING_OPT_OUT_NOTICE, 1); + usTn.setFieldValue(UsTnField.SALE_OPT_OUT, 1); + usTn.setFieldValue(UsTnField.TARGETED_ADVERTISING_OPT_OUT, 1); + usTn.setFieldValue(UsTnField.SENSITIVE_DATA_PROCESSING, Arrays.asList(2, 1, 0, 2, 1, 0, 2, 1)); + usTn.setFieldValue(UsTnField.KNOWN_CHILD_SENSITIVE_DATA_CONSENTS, 1); + usTn.setFieldValue(UsTnField.ADDITIONAL_DATA_PROCESSING_CONSENT, 1); + usTn.setFieldValue(UsTnField.MSPA_COVERED_TRANSACTION, 1); + usTn.setFieldValue(UsTnField.MSPA_OPT_OUT_OPTION_MODE, 1); + usTn.setFieldValue(UsTnField.MSPA_SERVICE_PROVIDER_MODE, 2); + usTn.setFieldValue(UsTnField.GPC, true); + + Assertions.assertEquals("BVWSSVW.Y", usTn.encode()); + } + + @Test + public void testSetInvalidValues() { + UsTn usTn = new UsTn(); + + try { + usTn.setFieldValue(UsTnField.PROCESSING_NOTICE, 3); + Assertions.fail("Expected ValidationException"); + } catch (ValidationException e) { + + } + + try { + usTn.setFieldValue(UsTnField.SALE_OPT_OUT_NOTICE, 3); + Assertions.fail("Expected ValidationException"); + } catch (ValidationException e) { + + } + + try { + usTn.setFieldValue(UsTnField.TARGETED_ADVERTISING_OPT_OUT_NOTICE, 3); + Assertions.fail("Expected ValidationException"); + } catch (ValidationException e) { + + } + + try { + usTn.setFieldValue(UsTnField.SALE_OPT_OUT, 3); + Assertions.fail("Expected ValidationException"); + } catch (ValidationException e) { + + } + + try { + usTn.setFieldValue(UsTnField.TARGETED_ADVERTISING_OPT_OUT, -1); + Assertions.fail("Expected ValidationException"); + } catch (ValidationException e) { + + } + + try { + usTn.setFieldValue(UsTnField.SENSITIVE_DATA_PROCESSING, Arrays.asList(0, 1, 2, 3, 1, 2, 0, 1)); + Assertions.fail("Expected ValidationException"); + } catch (ValidationException e) { + + } + + try { + usTn.setFieldValue(UsTnField.KNOWN_CHILD_SENSITIVE_DATA_CONSENTS, 3); + Assertions.fail("Expected ValidationException"); + } catch (ValidationException e) { + + } + + try { + usTn.setFieldValue(UsTnField.ADDITIONAL_DATA_PROCESSING_CONSENT, 3); + Assertions.fail("Expected ValidationException"); + } catch (ValidationException e) { + + } + + try { + usTn.setFieldValue(UsTnField.MSPA_COVERED_TRANSACTION, 0); + Assertions.fail("Expected ValidationException"); + } catch (ValidationException e) { + + } + + try { + usTn.setFieldValue(UsTnField.MSPA_OPT_OUT_OPTION_MODE, 4); + Assertions.fail("Expected ValidationException"); + } catch (ValidationException e) { + + } + + try { + usTn.setFieldValue(UsTnField.MSPA_SERVICE_PROVIDER_MODE, -1); + Assertions.fail("Expected ValidationException"); + } catch (ValidationException e) { + + } + } + + @Test + public void testEncodeWithGpcSegmentExcluded() { + UsTn usTn = new UsTn(); + usTn.setFieldValue(UsTnField.GPC_SEGMENT_INCLUDED, false); + Assertions.assertEquals("BAAAAAQ", usTn.encode()); + } + + @Test + public void testDecode1() throws DecodingException { + UsTn usTn = new UsTn("BVWSSVW.Y"); + + Assertions.assertEquals(1, usTn.getProcessingNotice()); + Assertions.assertEquals(1, usTn.getSaleOptOutNotice()); + Assertions.assertEquals(1, usTn.getTargetedAdvertisingOptOutNotice()); + Assertions.assertEquals(1, usTn.getSaleOptOut()); + Assertions.assertEquals(1, usTn.getTargetedAdvertisingOptOut()); + Assertions.assertEquals(Arrays.asList(2, 1, 0, 2, 1, 0, 2, 1), usTn.getSensitiveDataProcessing()); + Assertions.assertEquals(1, usTn.getKnownChildSensitiveDataConsents()); + Assertions.assertEquals(1, usTn.getAdditionalDataProcessingConsent()); + Assertions.assertEquals(1, usTn.getMspaCoveredTransaction()); + Assertions.assertEquals(1, usTn.getMspaOptOutOptionMode()); + Assertions.assertEquals(2, usTn.getMspaServiceProviderMode()); + Assertions.assertEquals(true, usTn.getGpc()); + } + + @Test + public void testDecode2() throws DecodingException { + UsTn usTn = new UsTn("BVWSSVWA.YA"); + + Assertions.assertEquals(1, usTn.getProcessingNotice()); + Assertions.assertEquals(1, usTn.getSaleOptOutNotice()); + Assertions.assertEquals(1, usTn.getTargetedAdvertisingOptOutNotice()); + Assertions.assertEquals(1, usTn.getSaleOptOut()); + Assertions.assertEquals(1, usTn.getTargetedAdvertisingOptOut()); + Assertions.assertEquals(Arrays.asList(2, 1, 0, 2, 1, 0, 2, 1), usTn.getSensitiveDataProcessing()); + Assertions.assertEquals(1, usTn.getKnownChildSensitiveDataConsents()); + Assertions.assertEquals(1, usTn.getAdditionalDataProcessingConsent()); + Assertions.assertEquals(1, usTn.getMspaCoveredTransaction()); + Assertions.assertEquals(1, usTn.getMspaOptOutOptionMode()); + Assertions.assertEquals(2, usTn.getMspaServiceProviderMode()); + Assertions.assertEquals(true, usTn.getGpc()); + } + + @Test + public void testDecodeWithGpcSegmentExcluded() throws DecodingException { + UsTn usTn = new UsTn("BVWSSVW"); + + Assertions.assertEquals(1, usTn.getProcessingNotice()); + Assertions.assertEquals(1, usTn.getSaleOptOutNotice()); + Assertions.assertEquals(1, usTn.getTargetedAdvertisingOptOutNotice()); + Assertions.assertEquals(1, usTn.getSaleOptOut()); + Assertions.assertEquals(1, usTn.getTargetedAdvertisingOptOut()); + Assertions.assertEquals(Arrays.asList(2, 1, 0, 2, 1, 0, 2, 1), usTn.getSensitiveDataProcessing()); + Assertions.assertEquals(1, usTn.getKnownChildSensitiveDataConsents()); + Assertions.assertEquals(1, usTn.getAdditionalDataProcessingConsent()); + Assertions.assertEquals(1, usTn.getMspaCoveredTransaction()); + Assertions.assertEquals(1, usTn.getMspaOptOutOptionMode()); + Assertions.assertEquals(2, usTn.getMspaServiceProviderMode()); + Assertions.assertEquals(false, usTn.getGpcSegmentIncluded()); + } + + @Test() + public void testDecodeGarbage() { + Assertions.assertThrows(DecodingException.class, () -> { + new UsTn("z").getProcessingNotice(); + }); + } +} diff --git a/iabgpp-encoder/src/test/java/com/iab/gpp/encoder/section/UsTxTest.java b/iabgpp-encoder/src/test/java/com/iab/gpp/encoder/section/UsTxTest.java new file mode 100644 index 00000000..4dee70ed --- /dev/null +++ b/iabgpp-encoder/src/test/java/com/iab/gpp/encoder/section/UsTxTest.java @@ -0,0 +1,188 @@ +package com.iab.gpp.encoder.section; + + +import java.util.Arrays; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; +import com.iab.gpp.encoder.error.DecodingException; +import com.iab.gpp.encoder.error.ValidationException; +import com.iab.gpp.encoder.field.UsTxField; + +public class UsTxTest { + + @Test + public void testEncode1() { + UsTx usTx = new UsTx(); + Assertions.assertEquals("BAAAAAQ.Q", usTx.encode()); + } + + @Test + public void testEncode2() { + UsTx usTx = new UsTx(); + + usTx.setFieldValue(UsTxField.PROCESSING_NOTICE, 1); + usTx.setFieldValue(UsTxField.SALE_OPT_OUT_NOTICE, 1); + usTx.setFieldValue(UsTxField.TARGETED_ADVERTISING_OPT_OUT_NOTICE, 1); + usTx.setFieldValue(UsTxField.SALE_OPT_OUT, 1); + usTx.setFieldValue(UsTxField.TARGETED_ADVERTISING_OPT_OUT, 1); + usTx.setFieldValue(UsTxField.SENSITIVE_DATA_PROCESSING, Arrays.asList(2, 1, 0, 2, 1, 0, 2, 1)); + usTx.setFieldValue(UsTxField.KNOWN_CHILD_SENSITIVE_DATA_CONSENTS, 1); + usTx.setFieldValue(UsTxField.ADDITIONAL_DATA_PROCESSING_CONSENT, 1); + usTx.setFieldValue(UsTxField.MSPA_COVERED_TRANSACTION, 1); + usTx.setFieldValue(UsTxField.MSPA_OPT_OUT_OPTION_MODE, 1); + usTx.setFieldValue(UsTxField.MSPA_SERVICE_PROVIDER_MODE, 2); + usTx.setFieldValue(UsTxField.GPC, true); + + Assertions.assertEquals("BVWSSVW.Y", usTx.encode()); + } + + @Test + public void testSetInvalidValues() { + UsTx usTx = new UsTx(); + + try { + usTx.setFieldValue(UsTxField.PROCESSING_NOTICE, 3); + Assertions.fail("Expected ValidationException"); + } catch (ValidationException e) { + + } + + try { + usTx.setFieldValue(UsTxField.SALE_OPT_OUT_NOTICE, 3); + Assertions.fail("Expected ValidationException"); + } catch (ValidationException e) { + + } + + try { + usTx.setFieldValue(UsTxField.TARGETED_ADVERTISING_OPT_OUT_NOTICE, 3); + Assertions.fail("Expected ValidationException"); + } catch (ValidationException e) { + + } + + try { + usTx.setFieldValue(UsTxField.SALE_OPT_OUT, 3); + Assertions.fail("Expected ValidationException"); + } catch (ValidationException e) { + + } + + try { + usTx.setFieldValue(UsTxField.TARGETED_ADVERTISING_OPT_OUT, -1); + Assertions.fail("Expected ValidationException"); + } catch (ValidationException e) { + + } + + try { + usTx.setFieldValue(UsTxField.SENSITIVE_DATA_PROCESSING, Arrays.asList(0, 1, 2, 3, 1, 2, 0, 1)); + Assertions.fail("Expected ValidationException"); + } catch (ValidationException e) { + + } + + try { + usTx.setFieldValue(UsTxField.KNOWN_CHILD_SENSITIVE_DATA_CONSENTS, 3); + Assertions.fail("Expected ValidationException"); + } catch (ValidationException e) { + + } + + try { + usTx.setFieldValue(UsTxField.ADDITIONAL_DATA_PROCESSING_CONSENT, 3); + Assertions.fail("Expected ValidationException"); + } catch (ValidationException e) { + + } + + try { + usTx.setFieldValue(UsTxField.MSPA_COVERED_TRANSACTION, 0); + Assertions.fail("Expected ValidationException"); + } catch (ValidationException e) { + + } + + try { + usTx.setFieldValue(UsTxField.MSPA_OPT_OUT_OPTION_MODE, 4); + Assertions.fail("Expected ValidationException"); + } catch (ValidationException e) { + + } + + try { + usTx.setFieldValue(UsTxField.MSPA_SERVICE_PROVIDER_MODE, -1); + Assertions.fail("Expected ValidationException"); + } catch (ValidationException e) { + + } + } + + @Test + public void testEncodeWithGpcSegmentExcluded() { + UsTx usTx = new UsTx(); + usTx.setFieldValue(UsTxField.GPC_SEGMENT_INCLUDED, false); + Assertions.assertEquals("BAAAAAQ", usTx.encode()); + } + + @Test + public void testDecode1() throws DecodingException { + UsTx usTx = new UsTx("BVWSSVW.Y"); + + Assertions.assertEquals(1, usTx.getProcessingNotice()); + Assertions.assertEquals(1, usTx.getSaleOptOutNotice()); + Assertions.assertEquals(1, usTx.getTargetedAdvertisingOptOutNotice()); + Assertions.assertEquals(1, usTx.getSaleOptOut()); + Assertions.assertEquals(1, usTx.getTargetedAdvertisingOptOut()); + Assertions.assertEquals(Arrays.asList(2, 1, 0, 2, 1, 0, 2, 1), usTx.getSensitiveDataProcessing()); + Assertions.assertEquals(1, usTx.getKnownChildSensitiveDataConsents()); + Assertions.assertEquals(1, usTx.getAdditionalDataProcessingConsent()); + Assertions.assertEquals(1, usTx.getMspaCoveredTransaction()); + Assertions.assertEquals(1, usTx.getMspaOptOutOptionMode()); + Assertions.assertEquals(2, usTx.getMspaServiceProviderMode()); + Assertions.assertEquals(true, usTx.getGpc()); + } + + @Test + public void testDecode2() throws DecodingException { + UsTx usTx = new UsTx("BVWSSVWA.YA"); + + Assertions.assertEquals(1, usTx.getProcessingNotice()); + Assertions.assertEquals(1, usTx.getSaleOptOutNotice()); + Assertions.assertEquals(1, usTx.getTargetedAdvertisingOptOutNotice()); + Assertions.assertEquals(1, usTx.getSaleOptOut()); + Assertions.assertEquals(1, usTx.getTargetedAdvertisingOptOut()); + Assertions.assertEquals(Arrays.asList(2, 1, 0, 2, 1, 0, 2, 1), usTx.getSensitiveDataProcessing()); + Assertions.assertEquals(1, usTx.getKnownChildSensitiveDataConsents()); + Assertions.assertEquals(1, usTx.getAdditionalDataProcessingConsent()); + Assertions.assertEquals(1, usTx.getMspaCoveredTransaction()); + Assertions.assertEquals(1, usTx.getMspaOptOutOptionMode()); + Assertions.assertEquals(2, usTx.getMspaServiceProviderMode()); + Assertions.assertEquals(true, usTx.getGpc()); + } + + @Test + public void testDecodeWithGpcSegmentExcluded() throws DecodingException { + UsTx usTx = new UsTx("BVWSSVW"); + + Assertions.assertEquals(1, usTx.getProcessingNotice()); + Assertions.assertEquals(1, usTx.getSaleOptOutNotice()); + Assertions.assertEquals(1, usTx.getTargetedAdvertisingOptOutNotice()); + Assertions.assertEquals(1, usTx.getSaleOptOut()); + Assertions.assertEquals(1, usTx.getTargetedAdvertisingOptOut()); + Assertions.assertEquals(Arrays.asList(2, 1, 0, 2, 1, 0, 2, 1), usTx.getSensitiveDataProcessing()); + Assertions.assertEquals(1, usTx.getKnownChildSensitiveDataConsents()); + Assertions.assertEquals(1, usTx.getAdditionalDataProcessingConsent()); + Assertions.assertEquals(1, usTx.getMspaCoveredTransaction()); + Assertions.assertEquals(1, usTx.getMspaOptOutOptionMode()); + Assertions.assertEquals(2, usTx.getMspaServiceProviderMode()); + Assertions.assertEquals(false, usTx.getGpcSegmentIncluded()); + } + + @Test() + public void testDecodeGarbage() { + Assertions.assertThrows(DecodingException.class, () -> { + new UsTx("z").getProcessingNotice(); + }); + } +} diff --git a/iabgpp-encoder/src/test/java/com/iab/gpp/encoder/section/UsUtTest.java b/iabgpp-encoder/src/test/java/com/iab/gpp/encoder/section/UsUtTest.java new file mode 100644 index 00000000..9f0ef497 --- /dev/null +++ b/iabgpp-encoder/src/test/java/com/iab/gpp/encoder/section/UsUtTest.java @@ -0,0 +1,159 @@ +package com.iab.gpp.encoder.section; + + +import java.util.Arrays; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; +import com.iab.gpp.encoder.error.DecodingException; +import com.iab.gpp.encoder.error.ValidationException; +import com.iab.gpp.encoder.field.UsUtField; + +public class UsUtTest { + + @Test + public void testEncode1() { + UsUt usUt = new UsUt(); + Assertions.assertEquals("BAAAAAQ", usUt.encode()); + } + + @Test + public void testEncode2() { + UsUt usUt = new UsUt(); + + usUt.setFieldValue(UsUtField.SHARING_NOTICE, 1); + usUt.setFieldValue(UsUtField.SALE_OPT_OUT_NOTICE, 1); + usUt.setFieldValue(UsUtField.TARGETED_ADVERTISING_OPT_OUT_NOTICE, 1); + usUt.setFieldValue(UsUtField.SALE_OPT_OUT, 1); + usUt.setFieldValue(UsUtField.SENSITIVE_DATA_PROCESSING_OPT_OUT_NOTICE, 1); + usUt.setFieldValue(UsUtField.TARGETED_ADVERTISING_OPT_OUT, 1); + usUt.setFieldValue(UsUtField.SENSITIVE_DATA_PROCESSING, Arrays.asList(2, 1, 0, 2, 1, 0, 2, 1)); + usUt.setFieldValue(UsUtField.KNOWN_CHILD_SENSITIVE_DATA_CONSENTS, 1); + usUt.setFieldValue(UsUtField.MSPA_COVERED_TRANSACTION, 1); + usUt.setFieldValue(UsUtField.MSPA_OPT_OUT_OPTION_MODE, 1); + usUt.setFieldValue(UsUtField.MSPA_SERVICE_PROVIDER_MODE, 2); + + Assertions.assertEquals("BVVkklW", usUt.encode()); + } + + @Test + public void testSetInvalidValues() { + UsUt usUt = new UsUt(); + + try { + usUt.setFieldValue(UsUtField.SHARING_NOTICE, -1); + Assertions.fail("Expected ValidationException"); + } catch (ValidationException e) { + + } + + try { + usUt.setFieldValue(UsUtField.SALE_OPT_OUT_NOTICE, 3); + Assertions.fail("Expected ValidationException"); + } catch (ValidationException e) { + + } + + try { + usUt.setFieldValue(UsUtField.TARGETED_ADVERTISING_OPT_OUT_NOTICE, 3); + Assertions.fail("Expected ValidationException"); + } catch (ValidationException e) { + + } + + try { + usUt.setFieldValue(UsUtField.SALE_OPT_OUT, 4); + Assertions.fail("Expected ValidationException"); + } catch (ValidationException e) { + + } + + try { + usUt.setFieldValue(UsUtField.SENSITIVE_DATA_PROCESSING_OPT_OUT_NOTICE, 3); + Assertions.fail("Expected ValidationException"); + } catch (ValidationException e) { + + } + + try { + usUt.setFieldValue(UsUtField.TARGETED_ADVERTISING_OPT_OUT, 3); + Assertions.fail("Expected ValidationException"); + } catch (ValidationException e) { + + } + + try { + usUt.setFieldValue(UsUtField.SENSITIVE_DATA_PROCESSING, Arrays.asList(0, 1, 2, 3, 0, 1, 2, 0)); + Assertions.fail("Expected ValidationException"); + } catch (ValidationException e) { + + } + + try { + usUt.setFieldValue(UsUtField.KNOWN_CHILD_SENSITIVE_DATA_CONSENTS, 3); + Assertions.fail("Expected ValidationException"); + } catch (ValidationException e) { + + } + + try { + usUt.setFieldValue(UsUtField.MSPA_COVERED_TRANSACTION, 0); + Assertions.fail("Expected ValidationException"); + } catch (ValidationException e) { + + } + + try { + usUt.setFieldValue(UsUtField.MSPA_OPT_OUT_OPTION_MODE, 3); + Assertions.fail("Expected ValidationException"); + } catch (ValidationException e) { + + } + + try { + usUt.setFieldValue(UsUtField.MSPA_SERVICE_PROVIDER_MODE, 3); + Assertions.fail("Expected ValidationException"); + } catch (ValidationException e) { + + } + + } + + @Test + public void testDecode1() throws DecodingException { + UsUt usUt = new UsUt("BVVkklW"); + + Assertions.assertEquals(1, usUt.getSharingNotice()); + Assertions.assertEquals(1, usUt.getSaleOptOutNotice()); + Assertions.assertEquals(1, usUt.getTargetedAdvertisingOptOutNotice()); + Assertions.assertEquals(1, usUt.getSaleOptOut()); + Assertions.assertEquals(1, usUt.getTargetedAdvertisingOptOut()); + Assertions.assertEquals(Arrays.asList(2, 1, 0, 2, 1, 0, 2, 1), usUt.getSensitiveDataProcessing()); + Assertions.assertEquals(1, usUt.getKnownChildSensitiveDataConsents()); + Assertions.assertEquals(1, usUt.getMspaCoveredTransaction()); + Assertions.assertEquals(1, usUt.getMspaOptOutOptionMode()); + Assertions.assertEquals(2, usUt.getMspaServiceProviderMode()); + } + + @Test + public void testDecode2() throws DecodingException { + UsUt usUt = new UsUt("BVVkklWA"); + + Assertions.assertEquals(1, usUt.getSharingNotice()); + Assertions.assertEquals(1, usUt.getSaleOptOutNotice()); + Assertions.assertEquals(1, usUt.getTargetedAdvertisingOptOutNotice()); + Assertions.assertEquals(1, usUt.getSaleOptOut()); + Assertions.assertEquals(1, usUt.getTargetedAdvertisingOptOut()); + Assertions.assertEquals(Arrays.asList(2, 1, 0, 2, 1, 0, 2, 1), usUt.getSensitiveDataProcessing()); + Assertions.assertEquals(1, usUt.getKnownChildSensitiveDataConsents()); + Assertions.assertEquals(1, usUt.getMspaCoveredTransaction()); + Assertions.assertEquals(1, usUt.getMspaOptOutOptionMode()); + Assertions.assertEquals(2, usUt.getMspaServiceProviderMode()); + } + + @Test() + public void testDecodeGarbage() { + Assertions.assertThrows(DecodingException.class, () -> { + new UsUt("z").getKnownChildSensitiveDataConsents(); + }); + } +} diff --git a/iabgpp-encoder/src/test/java/com/iab/gpp/encoder/section/UsVaTest.java b/iabgpp-encoder/src/test/java/com/iab/gpp/encoder/section/UsVaTest.java new file mode 100644 index 00000000..346e0ca6 --- /dev/null +++ b/iabgpp-encoder/src/test/java/com/iab/gpp/encoder/section/UsVaTest.java @@ -0,0 +1,141 @@ +package com.iab.gpp.encoder.section; + + +import java.util.Arrays; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; +import com.iab.gpp.encoder.error.DecodingException; +import com.iab.gpp.encoder.error.EncodingException; +import com.iab.gpp.encoder.error.InvalidFieldException; +import com.iab.gpp.encoder.error.ValidationException; +import com.iab.gpp.encoder.field.UsVaField; + +public class UsVaTest { + + @Test + public void testEncode1() { + UsVa usVa = new UsVa(); + Assertions.assertEquals("BAAAABA", usVa.encode()); + } + + @Test + public void testEncode2() { + UsVa usVa = new UsVa(); + + try { + usVa.setFieldValue(UsVaField.SHARING_NOTICE, 1); + usVa.setFieldValue(UsVaField.SALE_OPT_OUT_NOTICE, 1); + usVa.setFieldValue(UsVaField.TARGETED_ADVERTISING_OPT_OUT_NOTICE, 1); + usVa.setFieldValue(UsVaField.SALE_OPT_OUT, 1); + usVa.setFieldValue(UsVaField.TARGETED_ADVERTISING_OPT_OUT, 1); + usVa.setFieldValue(UsVaField.SENSITIVE_DATA_PROCESSING, Arrays.asList(2, 1, 0, 2, 1, 0, 2, 1)); + usVa.setFieldValue(UsVaField.KNOWN_CHILD_SENSITIVE_DATA_CONSENTS, 1); + usVa.setFieldValue(UsVaField.MSPA_COVERED_TRANSACTION, 1); + usVa.setFieldValue(UsVaField.MSPA_OPT_OUT_OPTION_MODE, 1); + usVa.setFieldValue(UsVaField.MSPA_SERVICE_PROVIDER_MODE, 2); + } catch (InvalidFieldException e) { + throw new EncodingException(e); + } + + Assertions.assertEquals("BVWSSVY", usVa.encode()); + } + + @Test + public void testSetInvalidValues() { + UsVa usVa = new UsVa(); + + try { + usVa.setFieldValue(UsVaField.SHARING_NOTICE, 3); + Assertions.fail("Expected ValidationException"); + } catch (ValidationException e) { + + } + + try { + usVa.setFieldValue(UsVaField.SALE_OPT_OUT_NOTICE, -1); + Assertions.fail("Expected ValidationException"); + } catch (ValidationException e) { + + } + + try { + usVa.setFieldValue(UsVaField.TARGETED_ADVERTISING_OPT_OUT_NOTICE, 4); + Assertions.fail("Expected ValidationException"); + } catch (ValidationException e) { + + } + + try { + usVa.setFieldValue(UsVaField.SALE_OPT_OUT, 3); + Assertions.fail("Expected ValidationException"); + } catch (ValidationException e) { + + } + + try { + usVa.setFieldValue(UsVaField.TARGETED_ADVERTISING_OPT_OUT, 3); + Assertions.fail("Expected ValidationException"); + } catch (ValidationException e) { + + } + + try { + usVa.setFieldValue(UsVaField.SENSITIVE_DATA_PROCESSING, Arrays.asList(0, 1, 2, 3, 1, 2, 0, 1)); + Assertions.fail("Expected ValidationException"); + } catch (ValidationException e) { + + } + + try { + usVa.setFieldValue(UsVaField.KNOWN_CHILD_SENSITIVE_DATA_CONSENTS, 3); + Assertions.fail("Expected ValidationException"); + } catch (ValidationException e) { + + } + + try { + usVa.setFieldValue(UsVaField.MSPA_COVERED_TRANSACTION, 0); + Assertions.fail("Expected ValidationException"); + } catch (ValidationException e) { + + } + + try { + usVa.setFieldValue(UsVaField.MSPA_OPT_OUT_OPTION_MODE, 3); + Assertions.fail("Expected ValidationException"); + } catch (ValidationException e) { + + } + + try { + usVa.setFieldValue(UsVaField.MSPA_SERVICE_PROVIDER_MODE, 3); + Assertions.fail("Expected ValidationException"); + } catch (ValidationException e) { + + } + + } + + @Test + public void testDecode1() throws DecodingException { + UsVa usVa = new UsVa("BVWSSVY"); + + Assertions.assertEquals(1, usVa.getSharingNotice()); + Assertions.assertEquals(1, usVa.getSaleOptOutNotice()); + Assertions.assertEquals(1, usVa.getTargetedAdvertisingOptOutNotice()); + Assertions.assertEquals(1, usVa.getSaleOptOut()); + Assertions.assertEquals(1, usVa.getTargetedAdvertisingOptOut()); + Assertions.assertEquals(Arrays.asList(2, 1, 0, 2, 1, 0, 2, 1), usVa.getSensitiveDataProcessing()); + Assertions.assertEquals(1, usVa.getKnownChildSensitiveDataConsents()); + Assertions.assertEquals(1, usVa.getMspaCoveredTransaction()); + Assertions.assertEquals(1, usVa.getMspaOptOutOptionMode()); + Assertions.assertEquals(2, usVa.getMspaServiceProviderMode()); + } + + @Test() + public void testDecodeGarbage() { + Assertions.assertThrows(DecodingException.class, () -> { + new UsVa("z").getMspaCoveredTransaction(); + }); + } +} diff --git a/iabgpp-encoder/src/test/java/com/iab/gpp/encoder/section/UspV1LegacyTest.java b/iabgpp-encoder/src/test/java/com/iab/gpp/encoder/section/UspV1LegacyTest.java deleted file mode 100644 index a15bf88d..00000000 --- a/iabgpp-encoder/src/test/java/com/iab/gpp/encoder/section/UspV1LegacyTest.java +++ /dev/null @@ -1,64 +0,0 @@ -package com.iab.gpp.encoder.section; - -import org.junit.jupiter.api.Assertions; -import org.junit.jupiter.api.Test; -import com.iab.gpp.encoder.error.EncodingException; - -public class UspV1LegacyTest { - - @Test - public void testEncode1() throws EncodingException { - UspV1Legacy uspv1 = new UspV1Legacy(); - Assertions.assertEquals("1---", uspv1.encode()); - } - - @Test - public void testEncode2() throws EncodingException { - UspV1Legacy uspv1 = new UspV1Legacy(); - uspv1.setFieldValue("Notice", "Y"); - uspv1.setFieldValue("OptOutSale", "N"); - uspv1.setFieldValue("LspaCovered", "N"); - - Assertions.assertEquals("1YNN", uspv1.encode()); - } - - @Test - public void testEncode3() throws EncodingException { - UspV1Legacy uspv1 = new UspV1Legacy(); - uspv1.setFieldValue("Version", 2); - uspv1.setFieldValue("Notice", "N"); - uspv1.setFieldValue("OptOutSale", "Y"); - uspv1.setFieldValue("LspaCovered", "Y"); - - Assertions.assertEquals("2NYY", uspv1.encode()); - } - - @Test - public void testDecode1() throws EncodingException { - UspV1Legacy uspv1 = new UspV1Legacy("1NYN"); - Assertions.assertEquals(1, uspv1.getFieldValue("Version")); - Assertions.assertEquals("N", uspv1.getFieldValue("Notice")); - Assertions.assertEquals("Y", uspv1.getFieldValue("OptOutSale")); - Assertions.assertEquals("N", uspv1.getFieldValue("LspaCovered")); - - Assertions.assertEquals(uspv1.getFieldValue("Version"), uspv1.getVersion()); - Assertions.assertEquals(uspv1.getFieldValue("Notice"), uspv1.getNotice()); - Assertions.assertEquals(uspv1.getFieldValue("OptOutSale"), uspv1.getOptOutSale()); - Assertions.assertEquals(uspv1.getFieldValue("LspaCovered"), uspv1.getLspaCovered()); - } - - @Test - public void testDecode2() throws EncodingException { - UspV1Legacy uspv1 = new UspV1Legacy("2YNY"); - Assertions.assertEquals(2, uspv1.getFieldValue("Version")); - Assertions.assertEquals("Y", uspv1.getFieldValue("Notice")); - Assertions.assertEquals("N", uspv1.getFieldValue("OptOutSale")); - Assertions.assertEquals("Y", uspv1.getFieldValue("LspaCovered")); - - Assertions.assertEquals(uspv1.getFieldValue("Version"), uspv1.getVersion()); - Assertions.assertEquals(uspv1.getFieldValue("Notice"), uspv1.getNotice()); - Assertions.assertEquals(uspv1.getFieldValue("OptOutSale"), uspv1.getOptOutSale()); - Assertions.assertEquals(uspv1.getFieldValue("LspaCovered"), uspv1.getLspaCovered()); - } - -} diff --git a/iabgpp-encoder/src/test/java/com/iab/gpp/encoder/section/UspV1Test.java b/iabgpp-encoder/src/test/java/com/iab/gpp/encoder/section/UspV1Test.java index b7ffa054..ffc7e741 100644 --- a/iabgpp-encoder/src/test/java/com/iab/gpp/encoder/section/UspV1Test.java +++ b/iabgpp-encoder/src/test/java/com/iab/gpp/encoder/section/UspV1Test.java @@ -3,38 +3,44 @@ import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.Test; import com.iab.gpp.encoder.error.DecodingException; -import com.iab.gpp.encoder.error.EncodingException; +import com.iab.gpp.encoder.error.InvalidFieldException; public class UspV1Test { @Test - public void testEncode1() throws EncodingException { + public void testEncode1() { UspV1 uspv1 = new UspV1(); - uspv1.setFieldValue("Notice", 1); - uspv1.setFieldValue("OptOutSale", 2); - uspv1.setFieldValue("LspaCovered", 3); - - Assertions.assertEquals("000001011011", uspv1.encodeToBitString()); + Assertions.assertEquals("1---", uspv1.encode()); } @Test - public void testEncode2() throws EncodingException { + public void testEncode2() { UspV1 uspv1 = new UspV1(); - uspv1.setFieldValue("Notice", 1); - uspv1.setFieldValue("OptOutSale", 2); - uspv1.setFieldValue("LspaCovered", 3); + uspv1.setFieldValue("Notice", 'Y'); + uspv1.setFieldValue("OptOutSale", 'N'); + uspv1.setFieldValue("LspaCovered", 'N'); - Assertions.assertEquals("BbA", uspv1.encode()); + Assertions.assertEquals("1YNN", uspv1.encode()); } @Test - public void testdecode1() throws DecodingException { + public void testEncode3() { UspV1 uspv1 = new UspV1(); - uspv1.decodeFromBitString("000001011011"); + uspv1.setFieldValue("Version", 2); + uspv1.setFieldValue("Notice", 'N'); + uspv1.setFieldValue("OptOutSale", 'Y'); + uspv1.setFieldValue("LspaCovered", 'Y'); - Assertions.assertEquals(1, uspv1.getFieldValue("Notice")); - Assertions.assertEquals(2, uspv1.getFieldValue("OptOutSale")); - Assertions.assertEquals(3, uspv1.getFieldValue("LspaCovered")); + Assertions.assertEquals("2NYY", uspv1.encode()); + } + + @Test + public void testDecode1() throws DecodingException, InvalidFieldException { + UspV1 uspv1 = new UspV1("1NYN"); + Assertions.assertEquals(1, uspv1.getFieldValue("Version")); + Assertions.assertEquals('N', uspv1.getFieldValue("Notice")); + Assertions.assertEquals('Y', uspv1.getFieldValue("OptOutSale")); + Assertions.assertEquals('N', uspv1.getFieldValue("LspaCovered")); Assertions.assertEquals(uspv1.getFieldValue("Version"), uspv1.getVersion()); Assertions.assertEquals(uspv1.getFieldValue("Notice"), uspv1.getNotice()); @@ -43,15 +49,17 @@ public void testdecode1() throws DecodingException { } @Test - public void testDecode2() throws DecodingException { - UspV1 uspv1 = new UspV1("BbA"); - Assertions.assertEquals(1, uspv1.getFieldValue("Notice")); - Assertions.assertEquals(2, uspv1.getFieldValue("OptOutSale")); - Assertions.assertEquals(3, uspv1.getFieldValue("LspaCovered")); + public void testDecode2() throws DecodingException, InvalidFieldException { + UspV1 uspv1 = new UspV1("1YNY"); + Assertions.assertEquals(1, uspv1.getFieldValue("Version")); + Assertions.assertEquals('Y', uspv1.getFieldValue("Notice")); + Assertions.assertEquals('N', uspv1.getFieldValue("OptOutSale")); + Assertions.assertEquals('Y', uspv1.getFieldValue("LspaCovered")); Assertions.assertEquals(uspv1.getFieldValue("Version"), uspv1.getVersion()); Assertions.assertEquals(uspv1.getFieldValue("Notice"), uspv1.getNotice()); Assertions.assertEquals(uspv1.getFieldValue("OptOutSale"), uspv1.getOptOutSale()); Assertions.assertEquals(uspv1.getFieldValue("LspaCovered"), uspv1.getLspaCovered()); } + } diff --git a/iabgpp-extras-jackson/pom.xml b/iabgpp-extras-jackson/pom.xml index a66edc22..5467e6b0 100644 --- a/iabgpp-extras-jackson/pom.xml +++ b/iabgpp-extras-jackson/pom.xml @@ -7,52 +7,68 @@ iabgpp-core com.iabgpp - 3.0.0-SNAPSHOT + 3.2.3-SNAPSHOT iabgpp-extras-jackson - IAB GPP Java GVL and CMP List Jackson jar - - - The Apache Software License, Version 2.0 - http://www.apache.org/licenses/LICENSE-2.0.txt - - - - - UTF-8 - 1.8 - 1.8 - - - junit - junit - 4.13.2 + org.junit.jupiter + junit-jupiter-engine + 5.9.2 test com.iabgpp iabgpp-extras - 3.0.0-SNAPSHOT + 3.2.3-SNAPSHOT com.fasterxml.jackson.core jackson-databind - 2.10.3 + 2.14.1 com.fasterxml.jackson.datatype jackson-datatype-jsr310 - 2.10.3 + 2.14.1 + + + + maven-surefire-plugin + 2.22.2 + + + + + + + release + + + + org.apache.maven.plugins + maven-source-plugin + + + org.apache.maven.plugins + maven-javadoc-plugin + + + org.apache.maven.plugins + maven-gpg-plugin + + + + + diff --git a/iabgpp-extras-jackson/src/main/java/com/iab/gpp/extras/jackson/Loader.java b/iabgpp-extras-jackson/src/main/java/com/iab/gpp/extras/jackson/Loader.java index bfd0d16e..158ced93 100644 --- a/iabgpp-extras-jackson/src/main/java/com/iab/gpp/extras/jackson/Loader.java +++ b/iabgpp-extras-jackson/src/main/java/com/iab/gpp/extras/jackson/Loader.java @@ -22,7 +22,6 @@ import java.io.IOException; import java.io.InputStream; - import com.fasterxml.jackson.databind.DeserializationFeature; import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.module.SimpleAbstractTypeResolver; @@ -30,6 +29,8 @@ import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule; import com.iab.gpp.extras.jackson.cmp.Cmp; import com.iab.gpp.extras.jackson.cmp.CmpList; +import com.iab.gpp.extras.jackson.gvl.DataCategory; +import com.iab.gpp.extras.jackson.gvl.DataRetention; import com.iab.gpp.extras.jackson.gvl.Feature; import com.iab.gpp.extras.jackson.gvl.Gvl; import com.iab.gpp.extras.jackson.gvl.Overflow; @@ -38,69 +39,73 @@ import com.iab.gpp.extras.jackson.gvl.SpecialPurpose; import com.iab.gpp.extras.jackson.gvl.Stack; import com.iab.gpp.extras.jackson.gvl.Vendor; +import com.iab.gpp.extras.jackson.gvl.VendorUrl; public class Loader { - private ObjectMapper objectMapper = new ObjectMapper(); + private ObjectMapper objectMapper = new ObjectMapper(); - public Loader() { - SimpleModule module = new SimpleModule(); + public Loader() { + SimpleModule module = new SimpleModule(); - SimpleAbstractTypeResolver resolver = new SimpleAbstractTypeResolver(); - resolver.addMapping(com.iab.gpp.extras.gvl.Gvl.class, Gvl.class); - resolver.addMapping(com.iab.gpp.extras.gvl.Feature.class, Feature.class); - resolver.addMapping(com.iab.gpp.extras.gvl.Overflow.class, Overflow.class); - resolver.addMapping(com.iab.gpp.extras.gvl.Purpose.class, Purpose.class); - resolver.addMapping(com.iab.gpp.extras.gvl.SpecialFeature.class, SpecialFeature.class); - resolver.addMapping(com.iab.gpp.extras.gvl.SpecialPurpose.class, SpecialPurpose.class); - resolver.addMapping(com.iab.gpp.extras.gvl.Stack.class, Stack.class); - resolver.addMapping(com.iab.gpp.extras.gvl.Vendor.class, Vendor.class); + SimpleAbstractTypeResolver resolver = new SimpleAbstractTypeResolver(); + resolver.addMapping(com.iab.gpp.extras.gvl.DataCategory.class, DataCategory.class); + resolver.addMapping(com.iab.gpp.extras.gvl.DataRetention.class, DataRetention.class); + resolver.addMapping(com.iab.gpp.extras.gvl.Gvl.class, Gvl.class); + resolver.addMapping(com.iab.gpp.extras.gvl.Feature.class, Feature.class); + resolver.addMapping(com.iab.gpp.extras.gvl.Overflow.class, Overflow.class); + resolver.addMapping(com.iab.gpp.extras.gvl.Purpose.class, Purpose.class); + resolver.addMapping(com.iab.gpp.extras.gvl.SpecialFeature.class, SpecialFeature.class); + resolver.addMapping(com.iab.gpp.extras.gvl.SpecialPurpose.class, SpecialPurpose.class); + resolver.addMapping(com.iab.gpp.extras.gvl.Stack.class, Stack.class); + resolver.addMapping(com.iab.gpp.extras.gvl.Vendor.class, Vendor.class); + resolver.addMapping(com.iab.gpp.extras.gvl.VendorUrl.class, VendorUrl.class); - resolver.addMapping(com.iab.gpp.extras.cmp.Cmp.class, Cmp.class); - resolver.addMapping(com.iab.gpp.extras.cmp.CmpList.class, CmpList.class); + resolver.addMapping(com.iab.gpp.extras.cmp.Cmp.class, Cmp.class); + resolver.addMapping(com.iab.gpp.extras.cmp.CmpList.class, CmpList.class); - module.setAbstractTypes(resolver); - objectMapper.registerModule(module); - objectMapper.registerModule(new JavaTimeModule()); - objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false); - } + module.setAbstractTypes(resolver); + objectMapper.registerModule(module); + objectMapper.registerModule(new JavaTimeModule()); + objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false); + } - /** - * Gets the global vendor list json from the specified InputStream - * - * @param content {@link InputStream} of GVL json content - * @return {@link com.iab.gpp.extras.gvl.Gvl} object - */ - public com.iab.gpp.extras.gvl.Gvl globalVendorList(InputStream content) throws IOException { - return objectMapper.readValue(content, com.iab.gpp.extras.gvl.Gvl.class); - } + /** + * Gets the global vendor list json from the specified InputStream + * + * @param content {@link InputStream} of GVL json content + * @return {@link com.iab.gpp.extras.gvl.Gvl} object + */ + public com.iab.gpp.extras.gvl.Gvl globalVendorList(InputStream content) throws IOException { + return objectMapper.readValue(content, com.iab.gpp.extras.gvl.Gvl.class); + } - /** - * Gets the global vendor list json using a json string - * - * @param json the gvl json as a string - * @return {@link com.iab.gpp.extras.gvl.Gvl} object - */ - public com.iab.gpp.extras.gvl.Gvl globalVendorList(String json) throws IOException { - return objectMapper.readValue(json, com.iab.gpp.extras.gvl.Gvl.class); - } + /** + * Gets the global vendor list json using a json string + * + * @param json the gvl json as a string + * @return {@link com.iab.gpp.extras.gvl.Gvl} object + */ + public com.iab.gpp.extras.gvl.Gvl globalVendorList(String json) throws IOException { + return objectMapper.readValue(json, com.iab.gpp.extras.gvl.Gvl.class); + } - /** - * Gets the CMP list from the specified InputStream - * - * @param content {@link InputStream} of CMP List json content - * @return {@link com.iab.gpp.extras.cmp.CmpList} object - */ - public com.iab.gpp.extras.cmp.CmpList cmpList(InputStream content) throws IOException { - return objectMapper.readValue(content, com.iab.gpp.extras.cmp.CmpList.class); - } + /** + * Gets the CMP list from the specified InputStream + * + * @param content {@link InputStream} of CMP List json content + * @return {@link com.iab.gpp.extras.cmp.CmpList} object + */ + public com.iab.gpp.extras.cmp.CmpList cmpList(InputStream content) throws IOException { + return objectMapper.readValue(content, com.iab.gpp.extras.cmp.CmpList.class); + } - /** - * Gets the CMP list from the specified InputStream - * - * @param json the CMP List json as a string - * @return {@link com.iab.gpp.extras.cmp.CmpList} object - */ - public com.iab.gpp.extras.cmp.CmpList cmpList(String json) throws IOException { - return objectMapper.readValue(json, com.iab.gpp.extras.cmp.CmpList.class); - } + /** + * Gets the CMP list from the specified InputStream + * + * @param json the CMP List json as a string + * @return {@link com.iab.gpp.extras.cmp.CmpList} object + */ + public com.iab.gpp.extras.cmp.CmpList cmpList(String json) throws IOException { + return objectMapper.readValue(json, com.iab.gpp.extras.cmp.CmpList.class); + } } diff --git a/iabgpp-extras-jackson/src/main/java/com/iab/gpp/extras/jackson/cmp/Cmp.java b/iabgpp-extras-jackson/src/main/java/com/iab/gpp/extras/jackson/cmp/Cmp.java index 3603b92c..eefc3bd3 100644 --- a/iabgpp-extras-jackson/src/main/java/com/iab/gpp/extras/jackson/cmp/Cmp.java +++ b/iabgpp-extras-jackson/src/main/java/com/iab/gpp/extras/jackson/cmp/Cmp.java @@ -27,64 +27,63 @@ public class Cmp implements com.iab.gpp.extras.cmp.Cmp { - private int id; - private String name; + private int id; + private String name; - @JsonProperty("isCommercial") - private boolean isCommercial; + @JsonProperty("isCommercial") + private boolean isCommercial; - private Instant deletedDate; + private Instant deletedDate; - /** - * A CMP id: a numeric ID which is incrementally assigned and never re-used – inactive CMPs are marked as deleted - * - * @return CMP id - */ - @Override - public int getId() { - return this.id; - } + /** + * A CMP id: a numeric ID which is incrementally assigned and never re-used – inactive CMPs are + * marked as deleted + * + * @return CMP id + */ + @Override + public int getId() { + return this.id; + } - /** - * Name of the CMP - * - * @return CMP name - */ - @Override - public String getName() { - return this.name; - } + /** + * Name of the CMP + * + * @return CMP name + */ + @Override + public String getName() { + return this.name; + } - /** - * Whether or not the CMP is a commercial service - * - * @return true, if the CMP is available as a commercial service - */ - @Override - public boolean isCommercial() { - return this.isCommercial; - } + /** + * Whether or not the CMP is a commercial service + * + * @return true, if the CMP is available as a commercial service + */ + @Override + public boolean isCommercial() { + return this.isCommercial; + } - /** - * If available, the date/time after which CMP is considered inactive - * - * @return {@link Optional} time after which CMP is inactive - */ - @Override - public Optional getDeletedDate() { - return Optional.ofNullable(this.deletedDate); - } + /** + * If available, the date/time after which CMP is considered inactive + * + * @return {@link Optional} time after which CMP is inactive + */ + @Override + public Optional getDeletedDate() { + return Optional.ofNullable(this.deletedDate); + } - /** - * Check whether the CMP is deleted - * - * @return true, if the CMP is considered deleted - */ - @Override - public boolean isDeleted() { - return Optional.ofNullable(this.deletedDate) - .map(deleteDate -> !deleteDate.isAfter(Instant.now())) - .orElse(false); - } + /** + * Check whether the CMP is deleted + * + * @return true, if the CMP is considered deleted + */ + @Override + public boolean isDeleted() { + return Optional.ofNullable(this.deletedDate).map(deleteDate -> !deleteDate.isAfter(Instant.now())).orElse(false); + } } diff --git a/iabgpp-extras-jackson/src/main/java/com/iab/gpp/extras/jackson/cmp/CmpList.java b/iabgpp-extras-jackson/src/main/java/com/iab/gpp/extras/jackson/cmp/CmpList.java index 02a73100..465118ea 100644 --- a/iabgpp-extras-jackson/src/main/java/com/iab/gpp/extras/jackson/cmp/CmpList.java +++ b/iabgpp-extras-jackson/src/main/java/com/iab/gpp/extras/jackson/cmp/CmpList.java @@ -27,37 +27,37 @@ public class CmpList implements com.iab.gpp.extras.cmp.CmpList { - private Instant lastUpdated; - private Map cmps; + private Instant lastUpdated; + private Map cmps; - /** - * Last Updated Date - * - * @return {@link Instant} time when the record was last updated - */ - @Override - public Instant getLastUpdated() { - return lastUpdated; - } + /** + * Last Updated Date + * + * @return {@link Instant} time when the record was last updated + */ + @Override + public Instant getLastUpdated() { + return lastUpdated; + } - /** - * List of CMPs - * - * @return {@link List} of {@link com.iab.gpp.extras.cmp.Cmp} objects - */ - @Override - public List getCmps() { - return new ArrayList<>(cmps.values()); - } + /** + * List of CMPs + * + * @return {@link List} of {@link com.iab.gpp.extras.cmp.Cmp} objects + */ + @Override + public List getCmps() { + return new ArrayList<>(cmps.values()); + } - /** - * Get the CMP object for a give CMP id - * - * @param cmpId CMP id - * @return {@link com.iab.gpp.extras.cmp.Cmp} object - */ - @Override - public com.iab.gpp.extras.cmp.Cmp getCmp(int cmpId) { - return cmps.get(cmpId); - } + /** + * Get the CMP object for a give CMP id + * + * @param cmpId CMP id + * @return {@link com.iab.gpp.extras.cmp.Cmp} object + */ + @Override + public com.iab.gpp.extras.cmp.Cmp getCmp(int cmpId) { + return cmps.get(cmpId); + } } diff --git a/iabgpp-extras-jackson/src/test/java/com/iab/gpp/extras/jackson/TestUtil.java b/iabgpp-extras-jackson/src/main/java/com/iab/gpp/extras/jackson/gvl/DataCategory.java similarity index 51% rename from iabgpp-extras-jackson/src/test/java/com/iab/gpp/extras/jackson/TestUtil.java rename to iabgpp-extras-jackson/src/main/java/com/iab/gpp/extras/jackson/gvl/DataCategory.java index 34ec9acb..375c5aea 100644 --- a/iabgpp-extras-jackson/src/test/java/com/iab/gpp/extras/jackson/TestUtil.java +++ b/iabgpp-extras-jackson/src/main/java/com/iab/gpp/extras/jackson/gvl/DataCategory.java @@ -1,17 +1,17 @@ -package com.iab.gpp.extras.jackson; +package com.iab.gpp.extras.jackson.gvl; /*- * #%L - * IAB TCF Java GVL and CMP List Jackson + * IAB TCF Java GVL Jackson * %% * Copyright (C) 2020 IAB Technology Laboratory, Inc * %% * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at - * + * * http://www.apache.org/licenses/LICENSE-2.0 - * + * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. @@ -20,20 +20,44 @@ * #L% */ -import com.iab.gpp.extras.jackson.gvl.GvlTest; +/* + * DataCategory + */ +public class DataCategory implements com.iab.gpp.extras.gvl.DataCategory { + + private int id; + private String name; + private String description; + + /** + * A id + * + * @return id + */ + @Override + public Integer getId() { + return id; + } -import java.io.IOException; -import java.io.InputStream; + /** + * Name + * + * @return name + */ + @Override + public String getName() { + return name; + } -public class TestUtil { + /** + * Description + * + * @return description + */ + @Override + public String getDescription() { + return description; + } - public static InputStream getCmpList() throws IOException { - ClassLoader loader = GvlTest.class.getClassLoader(); - return loader.getResourceAsStream("cmpList.json"); - } - public static InputStream getGlobalVendorList() throws IOException { - ClassLoader loader = GvlTest.class.getClassLoader(); - return loader.getResourceAsStream("gvl.json"); - } } diff --git a/iabgpp-extras-jackson/src/main/java/com/iab/gpp/extras/jackson/gvl/DataRetention.java b/iabgpp-extras-jackson/src/main/java/com/iab/gpp/extras/jackson/gvl/DataRetention.java new file mode 100644 index 00000000..9bb73c85 --- /dev/null +++ b/iabgpp-extras-jackson/src/main/java/com/iab/gpp/extras/jackson/gvl/DataRetention.java @@ -0,0 +1,64 @@ +package com.iab.gpp.extras.jackson.gvl; + +import java.util.Map; +import java.util.Optional; + +/*- + * #%L + * IAB TCF Java GVL Jackson + * %% + * Copyright (C) 2020 IAB Technology Laboratory, Inc + * %% + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * #L% + */ + +/* + * DataRetention + */ +public class DataRetention implements com.iab.gpp.extras.gvl.DataRetention { + + private Integer stdRetention; + private Map purposes; + private Map specialPurposes; + + /** + * stdRetention + * + * @return stdRetention + */ + @Override + public Optional getStdRetention() { + return Optional.ofNullable(stdRetention); + } + + /** + * purposes + * + * @return purposes + */ + @Override + public Map getPurposes() { + return purposes; + } + + /** + * specialPurposes + * + * @return specialPurposes + */ + @Override + public Map getSpecialPurposes() { + return specialPurposes; + } +} diff --git a/iabgpp-extras-jackson/src/main/java/com/iab/gpp/extras/jackson/gvl/Feature.java b/iabgpp-extras-jackson/src/main/java/com/iab/gpp/extras/jackson/gvl/Feature.java index e497cee6..0cb75378 100644 --- a/iabgpp-extras-jackson/src/main/java/com/iab/gpp/extras/jackson/gvl/Feature.java +++ b/iabgpp-extras-jackson/src/main/java/com/iab/gpp/extras/jackson/gvl/Feature.java @@ -1,5 +1,8 @@ package com.iab.gpp.extras.jackson.gvl; +import java.util.List; +import java.util.Optional; + /*- * #%L * IAB TCF Java GVL Jackson @@ -25,48 +28,59 @@ */ public class Feature implements com.iab.gpp.extras.gvl.Feature { - private int id; - private String name; - private String description; - private String descriptionLegal; + private int id; + private String name; + private String description; + private String descriptionLegal; + private List illustrations; + + /** + * A feature id + * + * @return feature id + */ + @Override + public int getId() { + return id; + } - /** - * A feature id - * - * @return feature id - */ - @Override - public int getId() { - return id; - } + /** + * Name of the feature + * + * @return feature name string + */ + @Override + public String getName() { + return name; + } - /** - * Name of the feature - * - * @return feature name string - */ - @Override - public String getName() { - return name; - } + /** + * Description of the feature + * + * @return feature description string + */ + @Override + public String getDescription() { + return description; + } - /** - * Description of the feature - * - * @return feature description string - */ - @Override - public String getDescription() { - return description; - } + /** + * Legal description of the feature + * + * @return legal description string + */ + @Override + public Optional getDescriptionLegal() { + return Optional.ofNullable(descriptionLegal); + } - /** - * Legal description of the feature - * - * @return legal description string - */ - @Override - public String getDescriptionLegal() { - return descriptionLegal; - } + /** + * illustrations + * + * @return illustrations + */ + @Override + public Optional> getIllustrations() { + return Optional.ofNullable(illustrations); + } } diff --git a/iabgpp-extras-jackson/src/main/java/com/iab/gpp/extras/jackson/gvl/Gvl.java b/iabgpp-extras-jackson/src/main/java/com/iab/gpp/extras/jackson/gvl/Gvl.java index d58e10dc..2cbcdcc8 100644 --- a/iabgpp-extras-jackson/src/main/java/com/iab/gpp/extras/jackson/gvl/Gvl.java +++ b/iabgpp-extras-jackson/src/main/java/com/iab/gpp/extras/jackson/gvl/Gvl.java @@ -25,141 +25,157 @@ import java.util.ArrayList; import java.util.List; import java.util.Map; - +import java.util.Optional; +import com.iab.gpp.extras.gvl.DataCategory; +import com.iab.gpp.extras.gvl.Feature; import com.iab.gpp.extras.gvl.Purpose; import com.iab.gpp.extras.gvl.SpecialFeature; import com.iab.gpp.extras.gvl.SpecialPurpose; import com.iab.gpp.extras.gvl.Stack; import com.iab.gpp.extras.gvl.Vendor; -import com.iab.gpp.extras.gvl.Feature; public class Gvl implements com.iab.gpp.extras.gvl.Gvl { - private int gvlSpecificationVersion; - private int vendorListVersion; - private int tcfPolicyVersion; - private Instant lastUpdated; - private Map purposes; - private Map specialPurposes; - private Map features; - private Map specialFeatures; - private Map stacks; - private Map vendors; - - /** - * A Global Vendor List Specification Version - * - * @return global vendor list specification version - */ - @Override - public int getGvlSpecificationVersion() { - return gvlSpecificationVersion; - } - - /** - * A Global Vendor List version incremented with each published file change - * - * @return global vendor list version - */ - @Override - public int getVendorListVersion() { - return vendorListVersion; - } - - /** - * A TCF Policy Version. The TCF MO will increment this value whenever a GVL change (such as - * adding a new Purpose or Feature or a change in Purpose wording) legally invalidates existing - * TC Strings and requires CMPs to re-establish transparency and consent from users. TCF Policy - * changes should be relatively infrequent and only occur when necessary to support changes in - * global mandate. If the policy version number in the latest GVL is different from the value in - * your TC String, then you need to re-establish transparency and consent for that user. A - * version 1 format TC String is considered to have a version value of 1. - * - * @return tcf policy version - */ - @Override - public int getTcfPolicyVersion() { - return tcfPolicyVersion; - } - - /** - * Last Updated Date - * - * @return timestamp when the record was last updated - */ - @Override - public Instant getLastUpdated() { - return lastUpdated; - } - - /** - * A list of standard purposes - * - * @return A {@link List} of standard {@link Purpose} objects - */ - @Override - public List getPurposes() { - return new ArrayList<>(purposes.values()); - } - - /** - * A list of special purposes - * - * @return A {@link List} of {@link SpecialPurpose} objects - */ - @Override - public List getSpecialPurposes() { - return new ArrayList<>(specialPurposes.values()); - } - - /** - * A list of standard features - * - * @return A {@link List} of standard {@link Feature} objects - */ - @Override - public List getFeatures() { - return new ArrayList<>(features.values()); - } - - /** - * A list of special features - * - * @return A {@link List} of special {@link SpecialFeature} objects - */ - @Override - public List getSpecialFeatures() { - return new ArrayList<>(specialFeatures.values()); - } - - /** - * A list of stacks - * - * @return A {@link List} of {@link Stack} objects - */ - @Override - public List getStacks() { - return new ArrayList<>(stacks.values()); - } - - /** - * A list of vendors - * - * @return A {@link List} of {@link Vendor} objects - */ - @Override - public List getVendors() { - return new ArrayList<>(vendors.values()); - } - - /** - * Return the vendor object for a given id - * - * @param vendorId vendor id - * @return A {@link Vendor} object - */ - @Override - public Vendor getVendor(int vendorId) { - return vendors.get(vendorId); + private int gvlSpecificationVersion; + private int vendorListVersion; + private int tcfPolicyVersion; + private Instant lastUpdated; + private Map purposes; + private Map specialPurposes; + private Map features; + private Map specialFeatures; + private Map stacks; + private Map vendors; + private Map dataCategories; + + /** + * A Global Vendor List Specification Version + * + * @return global vendor list specification version + */ + @Override + public int getGvlSpecificationVersion() { + return gvlSpecificationVersion; + } + + /** + * A Global Vendor List version incremented with each published file change + * + * @return global vendor list version + */ + @Override + public int getVendorListVersion() { + return vendorListVersion; + } + + /** + * A TCF Policy Version. The TCF MO will increment this value whenever a GVL change (such as adding + * a new Purpose or Feature or a change in Purpose wording) legally invalidates existing TC Strings + * and requires CMPs to re-establish transparency and consent from users. TCF Policy changes should + * be relatively infrequent and only occur when necessary to support changes in global mandate. If + * the policy version number in the latest GVL is different from the value in your TC String, then + * you need to re-establish transparency and consent for that user. A version 1 format TC String is + * considered to have a version value of 1. + * + * @return tcf policy version + */ + @Override + public int getTcfPolicyVersion() { + return tcfPolicyVersion; + } + + /** + * Last Updated Date + * + * @return timestamp when the record was last updated + */ + @Override + public Instant getLastUpdated() { + return lastUpdated; + } + + /** + * A list of standard purposes + * + * @return A {@link List} of standard {@link Purpose} objects + */ + @Override + public List getPurposes() { + return new ArrayList<>(purposes.values()); + } + + /** + * A list of special purposes + * + * @return A {@link List} of {@link SpecialPurpose} objects + */ + @Override + public List getSpecialPurposes() { + return new ArrayList<>(specialPurposes.values()); + } + + /** + * A list of standard features + * + * @return A {@link List} of standard {@link Feature} objects + */ + @Override + public List getFeatures() { + return new ArrayList<>(features.values()); + } + + /** + * A list of special features + * + * @return A {@link List} of special {@link SpecialFeature} objects + */ + @Override + public List getSpecialFeatures() { + return new ArrayList<>(specialFeatures.values()); + } + + /** + * A list of stacks + * + * @return A {@link List} of {@link Stack} objects + */ + @Override + public List getStacks() { + return new ArrayList<>(stacks.values()); + } + + /** + * A list of vendors + * + * @return A {@link List} of {@link Vendor} objects + */ + @Override + public List getVendors() { + return new ArrayList<>(vendors.values()); + } + + /** + * Return the vendor object for a given id + * + * @param vendorId vendor id + * @return A {@link Vendor} object + */ + @Override + public Vendor getVendor(int vendorId) { + return vendors.get(vendorId); + } + + /** + * A list of data categories + * + * @return A {@link List} of {@link DataCategory} objects + */ + @Override + public Optional> getDataCategories() { + if (dataCategories == null) { + return Optional.empty(); + } else { + return Optional.ofNullable(new ArrayList<>(dataCategories.values())); } + } } diff --git a/iabgpp-extras-jackson/src/main/java/com/iab/gpp/extras/jackson/gvl/Overflow.java b/iabgpp-extras-jackson/src/main/java/com/iab/gpp/extras/jackson/gvl/Overflow.java index 075baf01..d837da26 100644 --- a/iabgpp-extras-jackson/src/main/java/com/iab/gpp/extras/jackson/gvl/Overflow.java +++ b/iabgpp-extras-jackson/src/main/java/com/iab/gpp/extras/jackson/gvl/Overflow.java @@ -23,15 +23,15 @@ public class Overflow implements com.iab.gpp.extras.gvl.Overflow { - private int httpGetLimit; + private int httpGetLimit; - /** - * The vendor's http GET request length limit; 32 or 128 are the only supported options - * - * @return vendor's http GET request length limit - */ - @Override - public int getHttpGetLimit() { - return httpGetLimit; - } + /** + * The vendor's http GET request length limit; 32 or 128 are the only supported options + * + * @return vendor's http GET request length limit + */ + @Override + public int getHttpGetLimit() { + return httpGetLimit; + } } diff --git a/iabgpp-extras-jackson/src/main/java/com/iab/gpp/extras/jackson/gvl/Purpose.java b/iabgpp-extras-jackson/src/main/java/com/iab/gpp/extras/jackson/gvl/Purpose.java index b42036db..12919c57 100644 --- a/iabgpp-extras-jackson/src/main/java/com/iab/gpp/extras/jackson/gvl/Purpose.java +++ b/iabgpp-extras-jackson/src/main/java/com/iab/gpp/extras/jackson/gvl/Purpose.java @@ -1,5 +1,8 @@ package com.iab.gpp.extras.jackson.gvl; +import java.util.List; +import java.util.Optional; + /*- * #%L * IAB TCF Java GVL Jackson @@ -25,72 +28,83 @@ */ public class Purpose implements com.iab.gpp.extras.gvl.Purpose { - private int id; - private String name; - private String description; - private String descriptionLegal; - private boolean consentable = true; - private boolean rightToObject = true; + private int id; + private String name; + private String description; + private String descriptionLegal; + private List illustrations; + private boolean consentable = true; + private boolean rightToObject = true; + + /** + * A purpose id + * + * @return purpose id + */ + @Override + public int getId() { + return id; + } - /** - * A purpose id - * - * @return purpose id - */ - @Override - public int getId() { - return id; - } + /** + * Name of the purpose + * + * @return purpose name string + */ + @Override + public String getName() { + return name; + } - /** - * Name of the purpose - * - * @return purpose name string - */ - @Override - public String getName() { - return name; - } + /** + * Description of the purpose + * + * @return purpose description string + */ + @Override + public String getDescription() { + return description; + } - /** - * Description of the purpose - * - * @return purpose description string - */ - @Override - public String getDescription() { - return description; - } + /** + * Legal description of the purpose + * + * @return legal description string + */ + @Override + public Optional getDescriptionLegal() { + return Optional.ofNullable(descriptionLegal); + } - /** - * Legal description of the purpose - * - * @return legal description string - */ - @Override - public String getDescriptionLegal() { - return descriptionLegal; - } + /** + * illustrations + * + * @return illustrations + */ + @Override + public Optional> getIllustrations() { + return Optional.ofNullable(illustrations); + } - /** - * An optional flag where false means CMPs should never afford users the means to provide an - * opt-in consent choice - * - * @return consentable boolean - */ - @Override - public boolean getConsentable() { - return consentable; - } + /** + * An optional flag where false means CMPs should never afford users the means to provide an opt-in + * consent choice + * + * @return consentable boolean + */ + @Override + public boolean getConsentable() { + return consentable; + } - /** - * An optional flag where false means CMPs should never afford users the means to exercise a - * right to object - * - * @return right to object boolean - */ - @Override - public boolean getRightToObject() { - return rightToObject; - } + /** + * An optional flag where false means CMPs should never afford users the means to exercise a right + * to object + * + * @return right to object boolean + */ + @Override + public boolean getRightToObject() { + return rightToObject; + } } diff --git a/iabgpp-extras-jackson/src/main/java/com/iab/gpp/extras/jackson/gvl/Stack.java b/iabgpp-extras-jackson/src/main/java/com/iab/gpp/extras/jackson/gvl/Stack.java index 6f1952f7..b2fb80df 100644 --- a/iabgpp-extras-jackson/src/main/java/com/iab/gpp/extras/jackson/gvl/Stack.java +++ b/iabgpp-extras-jackson/src/main/java/com/iab/gpp/extras/jackson/gvl/Stack.java @@ -28,59 +28,59 @@ */ public class Stack implements com.iab.gpp.extras.gvl.Stack { - private int id; - private List specialFeatures; - private List purposes; - private String name; - private String description; + private int id; + private List specialFeatures; + private List purposes; + private String name; + private String description; - /** - * Stack id - * - * @return stack id - */ - @Override - public int getId() { - return id; - } + /** + * Stack id + * + * @return stack id + */ + @Override + public int getId() { + return id; + } - /** - * A list of special features - * - * @return A {@link List} of special feature ids - */ - @Override - public List getSpecialFeatures() { - return specialFeatures; - } + /** + * A list of special features + * + * @return A {@link List} of special feature ids + */ + @Override + public List getSpecialFeatures() { + return specialFeatures; + } - /** - * A list of purposes - * - * @return A {@link List} of purpose ids - */ - @Override - public List getPurposes() { - return purposes; - } + /** + * A list of purposes + * + * @return A {@link List} of purpose ids + */ + @Override + public List getPurposes() { + return purposes; + } - /** - * Name of the stack - * - * @return stack name string - */ - @Override - public String getName() { - return name; - } + /** + * Name of the stack + * + * @return stack name string + */ + @Override + public String getName() { + return name; + } - /** - * Description of the stack - * - * @return stack description string - */ - @Override - public String getDescription() { - return description; - } + /** + * Description of the stack + * + * @return stack description string + */ + @Override + public String getDescription() { + return description; + } } diff --git a/iabgpp-extras-jackson/src/main/java/com/iab/gpp/extras/jackson/gvl/Vendor.java b/iabgpp-extras-jackson/src/main/java/com/iab/gpp/extras/jackson/gvl/Vendor.java index e0537876..de55cfee 100644 --- a/iabgpp-extras-jackson/src/main/java/com/iab/gpp/extras/jackson/gvl/Vendor.java +++ b/iabgpp-extras-jackson/src/main/java/com/iab/gpp/extras/jackson/gvl/Vendor.java @@ -23,209 +23,247 @@ import java.time.Instant; import java.util.List; import java.util.Optional; - +import com.iab.gpp.extras.gvl.DataRetention; import com.iab.gpp.extras.gvl.Overflow; +import com.iab.gpp.extras.gvl.VendorUrl; public class Vendor implements com.iab.gpp.extras.gvl.Vendor { - private int id; - private String name; - private List purposes; - private List legIntPurposes; - private List flexiblePurposes; - private List specialPurposes; - private List features; - private List specialFeatures; - private String policyUrl; - private Instant deletedDate; - private com.iab.gpp.extras.gvl.Overflow overflow; - private Long cookieMaxAgeSeconds; - private boolean usesCookies; - private boolean cookieRefresh; - private boolean usesNonCookieAccess; - private String deviceStorageDisclosureUrl; - - /** - * A vendor id: a numeric ID which is incrementally assigned and never re-used – deleted Vendors - * are just marked as deleted - * - * @return vendor id - */ - @Override - public int getId() { - return id; - } - - /** - * Name of the vendor - * - * @return vendor name - */ - @Override - public String getName() { - return name; - } - - /** - * List of Purposes for which the vendor is requesting consent - * - * @return A {@link List} of purpose ids that require consent - */ - @Override - public List getPurposes() { - return purposes; - } - - /** - * List of Purposes for which the vendor requires to be transparently disclosed as their - * legitimate interest - * - * @return A {@link List} of purpose ids disclosed as legitimate interests - */ - @Override - public List getLegIntPurposes() { - return legIntPurposes; - } - - /** - * List of purposes where the vendor is flexible regarding the legal basis; they will perform - * the processing based on consent or a legitimate interest. The 'default' is determined by - * which of the other two mutually-exclusive purpose fields is used to declare the purpose for - * the vendor - * - * @return A {@link List} of flexible purpose ids - */ - @Override - public List getFlexiblePurposes() { - return flexiblePurposes; - } - - /** - * List of Special Purposes that the vendor transparently discloses as their legitimate interest - * that a user has no right to object - * - * @return A {@link List} of special purpose ids - */ - @Override - public List getSpecialPurposes() { - return specialPurposes; - } - - /** - * List of Features the vendor uses across Purposes - * - * @return A {@link List} of features - */ - @Override - public List getFeatures() { - return features; - } - - /** - * List of Special Features the vendor uses across Purposes - * - * @return A {@link List} of special features - */ - @Override - public List getSpecialFeatures() { - return specialFeatures; - } - - /** - * GDPR/privacy policy page URL - * - * @return policy url string - */ - @Override - public String getPolicyUrl() { - return policyUrl; - } - - /** - * A date string representing when the vendor is deleted from the GVL - * - * @return date string - */ - @Override - public Optional getDeletedDate() { - return Optional.ofNullable(deletedDate); - } - - /** - * object specifying the vendor's http GET request length limit. It is optional. If a vendor - * entry does not include this attribute then the vendor has no overflow options and none can be - * inferred. - * - * @return A {@link com.iab.gpp.extras.gvl.Overflow} object - */ - @Override - public Optional getOverflow() { - return Optional.ofNullable(overflow); - } - - /** - * A helper method to check if the vendor is deleted based on the current time (UTC) - * - * @return true, if the vendor is deleted - */ - @Override - public boolean isDeleted() { - return Optional.ofNullable(this.deletedDate) - .map(deletedDate -> !deletedDate.isAfter(Instant.now())) - .orElse(false); - } - - /** - * The number of seconds representing the longest potential duration for cookie storage on a device. - * - * @return The number, in seconds, of the longest potential duration for storage on a device, as set when using the - * cookie method of storage. - */ - @Override - public Optional getCookieMaxAgeSeconds() { - return Optional.ofNullable(cookieMaxAgeSeconds); - } - - /** - * This boolean field indicates whether the vendor uses cookie storage (session or otherwise). - * - * @return True indicates cookie storage is used - */ - @Override - public boolean getUsesCookies() { - return usesCookies; - } - - /** - * This boolean field indicates whether any cookies in scope for cookieMaxAgeSeconds are refreshed after being - * initially set. - * - * @return True indicates the vendor refreshes this cookie - */ - @Override - public boolean getHasCookieRefresh() { - return cookieRefresh; - } - - /** - * This true or false field indicates whether the vendor uses other, non-cookie methods of storage or accessing - * information already stored on a user’s device. Examples of non-cookie storage and access may be localStorage, - * indexDB, mobile ad IDs, etc. - * - * @return True indicates non-cookie access is used - */ - @Override - public boolean getUsesNonCookieAccess() { - return usesNonCookieAccess; - } - - /** - * Link to a recommended, vendor-hosted, secure URL for disclosing additional storage information - * - * @return Location of vendor-hosted deviceStorage.json file - */ - @Override - public Optional getDeviceStorageDisclosureUrl() { - return Optional.ofNullable(deviceStorageDisclosureUrl); - } + private int id; + private String name; + private List purposes; + private List legIntPurposes; + private List impConsPurposes; + private List flexiblePurposes; + private List specialPurposes; + private List features; + private List specialFeatures; + private String policyUrl; + private Instant deletedDate; + private com.iab.gpp.extras.gvl.Overflow overflow; + private Long cookieMaxAgeSeconds; + private Boolean usesCookies; + private Boolean cookieRefresh; + private Boolean usesNonCookieAccess; + private String deviceStorageDisclosureUrl; + private DataRetention dataRetention; + private List urls; + private List dataDeclaration; + + /** + * A vendor id: a numeric ID which is incrementally assigned and never re-used – deleted Vendors are + * just marked as deleted + * + * @return vendor id + */ + @Override + public int getId() { + return id; + } + + /** + * Name of the vendor + * + * @return vendor name + */ + @Override + public String getName() { + return name; + } + + /** + * List of Purposes for which the vendor is requesting consent + * + * @return A {@link List} of purpose ids that require consent + */ + @Override + public List getPurposes() { + return purposes; + } + + /** + * List of Purposes for which the vendor requires to be transparently disclosed as their legitimate + * interest + * + * @return A {@link List} of purpose ids disclosed as legitimate interests + */ + @Override + public Optional> getLegIntPurposes() { + return Optional.ofNullable(legIntPurposes); + } + + /** + * List of Purposes for which the vendor requires to be transparently disclosed as implied Consent + * + * @return A {@link List} of purpose ids disclosed as legitimate interests + */ + @Override + public Optional> getImpConsPurposes() { + return Optional.ofNullable(impConsPurposes); + } + + /** + * List of purposes where the vendor is flexible regarding the legal basis; they will perform the + * processing based on consent or a legitimate interest. The 'default' is determined by which of the + * other two mutually-exclusive purpose fields is used to declare the purpose for the vendor + * + * @return A {@link List} of flexible purpose ids + */ + @Override + public List getFlexiblePurposes() { + return flexiblePurposes; + } + + /** + * List of Special Purposes that the vendor transparently discloses as their legitimate interest + * that a user has no right to object + * + * @return A {@link List} of special purpose ids + */ + @Override + public List getSpecialPurposes() { + return specialPurposes; + } + + /** + * List of Features the vendor uses across Purposes + * + * @return A {@link List} of features + */ + @Override + public List getFeatures() { + return features; + } + + /** + * List of Special Features the vendor uses across Purposes + * + * @return A {@link List} of special features + */ + @Override + public List getSpecialFeatures() { + return specialFeatures; + } + + /** + * GDPR/privacy policy page URL + * + * @return policy url string + */ + @Override + public Optional getPolicyUrl() { + return Optional.ofNullable(policyUrl); + } + + /** + * A date string representing when the vendor is deleted from the GVL + * + * @return date string + */ + @Override + public Optional getDeletedDate() { + return Optional.ofNullable(deletedDate); + } + + /** + * object specifying the vendor's http GET request length limit. It is optional. If a vendor entry + * does not include this attribute then the vendor has no overflow options and none can be inferred. + * + * @return A {@link com.iab.gpp.extras.gvl.Overflow} object + */ + @Override + public Optional getOverflow() { + return Optional.ofNullable(overflow); + } + + /** + * A helper method to check if the vendor is deleted based on the current time (UTC) + * + * @return true, if the vendor is deleted + */ + @Override + public boolean isDeleted() { + return Optional.ofNullable(this.deletedDate).map(deletedDate -> !deletedDate.isAfter(Instant.now())).orElse(false); + } + + /** + * The number of seconds representing the longest potential duration for cookie storage on a device. + * + * @return The number, in seconds, of the longest potential duration for storage on a device, as set + * when using the cookie method of storage. + */ + @Override + public Optional getCookieMaxAgeSeconds() { + return Optional.ofNullable(cookieMaxAgeSeconds); + } + + /** + * This boolean field indicates whether the vendor uses cookie storage (session or otherwise). + * + * @return True indicates cookie storage is used + */ + @Override + public Optional getUsesCookies() { + return Optional.ofNullable(usesCookies); + } + + /** + * This boolean field indicates whether any cookies in scope for cookieMaxAgeSeconds are refreshed + * after being initially set. + * + * @return True indicates the vendor refreshes this cookie + */ + @Override + public Optional getCookieRefresh() { + return Optional.ofNullable(cookieRefresh); + } + + /** + * This true or false field indicates whether the vendor uses other, non-cookie methods of storage + * or accessing information already stored on a user’s device. Examples of non-cookie storage and + * access may be localStorage, indexDB, mobile ad IDs, etc. + * + * @return True indicates non-cookie access is used + */ + @Override + public Optional getUsesNonCookieAccess() { + return Optional.ofNullable(usesNonCookieAccess); + } + + /** + * Link to a recommended, vendor-hosted, secure URL for disclosing additional storage information + * + * @return Location of vendor-hosted deviceStorage.json file + */ + @Override + public Optional getDeviceStorageDisclosureUrl() { + return Optional.ofNullable(deviceStorageDisclosureUrl); + } + + /** + * dataRetention + * + * @return dataRetention + */ + public Optional getDataRetention() { + return Optional.ofNullable(dataRetention); + } + + /** + * urls + * + * @return urls + */ + public Optional> getUrls() { + return Optional.ofNullable(urls); + } + + /** + * dataDeclarations + * + * @return dataDeclarations + */ + public Optional> getDataDeclaration() { + return Optional.ofNullable(dataDeclaration); + } } diff --git a/iabgpp-extras-jackson/src/main/java/com/iab/gpp/extras/jackson/gvl/VendorUrl.java b/iabgpp-extras-jackson/src/main/java/com/iab/gpp/extras/jackson/gvl/VendorUrl.java new file mode 100644 index 00000000..cf4d3b86 --- /dev/null +++ b/iabgpp-extras-jackson/src/main/java/com/iab/gpp/extras/jackson/gvl/VendorUrl.java @@ -0,0 +1,64 @@ +package com.iab.gpp.extras.jackson.gvl; + +import java.util.Optional; + +/*- + * #%L + * IAB TCF Java GVL Jackson + * %% + * Copyright (C) 2020 IAB Technology Laboratory, Inc + * %% + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * #L% + */ + +/* + * DataCategory + */ +public class VendorUrl implements com.iab.gpp.extras.gvl.VendorUrl { + + private String langId; + private String privacy; + private String legIntClaim; + + /** + * langId + * + * @return lang id + */ + @Override + public String getLangId() { + return langId; + } + + /** + * privacy + * + * @return privacy + */ + @Override + public String getPrivacy() { + return privacy; + } + + /** + * legIntClaim + * + * @return legIntClaim + */ + @Override + public Optional getLegIntClaim() { + return Optional.ofNullable(legIntClaim); + } + +} diff --git a/iabgpp-extras-jackson/src/test/java/com/iab/gpp/extras/jackson/cmp/CmpListTest.java b/iabgpp-extras-jackson/src/test/java/com/iab/gpp/extras/jackson/cmp/CmpListTest.java index 98ca8447..673ad24f 100644 --- a/iabgpp-extras-jackson/src/test/java/com/iab/gpp/extras/jackson/cmp/CmpListTest.java +++ b/iabgpp-extras-jackson/src/test/java/com/iab/gpp/extras/jackson/cmp/CmpListTest.java @@ -1,5 +1,12 @@ package com.iab.gpp.extras.jackson.cmp; +import java.io.IOException; +import java.time.Instant; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.Test; +import com.iab.gpp.extras.cmp.Cmp; + /*- * #%L * IAB TCF Java CMP List Jackson @@ -21,32 +28,56 @@ */ import com.iab.gpp.extras.cmp.CmpList; -import com.iab.gpp.extras.jackson.TestUtil; import com.iab.gpp.extras.jackson.Loader; -import org.junit.Assert; -import org.junit.BeforeClass; -import org.junit.Test; - -import java.io.IOException; -import java.time.Instant; public class CmpListTest { - private static CmpList cmpList; + private static CmpList cmpList; + private static Cmp cmpThree; + private static Cmp cmpTwentyThree; + + @BeforeAll + public static void setUpBeforeClass() throws IOException { + cmpList = new Loader().cmpList(CmpListTest.class.getClassLoader().getResourceAsStream("cmpList.json")); + cmpThree = cmpList.getCmps().stream().filter(o -> o.getId() == 3).findFirst().orElse(null); + cmpTwentyThree = cmpList.getCmps().stream().filter(o -> o.getId() == 23).findFirst().orElse(null); + } + + @Test + public void getLastUpdated() { + Assertions.assertEquals(Instant.parse("2020-04-09T17:03:06Z"), cmpList.getLastUpdated()); + } + + @Test + public void getCmps() { + Assertions.assertEquals(12, cmpList.getCmps().size()); + } + + @Test + public void getId() { + Assertions.assertEquals(3, cmpThree.getId()); + } + + @Test + public void getName() { + String name = "LiveRamp"; + Assertions.assertEquals(name, cmpThree.getName()); + } - @BeforeClass - public static void setUpBeforeClass() throws IOException { - Loader loader = new Loader(); - cmpList = loader.cmpList(TestUtil.getCmpList()); - } + @Test + public void isCommercial() { + Assertions.assertTrue(cmpThree.isCommercial()); + } - @Test - public void getLastUpdated() { - Assert.assertEquals(Instant.parse("2020-04-09T17:03:06Z"), cmpList.getLastUpdated()); - } + @Test + public void getDeletedDate() { + Assertions.assertNull(cmpThree.getDeletedDate().orElse(null)); + Assertions.assertNotNull(cmpTwentyThree.getDeletedDate().orElse(null)); + } - @Test - public void getCmps() { - Assert.assertEquals(12, cmpList.getCmps().size()); - } -} \ No newline at end of file + @Test + public void isDeleted() { + Assertions.assertFalse(cmpThree.isDeleted()); + Assertions.assertTrue(cmpTwentyThree.isDeleted()); + } +} diff --git a/iabgpp-extras-jackson/src/test/java/com/iab/gpp/extras/jackson/cmp/CmpTest.java b/iabgpp-extras-jackson/src/test/java/com/iab/gpp/extras/jackson/cmp/CmpTest.java deleted file mode 100644 index d6f54381..00000000 --- a/iabgpp-extras-jackson/src/test/java/com/iab/gpp/extras/jackson/cmp/CmpTest.java +++ /dev/null @@ -1,76 +0,0 @@ -package com.iab.gpp.extras.jackson.cmp; - -/*- - * #%L - * IAB TCF Java CMP List Jackson - * %% - * Copyright (C) 2020 IAB Technology Laboratory, Inc - * %% - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * #L% - */ - -import com.iab.gpp.extras.cmp.Cmp; -import com.iab.gpp.extras.jackson.TestUtil; -import com.iab.gpp.extras.jackson.Loader; -import org.junit.Assert; -import org.junit.BeforeClass; -import org.junit.Test; - -import java.io.IOException; -import java.util.List; - -public class CmpTest { - - private static Cmp cmpThree; - private static Cmp cmpTwentyThree; - private static final int CMP_ID_SELECTED_FOR_TEST = 3; - private static final int DELETED_CMP_ID_SELECTED_FOR_TEST = 23; - - @BeforeClass - public static void setupBeforeClass() throws IOException { - Loader loader = new Loader(); - List cmps = loader.cmpList(TestUtil.getCmpList()).getCmps(); - cmpThree = cmps.stream().filter(o -> o.getId() == CMP_ID_SELECTED_FOR_TEST).findFirst().orElse(null); - cmpTwentyThree = - cmps.stream().filter(o -> o.getId() == DELETED_CMP_ID_SELECTED_FOR_TEST).findFirst().orElse(null); - } - - @Test - public void getId() { - Assert.assertEquals(3, cmpThree.getId()); - } - - @Test - public void getName() { - String name = "LiveRamp"; - Assert.assertEquals(name, cmpThree.getName()); - } - - @Test - public void isCommercial() { - Assert.assertTrue(cmpThree.isCommercial()); - } - - @Test - public void getDeletedDate() { - Assert.assertNull(cmpThree.getDeletedDate().orElse(null)); - Assert.assertNotNull(cmpTwentyThree.getDeletedDate().orElse(null)); - } - - @Test - public void isDeleted() { - Assert.assertFalse(cmpThree.isDeleted()); - Assert.assertTrue(cmpTwentyThree.isDeleted()); - } -} \ No newline at end of file diff --git a/iabgpp-extras-jackson/src/test/java/com/iab/gpp/extras/jackson/gvl/FeatureTest.java b/iabgpp-extras-jackson/src/test/java/com/iab/gpp/extras/jackson/gvl/FeatureTest.java deleted file mode 100644 index 261ee812..00000000 --- a/iabgpp-extras-jackson/src/test/java/com/iab/gpp/extras/jackson/gvl/FeatureTest.java +++ /dev/null @@ -1,69 +0,0 @@ -package com.iab.gpp.extras.jackson.gvl; - -/*- - * #%L - * IAB TCF Java GVL Jackson - * %% - * Copyright (C) 2020 IAB Technology Laboratory, Inc - * %% - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * #L% - */ - -import com.iab.gpp.extras.gvl.Feature; -import com.iab.gpp.extras.jackson.TestUtil; -import com.iab.gpp.extras.jackson.Loader; -import org.junit.Assert; -import org.junit.BeforeClass; -import org.junit.Test; - -import java.io.IOException; -import java.util.List; - -public class FeatureTest { - - private static Feature featureTwo; - private static final int FEATURE_ID_SELECTED_FOR_TEST = 2; - - @BeforeClass - public static void setupBeforeClass() throws IOException { - Loader loader = new Loader(); - List features = loader.globalVendorList(TestUtil.getGlobalVendorList()).getFeatures(); - featureTwo = features.stream().filter(o -> o.getId() == FEATURE_ID_SELECTED_FOR_TEST).findFirst().orElse(null); - } - - @Test - public void testGetId() { - Assert.assertEquals(2, featureTwo.getId()); - } - - @Test - public void testGetName() { - String expectedName = "Link different devices"; - Assert.assertEquals(expectedName, featureTwo.getName()); - } - - @Test - public void testGetDescription() { - String expectedDescription = - "Different devices can be determined as belonging to you or your household in support of one or more of purposes."; - Assert.assertEquals(expectedDescription, featureTwo.getDescription()); - } - - @Test - public void testGetDescriptionLegal() { - String expectedDescriptionLegal = - "Vendors can:\n* Deterministically determine that two or more devices belong to the same user or household\n* Probabilistically determine that two or more devices belong to the same user or household\n* Actively scan device characteristics for identification for probabilistic identification if users have allowed vendors to actively scan device characteristics for identification (Special Feature 2)"; - Assert.assertEquals(expectedDescriptionLegal, featureTwo.getDescriptionLegal()); - } -} diff --git a/iabgpp-extras-jackson/src/test/java/com/iab/gpp/extras/jackson/gvl/GvlCanadaTest.java b/iabgpp-extras-jackson/src/test/java/com/iab/gpp/extras/jackson/gvl/GvlCanadaTest.java new file mode 100644 index 00000000..8f665014 --- /dev/null +++ b/iabgpp-extras-jackson/src/test/java/com/iab/gpp/extras/jackson/gvl/GvlCanadaTest.java @@ -0,0 +1,104 @@ +package com.iab.gpp.extras.jackson.gvl; + +import com.iab.gpp.extras.gvl.Gvl; +import com.iab.gpp.extras.jackson.Loader; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; + +import java.io.IOException; +import java.util.Arrays; +import java.util.Collections; + +public class GvlCanadaTest { + @Test + public void test() throws IOException { + Gvl gvl = new Loader() + .globalVendorList(GvlV2Test.class.getClassLoader().getResourceAsStream("vendorlist/v2/ca/vendor-list.json")); + Assertions.assertFalse(gvl.getDataCategories().isPresent()); + Assertions.assertEquals(3, gvl.getFeatures().size()); + Assertions.assertEquals(2, gvl.getGvlSpecificationVersion()); + Assertions.assertNotNull(gvl.getLastUpdated()); + Assertions.assertEquals(10, gvl.getPurposes().size()); + Assertions.assertEquals(2, gvl.getSpecialFeatures().size()); + Assertions.assertEquals(2, gvl.getSpecialPurposes().size()); + Assertions.assertEquals(42, gvl.getStacks().size()); + Assertions.assertEquals(2, gvl.getTcfPolicyVersion()); + Assertions.assertEquals(45, gvl.getVendorListVersion()); + Assertions.assertEquals(36, gvl.getVendors().size()); + + Assertions.assertEquals(1, gvl.getPurposes().get(0).getId()); + Assertions.assertEquals("Store and/or access information on a device", gvl.getPurposes().get(0).getName()); + Assertions.assertEquals( + "Cookies, device identifiers, or other information can be stored or accessed on your device for the purposes presented to you.", + gvl.getPurposes().get(0).getDescription()); + Assertions.assertTrue(gvl.getPurposes().get(0).getDescriptionLegal().isPresent()); + Assertions.assertEquals( + "Vendors can:\n* Store and access information on the device such as cookies and device identifiers presented to a user.", + gvl.getPurposes().get(0).getDescriptionLegal().get()); + Assertions.assertFalse(gvl.getPurposes().get(0).getIllustrations().isPresent()); + + Assertions.assertEquals(1, gvl.getSpecialPurposes().get(0).getId()); + Assertions.assertEquals("Ensure security, prevent fraud, and debug", gvl.getSpecialPurposes().get(0).getName()); + Assertions.assertEquals( + "Your data can be used to monitor for and prevent fraudulent activity, and ensure systems and processes work properly and securely.", + gvl.getSpecialPurposes().get(0).getDescription()); + Assertions.assertTrue(gvl.getSpecialPurposes().get(0).getDescriptionLegal().isPresent()); + Assertions.assertEquals( + "To ensure security, prevent fraud and debug vendors can:\n* Ensure data are securely transmitted\n* Detect and prevent malicious, fraudulent, invalid, or illegal activity.\n* Ensure correct and efficient operation of systems and processes, including to monitor and enhance the performance of systems and processes engaged in permitted purposes\nVendors cannot:\n* Conduct any other data processing operation allowed under a different purpose under this purpose.\nNote: Data collected and used to ensure security, prevent fraud, and debug may include automatically-sent device characteristics for identification, precise geolocation data, and data obtained by actively scanning device characteristics for identification without separate disclosure and/or opt-in.", + gvl.getSpecialPurposes().get(0).getDescriptionLegal().get()); + Assertions.assertFalse(gvl.getSpecialPurposes().get(0).getIllustrations().isPresent()); + + Assertions.assertEquals(1, gvl.getFeatures().get(0).getId()); + Assertions.assertEquals("Match and combine offline data sources", gvl.getFeatures().get(0).getName()); + Assertions.assertEquals( + "Data from offline data sources can be combined with your online activity in support of one or more purposes", + gvl.getFeatures().get(0).getDescription()); + Assertions.assertTrue(gvl.getFeatures().get(0).getDescriptionLegal().isPresent()); + Assertions.assertEquals( + "Vendors can:\n* Combine data obtained offline with data collected online in support of one or more Purposes or Special Purposes.", + gvl.getFeatures().get(0).getDescriptionLegal().get()); + Assertions.assertFalse(gvl.getFeatures().get(0).getIllustrations().isPresent()); + + Assertions.assertEquals(1, gvl.getSpecialFeatures().get(0).getId()); + Assertions.assertEquals("Use precise geolocation data", gvl.getSpecialFeatures().get(0).getName()); + Assertions.assertEquals( + "Your precise geolocation data can be used in support of one or more purposes. This means your location can be accurate to within several meters.", + gvl.getSpecialFeatures().get(0).getDescription()); + Assertions.assertTrue(gvl.getSpecialFeatures().get(0).getDescriptionLegal().isPresent()); + Assertions.assertEquals( + "Vendors can:\n* Collect and process precise geolocation data in support of one or more purposes.\nN.B. Precise geolocation means that there are no restrictions on the precision of a user’s location; this can be accurate to within several meters.", + gvl.getSpecialFeatures().get(0).getDescriptionLegal().get()); + Assertions.assertFalse(gvl.getSpecialFeatures().get(0).getIllustrations().isPresent()); + + Assertions.assertEquals(1, gvl.getStacks().get(0).getId()); + Assertions.assertEquals("Precise geolocation data, and identification through device scanning", gvl.getStacks().get(0).getName()); + Assertions.assertEquals("Precise geolocation and information about device characteristics can be used.", gvl.getStacks().get(0).getDescription()); + Assertions.assertTrue(gvl.getStacks().get(0).getPurposes().isEmpty()); + Assertions.assertEquals(Arrays.asList(1, 2), gvl.getStacks().get(0).getSpecialFeatures()); + + Assertions.assertEquals(2, gvl.getStacks().get(1).getId()); + Assertions.assertEquals("Basic ads, and ad measurement", gvl.getStacks().get(1).getName()); + Assertions.assertEquals("Basic ads can be served. Ad performance can be measured.", gvl.getStacks().get(1).getDescription()); + Assertions.assertEquals(Arrays.asList(2, 7), gvl.getStacks().get(1).getPurposes()); + Assertions.assertTrue(gvl.getStacks().get(1).getSpecialFeatures().isEmpty()); + + Assertions.assertEquals(10, gvl.getVendors().get(0).getId()); + Assertions.assertFalse(gvl.getVendors().get(0).getDeletedDate().isPresent()); + Assertions.assertEquals("Index Exchange Inc. ", gvl.getVendors().get(0).getName()); + Assertions.assertEquals(Arrays.asList(2, 7), gvl.getVendors().get(0).getPurposes()); + Assertions.assertFalse(gvl.getVendors().get(0).getLegIntPurposes().isPresent()); + Assertions.assertTrue(gvl.getVendors().get(0).getImpConsPurposes().isPresent()); + Assertions.assertEquals(Collections.emptyList(), gvl.getVendors().get(0).getImpConsPurposes().get()); + Assertions.assertEquals(Arrays.asList(2, 7), gvl.getVendors().get(0).getFlexiblePurposes()); + Assertions.assertEquals(Arrays.asList(1, 2), gvl.getVendors().get(0).getSpecialPurposes()); + Assertions.assertEquals(Collections.singletonList(3), gvl.getVendors().get(0).getFeatures()); + Assertions.assertEquals(Collections.singletonList(1), gvl.getVendors().get(0).getSpecialFeatures()); + Assertions.assertTrue(gvl.getVendors().get(0).getUrls().isPresent()); + Assertions.assertEquals("https://www.indexexchange.com/privacy/", + gvl.getVendors().get(0).getUrls().get().get(0).getPrivacy()); + Assertions.assertEquals("en", + gvl.getVendors().get(0).getUrls().get().get(0).getLangId()); + Assertions.assertEquals(52, gvl.getVendors().get(1).getId()); + Assertions.assertFalse(gvl.getVendors().get(1).getDeletedDate().isPresent()); + } +} diff --git a/iabgpp-extras-jackson/src/test/java/com/iab/gpp/extras/jackson/gvl/GvlTest.java b/iabgpp-extras-jackson/src/test/java/com/iab/gpp/extras/jackson/gvl/GvlTest.java deleted file mode 100644 index 2ffeae12..00000000 --- a/iabgpp-extras-jackson/src/test/java/com/iab/gpp/extras/jackson/gvl/GvlTest.java +++ /dev/null @@ -1,98 +0,0 @@ -package com.iab.gpp.extras.jackson.gvl; - -/*- - * #%L - * IAB TCF Java GVL Jackson - * %% - * Copyright (C) 2020 IAB Technology Laboratory, Inc - * %% - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * #L% - */ - -import java.io.IOException; -import java.text.ParseException; -import java.text.SimpleDateFormat; -import java.util.Date; -import java.util.TimeZone; - -import com.iab.gpp.extras.jackson.TestUtil; -import com.iab.gpp.extras.jackson.Loader; -import org.junit.Assert; -import org.junit.BeforeClass; -import org.junit.Test; - -import com.iab.gpp.extras.gvl.Gvl; - -public class GvlTest { - private static Gvl gvl; - - @BeforeClass - public static void setUpBeforeClass() throws IOException { - Loader loader = new Loader(); - gvl = loader.globalVendorList(TestUtil.getGlobalVendorList()); - } - - @Test - public void testGetGvlSpecificationVersion() { - Assert.assertEquals(2, gvl.getGvlSpecificationVersion()); - } - - @Test - public void testGetVendorListVersion() { - Assert.assertEquals(26, gvl.getVendorListVersion()); - } - - @Test - public void testGetTcfPolicyVersion() { - Assert.assertEquals(2, gvl.getTcfPolicyVersion()); - } - - @Test - public void testGetLastUpdated() throws ParseException { - SimpleDateFormat parser = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss"); - parser.setTimeZone(TimeZone.getTimeZone("GMT")); - Date parsed = parser.parse("2020-02-20T16:05:20"); - Assert.assertEquals(parsed.toInstant(), gvl.getLastUpdated()); - } - - @Test - public void testGetPurposes() { - Assert.assertEquals(10, gvl.getPurposes().size()); - } - - @Test - public void testGetSpecialPurposes() { - Assert.assertEquals(2, gvl.getSpecialPurposes().size()); - } - - @Test - public void testGetFeatures() { - Assert.assertEquals(3, gvl.getFeatures().size()); - } - - @Test - public void testGetSpecialFeatures() { - Assert.assertEquals(2, gvl.getSpecialFeatures().size()); - } - - @Test - public void testGetStacks() { - Assert.assertEquals(37, gvl.getStacks().size()); - } - - @Test - public void testGetVendors() { - Assert.assertEquals(3, gvl.getVendors().size()); - } -} diff --git a/iabgpp-extras-jackson/src/test/java/com/iab/gpp/extras/jackson/gvl/GvlV2Test.java b/iabgpp-extras-jackson/src/test/java/com/iab/gpp/extras/jackson/gvl/GvlV2Test.java new file mode 100644 index 00000000..04ba44c9 --- /dev/null +++ b/iabgpp-extras-jackson/src/test/java/com/iab/gpp/extras/jackson/gvl/GvlV2Test.java @@ -0,0 +1,122 @@ +package com.iab.gpp.extras.jackson.gvl; + +/*- + * #%L + * IAB TCF Java GVL Jackson + * %% + * Copyright (C) 2020 IAB Technology Laboratory, Inc + * %% + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * #L% + */ + +import java.io.IOException; +import java.util.Arrays; +import java.util.List; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; +import com.iab.gpp.extras.gvl.Gvl; +import com.iab.gpp.extras.jackson.Loader; + +public class GvlV2Test { + + @Test + public void test() throws IOException { + Gvl gvl = new Loader() + .globalVendorList(GvlV2Test.class.getClassLoader().getResourceAsStream("vendorlist/v2/vendor-list.json")); + Assertions.assertFalse(gvl.getDataCategories().isPresent()); + Assertions.assertEquals(3, gvl.getFeatures().size()); + Assertions.assertEquals(2, gvl.getGvlSpecificationVersion()); + Assertions.assertNotNull(gvl.getLastUpdated()); + Assertions.assertEquals(10, gvl.getPurposes().size()); + Assertions.assertEquals(2, gvl.getSpecialFeatures().size()); + Assertions.assertEquals(2, gvl.getSpecialPurposes().size()); + Assertions.assertEquals(42, gvl.getStacks().size()); + Assertions.assertEquals(2, gvl.getTcfPolicyVersion()); + Assertions.assertEquals(51, gvl.getVendorListVersion()); + Assertions.assertEquals(496, gvl.getVendors().size()); + + Assertions.assertEquals(1, gvl.getPurposes().get(0).getId()); + Assertions.assertEquals("Store and/or access information on a device", gvl.getPurposes().get(0).getName()); + Assertions.assertEquals( + "Cookies, device identifiers, or other information can be stored or accessed on your device for the purposes presented to you.", + gvl.getPurposes().get(0).getDescription()); + Assertions.assertTrue(gvl.getPurposes().get(0).getDescriptionLegal().isPresent()); + Assertions.assertEquals( + "Vendors can:\n* Store and access information on the device such as cookies and device identifiers presented to a user.", + gvl.getPurposes().get(0).getDescriptionLegal().get()); + Assertions.assertFalse(gvl.getPurposes().get(0).getIllustrations().isPresent()); + + Assertions.assertEquals(1, gvl.getSpecialPurposes().get(0).getId()); + Assertions.assertEquals("Ensure security, prevent fraud, and debug", gvl.getSpecialPurposes().get(0).getName()); + Assertions.assertEquals( + "Your data can be used to monitor for and prevent fraudulent activity, and ensure systems and processes work properly and securely.", + gvl.getSpecialPurposes().get(0).getDescription()); + Assertions.assertTrue(gvl.getSpecialPurposes().get(0).getDescriptionLegal().isPresent()); + Assertions.assertEquals( + "To ensure security, prevent fraud and debug vendors can:\n* Ensure data are securely transmitted\n* Detect and prevent malicious, fraudulent, invalid, or illegal activity.\n* Ensure correct and efficient operation of systems and processes, including to monitor and enhance the performance of systems and processes engaged in permitted purposes\nVendors cannot:\n* Conduct any other data processing operation allowed under a different purpose under this purpose.", + gvl.getSpecialPurposes().get(0).getDescriptionLegal().get()); + Assertions.assertFalse(gvl.getSpecialPurposes().get(0).getIllustrations().isPresent()); + + Assertions.assertEquals(1, gvl.getFeatures().get(0).getId()); + Assertions.assertEquals("Match and combine offline data sources", gvl.getFeatures().get(0).getName()); + Assertions.assertEquals( + "Data from offline data sources can be combined with your online activity in support of one or more purposes", + gvl.getFeatures().get(0).getDescription()); + Assertions.assertTrue(gvl.getFeatures().get(0).getDescriptionLegal().isPresent()); + Assertions.assertEquals( + "Vendors can:\n* Combine data obtained offline with data collected online in support of one or more Purposes or Special Purposes.", + gvl.getFeatures().get(0).getDescriptionLegal().get()); + Assertions.assertFalse(gvl.getFeatures().get(0).getIllustrations().isPresent()); + + Assertions.assertEquals(1, gvl.getSpecialFeatures().get(0).getId()); + Assertions.assertEquals("Use precise geolocation data", gvl.getSpecialFeatures().get(0).getName()); + Assertions.assertEquals( + "Your precise geolocation data can be used in support of one or more purposes. This means your location can be accurate to within several meters.", + gvl.getSpecialFeatures().get(0).getDescription()); + Assertions.assertTrue(gvl.getSpecialFeatures().get(0).getDescriptionLegal().isPresent()); + Assertions.assertEquals( + "Vendors can:\n* Collect and process precise geolocation data in support of one or more purposes.\nN.B. Precise geolocation means that there are no restrictions on the precision of a user’s location; this can be accurate to within several meters.", + gvl.getSpecialFeatures().get(0).getDescriptionLegal().get()); + Assertions.assertFalse(gvl.getSpecialFeatures().get(0).getIllustrations().isPresent()); + + Assertions.assertEquals(1, gvl.getStacks().get(0).getId()); + Assertions.assertEquals("Precise geolocation data, and identification through device scanning", gvl.getStacks().get(0).getName()); + Assertions.assertEquals("Precise geolocation and information about device characteristics can be used.", gvl.getStacks().get(0).getDescription()); + Assertions.assertTrue(gvl.getStacks().get(0).getPurposes().isEmpty()); + Assertions.assertEquals(Arrays.asList(1, 2), gvl.getStacks().get(0).getSpecialFeatures()); + + Assertions.assertEquals(2, gvl.getStacks().get(1).getId()); + Assertions.assertEquals("Basic ads, and ad measurement", gvl.getStacks().get(1).getName()); + Assertions.assertEquals("Basic ads can be served. Ad performance can be measured.", gvl.getStacks().get(1).getDescription()); + Assertions.assertEquals(Arrays.asList(2, 7), gvl.getStacks().get(1).getPurposes()); + Assertions.assertTrue(gvl.getStacks().get(1).getSpecialFeatures().isEmpty()); + + Assertions.assertEquals(8, gvl.getVendors().get(0).getId()); + Assertions.assertFalse(gvl.getVendors().get(0).getDeletedDate().isPresent()); + Assertions.assertEquals("Emerse Sverige AB", gvl.getVendors().get(0).getName()); + Assertions.assertEquals(Arrays.asList(1, 3, 4), gvl.getVendors().get(0).getPurposes()); + Assertions.assertTrue(gvl.getVendors().get(0).getLegIntPurposes().isPresent()); + Assertions.assertEquals(Arrays.asList(2, 7, 8, 9), gvl.getVendors().get(0).getLegIntPurposes().get()); + Assertions.assertEquals(Arrays.asList(2, 9), gvl.getVendors().get(0).getFlexiblePurposes()); + Assertions.assertEquals(Arrays.asList(1, 2), gvl.getVendors().get(0).getSpecialPurposes()); + Assertions.assertEquals(Arrays.asList(1, 2), gvl.getVendors().get(0).getFeatures()); + Assertions.assertTrue(gvl.getVendors().get(0).getSpecialFeatures().isEmpty()); + Assertions.assertTrue(gvl.getVendors().get(0).getPolicyUrl().isPresent()); + Assertions.assertEquals("https://www.emerse.com/privacy-policy/", gvl.getVendors().get(0).getPolicyUrl().get()); + + Assertions.assertEquals(9, gvl.getVendors().get(1).getId()); + Assertions.assertTrue(gvl.getVendors().get(1).getDeletedDate().isPresent()); + } + +} diff --git a/iabgpp-extras-jackson/src/test/java/com/iab/gpp/extras/jackson/gvl/GvlV3Test.java b/iabgpp-extras-jackson/src/test/java/com/iab/gpp/extras/jackson/gvl/GvlV3Test.java new file mode 100644 index 00000000..e27831f1 --- /dev/null +++ b/iabgpp-extras-jackson/src/test/java/com/iab/gpp/extras/jackson/gvl/GvlV3Test.java @@ -0,0 +1,171 @@ +package com.iab.gpp.extras.jackson.gvl; + +/*- + * #%L + * IAB TCF Java GVL Jackson + * %% + * Copyright (C) 2020 IAB Technology Laboratory, Inc + * %% + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * #L% + */ + +import java.io.IOException; +import java.util.Arrays; +import java.util.Collections; + +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; +import com.iab.gpp.extras.gvl.Gvl; +import com.iab.gpp.extras.jackson.Loader; + +public class GvlV3Test { + + @Test + public void test() throws IOException { + Gvl gvl = new Loader() + .globalVendorList(GvlV3Test.class.getClassLoader().getResourceAsStream("vendorlist/v3.0/vendor-list.json")); + Assertions.assertTrue(gvl.getDataCategories().isPresent()); + Assertions.assertEquals(3, gvl.getFeatures().size()); + Assertions.assertEquals(3, gvl.getGvlSpecificationVersion()); + Assertions.assertNotNull(gvl.getLastUpdated()); + Assertions.assertEquals(11, gvl.getPurposes().size()); + Assertions.assertEquals(2, gvl.getSpecialFeatures().size()); + Assertions.assertEquals(2, gvl.getSpecialPurposes().size()); + Assertions.assertEquals(43, gvl.getStacks().size()); + Assertions.assertEquals(4, gvl.getTcfPolicyVersion()); + Assertions.assertEquals(7, gvl.getVendorListVersion()); + Assertions.assertEquals(376, gvl.getVendors().size()); + + Assertions.assertEquals(1, gvl.getPurposes().get(0).getId()); + Assertions.assertEquals("Store and/or access information on a device", gvl.getPurposes().get(0).getName()); + Assertions.assertEquals("Cookies, device or similar online identifiers (e.g. login-based identifiers, randomly assigned identifiers, network based identifiers) together with other information (e.g. browser type and information, language, screen size, supported technologies etc.) can be stored or read on your device to recognise it each time it connects to an app or to a website, for one or several of the purposes presented here. ", gvl.getPurposes().get(0).getDescription()); + Assertions.assertFalse(gvl.getPurposes().get(0).getDescriptionLegal().isPresent()); + Assertions.assertTrue(gvl.getPurposes().get(0).getIllustrations().isPresent()); + Assertions.assertEquals(1, gvl.getPurposes().get(0).getIllustrations().get().size()); + + Assertions.assertEquals(1, gvl.getSpecialPurposes().get(0).getId()); + Assertions.assertEquals("Ensure security, prevent and detect fraud, and fix errors\n", gvl.getSpecialPurposes().get(0).getName()); + Assertions.assertEquals("Your data can be used to monitor for and prevent unusual and possibly fraudulent activity (for example, regarding advertising, ad clicks by bots), and ensure systems and processes work properly and securely. It can also be used to correct any problems you, the publisher or the advertiser may encounter in the delivery of content and ads and in your interaction with them.", gvl.getSpecialPurposes().get(0).getDescription()); + Assertions.assertFalse(gvl.getSpecialPurposes().get(0).getDescriptionLegal().isPresent()); + Assertions.assertTrue(gvl.getSpecialPurposes().get(0).getIllustrations().isPresent()); + Assertions.assertEquals(1, gvl.getSpecialPurposes().get(0).getIllustrations().get().size()); + + Assertions.assertEquals(1, gvl.getFeatures().get(0).getId()); + Assertions.assertEquals("Match and combine data from other data sources", gvl.getFeatures().get(0).getName()); + Assertions.assertEquals("Information about your activity on this service may be matched and combined with other information relating to you and originating from various sources (for instance your activity on a separate online service, your use of a loyalty card in-store, or your answers to a survey), in support of the purposes explained in this notice.", gvl.getFeatures().get(0).getDescription()); + Assertions.assertFalse(gvl.getFeatures().get(0).getDescriptionLegal().isPresent()); + Assertions.assertTrue(gvl.getFeatures().get(0).getIllustrations().isPresent()); + Assertions.assertEquals(0, gvl.getFeatures().get(0).getIllustrations().get().size()); + + Assertions.assertEquals(1, gvl.getSpecialFeatures().get(0).getId()); + Assertions.assertEquals("Use precise geolocation data", gvl.getSpecialFeatures().get(0).getName()); + Assertions.assertEquals("With your acceptance, your precise location (within a radius of less than 500 metres) may be used in support of the purposes explained in this notice.", gvl.getSpecialFeatures().get(0).getDescription()); + Assertions.assertFalse(gvl.getSpecialFeatures().get(0).getDescriptionLegal().isPresent()); + Assertions.assertTrue(gvl.getSpecialFeatures().get(0).getIllustrations().isPresent()); + Assertions.assertEquals(0, gvl.getSpecialFeatures().get(0).getIllustrations().get().size()); + + Assertions.assertEquals(1, gvl.getStacks().get(0).getId()); + Assertions.assertEquals("Precise geolocation data, and identification through device scanning", gvl.getStacks().get(0).getName()); + Assertions.assertEquals("Precise geolocation and information about device characteristics can be used.\n\n", gvl.getStacks().get(0).getDescription()); + Assertions.assertTrue(gvl.getStacks().get(0).getPurposes().isEmpty()); + Assertions.assertEquals(Arrays.asList(1, 2), gvl.getStacks().get(0).getSpecialFeatures()); + + Assertions.assertEquals(2, gvl.getStacks().get(1).getId()); + Assertions.assertEquals("Advertising based on limited data and advertising measurement", gvl.getStacks().get(1).getName()); + Assertions.assertEquals("Advertising can be presented based on limited data. Advertising performance can be measured.", gvl.getStacks().get(1).getDescription()); + Assertions.assertEquals(Arrays.asList(2, 7), gvl.getStacks().get(1).getPurposes()); + Assertions.assertTrue(gvl.getStacks().get(1).getSpecialFeatures().isEmpty()); + + Assertions.assertEquals(1, gvl.getDataCategories().get().get(0).getId()); + Assertions.assertEquals("IP addresses", gvl.getDataCategories().get().get(0).getName()); + Assertions.assertEquals("Your IP address is a number assigned by your Internet Service Provider to any Internet connection. It is not always specific to your device and is not always a stable identifier.\nIt is used to route information on the Internet and display online content (including ads) on your connected device.", gvl.getDataCategories().get().get(0).getDescription()); + + Assertions.assertEquals(1, gvl.getVendors().get(0).getId()); + Assertions.assertFalse(gvl.getVendors().get(0).getDeletedDate().isPresent()); + Assertions.assertEquals("Exponential Interactive, Inc d/b/a VDX.tv", gvl.getVendors().get(0).getName()); + Assertions.assertEquals(Arrays.asList(1, 2, 3, 4, 7, 8, 9, 10), gvl.getVendors().get(0).getPurposes()); + Assertions.assertTrue(gvl.getVendors().get(0).getLegIntPurposes().isPresent()); + Assertions.assertEquals(Collections.emptyList(), gvl.getVendors().get(0).getLegIntPurposes().get()); + Assertions.assertEquals(Arrays.asList(7, 8, 9, 10), gvl.getVendors().get(0).getFlexiblePurposes()); + Assertions.assertEquals(Arrays.asList(1, 2), gvl.getVendors().get(0).getSpecialPurposes()); + Assertions.assertEquals(Arrays.asList(1, 2, 3), gvl.getVendors().get(0).getFeatures()); + Assertions.assertTrue(gvl.getVendors().get(0).getSpecialFeatures().isEmpty()); + Assertions.assertFalse(gvl.getVendors().get(0).getPolicyUrl().isPresent()); + Assertions.assertTrue(gvl.getVendors().get(0).getCookieMaxAgeSeconds().isPresent()); + Assertions.assertEquals(7776000, gvl.getVendors().get(0).getCookieMaxAgeSeconds().get()); + Assertions.assertTrue(gvl.getVendors().get(0).getUsesCookies().isPresent()); + Assertions.assertTrue(gvl.getVendors().get(0).getUsesCookies().get()); + Assertions.assertTrue(gvl.getVendors().get(0).getCookieRefresh().isPresent()); + Assertions.assertTrue(gvl.getVendors().get(0).getCookieRefresh().get()); + Assertions.assertTrue(gvl.getVendors().get(0).getUsesNonCookieAccess().isPresent()); + Assertions.assertFalse(gvl.getVendors().get(0).getUsesNonCookieAccess().get()); + Assertions.assertTrue(gvl.getVendors().get(0).getDataRetention().isPresent()); + Assertions.assertTrue(gvl.getVendors().get(0).getDataRetention().get().getStdRetention().isPresent()); + Assertions.assertEquals(397, gvl.getVendors().get(0).getDataRetention().get().getStdRetention().get()); + Assertions.assertTrue(gvl.getVendors().get(0).getDataRetention().get().getPurposes().isEmpty()); + Assertions.assertTrue(gvl.getVendors().get(0).getDataRetention().get().getSpecialPurposes().isEmpty()); + Assertions.assertTrue(gvl.getVendors().get(0).getUrls().isPresent()); + Assertions.assertEquals(1, gvl.getVendors().get(0).getUrls().get().size()); + Assertions.assertEquals("en", gvl.getVendors().get(0).getUrls().get().get(0).getLangId()); + Assertions.assertEquals("https://vdx.tv/privacy/", gvl.getVendors().get(0).getUrls().get().get(0).getPrivacy()); + Assertions.assertTrue(gvl.getVendors().get(0).getUrls().get().get(0).getLegIntClaim().isPresent()); + Assertions.assertEquals("https://cdnx.exponential.com/wp-content/uploads/2018/04/Balancing-Assessment-for-Legitimate-Interest-Publishers-v2.pdf", gvl.getVendors().get(0).getUrls().get().get(0).getLegIntClaim().get()); + Assertions.assertTrue(gvl.getVendors().get(0).getDataDeclaration().isPresent()); + Assertions.assertEquals(Arrays.asList(1, 3, 4, 6, 8, 10, 11), gvl.getVendors().get(0).getDataDeclaration().get()); + Assertions.assertTrue(gvl.getVendors().get(0).getDeviceStorageDisclosureUrl().isPresent()); + Assertions.assertEquals("https://vdxtv.expo.workers.dev", gvl.getVendors().get(0).getDeviceStorageDisclosureUrl().get()); + + Assertions.assertEquals(12, gvl.getVendors().get(4).getId()); + Assertions.assertFalse(gvl.getVendors().get(4).getDeletedDate().isPresent()); + Assertions.assertEquals("BeeswaxIO Corporation", gvl.getVendors().get(4).getName()); + Assertions.assertEquals(Arrays.asList(1, 2, 3, 4, 7), gvl.getVendors().get(4).getPurposes()); + Assertions.assertTrue(gvl.getVendors().get(4).getLegIntPurposes().isPresent()); + Assertions.assertEquals(Collections.emptyList(), gvl.getVendors().get(4).getLegIntPurposes().get()); + Assertions.assertEquals(Collections.emptyList(), gvl.getVendors().get(4).getFlexiblePurposes()); + Assertions.assertEquals(Arrays.asList(1, 2), gvl.getVendors().get(4).getSpecialPurposes()); + Assertions.assertEquals(Arrays.asList(1, 3), gvl.getVendors().get(4).getFeatures()); + Assertions.assertEquals(Arrays.asList(1), gvl.getVendors().get(4).getSpecialFeatures()); + Assertions.assertFalse(gvl.getVendors().get(4).getPolicyUrl().isPresent()); + Assertions.assertTrue(gvl.getVendors().get(4).getCookieMaxAgeSeconds().isPresent()); + Assertions.assertEquals(34109999, gvl.getVendors().get(4).getCookieMaxAgeSeconds().get()); + Assertions.assertTrue(gvl.getVendors().get(4).getUsesCookies().isPresent()); + Assertions.assertTrue(gvl.getVendors().get(4).getUsesCookies().get()); + Assertions.assertTrue(gvl.getVendors().get(4).getCookieRefresh().isPresent()); + Assertions.assertTrue(gvl.getVendors().get(4).getCookieRefresh().get()); + Assertions.assertTrue(gvl.getVendors().get(4).getUsesNonCookieAccess().isPresent()); + Assertions.assertTrue(gvl.getVendors().get(4).getUsesNonCookieAccess().get()); + Assertions.assertTrue(gvl.getVendors().get(4).getDataRetention().isPresent()); + Assertions.assertTrue(gvl.getVendors().get(4).getDataRetention().get().getStdRetention().isPresent()); + Assertions.assertEquals(0, gvl.getVendors().get(4).getDataRetention().get().getStdRetention().get()); + Assertions.assertEquals(1, gvl.getVendors().get(4).getDataRetention().get().getPurposes().size()); + Assertions.assertEquals(4320, gvl.getVendors().get(4).getDataRetention().get().getPurposes().get(7)); + Assertions.assertEquals(2, gvl.getVendors().get(4).getDataRetention().get().getSpecialPurposes().size()); + Assertions.assertEquals(392, gvl.getVendors().get(4).getDataRetention().get().getSpecialPurposes().get(1)); + Assertions.assertEquals(4320, gvl.getVendors().get(4).getDataRetention().get().getSpecialPurposes().get(2)); + Assertions.assertTrue(gvl.getVendors().get(4).getUrls().isPresent()); + Assertions.assertEquals(1, gvl.getVendors().get(4).getUrls().get().size()); + Assertions.assertEquals("en", gvl.getVendors().get(4).getUrls().get().get(0).getLangId()); + Assertions.assertEquals("https://www.beeswax.com/privacy/", gvl.getVendors().get(4).getUrls().get().get(0).getPrivacy()); + Assertions.assertTrue(gvl.getVendors().get(4).getUrls().get().get(0).getLegIntClaim().isPresent()); + Assertions.assertEquals("https://www.beeswax.com/privacy/", gvl.getVendors().get(4).getUrls().get().get(0).getLegIntClaim().get()); + Assertions.assertTrue(gvl.getVendors().get(4).getDataDeclaration().isPresent()); + Assertions.assertEquals(Arrays.asList(1, 2, 3, 4, 6, 8, 9, 11), gvl.getVendors().get(4).getDataDeclaration().get()); + Assertions.assertTrue(gvl.getVendors().get(4).getDeviceStorageDisclosureUrl().isPresent()); + Assertions.assertEquals("https://beeswax.com/devicedisclosure.json", gvl.getVendors().get(4).getDeviceStorageDisclosureUrl().get()); + + Assertions.assertTrue(gvl.getVendor(26).getCookieRefresh().isPresent()); + Assertions.assertFalse(gvl.getVendor(26).getCookieRefresh().get()); + } + +} diff --git a/iabgpp-extras-jackson/src/test/java/com/iab/gpp/extras/jackson/gvl/OverflowTest.java b/iabgpp-extras-jackson/src/test/java/com/iab/gpp/extras/jackson/gvl/OverflowTest.java deleted file mode 100644 index ea7b188e..00000000 --- a/iabgpp-extras-jackson/src/test/java/com/iab/gpp/extras/jackson/gvl/OverflowTest.java +++ /dev/null @@ -1,52 +0,0 @@ -package com.iab.gpp.extras.jackson.gvl; - -/*- - * #%L - * IAB TCF Java GVL Jackson - * %% - * Copyright (C) 2020 IAB Technology Laboratory, Inc - * %% - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * #L% - */ - -import java.util.List; - -import com.iab.gpp.extras.jackson.TestUtil; -import com.iab.gpp.extras.jackson.Loader; -import org.junit.Assert; -import org.junit.BeforeClass; -import org.junit.Test; - -import com.iab.gpp.extras.gvl.Overflow; -import com.iab.gpp.extras.gvl.Vendor; - -public class OverflowTest { - - private static Overflow vendorEightOverflow; - private static final int VENDOR_ID_SELECTED_FOR_TEST = 8; - - @BeforeClass - public static void setUpBeforeClass() throws Exception { - Loader loader = new Loader(); - List vendors = loader.globalVendorList(TestUtil.getGlobalVendorList()).getVendors(); - Vendor vendor = vendors.stream().filter(o -> o.getId() == VENDOR_ID_SELECTED_FOR_TEST).findFirst().orElse(null); - assert vendor != null; - vendorEightOverflow = vendor.getOverflow().get(); - } - - @Test - public void getHttpGetLimit() { - Assert.assertEquals(32, vendorEightOverflow.getHttpGetLimit()); - } -} diff --git a/iabgpp-extras-jackson/src/test/java/com/iab/gpp/extras/jackson/gvl/PurposeTest.java b/iabgpp-extras-jackson/src/test/java/com/iab/gpp/extras/jackson/gvl/PurposeTest.java deleted file mode 100644 index a75bf04b..00000000 --- a/iabgpp-extras-jackson/src/test/java/com/iab/gpp/extras/jackson/gvl/PurposeTest.java +++ /dev/null @@ -1,80 +0,0 @@ -package com.iab.gpp.extras.jackson.gvl; - -/*- - * #%L - * IAB TCF Java GVL Jackson - * %% - * Copyright (C) 2020 IAB Technology Laboratory, Inc - * %% - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * #L% - */ - -import java.io.IOException; -import java.util.List; - -import com.iab.gpp.extras.jackson.TestUtil; -import com.iab.gpp.extras.jackson.Loader; -import org.junit.Assert; -import org.junit.BeforeClass; -import org.junit.Test; - -import com.iab.gpp.extras.gvl.Purpose; - -public class PurposeTest { - - private static Purpose purposeTen; - private static final int PURPOSE_SELECTED_FOR_TEST = 10; - - @BeforeClass - public static void setUpBeforeClass() throws IOException { - Loader loader = new Loader(); - List purposes = loader.globalVendorList(TestUtil.getGlobalVendorList()).getPurposes(); - purposeTen = purposes.stream().filter(o -> o.getId() == PURPOSE_SELECTED_FOR_TEST).findFirst().orElse(null); - } - - @Test - public void testGetId() { - Assert.assertEquals(10, purposeTen.getId()); - } - - @Test - public void testGetName() { - String expectedName = "Develop and improve products"; - Assert.assertEquals(expectedName, purposeTen.getName()); - } - - @Test - public void testGetDescription() { - String expectedDescription = - "Your data can be used to improve existing systems and software, and to develop new products"; - Assert.assertEquals(expectedDescription, purposeTen.getDescription()); - } - - @Test - public void testGetDescriptionLegal() { - String expectedDescriptionLegal = - "To develop new products and improve products vendors can:\n* Use information to improve their existing products with new features and to develop new products\n* Create new models and algorithms through machine learning\nVendors cannot:\n* Conduct any other data processing operation allowed under a different purpose under this purpose"; - Assert.assertEquals(expectedDescriptionLegal, purposeTen.getDescriptionLegal()); - } - - @Test - public void testGetConsentable() { - Assert.assertTrue(purposeTen.getConsentable()); - } - - @Test - public void testGetRightToObject() { - Assert.assertFalse(purposeTen.getRightToObject()); - } -} diff --git a/iabgpp-extras-jackson/src/test/java/com/iab/gpp/extras/jackson/gvl/SpecialFeatureTest.java b/iabgpp-extras-jackson/src/test/java/com/iab/gpp/extras/jackson/gvl/SpecialFeatureTest.java deleted file mode 100644 index 362d6c75..00000000 --- a/iabgpp-extras-jackson/src/test/java/com/iab/gpp/extras/jackson/gvl/SpecialFeatureTest.java +++ /dev/null @@ -1,73 +0,0 @@ -package com.iab.gpp.extras.jackson.gvl; - -/*- - * #%L - * IAB TCF Java GVL Jackson - * %% - * Copyright (C) 2020 IAB Technology Laboratory, Inc - * %% - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * #L% - */ - -import java.util.List; - -import com.iab.gpp.extras.jackson.TestUtil; -import com.iab.gpp.extras.jackson.Loader; -import org.junit.Assert; -import org.junit.Before; -import org.junit.Test; - -import com.iab.gpp.extras.gvl.SpecialFeature; - -public class SpecialFeatureTest { - - private static SpecialFeature specialFeatureOne; - private final static int SPECIAL_FEAUTRE_ID_SELECTED_FOR_TEST = 1; - - @Before - public void setUp() throws Exception { - Loader loader = new Loader(); - List specialFeatures = loader.globalVendorList(TestUtil.getGlobalVendorList()).getSpecialFeatures(); - specialFeatureOne = - specialFeatures.stream() - .filter(o -> o.getId() == SPECIAL_FEAUTRE_ID_SELECTED_FOR_TEST) - .findFirst() - .orElse(null); - } - - @Test - public void testGetId() { - Assert.assertEquals(1, specialFeatureOne.getId()); - } - - @Test - public void testGetName() { - String expectedName = "Use precise geolocation data"; - Assert.assertEquals(expectedName, specialFeatureOne.getName()); - } - - @Test - public void testGetDescription() { - String expectedDescription = - "Your precise geolocation data can be used in support of one or more purposes. This means your location can be accurate to within several meters."; - Assert.assertEquals(expectedDescription, specialFeatureOne.getDescription()); - } - - @Test - public void testGetDescriptionLegal() { - String expectedDescriptionLegal = - "Vendors can:\n* Collect and process precise geolocation data in support of one or more purposes.\nN.B. Precise geolocation means that there are no restrictions on the precision of a user’s location; this can be accurate to within several meters."; - Assert.assertEquals(expectedDescriptionLegal, specialFeatureOne.getDescriptionLegal()); - } -} diff --git a/iabgpp-extras-jackson/src/test/java/com/iab/gpp/extras/jackson/gvl/SpecialPurposeTest.java b/iabgpp-extras-jackson/src/test/java/com/iab/gpp/extras/jackson/gvl/SpecialPurposeTest.java deleted file mode 100644 index 3ec1e289..00000000 --- a/iabgpp-extras-jackson/src/test/java/com/iab/gpp/extras/jackson/gvl/SpecialPurposeTest.java +++ /dev/null @@ -1,83 +0,0 @@ -package com.iab.gpp.extras.jackson.gvl; - -/*- - * #%L - * IAB TCF Java GVL Jackson - * %% - * Copyright (C) 2020 IAB Technology Laboratory, Inc - * %% - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * #L% - */ - -import com.iab.gpp.extras.gvl.SpecialPurpose; -import com.iab.gpp.extras.jackson.TestUtil; -import com.iab.gpp.extras.jackson.Loader; -import org.junit.Assert; -import org.junit.BeforeClass; -import org.junit.Test; - -import java.io.IOException; -import java.util.List; - -public class SpecialPurposeTest { - - private static SpecialPurpose specialPurposeOne; - private static final int SPECIAL_PURPOSE_SELECTED_FOR_TEST = 1; - - @BeforeClass - public static void setupBeforeClass() throws IOException { - Loader loader = new Loader(); - List specialPurposes = loader.globalVendorList(TestUtil.getGlobalVendorList()).getSpecialPurposes(); - specialPurposeOne = - specialPurposes.stream() - .filter(o -> o.getId() == SPECIAL_PURPOSE_SELECTED_FOR_TEST) - .findFirst() - .orElse(null); - } - - @Test - public void testGetId() { - Assert.assertEquals(1, specialPurposeOne.getId()); - } - - @Test - public void testGetName() { - String expectedName = "Ensure security, prevent fraud, and debug"; - Assert.assertEquals(expectedName, specialPurposeOne.getName()); - } - - @Test - public void testGetDescription() { - String expectedDescription = - "Your data can be used to monitor for and prevent fraudulent activity, and ensure systems and processes work properly and securely."; - Assert.assertEquals(expectedDescription, specialPurposeOne.getDescription()); - } - - @Test - public void testGetDescriptionLegal() { - String expectedDescriptionLegal = - "To ensure security, prevent fraud and debug vendors can:\n* Ensure data are securely transmitted\n* Detect and prevent malicious, fraudulent, invalid, or illegal activity.\n* Ensure correct and efficient operation of systems and processes, including to monitor and enhance the performance of systems and processes engaged in permitted purposes\nVendors cannot:\n* Conduct any other data processing operation allowed under a different purpose under this purpose."; - Assert.assertEquals(expectedDescriptionLegal, specialPurposeOne.getDescriptionLegal()); - } - - @Test - public void testGetConsentable() { - Assert.assertTrue(specialPurposeOne.getConsentable()); - } - - @Test - public void testGetRightToObject() { - Assert.assertFalse(specialPurposeOne.getRightToObject()); - } -} diff --git a/iabgpp-extras-jackson/src/test/java/com/iab/gpp/extras/jackson/gvl/StackTest.java b/iabgpp-extras-jackson/src/test/java/com/iab/gpp/extras/jackson/gvl/StackTest.java deleted file mode 100644 index 5a5f6b5f..00000000 --- a/iabgpp-extras-jackson/src/test/java/com/iab/gpp/extras/jackson/gvl/StackTest.java +++ /dev/null @@ -1,75 +0,0 @@ -package com.iab.gpp.extras.jackson.gvl; - -/*- - * #%L - * IAB TCF Java GVL Jackson - * %% - * Copyright (C) 2020 IAB Technology Laboratory, Inc - * %% - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * #L% - */ - -import com.iab.gpp.extras.gvl.Stack; -import com.iab.gpp.extras.jackson.TestUtil; -import com.iab.gpp.extras.jackson.Loader; -import org.junit.Assert; -import org.junit.BeforeClass; -import org.junit.Test; - -import java.util.Arrays; -import java.util.List; - -public class StackTest { - - private static Stack stackTwenty; - private final static int STACK_ID_SELECTED_FOR_TEST = 20; - - @BeforeClass - public static void setUpBeforeClass() throws Exception { - Loader loader = new Loader(); - List stacks = loader.globalVendorList(TestUtil.getGlobalVendorList()).getStacks(); - stackTwenty = stacks.stream().filter(o -> o.getId() == STACK_ID_SELECTED_FOR_TEST).findFirst().orElse(null); - } - - @Test - public void testGetId() { - Assert.assertEquals(20, stackTwenty.getId()); - } - - @Test - public void testGetSpecialFeatures() { - Assert.assertNotNull(stackTwenty.getSpecialFeatures()); - Assert.assertEquals(0, stackTwenty.getSpecialFeatures().size()); - } - - @Test - public void testGetPurposes() { - Assert.assertNotNull(stackTwenty.getPurposes()); - Assert.assertEquals(4, stackTwenty.getPurposes().size()); - Assert.assertEquals(Arrays.asList(7, 8, 9, 10), stackTwenty.getPurposes()); - } - - @Test - public void testGetName() { - String expectedName = "Ad and content measurement, audience insights, and product development"; - Assert.assertEquals(expectedName, stackTwenty.getName()); - } - - @Test - public void testGetDescription() { - String expectedDescription = - "Ad and content performance can be measured. Insights about the audiences who saw the ads and content can be derived. Data can be used to build or improve user experience, systems, and software. Insights about the audiences who saw the ads and content can be derived."; - Assert.assertEquals(expectedDescription, stackTwenty.getDescription()); - } -} diff --git a/iabgpp-extras-jackson/src/test/java/com/iab/gpp/extras/jackson/gvl/VendorTest.java b/iabgpp-extras-jackson/src/test/java/com/iab/gpp/extras/jackson/gvl/VendorTest.java deleted file mode 100644 index b906ec93..00000000 --- a/iabgpp-extras-jackson/src/test/java/com/iab/gpp/extras/jackson/gvl/VendorTest.java +++ /dev/null @@ -1,161 +0,0 @@ -package com.iab.gpp.extras.jackson.gvl; - -/*- - * #%L - * IAB TCF Java GVL Jackson - * %% - * Copyright (C) 2020 IAB Technology Laboratory, Inc - * %% - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * #L% - */ - -import java.time.Instant; -import java.util.Arrays; - -import org.junit.Assert; -import org.junit.BeforeClass; -import org.junit.Test; - -import com.iab.gpp.extras.gvl.Gvl; -import com.iab.gpp.extras.gvl.Vendor; -import com.iab.gpp.extras.jackson.Loader; -import com.iab.gpp.extras.jackson.TestUtil; - -public class VendorTest { - - private static Vendor vendorEight; - private static Vendor vendorTwo; - private static final int VENDOR_ID_SELECTED_FOR_TEST = 8; - - @BeforeClass - public static void setUpBeforeClass() throws Exception { - Loader loader = new Loader(); - Gvl gvl = loader.globalVendorList(TestUtil.getGlobalVendorList()); - vendorEight = gvl.getVendor(VENDOR_ID_SELECTED_FOR_TEST); - vendorTwo = gvl.getVendor(2); - } - - @Test - public void testGetId() { - Assert.assertEquals(8, vendorEight.getId()); - } - - @Test - public void testGetName() { - String expectedName = "Emerse Sverige AB"; - Assert.assertEquals(expectedName, vendorEight.getName()); - } - - @Test - public void testGetPurposes() { - Assert.assertNotNull(vendorEight.getPurposes()); - Assert.assertEquals(3, vendorEight.getPurposes().size()); - Assert.assertEquals(Arrays.asList(1, 3, 4), vendorEight.getPurposes()); - } - - @Test - public void testGetLegIntPurposes() { - Assert.assertNotNull(vendorEight.getLegIntPurposes()); - Assert.assertEquals(4, vendorEight.getLegIntPurposes().size()); - Assert.assertEquals(Arrays.asList(2, 7, 8, 9), vendorEight.getLegIntPurposes()); - } - - @Test - public void testGetFlexiblePurposes() { - Assert.assertNotNull(vendorEight.getFlexiblePurposes()); - Assert.assertEquals(2, vendorEight.getFlexiblePurposes().size()); - Assert.assertEquals(Arrays.asList(2, 9), vendorEight.getFlexiblePurposes()); - } - - @Test - public void testGetSpecialPurposes() { - Assert.assertNotNull(vendorEight.getSpecialPurposes()); - Assert.assertEquals(2, vendorEight.getSpecialPurposes().size()); - Assert.assertEquals(Arrays.asList(1, 2), vendorEight.getSpecialPurposes()); - } - - @Test - public void testGetFeatures() { - Assert.assertNotNull(vendorEight.getFeatures()); - Assert.assertEquals(2, vendorEight.getFeatures().size()); - Assert.assertEquals(Arrays.asList(1, 2), vendorEight.getFeatures()); - } - - @Test - public void testGetSpecialFeatures() { - Assert.assertNotNull(vendorEight.getSpecialFeatures()); - Assert.assertEquals(0, vendorEight.getSpecialFeatures().size()); - } - - @Test - public void testGetPolicyUrl() { - String expectedPolicyUrl = "https://www.emerse.com/privacy-policy/"; - Assert.assertEquals(expectedPolicyUrl, vendorEight.getPolicyUrl()); - } - - @Test - public void testGetDeletedDate() { - Assert.assertEquals(Instant.parse("2020-06-28T00:00:00Z"), vendorEight.getDeletedDate().get()); - } - - @Test - public void testGetOverflow() { - Assert.assertNotNull(vendorEight.getOverflow()); - } - - @Test - public void testIsDeleted() { - Assert.assertTrue(vendorEight.isDeleted()); - } - - @Test - public void testCookieMaxAgeSeconds() { - long expectedCookieMaxAgeSeconds = 31557600000L; - Assert.assertTrue(vendorEight.getCookieMaxAgeSeconds().isPresent()); - Assert.assertEquals(expectedCookieMaxAgeSeconds, vendorEight.getCookieMaxAgeSeconds().get().longValue()); - } - - @Test - public void testUsesCookies() { - Assert.assertTrue(vendorEight.getUsesCookies()); - } - - @Test - public void testCookieRefresh() { - Assert.assertFalse(vendorEight.getHasCookieRefresh()); - } - - @Test - public void testUsesNonCookieAccess() { - Assert.assertTrue(vendorEight.getUsesNonCookieAccess()); - } - - @Test - public void testNullDeviceStorageDisclosureUrl() { - Assert.assertFalse(vendorEight.getDeviceStorageDisclosureUrl().isPresent()); - } - - @Test - public void testNullCookieMaxAgeSeconds() { - Assert.assertFalse(vendorTwo.getUsesCookies()); - Assert.assertFalse(vendorTwo.getCookieMaxAgeSeconds().isPresent()); - } - - @Test - public void testDeviceStorageDisclosureUrl() { - String expectedDeviceStorageDisclosureUrl = "https://privacy.blismedia.com/.well-known/deviceStorage.json"; - Assert.assertTrue(vendorTwo.getDeviceStorageDisclosureUrl().isPresent()); - Assert.assertEquals(expectedDeviceStorageDisclosureUrl, vendorTwo.getDeviceStorageDisclosureUrl().get()); - } -} diff --git a/iabgpp-extras-jackson/src/test/resources/gvl.json b/iabgpp-extras-jackson/src/test/resources/gvl.json deleted file mode 100644 index 660b47ec..00000000 --- a/iabgpp-extras-jackson/src/test/resources/gvl.json +++ /dev/null @@ -1,664 +0,0 @@ -{ - "gvlSpecificationVersion": 2, - "vendorListVersion": 26, - "tcfPolicyVersion": 2, - "lastUpdated": "2020-02-20T16:05:20Z", - "purposes": { - "1": { - "id": 1, - "name": "Store and/or access information on a device", - "description": "Cookies, device identifiers, or other information can be stored or accessed on your device for the purposes presented to you.", - "descriptionLegal": "Vendors can:\n* Store and access information on the device such as cookies and device identifiers presented to a user." - }, - "2": { - "id": 2, - "name": "Select basic ads", - "description": "Ads can be shown to you based on the content you’re viewing, the app you’re using, your approximate location, or your device type.", - "descriptionLegal": "To do basic ad selection vendors can:\n* Use real-time information about the context in which the ad will be shown, to show the ad, including information about the content and the device, such as: device type and capabilities, user agent, URL, IP address\n* Use a user’s non-precise geolocation data\n* Control the frequency of ads shown to a user.\n* Sequence the order in which ads are shown to a user.\n* Prevent an ad from serving in an unsuitable editorial (brand-unsafe) context\nVendors cannot:\n* Create a personalised ads profile using this information for the selection of future ads.\n* N.B. Non-precise means only an approximate location involving at least a radius of 500 meters is permitted." - }, - "3": { - "id": 3, - "name": "Create a personalised ads profile", - "description": "A profile can be built about you and your interests to show you personalised ads that are relevant to you.", - "descriptionLegal": "To create a personalised ads profile vendors can:\n* Collect information about a user, including a user's activity, interests, demographic information, or location, to create or edit a user profile for use in personalised advertising.\n* Combine this information with other information previously collected, including from across websites and apps, to create or edit a user profile for use in personalised advertising." - }, - "4": { - "id": 4, - "name": "Select personalised ads", - "description": "Personalised ads can be shown to you based on a profile about you.", - "descriptionLegal": "To select personalised ads vendors can:\n* Select personalised ads based on a user profile or other historical user data, including a user’s prior activity, interests, visits to sites or apps, location, or demographic information." - }, - "5": { - "id": 5, - "name": "Create a personalised content profile", - "description": "A profile can be built about you and your interests to show you personalised content that is relevant to you.", - "descriptionLegal": "To create a personalised content profile vendors can:\n* Collect information about a user, including a user's activity, interests, visits to sites or apps, demographic information, or location, to create or edit a user profile for personalising content.\n* Combine this information with other information previously collected, including from across websites and apps, to create or edit a user profile for use in personalising content." - }, - "6": { - "id": 6, - "name": "Select personalised content", - "description": "Personalised content can be shown to you based on a profile about you.", - "descriptionLegal": "To select personalised content vendors can:\n* Select personalised content based on a user profile or other historical user data, including a user’s prior activity, interests, visits to sites or apps, location, or demographic information." - }, - "7": { - "id": 7, - "name": "Measure ad performance", - "description": "The performance and effectiveness of ads that you see or interact with can be measured.", - "descriptionLegal": "To measure ad performance vendors can:\n* Measure whether and how ads were delivered to and interacted with by a user\n* Provide reporting about ads including their effectiveness and performance\n* Provide reporting about users who interacted with ads using data observed during the course of the user's interaction with that ad\n* Provide reporting to publishers about the ads displayed on their property\n* Measure whether an ad is serving in a suitable editorial environment (brand-safe) context\n* Determine the percentage of the ad that had the opportunity to be seen and the duration of that opportunity\n* Combine this information with other information previously collected, including from across websites and apps\nVendors cannot:\n*Apply panel- or similarly-derived audience insights data to ad measurement data without a Legal Basis to apply market research to generate audience insights (Purpose 9)" - }, - "8": { - "id": 8, - "name": "Measure content performance", - "description": "The performance and effectiveness of content that you see or interact with can be measured.", - "descriptionLegal": "To measure content performance vendors can:\n* Measure and report on how content was delivered to and interacted with by users.\n* Provide reporting, using directly measurable or known information, about users who interacted with the content\n* Combine this information with other information previously collected, including from across websites and apps.\nVendors cannot:\n* Measure whether and how ads (including native ads) were delivered to and interacted with by a user.\n* Apply panel- or similarly derived audience insights data to ad measurement data without a Legal Basis to apply market research to generate audience insights (Purpose 9)" - }, - "9": { - "id": 9, - "name": "Apply market research to generate audience insights", - "description": "Market research can be used to learn more about the audiences who visit sites/apps and view ads.", - "descriptionLegal": "To apply market research to generate audience insights vendors can:\n* Provide aggregate reporting to advertisers or their representatives about the audiences reached by their ads, through panel-based and similarly derived insights.\n* Provide aggregate reporting to publishers about the audiences that were served or interacted with content and/or ads on their property by applying panel-based and similarly derived insights.\n* Associate offline data with an online user for the purposes of market research to generate audience insights if vendors have declared to match and combine offline data sources (Feature 1)\n* Combine this information with other information previously collected including from across websites and apps. \nVendors cannot:\n* Measure the performance and effectiveness of ads that a specific user was served or interacted with, without a Legal Basis to measure ad performance.\n* Measure which content a specific user was served and how they interacted with it, without a Legal Basis to measure content performance." - }, - "10": { - "id": 10, - "name": "Develop and improve products", - "description": "Your data can be used to improve existing systems and software, and to develop new products", - "descriptionLegal": "To develop new products and improve products vendors can:\n* Use information to improve their existing products with new features and to develop new products\n* Create new models and algorithms through machine learning\nVendors cannot:\n* Conduct any other data processing operation allowed under a different purpose under this purpose", - "consentable": true, - "rightToObject": false - } - }, - "specialPurposes": { - "1": { - "id": 1, - "name": "Ensure security, prevent fraud, and debug", - "description": "Your data can be used to monitor for and prevent fraudulent activity, and ensure systems and processes work properly and securely.", - "descriptionLegal": "To ensure security, prevent fraud and debug vendors can:\n* Ensure data are securely transmitted\n* Detect and prevent malicious, fraudulent, invalid, or illegal activity.\n* Ensure correct and efficient operation of systems and processes, including to monitor and enhance the performance of systems and processes engaged in permitted purposes\nVendors cannot:\n* Conduct any other data processing operation allowed under a different purpose under this purpose.", - "consentable": true, - "rightToObject": false - }, - "2": { - "id": 2, - "name": "Technically deliver ads or content", - "description": "Your device can receive and send information that allows you to see and interact with ads and content.", - "descriptionLegal": "To deliver information and respond to technical requests vendors can:\n* Use a user’s IP address to deliver an ad over the internet\n* Respond to a user’s interaction with an ad by sending the user to a landing page\n* Use a user’s IP address to deliver content over the internet\n* Respond to a user’s interaction with content by sending the user to a landing page\n* Use information about the device type and capabilities for delivering ads or content, for example, to deliver the right size ad creative or video file in a format supported by the device\nVendors cannot:\n* Conduct any other data processing operation allowed under a different purpose under this purpose" - } - }, - "features": { - "1": { - "id": 1, - "name": "Match and combine offline data sources", - "description": "Data from offline data sources can be combined with your online activity in support of one or more purposes", - "descriptionLegal": "Vendors can:\n* Combine data obtained offline with data collected online in support of one or more Purposes or Special Purposes." - }, - "2": { - "id": 2, - "name": "Link different devices", - "description": "Different devices can be determined as belonging to you or your household in support of one or more of purposes.", - "descriptionLegal": "Vendors can:\n* Deterministically determine that two or more devices belong to the same user or household\n* Probabilistically determine that two or more devices belong to the same user or household\n* Actively scan device characteristics for identification for probabilistic identification if users have allowed vendors to actively scan device characteristics for identification (Special Feature 2)" - }, - "3": { - "id": 3, - "name": "Receive and use automatically-sent device characteristics for identification", - "description": "Your device might be distinguished from other devices based on information it automatically sends, such as IP address or browser type.", - "descriptionLegal": "Vendors can:\n* Create an identifier using data collected automatically from a device for specific characteristics, e.g. IP address, user-agent string.\n* Use such an identifier to attempt to re-identify a device.\nVendors cannot:\n* Create an identifier using data collected via actively scanning a device for specific characteristics, e.g. installed font or screen resolution without users’ separate opt-in to actively scanning device characteristics for identification.\n* Use such an identifier to re-identify a device." - } - }, - "specialFeatures": { - "1": { - "id": 1, - "name": "Use precise geolocation data", - "description": "Your precise geolocation data can be used in support of one or more purposes. This means your location can be accurate to within several meters.", - "descriptionLegal": "Vendors can:\n* Collect and process precise geolocation data in support of one or more purposes.\nN.B. Precise geolocation means that there are no restrictions on the precision of a user’s location; this can be accurate to within several meters." - }, - "2": { - "id": 2, - "name": "Actively scan device characteristics for identification", - "description": "Your device can be identified based on a scan of your device's unique combination of characteristics.", - "descriptionLegal": "Vendors can:\n* Create an identifier using data collected via actively scanning a device for specific characteristics, e.g. installed fonts or screen resolution.\n* Use such an identifier to re-identify a device." - } - }, - "stacks": { - "1": { - "id": 1, - "purposes": [], - "specialFeatures": [ - 1, - 2 - ], - "name": "Precise geolocation data, and identification through device scanning", - "description": "Precise geolocation and information about device characteristics can be used." - }, - "2": { - "id": 2, - "purposes": [ - 2, - 7 - ], - "specialFeatures": [], - "name": "Basic ads, and ad measurement", - "description": "Basic ads can be served. Ad performance can be measured." - }, - "3": { - "id": 3, - "purposes": [ - 2, - 3, - 4 - ], - "specialFeatures": [], - "name": "Personalised ads", - "description": "Ads can be personalised based on a profile. More data can be added to better personalise ads." - }, - "4": { - "id": 4, - "purposes": [ - 2, - 7, - 9 - ], - "specialFeatures": [], - "name": "Basic ads, and ad measurement", - "description": "Basic ads can be served. Ad performance can be measured. Insights about the audiences who saw the ads and content can be derived." - }, - "5": { - "id": 5, - "purposes": [ - 2, - 3, - 7 - ], - "specialFeatures": [], - "name": "Basic ads, personalised ads profile, and ad measurement", - "description": "Basic ads can be served. More data can be added to better personalise ads. Ad performance can be measured." - }, - "6": { - "id": 6, - "purposes": [ - 2, - 4, - 7 - ], - "specialFeatures": [], - "name": "Personalised ads display, and measurement", - "description": "Ads can be personalised based on a profile. Ad performance can be measured." - }, - "7": { - "id": 7, - "purposes": [ - 2, - 4, - 7, - 9 - ], - "specialFeatures": [], - "name": "Personalised ads display, ad measurement, and audience insights", - "description": "Ads can be personalised based on a profile. Ad performance can be measured. Insights about the audiences who saw the ads and content can be derived." - }, - "8": { - "id": 8, - "purposes": [ - 2, - 3, - 4, - 7 - ], - "specialFeatures": [], - "name": "Personalised ads, and ad measurement", - "description": "Ads can be personalised based on a profile. More data can be added to better personalise ads. Ad performance can be measured." - }, - "9": { - "id": 9, - "purposes": [ - 2, - 3, - 4, - 7, - 9 - ], - "specialFeatures": [], - "name": "Personalised ads, ad measurement, and audience insights", - "description": "Ads can be personalised based on a profile. More data can be added to better personalise ads. Ad performance can be measured. Insights about the audiences who saw the ads and content can be derived." - }, - "10": { - "id": 10, - "purposes": [ - 3, - 4 - ], - "specialFeatures": [], - "name": "Personalised ads profile and display", - "description": "Ads can be personalised based on a profile. More data can be added to better personalise ads." - }, - "11": { - "id": 11, - "purposes": [ - 5, - 6 - ], - "specialFeatures": [], - "name": "Personalised content", - "description": "Content can be personalised based on a profile. More data can be added to better personalise content." - }, - "12": { - "id": 12, - "purposes": [ - 6, - 8 - ], - "specialFeatures": [], - "name": "Personalised content display, and content measurement", - "description": "Content can be personalised based on a profile. Content performance can be measured." - }, - "13": { - "id": 13, - "purposes": [ - 6, - 8, - 9 - ], - "specialFeatures": [], - "name": "Personalised content display, content measurement and audience insights", - "description": "Content can be personalised based on a profile. Content performance can be measured. Insights about the audiences who saw the ads and content can be derived." - }, - "14": { - "id": 14, - "purposes": [ - 5, - 6, - 8 - ], - "specialFeatures": [], - "name": "Personalised content, and content measurement", - "description": "Content can be personalised based on a profile. More data can be added to better personalise content. Content performance can be measured." - }, - "15": { - "id": 15, - "purposes": [ - 5, - 6, - 8, - 9 - ], - "specialFeatures": [], - "name": "Personalised content, content measurement and audience insights", - "description": "Content can be personalised based on a profile. More data can be added to better personalise content. Content performance can be measured. Insights about the audiences who saw the ads and content can be derived." - }, - "16": { - "id": 16, - "purposes": [ - 5, - 6, - 8, - 9, - 10 - ], - "specialFeatures": [], - "name": "Personalised content, content measurement, audience insights, and product development", - "description": "Content can be personalised based on a profile. More data can be added to better personalise content. Content performance can be measured. Insights about the audiences who saw the ads and content can be derived. Data can be used to build or improve user experience, systems, and software" - }, - "17": { - "id": 17, - "purposes": [ - 7, - 8, - 9 - ], - "specialFeatures": [], - "name": "Ad and content measurement, and audience insights", - "description": "Ad and content performance can be measured. Insights about the audiences who saw the ads and content can be derived." - }, - "18": { - "id": 18, - "purposes": [ - 7, - 8 - ], - "specialFeatures": [], - "name": "Ad and content measurement", - "description": "Ad and content performance can be measured." - }, - "19": { - "id": 19, - "purposes": [ - 7, - 9 - ], - "specialFeatures": [], - "name": "Ad measurement, and audience insights", - "description": "Ad can be measured. Insights about the audiences who saw the ads and content can be derived." - }, - "20": { - "id": 20, - "purposes": [ - 7, - 8, - 9, - 10 - ], - "specialFeatures": [], - "name": "Ad and content measurement, audience insights, and product development", - "description": "Ad and content performance can be measured. Insights about the audiences who saw the ads and content can be derived. Data can be used to build or improve user experience, systems, and software. Insights about the audiences who saw the ads and content can be derived." - }, - "21": { - "id": 21, - "purposes": [ - 8, - 9, - 10 - ], - "specialFeatures": [], - "name": "Content measurement, audience insights, and product development.", - "description": "Content performance can be measured. Insights about the audiences who saw the ads and content can be derived. Data can be used to build or improve user experience, systems, and software." - }, - "22": { - "id": 22, - "purposes": [ - 8, - 10 - ], - "specialFeatures": [], - "name": "Content measurement, and product development", - "description": "Content performance can be measured. Data can be used to build or improve user experience, systems, and software." - }, - "23": { - "id": 23, - "purposes": [ - 2, - 4, - 6, - 7, - 8 - ], - "specialFeatures": [], - "name": "Personalised ads and content display, ad and content measurement", - "description": "Ads and content can be personalised based on a profile. Ad and content performance can be measured." - }, - "24": { - "id": 24, - "purposes": [ - 2, - 4, - 6, - 7, - 8, - 9 - ], - "specialFeatures": [], - "name": "Personalised ads and content display, ad and content measurement, and audience insights", - "description": "Ads and content can be personalised based on a profile. Ad and content performance can be measured. Insights about the audiences who saw the ads and content can be derived. Data can be used to build or improve user experience, systems, and software." - }, - "25": { - "id": 25, - "purposes": [ - 2, - 3, - 4, - 5, - 6, - 7, - 8 - ], - "specialFeatures": [], - "name": "Personalised ads and content, ad and content measurement", - "description": "Ads and content can be personalised based on a profile. More data can be added to better personalise ads and content. Ad and content performance can be measured." - }, - "26": { - "id": 26, - "purposes": [ - 2, - 3, - 4, - 5, - 6, - 7, - 8, - 9 - ], - "specialFeatures": [], - "name": "Personalised ads and content, ad and content measurement, and audience insights", - "description": "Ads and content can be personalised based on a profile. More data can be added to better personalise ads and content. Ad and content performance can be measured. Insights about the audiences who saw the ads and content can be derived." - }, - "27": { - "id": 27, - "purposes": [ - 3, - 5 - ], - "specialFeatures": [], - "name": "Personalised ads, and content profile", - "description": "More data can be added to personalise ads and content." - }, - "28": { - "id": 28, - "purposes": [ - 2, - 4, - 6 - ], - "specialFeatures": [], - "name": "Personalised ads and content display", - "description": "Ads and content can be personalised based on a profile." - }, - "29": { - "id": 29, - "purposes": [ - 2, - 7, - 8, - 9 - ], - "specialFeatures": [], - "name": "Basic ads, ad and content measurement, and audience insights", - "description": "Basic ads can be served. Ad and content performance can be measured. Insights about the audiences who saw the ads and content can be derived." - }, - "30": { - "id": 30, - "purposes": [ - 2, - 4, - 5, - 6, - 7, - 8, - 9 - ], - "specialFeatures": [], - "name": "Personalised ads display, personalised content, ad and content measurement, and audience insights", - "description": "Ads and content can be personalised based on a profile. More data can be added to better personalise content. Ad and content performance can be measured. Insights about the audiences who saw the ads and content can be derived." - }, - "31": { - "id": 31, - "purposes": [ - 2, - 4, - 5, - 6, - 7, - 8, - 9, - 10 - ], - "specialFeatures": [], - "name": "Personalised ads display, personalised content, ad and content measurement, audience insights, and product development", - "description": "Ads and content can be personalised based on a profile. More data can be added to better personalise content. Ad and content performance can be measured. Insights about the audiences who saw the ads and content can be derived. Data can be used to build or improve user experience, systems, and software." - }, - "32": { - "id": 32, - "purposes": [ - 2, - 5, - 6, - 7, - 8, - 9 - ], - "specialFeatures": [], - "name": "Basic ads, personalised content, ad and content measurement, and audience insights", - "description": "Basic ads can be served. Content can be personalised based on a profile. More data can be added to better personalise content. Ad and content performance can be measured. Insights about the audiences who saw the ads and content can be derived." - }, - "33": { - "id": 33, - "purposes": [ - 2, - 5, - 6, - 7, - 8, - 9, - 10 - ], - "specialFeatures": [], - "name": "Basic ads, personalised content, ad and content measurement, audience insights, and product development", - "description": "Basic ads can be served. Content can be personalised based on a profile. More data can be added to better personalise content. Ad and content performance can be measured. Insights about the audiences who saw the ads and content can be derived. Data can be used to build or improve user experience, systems, and software." - }, - "34": { - "id": 34, - "purposes": [ - 2, - 5, - 6, - 8, - 9 - ], - "specialFeatures": [], - "name": "Basic ads, personalised content, content measurement, and audience insights", - "description": "Basic ads can be served. Content can be personalised based on a profile. More data can be added to better personalise content. Ad and content performance can be measured. Insights about the audiences who saw the ads and content can be derived." - }, - "35": { - "id": 35, - "purposes": [ - 2, - 5, - 6, - 8, - 9, - 10 - ], - "specialFeatures": [], - "name": "Basic ads, personalised content, content measurement, audience insights, and product development", - "description": "Basic ads can be served. Content can be personalised based on a profile. More data can be added to better personalise content. Content performance can be measured. Insights about the audiences who saw the ads and content can be derived. Data can be used to build or improve user experience, systems, and software." - }, - "36": { - "id": 36, - "purposes": [ - 2, - 5, - 6, - 7 - ], - "specialFeatures": [], - "name": "Basic ads, personalised content, and ad measurement", - "description": "Basic ads can be served. Content can be personalised based on a profile. More data can be added to better personalise content. Ad performance can be measured." - }, - "37": { - "id": 37, - "purposes": [ - 2, - 5, - 6, - 7, - 10 - ], - "specialFeatures": [], - "name": "Basic ads, personalised content, ad measurement, and product development", - "description": "Basic ads can be served. Content can be personalised based on a profile. More data can be added to better personalise content. Ad performance can be measured. Data can be used to build or improve user experience, systems, and software." - } - }, - "vendors": { - "512": { - "id": 512, - "name": "PubNative GmbH", - "purposes": [ - 1, - 2, - 3, - 4, - 4, - 7, - 8, - 10 - ], - "legIntPurposes": [], - "flexiblePurposes": [], - "specialPurposes": [], - "features": [ - 3 - ], - "specialFeatures": [ - 2 - ], - "policyUrl": "https://pubnative.net/privacy-notice/", - "deletedDate": "2019-02-28T00:00:00Z", - "cookieMaxAgeSeconds": null, - "usesCookies": false, - "cookieRefresh": false, - "usesNonCookieAccess": false - }, - "8": { - "id": 8, - "name": "Emerse Sverige AB", - "purposes": [ - 1, - 3, - 4 - ], - "legIntPurposes": [ - 2, - 7, - 8, - 9 - ], - "flexiblePurposes": [ - 2, - 9 - ], - "specialPurposes": [ - 1, - 2 - ], - "features": [ - 1, - 2 - ], - "specialFeatures": [], - "policyUrl": "https://www.emerse.com/privacy-policy/", - "deletedDate": "2020-06-28T00:00:00Z", - "overflow": { - "httpGetLimit": 32 - }, - "cookieMaxAgeSeconds": 31557600000, - "usesCookies": true, - "cookieRefresh": false, - "usesNonCookieAccess": true - }, - "2": { - "id": 2, - "name": "Captify Technologies Limited", - "purposes": [ - 1, - 2, - 3, - 4 - ], - "legIntPurposes": [ - 7, - 9, - 10 - ], - "flexiblePurposes": [ - 2 - ], - "specialPurposes": [ ], - "features": [ - 2 - ], - "specialFeatures": [ ], - "policyUrl": "http://www.captify.co.uk/privacy-policy/", - "cookieMaxAgeSeconds": null, - "usesCookies": false, - "cookieRefresh": true, - "usesNonCookieAccess": true, - "deviceStorageDisclosureUrl": "https://privacy.blismedia.com/.well-known/deviceStorage.json" - } - } -} \ No newline at end of file diff --git a/iabgpp-extras-jackson/src/test/resources/vendorlist/v2/ca/vendor-list.json b/iabgpp-extras-jackson/src/test/resources/vendorlist/v2/ca/vendor-list.json new file mode 100644 index 00000000..bb4840a2 --- /dev/null +++ b/iabgpp-extras-jackson/src/test/resources/vendorlist/v2/ca/vendor-list.json @@ -0,0 +1,2070 @@ +{ + "gvlSpecificationVersion": 2, + "vendorListVersion": 45, + "tcfPolicyVersion": 2, + "lastUpdated": "2023-09-07T16:00:27Z", + "purposes": { + "1": { + "id": 1, + "name": "Store and/or access information on a device", + "description": "Cookies, device identifiers, or other information can be stored or accessed on your device for the purposes presented to you.", + "descriptionLegal": "Vendors can:\n* Store and access information on the device such as cookies and device identifiers presented to a user." + }, + "2": { + "id": 2, + "name": "Select basic ads", + "description": "Ads can be shown to you based on the content you’re viewing, the app you’re using, your approximate location, or your device type.", + "descriptionLegal": "To do basic ad selection vendors can:\n* Use real-time information about the context in which the ad will be shown, to show the ad, including information about the content and the device, such as: device type and capabilities, user agent, URL, IP address\n* Use a user’s non-precise geolocation data\n* Control the frequency of ads shown to a user.\n* Sequence the order in which ads are shown to a user.\n* Prevent an ad from serving in an unsuitable editorial (brand-unsafe) context\nVendors cannot:\n* Create a personalised ads profile using this information for the selection of future ads without a separate legal basis to create a personalised ads profile.\n* N.B. Non-precise means only an approximate location involving at least a radius of 500 meters is permitted." + }, + "3": { + "id": 3, + "name": "Create a personalised ads profile", + "description": "A profile can be built about you and your interests to show you personalised ads that are relevant to you.", + "descriptionLegal": "To create a personalised ads profile vendors can:\n* Collect information about a user, including a user's activity, interests, demographic information, or location, to create or edit a user profile for use in personalised advertising.\n* Combine this information with other information previously collected, including from across websites and apps, to create or edit a user profile for use in personalised advertising." + }, + "4": { + "id": 4, + "name": "Select personalised ads", + "description": "Personalised ads can be shown to you based on a profile about you.", + "descriptionLegal": "To select personalised ads vendors can:\n* Select personalised ads based on a user profile or other historical user data, including a user’s prior activity, interests, visits to sites or apps, location, or demographic information." + }, + "5": { + "id": 5, + "name": "Create a personalised content profile", + "description": "A profile can be built about you and your interests to show you personalised content that is relevant to you.", + "descriptionLegal": "To create a personalised content profile vendors can:\n* Collect information about a user, including a user's activity, interests, visits to sites or apps, demographic information, or location, to create or edit a user profile for personalising content.\n* Combine this information with other information previously collected, including from across websites and apps, to create or edit a user profile for use in personalising content." + }, + "6": { + "id": 6, + "name": "Select personalised content", + "description": "Personalised content can be shown to you based on a profile about you.", + "descriptionLegal": "To select personalised content vendors can:\n* Select personalised content based on a user profile or other historical user data, including a user’s prior activity, interests, visits to sites or apps, location, or demographic information." + }, + "7": { + "id": 7, + "name": "Measure ad performance", + "description": "The performance and effectiveness of ads that you see or interact with can be measured.", + "descriptionLegal": "To measure ad performance vendors can:\n* Measure whether and how ads were delivered to and interacted with by a user\n* Provide reporting about ads including their effectiveness and performance\n* Provide reporting about users who interacted with ads using data observed during the course of the user's interaction with that ad\n* Provide reporting to publishers about the ads displayed on their property\n* Measure whether an ad is serving in a suitable editorial environment (brand-safe) context\n* Determine the percentage of the ad that had the opportunity to be seen and the duration of that opportunity\n* Combine this information with other information previously collected, including from across websites and apps\nVendors cannot:\n*Apply panel- or similarly-derived audience insights data to ad measurement data without a Legal Basis to apply market research to generate audience insights (Purpose 9)" + }, + "8": { + "id": 8, + "name": "Measure content performance", + "description": "The performance and effectiveness of content that you see or interact with can be measured.", + "descriptionLegal": "To measure content performance vendors can:\n* Measure and report on how content was delivered to and interacted with by users.\n* Provide reporting, using directly measurable or known information, about users who interacted with the content\n* Combine this information with other information previously collected, including from across websites and apps.\nVendors cannot:\n* Measure whether and how ads (including native ads) were delivered to and interacted with by a user.\n* Apply panel- or similarly derived audience insights data to ad measurement data without a Legal Basis to apply market research to generate audience insights (Purpose 9)" + }, + "9": { + "id": 9, + "name": "Apply market research to generate audience insights", + "description": "Market research can be used to learn more about the audiences who visit sites/apps and view ads.", + "descriptionLegal": "To apply market research to generate audience insights vendors can:\n* Provide aggregate reporting to advertisers or their representatives about the audiences reached by their ads, through panel-based and similarly derived insights.\n* Provide aggregate reporting to publishers about the audiences that were served or interacted with content and/or ads on their property by applying panel-based and similarly derived insights.\n* Associate offline data with an online user for the purposes of market research to generate audience insights if vendors have declared to match and combine offline data sources (Feature 1)\n* Combine this information with other information previously collected including from across websites and apps. \nVendors cannot:\n* Measure the performance and effectiveness of ads that a specific user was served or interacted with, without a Legal Basis to measure ad performance.\n* Measure which content a specific user was served and how they interacted with it, without a Legal Basis to measure content performance." + }, + "10": { + "id": 10, + "name": "Develop and improve products", + "description": "Your data can be used to improve existing systems and software, and to develop new products", + "descriptionLegal": "To develop new products and improve products vendors can:\n* Use information to improve their existing products with new features and to develop new products\n* Create new models and algorithms through machine learning\nVendors cannot:\n* Conduct any other data processing operation allowed under a different purpose under this purpose" + } + }, + "specialPurposes": { + "1": { + "id": 1, + "name": "Ensure security, prevent fraud, and debug", + "description": "Your data can be used to monitor for and prevent fraudulent activity, and ensure systems and processes work properly and securely.", + "descriptionLegal": "To ensure security, prevent fraud and debug vendors can:\n* Ensure data are securely transmitted\n* Detect and prevent malicious, fraudulent, invalid, or illegal activity.\n* Ensure correct and efficient operation of systems and processes, including to monitor and enhance the performance of systems and processes engaged in permitted purposes\nVendors cannot:\n* Conduct any other data processing operation allowed under a different purpose under this purpose.\nNote: Data collected and used to ensure security, prevent fraud, and debug may include automatically-sent device characteristics for identification, precise geolocation data, and data obtained by actively scanning device characteristics for identification without separate disclosure and/or opt-in." + }, + "2": { + "id": 2, + "name": "Technically deliver ads or content", + "description": "Your device can receive and send information that allows you to see and interact with ads and content.", + "descriptionLegal": "To deliver information and respond to technical requests vendors can:\n* Use a user’s IP address to deliver an ad over the internet\n* Respond to a user’s interaction with an ad by sending the user to a landing page\n* Use a user’s IP address to deliver content over the internet\n* Respond to a user’s interaction with content by sending the user to a landing page\n* Use information about the device type and capabilities for delivering ads or content, for example, to deliver the right size ad creative or video file in a format supported by the device\nVendors cannot:\n* Conduct any other data processing operation allowed under a different purpose under this purpose" + } + }, + "features": { + "1": { + "id": 1, + "name": "Match and combine offline data sources", + "description": "Data from offline data sources can be combined with your online activity in support of one or more purposes", + "descriptionLegal": "Vendors can:\n* Combine data obtained offline with data collected online in support of one or more Purposes or Special Purposes." + }, + "2": { + "id": 2, + "name": "Link different devices", + "description": "Different devices can be determined as belonging to you or your household in support of one or more of purposes.", + "descriptionLegal": "Vendors can:\n* Deterministically determine that two or more devices belong to the same user or household\n* Probabilistically determine that two or more devices belong to the same user or household\n* Actively scan device characteristics for identification for probabilistic identification if users have allowed vendors to actively scan device characteristics for identification (Special Feature 2)" + }, + "3": { + "id": 3, + "name": "Receive and use automatically-sent device characteristics for identification", + "description": "Your device might be distinguished from other devices based on information it automatically sends, such as IP address or browser type.", + "descriptionLegal": "Vendors can:\n* Create an identifier using data collected automatically from a device for specific characteristics, e.g. IP address, user-agent string.\n* Use such an identifier to attempt to re-identify a device.\nVendors cannot:\n* Create an identifier using data collected via actively scanning a device for specific characteristics, e.g. installed font or screen resolution without users’ separate opt-in to actively scanning device characteristics for identification.\n* Use such an identifier to re-identify a device." + } + }, + "specialFeatures": { + "1": { + "id": 1, + "name": "Use precise geolocation data", + "description": "Your precise geolocation data can be used in support of one or more purposes. This means your location can be accurate to within several meters.", + "descriptionLegal": "Vendors can:\n* Collect and process precise geolocation data in support of one or more purposes.\nN.B. Precise geolocation means that there are no restrictions on the precision of a user’s location; this can be accurate to within several meters." + }, + "2": { + "id": 2, + "name": "Actively scan device characteristics for identification", + "description": "Your device can be identified based on a scan of your device's unique combination of characteristics.", + "descriptionLegal": "Vendors can:\n* Create an identifier using data collected via actively scanning a device for specific characteristics, e.g. installed fonts or screen resolution.\n* Use such an identifier to re-identify a device." + } + }, + "stacks": { + "1": { + "id": 1, + "purposes": [ + + ], + "specialFeatures": [ + 1, + 2 + ], + "name": "Precise geolocation data, and identification through device scanning", + "description": "Precise geolocation and information about device characteristics can be used." + }, + "2": { + "id": 2, + "purposes": [ + 2, + 7 + ], + "specialFeatures": [ + + ], + "name": "Basic ads, and ad measurement", + "description": "Basic ads can be served. Ad performance can be measured." + }, + "3": { + "id": 3, + "purposes": [ + 2, + 3, + 4 + ], + "specialFeatures": [ + + ], + "name": "Personalised ads", + "description": "Ads can be personalised based on a profile. More data can be added to better personalise ads." + }, + "4": { + "id": 4, + "purposes": [ + 2, + 7, + 9 + ], + "specialFeatures": [ + + ], + "name": "Basic ads, ad measurement, and audience insights", + "description": "Basic ads can be served. Ad performance can be measured. Insights about the audiences who saw the ads and content can be derived." + }, + "5": { + "id": 5, + "purposes": [ + 2, + 3, + 7 + ], + "specialFeatures": [ + + ], + "name": "Basic ads, personalised ads profile, and ad measurement", + "description": "Basic ads can be served. More data can be added to better personalise ads. Ad performance can be measured." + }, + "6": { + "id": 6, + "purposes": [ + 2, + 4, + 7 + ], + "specialFeatures": [ + + ], + "name": "Personalised ads display and ad measurement", + "description": "Ads can be personalised based on a profile. Ad performance can be measured." + }, + "7": { + "id": 7, + "purposes": [ + 2, + 4, + 7, + 9 + ], + "specialFeatures": [ + + ], + "name": "Personalised ads display, ad measurement, and audience insights", + "description": "Ads can be personalised based on a profile. Ad performance can be measured. Insights about the audiences who saw the ads and content can be derived." + }, + "8": { + "id": 8, + "purposes": [ + 2, + 3, + 4, + 7 + ], + "specialFeatures": [ + + ], + "name": "Personalised ads, and ad measurement", + "description": "Ads can be personalised based on a profile. More data can be added to better personalise ads. Ad performance can be measured." + }, + "9": { + "id": 9, + "purposes": [ + 2, + 3, + 4, + 7, + 9 + ], + "specialFeatures": [ + + ], + "name": "Personalised ads, ad measurement, and audience insights", + "description": "Ads can be personalised based on a profile. More data can be added to better personalise ads. Ad performance can be measured. Insights about the audiences who saw the ads and content can be derived." + }, + "10": { + "id": 10, + "purposes": [ + 3, + 4 + ], + "specialFeatures": [ + + ], + "name": "Personalised ads profile and display", + "description": "Ads can be personalised based on a profile. More data can be added to better personalise ads." + }, + "11": { + "id": 11, + "purposes": [ + 5, + 6 + ], + "specialFeatures": [ + + ], + "name": "Personalised content", + "description": "Content can be personalised based on a profile. More data can be added to better personalise content." + }, + "12": { + "id": 12, + "purposes": [ + 6, + 8 + ], + "specialFeatures": [ + + ], + "name": "Personalised content display, and content measurement", + "description": "Content can be personalised based on a profile. Content performance can be measured." + }, + "13": { + "id": 13, + "purposes": [ + 6, + 8, + 9 + ], + "specialFeatures": [ + + ], + "name": "Personalised content display, content measurement and audience insights", + "description": "Content can be personalised based on a profile. Content performance can be measured. Insights about the audiences who saw the ads and content can be derived." + }, + "14": { + "id": 14, + "purposes": [ + 5, + 6, + 8 + ], + "specialFeatures": [ + + ], + "name": "Personalised content, and content measurement", + "description": "Content can be personalised based on a profile. More data can be added to better personalise content. Content performance can be measured." + }, + "15": { + "id": 15, + "purposes": [ + 5, + 6, + 8, + 9 + ], + "specialFeatures": [ + + ], + "name": "Personalised content, content measurement and audience insights", + "description": "Content can be personalised based on a profile. More data can be added to better personalise content. Content performance can be measured. Insights about the audiences who saw the ads and content can be derived." + }, + "16": { + "id": 16, + "purposes": [ + 5, + 6, + 8, + 9, + 10 + ], + "specialFeatures": [ + + ], + "name": "Personalised content, content measurement, audience insights, and product development", + "description": "Content can be personalised based on a profile. More data can be added to better personalise content. Content performance can be measured. Insights about the audiences who saw the ads and content can be derived. Data can be used to build or improve user experience, systems, and software" + }, + "17": { + "id": 17, + "purposes": [ + 7, + 8, + 9 + ], + "specialFeatures": [ + + ], + "name": "Ad and content measurement, and audience insights", + "description": "Ad and content performance can be measured. Insights about the audiences who saw the ads and content can be derived." + }, + "18": { + "id": 18, + "purposes": [ + 7, + 8 + ], + "specialFeatures": [ + + ], + "name": "Ad and content measurement", + "description": "Ad and content performance can be measured." + }, + "19": { + "id": 19, + "purposes": [ + 7, + 9 + ], + "specialFeatures": [ + + ], + "name": "Ad measurement, and audience insights", + "description": "Ad can be measured. Insights about the audiences who saw the ads and content can be derived." + }, + "20": { + "id": 20, + "purposes": [ + 7, + 8, + 9, + 10 + ], + "specialFeatures": [ + + ], + "name": "Ad and content measurement, audience insights, and product development", + "description": "Ad and content performance can be measured. Insights about the audiences who saw the ads and content can be derived. Data can be used to build or improve user experience, systems, and software. Insights about the audiences who saw the ads and content can be derived." + }, + "21": { + "id": 21, + "purposes": [ + 8, + 9, + 10 + ], + "specialFeatures": [ + + ], + "name": "Content measurement, audience insights, and product development", + "description": "Content performance can be measured. Insights about the audiences who saw the ads and content can be derived. Data can be used to build or improve user experience, systems, and software." + }, + "22": { + "id": 22, + "purposes": [ + 8, + 10 + ], + "specialFeatures": [ + + ], + "name": "Content measurement, and product development", + "description": "Content performance can be measured. Data can be used to build or improve user experience, systems, and software." + }, + "23": { + "id": 23, + "purposes": [ + 2, + 4, + 6, + 7, + 8 + ], + "specialFeatures": [ + + ], + "name": "Personalised ads and content display, ad and content measurement", + "description": "Ads and content can be personalised based on a profile. Ad and content performance can be measured." + }, + "24": { + "id": 24, + "purposes": [ + 2, + 4, + 6, + 7, + 8, + 9 + ], + "specialFeatures": [ + + ], + "name": "Personalised ads and content display, ad and content measurement, and audience insights", + "description": "Ads and content can be personalised based on a profile. Ad and content performance can be measured. Insights about the audiences who saw the ads and content can be derived. Data can be used to build or improve user experience, systems, and software." + }, + "25": { + "id": 25, + "purposes": [ + 2, + 3, + 4, + 5, + 6, + 7, + 8 + ], + "specialFeatures": [ + + ], + "name": "Personalised ads and content, ad and content measurement", + "description": "Ads and content can be personalised based on a profile. More data can be added to better personalise ads and content. Ad and content performance can be measured." + }, + "26": { + "id": 26, + "purposes": [ + 2, + 3, + 4, + 5, + 6, + 7, + 8, + 9 + ], + "specialFeatures": [ + + ], + "name": "Personalised ads and content, ad and content measurement, and audience insights", + "description": "Ads and content can be personalised based on a profile. More data can be added to better personalise ads and content. Ad and content performance can be measured. Insights about the audiences who saw the ads and content can be derived." + }, + "27": { + "id": 27, + "purposes": [ + 3, + 5 + ], + "specialFeatures": [ + + ], + "name": "Personalised ads, and content profile", + "description": "More data can be added to personalise ads and content." + }, + "28": { + "id": 28, + "purposes": [ + 2, + 4, + 6 + ], + "specialFeatures": [ + + ], + "name": "Personalised ads and content display", + "description": "Ads and content can be personalised based on a profile." + }, + "29": { + "id": 29, + "purposes": [ + 2, + 7, + 8, + 9 + ], + "specialFeatures": [ + + ], + "name": "Basic ads, ad and content measurement, and audience insights", + "description": "Basic ads can be served. Ad and content performance can be measured. Insights about the audiences who saw the ads and content can be derived." + }, + "30": { + "id": 30, + "purposes": [ + 2, + 4, + 5, + 6, + 7, + 8, + 9 + ], + "specialFeatures": [ + + ], + "name": "Personalised ads display, personalised content, ad and content measurement, and audience insights", + "description": "Ads and content can be personalised based on a profile. More data can be added to better personalise content. Ad and content performance can be measured. Insights about the audiences who saw the ads and content can be derived." + }, + "31": { + "id": 31, + "purposes": [ + 2, + 4, + 5, + 6, + 7, + 8, + 9, + 10 + ], + "specialFeatures": [ + + ], + "name": "Personalised ads display, personalised content, ad and content measurement, audience insights, and product development", + "description": "Ads and content can be personalised based on a profile. More data can be added to better personalise content. Ad and content performance can be measured. Insights about the audiences who saw the ads and content can be derived. Data can be used to build or improve user experience, systems, and software." + }, + "32": { + "id": 32, + "purposes": [ + 2, + 5, + 6, + 7, + 8, + 9 + ], + "specialFeatures": [ + + ], + "name": "Basic ads, personalised content, ad and content measurement, and audience insights", + "description": "Basic ads can be served. Content can be personalised based on a profile. More data can be added to better personalise content. Ad and content performance can be measured. Insights about the audiences who saw the ads and content can be derived." + }, + "33": { + "id": 33, + "purposes": [ + 2, + 5, + 6, + 7, + 8, + 9, + 10 + ], + "specialFeatures": [ + + ], + "name": "Basic ads, personalised content, ad and content measurement, audience insights, and product development", + "description": "Basic ads can be served. Content can be personalised based on a profile. More data can be added to better personalise content. Ad and content performance can be measured. Insights about the audiences who saw the ads and content can be derived. Data can be used to build or improve user experience, systems, and software." + }, + "34": { + "id": 34, + "purposes": [ + 2, + 5, + 6, + 8, + 9 + ], + "specialFeatures": [ + + ], + "name": "Basic ads, personalised content, content measurement, and audience insights", + "description": "Basic ads can be served. Content can be personalised based on a profile. More data can be added to better personalise content. Ad and content performance can be measured. Insights about the audiences who saw the ads and content can be derived." + }, + "35": { + "id": 35, + "purposes": [ + 2, + 5, + 6, + 8, + 9, + 10 + ], + "specialFeatures": [ + + ], + "name": "Basic ads, personalised content, content measurement, audience insights, and product development", + "description": "Basic ads can be served. Content can be personalised based on a profile. More data can be added to better personalise content. Content performance can be measured. Insights about the audiences who saw the ads and content can be derived. Data can be used to build or improve user experience, systems, and software." + }, + "36": { + "id": 36, + "purposes": [ + 2, + 5, + 6, + 7 + ], + "specialFeatures": [ + + ], + "name": "Basic ads, personalised content, and ad measurement", + "description": "Basic ads can be served. Content can be personalised based on a profile. More data can be added to better personalise content. Ad performance can be measured." + }, + "37": { + "id": 37, + "purposes": [ + 2, + 5, + 6, + 7, + 10 + ], + "specialFeatures": [ + + ], + "name": "Basic ads, personalised content, ad measurement, and product development", + "description": "Basic ads can be served. Content can be personalised based on a profile. More data can be added to better personalise content. Ad performance can be measured. Data can be used to build or improve user experience, systems, and software." + }, + "38": { + "id": 38, + "purposes": [ + 2, + 3, + 4, + 7, + 10 + ], + "specialFeatures": [ + + ], + "name": "Personalised ads, ad measurement, and product development", + "description": "Ads can be personalised based on a profile. More data can be added to better personalise ads. Ad performance can be measured. Data can be used to build or improve user experience, systems, and software." + }, + "39": { + "id": 39, + "purposes": [ + 2, + 3, + 4, + 7, + 9, + 10 + ], + "specialFeatures": [ + + ], + "name": "Personalised ads, ad measurement, audience insights and product development", + "description": "Ads can be personalised based on a profile. More data can be added to better personalise ads. Ad performance can be measured. Insights about the audiences who saw the ads and content can be derived. Data can be used to build or improve user experience, systems and software." + }, + "40": { + "id": 40, + "purposes": [ + 2, + 3, + 4, + 7, + 8, + 9, + 10 + ], + "specialFeatures": [ + + ], + "name": "Personalised ads, ad and content measurement, audience insights and product development", + "description": "Ads can be personalised based on a profile. More data can be added to better personalise ads. Ad and content performance can be measured. Insights about audiences who saw the ads and content can be derived. Data can be used to build or improve user experience, systems and software." + }, + "41": { + "id": 41, + "purposes": [ + 2, + 3, + 4, + 6, + 7, + 8, + 9, + 10 + ], + "specialFeatures": [ + + ], + "name": "Personalised ads, personalised content display, ad and content measurement, audience insights and product development", + "description": "Ads and content can be personalised based on a profile. More data can be added to better personalise ads. Ad and content performance can be measured. Insights about audiences who saw the ads and content can be derived. Data can be used to build or improve user experience, systems and software." + }, + "42": { + "id": 42, + "purposes": [ + 2, + 3, + 4, + 5, + 6, + 7, + 8, + 9, + 10 + ], + "specialFeatures": [ + + ], + "name": "Personalised ads and content, ad and content measurement, audience insights and product development", + "description": "Ads and content can be personalised based on a profile. More data can be added to better personalise ads and content. Ad and content performance can be measured. Insights about audiences who saw the ads and content can be derived. Data can be used to build or improve user experience, systems and software." + } + }, + "vendors": { + "10": { + "id": 10, + "name": "Index Exchange Inc. ", + "purposes": [ + 2, + 7 + ], + "impConsPurposes": [ + + ], + "flexiblePurposes": [ + 2, + 7 + ], + "specialPurposes": [ + 1, + 2 + ], + "features": [ + 3 + ], + "specialFeatures": [ + 1 + ], + "urls": [ + { + "langId": "en", + "privacy": "https://www.indexexchange.com/privacy/" + } + ] + }, + "52": { + "id": 52, + "name": "Magnite, Inc. ", + "purposes": [ + + ], + "impConsPurposes": [ + 2, + 3, + 4, + 5, + 6, + 7, + 10 + ], + "flexiblePurposes": [ + 2, + 3, + 4, + 5, + 6 + ], + "specialPurposes": [ + 1, + 2 + ], + "features": [ + 2, + 3 + ], + "specialFeatures": [ + 1, + 2 + ], + "urls": [ + { + "langId": "en", + "privacy": "https://www.magnite.com/legal/advertising-platform-privacy-policy/" + } + ], + "overflow": { + "httpGetLimit": 128 + } + }, + "75": { + "id": 75, + "name": "M32 Connect Inc", + "purposes": [ + 2, + 3, + 4, + 8, + 10 + ], + "impConsPurposes": [ + + ], + "flexiblePurposes": [ + + ], + "specialPurposes": [ + 2 + ], + "features": [ + 1, + 2, + 3 + ], + "specialFeatures": [ + 2 + ], + "urls": [ + { + "langId": "en", + "privacy": "https://m32connect.com/privacy-consent-management/privacy-cookie-policy/" + }, + { + "langId": "fr", + "privacy": "https://m32connect.com/fr/vie-privee-et-gestion-du-consentement/politique-de-confidentialite/" + } + ] + }, + "93": { + "id": 93, + "name": "Adloox SA", + "purposes": [ + 2, + 7 + ], + "impConsPurposes": [ + + ], + "flexiblePurposes": [ + 2, + 7 + ], + "specialPurposes": [ + 1 + ], + "features": [ + + ], + "specialFeatures": [ + + ], + "urls": [ + { + "langId": "en", + "privacy": "https://www.adloox.com/legal/privacy-policy" + } + ], + "overflow": { + "httpGetLimit": 128 + } + }, + "102": { + "id": 102, + "name": "Magnite, Inc. (Outstream)", + "purposes": [ + + ], + "impConsPurposes": [ + 2, + 7, + 8, + 10 + ], + "flexiblePurposes": [ + 2, + 8 + ], + "specialPurposes": [ + 1, + 2 + ], + "features": [ + 1, + 2, + 3 + ], + "specialFeatures": [ + 1, + 2 + ], + "urls": [ + { + "langId": "en", + "privacy": "https://www.magnite.com/legal/advertising-platform-privacy-policy/" + } + ], + "overflow": { + "httpGetLimit": 128 + } + }, + "130": { + "id": 130, + "name": "NextRoll, Inc.", + "purposes": [ + 2, + 3, + 4, + 5, + 6, + 7, + 9, + 10 + ], + "impConsPurposes": [ + + ], + "flexiblePurposes": [ + 2, + 7, + 9, + 10 + ], + "specialPurposes": [ + 1, + 2 + ], + "features": [ + 1, + 2, + 3 + ], + "specialFeatures": [ + + ], + "urls": [ + { + "langId": "en", + "privacy": "https://www.nextroll.com/privacy" + }, + { + "langId": "de", + "privacy": "https://www.nextroll.com/privacy" + }, + { + "langId": "es", + "privacy": "https://www.nextroll.com/es-ES/privacy" + }, + { + "langId": "nl", + "privacy": "https://www.nextroll.com/nl-NL/privacy" + }, + { + "langId": "fr", + "privacy": "https://www.nextroll.com/fr-FR/privacy" + }, + { + "langId": "it", + "privacy": "https://www.nextroll.com/it-IT/privacy" + } + ] + }, + "138": { + "id": 138, + "name": "ConnectAd Demand GmbH", + "purposes": [ + 4 + ], + "impConsPurposes": [ + 2, + 7, + 10 + ], + "flexiblePurposes": [ + 7, + 10 + ], + "specialPurposes": [ + 1, + 2 + ], + "features": [ + 3 + ], + "specialFeatures": [ + + ], + "urls": [ + { + "langId": "en", + "privacy": "https://connectadrealtime.com/privacy/" + } + ] + }, + "202": { + "id": 202, + "name": "Magnite CTV, Inc.", + "purposes": [ + + ], + "impConsPurposes": [ + 2, + 3, + 4, + 5, + 6, + 7, + 8, + 10 + ], + "flexiblePurposes": [ + 2, + 3, + 4, + 5, + 6, + 8 + ], + "specialPurposes": [ + 1, + 2 + ], + "features": [ + 2, + 3 + ], + "specialFeatures": [ + 1, + 2 + ], + "urls": [ + { + "langId": "en", + "privacy": "https://www.magnite.com/legal/advertising-platform-privacy-policy/" + } + ], + "overflow": { + "httpGetLimit": 128 + } + }, + "211": { + "id": 211, + "name": "AdTheorent, Inc", + "purposes": [ + 2, + 3, + 4, + 5, + 6, + 7, + 8, + 9, + 10 + ], + "impConsPurposes": [ + + ], + "flexiblePurposes": [ + + ], + "specialPurposes": [ + 1, + 2 + ], + "features": [ + 1, + 2, + 3 + ], + "specialFeatures": [ + 1, + 2 + ], + "urls": [ + { + "langId": "en", + "privacy": "https://adtheorent.com/privacy-policy" + } + ], + "overflow": { + "httpGetLimit": 128 + } + }, + "231": { + "id": 231, + "name": "AcuityAds Inc.", + "purposes": [ + 3, + 4 + ], + "impConsPurposes": [ + 2, + 7, + 8, + 10 + ], + "flexiblePurposes": [ + 2, + 7, + 8, + 10 + ], + "specialPurposes": [ + 1, + 2 + ], + "features": [ + 2 + ], + "specialFeatures": [ + + ], + "urls": [ + { + "langId": "en", + "privacy": "https://illumin.com/legal/privacy/" + } + ] + }, + "293": { + "id": 293, + "name": "SpringServe, LLC", + "purposes": [ + + ], + "impConsPurposes": [ + 2, + 7, + 8, + 10 + ], + "flexiblePurposes": [ + 2 + ], + "specialPurposes": [ + 1, + 2 + ], + "features": [ + 2, + 3 + ], + "specialFeatures": [ + 1, + 2 + ], + "urls": [ + { + "langId": "en", + "privacy": "https://springserve.com/privacy-policy/" + } + ] + }, + "294": { + "id": 294, + "name": "Jivox Corporation", + "purposes": [ + 2, + 3, + 4, + 5, + 7 + ], + "impConsPurposes": [ + + ], + "flexiblePurposes": [ + 2, + 3, + 4, + 5, + 7 + ], + "specialPurposes": [ + 1, + 2 + ], + "features": [ + 2 + ], + "specialFeatures": [ + 1 + ], + "urls": [ + { + "langId": "en", + "privacy": "https://www.jivox.com/privacy" + } + ], + "overflow": { + "httpGetLimit": 32 + } + }, + "319": { + "id": 319, + "name": "Clipcentric, Inc.", + "purposes": [ + + ], + "impConsPurposes": [ + 2, + 7, + 10 + ], + "flexiblePurposes": [ + 2, + 7 + ], + "specialPurposes": [ + 1, + 2 + ], + "features": [ + 3 + ], + "specialFeatures": [ + 1 + ] + }, + "410": { + "id": 410, + "name": "Adtelligent Inc.", + "purposes": [ + 2, + 7 + ], + "impConsPurposes": [ + + ], + "flexiblePurposes": [ + + ], + "specialPurposes": [ + 1, + 2 + ], + "features": [ + 3 + ], + "specialFeatures": [ + + ], + "urls": [ + { + "langId": "en", + "privacy": "https://adtelligent.com/privacy-policy/" + } + ] + }, + "413": { + "id": 413, + "name": "Eulerian Technologies", + "purposes": [ + 2, + 3, + 4, + 5, + 6, + 7, + 8, + 9, + 10 + ], + "impConsPurposes": [ + + ], + "flexiblePurposes": [ + + ], + "specialPurposes": [ + + ], + "features": [ + 1, + 2, + 3 + ], + "specialFeatures": [ + + ], + "urls": [ + { + "langId": "en", + "privacy": "https://www.eulerian.com/en/privacy/" + }, + { + "langId": "fr", + "privacy": "https://www.eulerian.com/vieprivee/" + }, + { + "langId": "it", + "privacy": "https://www.eulerian.com/it/privacy" + }, + { + "langId": "es", + "privacy": "https://www.eulerian.com/es/privacidad" + } + ] + }, + "415": { + "id": 415, + "name": "Seenthis AB", + "purposes": [ + + ], + "impConsPurposes": [ + + ], + "flexiblePurposes": [ + + ], + "specialPurposes": [ + 2 + ], + "features": [ + + ], + "specialFeatures": [ + + ] + }, + "431": { + "id": 431, + "name": "HUMAN", + "purposes": [ + + ], + "impConsPurposes": [ + + ], + "flexiblePurposes": [ + + ], + "specialPurposes": [ + 1 + ], + "features": [ + 1, + 3 + ], + "specialFeatures": [ + + ], + "urls": [ + { + "langId": "en", + "privacy": "https://www.humansecurity.com/privacy" + } + ] + }, + "639": { + "id": 639, + "name": "Smile Wanted Group", + "purposes": [ + 2, + 3, + 4, + 5, + 6, + 7, + 8, + 9, + 10 + ], + "impConsPurposes": [ + + ], + "flexiblePurposes": [ + + ], + "specialPurposes": [ + + ], + "features": [ + + ], + "specialFeatures": [ + + ], + "urls": [ + { + "langId": "en", + "privacy": "https://www.smilewanted.com/privacy.php" + } + ] + }, + "734": { + "id": 734, + "name": "Cint AB", + "purposes": [ + 7, + 8, + 9 + ], + "impConsPurposes": [ + + ], + "flexiblePurposes": [ + 7, + 8, + 9 + ], + "specialPurposes": [ + 1 + ], + "features": [ + 1, + 2, + 3 + ], + "specialFeatures": [ + + ], + "urls": [ + { + "langId": "en", + "privacy": "https://www.cint.com/participant-privacy-notice" + } + ] + }, + "737": { + "id": 737, + "name": "Monet Engine Inc", + "purposes": [ + 2, + 3, + 4, + 5, + 6, + 7, + 8, + 9, + 10 + ], + "impConsPurposes": [ + + ], + "flexiblePurposes": [ + + ], + "specialPurposes": [ + 2 + ], + "features": [ + 3 + ], + "specialFeatures": [ + + ], + "urls": [ + { + "langId": "en", + "privacy": "https://adaptmx.com/privacy-policy/" + } + ] + }, + "759": { + "id": 759, + "name": "RevJet", + "purposes": [ + 2, + 3, + 4, + 5, + 6, + 7, + 8, + 10 + ], + "impConsPurposes": [ + + ], + "flexiblePurposes": [ + + ], + "specialPurposes": [ + 1, + 2 + ], + "features": [ + 1 + ], + "specialFeatures": [ + + ], + "urls": [ + { + "langId": "en", + "privacy": "https://www.innervate.com/privacy" + } + ], + "overflow": { + "httpGetLimit": 128 + } + }, + "767": { + "id": 767, + "name": "Clinch Labs LTD", + "purposes": [ + + ], + "impConsPurposes": [ + 2, + 3, + 4, + 7, + 9, + 10 + ], + "flexiblePurposes": [ + 2, + 3, + 4, + 7, + 9, + 10 + ], + "specialPurposes": [ + 1, + 2 + ], + "features": [ + 1, + 2, + 3 + ], + "specialFeatures": [ + + ], + "urls": [ + { + "langId": "en", + "privacy": "https://clinch.co/privacy-policy/" + } + ] + }, + "775": { + "id": 775, + "name": "SelectMedia International LTD", + "purposes": [ + 2, + 3, + 4, + 7, + 8 + ], + "impConsPurposes": [ + + ], + "flexiblePurposes": [ + + ], + "specialPurposes": [ + 1, + 2 + ], + "features": [ + 3 + ], + "specialFeatures": [ + + ], + "urls": [ + { + "langId": "en", + "privacy": "https://www.selectmedia.asia/terms-and-privacy/" + } + ] + }, + "816": { + "id": 816, + "name": "NoBid, Inc.", + "purposes": [ + 2 + ], + "impConsPurposes": [ + 7, + 10 + ], + "flexiblePurposes": [ + + ], + "specialPurposes": [ + 1, + 2 + ], + "features": [ + + ], + "specialFeatures": [ + + ], + "urls": [ + { + "langId": "en", + "privacy": "https://www.nobid.io/privacy-policy/" + } + ] + }, + "839": { + "id": 839, + "name": "PIXFUTURE MEDIA INC.", + "purposes": [ + 3, + 4, + 5, + 6, + 7, + 8, + 9, + 10 + ], + "impConsPurposes": [ + 2 + ], + "flexiblePurposes": [ + + ], + "specialPurposes": [ + 1, + 2 + ], + "features": [ + 1, + 2, + 3 + ], + "specialFeatures": [ + 1, + 2 + ], + "urls": [ + { + "langId": "en", + "privacy": "https://www.pixfuture.com/terms-and-conditions#dpa-terms" + } + ] + }, + "874": { + "id": 874, + "name": "PRECISO SRL", + "purposes": [ + 3, + 4, + 5, + 6 + ], + "impConsPurposes": [ + + ], + "flexiblePurposes": [ + + ], + "specialPurposes": [ + + ], + "features": [ + + ], + "specialFeatures": [ + + ], + "urls": [ + { + "langId": "en", + "privacy": "https://preciso.net/privacy.html" + } + ], + "overflow": { + "httpGetLimit": 128 + } + }, + "881": { + "id": 881, + "name": "Hillside (Sports) GP Limited", + "purposes": [ + 2, + 7, + 8, + 10 + ], + "impConsPurposes": [ + + ], + "flexiblePurposes": [ + + ], + "specialPurposes": [ + 2 + ], + "features": [ + + ], + "specialFeatures": [ + + ], + "urls": [ + { + "langId": "en", + "privacy": "https://www.bet365partners.com/en/privacypolicy" + }, + { + "langId": "it", + "privacy": "https://www.bet365partners.com/it/privacypolicy" + }, + { + "langId": "es", + "privacy": "https://www.bet365partners.com/es/privacypolicy" + }, + { + "langId": "de", + "privacy": "https://www.bet365partners.com/de/privacypolicy" + }, + { + "langId": "da", + "privacy": "https://www.bet365partners.com/da/privacypolicy" + }, + { + "langId": "sv", + "privacy": "https://www.bet365partners.com/sv/privacypolicy" + }, + { + "langId": "no", + "privacy": "https://www.bet365partners.com/nn/privacypolicy" + }, + { + "langId": "fr", + "privacy": "https://www.bet365partners.com/fr/privacypolicy" + }, + { + "langId": "bg", + "privacy": "https://www.bet365partners.com/bg/privacypolicy" + }, + { + "langId": "el", + "privacy": "https://www.bet365partners.com/el/privacypolicy" + }, + { + "langId": "pt", + "privacy": "https://www.bet365partners.com/br/privacypolicy" + }, + { + "langId": "pl", + "privacy": "https://www.bet365partners.com/pl/privacypolicy" + }, + { + "langId": "cs", + "privacy": "https://www.bet365partners.com/cs/privacypolicy" + }, + { + "langId": "hu", + "privacy": "https://www.bet365partners.com/hu/privacypolicy" + }, + { + "langId": "sl", + "privacy": "https://www.bet365partners.com/sk/privacypolicy" + }, + { + "langId": "nl", + "privacy": "https://www.bet365partners.com/nl/privacypolicy" + }, + { + "langId": "et", + "privacy": "https://www.bet365partners.com/et/privacypolicy" + }, + { + "langId": "ru", + "privacy": "https://www.bet365partners.com/ru/privacypolicy" + }, + { + "langId": "ja", + "privacy": "https://www.bet365partners.com/ja/privacypolicy" + } + ] + }, + "909": { + "id": 909, + "name": "MobileFuse LLC", + "purposes": [ + 2, + 7, + 9, + 10 + ], + "impConsPurposes": [ + + ], + "flexiblePurposes": [ + + ], + "specialPurposes": [ + 1, + 2 + ], + "features": [ + 1 + ], + "specialFeatures": [ + + ], + "urls": [ + { + "langId": "en", + "privacy": "https://mobilefuse.com/privacy-policy/" + } + ] + }, + "964": { + "id": 964, + "name": "Solution coupons", + "purposes": [ + 2, + 3, + 7, + 8 + ], + "impConsPurposes": [ + + ], + "flexiblePurposes": [ + + ], + "specialPurposes": [ + + ], + "features": [ + + ], + "specialFeatures": [ + + ], + "urls": [ + { + "langId": "en", + "privacy": "https://solution.coupons/privacy" + } + ], + "overflow": { + "httpGetLimit": 32 + } + }, + "996": { + "id": 996, + "name": "CMI Marketing, Inc. d/b/a CafeMedia", + "purposes": [ + 3, + 4, + 5, + 6, + 7, + 8, + 10 + ], + "impConsPurposes": [ + 2 + ], + "flexiblePurposes": [ + 2 + ], + "specialPurposes": [ + 1, + 2 + ], + "features": [ + + ], + "specialFeatures": [ + + ], + "urls": [ + { + "langId": "en", + "privacy": "https://cafemedia.com/publisher-advertising-privacy-policy/" + } + ] + }, + "1028": { + "id": 1028, + "name": "Sparteo", + "purposes": [ + 3, + 4, + 5, + 6, + 9 + ], + "impConsPurposes": [ + 2, + 7, + 8, + 10 + ], + "flexiblePurposes": [ + 2, + 7, + 8, + 10 + ], + "specialPurposes": [ + 1, + 2 + ], + "features": [ + 2, + 3 + ], + "specialFeatures": [ + 1 + ], + "urls": [ + { + "langId": "en", + "privacy": "https://sparteo.com/privacy-policy" + } + ] + }, + "1134": { + "id": 1134, + "name": "Bidmatic Inc", + "purposes": [ + 2, + 7 + ], + "impConsPurposes": [ + + ], + "flexiblePurposes": [ + + ], + "specialPurposes": [ + 1, + 2 + ], + "features": [ + 3 + ], + "specialFeatures": [ + + ], + "urls": [ + { + "langId": "en", + "privacy": "https://bidmatic.io/privacy-policy/" + } + ] + }, + "1151": { + "id": 1151, + "name": "Boldwin LTD", + "purposes": [ + 7 + ], + "impConsPurposes": [ + + ], + "flexiblePurposes": [ + + ], + "specialPurposes": [ + 1, + 2 + ], + "features": [ + 1, + 2, + 3 + ], + "specialFeatures": [ + 1, + 2 + ], + "urls": [ + { + "langId": "en", + "privacy": "https://bold-win.com/privacy-policy/" + } + ] + }, + "1189": { + "id": 1189, + "name": "ResponsiveAds, Inc.", + "purposes": [ + 7, + 10 + ], + "impConsPurposes": [ + + ], + "flexiblePurposes": [ + + ], + "specialPurposes": [ + 1, + 2 + ], + "features": [ + + ], + "specialFeatures": [ + + ] + }, + "1194": { + "id": 1194, + "name": "GREEN GREY HOLDING (CY) LTD", + "purposes": [ + 2, + 3, + 4, + 9 + ], + "impConsPurposes": [ + 7, + 10 + ], + "flexiblePurposes": [ + 2, + 4, + 7, + 9 + ], + "specialPurposes": [ + 1, + 2 + ], + "features": [ + 1, + 2, + 3 + ], + "specialFeatures": [ + 1 + ] + }, + "1217": { + "id": 1217, + "name": "Channel99, Inc.", + "purposes": [ + + ], + "impConsPurposes": [ + 7 + ], + "flexiblePurposes": [ + + ], + "specialPurposes": [ + + ], + "features": [ + 1 + ], + "specialFeatures": [ + + ], + "urls": [ + { + "langId": "en", + "privacy": "https://www.channel99.com/privacy-policy/" + } + ] + } + } +} \ No newline at end of file diff --git a/iabgpp-extras-jackson/src/test/resources/vendorlist/v2/purposes-fr.json b/iabgpp-extras-jackson/src/test/resources/vendorlist/v2/purposes-fr.json new file mode 100644 index 00000000..98cfa81b --- /dev/null +++ b/iabgpp-extras-jackson/src/test/resources/vendorlist/v2/purposes-fr.json @@ -0,0 +1 @@ +{"vendorListVersion":29,"lastUpdated":"2020-03-12T16:40:38Z","purposes":{"1":{"id":1,"name":"Stocker et/ou acc\u00e9der \u00e0 des informations stock\u00e9es sur un terminal","description":"Les cookies, identifiants de votre terminal ou autres informations peuvent \u00eatre stock\u00e9s ou consult\u00e9s sur votre terminal pour les finalit\u00e9s qui vous sont pr\u00e9sent\u00e9es.","descriptionLegal":"Les partenaires peuvent :\n* Stocker des informations et acc\u00e9der \u00e0 des informations stock\u00e9es sur le terminal, comme les cookies et les identifiants du terminal pr\u00e9sent\u00e9s \u00e0 un utilisateur.\n"},"2":{"id":2,"name":"S\u00e9lectionner des publicit\u00e9s standard","description":"Les publicit\u00e9s peuvent vous \u00eatre pr\u00e9sent\u00e9es en fonction du contenu \u00e9ditorial que vous consultez, de l\u2019application que vous utilisez, de votre localisation approximative, ou de votre type de terminal\n","descriptionLegal":"Pour s\u00e9lectionner des publicit\u00e9s standard, les partenaires peuvent :\n* Utiliser des informations en temps r\u00e9el sur le contexte dans lequel la publicit\u00e9 sera affich\u00e9e, pour afficher la publicit\u00e9, y compris des informations sur le contenu et le terminal, telles que : type de terminal et capacit\u00e9s, user agent, URL, adresse IP \n* Utiliser des donn\u00e9es de g\u00e9olocalisation non-pr\u00e9cises d\u2019un utilisateur\n* Contr\u00f4ler la fr\u00e9quence de diffusion des publicit\u00e9s \u00e0 un utilisateur.\n* D\u00e9finir l\u2019ordre dans lequel les publicit\u00e9s sont pr\u00e9sent\u00e9es \u00e0 un utilisateur.\n* Emp\u00eacher une publicit\u00e9 de s\u2019afficher dans un contexte \u00e9ditorial inadapt\u00e9 (dangereux pour la marque)\nLes partenaires ne peuvent pas :\n* Cr\u00e9er un profil publicitaire personnalis\u00e9 \u00e0 l\u2019aide de ces informations pour la s\u00e9lection de publicit\u00e9s futures sans base l\u00e9gale distincte. \nN.B. \u00ab Non-pr\u00e9cises \u00bb signifie qu\u2019une g\u00e9olocalisation approximative dans un rayon d\u2019au moins 500 m\u00e8tres est autoris\u00e9e.\n"},"3":{"id":3,"name":"Cr\u00e9er un profil personnalis\u00e9 de publicit\u00e9s","description":"Un profil peut \u00eatre cr\u00e9\u00e9 sur vous et sur vos centres d\u2019int\u00e9r\u00eat pour vous pr\u00e9senter des publicit\u00e9s personnalis\u00e9es susceptibles de vous int\u00e9resser.","descriptionLegal":"Pour cr\u00e9er un profil de publicit\u00e9s personnalis\u00e9es, les partenaires peuvent :\n* Collecter des informations sur un utilisateur, notamment son activit\u00e9, ses centres d\u2019int\u00e9r\u00eat, les sites ou applications consult\u00e9s, les donn\u00e9es d\u00e9mographiques ou la g\u00e9olocalisation d\u2019un utilisateur, pour cr\u00e9er ou modifier un profil utilisateur \u00e0 utiliser dans des publicit\u00e9s personnalis\u00e9es.\n"},"4":{"id":4,"name":"S\u00e9lectionner des publicit\u00e9s personnalis\u00e9es","description":"Des publicit\u00e9s personnalis\u00e9es peuvent vous \u00eatre pr\u00e9sent\u00e9es sur la base d\u2019un profil cr\u00e9\u00e9 sur vous.","descriptionLegal":"Pour s\u00e9lectionner des publicit\u00e9s personnalis\u00e9es, les partenaires peuvent :\n* S\u00e9lectionner des publicit\u00e9s personnalis\u00e9es sur la base d\u2019un profil utilisateur ou d\u2019autres donn\u00e9es d\u2019utilisateur historiques, y compris l\u2019activit\u00e9 pass\u00e9e d\u2019un utilisateur, ses centres d\u2019int\u00e9r\u00eat, les sites qu\u2019il a visit\u00e9s ou les applications qu\u2019il a utilis\u00e9es, sa localisation ou ses donn\u00e9es d\u00e9mographiques.\n"},"5":{"id":5,"name":"Cr\u00e9er un profil pour afficher un contenu personnalis\u00e9","description":"Un profil peut \u00eatre cr\u00e9\u00e9 sur vous et sur vos centres d\u2019int\u00e9r\u00eat afin de vous pr\u00e9senter du contenu personnalis\u00e9 susceptible de vous int\u00e9resser.","descriptionLegal":"Pour cr\u00e9er un profil pour afficher du contenu personnalis\u00e9, les partenaires peuvent :\n* Collecter des informations sur un utilisateur, y compris l\u2019activit\u00e9 d\u2019un utilisateur, ses centres d\u2019int\u00e9r\u00eat, les sites qu\u2019il a visit\u00e9s ou les applications qu\u2019il a utilis\u00e9es, ses donn\u00e9es d\u00e9mographiques ou sa localisation, pour cr\u00e9er ou modifier un profil utilisateur pour afficher du contenu personnalis\u00e9.\n"},"6":{"id":6,"name":"S\u00e9lectionner du contenu personnalis\u00e9","description":"Du contenu personnalis\u00e9 peut vous \u00eatre pr\u00e9sent\u00e9 sur la base de votre profil utilisateur. ","descriptionLegal":"Pour s\u00e9lectionner du contenu personnalis\u00e9, les partenaires peuvent :\n* S\u00e9lectionner du contenu personnalis\u00e9 sur la base d\u2019un profil utilisateur induit des donn\u00e9es relatives \u00e0 son activit\u00e9 en ligne, ses centres d\u2019int\u00e9r\u00eat, les sites qu\u2019il a visit\u00e9s, les applications qu\u2019il a utilis\u00e9es, sa localisation ou ses donn\u00e9es socio-d\u00e9mographiques.\n"},"7":{"id":7,"name":"Mesurer la performance des publicit\u00e9s","description":"La performance et l\u2019efficacit\u00e9 des publicit\u00e9s que vous voyez ou avec lesquelles vous interagissez peuvent \u00eatre mesur\u00e9es.","descriptionLegal":"Pour mesurer la performance des publicit\u00e9s, les partenaires peuvent:\n* Mesurer si et comment des publicit\u00e9s ont \u00e9t\u00e9 pr\u00e9sent\u00e9e \u00e0 un utilisateur et comment celui-ci a interagi avec celles-ci\n* G\u00e9n\u00e9rer des rapports sur les publicit\u00e9s, notamment sur leur performance\n* G\u00e9n\u00e9rer des rapports sur les utilisateurs ayant interagi avec des publicit\u00e9s en utilisant des donn\u00e9es issues de cette interaction \n* Fournir des rapports aux \u00e9diteurs sur les publicit\u00e9s pr\u00e9sent\u00e9es/affich\u00e9es sur leurs propri\u00e9t\u00e9s num\u00e9riques \n* \u00c9valuer si une publicit\u00e9 diffus\u00e9e dans un contexte \u00e9ditorial appropri\u00e9 (conforme \u00e0 l\u2019image de la marque) sans danger pour la marque)\n* D\u00e9terminer le pourcentage du visionnage \u00e9ventuel de la publicit\u00e9 et sa dur\u00e9e \n* Combiner ces informations avec d\u2019autres informations collect\u00e9es au pr\u00e9alable, pouvant provenir de sites internet et applications\nLes partenaires ne peuvent pas: \n* Croiser des donn\u00e9es d\u2019audience, issues ou d\u00e9riv\u00e9es d\u2019un panel, avec des donn\u00e9es de mesure de performance, sans base l\u00e9gale pour titre \"Finalit\u00e9 9\". \n"},"8":{"id":8,"name":"Mesurer la performance du contenu","description":"La performance et l\u2019efficacit\u00e9 du contenu que vous voyez ou avec lequel vous interagissez peuvent \u00eatre mesur\u00e9es.","descriptionLegal":"Pour mesurer la performance du contenu, les partenaires peuvent:\n* Mesurer comment le contenu a \u00e9t\u00e9 diffus\u00e9 et comment les utilisateurs ont interagi avec, et g\u00e9n\u00e9rer des rapports.\n* G\u00e9n\u00e9rer des rapports \u00e0 l\u2019aide d\u2019informations directement mesurables ou connues, sur les utilisateurs qui ont interagi avec le contenu\nLes partenaires ne peuvent pas:\n* Mesurer si et comment des publicit\u00e9s (y compris des publicit\u00e9s natives) ont \u00e9t\u00e9 pr\u00e9sent\u00e9es \u00e0 un utilisateur et comment celui-ci a interagi avec, sans base l\u00e9gale distincte\n* Croiser des donn\u00e9es d\u2019audience, issues ou d\u00e9riv\u00e9es d\u2019un panel, avec des donn\u00e9es de mesure de performance, sans base l\u00e9gale pour titre \"Finalit\u00e9 9\u201d. "},"9":{"id":9,"name":"Exploiter des \u00e9tudes de march\u00e9 afin de g\u00e9n\u00e9rer des donn\u00e9es d\u2019audience","description":"Les \u00e9tudes de march\u00e9 peuvent servir \u00e0 en apprendre davantage sur les audiences qui visitent des sites/utilisent des applications et voient des publicit\u00e9s.","descriptionLegal":"Pour utiliser des \u00e9tudes de march\u00e9 afin de g\u00e9n\u00e9rer des donn\u00e9es d\u2019audience, les partenaires peuvent:\n* Fournir des rapports agr\u00e9g\u00e9s aux annonceurs ou \u00e0 leurs repr\u00e9sentants sur les audiences expos\u00e9es \u00e0 leurs publicit\u00e9s, en utilisant des donn\u00e9es issues d\u2019un panel ou d\u2019un autre dispositif.\n* Fournir des rapports agr\u00e9g\u00e9s aux \u00e9diteurs sur les audiences expos\u00e9es \u00e0 des contenus et/ou des publicit\u00e9s ou qui ont interagi avec des contenus et/ou les publicit\u00e9s sur leurs sites, en utilisant des donn\u00e9es issues d\u2019un panel ou d\u2019un autre dispositif. \n* Combiner des donn\u00e9es hors ligne \u00e0 celles d\u2019un utilisateur en ligne dans le cadre d\u2019\u00e9tudes de march\u00e9 pour g\u00e9n\u00e9rer des donn\u00e9es d\u2019audience si les partenaires ont d\u00e9clar\u00e9 faire correspondre et associer des sources de donn\u00e9es hors ligne (Fonctionnalit\u00e9 1)\n* Texte dans la version anglaise : Combiner ces informations avec des donn\u00e9es d\u00e9j\u00e0 collect\u00e9es que ce soit sur le web ou via des applications. \nLes partenaires ne peuvent pas : \n* Mesurer la performance et l\u2019efficacit\u00e9 des publicit\u00e9s qui ont \u00e9t\u00e9 pr\u00e9sent\u00e9es \u00e0 un utilisateur en particulier, ou avec lesquelles il a interagi, sans s\u2019appuyer sur une base l\u00e9gale sp\u00e9cifique pour la mesure de la performance publicitaire.\n* \u00c9valuer le contenu qui a \u00e9t\u00e9 pr\u00e9sent\u00e9 \u00e0 un utilisateur en particulier et la fa\u00e7on dont ce dernier a r\u00e9agi sans s\u2019appuyer sur une base l\u00e9gale sp\u00e9cifique pour la mesure de la performance des contenus.\n"},"10":{"id":10,"name":"D\u00e9velopper et am\u00e9liorer les produits","description":"Vos donn\u00e9es peuvent \u00eatre utilis\u00e9es pour am\u00e9liorer les syst\u00e8mes et logiciels existants et pour d\u00e9velopper de nouveaux produits.","descriptionLegal":"Pour d\u00e9velopper de nouveaux produits et am\u00e9liorer des produits existants, les partenaires peuvent:\n* Utiliser des informations pour am\u00e9liorer leurs produits existants en y ajoutant de nouvelles fonctionnalit\u00e9s et pour d\u00e9velopper de nouveaux produits\n* Cr\u00e9er de nouveaux mod\u00e8les et algorithmes gr\u00e2ce au machine-learning \nLes partenaires ne peuvent pas:\n* Effectuer toute autre op\u00e9ration de traitement des donn\u00e9es autoris\u00e9e par une autre finalit\u00e9 dans le cadre de cette finalit\u00e9\n"}},"specialPurposes":{"1":{"id":1,"name":"Assurer la s\u00e9curit\u00e9, pr\u00e9venir la fraude et d\u00e9boguer","description":"Vos donn\u00e9es peuvent \u00eatre utilis\u00e9es pour surveiller et pr\u00e9venir les activit\u00e9s frauduleuses, et s\u2019assurer que les syst\u00e8mes et processus fonctionnent correctement et en toute s\u00e9curit\u00e9.","descriptionLegal":"Pour garantir la s\u00e9curit\u00e9, pr\u00e9venir la fraude et d\u00e9boguer, les partenaires peuvent:\n* Veiller \u00e0 ce que les donn\u00e9es soient transmises en toute s\u00e9curit\u00e9 \n* D\u00e9tecter et pr\u00e9venir les activit\u00e9s malveillantes, frauduleuses, inappropri\u00e9es ou ill\u00e9gales.\n* Assurer un fonctionnement correct et efficace des syst\u00e8mes et des processus, y compris surveiller et am\u00e9liorer la performance des syst\u00e8mes et processus utilis\u00e9s pour des finalit\u00e9s autoris\u00e9es\nLes partenaires ne peuvent pas:\n* Effectuer, au titre de cette finalit\u00e9, toute autre op\u00e9ration de traitement des donn\u00e9es autoris\u00e9e pour une finalit\u00e9 diff\u00e9rente .\nRemarque: Les donn\u00e9es collect\u00e9es et utilis\u00e9es pour assurer la s\u00e9curit\u00e9, pr\u00e9venir la fraude et d\u00e9boguer peuvent inclure des caract\u00e9ristiques d\u2019appareil envoy\u00e9es automatiquement \u00e0 des fins d'identification, des donn\u00e9es de g\u00e9olocalisation pr\u00e9cises et des donn\u00e9es obtenues par l\u2019analyse active des caract\u00e9ristiques de l\u2019appareil \u00e0 des fins d\u2019identification sans notification distincte et/ou opt-in distinct \n"},"2":{"id":2,"name":"Diffuser techniquement les publicit\u00e9s ou le contenu","description":"Votre terminal peut recevoir et envoyer des informations qui vous permettent de voir des publicit\u00e9s et du contenu et d\u2019interagir avec eux.","descriptionLegal":"Pour fournir des informations et r\u00e9pondre aux appels techniques, les partenaires peuvent:\n* Utiliser l\u2019adresse IP d\u2019un utilisateur pour diffuser une publicit\u00e9 sur Internet\n* R\u00e9agir \u00e0 l\u2019interaction d\u2019un utilisateur avec une publicit\u00e9 en dirigeant l\u2019utilisateur vers une page d\u2019accueil\n* Utiliser l\u2019adresse IP d\u2019un utilisateur pour diffuser du contenu sur Internet\n* R\u00e9agir \u00e0 l\u2019interaction d\u2019un utilisateur avec du contenu en dirigeant l\u2019utilisateur vers une page d\u2019accueil\n* Utiliser des informations sur le type de terminal et les capacit\u00e9s du terminal pour pr\u00e9senter des publicit\u00e9s ou du contenu, par exemple, pour pr\u00e9senter une publicit\u00e9 \u00e0 la bonne taille ou une vid\u00e9o dans un format pris en charge par le terminal \nLes partenaires ne peuvent pas:\n* Effectuer, au titre de cette finalit\u00e9, toute autre op\u00e9ration de traitement des donn\u00e9es autoris\u00e9e pour une finalit\u00e9 diff\u00e9rente \n"}},"features":{"1":{"id":1,"name":"Mettre en correspondance et combiner des sources de donn\u00e9es hors ligne","description":"Les donn\u00e9es issues de sources de donn\u00e9es hors ligne peuvent \u00eatre combin\u00e9es \u00e0 votre activit\u00e9 en ligne \u00e0 l\u2019appui d\u2019une ou de plusieurs finalit\u00e9s.","descriptionLegal":"Les partenaires peuvent : \n* Combiner des donn\u00e9es obtenues hors ligne avec des donn\u00e9es collect\u00e9es en ligne \u00e0 l\u2019appui d\u2019une ou de plusieurs Finalit\u00e9s ou Finalit\u00e9s sp\u00e9ciales.\n"},"2":{"id":2,"name":"Relier diff\u00e9rents terminaux","description":"Diff\u00e9rents terminaux peuvent \u00eatre identifi\u00e9s comme vous appartenant ou appartenant \u00e0 votre foyer \u00e0 l\u2019appui d\u2019une ou de plusieurs finalit\u00e9s","descriptionLegal":"Les partnenaires peuvent :\n* D\u00e9terminer, selon une approche d\u00e9terministe, que deux terminaux ou plus appartiennent au m\u00eame utilisateur ou au m\u00eame foyer\n* D\u00e9terminer, selon une approche probabiliste, que deux terminaux ou plus appartiennent au m\u00eame utilisateur ou au m\u00eame foyer\n* Analyser activement les caract\u00e9ristiques du terminal pour l\u2019identification probabiliste si les utilisateurs ont autoris\u00e9 les partenanaires \u00e0 analyser activement les caract\u00e9ristiques du terminal pour l\u2019identification (Fonctionnalit\u00e9 sp\u00e9ciale 2)\n"},"3":{"id":3,"name":"Recevoir et utiliser des caract\u00e9ristiques d\u2019identification d\u2019appareil envoy\u00e9es automatiquement","description":"Votre appareil peut \u00eatre distingu\u00e9 d\u2019autres appareils en fonction des informations qu\u2019il envoie automatiquement, telles que l\u2019adresse IP ou le type de navigateur.","descriptionLegal":"Les partenaires peuvent :\n* Cr\u00e9er un identifiant \u00e0 l\u2019aide des donn\u00e9es collect\u00e9es automatiquement \u00e0 partir d\u2019un appareil pour des caract\u00e9ristiques sp\u00e9cifiques ; par ex., adresse IP, cha\u00eene d\u2019agent utilisateur.\n* Utiliser cet identifiant pour r\u00e9identifier un appareil.\nLes partenaires ne peuvent pas :\n* Cr\u00e9er un identifiant \u00e0 l\u2019aide des donn\u00e9es collect\u00e9es via une analyse active d\u2019un terminal pour l\u2019identification de caract\u00e9ristiques sp\u00e9cifiques (par exemple, des polices install\u00e9es ou la r\u00e9solution d\u2019\u00e9cran) sans une adh\u00e9sion distincte de l\u2019utilisateur \u00e0 l\u2019analyse active des caract\u00e9ristiques de l\u2019appareil \u00e0 des fins d\u2019identification.\n* Utiliser cet identifiant pour r\u00e9-identifier un terminal.\n"}},"specialFeatures":{"1":{"id":1,"name":"Utiliser des donn\u00e9es de g\u00e9olocalisation pr\u00e9cises","description":"Vos donn\u00e9es de g\u00e9olocalisation pr\u00e9cises peuvent \u00eatre utilis\u00e9es \u00e0 l\u2019appui d\u2019une ou de plusieurs finalit\u00e9s. Cela signifie que votre localisation peut \u00eatre pr\u00e9cise \u00e0 plusieurs m\u00e8tres pr\u00e8s.","descriptionLegal":"Les partnenaires peuvent :\n* Collecter et traiter des donn\u00e9es de g\u00e9olocalisation pr\u00e9cises \u00e0 l\u2019appui d\u2019une ou de plusieurs finalit\u00e9s.\nN.B. Une g\u00e9olocalisation pr\u00e9cise signifie qu\u2019il n\u2019y a aucune restriction \u00e0 la pr\u00e9cision de la localisation d\u2019un utilisateur ; elle peut \u00eatre pr\u00e9cise \u00e0 quelques m\u00e8tres pr\u00e8s.\n"},"2":{"id":2,"name":"Analyser activement les caract\u00e9ristiques du terminal pour l\u2019identification","description":"Votre terminal peut \u00eatre identifi\u00e9 sur la base d\u2019une analyse de la combinaison unique de caract\u00e9ristiques de votre terminal.","descriptionLegal":"Les partenaires peuvent :\n* Cr\u00e9er un identifiant \u00e0 l\u2019aide des donn\u00e9es collect\u00e9es via une analyse active d\u2019un terminal pour l\u2019identification de caract\u00e9ristiques sp\u00e9cifiques, par exemple des polices install\u00e9es ou la r\u00e9solution d\u2019\u00e9cran. \n* Utiliser cet identifiant pour r\u00e9-identifier un terminal.\n"}},"stacks":{"1":{"id":1,"purposes":[],"specialFeatures":[1,2],"name":"Donn\u00e9es de g\u00e9olocalisation pr\u00e9cises et identification par analyse du terminal","description":"Des informations de g\u00e9olocalisation pr\u00e9cises et des informations sur les caract\u00e9ristiques de l\u2019appareil peuvent \u00eatre utilis\u00e9es."},"2":{"id":2,"purposes":[2,7],"specialFeatures":[],"name":"Publicit\u00e9s standards et mesure de performance des publicit\u00e9s","description":"Des publicit\u00e9s standards peuvent \u00eatre diffus\u00e9es. La performance des publicit\u00e9s peut \u00eatre mesur\u00e9e."},"3":{"id":3,"purposes":[2,3,4],"specialFeatures":[],"name":"Publicit\u00e9s personnalis\u00e9es","description":"Les publicit\u00e9s peuvent \u00eatre personnalis\u00e9es sur la base d\u2019un profil. Des donn\u00e9es suppl\u00e9mentaires peuvent \u00eatre ajout\u00e9es pour mieux personnaliser les publicit\u00e9s."},"4":{"id":4,"purposes":[2,7,9],"specialFeatures":[],"name":"Publicit\u00e9s standards et mesure de performance des publicit\u00e9s","description":"Des publicit\u00e9s standards peuvent \u00eatre diffus\u00e9es. La performance des publicit\u00e9s peut \u00eatre mesur\u00e9e. Des informations peuvent \u00eatre g\u00e9n\u00e9r\u00e9es sur les audiences qui ont vu les publicit\u00e9s et le contenu."},"5":{"id":5,"purposes":[2,3,7],"specialFeatures":[],"name":"Publicit\u00e9s standards, profil de publicit\u00e9s personnalis\u00e9es et mesure de performance des publicit\u00e9s","description":"Des publicit\u00e9s standards peuvent \u00eatre diffus\u00e9es. Des donn\u00e9es suppl\u00e9mentaires peuvent \u00eatre ajout\u00e9es pour mieux personnaliser les publicit\u00e9s. La performance des publicit\u00e9s peut \u00eatre mesur\u00e9e."},"6":{"id":6,"purposes":[2,4,7],"specialFeatures":[],"name":"Affichage de publicit\u00e9s personnalis\u00e9es et mesure de performance des publicit\u00e9s","description":"Les publicit\u00e9s peuvent \u00eatre personnalis\u00e9es sur la base d\u2019un profil. La performance des publicit\u00e9s peut \u00eatre mesur\u00e9e."},"7":{"id":7,"purposes":[2,4,7,9],"specialFeatures":[],"name":"Affichage de publicit\u00e9s personnalis\u00e9es, mesure de performance des publicit\u00e9s, et donn\u00e9es d\u2019audience","description":"Les publicit\u00e9s peuvent \u00eatre personnalis\u00e9es sur la base d\u2019un profil. La performance des publicit\u00e9s peut \u00eatre mesur\u00e9e. Des informations peuvent \u00eatre g\u00e9n\u00e9r\u00e9es sur les audiences qui ont vu les publicit\u00e9s et le contenu."},"8":{"id":8,"purposes":[2,3,4,7],"specialFeatures":[],"name":"Publicit\u00e9s personnalis\u00e9es et mesure de performance des annonces","description":"Les publicit\u00e9s peuvent \u00eatre personnalis\u00e9es sur la base d\u2019un profil. Des donn\u00e9es suppl\u00e9mentaires peuvent \u00eatre ajout\u00e9es pour mieux personnaliser les publicit\u00e9s. La performance des publicit\u00e9s peut \u00eatre mesur\u00e9e."},"9":{"id":9,"purposes":[2,3,4,7,9],"specialFeatures":[],"name":"Publicit\u00e9s personnalis\u00e9es, mesure de performance des publicit\u00e9s, et donn\u00e9es d\u2019audience","description":"Les publicit\u00e9s peuvent \u00eatre personnalis\u00e9es sur la base d\u2019un profil. Des donn\u00e9es suppl\u00e9mentaires peuvent \u00eatre ajout\u00e9es pour mieux personnaliser les publicit\u00e9s. La performance des publicit\u00e9s peut \u00eatre mesur\u00e9e. Des informations peuvent \u00eatre g\u00e9n\u00e9r\u00e9es sur les audiences qui ont vu les publicit\u00e9s et le contenu."},"10":{"id":10,"purposes":[3,4],"specialFeatures":[],"name":"Profil de publicit\u00e9s personnalis\u00e9es et affichage","description":"Les publicit\u00e9s peuvent \u00eatre personnalis\u00e9es sur la base d\u2019un profil. Des donn\u00e9es suppl\u00e9mentaires peuvent \u00eatre ajout\u00e9es pour mieux personnaliser les publicit\u00e9s. "},"11":{"id":11,"purposes":[5,6],"specialFeatures":[],"name":"Contenu personnalis\u00e9","description":"Le contenu peut \u00eatre personnalis\u00e9 sur la base d\u2019un profil. Des donn\u00e9es suppl\u00e9mentaires peuvent \u00eatre ajout\u00e9es pour mieux personnaliser le contenu."},"12":{"id":12,"purposes":[6,8],"specialFeatures":[],"name":"Affichage de contenu personnalis\u00e9 et mesure de performance du contenu","description":"Le contenu peut \u00eatre personnalis\u00e9 sur la base d\u2019un profil. La performance du contenu peut \u00eatre mesur\u00e9e."},"13":{"id":13,"purposes":[6,8,9],"specialFeatures":[],"name":"Affichage de contenu personnalis\u00e9, mesure de performance du contenu et donn\u00e9es d\u2019audience","description":"Le contenu peut \u00eatre personnalis\u00e9 sur la base d\u2019un profil. La performance du contenu peut \u00eatre mesur\u00e9e. Des informations peuvent \u00eatre g\u00e9n\u00e9r\u00e9es sur les audiences qui ont vu les publicit\u00e9s et le contenu."},"14":{"id":14,"purposes":[5,6,8],"specialFeatures":[],"name":"Contenu personnalis\u00e9 et mesure de performance du contenu","description":"Le contenu peut \u00eatre personnalis\u00e9 sur la base d\u2019un profil. Des donn\u00e9es suppl\u00e9mentaires peuvent \u00eatre ajout\u00e9es pour mieux personnaliser le contenu. La performance du contenu peut \u00eatre mesur\u00e9e."},"15":{"id":15,"purposes":[5,6,8,9],"specialFeatures":[],"name":"Contenu personnalis\u00e9, mesure de performance du contenu et donn\u00e9es d\u2019audience","description":"Le contenu peut \u00eatre personnalis\u00e9 sur la base d\u2019un profil. Des donn\u00e9es suppl\u00e9mentaires peuvent \u00eatre ajout\u00e9es pour mieux personnaliser le contenu. La performance du contenu peut \u00eatre mesur\u00e9e. Des informations peuvent \u00eatre g\u00e9n\u00e9r\u00e9es sur les audiences qui ont vu les publicit\u00e9s et le contenu."},"16":{"id":16,"purposes":[5,6,8,9,10],"specialFeatures":[],"name":"Contenu personnalis\u00e9, mesure de performance du contenu, donn\u00e9es d\u2019audience, et d\u00e9veloppement produit","description":"Le contenu peut \u00eatre personnalis\u00e9 sur la base d\u2019un profil. Des donn\u00e9es suppl\u00e9mentaires peuvent \u00eatre ajout\u00e9es pour mieux personnaliser le contenu. La performance du contenu peut \u00eatre mesur\u00e9e. Des informations peuvent \u00eatre g\u00e9n\u00e9r\u00e9es sur les audiences qui ont vu les publicit\u00e9s et le contenu. Les donn\u00e9es peuvent \u00eatre utilis\u00e9es pour cr\u00e9er ou am\u00e9liorer l\u2019exp\u00e9rience utilisateur, des syst\u00e8mes et logiciels"},"17":{"id":17,"purposes":[7,8,9],"specialFeatures":[],"name":"Mesure de performance des annonces et du contenu et donn\u00e9es d\u2019audience","description":"La performance des publicit\u00e9s et du contenu peut \u00eatre mesur\u00e9e. Des informations peuvent \u00eatre g\u00e9n\u00e9r\u00e9es sur les audiences qui ont vu les publicit\u00e9s et le contenu."},"18":{"id":18,"purposes":[7,8],"specialFeatures":[],"name":"Mesure de performance des publicit\u00e9s et du contenu","description":"La performance des publicit\u00e9s et du contenu peut \u00eatre mesur\u00e9e."},"19":{"id":19,"purposes":[7,9],"specialFeatures":[],"name":"Mesure de performance des publicit\u00e9s et donn\u00e9es d\u2019audience","description":"La performance des publicit\u00e9s peut \u00eatre mesur\u00e9e. Des informations peuvent \u00eatre g\u00e9n\u00e9r\u00e9es sur les audiences qui ont vu les publicit\u00e9s et le contenu"},"20":{"id":20,"purposes":[7,8,9,10],"specialFeatures":[],"name":"Mesure de performance des publicit\u00e9s et du contenu, donn\u00e9es d\u2019audience, et d\u00e9veloppement produit","description":"La performance des publicit\u00e9s et du contenu peut \u00eatre mesur\u00e9e. Des informations peuvent \u00eatre g\u00e9n\u00e9r\u00e9es sur les audiences qui ont vu les publicit\u00e9s et le contenu. Les donn\u00e9es peuvent \u00eatre utilis\u00e9es pour cr\u00e9er ou am\u00e9liorer l\u2019exp\u00e9rience utilisateur, les syst\u00e8mes et les logiciels. Des informations peuvent \u00eatre g\u00e9n\u00e9r\u00e9es sur les audiences qui ont vu les publicit\u00e9s et le contenu."},"21":{"id":21,"purposes":[8,9,10],"specialFeatures":[],"name":"Mesure de performance du contenu, donn\u00e9es d\u2019audience, et d\u00e9veloppement produit.","description":"La performance du contenu peut \u00eatre mesur\u00e9e. Des informations peuvent \u00eatre g\u00e9n\u00e9r\u00e9es sur les audiences qui ont vu les publicit\u00e9s et le contenu. Les donn\u00e9es peuvent \u00eatre utilis\u00e9es pour cr\u00e9er ou am\u00e9liorer l\u2019exp\u00e9rience utilisateur, les syst\u00e8mes et les logiciels."},"22":{"id":22,"purposes":[8,10],"specialFeatures":[],"name":"Mesure de performance du contenu, et d\u00e9veloppement produit","description":"La performance du contenu peut \u00eatre mesur\u00e9e. Les donn\u00e9es peuvent \u00eatre utilis\u00e9es pour cr\u00e9er ou am\u00e9liorer l\u2019exp\u00e9rience utilisateur, les syst\u00e8mes et les logiciels."},"23":{"id":23,"purposes":[2,4,6,7,8],"specialFeatures":[],"name":"Affichage de publicit\u00e9s et de contenu personnalis\u00e9s, mesure de performance des publicit\u00e9s et du contenu","description":"Les publicit\u00e9s et le contenu peuvent \u00eatre personnalis\u00e9s sur la base d\u2019un profil. La performance des publicit\u00e9s et du contenu peut \u00eatre mesur\u00e9e."},"24":{"id":24,"purposes":[2,4,6,7,8,9],"specialFeatures":[],"name":"Affichage de publicit\u00e9s et de contenu personnalis\u00e9s, mesure de performance des publicit\u00e9s et du contenu, et donn\u00e9es d\u2019audience","description":"Les publicit\u00e9s et le contenu peuvent \u00eatre personnalis\u00e9s sur la base d\u2019un profil. La performance des publicit\u00e9s et du contenu peut \u00eatre mesur\u00e9e. Des informations peuvent \u00eatre g\u00e9n\u00e9r\u00e9es sur les audiences qui ont vu les publicit\u00e9s et le contenu. Les donn\u00e9es peuvent \u00eatre utilis\u00e9es pour cr\u00e9er ou am\u00e9liorer l\u2019exp\u00e9rience utilisateur, les syst\u00e8mes et les logiciels."},"25":{"id":25,"purposes":[2,3,4,5,6,7,8],"specialFeatures":[],"name":"Publicit\u00e9s et contenu personnalis\u00e9s, mesure de performance des publicit\u00e9s et du contenu","description":"Les publicit\u00e9s et le contenu peuvent \u00eatre personnalis\u00e9s sur la base d\u2019un profil. Des donn\u00e9es suppl\u00e9mentaires peuvent \u00eatre ajout\u00e9es pour mieux personnaliser les publicit\u00e9s et le contenu. La performance des publicit\u00e9s et du contenu peut \u00eatre mesur\u00e9e."},"26":{"id":26,"purposes":[2,3,4,5,6,7,8,9],"specialFeatures":[],"name":"Publicit\u00e9s et contenu personnalis\u00e9s, mesure de performance des publicit\u00e9s et du contenu, et donn\u00e9es d\u2019audience","description":"Les publicit\u00e9s et le contenu peuvent \u00eatre personnalis\u00e9s sur la base d\u2019un profil. Des donn\u00e9es suppl\u00e9mentaires peuvent \u00eatre ajout\u00e9es pour mieux personnaliser les publicit\u00e9s et le contenu. La performance des publicit\u00e9s et du contenu peut \u00eatre mesur\u00e9e. Des informations peuvent \u00eatre g\u00e9n\u00e9r\u00e9es sur les audiences qui ont vu les publicit\u00e9s et le contenu."},"27":{"id":27,"purposes":[3,5],"specialFeatures":[],"name":"Publicit\u00e9s personnalis\u00e9es et profil de contenu","description":"Des donn\u00e9es suppl\u00e9mentaires peuvent \u00eatre ajout\u00e9es pour personnaliser les publicit\u00e9s et le contenu. "},"28":{"id":28,"purposes":[2,4,6],"specialFeatures":[],"name":"Affichage de publicit\u00e9s et de contenu personnalis\u00e9s","description":"Les publicit\u00e9s et le contenu peuvent \u00eatre personnalis\u00e9s sur la base d\u2019un profil. "},"29":{"id":29,"purposes":[2,7,8,9],"specialFeatures":[],"name":"Publicit\u00e9s standards, mesure de performance des publicit\u00e9s et du contenu, et donn\u00e9es d\u2019audience","description":"Des publicit\u00e9s standards peuvent \u00eatre diffus\u00e9es. La performance des publicit\u00e9s et du contenu peut \u00eatre mesur\u00e9e. Des informations peuvent \u00eatre g\u00e9n\u00e9r\u00e9es sur les audiences qui ont vu les publicit\u00e9s et le contenu."},"30":{"id":30,"purposes":[2,4,5,6,7,8,9],"specialFeatures":[],"name":"Affichage de publicit\u00e9s personnalis\u00e9es, contenu personnalis\u00e9, mesure de performance des publicit\u00e9s et du contenu, et donn\u00e9es d\u2019audience","description":"Les publicit\u00e9s et le contenu peuvent \u00eatre personnalis\u00e9s sur la base d\u2019un profil. Des donn\u00e9es suppl\u00e9mentaires peuvent \u00eatre ajout\u00e9es pour mieux personnaliser le contenu. La performance des publicit\u00e9s et du contenu peut \u00eatre mesur\u00e9e. Des informations peuvent \u00eatre g\u00e9n\u00e9r\u00e9es sur les audiences qui ont vu les publicit\u00e9s et le contenu."},"31":{"id":31,"purposes":[2,4,5,6,7,8,9,10],"specialFeatures":[],"name":"Affichage de publicit\u00e9s personnalis\u00e9es, contenu personnalis\u00e9, mesure de performance des publicit\u00e9s et du contenu, donn\u00e9es d\u2019audience et d\u00e9veloppement de produit","description":"Les publicit\u00e9s et le contenu peuvent \u00eatre personnalis\u00e9s sur la base d\u2019un profil. Des donn\u00e9es suppl\u00e9mentaires peuvent \u00eatre ajout\u00e9es pour mieux personnaliser le contenu. La performance des publicit\u00e9s et du contenu peut \u00eatre mesur\u00e9e. Des informations peuvent \u00eatre g\u00e9n\u00e9r\u00e9es sur les audiences qui ont vu les publicit\u00e9s et le contenu. Les donn\u00e9es peuvent \u00eatre utilis\u00e9es pour cr\u00e9er ou am\u00e9liorer l\u2019exp\u00e9rience utilisateur, les syst\u00e8mes et les logiciels."},"32":{"id":32,"purposes":[2,5,6,7,8,9],"specialFeatures":[],"name":"Publicit\u00e9s standards, contenu personnalis\u00e9, mesure de performance des publicit\u00e9s et du contenu, et donn\u00e9es d\u2019audience","description":"Des publicit\u00e9s standards peuvent \u00eatre diffus\u00e9es. Le contenu peut \u00eatre personnalis\u00e9 sur la base d\u2019un profil. Des donn\u00e9es suppl\u00e9mentaires peuvent \u00eatre ajout\u00e9es pour mieux personnaliser le contenu. La performance des publicit\u00e9s et du contenu peut \u00eatre mesur\u00e9e. Des informations peuvent \u00eatre g\u00e9n\u00e9r\u00e9es sur les audiences qui ont vu les publicit\u00e9s et le contenu."},"33":{"id":33,"purposes":[2,5,6,7,8,9,10],"specialFeatures":[],"name":"Publicit\u00e9s standards, contenu personnalis\u00e9, mesure de performance des publicit\u00e9s et du contenu, donn\u00e9es d\u2019audience, et d\u00e9veloppement produit","description":"Des publicit\u00e9s standards peuvent \u00eatre diffus\u00e9es. Le contenu peut \u00eatre personnalis\u00e9 sur la base d\u2019un profil. Des donn\u00e9es suppl\u00e9mentaires peuvent \u00eatre ajout\u00e9es pour mieux personnaliser le contenu. La performance des publicit\u00e9s et du contenu peut \u00eatre mesur\u00e9e. Des informations peuvent \u00eatre g\u00e9n\u00e9r\u00e9es sur les audiences qui ont vu les publicit\u00e9s et le contenu. Les donn\u00e9es peuvent \u00eatre utilis\u00e9es pour cr\u00e9er ou am\u00e9liorer l\u2019exp\u00e9rience utilisateur, les syst\u00e8mes et les logiciels."},"34":{"id":34,"purposes":[2,5,6,8,9],"specialFeatures":[],"name":"Publicit\u00e9s standards, contenu personnalis\u00e9, mesure de performance du contenu, et donn\u00e9es d\u2019audience","description":"Des publicit\u00e9s standards peuvent \u00eatre diffus\u00e9es. Le contenu peut \u00eatre personnalis\u00e9 sur la base d\u2019un profil. Des donn\u00e9es suppl\u00e9mentaires peuvent \u00eatre ajout\u00e9es pour mieux personnaliser le contenu. La performance des publicit\u00e9s et du contenu peut \u00eatre mesur\u00e9e. Des informations peuvent \u00eatre g\u00e9n\u00e9r\u00e9es sur les audiences qui ont vu les publicit\u00e9s et le contenu."},"35":{"id":35,"purposes":[2,5,6,8,9,10],"specialFeatures":[],"name":"Publicit\u00e9s standards, contenu personnalis\u00e9, mesure de performance du contenu, donn\u00e9es d\u2019audience et d\u00e9veloppement de produit ","description":"Des publicit\u00e9s standards peuvent \u00eatre diffus\u00e9es. Le contenu peut \u00eatre personnalis\u00e9 sur la base d\u2019un profil. Des donn\u00e9es suppl\u00e9mentaires peuvent \u00eatre ajout\u00e9es pour mieux personnaliser le contenu. La performance du contenu peut \u00eatre mesur\u00e9e. Des informations peuvent \u00eatre g\u00e9n\u00e9r\u00e9es sur les audiences qui ont vu les publicit\u00e9s et le contenu. Les donn\u00e9es peuvent \u00eatre utilis\u00e9es pour cr\u00e9er ou am\u00e9liorer l\u2019exp\u00e9rience utilisateur, les syst\u00e8mes et les logiciels."},"36":{"id":36,"purposes":[2,5,6,7],"specialFeatures":[],"name":"Publicit\u00e9s standard, contenu personnalis\u00e9 et mesure de performance des publicit\u00e9s","description":"Des publicit\u00e9s standards peuvent \u00eatre diffus\u00e9es. Le contenu peut \u00eatre personnalis\u00e9 sur la base d\u2019un profil. Des donn\u00e9es suppl\u00e9mentaires peuvent \u00eatre ajout\u00e9es pour mieux personnaliser le contenu. La performance des publicit\u00e9s peut \u00eatre mesur\u00e9e."},"37":{"id":37,"purposes":[2,5,6,7,10],"specialFeatures":[],"name":"Publicit\u00e9s standards, contenu personnalis\u00e9, mesure de performance des publicit\u00e9s, et d\u00e9veloppement produit","description":"Des publicit\u00e9s standards peuvent \u00eatre diffus\u00e9es. Le contenu peut \u00eatre personnalis\u00e9 sur la base d\u2019un profil. Des donn\u00e9es suppl\u00e9mentaires peuvent \u00eatre ajout\u00e9es pour mieux personnaliser le contenu. La performance des publicit\u00e9s peut \u00eatre mesur\u00e9e. Les donn\u00e9es peuvent \u00eatre utilis\u00e9es pour cr\u00e9er ou am\u00e9liorer l\u2019exp\u00e9rience utilisateur, les syst\u00e8mes et les logiciels."}}} \ No newline at end of file diff --git a/iabgpp-extras-jackson/src/test/resources/vendorlist/v2/vendor-list-v51.json b/iabgpp-extras-jackson/src/test/resources/vendorlist/v2/vendor-list-v51.json new file mode 100644 index 00000000..63ffbf6c --- /dev/null +++ b/iabgpp-extras-jackson/src/test/resources/vendorlist/v2/vendor-list-v51.json @@ -0,0 +1 @@ +{"gvlSpecificationVersion":2,"vendorListVersion":51,"tcfPolicyVersion":2,"lastUpdated":"2020-08-13T16:05:23Z","purposes":{"1":{"id":1,"name":"Store and/or access information on a device","description":"Cookies, device identifiers, or other information can be stored or accessed on your device for the purposes presented to you.","descriptionLegal":"Vendors can:\n* Store and access information on the device such as cookies and device identifiers presented to a user."},"2":{"id":2,"name":"Select basic ads","description":"Ads can be shown to you based on the content you\u2019re viewing, the app you\u2019re using, your approximate location, or your device type.","descriptionLegal":"To do basic ad selection vendors can:\n* Use real-time information about the context in which the ad will be shown, to show the ad, including information about the content and the device, such as: device type and capabilities, user agent, URL, IP address\n* Use a user\u2019s non-precise geolocation data\n* Control the frequency of ads shown to a user.\n* Sequence the order in which ads are shown to a user.\n* Prevent an ad from serving in an unsuitable editorial (brand-unsafe) context\nVendors cannot:\n* Create a personalised ads profile using this information for the selection of future ads.\n* N.B. Non-precise means only an approximate location involving at least a radius of 500 meters is permitted."},"3":{"id":3,"name":"Create a personalised ads profile","description":"A profile can be built about you and your interests to show you personalised ads that are relevant to you.","descriptionLegal":"To create a personalised ads profile vendors can:\n* Collect information about a user, including a user's activity, interests, demographic information, or location, to create or edit a user profile for use in personalised advertising.\n* Combine this information with other information previously collected, including from across websites and apps, to create or edit a user profile for use in personalised advertising."},"4":{"id":4,"name":"Select personalised ads","description":"Personalised ads can be shown to you based on a profile about you.","descriptionLegal":"To select personalised ads vendors can:\n* Select personalised ads based on a user profile or other historical user data, including a user\u2019s prior activity, interests, visits to sites or apps, location, or demographic information."},"5":{"id":5,"name":"Create a personalised content profile","description":"A profile can be built about you and your interests to show you personalised content that is relevant to you.","descriptionLegal":"To create a personalised content profile vendors can:\n* Collect information about a user, including a user's activity, interests, visits to sites or apps, demographic information, or location, to create or edit a user profile for personalising content.\n* Combine this information with other information previously collected, including from across websites and apps, to create or edit a user profile for use in personalising content."},"6":{"id":6,"name":"Select personalised content","description":"Personalised content can be shown to you based on a profile about you.","descriptionLegal":"To select personalised content vendors can:\n* Select personalised content based on a user profile or other historical user data, including a user\u2019s prior activity, interests, visits to sites or apps, location, or demographic information."},"7":{"id":7,"name":"Measure ad performance","description":"The performance and effectiveness of ads that you see or interact with can be measured.","descriptionLegal":"To measure ad performance vendors can:\n* Measure whether and how ads were delivered to and interacted with by a user\n* Provide reporting about ads including their effectiveness and performance\n* Provide reporting about users who interacted with ads using data observed during the course of the user's interaction with that ad\n* Provide reporting to publishers about the ads displayed on their property\n* Measure whether an ad is serving in a suitable editorial environment (brand-safe) context\n* Determine the percentage of the ad that had the opportunity to be seen and the duration of that opportunity\n* Combine this information with other information previously collected, including from across websites and apps\nVendors cannot:\n*Apply panel- or similarly-derived audience insights data to ad measurement data without a Legal Basis to apply market research to generate audience insights (Purpose 9)"},"8":{"id":8,"name":"Measure content performance","description":"The performance and effectiveness of content that you see or interact with can be measured.","descriptionLegal":"To measure content performance vendors can:\n* Measure and report on how content was delivered to and interacted with by users.\n* Provide reporting, using directly measurable or known information, about users who interacted with the content\n* Combine this information with other information previously collected, including from across websites and apps.\nVendors cannot:\n* Measure whether and how ads (including native ads) were delivered to and interacted with by a user.\n* Apply panel- or similarly derived audience insights data to ad measurement data without a Legal Basis to apply market research to generate audience insights (Purpose 9)"},"9":{"id":9,"name":"Apply market research to generate audience insights","description":"Market research can be used to learn more about the audiences who visit sites/apps and view ads.","descriptionLegal":"To apply market research to generate audience insights vendors can:\n* Provide aggregate reporting to advertisers or their representatives about the audiences reached by their ads, through panel-based and similarly derived insights.\n* Provide aggregate reporting to publishers about the audiences that were served or interacted with content and/or ads on their property by applying panel-based and similarly derived insights.\n* Associate offline data with an online user for the purposes of market research to generate audience insights if vendors have declared to match and combine offline data sources (Feature 1)\n* Combine this information with other information previously collected including from across websites and apps. \nVendors cannot:\n* Measure the performance and effectiveness of ads that a specific user was served or interacted with, without a Legal Basis to measure ad performance.\n* Measure which content a specific user was served and how they interacted with it, without a Legal Basis to measure content performance."},"10":{"id":10,"name":"Develop and improve products","description":"Your data can be used to improve existing systems and software, and to develop new products","descriptionLegal":"To develop new products and improve products vendors can:\n* Use information to improve their existing products with new features and to develop new products\n* Create new models and algorithms through machine learning\nVendors cannot:\n* Conduct any other data processing operation allowed under a different purpose under this purpose"}},"specialPurposes":{"1":{"id":1,"name":"Ensure security, prevent fraud, and debug","description":"Your data can be used to monitor for and prevent fraudulent activity, and ensure systems and processes work properly and securely.","descriptionLegal":"To ensure security, prevent fraud and debug vendors can:\n* Ensure data are securely transmitted\n* Detect and prevent malicious, fraudulent, invalid, or illegal activity.\n* Ensure correct and efficient operation of systems and processes, including to monitor and enhance the performance of systems and processes engaged in permitted purposes\nVendors cannot:\n* Conduct any other data processing operation allowed under a different purpose under this purpose."},"2":{"id":2,"name":"Technically deliver ads or content","description":"Your device can receive and send information that allows you to see and interact with ads and content.","descriptionLegal":"To deliver information and respond to technical requests vendors can:\n* Use a user\u2019s IP address to deliver an ad over the internet\n* Respond to a user\u2019s interaction with an ad by sending the user to a landing page\n* Use a user\u2019s IP address to deliver content over the internet\n* Respond to a user\u2019s interaction with content by sending the user to a landing page\n* Use information about the device type and capabilities for delivering ads or content, for example, to deliver the right size ad creative or video file in a format supported by the device\nVendors cannot:\n* Conduct any other data processing operation allowed under a different purpose under this purpose"}},"features":{"1":{"id":1,"name":"Match and combine offline data sources","description":"Data from offline data sources can be combined with your online activity in support of one or more purposes","descriptionLegal":"Vendors can:\n* Combine data obtained offline with data collected online in support of one or more Purposes or Special Purposes."},"2":{"id":2,"name":"Link different devices","description":"Different devices can be determined as belonging to you or your household in support of one or more of purposes.","descriptionLegal":"Vendors can:\n* Deterministically determine that two or more devices belong to the same user or household\n* Probabilistically determine that two or more devices belong to the same user or household\n* Actively scan device characteristics for identification for probabilistic identification if users have allowed vendors to actively scan device characteristics for identification (Special Feature 2)"},"3":{"id":3,"name":"Receive and use automatically-sent device characteristics for identification","description":"Your device might be distinguished from other devices based on information it automatically sends, such as IP address or browser type.","descriptionLegal":"Vendors can:\n* Create an identifier using data collected automatically from a device for specific characteristics, e.g. IP address, user-agent string.\n* Use such an identifier to attempt to re-identify a device.\nVendors cannot:\n* Create an identifier using data collected via actively scanning a device for specific characteristics, e.g. installed font or screen resolution without users\u2019 separate opt-in to actively scanning device characteristics for identification.\n* Use such an identifier to re-identify a device."}},"specialFeatures":{"1":{"id":1,"name":"Use precise geolocation data","description":"Your precise geolocation data can be used in support of one or more purposes. This means your location can be accurate to within several meters.","descriptionLegal":"Vendors can:\n* Collect and process precise geolocation data in support of one or more purposes.\nN.B. Precise geolocation means that there are no restrictions on the precision of a user\u2019s location; this can be accurate to within several meters."},"2":{"id":2,"name":"Actively scan device characteristics for identification","description":"Your device can be identified based on a scan of your device's unique combination of characteristics.","descriptionLegal":"Vendors can:\n* Create an identifier using data collected via actively scanning a device for specific characteristics, e.g. installed fonts or screen resolution.\n* Use such an identifier to re-identify a device."}},"stacks":{"1":{"id":1,"purposes":[],"specialFeatures":[1,2],"name":"Precise geolocation data, and identification through device scanning","description":"Precise geolocation and information about device characteristics can be used."},"2":{"id":2,"purposes":[2,7],"specialFeatures":[],"name":"Basic ads, and ad measurement","description":"Basic ads can be served. Ad performance can be measured."},"3":{"id":3,"purposes":[2,3,4],"specialFeatures":[],"name":"Personalised ads","description":"Ads can be personalised based on a profile. More data can be added to better personalise ads."},"4":{"id":4,"purposes":[2,7,9],"specialFeatures":[],"name":"Basic ads, ad measurement, and audience insights","description":"Basic ads can be served. Ad performance can be measured. Insights about the audiences who saw the ads and content can be derived."},"5":{"id":5,"purposes":[2,3,7],"specialFeatures":[],"name":"Basic ads, personalised ads profile, and ad measurement","description":"Basic ads can be served. More data can be added to better personalise ads. Ad performance can be measured."},"6":{"id":6,"purposes":[2,4,7],"specialFeatures":[],"name":"Personalised ads display and ad measurement","description":"Ads can be personalised based on a profile. Ad performance can be measured."},"7":{"id":7,"purposes":[2,4,7,9],"specialFeatures":[],"name":"Personalised ads display, ad measurement, and audience insights","description":"Ads can be personalised based on a profile. Ad performance can be measured. Insights about the audiences who saw the ads and content can be derived."},"8":{"id":8,"purposes":[2,3,4,7],"specialFeatures":[],"name":"Personalised ads, and ad measurement","description":"Ads can be personalised based on a profile. More data can be added to better personalise ads. Ad performance can be measured."},"9":{"id":9,"purposes":[2,3,4,7,9],"specialFeatures":[],"name":"Personalised ads, ad measurement, and audience insights","description":"Ads can be personalised based on a profile. More data can be added to better personalise ads. Ad performance can be measured. Insights about the audiences who saw the ads and content can be derived."},"10":{"id":10,"purposes":[3,4],"specialFeatures":[],"name":"Personalised ads profile and display","description":"Ads can be personalised based on a profile. More data can be added to better personalise ads."},"11":{"id":11,"purposes":[5,6],"specialFeatures":[],"name":"Personalised content","description":"Content can be personalised based on a profile. More data can be added to better personalise content."},"12":{"id":12,"purposes":[6,8],"specialFeatures":[],"name":"Personalised content display, and content measurement","description":"Content can be personalised based on a profile. Content performance can be measured."},"13":{"id":13,"purposes":[6,8,9],"specialFeatures":[],"name":"Personalised content display, content measurement and audience insights","description":"Content can be personalised based on a profile. Content performance can be measured. Insights about the audiences who saw the ads and content can be derived."},"14":{"id":14,"purposes":[5,6,8],"specialFeatures":[],"name":"Personalised content, and content measurement","description":"Content can be personalised based on a profile. More data can be added to better personalise content. Content performance can be measured."},"15":{"id":15,"purposes":[5,6,8,9],"specialFeatures":[],"name":"Personalised content, content measurement and audience insights","description":"Content can be personalised based on a profile. More data can be added to better personalise content. Content performance can be measured. Insights about the audiences who saw the ads and content can be derived."},"16":{"id":16,"purposes":[5,6,8,9,10],"specialFeatures":[],"name":"Personalised content, content measurement, audience insights, and product development","description":"Content can be personalised based on a profile. More data can be added to better personalise content. Content performance can be measured. Insights about the audiences who saw the ads and content can be derived. Data can be used to build or improve user experience, systems, and software"},"17":{"id":17,"purposes":[7,8,9],"specialFeatures":[],"name":"Ad and content measurement, and audience insights","description":"Ad and content performance can be measured. Insights about the audiences who saw the ads and content can be derived."},"18":{"id":18,"purposes":[7,8],"specialFeatures":[],"name":"Ad and content measurement","description":"Ad and content performance can be measured."},"19":{"id":19,"purposes":[7,9],"specialFeatures":[],"name":"Ad measurement, and audience insights","description":"Ad can be measured. Insights about the audiences who saw the ads and content can be derived."},"20":{"id":20,"purposes":[7,8,9,10],"specialFeatures":[],"name":"Ad and content measurement, audience insights, and product development","description":"Ad and content performance can be measured. Insights about the audiences who saw the ads and content can be derived. Data can be used to build or improve user experience, systems, and software. Insights about the audiences who saw the ads and content can be derived."},"21":{"id":21,"purposes":[8,9,10],"specialFeatures":[],"name":"Content measurement, audience insights, and product development.","description":"Content performance can be measured. Insights about the audiences who saw the ads and content can be derived. Data can be used to build or improve user experience, systems, and software."},"22":{"id":22,"purposes":[8,10],"specialFeatures":[],"name":"Content measurement, and product development","description":"Content performance can be measured. Data can be used to build or improve user experience, systems, and software."},"23":{"id":23,"purposes":[2,4,6,7,8],"specialFeatures":[],"name":"Personalised ads and content display, ad and content measurement","description":"Ads and content can be personalised based on a profile. Ad and content performance can be measured."},"24":{"id":24,"purposes":[2,4,6,7,8,9],"specialFeatures":[],"name":"Personalised ads and content display, ad and content measurement, and audience insights","description":"Ads and content can be personalised based on a profile. Ad and content performance can be measured. Insights about the audiences who saw the ads and content can be derived. Data can be used to build or improve user experience, systems, and software."},"25":{"id":25,"purposes":[2,3,4,5,6,7,8],"specialFeatures":[],"name":"Personalised ads and content, ad and content measurement","description":"Ads and content can be personalised based on a profile. More data can be added to better personalise ads and content. Ad and content performance can be measured."},"26":{"id":26,"purposes":[2,3,4,5,6,7,8,9],"specialFeatures":[],"name":"Personalised ads and content, ad and content measurement, and audience insights","description":"Ads and content can be personalised based on a profile. More data can be added to better personalise ads and content. Ad and content performance can be measured. Insights about the audiences who saw the ads and content can be derived."},"27":{"id":27,"purposes":[3,5],"specialFeatures":[],"name":"Personalised ads, and content profile","description":"More data can be added to personalise ads and content."},"28":{"id":28,"purposes":[2,4,6],"specialFeatures":[],"name":"Personalised ads and content display","description":"Ads and content can be personalised based on a profile."},"29":{"id":29,"purposes":[2,7,8,9],"specialFeatures":[],"name":"Basic ads, ad and content measurement, and audience insights","description":"Basic ads can be served. Ad and content performance can be measured. Insights about the audiences who saw the ads and content can be derived."},"30":{"id":30,"purposes":[2,4,5,6,7,8,9],"specialFeatures":[],"name":"Personalised ads display, personalised content, ad and content measurement, and audience insights","description":"Ads and content can be personalised based on a profile. More data can be added to better personalise content. Ad and content performance can be measured. Insights about the audiences who saw the ads and content can be derived."},"31":{"id":31,"purposes":[2,4,5,6,7,8,9,10],"specialFeatures":[],"name":"Personalised ads display, personalised content, ad and content measurement, audience insights, and product development","description":"Ads and content can be personalised based on a profile. More data can be added to better personalise content. Ad and content performance can be measured. Insights about the audiences who saw the ads and content can be derived. Data can be used to build or improve user experience, systems, and software."},"32":{"id":32,"purposes":[2,5,6,7,8,9],"specialFeatures":[],"name":"Basic ads, personalised content, ad and content measurement, and audience insights","description":"Basic ads can be served. Content can be personalised based on a profile. More data can be added to better personalise content. Ad and content performance can be measured. Insights about the audiences who saw the ads and content can be derived."},"33":{"id":33,"purposes":[2,5,6,7,8,9,10],"specialFeatures":[],"name":"Basic ads, personalised content, ad and content measurement, audience insights, and product development","description":"Basic ads can be served. Content can be personalised based on a profile. More data can be added to better personalise content. Ad and content performance can be measured. Insights about the audiences who saw the ads and content can be derived. Data can be used to build or improve user experience, systems, and software."},"34":{"id":34,"purposes":[2,5,6,8,9],"specialFeatures":[],"name":"Basic ads, personalised content, content measurement, and audience insights","description":"Basic ads can be served. Content can be personalised based on a profile. More data can be added to better personalise content. Ad and content performance can be measured. Insights about the audiences who saw the ads and content can be derived."},"35":{"id":35,"purposes":[2,5,6,8,9,10],"specialFeatures":[],"name":"Basic ads, personalised content, content measurement, audience insights, and product development","description":"Basic ads can be served. Content can be personalised based on a profile. More data can be added to better personalise content. Content performance can be measured. Insights about the audiences who saw the ads and content can be derived. Data can be used to build or improve user experience, systems, and software."},"36":{"id":36,"purposes":[2,5,6,7],"specialFeatures":[],"name":"Basic ads, personalised content, and ad measurement","description":"Basic ads can be served. Content can be personalised based on a profile. More data can be added to better personalise content. Ad performance can be measured."},"37":{"id":37,"purposes":[2,5,6,7,10],"specialFeatures":[],"name":"Basic ads, personalised content, ad measurement, and product development","description":"Basic ads can be served. Content can be personalised based on a profile. More data can be added to better personalise content. Ad performance can be measured. Data can be used to build or improve user experience, systems, and software."},"38":{"id":38,"purposes":[2,3,4,7,10],"specialFeatures":[],"name":"Personalised ads, ad measurement, and product development","description":"Ads can be personalised based on a profile. More data can be added to better personalise ads. Ad performance can be measured. Data can be used to build or improve user experience, systems, and software."},"39":{"id":39,"purposes":[2,3,4,7,9,10],"specialFeatures":[],"name":"Personalised ads, ad measurement, audience insights and product development","description":"Ads can be personalised based on a profile. More data can be added to better personalise ads. Ad performance can be measured. Insights about the audiences who saw the ads and content can be derived. Data can be used to build or improve user experience, systems and software."},"40":{"id":40,"purposes":[2,3,4,7,8,9,10],"specialFeatures":[],"name":"Personalised ads, ad and content measurement, audience insights and product development","description":"Ads can be personalised based on a profile. More data can be added to better personalise ads. Ad and content performance can be measured. Insights about audiences who saw the ads and content can be derived. Data can be used to build or improve user experience, systems and software."},"41":{"id":41,"purposes":[2,3,4,6,7,8,9,10],"specialFeatures":[],"name":"Personalised ads, personalised content display, ad and content measurement, audience insights and product development","description":"Ads and content can be personalised based on a profile. More data can be added to better personalise ads. Ad and content performance can be measured. Insights about audiences who saw the ads and content can be derived. Data can be used to build or improve user experience, systems and software."},"42":{"id":42,"purposes":[2,3,4,5,6,7,8,9,10],"specialFeatures":[],"name":"Personalised ads and content, ad and content measurement, audience insights and product development","description":"Ads and content can be personalised based on a profile. More data can be added to better personalise ads and content. Ad and content performance can be measured. Insights about audiences who saw the ads and content can be derived. Data can be used to build or improve user experience, systems and software."}},"vendors":{"8":{"id":8,"name":"Emerse Sverige AB","purposes":[1,3,4],"legIntPurposes":[2,7,8,9],"flexiblePurposes":[2,9],"specialPurposes":[1,2],"features":[1,2],"specialFeatures":[],"policyUrl":"https://www.emerse.com/privacy-policy/"},"9":{"id":9,"name":"AdMaxim Inc.","purposes":[1,2,3,4,5,6,7,8,9,10],"legIntPurposes":[],"flexiblePurposes":[],"specialPurposes":[],"features":[3],"specialFeatures":[1],"policyUrl":"http://www.admaxim.com/admaxim-privacy-policy/","deletedDate":"2020-06-17T00:00:00Z"},"12":{"id":12,"name":"BeeswaxIO Corporation","purposes":[1,2,3,4,7],"legIntPurposes":[],"flexiblePurposes":[],"specialPurposes":[1,2],"features":[1,3],"specialFeatures":[1],"policyUrl":"https://www.beeswax.com/privacy/"},"28":{"id":28,"name":"TripleLift, Inc.","purposes":[1],"legIntPurposes":[2,7,9,10],"flexiblePurposes":[2,7,9,10],"specialPurposes":[1,2],"features":[],"specialFeatures":[1],"policyUrl":"https://triplelift.com/privacy/","overflow":{"httpGetLimit":32}},"25":{"id":25,"name":"Verizon Media EMEA Limited","purposes":[1,3,4,5,6],"legIntPurposes":[2,7,8,9,10],"flexiblePurposes":[2,7,8,9,10],"specialPurposes":[1,2],"features":[1,2,3],"specialFeatures":[1],"policyUrl":"https://www.verizonmedia.com/policies/ie/en/verizonmedia/privacy/index.html"},"26":{"id":26,"name":"Venatus Media Limited","purposes":[1,2,3,4,7,8,9,10],"legIntPurposes":[],"flexiblePurposes":[],"specialPurposes":[],"features":[3],"specialFeatures":[],"policyUrl":"https://www.venatusmedia.com/privacy/"},"1":{"id":1,"name":"Exponential Interactive, Inc d/b/a VDX.tv","purposes":[1,2,3,4,7,8,9,10],"legIntPurposes":[],"flexiblePurposes":[2,3,4,7,8,9,10],"specialPurposes":[1,2],"features":[1,3],"specialFeatures":[],"policyUrl":"https://vdx.tv/privacy/"},"6":{"id":6,"name":"AdSpirit GmbH","purposes":[1,2,3,4,7,9,10],"legIntPurposes":[],"flexiblePurposes":[2,3,4,7,9],"specialPurposes":[1,2],"features":[3],"specialFeatures":[],"policyUrl":"http://www.adspirit.de/privacy","overflow":{"httpGetLimit":32}},"30":{"id":30,"name":"BidTheatre AB","purposes":[1,3,4],"legIntPurposes":[2],"flexiblePurposes":[2],"specialPurposes":[1,2],"features":[2],"specialFeatures":[],"policyUrl":"https://www.bidtheatre.com/privacy-policy"},"24":{"id":24,"name":"Epsilon","purposes":[1,2,3,4,5,6,7,9,10],"legIntPurposes":[],"flexiblePurposes":[],"specialPurposes":[1,2],"features":[1,2,3],"specialFeatures":[],"policyUrl":"https://www.conversantmedia.eu/legal/privacy-policy"},"39":{"id":39,"name":"ADITION technologies AG","purposes":[1,2,3,4,7,9,10],"legIntPurposes":[],"flexiblePurposes":[2,3,4,7,9,10],"specialPurposes":[1,2],"features":[1,2,3],"specialFeatures":[1],"policyUrl":"https://www.adition.com/datenschutz"},"11":{"id":11,"name":"Quantcast International Limited","purposes":[1,3,4],"legIntPurposes":[2,7,8,9,10],"flexiblePurposes":[2,3,4,7,8,9,10],"specialPurposes":[1,2],"features":[1,3],"specialFeatures":[],"policyUrl":"https://www.quantcast.com/privacy/"},"15":{"id":15,"name":"Adikteev","purposes":[1,3,4,5,6,8,9,10],"legIntPurposes":[2,7],"flexiblePurposes":[],"specialPurposes":[1,2],"features":[2],"specialFeatures":[],"policyUrl":"https://www.adikteev.com/privacy-policy-eng/"},"4":{"id":4,"name":"Roq.ad Inc.","purposes":[1,2,3,4,7,10],"legIntPurposes":[],"flexiblePurposes":[],"specialPurposes":[],"features":[2,3],"specialFeatures":[1],"policyUrl":"https://www.roq.ad/privacy-policy"},"7":{"id":7,"name":"Vibrant Media Limited","purposes":[1,3,4,5,6,7,8],"legIntPurposes":[],"flexiblePurposes":[],"specialPurposes":[],"features":[3],"specialFeatures":[1],"policyUrl":"https://www.vibrantmedia.com/en/privacy-policy/"},"2":{"id":2,"name":"Captify Technologies Limited","purposes":[1,2,3,4],"legIntPurposes":[7,9,10],"flexiblePurposes":[2],"specialPurposes":[],"features":[2],"specialFeatures":[],"policyUrl":"http://www.captify.co.uk/privacy-policy/"},"37":{"id":37,"name":"NEURAL.ONE","purposes":[1,2,3,4,5,7,9],"legIntPurposes":[],"flexiblePurposes":[],"specialPurposes":[1,2],"features":[1,2,3],"specialFeatures":[],"policyUrl":"https://web.neural.one/privacy-policy/"},"13":{"id":13,"name":"Sovrn Holdings Inc","purposes":[1,2,3,5,7,8,9,10],"legIntPurposes":[],"flexiblePurposes":[],"specialPurposes":[1,2],"features":[1,2,3],"specialFeatures":[],"policyUrl":"https://www.sovrn.com/sovrn-privacy/"},"34":{"id":34,"name":"NEORY GmbH","purposes":[1,3,4,5,6,9],"legIntPurposes":[2,7,8],"flexiblePurposes":[2,3,4,5,6,7,8,9],"specialPurposes":[1,2],"features":[3],"specialFeatures":[],"policyUrl":"https://www.neory.com/privacy.html","overflow":{"httpGetLimit":128}},"32":{"id":32,"name":"Xandr, Inc.","purposes":[1,3,4],"legIntPurposes":[2,7,10],"flexiblePurposes":[2,7,10],"specialPurposes":[1,2],"features":[2],"specialFeatures":[1],"policyUrl":"https://www.xandr.com/privacy/platform-privacy-policy/"},"10":{"id":10,"name":"Index Exchange, Inc. ","purposes":[1,2,7],"legIntPurposes":[],"flexiblePurposes":[2,7],"specialPurposes":[1,2],"features":[3],"specialFeatures":[1],"policyUrl":"https://www.indexexchange.com/privacy"},"57":{"id":57,"name":"ADARA MEDIA UNLIMITED","purposes":[1,2,3,4],"legIntPurposes":[7,9,10],"flexiblePurposes":[],"specialPurposes":[1,2],"features":[1,2,3],"specialFeatures":[],"policyUrl":"https://adara.com/privacy-promise/"},"63":{"id":63,"name":"Avocet Systems Limited","purposes":[1,2,3,4,5,6],"legIntPurposes":[7,8,10],"flexiblePurposes":[],"specialPurposes":[1,2],"features":[1,2,3],"specialFeatures":[1],"policyUrl":"https://avocet.io/privacy-portal"},"51":{"id":51,"name":"xAd, Inc. dba GroundTruth","purposes":[1,2,3,4,7,9,10],"legIntPurposes":[],"flexiblePurposes":[],"specialPurposes":[1,2],"features":[1,2,3],"specialFeatures":[1],"policyUrl":"https://www.groundtruth.com/privacy-policy/"},"49":{"id":49,"name":"TRADELAB","purposes":[1,2,3,4,5,6],"legIntPurposes":[7,8,9,10],"flexiblePurposes":[7,8,9,10],"specialPurposes":[],"features":[1,2],"specialFeatures":[1],"policyUrl":"https://tradelab.com/en/privacy/","overflow":{"httpGetLimit":32}},"45":{"id":45,"name":"Smart Adserver","purposes":[1,2,4,7],"legIntPurposes":[],"flexiblePurposes":[2,7],"specialPurposes":[1,2],"features":[3],"specialFeatures":[1],"policyUrl":"https://smartadserver.com/end-user-privacy-policy/"},"52":{"id":52,"name":"The Rubicon Project, Inc. ","purposes":[1],"legIntPurposes":[2,7,10],"flexiblePurposes":[2,7,10],"specialPurposes":[1,2],"features":[],"specialFeatures":[1],"policyUrl":"http://www.rubiconproject.com/rubicon-project-yield-optimization-privacy-policy/","overflow":{"httpGetLimit":128}},"71":{"id":71,"name":"Roku Advertising Services","purposes":[1,2,3,4,7,9,10],"legIntPurposes":[],"flexiblePurposes":[2,3,4,7,9,10],"specialPurposes":[1,2],"features":[1,2,3],"specialFeatures":[1],"policyUrl":"https://docs.roku.com/published/userprivacypolicy/en/us"},"79":{"id":79,"name":"MediaMath, Inc.","purposes":[1,3,4],"legIntPurposes":[2,7,10],"flexiblePurposes":[2,3,4,7,10],"specialPurposes":[1,2],"features":[1,2,3],"specialFeatures":[1],"policyUrl":"http://www.mediamath.com/privacy-policy/"},"91":{"id":91,"name":"Criteo SA","purposes":[1,2,3,4,7],"legIntPurposes":[],"flexiblePurposes":[2,3,4,7],"specialPurposes":[],"features":[1,2,3],"specialFeatures":[],"policyUrl":"https://www.criteo.com/privacy/"},"85":{"id":85,"name":"Crimtan Holdings Limited","purposes":[1,3,4],"legIntPurposes":[2,7,8,9,10],"flexiblePurposes":[2,7,8,9,10],"specialPurposes":[1,2],"features":[1,3],"specialFeatures":[1],"policyUrl":"https://crimtan.com/privacy/"},"16":{"id":16,"name":"RTB House S.A.","purposes":[1,2,3,4,7,10],"legIntPurposes":[],"flexiblePurposes":[],"specialPurposes":[1],"features":[],"specialFeatures":[],"policyUrl":"https://www.rtbhouse.com/privacy-center/services-privacy-policy/"},"86":{"id":86,"name":"Scene Stealer Limited","purposes":[1],"legIntPurposes":[2,3,4,7,10],"flexiblePurposes":[2,3,4,7],"specialPurposes":[1,2],"features":[],"specialFeatures":[],"policyUrl":"http://scenestealer.tv/privacy-policy/"},"94":{"id":94,"name":"Blis Media Limited","purposes":[1,2,3,4,5,6,7,8,9,10],"legIntPurposes":[],"flexiblePurposes":[],"specialPurposes":[],"features":[1,2,3],"specialFeatures":[1],"policyUrl":"http://www.blis.com/privacy/"},"73":{"id":73,"name":"Simplifi Holdings Inc.","purposes":[1,2,3,4,7,10],"legIntPurposes":[],"flexiblePurposes":[2,3,4],"specialPurposes":[],"features":[2],"specialFeatures":[1],"policyUrl":"https://simpli.fi/site-privacy-policy/"},"33":{"id":33,"name":"ShareThis, Inc","purposes":[1,3,5,6],"legIntPurposes":[9,10],"flexiblePurposes":[],"specialPurposes":[1,2],"features":[1,2,3],"specialFeatures":[],"policyUrl":"https://sharethis.com/privacy/"},"20":{"id":20,"name":"N Technologies Inc.","purposes":[1,3,4],"legIntPurposes":[2,5,6,7,8,9,10],"flexiblePurposes":[2,3,4,5,6,7,8,9,10],"specialPurposes":[1,2],"features":[2],"specialFeatures":[1],"policyUrl":"https://n.rich/privacy-notice"},"53":{"id":53,"name":"Sirdata","purposes":[1,2,3,4,5,6,7,9,10],"legIntPurposes":[],"flexiblePurposes":[],"specialPurposes":[],"features":[1,2,3],"specialFeatures":[],"policyUrl":"https://www.sirdata.com/privacy/"},"69":{"id":69,"name":"OpenX","purposes":[1],"legIntPurposes":[],"flexiblePurposes":[],"specialPurposes":[],"features":[],"specialFeatures":[],"policyUrl":"https://www.openx.com/legal/privacy-policy/"},"98":{"id":98,"name":"GroupM UK Limited","purposes":[1,2,3,4,5,6],"legIntPurposes":[7,8,9,10],"flexiblePurposes":[2,3,4,5,6,7,8,9,10],"specialPurposes":[1,2],"features":[1,2],"specialFeatures":[],"policyUrl":"https://www.groupm.com/privacy-notice"},"62":{"id":62,"name":"Justpremium BV","purposes":[1,4,5,10],"legIntPurposes":[2,7],"flexiblePurposes":[2,4,7,10],"specialPurposes":[1,2],"features":[],"specialFeatures":[],"policyUrl":"http://justpremium.com/privacy-policy/"},"36":{"id":36,"name":"RhythmOne DBA Unruly Group Ltd","purposes":[1,2,3,4,7,8,9,10],"legIntPurposes":[],"flexiblePurposes":[],"specialPurposes":[1,2],"features":[1,2,3],"specialFeatures":[1],"policyUrl":"https://www.rhythmone.com/privacy-policy"},"80":{"id":80,"name":"Sharethrough, Inc","purposes":[1,2,4,7,9,10],"legIntPurposes":[],"flexiblePurposes":[2,4,7,9,10],"specialPurposes":[],"features":[],"specialFeatures":[],"policyUrl":"https://platform-cdn.sharethrough.com/privacy-policy"},"23":{"id":23,"name":"Amobee, Inc. ","purposes":[1,2,3,4],"legIntPurposes":[7,9,10],"flexiblePurposes":[2,3,4,7,9,10],"specialPurposes":[],"features":[1,2,3],"specialFeatures":[],"policyUrl":"https://www.amobee.com/trust/privacy-guidelines"},"67":{"id":67,"name":"LifeStreet Corporation","purposes":[1,3,4],"legIntPurposes":[2,5,6,7,8,10],"flexiblePurposes":[2,5,6,7,8,10],"specialPurposes":[1,2],"features":[3],"specialFeatures":[1],"policyUrl":"https://lifestreet.com/privacy/"},"68":{"id":68,"name":"Sizmek by Amazon","purposes":[1,3,4],"legIntPurposes":[2,7,9,10],"flexiblePurposes":[2,3,4,7,9,10],"specialPurposes":[1,2],"features":[1,2],"specialFeatures":[],"policyUrl":"https://www.sizmek.com/privacy-policy/"},"61":{"id":61,"name":"GumGum, Inc.","purposes":[1,2,3,4,7],"legIntPurposes":[],"flexiblePurposes":[],"specialPurposes":[1,2],"features":[],"specialFeatures":[],"policyUrl":"https://gumgum.com/privacy-policy"},"40":{"id":40,"name":"Active Agent (ADITION technologies AG)","purposes":[1,2,3,4,7,9,10],"legIntPurposes":[],"flexiblePurposes":[2,3,4,7,9,10],"specialPurposes":[1,2],"features":[1,2,3],"specialFeatures":[1],"policyUrl":"http://www.active-agent.com/de/unternehmen/datenschutzerklaerung/"},"76":{"id":76,"name":"PubMatic, Inc.","purposes":[1,3,4],"legIntPurposes":[2,5,6,7,8,9,10],"flexiblePurposes":[2,3,4,5,6,7,8,9,10],"specialPurposes":[],"features":[1,2,3],"specialFeatures":[1],"policyUrl":"https://pubmatic.com/privacy-policy/"},"89":{"id":89,"name":"Tapad, Inc.","purposes":[1],"legIntPurposes":[10],"flexiblePurposes":[],"specialPurposes":[],"features":[2],"specialFeatures":[],"policyUrl":"https://www.tapad.com/eu-privacy-policy"},"66":{"id":66,"name":"adsquare GmbH","purposes":[1,2,3,4,5,6,7,8,9,10],"legIntPurposes":[],"flexiblePurposes":[2,3,4,5,6,7,8,9,10],"specialPurposes":[],"features":[1,2,3],"specialFeatures":[1],"policyUrl":"https://www.adsquare.com/privacy"},"41":{"id":41,"name":"Adverline","purposes":[1,2,3,4,5,6,7,10],"legIntPurposes":[],"flexiblePurposes":[],"specialPurposes":[1,2],"features":[],"specialFeatures":[],"policyUrl":"https://www.adverline.com/privacy/","overflow":{"httpGetLimit":128}},"82":{"id":82,"name":"Smaato, Inc.","purposes":[1,2,3,4,7,9],"legIntPurposes":[10],"flexiblePurposes":[2,7,9,10],"specialPurposes":[1,2],"features":[1,3],"specialFeatures":[1],"policyUrl":"https://www.smaato.com/privacy/"},"60":{"id":60,"name":"Rakuten Marketing LLC","purposes":[1,3,4],"legIntPurposes":[2,7,9,10],"flexiblePurposes":[2,3,4,7,9,10],"specialPurposes":[1,2],"features":[1,2,3],"specialFeatures":[],"policyUrl":"https://rakutenadvertising.com/legal-notices/services-privacy-policy/"},"70":{"id":70,"name":"Yieldlab AG","purposes":[1,2,3,4,7,10],"legIntPurposes":[],"flexiblePurposes":[2,3,4,7,10],"specialPurposes":[1,2],"features":[1,2,3],"specialFeatures":[1],"policyUrl":"http://www.yieldlab.de/meta-navigation/datenschutz/","overflow":{"httpGetLimit":128}},"50":{"id":50,"name":"Adform","purposes":[1,2,3,4,7,10],"legIntPurposes":[],"flexiblePurposes":[2,7,10],"specialPurposes":[1,2],"features":[1,2],"specialFeatures":[],"policyUrl":"https://site.adform.com/privacy-center/platform-privacy/product-and-services-privacy-policy/","overflow":{"httpGetLimit":32}},"100":{"id":100,"name":"Fifty Technology Limited","purposes":[1,2,3,4],"legIntPurposes":[7,9,10],"flexiblePurposes":[],"specialPurposes":[1,2],"features":[2,3],"specialFeatures":[],"policyUrl":"https://fifty.io/privacy-policy.php"},"21":{"id":21,"name":"The Trade Desk","purposes":[1,3,4],"legIntPurposes":[2,7,10],"flexiblePurposes":[2,7,10],"specialPurposes":[1,2],"features":[1,2],"specialFeatures":[1],"policyUrl":"https://www.thetradedesk.com/general/privacy-policy"},"110":{"id":110,"name":"Dynata LLC","purposes":[1,7,9],"legIntPurposes":[],"flexiblePurposes":[],"specialPurposes":[],"features":[1,2],"specialFeatures":[],"policyUrl":"https://www.opinionoutpost.co.uk/en-gb/policies/privacy"},"42":{"id":42,"name":"Taboola Europe Limited","purposes":[1],"legIntPurposes":[2,3,4,5,6,7,8,10],"flexiblePurposes":[2,3,4,5,6,7,8,10],"specialPurposes":[1,2],"features":[1,2,3],"specialFeatures":[],"policyUrl":"https://www.taboola.com/privacy-policy"},"77":{"id":77,"name":"comScore, Inc.","purposes":[1,7,8,9,10],"legIntPurposes":[],"flexiblePurposes":[7,8,9,10],"specialPurposes":[1],"features":[1,2],"specialFeatures":[],"policyUrl":"https://www.scorecardresearch.com/privacy.aspx?newlanguage=1"},"109":{"id":109,"name":"LoopMe Limited","purposes":[1,2,3,4,5,6,7,8],"legIntPurposes":[9,10],"flexiblePurposes":[9],"specialPurposes":[1,2],"features":[1,2],"specialFeatures":[1],"policyUrl":"https://loopme.com/privacy-policy/"},"120":{"id":120,"name":"Eyeota Pte Ltd","purposes":[1,3,5,9,10],"legIntPurposes":[],"flexiblePurposes":[3,5,9,10],"specialPurposes":[1],"features":[1,2,3],"specialFeatures":[],"policyUrl":"https://www.eyeota.com/privacy-center"},"93":{"id":93,"name":"Adloox SA","purposes":[],"legIntPurposes":[7],"flexiblePurposes":[],"specialPurposes":[1],"features":[],"specialFeatures":[],"policyUrl":"http://adloox.com/disclaimer","overflow":{"httpGetLimit":128}},"132":{"id":132,"name":"Teads ","purposes":[1,3,4],"legIntPurposes":[2,7,9,10],"flexiblePurposes":[2,7,9,10],"specialPurposes":[1,2],"features":[3],"specialFeatures":[],"policyUrl":"https://www.teads.com/privacy-policy/"},"22":{"id":22,"name":"admetrics GmbH","purposes":[2,7,8,9],"legIntPurposes":[],"flexiblePurposes":[],"specialPurposes":[],"features":[],"specialFeatures":[],"policyUrl":"https://admetrics.io/en/privacy_policy/"},"102":{"id":102,"name":"Telaria SAS","purposes":[1,2,3,4,5,6],"legIntPurposes":[7,8,9,10],"flexiblePurposes":[5,6,7,8,9,10],"specialPurposes":[1,2],"features":[1,2,3],"specialFeatures":[1,2],"policyUrl":"https://telaria.com/privacy-policy/"},"108":{"id":108,"name":"Rich Audience Technologies SL","purposes":[1,2,3,4,7,9,10],"legIntPurposes":[],"flexiblePurposes":[],"specialPurposes":[1,2],"features":[],"specialFeatures":[1],"policyUrl":"https://richaudience.com/privacy/"},"18":{"id":18,"name":"Widespace AB","purposes":[1,2,3,4,7],"legIntPurposes":[],"flexiblePurposes":[2,3,4,7],"specialPurposes":[],"features":[],"specialFeatures":[],"policyUrl":"https://www.widespace.com/legal/privacy-policy-notice/"},"122":{"id":122,"name":"Avid Media Ltd","purposes":[1,3,4,5,10],"legIntPurposes":[2,7,8],"flexiblePurposes":[2,7,8],"specialPurposes":[1,2],"features":[],"specialFeatures":[],"policyUrl":"https://www.avidglobalmedia.eu/privacy-policy.html"},"97":{"id":97,"name":"LiveRamp, Inc.","purposes":[1,2,3,4,5,6,7,8,9,10],"legIntPurposes":[],"flexiblePurposes":[],"specialPurposes":[1,2],"features":[1,2,3],"specialFeatures":[],"policyUrl":"https://www.liveramp.com/service-privacy-policy/"},"138":{"id":138,"name":"ConnectAd Realtime GmbH","purposes":[1,3,4,5],"legIntPurposes":[2,7],"flexiblePurposes":[],"specialPurposes":[1,2],"features":[3],"specialFeatures":[],"policyUrl":"http://connectadrealtime.com/privacy/"},"72":{"id":72,"name":"Nano Interactive GmbH","purposes":[1,2,3,4,7,9,10],"legIntPurposes":[],"flexiblePurposes":[],"specialPurposes":[1,2],"features":[],"specialFeatures":[],"policyUrl":"http://www.nanointeractive.com/privacy"},"127":{"id":127,"name":"PIXIMEDIA SAS","purposes":[1,3,4,5,6,9,10],"legIntPurposes":[2,7,8],"flexiblePurposes":[],"specialPurposes":[1,2],"features":[3],"specialFeatures":[1],"policyUrl":"https://piximedia.com/privacy/","overflow":{"httpGetLimit":128}},"136":{"id":136,"name":"Str\u00f6er SSP GmbH (SSP)","purposes":[1],"legIntPurposes":[2,7,9,10],"flexiblePurposes":[2,7,9,10],"specialPurposes":[1,2],"features":[],"specialFeatures":[],"policyUrl":"https://www.stroeer.de/fileadmin/de/Konvergenz_und_Konzepte/Daten_und_Technologien/Stroeer_SSP/Downloads/Datenschutz_Stroeer_SSP.pdf"},"111":{"id":111,"name":"Showheroes SE","purposes":[1,3,4,9,10],"legIntPurposes":[2,7,8],"flexiblePurposes":[2,3,4,7,8,9,10],"specialPurposes":[1,2],"features":[1],"specialFeatures":[],"policyUrl":"https://showheroes.com/privacy/"},"124":{"id":124,"name":"Teemo SA","purposes":[1,2,3,4,7],"legIntPurposes":[],"flexiblePurposes":[],"specialPurposes":[1,2],"features":[1],"specialFeatures":[1],"policyUrl":"https://teemo.co/fr/confidentialite/"},"154":{"id":154,"name":"YOC AG","purposes":[1,3,4,10],"legIntPurposes":[2,7],"flexiblePurposes":[2,7],"specialPurposes":[1,2],"features":[3],"specialFeatures":[1],"policyUrl":"https://yoc.com/privacy/"},"101":{"id":101,"name":"MiQ","purposes":[1,2,3,4,7,9,10],"legIntPurposes":[],"flexiblePurposes":[],"specialPurposes":[1,2],"features":[1,2,3],"specialFeatures":[1],"policyUrl":"http://wearemiq.com/privacy-policy/"},"149":{"id":149,"name":"ADman Interactive SLU","purposes":[1,2,3,4,5,6,7,8,9,10],"legIntPurposes":[],"flexiblePurposes":[2],"specialPurposes":[],"features":[2,3],"specialFeatures":[],"policyUrl":"https://admanmedia.com/politica.html?setLng=es"},"153":{"id":153,"name":"MADVERTISE MEDIA","purposes":[1,2,3,4,5,6,7,9,10],"legIntPurposes":[],"flexiblePurposes":[5,6,10],"specialPurposes":[2],"features":[],"specialFeatures":[1,2],"policyUrl":"https://madvertise.com/en/gdpr/","overflow":{"httpGetLimit":128}},"157":{"id":157,"name":"Seedtag Advertising S.L","purposes":[1,2,3,4,7,10],"legIntPurposes":[],"flexiblePurposes":[],"specialPurposes":[1,2],"features":[],"specialFeatures":[],"policyUrl":"https://www.seedtag.com/en/privacy-policy/"},"145":{"id":145,"name":"Snapsort Inc., operating as Sortable","purposes":[1],"legIntPurposes":[2,7,8,9,10],"flexiblePurposes":[],"specialPurposes":[1,2],"features":[3],"specialFeatures":[],"policyUrl":"https://help.sortable.com/help/privacy-policy"},"131":{"id":131,"name":"ID5 Technology SAS","purposes":[1],"legIntPurposes":[],"flexiblePurposes":[],"specialPurposes":[],"features":[3],"specialFeatures":[],"policyUrl":"https://www.id5.io/privacy"},"158":{"id":158,"name":"Reveal Mobile, Inc","purposes":[1,2,3,4,5,6,7,8,9,10],"legIntPurposes":[],"flexiblePurposes":[],"specialPurposes":[],"features":[],"specialFeatures":[1],"policyUrl":"https://revealmobile.com/privacy"},"147":{"id":147,"name":"Adacado Technologies Inc. (DBA Adacado)","purposes":[1,2,3,4,5,6,7,8,9,10],"legIntPurposes":[],"flexiblePurposes":[7,8,9,10],"specialPurposes":[1,2],"features":[3],"specialFeatures":[1],"policyUrl":"https://www.adacado.com/privacy-policy-april-25-2018/"},"130":{"id":130,"name":"NextRoll, Inc.","purposes":[1,2,3,4,5,6,7,9,10],"legIntPurposes":[],"flexiblePurposes":[],"specialPurposes":[1,2],"features":[1,2],"specialFeatures":[],"policyUrl":"https://www.nextroll.com/privacy"},"129":{"id":129,"name":"IPONWEB GmbH","purposes":[1,2,3,4,5,6,7,8,9,10],"legIntPurposes":[],"flexiblePurposes":[],"specialPurposes":[],"features":[1,2,3],"specialFeatures":[1],"policyUrl":"https://www.iponweb.com/privacy-policy/"},"128":{"id":128,"name":"BIDSWITCH GmbH","purposes":[1,2,3,4,5,6,7,8,9,10],"legIntPurposes":[],"flexiblePurposes":[],"specialPurposes":[],"features":[1,3],"specialFeatures":[1],"policyUrl":"http://www.bidswitch.com/privacy-policy/"},"168":{"id":168,"name":"EASYmedia GmbH","purposes":[1,2,3,4,5,6,7,8,9,10],"legIntPurposes":[],"flexiblePurposes":[],"specialPurposes":[],"features":[1,2,3],"specialFeatures":[1],"policyUrl":"https://login.rtbmarket.com/gdpr"},"164":{"id":164,"name":"Outbrain UK Ltd","purposes":[1],"legIntPurposes":[3,4,5,6,7,8,9,10],"flexiblePurposes":[3,4,5,6,7,8,9,10],"specialPurposes":[1,2],"features":[1,3],"specialFeatures":[],"policyUrl":"https://www.outbrain.com/legal/privacy#privacy-policy"},"144":{"id":144,"name":"district m inc.","purposes":[1,2,4,7,10],"legIntPurposes":[],"flexiblePurposes":[],"specialPurposes":[2],"features":[3],"specialFeatures":[1],"policyUrl":"https://districtm.net/en/page/platforms-data-and-privacy-policy/","overflow":{"httpGetLimit":128}},"163":{"id":163,"name":"Bombora Inc.","purposes":[1,3,8],"legIntPurposes":[7,9,10],"flexiblePurposes":[7,9,10],"specialPurposes":[1],"features":[1,3],"specialFeatures":[],"policyUrl":"https://bombora.com/privacy"},"173":{"id":173,"name":"Yieldmo, Inc.","purposes":[1,2,3,4,5,6,7,8,9,10],"legIntPurposes":[],"flexiblePurposes":[2,3,4,5,6,7,8,9,10],"specialPurposes":[1,2],"features":[],"specialFeatures":[],"policyUrl":"https://www.yieldmo.com/privacy/"},"88":{"id":88,"name":"TreSensa, Inc.","purposes":[1,3,4],"legIntPurposes":[2,7,10],"flexiblePurposes":[2,3,4,7,10],"specialPurposes":[1,2],"features":[1,3],"specialFeatures":[],"policyUrl":"https://www.tresensa.com/eu-privacy"},"78":{"id":78,"name":"Flashtalking, Inc.","purposes":[1,2,3,4,7],"legIntPurposes":[],"flexiblePurposes":[],"specialPurposes":[],"features":[1,2,3],"specialFeatures":[1],"policyUrl":"http://www.flashtalking.com/privacypolicy/"},"59":{"id":59,"name":"Sift Media, Inc","purposes":[2],"legIntPurposes":[],"flexiblePurposes":[2],"specialPurposes":[],"features":[3],"specialFeatures":[1],"policyUrl":"https://www.sift.co/privacy"},"114":{"id":114,"name":"Sublime","purposes":[1,2,3,4,7,9,10],"legIntPurposes":[],"flexiblePurposes":[],"specialPurposes":[],"features":[],"specialFeatures":[],"policyUrl":"http://ayads.co/privacy.php"},"133":{"id":133,"name":"digitalAudience","purposes":[1,3,5,9],"legIntPurposes":[],"flexiblePurposes":[],"specialPurposes":[],"features":[1,2],"specialFeatures":[],"policyUrl":"https://digitalaudience.io/legal/privacy-cookies/"},"14":{"id":14,"name":"Adkernel LLC","purposes":[1,3,4],"legIntPurposes":[2,7,9],"flexiblePurposes":[3,4],"specialPurposes":[1,2],"features":[3],"specialFeatures":[1],"policyUrl":"http://adkernel.com/privacy-policy/","overflow":{"httpGetLimit":32}},"183":{"id":183,"name":"EMX Digital LLC","purposes":[1,3,4,5,6],"legIntPurposes":[2,7,8,9,10],"flexiblePurposes":[],"specialPurposes":[1,2],"features":[1,2,3],"specialFeatures":[1,2],"policyUrl":"https://emxdigital.com/privacy/"},"58":{"id":58,"name":"33Across","purposes":[1,2,4,7,10],"legIntPurposes":[],"flexiblePurposes":[],"specialPurposes":[1,2],"features":[2],"specialFeatures":[],"policyUrl":"http://www.33across.com/privacy-policy"},"140":{"id":140,"name":"Platform161","purposes":[1,2,3,4,7,10],"legIntPurposes":[],"flexiblePurposes":[],"specialPurposes":[1,2],"features":[2,3],"specialFeatures":[1],"policyUrl":"https://platform161.com/cookie-and-privacy-policy/"},"90":{"id":90,"name":"Teroa S.A.","purposes":[1,2,3,4,5,7,9,10],"legIntPurposes":[],"flexiblePurposes":[],"specialPurposes":[],"features":[],"specialFeatures":[],"policyUrl":"https://www.e-planning.net/en/privacy.html"},"141":{"id":141,"name":"1020, Inc. dba Placecast and Ericsson Emodo","purposes":[1,2,3,4,5,6,7,8,9,10],"legIntPurposes":[],"flexiblePurposes":[],"specialPurposes":[],"features":[],"specialFeatures":[],"policyUrl":"https://www.emodoinc.com/privacy-policy/"},"142":{"id":142,"name":"Media.net Advertising FZ-LLC","purposes":[1,3,4],"legIntPurposes":[2,5,6,7,8,9,10],"flexiblePurposes":[5,6,8],"specialPurposes":[1,2],"features":[3],"specialFeatures":[],"policyUrl":"https://www.media.net/en/privacy-policy"},"209":{"id":209,"name":"Delta Projects AB","purposes":[1,2,3,4],"legIntPurposes":[7,10],"flexiblePurposes":[2,7,10],"specialPurposes":[1,2],"features":[],"specialFeatures":[1],"policyUrl":"https://deltaprojects.com/data-collection-policy"},"195":{"id":195,"name":"advanced store GmbH","purposes":[1,3,4],"legIntPurposes":[2],"flexiblePurposes":[2],"specialPurposes":[1,2],"features":[],"specialFeatures":[],"policyUrl":"http://www.advanced-store.com/de/datenschutz/"},"190":{"id":190,"name":"video intelligence AG","purposes":[],"legIntPurposes":[2,7,8,9,10],"flexiblePurposes":[],"specialPurposes":[],"features":[],"specialFeatures":[],"policyUrl":"https://www.vi.ai/privacy-policy/"},"84":{"id":84,"name":"Semasio GmbH","purposes":[1,3,9,10],"legIntPurposes":[],"flexiblePurposes":[3,9,10],"specialPurposes":[],"features":[],"specialFeatures":[],"policyUrl":"http://www.semasio.com/privacy-policy/"},"65":{"id":65,"name":"Location Sciences AI Ltd","purposes":[1,7,8,9,10],"legIntPurposes":[],"flexiblePurposes":[7,8],"specialPurposes":[1],"features":[],"specialFeatures":[1],"policyUrl":"https://www.locationsciences.ai/privacy-policy/"},"210":{"id":210,"name":"Zemanta, Inc.","purposes":[1],"legIntPurposes":[3,7,9,10],"flexiblePurposes":[3,7,9,10],"specialPurposes":[1,2],"features":[1],"specialFeatures":[],"policyUrl":"http://www.zemanta.com/legal/privacy"},"200":{"id":200,"name":"Tapjoy, Inc.","purposes":[1],"legIntPurposes":[2,3,4,7],"flexiblePurposes":[2,3,4,7],"specialPurposes":[1,2],"features":[3],"specialFeatures":[],"policyUrl":"https://www.tapjoy.com/legal/#privacy-policy"},"217":{"id":217,"name":"2KDirect, Inc. (dba iPromote)","purposes":[1],"legIntPurposes":[2,3,4,7,9,10],"flexiblePurposes":[2,3,4,7,9,10],"specialPurposes":[1,2],"features":[],"specialFeatures":[],"policyUrl":"https://www.ipromote.com/privacy-policy/"},"194":{"id":194,"name":"Rezonence Limited","purposes":[1,3,4,9],"legIntPurposes":[2,7,8,10],"flexiblePurposes":[],"specialPurposes":[1,2],"features":[],"specialFeatures":[],"policyUrl":"https://rezonence.com/privacy-policy/"},"226":{"id":226,"name":"Publicis Media GmbH","purposes":[1,9],"legIntPurposes":[2,3,4,5,6,7,8,10],"flexiblePurposes":[2,3,4,5,6,7,8,10],"specialPurposes":[],"features":[1],"specialFeatures":[],"policyUrl":"https://www.publicismedia.de/datenschutz/"},"227":{"id":227,"name":"ORTEC B.V.","purposes":[1,2,3,4,5,6,7,9,10],"legIntPurposes":[],"flexiblePurposes":[2,3,4,5,6,7,9,10],"specialPurposes":[1,2],"features":[1,2,3],"specialFeatures":[1],"policyUrl":"https://www.ortecadscience.com/privacy-policy/"},"205":{"id":205,"name":"Adssets AB","purposes":[1,3,4,5,8,9],"legIntPurposes":[2,7],"flexiblePurposes":[],"specialPurposes":[2],"features":[],"specialFeatures":[],"policyUrl":"http://adssets.com/policy/"},"179":{"id":179,"name":"Collective Europe Ltd.","purposes":[1,2,3,4,9],"legIntPurposes":[7],"flexiblePurposes":[],"specialPurposes":[1,2],"features":[],"specialFeatures":[1],"policyUrl":"https://www.collectiveuk.com/privacy.html","overflow":{"httpGetLimit":128}},"31":{"id":31,"name":"Ogury Ltd.","purposes":[1,3,4,9],"legIntPurposes":[2,7,10],"flexiblePurposes":[],"specialPurposes":[1,2],"features":[2],"specialFeatures":[],"policyUrl":"https://www.ogury.com/privacy-policy/"},"92":{"id":92,"name":"1plusX AG","purposes":[1],"legIntPurposes":[2,3,4,5,6,7,8,9,10],"flexiblePurposes":[2,3,4,5,6,7,8,9,10],"specialPurposes":[],"features":[1,2,3],"specialFeatures":[],"policyUrl":"https://www.1plusx.com/privacy-policy/"},"155":{"id":155,"name":"AntVoice","purposes":[1,2,3,4,7],"legIntPurposes":[],"flexiblePurposes":[],"specialPurposes":[2],"features":[],"specialFeatures":[],"policyUrl":"https://www.antvoice.com/en/privacypolicy/"},"115":{"id":115,"name":"smartclip Europe GmbH","purposes":[1,3,4],"legIntPurposes":[2,7,10],"flexiblePurposes":[2,3,4,7,10],"specialPurposes":[1,2],"features":[2],"specialFeatures":[],"policyUrl":"https://privacy-portal.smartclip.net/","overflow":{"httpGetLimit":32}},"126":{"id":126,"name":"DoubleVerify Inc.\u200b","purposes":[2,7,10],"legIntPurposes":[],"flexiblePurposes":[],"specialPurposes":[1,2],"features":[],"specialFeatures":[],"policyUrl":"https://www.doubleverify.com/privacy/"},"193":{"id":193,"name":"Mediasmart Mobile S.L.","purposes":[1,2,3,4,7,9,10],"legIntPurposes":[],"flexiblePurposes":[],"specialPurposes":[],"features":[3],"specialFeatures":[1],"policyUrl":"http://mediasmart.io/privacy/"},"213":{"id":213,"name":"emetriq GmbH","purposes":[1,2,3,4,5,6,7,8,9,10],"legIntPurposes":[],"flexiblePurposes":[2,3,4,5,6,7,8,9,10],"specialPurposes":[2],"features":[1,2],"specialFeatures":[],"policyUrl":"https://www.emetriq.com/datenschutz/"},"244":{"id":244,"name":"Temelio","purposes":[1,2,3,4,5,6,7,8,9,10],"legIntPurposes":[],"flexiblePurposes":[],"specialPurposes":[],"features":[1,2,3],"specialFeatures":[],"policyUrl":"https://temelio.com/vie-privee"},"224":{"id":224,"name":"adrule mobile GmbH","purposes":[1,2,3,4,5,6,8],"legIntPurposes":[7],"flexiblePurposes":[2,3,4,5,6,7,8],"specialPurposes":[1,2],"features":[],"specialFeatures":[1],"policyUrl":"https://www.adrule.net/de/datenschutz/"},"174":{"id":174,"name":"A Million Ads Ltd","purposes":[2,3,4,7],"legIntPurposes":[],"flexiblePurposes":[],"specialPurposes":[2],"features":[],"specialFeatures":[1],"policyUrl":"https://www.amillionads.com/privacy-policy"},"192":{"id":192,"name":"remerge GmbH","purposes":[1,2,3,4,7],"legIntPurposes":[],"flexiblePurposes":[],"specialPurposes":[],"features":[],"specialFeatures":[],"policyUrl":"https://remerge.io/privacy-policy.html"},"256":{"id":256,"name":"Bounce Exchange, Inc","purposes":[1],"legIntPurposes":[7,10],"flexiblePurposes":[],"specialPurposes":[1,2],"features":[],"specialFeatures":[],"policyUrl":"https://www.bouncex.com/privacy/"},"234":{"id":234,"name":"ZBO Media","purposes":[1,3,4,9],"legIntPurposes":[2,7,10],"flexiblePurposes":[],"specialPurposes":[1,2],"features":[1],"specialFeatures":[],"policyUrl":"https://zbo.media/mentions-legales/politique-de-confidentialite-service-publicitaire/"},"246":{"id":246,"name":"Smartology Limited","purposes":[1,3,4,8],"legIntPurposes":[2,7],"flexiblePurposes":[2,7],"specialPurposes":[1,2],"features":[],"specialFeatures":[],"policyUrl":"https://www.smartology.net/privacy-policy/"},"241":{"id":241,"name":"OneTag Limited","purposes":[1,2,3,4,7,9,10],"legIntPurposes":[],"flexiblePurposes":[7],"specialPurposes":[1,2],"features":[1,2,3],"specialFeatures":[1],"policyUrl":"https://www.onetag.com/privacy/"},"254":{"id":254,"name":"LiquidM Technology GmbH","purposes":[1,2,3,4,7],"legIntPurposes":[],"flexiblePurposes":[],"specialPurposes":[1,2],"features":[3],"specialFeatures":[1],"policyUrl":"https://liquidm.com/privacy-policy/"},"215":{"id":215,"name":"ARMIS SAS","purposes":[1,2,7],"legIntPurposes":[10],"flexiblePurposes":[],"specialPurposes":[],"features":[],"specialFeatures":[],"policyUrl":"https://armis.tech/en/armis-personal-data-privacy-policy/"},"167":{"id":167,"name":"Audiens S.r.l.","purposes":[1,9],"legIntPurposes":[],"flexiblePurposes":[],"specialPurposes":[],"features":[1,2,3],"specialFeatures":[1,2],"policyUrl":"http://www.audiens.com/privacy"},"240":{"id":240,"name":"7Hops.com Inc. (ZergNet)","purposes":[1],"legIntPurposes":[5,6,8,10],"flexiblePurposes":[],"specialPurposes":[1,2],"features":[],"specialFeatures":[],"policyUrl":"https://zergnet.com/privacy"},"235":{"id":235,"name":"Bucksense Inc","purposes":[2,3,4,7,9],"legIntPurposes":[],"flexiblePurposes":[2,3,4,7,9],"specialPurposes":[],"features":[],"specialFeatures":[1],"policyUrl":"http://www.bucksense.com/platform-privacy-policy/"},"185":{"id":185,"name":"Bidtellect, Inc","purposes":[1,2,3,4,7,8],"legIntPurposes":[9,10],"flexiblePurposes":[],"specialPurposes":[1,2],"features":[1,2,3],"specialFeatures":[],"policyUrl":"https://www.bidtellect.com/privacy-policy/","overflow":{"httpGetLimit":128}},"211":{"id":211,"name":"AdTheorent, Inc","purposes":[1,2,3,4,5,6,7,8,9,10],"legIntPurposes":[],"flexiblePurposes":[],"specialPurposes":[],"features":[1,2,3],"specialFeatures":[1,2],"policyUrl":"http://adtheorent.com/privacy-policy"},"273":{"id":273,"name":"Bannerflow AB","purposes":[1,4],"legIntPurposes":[2,7],"flexiblePurposes":[],"specialPurposes":[1,2],"features":[],"specialFeatures":[],"policyUrl":"https://www.bannerflow.com/privacy "},"104":{"id":104,"name":"Sonobi, Inc","purposes":[1,2,3,4],"legIntPurposes":[7,8],"flexiblePurposes":[],"specialPurposes":[2],"features":[1],"specialFeatures":[],"policyUrl":"http://sonobi.com/privacy-policy/"},"162":{"id":162,"name":"Unruly Group Ltd","purposes":[1,2,3,4,7,9,10],"legIntPurposes":[],"flexiblePurposes":[],"specialPurposes":[1,2],"features":[1,2,3],"specialFeatures":[1],"policyUrl":"https://unruly.co/privacy/"},"249":{"id":249,"name":"Spolecznosci Sp. z o.o. Sp. k.","purposes":[1,2,3,4,5,7,8,9,10],"legIntPurposes":[],"flexiblePurposes":[2,3,4,5,7,8,9,10],"specialPurposes":[1,2],"features":[1,2,3],"specialFeatures":[],"policyUrl":"https://www.spolecznosci.pl/polityka-prywatnosci"},"160":{"id":160,"name":"Netsprint SA","purposes":[1,2,3,4,5,6,7,8,9,10],"legIntPurposes":[],"flexiblePurposes":[],"specialPurposes":[],"features":[1,2,3],"specialFeatures":[1,2],"policyUrl":"https://netsprint.eu/privacy.html","overflow":{"httpGetLimit":32}},"279":{"id":279,"name":"Mirando GmbH & Co KG","purposes":[1],"legIntPurposes":[2,7],"flexiblePurposes":[],"specialPurposes":[],"features":[],"specialFeatures":[],"policyUrl":"https://wwwmirando.de/datenschutz/"},"255":{"id":255,"name":"Onnetwork Sp. z o.o.","purposes":[1,5,6],"legIntPurposes":[2,7,8],"flexiblePurposes":[],"specialPurposes":[2],"features":[],"specialFeatures":[],"policyUrl":"https://www.onnetwork.tv/pp_services.php"},"203":{"id":203,"name":"Revcontent, LLC","purposes":[1],"legIntPurposes":[2,3,4,5,6,7,8,9,10],"flexiblePurposes":[2,3,4,5,6],"specialPurposes":[],"features":[],"specialFeatures":[],"policyUrl":"https://intercom.help/revcontent2/en/articles/2290675-revcontent-s-privacy-policy"},"274":{"id":274,"name":"Golden Bees","purposes":[1,2,3,4,6,7,9,10],"legIntPurposes":[],"flexiblePurposes":[],"specialPurposes":[],"features":[2],"specialFeatures":[],"policyUrl":"https://www.goldenbees.fr/en/privacy-charter/","overflow":{"httpGetLimit":128}},"280":{"id":280,"name":"Spot.IM LTD","purposes":[1],"legIntPurposes":[2,3,4,5,6,7,8,9,10],"flexiblePurposes":[2,3,4,5,6,7,8,9,10],"specialPurposes":[1,2],"features":[1,2,3],"specialFeatures":[1,2],"policyUrl":"https://www.spot.im/privacy/"},"239":{"id":239,"name":"Triton Digital Canada Inc.","purposes":[1,3,4,5,6],"legIntPurposes":[2,7,8,9,10],"flexiblePurposes":[2,7,8,9,10],"specialPurposes":[1,2],"features":[3],"specialFeatures":[1],"policyUrl":"https://www.tritondigital.com/privacy-policies"},"177":{"id":177,"name":"plista GmbH","purposes":[1],"legIntPurposes":[7,8,10],"flexiblePurposes":[7,8,10],"specialPurposes":[2],"features":[],"specialFeatures":[],"policyUrl":"https://www.plista.com/about/privacy/"},"150":{"id":150,"name":"Inskin Media LTD","purposes":[1,3,4,9,10],"legIntPurposes":[2,7],"flexiblePurposes":[2,7],"specialPurposes":[1,2],"features":[3],"specialFeatures":[],"policyUrl":"http://www.inskinmedia.com/privacy-policy.html"},"252":{"id":252,"name":"Jaduda GmbH","purposes":[1],"legIntPurposes":[2,3,4,5,6,7,8,9,10],"flexiblePurposes":[2,3,4,5,6,7,8,9,10],"specialPurposes":[1,2],"features":[3],"specialFeatures":[1],"policyUrl":"https://www.jadudamobile.com/datenschutzerklaerung/"},"248":{"id":248,"name":"Converge-Digital","purposes":[1],"legIntPurposes":[2],"flexiblePurposes":[2],"specialPurposes":[],"features":[3],"specialFeatures":[],"policyUrl":"https://converge-digital.com/privacy-policy/","overflow":{"httpGetLimit":32}},"161":{"id":161,"name":"Smadex SL","purposes":[1,2,3,4,7,10],"legIntPurposes":[],"flexiblePurposes":[],"specialPurposes":[1,2],"features":[1,2,3],"specialFeatures":[1],"policyUrl":"http://smadex.com/end-user-privacy-policy/"},"285":{"id":285,"name":"Comcast International France SAS","purposes":[1],"legIntPurposes":[],"flexiblePurposes":[],"specialPurposes":[],"features":[],"specialFeatures":[],"policyUrl":"https://www.freewheel.com/privacy-policy"},"228":{"id":228,"name":"McCann Discipline LTD","purposes":[1,2,5,6,7,8],"legIntPurposes":[],"flexiblePurposes":[2,5,6,7,8],"specialPurposes":[],"features":[],"specialFeatures":[],"policyUrl":"https://www.primis.tech/privacy-policy/"},"299":{"id":299,"name":"AdClear GmbH","purposes":[1,2,3,4,5,6,7,8,9,10],"legIntPurposes":[],"flexiblePurposes":[2,3,4,5,6,7,8,9,10],"specialPurposes":[2],"features":[1,2],"specialFeatures":[],"policyUrl":"https://www.adclear.de/datenschutzerklaerung/"},"277":{"id":277,"name":"Codewise VL Sp. z o.o. Sp. k","purposes":[1,2,3,4,7,9],"legIntPurposes":[10],"flexiblePurposes":[],"specialPurposes":[1,2],"features":[1,2,3],"specialFeatures":[],"policyUrl":"https://voluumdsp.com/end-user-privacy-policy/"},"259":{"id":259,"name":"ADYOULIKE SA","purposes":[1,3,4],"legIntPurposes":[2,7,8],"flexiblePurposes":[8],"specialPurposes":[1,2],"features":[3],"specialFeatures":[],"policyUrl":"https://www.adyoulike.com/privacy_policy.php"},"289":{"id":289,"name":"mobalo GmbH","purposes":[1,2,3,4,7,9,10],"legIntPurposes":[],"flexiblePurposes":[],"specialPurposes":[],"features":[1],"specialFeatures":[1],"policyUrl":"https://www.mobalo.com/en/privacy/"},"272":{"id":272,"name":"A.Mob","purposes":[1,2,3,4,5,6,7,8,9,10],"legIntPurposes":[],"flexiblePurposes":[],"specialPurposes":[1,2],"features":[1,2,3],"specialFeatures":[1],"policyUrl":"https://www.we-are-adot.com/privacy-policy/"},"253":{"id":253,"name":"Improve Digital BV","purposes":[1,3,4,9],"legIntPurposes":[2,7,10],"flexiblePurposes":[2,7,10],"specialPurposes":[1,2],"features":[3],"specialFeatures":[1],"policyUrl":"https://www.improvedigital.com/platform-privacy-policy","overflow":{"httpGetLimit":128}},"304":{"id":304,"name":"On Device Research Limited","purposes":[1,2,3,4,5,6,7,8,9,10],"legIntPurposes":[],"flexiblePurposes":[],"specialPurposes":[],"features":[1,2,3],"specialFeatures":[1,2],"policyUrl":"https://s.on-device.com/privacyPolicy"},"314":{"id":314,"name":"Keymantics","purposes":[1,2,3,4,7,9,10],"legIntPurposes":[],"flexiblePurposes":[2,3,4,7,9,10],"specialPurposes":[1,2],"features":[],"specialFeatures":[],"policyUrl":"https://www.keymantics.com/assets/privacy-policy.pdf"},"317":{"id":317,"name":"mainADV Srl","purposes":[1,2,3,4,5,6,7],"legIntPurposes":[],"flexiblePurposes":[],"specialPurposes":[1,2],"features":[],"specialFeatures":[],"policyUrl":"http://www.mainad.com/privacy-policy/"},"278":{"id":278,"name":"Integral Ad Science, Inc.","purposes":[],"legIntPurposes":[7,10],"flexiblePurposes":[],"specialPurposes":[1],"features":[],"specialFeatures":[],"policyUrl":"https://integralads.com/privacy-policy/"},"315":{"id":315,"name":"Celtra, Inc.","purposes":[1,2,4,7,10],"legIntPurposes":[],"flexiblePurposes":[],"specialPurposes":[1,2],"features":[],"specialFeatures":[1],"policyUrl":"https://www.celtra.com/privacy-policy/"},"165":{"id":165,"name":"SpotX, Inc.","purposes":[1,3,4],"legIntPurposes":[2,7,9,10],"flexiblePurposes":[2,3,4,7,9,10],"specialPurposes":[1,2],"features":[],"specialFeatures":[],"policyUrl":"https://www.spotx.tv/privacy-policy/","overflow":{"httpGetLimit":32}},"47":{"id":47,"name":"ADMAN - Phaistos Networks, S.A.","purposes":[1,2,4,7],"legIntPurposes":[],"flexiblePurposes":[],"specialPurposes":[1,2],"features":[],"specialFeatures":[],"policyUrl":"http://www.adman.gr/privacy"},"134":{"id":134,"name":"SMARTSTREAM.TV GmbH","purposes":[1],"legIntPurposes":[2,3,4,7,9,10],"flexiblePurposes":[2,3,4,7,9,10],"specialPurposes":[1,2],"features":[1,2,3],"specialFeatures":[],"policyUrl":"https://www.smartstream.tv/en/productprivacy","overflow":{"httpGetLimit":32}},"325":{"id":325,"name":"Knorex","purposes":[1,2,3,4,7,8,9,10],"legIntPurposes":[],"flexiblePurposes":[],"specialPurposes":[],"features":[1,2,3],"specialFeatures":[1],"policyUrl":"https://www.knorex.com/privacy"},"316":{"id":316,"name":"Gamned","purposes":[1,2,3,4,5,6,7,8,9,10],"legIntPurposes":[],"flexiblePurposes":[],"specialPurposes":[],"features":[],"specialFeatures":[1],"policyUrl":"https://www.gamned.com/privacy-policy/"},"318":{"id":318,"name":"Accorp Sp. z o.o.","purposes":[1,3,4,9],"legIntPurposes":[7,10],"flexiblePurposes":[],"specialPurposes":[],"features":[2],"specialFeatures":[],"policyUrl":"http://www.instytut-pollster.pl/privacy-policy/"},"199":{"id":199,"name":"ADUX","purposes":[1,2,3,4,6,7,9],"legIntPurposes":[],"flexiblePurposes":[],"specialPurposes":[2],"features":[],"specialFeatures":[1],"policyUrl":"https://www.adux.com/donnees-personelles/"},"294":{"id":294,"name":"Jivox Corporation","purposes":[1,2,3,4,5,7],"legIntPurposes":[],"flexiblePurposes":[2,3,4,5,7],"specialPurposes":[1,2],"features":[1,2,3],"specialFeatures":[1],"policyUrl":"https://www.jivox.com/privacy","overflow":{"httpGetLimit":32}},"143":{"id":143,"name":"Connatix Native Exchange Inc.","purposes":[1,2,4,6,7,8,10],"legIntPurposes":[],"flexiblePurposes":[],"specialPurposes":[],"features":[3],"specialFeatures":[],"policyUrl":"https://connatix.com/privacy-policy/"},"297":{"id":297,"name":"Polar Mobile Group Inc.","purposes":[1,3,4],"legIntPurposes":[2,7,8,10],"flexiblePurposes":[2,7,8,10],"specialPurposes":[1,2],"features":[],"specialFeatures":[],"policyUrl":"https://privacy.polar.me"},"319":{"id":319,"name":"Clipcentric, Inc.","purposes":[1],"legIntPurposes":[2,7,10],"flexiblePurposes":[],"specialPurposes":[1,2],"features":[],"specialFeatures":[1],"policyUrl":"https://clipcentric.com/privacy.bhtml"},"290":{"id":290,"name":"Readpeak Oy","purposes":[1,2,3,4,5,6,7,8,9,10],"legIntPurposes":[],"flexiblePurposes":[],"specialPurposes":[],"features":[],"specialFeatures":[],"policyUrl":"http://readpeak.com/privacy-policy/"},"323":{"id":323,"name":"DAZN Media Services Limited","purposes":[1,3,4,7],"legIntPurposes":[2,8,10],"flexiblePurposes":[8,10],"specialPurposes":[1,2],"features":[3],"specialFeatures":[1],"policyUrl":"https://www.goal.com/en-gb/legal/privacy-policy"},"119":{"id":119,"name":"Fusio by S4M","purposes":[1,3,4,10],"legIntPurposes":[],"flexiblePurposes":[3,4,10],"specialPurposes":[1,2],"features":[],"specialFeatures":[1],"policyUrl":"http://www.s4m.io/privacy-policy/"},"302":{"id":302,"name":"Mobile Professionals BV","purposes":[1,2,3,4,5,7,8,9],"legIntPurposes":[],"flexiblePurposes":[3,5,7,8],"specialPurposes":[],"features":[3],"specialFeatures":[1],"policyUrl":"https://mobpro.com/privacy.html"},"212":{"id":212,"name":"usemax advertisement (Emego GmbH)","purposes":[1],"legIntPurposes":[2,3,4,5,6,7,8,9,10],"flexiblePurposes":[2,3,4,5,6,7,8],"specialPurposes":[1,2],"features":[],"specialFeatures":[],"policyUrl":"http://www.usemax.de/?l=privacy"},"264":{"id":264,"name":"Adobe Advertising Cloud","purposes":[1,2,3,4,10],"legIntPurposes":[7],"flexiblePurposes":[2],"specialPurposes":[1,2],"features":[3],"specialFeatures":[],"policyUrl":"https://www.adobe.com/privacy/experience-cloud.html"},"44":{"id":44,"name":"The ADEX GmbH","purposes":[1,2,3,4,5,6,7,8,9,10],"legIntPurposes":[],"flexiblePurposes":[2,3,4,5,6,7,8,9,10],"specialPurposes":[1,2],"features":[1,2,3],"specialFeatures":[],"policyUrl":"https://theadex.com/privacy-opt-out/"},"282":{"id":282,"name":"Welect GmbH","purposes":[10],"legIntPurposes":[2,7],"flexiblePurposes":[2],"specialPurposes":[2],"features":[],"specialFeatures":[],"policyUrl":"https://www.welect.de/datenschutz"},"238":{"id":238,"name":"StackAdapt","purposes":[1,2,3,4],"legIntPurposes":[7,9,10],"flexiblePurposes":[],"specialPurposes":[2],"features":[1,2],"specialFeatures":[1],"policyUrl":"https://www.stackadapt.com/privacy"},"284":{"id":284,"name":"WEBORAMA","purposes":[1,3,4],"legIntPurposes":[2,5,6,7,8,9,10],"flexiblePurposes":[2,5,6,7,8,9,10],"specialPurposes":[1,2],"features":[1,2],"specialFeatures":[1],"policyUrl":"https://weborama.com/privacy_en/"},"301":{"id":301,"name":"zeotap GmbH","purposes":[1,3,4,5,6,7,9,10],"legIntPurposes":[],"flexiblePurposes":[3,4,5,6,7,9,10],"specialPurposes":[],"features":[1,2,3],"specialFeatures":[],"policyUrl":"https://zeotap.com/privacy_policy"},"275":{"id":275,"name":"TabMo SAS","purposes":[1,2,3,4,7,9,10],"legIntPurposes":[],"flexiblePurposes":[],"specialPurposes":[1,2],"features":[1,2,3],"specialFeatures":[1],"policyUrl":"http://static.tabmo.io.s3.amazonaws.com/privacy-policy/index.html"},"310":{"id":310,"name":"Adevinta Spain S.L.U.","purposes":[1,2,3,4,9],"legIntPurposes":[7,10],"flexiblePurposes":[],"specialPurposes":[1,2],"features":[1,2,3],"specialFeatures":[1],"policyUrl":"https://www.adevinta.com/about/privacy/"},"139":{"id":139,"name":"Permodo GmbH","purposes":[1,2,7,8,10],"legIntPurposes":[],"flexiblePurposes":[2,7,8,10],"specialPurposes":[1,2],"features":[1,2],"specialFeatures":[1],"policyUrl":"https://permodo.com/de/privacy.html","overflow":{"httpGetLimit":32}},"262":{"id":262,"name":"Fyber ","purposes":[1,2,3,4,5,7],"legIntPurposes":[],"flexiblePurposes":[],"specialPurposes":[],"features":[3],"specialFeatures":[1],"policyUrl":"https://www.fyber.com/legal/privacy-policy/"},"331":{"id":331,"name":"ad6media","purposes":[1],"legIntPurposes":[2,3,4,5,6,7,8,10],"flexiblePurposes":[2,3,4,5,6],"specialPurposes":[1,2],"features":[2,3],"specialFeatures":[1,2],"policyUrl":"https://www.ad6media.fr/privacy"},"345":{"id":345,"name":"The Kantar Group Limited","purposes":[1,2,3,4,7,8,9,10],"legIntPurposes":[],"flexiblePurposes":[2,3,4,7,8,9,10],"specialPurposes":[2],"features":[1,2,3],"specialFeatures":[1,2],"policyUrl":"http://www.kantar.com/cookies-policies"},"270":{"id":270,"name":"Marfeel Solutions, SL","purposes":[1],"legIntPurposes":[],"flexiblePurposes":[],"specialPurposes":[],"features":[],"specialFeatures":[],"policyUrl":"https://www.marfeel.com/privacy-policy/"},"333":{"id":333,"name":"InMobi Pte Ltd","purposes":[1,2,3,4,9,10],"legIntPurposes":[],"flexiblePurposes":[9],"specialPurposes":[1],"features":[1,2,3],"specialFeatures":[1],"policyUrl":"https://www.inmobi.com/privacy-policy-for-eea"},"202":{"id":202,"name":"Telaria, Inc","purposes":[1,2,3,4,5,6],"legIntPurposes":[7,8,9,10],"flexiblePurposes":[5,6,7,8,9,10],"specialPurposes":[1,2],"features":[1,2,3],"specialFeatures":[1,2],"policyUrl":"https://telaria.com/privacy-policy/"},"328":{"id":328,"name":"Gemius SA","purposes":[1,2,3,4,5,6,7,8,9,10],"legIntPurposes":[],"flexiblePurposes":[],"specialPurposes":[],"features":[3],"specialFeatures":[],"policyUrl":"https://www.gemius.com/cookie-policy.html"},"281":{"id":281,"name":"Wizaly","purposes":[1,7,8,9],"legIntPurposes":[],"flexiblePurposes":[],"specialPurposes":[],"features":[1,2],"specialFeatures":[],"policyUrl":"https://www.wizaly.com/terms-of-use#privacy-policy"},"354":{"id":354,"name":"Apester Ltd","purposes":[2,4],"legIntPurposes":[6,7,8,9,10],"flexiblePurposes":[7],"specialPurposes":[1,2],"features":[],"specialFeatures":[],"policyUrl":"https://apester.com/privacy-policy/"},"359":{"id":359,"name":"AerServ LLC","purposes":[1,2,3,4,9,10],"legIntPurposes":[],"flexiblePurposes":[9],"specialPurposes":[1],"features":[1,2,3],"specialFeatures":[1],"policyUrl":"https://www.inmobi.com/privacy-policy-for-eea"},"265":{"id":265,"name":"Instinctive, Inc.","purposes":[1,2,3,4,5,6,7,8],"legIntPurposes":[9,10],"flexiblePurposes":[],"specialPurposes":[1,2],"features":[3],"specialFeatures":[1],"policyUrl":"https://instinctive.io/privacy"},"303":{"id":303,"name":"Orion Semantics","purposes":[1,2,3,4,7,9],"legIntPurposes":[],"flexiblePurposes":[],"specialPurposes":[],"features":[],"specialFeatures":[],"policyUrl":"http://static.orion-semantics.com/privacy.html"},"83":{"id":83,"name":"Visarity Technologies GmbH","purposes":[2,6,7,8],"legIntPurposes":[],"flexiblePurposes":[2],"specialPurposes":[1,2],"features":[],"specialFeatures":[],"policyUrl":"http://primo.design/docs/PrivacyPolicyPrimo.html"},"343":{"id":343,"name":"DIGITEKA Technologies","purposes":[1],"legIntPurposes":[2,3,4,5,6,7,8,9,10],"flexiblePurposes":[2,3,4,5,6,7,8,9,10],"specialPurposes":[1,2],"features":[1,3],"specialFeatures":[1],"policyUrl":"https://www.ultimedia.com/POLICY.html"},"231":{"id":231,"name":"AcuityAds Inc.","purposes":[1,3,4],"legIntPurposes":[2,7,8,10],"flexiblePurposes":[3,4],"specialPurposes":[1,2],"features":[2],"specialFeatures":[],"policyUrl":"https://privacy.acuityads.com/corporate-privacy-policy.html","overflow":{"httpGetLimit":128}},"216":{"id":216,"name":"Mindlytix SAS","purposes":[1,2,3,5,7,8,9,10],"legIntPurposes":[],"flexiblePurposes":[],"specialPurposes":[1],"features":[1,2],"specialFeatures":[],"policyUrl":"http://mindlytix.com/privacy/"},"360":{"id":360,"name":"Permutive Technologies, Inc.","purposes":[1],"legIntPurposes":[3,5,7,8,9],"flexiblePurposes":[3,5,7,8,9],"specialPurposes":[],"features":[1,2],"specialFeatures":[],"policyUrl":"https://permutive.com/privacy/"},"361":{"id":361,"name":"Permutive Limited","purposes":[1],"legIntPurposes":[3,5,7,8,9],"flexiblePurposes":[3,5,7,8,9],"specialPurposes":[],"features":[1,2],"specialFeatures":[],"policyUrl":"https://permutive.com/privacy/"},"311":{"id":311,"name":"Mobfox US LLC","purposes":[1,2,3,4,5,6,7,8,9,10],"legIntPurposes":[],"flexiblePurposes":[],"specialPurposes":[1,2],"features":[],"specialFeatures":[1],"policyUrl":"https://www.mobfox.com/privacy-policy/"},"358":{"id":358,"name":"MGID Inc.","purposes":[2,3,4,5,6,7,8,9,10],"legIntPurposes":[],"flexiblePurposes":[],"specialPurposes":[1,2],"features":[1,2,3],"specialFeatures":[1],"policyUrl":"https://www.mgid.com/privacy-policy"},"152":{"id":152,"name":"Meetrics GmbH","purposes":[1,9],"legIntPurposes":[7],"flexiblePurposes":[7],"specialPurposes":[1],"features":[],"specialFeatures":[],"policyUrl":"https://www.meetrics.com/en/data-privacy/"},"251":{"id":251,"name":"Yieldlove GmbH","purposes":[1],"legIntPurposes":[2,7,10],"flexiblePurposes":[2,7,10],"specialPurposes":[1,2],"features":[],"specialFeatures":[],"policyUrl":"http://www.yieldlove.com/cookie-policy"},"371":{"id":371,"name":"Seeding Alliance GmbH","purposes":[1,3,4,5,6],"legIntPurposes":[2,7,8,10],"flexiblePurposes":[2,7,8,10],"specialPurposes":[1,2],"features":[],"specialFeatures":[1],"policyUrl":"https://seeding-alliance.de/datenschutz/"},"347":{"id":347,"name":"Ezoic Inc.","purposes":[1,7,8,9],"legIntPurposes":[6,10],"flexiblePurposes":[6,10],"specialPurposes":[1,2],"features":[3],"specialFeatures":[1],"policyUrl":"https://www.ezoic.com/terms/"},"218":{"id":218,"name":"Bigabid Media ltd","purposes":[1,3,4],"legIntPurposes":[2,5,6,7,8,9,10],"flexiblePurposes":[],"specialPurposes":[1],"features":[3],"specialFeatures":[1],"policyUrl":"https://www.bigabid.com/privacy-policy"},"350":{"id":350,"name":"Free Stream Media Corp. dba Samba TV","purposes":[1,2,3,4,5,6,7,8,9,10],"legIntPurposes":[],"flexiblePurposes":[2,3,4,5,6,7,8,9,10],"specialPurposes":[1],"features":[1,2,3],"specialFeatures":[],"policyUrl":"https://samba.tv/legal/privacy-policy/","overflow":{"httpGetLimit":128}},"351":{"id":351,"name":"Samba TV UK Limited","purposes":[1,2,3,4,5,6,7,8,9,10],"legIntPurposes":[],"flexiblePurposes":[2,3,4,5,6,7,8,9,10],"specialPurposes":[1],"features":[1,2,3],"specialFeatures":[],"policyUrl":"https://samba.tv/legal/privacy-policy/","overflow":{"httpGetLimit":128}},"380":{"id":380,"name":"Vidoomy Media SL","purposes":[2,3,4,5,6,7,8],"legIntPurposes":[],"flexiblePurposes":[],"specialPurposes":[],"features":[],"specialFeatures":[],"policyUrl":"http://vidoomy.com/privacy-policy.html"},"184":{"id":184,"name":"mediarithmics SAS","purposes":[1,2,3,4,5,6,7,8,9,10],"legIntPurposes":[],"flexiblePurposes":[2,7],"specialPurposes":[1,2],"features":[1,2,3],"specialFeatures":[],"policyUrl":"https://www.mediarithmics.com/en-us/content/privacy-policy"},"368":{"id":368,"name":"VECTAURY","purposes":[1,2,3,4,7,9],"legIntPurposes":[],"flexiblePurposes":[],"specialPurposes":[1,2],"features":[1,2,3],"specialFeatures":[1],"policyUrl":"https://www.vectaury.io/en/personal-data"},"373":{"id":373,"name":"Nielsen Marketing Cloud","purposes":[1,3,5],"legIntPurposes":[7,8,9,10],"flexiblePurposes":[],"specialPurposes":[1],"features":[1,2,3],"specialFeatures":[1],"policyUrl":"http://www.nielsen.com/us/en/privacy-statement/exelate-privacy-policy.html"},"388":{"id":388,"name":"numberly","purposes":[1,3,4,5,6,9],"legIntPurposes":[2,7,8,10],"flexiblePurposes":[2,7,8,10],"specialPurposes":[1],"features":[1,2,3],"specialFeatures":[1,2],"policyUrl":"https://numberly.com/en/privacy/"},"250":{"id":250,"name":"Qriously Ltd","purposes":[2,3,4,5,6,7,8,9,10],"legIntPurposes":[],"flexiblePurposes":[],"specialPurposes":[2],"features":[],"specialFeatures":[],"policyUrl":"https://www.brandwatch.com/legal/qriously-privacy-notice/"},"223":{"id":223,"name":"Audience Trading Platform Ltd.","purposes":[1],"legIntPurposes":[7,8],"flexiblePurposes":[7,8],"specialPurposes":[],"features":[2],"specialFeatures":[],"policyUrl":"https://atp.io/privacy-policy"},"384":{"id":384,"name":"Pixalate, Inc.","purposes":[],"legIntPurposes":[7,8,10],"flexiblePurposes":[],"specialPurposes":[1,2],"features":[3],"specialFeatures":[1,2],"policyUrl":"https://pixalate.com/privacypolicy/"},"387":{"id":387,"name":"Triapodi Ltd.","purposes":[2,3,4,7],"legIntPurposes":[],"flexiblePurposes":[],"specialPurposes":[],"features":[3],"specialFeatures":[],"policyUrl":"https://appreciate.mobi/page.html#/end-user-privacy-policy"},"312":{"id":312,"name":"Exactag GmbH","purposes":[1,3,7,8],"legIntPurposes":[],"flexiblePurposes":[3,7,8],"specialPurposes":[1],"features":[2],"specialFeatures":[],"policyUrl":"https://www.exactag.com/en/data-privacy/","overflow":{"httpGetLimit":128}},"178":{"id":178,"name":"Hybrid Theory","purposes":[1,2,3,4,5,6,7,8,9,10],"legIntPurposes":[],"flexiblePurposes":[7,8,9,10],"specialPurposes":[1],"features":[],"specialFeatures":[],"policyUrl":"https://hybridtheory.com/privacy-policy/"},"377":{"id":377,"name":"AddApptr GmbH","purposes":[1],"legIntPurposes":[7,10],"flexiblePurposes":[7,10],"specialPurposes":[1,2],"features":[],"specialFeatures":[1],"policyUrl":"https://www.addapptr.com/data-privacy"},"382":{"id":382,"name":"The Reach Group GmbH","purposes":[1,3,4,5,6,9],"legIntPurposes":[2,7,8],"flexiblePurposes":[2,3,4,5,6,7,8,9],"specialPurposes":[1,2],"features":[3],"specialFeatures":[],"policyUrl":"https://trg.de/en/privacy-statement/","overflow":{"httpGetLimit":128}},"206":{"id":206,"name":"Hybrid Adtech GmbH","purposes":[1,2,3,4,5,6,7,8,9,10],"legIntPurposes":[],"flexiblePurposes":[],"specialPurposes":[],"features":[1,2,3],"specialFeatures":[1,2],"policyUrl":"https://hybrid.ai/data_protection_policy"},"385":{"id":385,"name":"Oracle Data Cloud","purposes":[1,3,5,9,10],"legIntPurposes":[7],"flexiblePurposes":[],"specialPurposes":[],"features":[1,2],"specialFeatures":[],"policyUrl":"https://www.oracle.com/legal/privacy/marketing-cloud-data-cloud-privacy-policy.html"},"242":{"id":242,"name":"twiago GmbH","purposes":[1,2,3,4,7,10],"legIntPurposes":[],"flexiblePurposes":[2,3,4,7],"specialPurposes":[1,2],"features":[3],"specialFeatures":[],"policyUrl":"https://www.twiago.com/datenschutz/","overflow":{"httpGetLimit":32}},"402":{"id":402,"name":"Effiliation","purposes":[1,7],"legIntPurposes":[],"flexiblePurposes":[],"specialPurposes":[],"features":[],"specialFeatures":[],"policyUrl":"https://inter.effiliation.com/politique-confidentialite.html"},"413":{"id":413,"name":"Eulerian Technologies","purposes":[1,2,3,4,5,6,7,8,9,10],"legIntPurposes":[],"flexiblePurposes":[],"specialPurposes":[],"features":[1,2,3],"specialFeatures":[],"policyUrl":"https://www.eulerian.com/en/privacy/"},"415":{"id":415,"name":"Seenthis AB","purposes":[],"legIntPurposes":[],"flexiblePurposes":[],"specialPurposes":[2],"features":[],"specialFeatures":[],"policyUrl":"https://seenthis.co/privacy-notice-2018-04-18.pdf"},"263":{"id":263,"name":"Nativo, Inc.","purposes":[1,3,4],"legIntPurposes":[2,7,9,10],"flexiblePurposes":[],"specialPurposes":[1,2],"features":[2],"specialFeatures":[],"policyUrl":"https://www.nativo.com/interest-based-ads"},"329":{"id":329,"name":"Browsi Mobile Ltd","purposes":[1,7,8],"legIntPurposes":[],"flexiblePurposes":[],"specialPurposes":[1,2],"features":[],"specialFeatures":[],"policyUrl":"http://gobrowsi.com/browsi-privacy-policy/"},"337":{"id":337,"name":"SheMedia, LLC","purposes":[1,2,3,4,5,6,7,8,9,10],"legIntPurposes":[],"flexiblePurposes":[],"specialPurposes":[],"features":[2,3],"specialFeatures":[],"policyUrl":"https://www.shemedia.com/ad-services-privacy-policy"},"422":{"id":422,"name":"Brand Metrics Sweden AB","purposes":[1,6,7,8,9],"legIntPurposes":[],"flexiblePurposes":[],"specialPurposes":[],"features":[],"specialFeatures":[],"policyUrl":"https://collector.brandmetrics.com/brandmetrics_privacypolicy.pdf"},"394":{"id":394,"name":"AudienceProject Aps","purposes":[1,3,4,5,6],"legIntPurposes":[2,7,8,9,10],"flexiblePurposes":[2,7,8,9],"specialPurposes":[1,2],"features":[1,2],"specialFeatures":[],"policyUrl":"https://privacy.audienceproject.com"},"243":{"id":243,"name":"Cloud Technologies S.A.","purposes":[1,2,3,4,5,6,7,8,9,10],"legIntPurposes":[],"flexiblePurposes":[],"specialPurposes":[1,2],"features":[1,2,3],"specialFeatures":[1],"policyUrl":"https://www.cloudtechnologies.pl/en/internet-advertising-privacy-policy"},"416":{"id":416,"name":"Commanders Act","purposes":[1,2,3,4,5,6,7,8,10],"legIntPurposes":[],"flexiblePurposes":[],"specialPurposes":[],"features":[1,2,3],"specialFeatures":[],"policyUrl":"https://www.commandersact.com/en/privacy/"},"434":{"id":434,"name":"DynAdmic","purposes":[1,2,4,7],"legIntPurposes":[3,6,8],"flexiblePurposes":[],"specialPurposes":[1,2],"features":[1,3],"specialFeatures":[1],"policyUrl":"http://eu.dynadmic.com/privacy-policy/"},"435":{"id":435,"name":"SINGLESPOT SAS ","purposes":[1,3,4,7,9],"legIntPurposes":[],"flexiblePurposes":[],"specialPurposes":[1],"features":[1,2,3],"specialFeatures":[1,2],"policyUrl":"https://www.singlespot.com/privacy_policy?locale=fr"},"409":{"id":409,"name":"Arrivalist Co.","purposes":[1,9],"legIntPurposes":[7,8],"flexiblePurposes":[],"specialPurposes":[],"features":[1,2,3],"specialFeatures":[1,2],"policyUrl":"https://www.arrivalist.com/privacy"},"436":{"id":436,"name":"INVIBES GROUP","purposes":[1,3,4,5,6,9],"legIntPurposes":[2,7,8,10],"flexiblePurposes":[2,7,8,10],"specialPurposes":[1,2],"features":[1,2,3],"specialFeatures":[],"policyUrl":"http://www.invibes.com/terms"},"418":{"id":418,"name":"PROXISTORE","purposes":[1,2,4,7,9,10],"legIntPurposes":[],"flexiblePurposes":[],"specialPurposes":[],"features":[2],"specialFeatures":[1,2],"policyUrl":"https://www.proxistore.com/common/en/cgv"},"429":{"id":429,"name":"Signals","purposes":[1,2,3,4,5,6,7,8,9,10],"legIntPurposes":[],"flexiblePurposes":[],"specialPurposes":[],"features":[1,2,3],"specialFeatures":[1,2],"policyUrl":"https://signalsdata.com/platform-cookie-policy/"},"374":{"id":374,"name":"Bmind a Sales Maker Company, S.L.","purposes":[1,2,3,4,5,6,7,8,9,10],"legIntPurposes":[],"flexiblePurposes":[2,3,4,5,6,7,8,9,10],"specialPurposes":[1,2],"features":[1,2],"specialFeatures":[],"policyUrl":"http://www.bmind.es/legal-notice/"},"438":{"id":438,"name":"INVIDI technologies AB","purposes":[1,2,3,4,7,9,10],"legIntPurposes":[],"flexiblePurposes":[2,3,4,7,9,10],"specialPurposes":[],"features":[1,2],"specialFeatures":[],"policyUrl":"http://www.invidi.com/wp-content/uploads/2020/02/ad-tech-services-privacy-policy.pdf"},"450":{"id":450,"name":"Neodata Group srl","purposes":[1,2,3,4,5,6,7,8,9,10],"legIntPurposes":[],"flexiblePurposes":[],"specialPurposes":[1,2],"features":[1,2,3],"specialFeatures":[1],"policyUrl":"https://www.neodatagroup.com/en/security-policy","overflow":{"httpGetLimit":32}},"444":{"id":444,"name":"Playbuzz Ltd (aka EX.CO)","purposes":[1],"legIntPurposes":[2,3,4,5,6,7,8,9,10],"flexiblePurposes":[2,3,5,6],"specialPurposes":[1,2],"features":[],"specialFeatures":[],"policyUrl":"https://ex.co/privacy-policy/"},"412":{"id":412,"name":"Cxense ASA","purposes":[1,2,3,4,5,6,7,8,9,10],"legIntPurposes":[],"flexiblePurposes":[2,3,4,5,6,7,8,9,10],"specialPurposes":[],"features":[1,2,3],"specialFeatures":[1],"policyUrl":"https://www.cxense.com/about-us/privacy-policy"},"455":{"id":455,"name":"GDMServices, Inc. d/b/a FiksuDSP","purposes":[1,2,3,4,10],"legIntPurposes":[7,8],"flexiblePurposes":[2,3,4,10],"specialPurposes":[1,2],"features":[1,2,3],"specialFeatures":[1],"policyUrl":"https://fiksu.com/privacy-policy/"},"423":{"id":423,"name":"travel audience GmbH","purposes":[1,2,3,4,5,6,7,8,9,10],"legIntPurposes":[],"flexiblePurposes":[],"specialPurposes":[],"features":[1,2],"specialFeatures":[1],"policyUrl":"https://travelaudience.com/product-privacy-policy/"},"381":{"id":381,"name":"Solocal","purposes":[1,2,3,4,7,9,10],"legIntPurposes":[],"flexiblePurposes":[],"specialPurposes":[1,2],"features":[],"specialFeatures":[1],"policyUrl":"https://frontend.adhslx.com/privacy.html?"},"365":{"id":365,"name":"Forensiq LLC","purposes":[],"legIntPurposes":[7],"flexiblePurposes":[],"specialPurposes":[1],"features":[1,3],"specialFeatures":[1],"policyUrl":"https://impact.com/privacy-policy/"},"447":{"id":447,"name":"Adludio Ltd","purposes":[2,3,4,7,9,10],"legIntPurposes":[],"flexiblePurposes":[],"specialPurposes":[],"features":[1],"specialFeatures":[1],"policyUrl":"https://www.adludio.com/privacy-policy/"},"410":{"id":410,"name":"Adtelligent Inc.","purposes":[1,7,10],"legIntPurposes":[],"flexiblePurposes":[],"specialPurposes":[1,2],"features":[3],"specialFeatures":[1],"policyUrl":"https://adtelligent.com/privacy-policy/"},"137":{"id":137,"name":"Str\u00f6er SSP GmbH (DSP)","purposes":[1],"legIntPurposes":[2,3,4,7,9,10],"flexiblePurposes":[2,3,4,9],"specialPurposes":[1,2],"features":[1,2],"specialFeatures":[1],"policyUrl":"https://www.stroeer.de/fileadmin/de/Konvergenz_und_Konzepte/Daten_und_Technologien/Stroeer_SSP/Downloads/Datenschutz_Stroeer_SSP.pdf"},"466":{"id":466,"name":"TACTIC\u2122 Real-Time Marketing AS","purposes":[],"legIntPurposes":[],"flexiblePurposes":[],"specialPurposes":[],"features":[],"specialFeatures":[],"policyUrl":"https://tacticrealtime.com/privacy/"},"431":{"id":431,"name":"White Ops, Inc.","purposes":[],"legIntPurposes":[7,9,10],"flexiblePurposes":[],"specialPurposes":[1,2],"features":[1,3],"specialFeatures":[2],"policyUrl":"https://www.whiteops.com/privacy"},"336":{"id":336,"name":"Telecoming S.A.","purposes":[2,4],"legIntPurposes":[7,9],"flexiblePurposes":[2,4],"specialPurposes":[1,2],"features":[],"specialFeatures":[],"policyUrl":"http://www.telecoming.com/privacy-policy/","overflow":{"httpGetLimit":128}},"440":{"id":440,"name":"DEFINE MEDIA GMBH","purposes":[1,4],"legIntPurposes":[2,7,9,10],"flexiblePurposes":[2,7,9,10],"specialPurposes":[1,2],"features":[],"specialFeatures":[],"policyUrl":"http://www.definemedia.de/datenschutz-conative/"},"375":{"id":375,"name":"Affle International","purposes":[1,2,3,4,5,6,7,8,9,10],"legIntPurposes":[],"flexiblePurposes":[],"specialPurposes":[],"features":[3],"specialFeatures":[1],"policyUrl":"https://affle.com/privacy-policy "},"475":{"id":475,"name":"TAPTAP Digital SL","purposes":[1,2,3,4,5,6,7],"legIntPurposes":[8,10],"flexiblePurposes":[],"specialPurposes":[],"features":[1,2,3],"specialFeatures":[1],"policyUrl":"http://www.taptapnetworks.com/privacy_policy/"},"448":{"id":448,"name":"Targetspot Belgium SPRL","purposes":[1,2,3,4,7,9],"legIntPurposes":[],"flexiblePurposes":[2,3,4,7,9],"specialPurposes":[1,2],"features":[1,2,3],"specialFeatures":[1,2],"policyUrl":"http://marketing.targetspot.com/Targetspot/Legal/TargetSpot%20Privacy%20Policy%20-%20June%202018.pdf","overflow":{"httpGetLimit":128}},"428":{"id":428,"name":"Internet BillBoard a.s.","purposes":[1],"legIntPurposes":[2,3,4,7],"flexiblePurposes":[2,3,4],"specialPurposes":[1,2],"features":[],"specialFeatures":[],"policyUrl":"http://www.ibillboard.com/en/privacy-information/"},"486":{"id":486,"name":"Madington","purposes":[1],"legIntPurposes":[],"flexiblePurposes":[],"specialPurposes":[1,2],"features":[],"specialFeatures":[],"policyUrl":"https://delivered-by-madington.com/dat-privacy-policy/"},"468":{"id":468,"name":"NeuStar, Inc.","purposes":[1],"legIntPurposes":[3,7,8,9,10],"flexiblePurposes":[7,8,9,10],"specialPurposes":[1],"features":[1,2],"specialFeatures":[],"policyUrl":"https://www.home.neustar/privacy"},"293":{"id":293,"name":"SpringServe, LLC","purposes":[1,2,3,4,5,6,7,8,9,10],"legIntPurposes":[],"flexiblePurposes":[],"specialPurposes":[1],"features":[3],"specialFeatures":[2],"policyUrl":"https://springserve.com/privacy-policy/"},"484":{"id":484,"name":"STRIATUM SAS","purposes":[],"legIntPurposes":[7,10],"flexiblePurposes":[],"specialPurposes":[1],"features":[],"specialFeatures":[],"policyUrl":"https://adledge.com/data-privacy/"},"493":{"id":493,"name":"Carbon (AI) Limited","purposes":[1,2,3,4,5,6,7,8,10],"legIntPurposes":[],"flexiblePurposes":[2,7,8],"specialPurposes":[2],"features":[1,2,3],"specialFeatures":[2],"policyUrl":"https://carbonrmp.com/privacy.html"},"495":{"id":495,"name":"Arcspire Limited","purposes":[2,3,4,7,9,10],"legIntPurposes":[],"flexiblePurposes":[],"specialPurposes":[],"features":[3],"specialFeatures":[1],"policyUrl":"https://public.arcspire.io/privacy.pdf","overflow":{"httpGetLimit":128}},"424":{"id":424,"name":"KUPONA GmbH","purposes":[4,7],"legIntPurposes":[],"flexiblePurposes":[4],"specialPurposes":[],"features":[],"specialFeatures":[],"policyUrl":"https://www.kupona.de/dsgvo/"},"408":{"id":408,"name":"Fidelity Media","purposes":[1,2,7],"legIntPurposes":[],"flexiblePurposes":[2,7],"specialPurposes":[],"features":[],"specialFeatures":[],"policyUrl":"https://fidelity-media.com/privacy-policy/"},"467":{"id":467,"name":"Haensel AMS GmbH","purposes":[1],"legIntPurposes":[7],"flexiblePurposes":[7],"specialPurposes":[],"features":[2],"specialFeatures":[],"policyUrl":"https://haensel-ams.com/data-privacy/"},"488":{"id":488,"name":"Opinary GmbH","purposes":[1],"legIntPurposes":[2,7,8,10],"flexiblePurposes":[2,7,8,10],"specialPurposes":[1,2],"features":[],"specialFeatures":[],"policyUrl":"https://opinary.com/privacy-policy/"},"490":{"id":490,"name":"PLAYGROUND XYZ EMEA LTD","purposes":[1,2,3,4,7,8,9,10],"legIntPurposes":[],"flexiblePurposes":[2,3,4,7],"specialPurposes":[],"features":[],"specialFeatures":[],"policyUrl":"https://playground.xyz/privacy"},"491":{"id":491,"name":"Triboo Data Analytics","purposes":[1,2,3,4,5,6,7,8,9,10],"legIntPurposes":[],"flexiblePurposes":[],"specialPurposes":[],"features":[],"specialFeatures":[],"policyUrl":"https://www.shinystat.com/it/informativa_privacy_generale.html"},"502":{"id":502,"name":"NEXD","purposes":[1,7,10],"legIntPurposes":[9],"flexiblePurposes":[],"specialPurposes":[1,2],"features":[],"specialFeatures":[],"policyUrl":"https://nexd.com/privacy-policy","overflow":{"httpGetLimit":128}},"508":{"id":508,"name":"Lucid Holdings, LLC","purposes":[1,7,8,9],"legIntPurposes":[],"flexiblePurposes":[7,8,9],"specialPurposes":[1],"features":[1,2,3],"specialFeatures":[],"policyUrl":"luc.id/privacy-policy"},"512":{"id":512,"name":"PubNative GmbH","purposes":[1,2,3,4,7,8,10],"legIntPurposes":[],"flexiblePurposes":[],"specialPurposes":[],"features":[3],"specialFeatures":[2],"policyUrl":"https://pubnative.net/privacy-notice/"},"516":{"id":516,"name":"Pexi B.V.","purposes":[1,2,3,4,5,6,7,8,9,10],"legIntPurposes":[],"flexiblePurposes":[],"specialPurposes":[],"features":[],"specialFeatures":[],"policyUrl":"https://pexi.nl/privacy-policy/"},"507":{"id":507,"name":"AdsWizz Inc.","purposes":[1,2,3,4,5,6,7,8,9,10],"legIntPurposes":[],"flexiblePurposes":[2,3,4,5,6,7,8,9,10],"specialPurposes":[1,2],"features":[1,2,3],"specialFeatures":[1,2],"policyUrl":"https://www.adswizz.com/our-privacy-policy/"},"482":{"id":482,"name":"UberMedia, Inc.","purposes":[1,2,3,4,5,6,7,8,9,10],"legIntPurposes":[],"flexiblePurposes":[2,3,4,5,6,7,8,9,10],"specialPurposes":[],"features":[],"specialFeatures":[],"policyUrl":"https://ubermedia.com/summary-of-privacy-policy/"},"505":{"id":505,"name":"Shopalyst Inc","purposes":[1,7,8],"legIntPurposes":[],"flexiblePurposes":[],"specialPurposes":[],"features":[],"specialFeatures":[1],"policyUrl":"https://www.shortlyst.com/eu/privacy_terms.html"},"517":{"id":517,"name":"SunMedia ","purposes":[1,2,3,4,7,9,10],"legIntPurposes":[],"flexiblePurposes":[],"specialPurposes":[1,2],"features":[3],"specialFeatures":[],"policyUrl":"https://www.sunmedia.tv/en/cookies"},"511":{"id":511,"name":"Admixer EU GmbH","purposes":[1,2,3,4,5,7,9],"legIntPurposes":[10],"flexiblePurposes":[],"specialPurposes":[1,2],"features":[1,2],"specialFeatures":[1],"policyUrl":"https://admixer.com/privacy/","overflow":{"httpGetLimit":128}},"479":{"id":479,"name":"INFINIA MOBILE S.L.","purposes":[1,2,3,4,5,6,7,8,9,10],"legIntPurposes":[],"flexiblePurposes":[],"specialPurposes":[1,2],"features":[1,2,3],"specialFeatures":[1,2],"policyUrl":"http://www.infiniamobile.com/privacy_policy"},"509":{"id":509,"name":"ATG Ad Tech Group GmbH","purposes":[2,7],"legIntPurposes":[],"flexiblePurposes":[2,7],"specialPurposes":[],"features":[],"specialFeatures":[],"policyUrl":"https://ad-tech-group.com/privacy-policy/"},"521":{"id":521,"name":"netzeffekt GmbH","purposes":[1,7],"legIntPurposes":[],"flexiblePurposes":[],"specialPurposes":[],"features":[],"specialFeatures":[1],"policyUrl":"https://www.netzeffekt.de/en/imprint"},"524":{"id":524,"name":"The Ozone Project Limited","purposes":[1,2,3,4,5,7,9,10],"legIntPurposes":[],"flexiblePurposes":[],"specialPurposes":[],"features":[2,3],"specialFeatures":[1],"policyUrl":"https://ozoneproject.com/privacy-policy"},"528":{"id":528,"name":"Kayzen","purposes":[1,2,3,4,9,10],"legIntPurposes":[7],"flexiblePurposes":[],"specialPurposes":[1,2],"features":[1],"specialFeatures":[],"policyUrl":"https://kayzen.io/data-privacy-policy"},"527":{"id":527,"name":"Jampp LTD","purposes":[1,2,4,7,9,10],"legIntPurposes":[],"flexiblePurposes":[],"specialPurposes":[],"features":[],"specialFeatures":[],"policyUrl":"https://jampp.com/privacy.html"},"535":{"id":535,"name":"INNITY","purposes":[1,2,4,5,6,7,8,9,10],"legIntPurposes":[],"flexiblePurposes":[],"specialPurposes":[1,2],"features":[1,2],"specialFeatures":[],"policyUrl":"https://www.innity.com/privacy-policy.php"},"530":{"id":530,"name":"Near Pte Ltd","purposes":[1,2,3,4,5,6,7,9,10],"legIntPurposes":[],"flexiblePurposes":[2,3,4,5,6,7,9,10],"specialPurposes":[],"features":[1,2],"specialFeatures":[1],"policyUrl":"https://near.co/privacy","overflow":{"httpGetLimit":128}},"539":{"id":539,"name":"AdDefend GmbH","purposes":[1],"legIntPurposes":[2,3,4,7],"flexiblePurposes":[2,3,4,7],"specialPurposes":[1,2],"features":[3],"specialFeatures":[],"policyUrl":"https://www.addefend.com/en/privacy-policy/"},"501":{"id":501,"name":"Alliance Gravity Data Media","purposes":[1,2,3,4,7,9],"legIntPurposes":[],"flexiblePurposes":[],"specialPurposes":[],"features":[1,2],"specialFeatures":[],"policyUrl":"https://www.alliancegravity.com/politiquedeprotectiondesdonneespersonnelles"},"531":{"id":531,"name":"Smartclip Hispania SL","purposes":[1,2,3,4,7,8,9,10],"legIntPurposes":[],"flexiblePurposes":[],"specialPurposes":[],"features":[2,3],"specialFeatures":[1],"policyUrl":"http://rgpd-smartclip.com/"},"536":{"id":536,"name":"GlobalWebIndex","purposes":[1,7,8,9],"legIntPurposes":[],"flexiblePurposes":[],"specialPurposes":[],"features":[1,2,3],"specialFeatures":[],"policyUrl":"http://legal.trendstream.net/non-panellist_privacy_policy"},"544":{"id":544,"name":"Kochava Inc.","purposes":[],"legIntPurposes":[7],"flexiblePurposes":[],"specialPurposes":[],"features":[1,2,3],"specialFeatures":[1,2],"policyUrl":"https://www.kochava.com/support-privacy/"},"543":{"id":543,"name":"PaperG, Inc. dba Thunder Industries","purposes":[1,3,4,5,6],"legIntPurposes":[2,7,8],"flexiblePurposes":[],"specialPurposes":[],"features":[],"specialFeatures":[],"policyUrl":"https://www.makethunder.com/privacy"},"546":{"id":546,"name":"Smart Traffik","purposes":[1,8],"legIntPurposes":[7],"flexiblePurposes":[7,8],"specialPurposes":[],"features":[1,2,3],"specialFeatures":[1,2],"policyUrl":"https://okube-attribution.com/politique-de-confidentialite/"},"545":{"id":545,"name":"Reignn Platform Ltd","purposes":[1,2,3,4,7,8,10],"legIntPurposes":[],"flexiblePurposes":[],"specialPurposes":[1,2],"features":[],"specialFeatures":[2],"policyUrl":"http://reignn.com/user-privacy-policy"},"439":{"id":439,"name":"Bit Q Holdings Limited","purposes":[1,7,9],"legIntPurposes":[],"flexiblePurposes":[],"specialPurposes":[],"features":[3],"specialFeatures":[1],"policyUrl":"https://www.rippll.com/privacy"},"553":{"id":553,"name":"Adhese","purposes":[1,2,3,4,7,9],"legIntPurposes":[],"flexiblePurposes":[],"specialPurposes":[1,2],"features":[1,2],"specialFeatures":[1],"policyUrl":"https://adhese.com/privacy-and-cookie-policy"},"556":{"id":556,"name":"adhood.com","purposes":[1,2,3,4,5,6,7,8,9,10],"legIntPurposes":[],"flexiblePurposes":[],"specialPurposes":[],"features":[],"specialFeatures":[1],"policyUrl":"http://v3.adhood.com/en/site/politikavekurallar/gizlilik.php?lang=en"},"550":{"id":550,"name":"Happydemics","purposes":[7],"legIntPurposes":[],"flexiblePurposes":[],"specialPurposes":[],"features":[1,3],"specialFeatures":[],"policyUrl":"https://www.iubenda.com/privacy-policy/69056167/full-legal"},"554":{"id":554,"name":"RMSi Radio Marketing Service interactive GmbH","purposes":[1,3,4],"legIntPurposes":[2,7,9],"flexiblePurposes":[2],"specialPurposes":[1,2],"features":[1,2,3],"specialFeatures":[1,2],"policyUrl":"https://www.rms.de/datenschutz/"},"498":{"id":498,"name":"Mediakeys Platform","purposes":[1,6,10],"legIntPurposes":[2,3,4,7,9],"flexiblePurposes":[2,3,4,9],"specialPurposes":[1,2],"features":[1,2,3],"specialFeatures":[1],"policyUrl":"https://drbanner.com/privacypolicy_en/"},"565":{"id":565,"name":"Adobe Audience Manager","purposes":[1,10],"legIntPurposes":[],"flexiblePurposes":[],"specialPurposes":[1],"features":[],"specialFeatures":[],"policyUrl":"https://www.adobe.com/privacy/policy.html"},"571":{"id":571,"name":"ViewPay","purposes":[1,2,4,5,6,7,8,9,10],"legIntPurposes":[],"flexiblePurposes":[2,4,5,6,7,8,9,10],"specialPurposes":[],"features":[3],"specialFeatures":[],"policyUrl":"http://viewpay.tv/mentions-legales/"},"568":{"id":568,"name":"Jointag S.r.l.","purposes":[1,2,3,4,5,6,7,8],"legIntPurposes":[],"flexiblePurposes":[],"specialPurposes":[],"features":[3],"specialFeatures":[1,2],"policyUrl":"https://www.jointag.com/privacy/kariboo/publisher/third/"},"570":{"id":570,"name":"Czech Publisher Exchange z.s.p.o.","purposes":[1,2,3,4,5,6,7,8,9,10],"legIntPurposes":[],"flexiblePurposes":[2,3,4,5,6,7,8,9,10],"specialPurposes":[1,2],"features":[1,2,3],"specialFeatures":[],"policyUrl":"https://www.cpex.cz/pro-uzivatele/ochrana-soukromi/"},"559":{"id":559,"name":"Otto (GmbH & Co KG)","purposes":[1],"legIntPurposes":[2,3,4,7,9,10],"flexiblePurposes":[2,3,4,7,9,10],"specialPurposes":[1,2],"features":[],"specialFeatures":[],"policyUrl":"https://www.otto.de/shoppages/service/datenschutz"},"569":{"id":569,"name":"Kairos Fire","purposes":[1,7,8,9,10],"legIntPurposes":[],"flexiblePurposes":[],"specialPurposes":[],"features":[],"specialFeatures":[1],"policyUrl":"https://www.kairosfire.com/privacy"},"577":{"id":577,"name":"Neustar on behalf of The Procter & Gamble Company","purposes":[1,2,3,4,6,9],"legIntPurposes":[5,7,8],"flexiblePurposes":[2,3,4,5,6,7,8,9],"specialPurposes":[],"features":[1,2,3],"specialFeatures":[],"policyUrl":"https://www.pg.com/privacy/english/privacy_statement.shtml"},"590":{"id":590,"name":"Sourcepoint Technologies, Inc.","purposes":[],"legIntPurposes":[6,8],"flexiblePurposes":[],"specialPurposes":[],"features":[],"specialFeatures":[],"policyUrl":"https://www.sourcepoint.com/privacy-policy"},"587":{"id":587,"name":"Localsensor B.V.","purposes":[1,2,3,4,7,10],"legIntPurposes":[],"flexiblePurposes":[2,3,4,7,10],"specialPurposes":[1,2],"features":[],"specialFeatures":[],"policyUrl":"https://www.localsensor.com/privacy.html"},"580":{"id":580,"name":"Goldbach Group AG","purposes":[1],"legIntPurposes":[2,3,4,7,8,9,10],"flexiblePurposes":[2,3,4,7,8,9,10],"specialPurposes":[1,2],"features":[1,2],"specialFeatures":[1],"policyUrl":"https://goldbach.com/ch/de/datenschutz"},"593":{"id":593,"name":"Programatica de publicidad S.L.","purposes":[1,2,3,4,5,6,7,8,9,10],"legIntPurposes":[],"flexiblePurposes":[2,3,4,5,6,7,8,9,10],"specialPurposes":[],"features":[1,2,3],"specialFeatures":[],"policyUrl":"https://datmean.com/politica-privacidad/"},"574":{"id":574,"name":"Realeyes OU","purposes":[1,7,8,9,10],"legIntPurposes":[],"flexiblePurposes":[],"specialPurposes":[1,2],"features":[1],"specialFeatures":[],"policyUrl":"https://realview.realeyesit.com/privacy"},"598":{"id":598,"name":"audio content & control GmbH","purposes":[1],"legIntPurposes":[2,7,9],"flexiblePurposes":[],"specialPurposes":[1,2],"features":[],"specialFeatures":[1],"policyUrl":"https://www.audio-cc.com/audiocc_privacy_policy.pdf"},"596":{"id":596,"name":"InsurAds Technologies SA.","purposes":[1,2,3,4,5,6,9,10],"legIntPurposes":[7,8],"flexiblePurposes":[],"specialPurposes":[1,2],"features":[],"specialFeatures":[1],"policyUrl":"https://www.insurads.com/privacy.html"},"549":{"id":549,"name":"Bandsintown Amplified LLC","purposes":[2,3,4,5,6,7,8,9,10],"legIntPurposes":[],"flexiblePurposes":[],"specialPurposes":[],"features":[],"specialFeatures":[],"policyUrl":"http://corp.bandsintown.com/privacy"},"584":{"id":584,"name":"Dynamic 1001 GmbH","purposes":[1,7,10],"legIntPurposes":[],"flexiblePurposes":[7,10],"specialPurposes":[2],"features":[3],"specialFeatures":[2],"policyUrl":"https://dynamic-tracking.com/Datenschutz.aspx"},"601":{"id":601,"name":"WebAds B.V","purposes":[1,2],"legIntPurposes":[],"flexiblePurposes":[],"specialPurposes":[2],"features":[],"specialFeatures":[],"policyUrl":"https://privacy.webads.eu/"},"599":{"id":599,"name":"Maximus Live LLC","purposes":[],"legIntPurposes":[7,8],"flexiblePurposes":[],"specialPurposes":[1],"features":[],"specialFeatures":[1],"policyUrl":"https://maximusx.com/privacy-policy/"},"606":{"id":606,"name":"Impactify ","purposes":[1,2,3,4,5,6,7,8,9,10],"legIntPurposes":[],"flexiblePurposes":[2,3,4,5,6,7,8,9,10],"specialPurposes":[2],"features":[],"specialFeatures":[],"policyUrl":"https://impactify.io/privacy-policy/"},"602":{"id":602,"name":"Online Solution Int Limited","purposes":[1,2,3,4,7,8,9,10],"legIntPurposes":[],"flexiblePurposes":[2,3,4,7,8,9,10],"specialPurposes":[1,2],"features":[1,2],"specialFeatures":[1],"policyUrl":"https://adsafety.net/privacy.html","overflow":{"httpGetLimit":32}},"612":{"id":612,"name":"Adnami Aps","purposes":[],"legIntPurposes":[],"flexiblePurposes":[],"specialPurposes":[1,2],"features":[],"specialFeatures":[],"policyUrl":"www.adnami.io/privacy"},"591":{"id":591,"name":"Consumable, Inc.","purposes":[1,2,4,7],"legIntPurposes":[],"flexiblePurposes":[],"specialPurposes":[2],"features":[],"specialFeatures":[],"policyUrl":"http://consumable.com/privacy-policy.html"},"614":{"id":614,"name":"Market Resource Partners LLC","purposes":[1,2,3,4,5,6,7,8,9,10],"legIntPurposes":[],"flexiblePurposes":[],"specialPurposes":[1,2],"features":[3],"specialFeatures":[2],"policyUrl":"https://www.mrpfd.com/privacy-policy/"},"615":{"id":615,"name":"Adsolutions BV","purposes":[],"legIntPurposes":[],"flexiblePurposes":[],"specialPurposes":[1,2],"features":[],"specialFeatures":[],"policyUrl":"https://www.adsolutions.com/privacy-policy/"},"607":{"id":607,"name":"ucfunnel Co., Ltd.","purposes":[1,2,3,4,5,6,7,8,9,10],"legIntPurposes":[],"flexiblePurposes":[],"specialPurposes":[1,2],"features":[2,3],"specialFeatures":[1],"policyUrl":"https://www.ucfunnel.com/privacy-policy"},"609":{"id":609,"name":"Predicio","purposes":[1,2,3,4,5,6,7,8,9,10],"legIntPurposes":[],"flexiblePurposes":[],"specialPurposes":[1,2],"features":[1,2,3],"specialFeatures":[1,2],"policyUrl":"http://www.predic.io/privacy","overflow":{"httpGetLimit":128}},"617":{"id":617,"name":"Onfocus (Adagio)","purposes":[1,2,7,8],"legIntPurposes":[],"flexiblePurposes":[],"specialPurposes":[],"features":[],"specialFeatures":[1],"policyUrl":"https://adagio.io/privacy"},"620":{"id":620,"name":"Blue","purposes":[1],"legIntPurposes":[2,3,4,5,6,7,8,9,10],"flexiblePurposes":[2,3,4,5,6,7,8,9,10],"specialPurposes":[1,2],"features":[2,3],"specialFeatures":[1],"policyUrl":"http://www.getblue.io/privacy/"},"610":{"id":610,"name":"Azerion Holding B.V.","purposes":[1,3,4,9],"legIntPurposes":[2,5,6,7,8,10],"flexiblePurposes":[2,5,6],"specialPurposes":[1,2],"features":[2,3],"specialFeatures":[1],"policyUrl":"https://azerion.com/business/privacy.html","overflow":{"httpGetLimit":128}},"621":{"id":621,"name":"Seznam.cz, a.s.","purposes":[1,3,4,5,6],"legIntPurposes":[2,7,8,9,10],"flexiblePurposes":[],"specialPurposes":[],"features":[2,3],"specialFeatures":[1,2],"policyUrl":"https://www.seznam.cz/ochranaudaju"},"624":{"id":624,"name":"Norstat AS","purposes":[1,9],"legIntPurposes":[],"flexiblePurposes":[],"specialPurposes":[],"features":[1,2,3],"specialFeatures":[],"policyUrl":"https://www.norstatpanel.com/en/data-protection"},"95":{"id":95,"name":"Lotame Solutions, inc","purposes":[1,3,5],"legIntPurposes":[7,8,9,10],"flexiblePurposes":[],"specialPurposes":[],"features":[2,3],"specialFeatures":[],"policyUrl":"https://www.lotame.com/about-lotame/privacy/lotame-corporate-websites-privacy-policy/"},"618":{"id":618,"name":"BEINTOO SPA","purposes":[1,2,9,10],"legIntPurposes":[],"flexiblePurposes":[],"specialPurposes":[1,2],"features":[1],"specialFeatures":[1],"policyUrl":"http://www.beintoo.com/privacy-cookie-policy/"},"625":{"id":625,"name":"BILENDI SA","purposes":[1,6,7,8,9],"legIntPurposes":[],"flexiblePurposes":[],"specialPurposes":[],"features":[1],"specialFeatures":[],"policyUrl":"https://www.maximiles.com/privacy-policy"},"628":{"id":628,"name":": Tappx","purposes":[1,2,4,7,10],"legIntPurposes":[],"flexiblePurposes":[],"specialPurposes":[1,2],"features":[2],"specialFeatures":[1,2],"policyUrl":"https://www.tappx.com/en/privacy-policy/"},"630":{"id":630,"name":"Contact Impact GmbH","purposes":[1],"legIntPurposes":[2,3,4,7,10],"flexiblePurposes":[2,3,4,7,10],"specialPurposes":[1,2],"features":[3],"specialFeatures":[],"policyUrl":"https://contactimpact.de/privacy"},"626":{"id":626,"name":"Hivestack Inc.","purposes":[1,7,9,10],"legIntPurposes":[],"flexiblePurposes":[],"specialPurposes":[],"features":[],"specialFeatures":[1],"policyUrl":"https://hivestack.com/privacy-policy"},"631":{"id":631,"name":"Relay42 Netherlands B.V.","purposes":[1,2,3,4,5,6,7,8,9,10],"legIntPurposes":[],"flexiblePurposes":[],"specialPurposes":[2],"features":[],"specialFeatures":[],"policyUrl":"https://relay42.com/privacy"},"638":{"id":638,"name":"Passendo Aps","purposes":[1,2,4,7],"legIntPurposes":[],"flexiblePurposes":[],"specialPurposes":[],"features":[],"specialFeatures":[],"policyUrl":"https://passendo.com/users-privacy-policy"},"644":{"id":644,"name":"Gamoshi LTD","purposes":[2,7],"legIntPurposes":[],"flexiblePurposes":[2,7],"specialPurposes":[2],"features":[3],"specialFeatures":[],"policyUrl":"https://www.gamoshi.com/privacy-policy"},"639":{"id":639,"name":"Smile Wanted Group","purposes":[1,2,3,4,5,6,7,8,9,10],"legIntPurposes":[],"flexiblePurposes":[],"specialPurposes":[],"features":[],"specialFeatures":[2],"policyUrl":"https://www.smilewanted.com/privacy.php"},"645":{"id":645,"name":"Noster Finance S.L.","purposes":[1,2,3,4,5,6,9,10],"legIntPurposes":[7,8],"flexiblePurposes":[],"specialPurposes":[],"features":[1,2,3],"specialFeatures":[1,2],"policyUrl":"https://www.finect.com/terminos-legales/politica-de-cookies"},"653":{"id":653,"name":"Smartme Analytics","purposes":[7,8,9],"legIntPurposes":[],"flexiblePurposes":[],"specialPurposes":[],"features":[1,3],"specialFeatures":[],"policyUrl":"http://smartmeapp.com/info/smartme/aviso_legal.php","deletedDate":"2020-07-03T00:00:00Z"},"613":{"id":613,"name":"Adserve.zone / Artworx AS","purposes":[1],"legIntPurposes":[2,7],"flexiblePurposes":[2],"specialPurposes":[1,2],"features":[],"specialFeatures":[],"policyUrl":"http://adserve.zone/adserveprivacypolicy.html"},"573":{"id":573,"name":"Dailymotion SA","purposes":[1,3,4],"legIntPurposes":[2,5,6,7,8,10],"flexiblePurposes":[],"specialPurposes":[1,2],"features":[2],"specialFeatures":[],"policyUrl":"https://www.dailymotion.com/legal/privacy","overflow":{"httpGetLimit":32}},"652":{"id":652,"name":"Skaze","purposes":[1,2,3,4,5,6,7,8,9,10],"legIntPurposes":[],"flexiblePurposes":[],"specialPurposes":[],"features":[1,2,3],"specialFeatures":[1],"policyUrl":"http://www.skaze.fr/rgpd/"},"646":{"id":646,"name":"Notify","purposes":[],"legIntPurposes":[],"flexiblePurposes":[],"specialPurposes":[],"features":[1],"specialFeatures":[],"policyUrl":"https://notify-group.com/en/mentions-legales/"},"648":{"id":648,"name":"TrueData Solutions, Inc.","purposes":[1,2,3,4,5,6,7,8,9,10],"legIntPurposes":[],"flexiblePurposes":[],"specialPurposes":[],"features":[1,2,3],"specialFeatures":[1,2],"policyUrl":"https://www.truedata.co/privacy-policy/"},"647":{"id":647,"name":"Axel Springer Teaser Ad GmbH","purposes":[1],"legIntPurposes":[2,3,4,7,10],"flexiblePurposes":[2,3,4,7,10],"specialPurposes":[1,2],"features":[3],"specialFeatures":[],"policyUrl":"https://www.adup-tech.com/privacy"},"659":{"id":659,"name":"Research and Analysis of Media in Sweden AB","purposes":[1],"legIntPurposes":[7,8,9],"flexiblePurposes":[],"specialPurposes":[],"features":[2],"specialFeatures":[],"policyUrl":"https://www2.rampanel.com/privacy-policy/"},"656":{"id":656,"name":"Think Clever Media","purposes":[1,2,3,4,5,6,9],"legIntPurposes":[7,8,10],"flexiblePurposes":[],"specialPurposes":[1,2],"features":[],"specialFeatures":[],"policyUrl":"https://www.contentignite.com/privacy-policy/"},"657":{"id":657,"name":"GP One GmbH","purposes":[1],"legIntPurposes":[2,3,4],"flexiblePurposes":[2,3,4],"specialPurposes":[1,2],"features":[],"specialFeatures":[1,2],"policyUrl":"https://www.gsi-one.org/de/privacy-policy.html"},"655":{"id":655,"name":"Sportradar AG","purposes":[1,2,3,4,5,6,7,8,9,10],"legIntPurposes":[],"flexiblePurposes":[],"specialPurposes":[1,2],"features":[1,2,3],"specialFeatures":[1,2],"policyUrl":"https://www.sportradar.com/about-us/privacy/"},"662":{"id":662,"name":"SoundCast","purposes":[1,2,3,4,7,8,9,10],"legIntPurposes":[],"flexiblePurposes":[],"specialPurposes":[],"features":[],"specialFeatures":[1],"policyUrl":"https://soundcast.fm/en/data-privacy"},"665":{"id":665,"name":"Digital East GmbH","purposes":[2,5,6,7,8,9,10],"legIntPurposes":[],"flexiblePurposes":[2,5,6,7,8,9,10],"specialPurposes":[1,2],"features":[3],"specialFeatures":[1],"policyUrl":"https://www.digitaleast.mobi/en/legal/privacy-policy/"},"650":{"id":650,"name":"Telefonica Investigaci\u00f3n y Desarrollo S.A.U","purposes":[1,2,3,4,7,9,10],"legIntPurposes":[],"flexiblePurposes":[],"specialPurposes":[1,2],"features":[],"specialFeatures":[1],"policyUrl":"http://www.cognitivemarketing.tid.es/"},"666":{"id":666,"name":"BeOp","purposes":[1,2],"legIntPurposes":[7,8,10],"flexiblePurposes":[2,7,8,10],"specialPurposes":[1,2],"features":[3],"specialFeatures":[],"policyUrl":"https://beop.io/privacy"},"663":{"id":663,"name":"Mobsuccess","purposes":[1,2,3,4,7,9],"legIntPurposes":[],"flexiblePurposes":[2,7],"specialPurposes":[1,2],"features":[1],"specialFeatures":[],"policyUrl":"https://www.mobsuccess.com/en/privacy"},"658":{"id":658,"name":"BLIINK SAS","purposes":[1,2,3,4,7,8,9,10],"legIntPurposes":[],"flexiblePurposes":[2,3,4,7,8,9,10],"specialPurposes":[2],"features":[],"specialFeatures":[1],"policyUrl":"https://bliink.io/privacy-policy"},"667":{"id":667,"name":"Liftoff Mobile, Inc.","purposes":[1,3,4],"legIntPurposes":[2,5,6,7,8,10],"flexiblePurposes":[2,3,4,5,6,7,8,10],"specialPurposes":[1,2],"features":[3],"specialFeatures":[1],"policyUrl":"https://liftoff.io/privacy-policy/"},"668":{"id":668,"name":"WhatRocks Inc. ","purposes":[1,2,3,4,5,6,7,8,9,10],"legIntPurposes":[],"flexiblePurposes":[],"specialPurposes":[],"features":[2],"specialFeatures":[1,2],"policyUrl":"https://www.whatrocks.co/en/privacy-policy "},"674":{"id":674,"name":"Duration Media, LLC.","purposes":[1,2,3,4,5,6,7,8,10],"legIntPurposes":[],"flexiblePurposes":[],"specialPurposes":[],"features":[],"specialFeatures":[],"policyUrl":"https://www.durationmedia.net/privacy-policy"},"675":{"id":675,"name":"Instreamatic inc.","purposes":[2,3,4,7],"legIntPurposes":[],"flexiblePurposes":[],"specialPurposes":[2],"features":[3],"specialFeatures":[],"policyUrl":"http://instreamatic.com/privacy-policy/"},"676":{"id":676,"name":"BusinessClick","purposes":[1,2,3,4,5,6,7,8,9,10],"legIntPurposes":[],"flexiblePurposes":[],"specialPurposes":[1,2],"features":[1,2],"specialFeatures":[1],"policyUrl":"https://www.businessclick.com/documents/RegulaminProgramuBusinessClick-2019.pdf"},"672":{"id":672,"name":"Cedato Technologies Ltd","purposes":[1,2],"legIntPurposes":[],"flexiblePurposes":[],"specialPurposes":[],"features":[],"specialFeatures":[],"policyUrl":"https://www.cedato.com/privacy-policy/"},"664":{"id":664,"name":"adMarketplace, Inc.","purposes":[1,2,3,4],"legIntPurposes":[7,10],"flexiblePurposes":[],"specialPurposes":[1,2],"features":[1,2,3],"specialFeatures":[],"policyUrl":"https://www.admarketplace.com/privacy-policy/"},"561":{"id":561,"name":"AuDigent","purposes":[1,2,3,4,9],"legIntPurposes":[],"flexiblePurposes":[],"specialPurposes":[],"features":[2,3],"specialFeatures":[],"policyUrl":"http://audigent.com/platform-privacy-policy"},"682":{"id":682,"name":"Radio Net Media Limited","purposes":[1,2,3,4],"legIntPurposes":[7],"flexiblePurposes":[],"specialPurposes":[],"features":[1,2,3],"specialFeatures":[1,2],"policyUrl":"https://www.adtonos.com/service-privacy-policy/","overflow":{"httpGetLimit":128}},"684":{"id":684,"name":"Blue Billywig BV","purposes":[],"legIntPurposes":[7],"flexiblePurposes":[7],"specialPurposes":[2],"features":[],"specialFeatures":[],"policyUrl":"https://www.bluebillywig.com/privacy-statement/"},"686":{"id":686,"name":"The MediaGrid Inc.","purposes":[1,2,3,4,5,6,7,8,9,10],"legIntPurposes":[],"flexiblePurposes":[],"specialPurposes":[],"features":[1,2],"specialFeatures":[],"policyUrl":"https://www.themediagrid.com/privacy-policy/"},"685":{"id":685,"name":"Arkeero","purposes":[1,2,3,4,5,6,7,8,9,10],"legIntPurposes":[],"flexiblePurposes":[],"specialPurposes":[],"features":[1,2,3],"specialFeatures":[1,2],"policyUrl":"https://arkeero.com/privacy-2/"},"687":{"id":687,"name":"MISSENA","purposes":[1,2,3,4,5,6,7,8],"legIntPurposes":[],"flexiblePurposes":[2,7],"specialPurposes":[2],"features":[],"specialFeatures":[],"policyUrl":"http://missena.com/confidentialite/"},"690":{"id":690,"name":"Go.pl sp. z o.o.","purposes":[1,2,3,4],"legIntPurposes":[],"flexiblePurposes":[],"specialPurposes":[],"features":[],"specialFeatures":[1],"policyUrl":"https://go.pl/polityka-prywatnosci/"},"691":{"id":691,"name":"Lifesight Pte. Ltd.","purposes":[2,3,4,5,6,7,8,9,10],"legIntPurposes":[],"flexiblePurposes":[],"specialPurposes":[],"features":[],"specialFeatures":[],"policyUrl":"https://www.lifesight.io/privacy-policy/"},"697":{"id":697,"name":"ADWAYS SAS","purposes":[],"legIntPurposes":[7],"flexiblePurposes":[],"specialPurposes":[2],"features":[],"specialFeatures":[],"policyUrl":"https://www.adways.com/confidentialite/?lang=en"},"699":{"id":699,"name":"HyperTV Inc.","purposes":[1,2,4,9],"legIntPurposes":[7,10],"flexiblePurposes":[],"specialPurposes":[2],"features":[1],"specialFeatures":[],"policyUrl":"https://www.hypertvx.com/privacy/"},"703":{"id":703,"name":"MindTake Research GmbH","purposes":[1,7,8,9,10],"legIntPurposes":[],"flexiblePurposes":[],"specialPurposes":[1],"features":[2,3],"specialFeatures":[],"policyUrl":"https://www.mindtake.com/en/reppublika-privacy-policy"},"706":{"id":706,"name":"VRTCAL Markets Inc","purposes":[],"legIntPurposes":[2],"flexiblePurposes":[],"specialPurposes":[1,2],"features":[],"specialFeatures":[1],"policyUrl":"https://vrtcal.com/docs/PrivacyPolicy-Advertising.pdf"},"681":{"id":681,"name":"MyTraffic","purposes":[1,9],"legIntPurposes":[],"flexiblePurposes":[9],"specialPurposes":[],"features":[],"specialFeatures":[1],"policyUrl":"https://www.mytraffic.io/en/privacy"},"649":{"id":649,"name":"adality GmbH","purposes":[],"legIntPurposes":[2],"flexiblePurposes":[],"specialPurposes":[],"features":[1],"specialFeatures":[],"policyUrl":"https://adality.de/en/privacy/"},"711":{"id":711,"name":"SITU8ED SA","purposes":[1,3,4,5,6,7,8,10],"legIntPurposes":[],"flexiblePurposes":[],"specialPurposes":[],"features":[3],"specialFeatures":[1],"policyUrl":"https://www.situ8ed.com/privacy-policy/"},"712":{"id":712,"name":"Inspired Mobile Limited","purposes":[1,2,3,4,5,6,7,8,9,10],"legIntPurposes":[],"flexiblePurposes":[],"specialPurposes":[1,2],"features":[1,2,3],"specialFeatures":[1,2],"policyUrl":"https://byinspired.com/privacypolicy.pdf"},"688":{"id":688,"name":"Effinity","purposes":[],"legIntPurposes":[2],"flexiblePurposes":[2,7],"specialPurposes":[],"features":[],"specialFeatures":[],"policyUrl":"https://www.effiliation.com/politique-de-confidentialite/","overflow":{"httpGetLimit":128}},"702":{"id":702,"name":"Kwanko","purposes":[1,2,7,8],"legIntPurposes":[],"flexiblePurposes":[2,7,8],"specialPurposes":[1,2],"features":[3],"specialFeatures":[],"policyUrl":"https://www.kwanko.com/fr/rgpd/"},"714":{"id":714,"name":"Survata Inc.","purposes":[1],"legIntPurposes":[7,9],"flexiblePurposes":[],"specialPurposes":[],"features":[],"specialFeatures":[],"policyUrl":"https://www.survata.com/respondent-privacy-policy/","overflow":{"httpGetLimit":128}},"713":{"id":713,"name":"Dataseat Ltd","purposes":[2,3,4,5,6,7,8,9],"legIntPurposes":[],"flexiblePurposes":[2,7,8],"specialPurposes":[],"features":[3],"specialFeatures":[],"policyUrl":"https://dataseat.com/privacy-policy"},"716":{"id":716,"name":"OnAudience Ltd","purposes":[1,2,3,4,5,6,7,8,9,10],"legIntPurposes":[],"flexiblePurposes":[],"specialPurposes":[1,2],"features":[1,2,3],"specialFeatures":[1],"policyUrl":"https://www.onaudience.com/internet-advertising-privacy-policy"},"708":{"id":708,"name":"Dugout Limited ","purposes":[1,2,3,4,5,6,7,8,9,10],"legIntPurposes":[],"flexiblePurposes":[2,3,4,5,6,7,8,9,10],"specialPurposes":[],"features":[1,2,3],"specialFeatures":[1,2],"policyUrl":"https://dugout.com/privacy-policy"},"694":{"id":694,"name":"Snapupp Technologies SL","purposes":[2,3,4,5,6,9],"legIntPurposes":[7,8,10],"flexiblePurposes":[10],"specialPurposes":[],"features":[3],"specialFeatures":[],"policyUrl":"https://www.enterprise.noddus.com/privacy-policy","overflow":{"httpGetLimit":128}},"683":{"id":683,"name":"Cookie Market LTD","purposes":[1,3,4,9],"legIntPurposes":[],"flexiblePurposes":[],"specialPurposes":[],"features":[2,3],"specialFeatures":[1],"policyUrl":"http://cookie.market/privacyPolicy.php"},"720":{"id":720,"name":"AAX LLC","purposes":[1,3,4],"legIntPurposes":[2,7,10],"flexiblePurposes":[],"specialPurposes":[1,2],"features":[3],"specialFeatures":[],"policyUrl":"https://aax.media/privacy/","overflow":{"httpGetLimit":32}},"678":{"id":678,"name":"Axonix LTD","purposes":[2],"legIntPurposes":[7,10],"flexiblePurposes":[2],"specialPurposes":[1,2],"features":[3],"specialFeatures":[1],"policyUrl":"https://axonix.com/privacy-cookie-policy/","overflow":{"httpGetLimit":128}},"719":{"id":719,"name":"Online Advertising Network Sp. z o.o.","purposes":[1,2,3,4,7,9,10],"legIntPurposes":[],"flexiblePurposes":[],"specialPurposes":[1,2],"features":[2,3],"specialFeatures":[1],"policyUrl":"https://www.oan.pl/en/privacy-policy"},"707":{"id":707,"name":"Dentsu Aegis Network Italia SpA","purposes":[1,2,3,4,7,9,10],"legIntPurposes":[],"flexiblePurposes":[],"specialPurposes":[1],"features":[1,2,3],"specialFeatures":[1,2],"policyUrl":"https://www.dentsuaegisnetwork.com/it/it/policies/info-cookie"},"721":{"id":721,"name":"Beaconspark Ltd","purposes":[1,2,3,4,5,7],"legIntPurposes":[6,8],"flexiblePurposes":[2,3,4,5,6,7,8],"specialPurposes":[1,2],"features":[1],"specialFeatures":[],"policyUrl":"https://www.engageya.com/privacy"},"728":{"id":728,"name":"Appier PTE Ltd","purposes":[1,3,4,5,6,9],"legIntPurposes":[2,7,8,10],"flexiblePurposes":[2,7,8,9,10],"specialPurposes":[1,2],"features":[1,2,3],"specialFeatures":[1],"policyUrl":"https://www.appier.com/privacy-policy/"},"729":{"id":729,"name":"Cavai AS & UK ","purposes":[],"legIntPurposes":[7,8],"flexiblePurposes":[7,8],"specialPurposes":[],"features":[],"specialFeatures":[],"policyUrl":"https://cav.ai/privacy-policy/"},"730":{"id":730,"name":"INFOnline GmbH","purposes":[],"legIntPurposes":[8],"flexiblePurposes":[8],"specialPurposes":[],"features":[],"specialFeatures":[],"policyUrl":"https://www.infonline.de/en/privacy-policy/"},"722":{"id":722,"name":"agof - daily campaign facts","purposes":[1,7,9],"legIntPurposes":[],"flexiblePurposes":[],"specialPurposes":[1],"features":[],"specialFeatures":[],"policyUrl":"http://www.agof.de/datenschutz/"},"723":{"id":723,"name":"Adzymic Pte Ltd","purposes":[1,2,3,4,7,8],"legIntPurposes":[],"flexiblePurposes":[],"specialPurposes":[],"features":[2],"specialFeatures":[],"policyUrl":"http://www.adzymic.co/privacy","overflow":{"httpGetLimit":128}},"725":{"id":725,"name":"Pubfinity LLC","purposes":[1,2,3,4,5,6,7,8,9,10],"legIntPurposes":[],"flexiblePurposes":[],"specialPurposes":[1,2],"features":[2,3],"specialFeatures":[],"policyUrl":"https://pubfinity.com/privacy-policy/","overflow":{"httpGetLimit":128}},"733":{"id":733,"name":"Anzu Virtual Reality LTD","purposes":[1,2,4,7,9,10],"legIntPurposes":[],"flexiblePurposes":[],"specialPurposes":[1],"features":[1],"specialFeatures":[1],"policyUrl":"https://anzu.io/privacy/"},"737":{"id":737,"name":"Monet Engine Inc","purposes":[1,2,7],"legIntPurposes":[],"flexiblePurposes":[],"specialPurposes":[],"features":[],"specialFeatures":[],"policyUrl":"https://appmonet.com/privacy-policy/"},"740":{"id":740,"name":"6Sense Insights, Inc.","purposes":[1],"legIntPurposes":[2,3,4,5,7,8,10],"flexiblePurposes":[2,3,4,5,7,8,10],"specialPurposes":[],"features":[1,2,3],"specialFeatures":[],"policyUrl":"https://6sense.com/privacy-policy/","overflow":{"httpGetLimit":128}},"744":{"id":744,"name":"Vidazoo Ltd","purposes":[3,4],"legIntPurposes":[2,7,8,10],"flexiblePurposes":[3,4],"specialPurposes":[1,2],"features":[2],"specialFeatures":[2],"policyUrl":"https://vidazoo.gitbook.io/vidazoo-legal/privacy-policy","overflow":{"httpGetLimit":128}},"731":{"id":731,"name":"GeistM Technologies LTD","purposes":[],"legIntPurposes":[],"flexiblePurposes":[],"specialPurposes":[],"features":[],"specialFeatures":[],"policyUrl":"https://www.geistm.com/privacy"},"741":{"id":741,"name":"Brand Advance Limited","purposes":[1,2,3,4,5,6,7,8,9,10],"legIntPurposes":[],"flexiblePurposes":[],"specialPurposes":[],"features":[2,3],"specialFeatures":[1,2],"policyUrl":"https://www.wearebrandadvance.com/website-privacy-policy"},"735":{"id":735,"name":"Deutsche Post AG","purposes":[1,7],"legIntPurposes":[],"flexiblePurposes":[],"specialPurposes":[],"features":[1],"specialFeatures":[],"policyUrl":"https://www.deutschepost.de/de/c/consentric/datenschutz.html"},"734":{"id":734,"name":"Cint AB","purposes":[1,7,8,9,10],"legIntPurposes":[],"flexiblePurposes":[],"specialPurposes":[],"features":[1],"specialFeatures":[],"policyUrl":"https://www.cint.com/participant-privacy-notice"},"709":{"id":709,"name":"NC Audience Exchange, LLC (NewsIQ)","purposes":[1,3,4,5],"legIntPurposes":[2,7,8,9,10],"flexiblePurposes":[2,3,4,5,7,8,9,10],"specialPurposes":[2],"features":[1,2,3],"specialFeatures":[],"policyUrl":"https://www.ncaudienceexchange.com/privacy/"},"739":{"id":739,"name":"Blingby LLC","purposes":[1,8,10],"legIntPurposes":[],"flexiblePurposes":[],"specialPurposes":[],"features":[],"specialFeatures":[],"policyUrl":"https://blingby.com/privacy"},"727":{"id":727,"name":"Pinpoll GmbH (Private Limited)","purposes":[1,2,3,4,5,6,7,8,9,10],"legIntPurposes":[],"flexiblePurposes":[],"specialPurposes":[1,2],"features":[1],"specialFeatures":[],"policyUrl":"https://www.pinpoll.com/#data_protection_declaration"},"732":{"id":732,"name":"Performax.cz, s.r.o.","purposes":[1,2,3,4,5,6,7,8,9,10],"legIntPurposes":[],"flexiblePurposes":[],"specialPurposes":[],"features":[2],"specialFeatures":[],"policyUrl":"https://reg.tiscali.cz/privacy-policy"},"736":{"id":736,"name":"BidMachine Inc.","purposes":[1,2,3,4,5,6],"legIntPurposes":[7,8,10],"flexiblePurposes":[7,8,10],"specialPurposes":[1,2],"features":[],"specialFeatures":[1],"policyUrl":"https://explorestack.com/privacy-policy/"},"738":{"id":738,"name":"adbility media GmbH","purposes":[2,3,4,9],"legIntPurposes":[7],"flexiblePurposes":[2,3,4,9],"specialPurposes":[1,2],"features":[1,2,3],"specialFeatures":[1,2],"policyUrl":"https://www.adbility-media.com/datenschutzerklaerung/"},"742":{"id":742,"name":"Audiencerate LTD","purposes":[1,2,3,5,6],"legIntPurposes":[],"flexiblePurposes":[],"specialPurposes":[],"features":[],"specialFeatures":[],"policyUrl":"https://www.audiencerate.com/privacy/"},"743":{"id":743,"name":"MOVIads Sp. z o.o. Sp. k.","purposes":[1,2,3,4,5,6,7,8,9,10],"legIntPurposes":[],"flexiblePurposes":[],"specialPurposes":[],"features":[2,3],"specialFeatures":[1],"policyUrl":"https://moviads.pl/polityka-prywatnosci/","overflow":{"httpGetLimit":128}},"745":{"id":745,"name":"Justtag Sp. z o.o.","purposes":[1,3,4,9],"legIntPurposes":[7],"flexiblePurposes":[],"specialPurposes":[1,2],"features":[1,2,3],"specialFeatures":[1],"policyUrl":"https://www.justtag.com/pdf/PRIVACY_POLICY_Koalametrics_english.pdf"},"746":{"id":746,"name":"Adxperience SAS","purposes":[4],"legIntPurposes":[2,7],"flexiblePurposes":[],"specialPurposes":[1,2],"features":[],"specialFeatures":[1],"policyUrl":"https://adxperience.com/privacy-policy/"},"747":{"id":747,"name":"Kairion GmbH","purposes":[1,2,3,4,5,6,7,8,9,10],"legIntPurposes":[],"flexiblePurposes":[2,3,4,5,6,7,8,9,10],"specialPurposes":[],"features":[2,3],"specialFeatures":[1,2],"policyUrl":"https://kairion.de/datenschutzbestimmungen/"},"748":{"id":748,"name":"AUDIOMOB LTD","purposes":[1,2,3,4,7,8,9],"legIntPurposes":[],"flexiblePurposes":[2,3,4,7,8,9],"specialPurposes":[1,2],"features":[1,2],"specialFeatures":[1],"policyUrl":"https://www.audiomob.io/privacy"},"749":{"id":749,"name":"Good-Loop Ltd","purposes":[1,3,4,5,6],"legIntPurposes":[2,7,8,9,10],"flexiblePurposes":[7,8,9,10],"specialPurposes":[1,2],"features":[],"specialFeatures":[],"policyUrl":"https://doc.good-loop.com/policy/privacy-policy.html"},"750":{"id":750,"name":"THE NEWCO S.R.L.","purposes":[1,2,3,4,5,6,7,8,9,10],"legIntPurposes":[],"flexiblePurposes":[2,3,4,5,6,7,8,9,10],"specialPurposes":[1,2],"features":[1,2,3],"specialFeatures":[1,2],"policyUrl":"https://www.thenewco.it/privacy_policy_servizi_prodotti.html"},"751":{"id":751,"name":"Kiosked Ltd","purposes":[],"legIntPurposes":[2,7],"flexiblePurposes":[2,7],"specialPurposes":[1,2],"features":[],"specialFeatures":[],"policyUrl":"https://kiosked.com/privacy-policy/"},"753":{"id":753,"name":"ScaleMonk Inc.","purposes":[1,2,3,4,7,9,10],"legIntPurposes":[],"flexiblePurposes":[2,3,4,7,9,10],"specialPurposes":[1,2],"features":[3],"specialFeatures":[],"policyUrl":"https://www.scalemonk.com/privacy-policy/index.html"},"754":{"id":754,"name":"DistroScale, Inc.","purposes":[1,2],"legIntPurposes":[],"flexiblePurposes":[2],"specialPurposes":[2],"features":[3],"specialFeatures":[],"policyUrl":"http://www.distroscale.com/privacy-policy/"},"757":{"id":757,"name":"UAB Meazy","purposes":[1,2,3,4,5,7,10],"legIntPurposes":[],"flexiblePurposes":[],"specialPurposes":[1,2],"features":[],"specialFeatures":[],"policyUrl":"https://meazy.co/privacy-policy"},"758":{"id":758,"name":"GfK Netherlands B.V.","purposes":[1,7,8,9],"legIntPurposes":[],"flexiblePurposes":[7,8,9],"specialPurposes":[],"features":[1],"specialFeatures":[],"policyUrl":"https://gfkpanel.nl/privacy"},"759":{"id":759,"name":"RevJet","purposes":[1,2,3,4,5,6,7,8,9,10],"legIntPurposes":[],"flexiblePurposes":[],"specialPurposes":[],"features":[1],"specialFeatures":[],"policyUrl":"https://www.revjet.com/privacy","overflow":{"httpGetLimit":128}},"760":{"id":760,"name":"VEXPRO TECHNOLOGIES LTD","purposes":[1,2,3,4,5,6,7,8,9,10],"legIntPurposes":[],"flexiblePurposes":[],"specialPurposes":[1,2],"features":[1,2,3],"specialFeatures":[2],"policyUrl":"https://onedash.com/privacy-policy.html"},"761":{"id":761,"name":"Digiseg ApS","purposes":[1,3,5,7,8,9],"legIntPurposes":[],"flexiblePurposes":[],"specialPurposes":[],"features":[1],"specialFeatures":[],"policyUrl":"https://digiseg.io/privacy-center/"},"762":{"id":762,"name":"Protected Media LTD","purposes":[1],"legIntPurposes":[3,5,7,8,9,10],"flexiblePurposes":[],"specialPurposes":[1],"features":[3],"specialFeatures":[],"policyUrl":"https://www.protected.media/privacy-policy/"},"764":{"id":764,"name":"Lucidity","purposes":[1,2,7,8,9,10],"legIntPurposes":[],"flexiblePurposes":[],"specialPurposes":[1,2],"features":[],"specialFeatures":[],"policyUrl":"https://golucidity.com/privacy-policy/"},"765":{"id":765,"name":"Grabit Interactive Media Inc dba KERV Interctive","purposes":[2,3,4,7,8,9,10],"legIntPurposes":[],"flexiblePurposes":[],"specialPurposes":[1,2],"features":[2],"specialFeatures":[],"policyUrl":"https://kervit.com/privacy-policy/"},"766":{"id":766,"name":"ADCELL | Firstlead GmbH","purposes":[1,2],"legIntPurposes":[],"flexiblePurposes":[2],"specialPurposes":[],"features":[],"specialFeatures":[],"policyUrl":"https://www.adcell.de/agb#sector_6"},"767":{"id":767,"name":"Clinch Labs LTD","purposes":[1,2,3,4,7,9,10],"legIntPurposes":[],"flexiblePurposes":[],"specialPurposes":[1,2],"features":[1,2,3],"specialFeatures":[1],"policyUrl":"https://clinch.co/pages/privacy.html"},"768":{"id":768,"name":"Global Media & Entertainment Limited","purposes":[1,2,3,4,7,9,10],"legIntPurposes":[],"flexiblePurposes":[],"specialPurposes":[1,2],"features":[1,2,3],"specialFeatures":[1,2],"policyUrl":"http://global.com/privacy-policy/"},"769":{"id":769,"name":"MEDIAMETRIE","purposes":[1,8],"legIntPurposes":[],"flexiblePurposes":[],"specialPurposes":[],"features":[],"specialFeatures":[],"policyUrl":"https://www.mediametrie.fr/fr/gestion-des-cookies"},"770":{"id":770,"name":"MARKETPERF CORP","purposes":[1],"legIntPurposes":[2,3,4,5,6,7,8,10],"flexiblePurposes":[2,3,4,5,6],"specialPurposes":[1,2],"features":[1,2,3],"specialFeatures":[],"policyUrl":"https://www.marketperf.com/assets/images/app/marketperf/pdf/privacy-policy.pdf"},"771":{"id":771,"name":"bam! interactive marketing GmbH ","purposes":[1,7,8,9,10],"legIntPurposes":[],"flexiblePurposes":[],"specialPurposes":[],"features":[3],"specialFeatures":[1,2],"policyUrl":"https://bam-interactive.de/privacy-policy/"},"772":{"id":772,"name":"Oracle Data Cloud - Moat","purposes":[],"legIntPurposes":[7,8,10],"flexiblePurposes":[],"specialPurposes":[1],"features":[],"specialFeatures":[],"policyUrl":"https://www.oracle.com/legal/privacy/services-privacy-policy.html"},"773":{"id":773,"name":"360e-com Sp. z o.o.","purposes":[1,2,3,4,7,9,10],"legIntPurposes":[],"flexiblePurposes":[],"specialPurposes":[],"features":[3],"specialFeatures":[1],"policyUrl":"https://www.clickonometrics.com/optout/"},"774":{"id":774,"name":"Wagawin GmbH","purposes":[1],"legIntPurposes":[2,7],"flexiblePurposes":[2],"specialPurposes":[1,2],"features":[],"specialFeatures":[],"policyUrl":"https://www.wagawin.com/privacy-en/#productprivacy"},"775":{"id":775,"name":"SelectMedia International LTD","purposes":[1,2],"legIntPurposes":[],"flexiblePurposes":[],"specialPurposes":[1,2],"features":[3],"specialFeatures":[],"policyUrl":"https://www.selectmedia.asia/terms-and-privacy/"},"776":{"id":776,"name":"Mars Media Group","purposes":[2],"legIntPurposes":[],"flexiblePurposes":[2],"specialPurposes":[],"features":[],"specialFeatures":[],"policyUrl":"https://pay-per-leads.com/terms"},"777":{"id":777,"name":"One Planet Only","purposes":[1],"legIntPurposes":[2,3,4,7],"flexiblePurposes":[2,3,4,7],"specialPurposes":[1,2],"features":[],"specialFeatures":[],"policyUrl":"https://oneplanetonly.com/files/PRIVACY%20POLICY.pdf","overflow":{"httpGetLimit":32}},"778":{"id":778,"name":"Discover-Tech ltd","purposes":[2,3,4,5,6,7,8,9],"legIntPurposes":[],"flexiblePurposes":[],"specialPurposes":[],"features":[],"specialFeatures":[1],"policyUrl":"https://discover-tech.io/dsp-privacy-policy/"},"779":{"id":779,"name":"Adtarget Medya A.S.","purposes":[1,7],"legIntPurposes":[],"flexiblePurposes":[],"specialPurposes":[],"features":[3],"specialFeatures":[1],"policyUrl":"https://adtarget.com.tr/adtarget-privacy-policy-2020.pdf"},"780":{"id":780,"name":"Aniview LTD","purposes":[1,2,7,8],"legIntPurposes":[],"flexiblePurposes":[],"specialPurposes":[2],"features":[],"specialFeatures":[],"policyUrl":"https://www.aniview.com/privacy-policy/"},"781":{"id":781,"name":"FeedAd GmbH","purposes":[1,3,4,5,6,8,9],"legIntPurposes":[2,7,10],"flexiblePurposes":[2,7,10],"specialPurposes":[1,2],"features":[2,3],"specialFeatures":[1,2],"policyUrl":"https://feedad.com/privacy/","overflow":{"httpGetLimit":128}},"782":{"id":782,"name":"AirGrid LTD","purposes":[1,3,5,7,8,9,10],"legIntPurposes":[],"flexiblePurposes":[],"specialPurposes":[],"features":[],"specialFeatures":[],"policyUrl":"airgid.io/privacy-policy"},"783":{"id":783,"name":"Audienzz AG","purposes":[1],"legIntPurposes":[2,3,4,5,6,7,8,9,10],"flexiblePurposes":[2,3,4,5,6,7,8,9,10],"specialPurposes":[1,2],"features":[1,2],"specialFeatures":[1],"policyUrl":"https://audienzz.ch/wp-content/uploads/2020/03/AGB_audienzz_2020.pdf"},"784":{"id":784,"name":"Nubo LTD","purposes":[],"legIntPurposes":[2],"flexiblePurposes":[],"specialPurposes":[1,2],"features":[],"specialFeatures":[],"policyUrl":"https://www.recod3.com/privacypolicy.php"},"785":{"id":785,"name":"agof - daily digital facts","purposes":[1,9],"legIntPurposes":[],"flexiblePurposes":[],"specialPurposes":[1],"features":[],"specialFeatures":[],"policyUrl":"http://www.agof.de/datenschutz/"},"755":{"id":755,"name":"Google Advertising Products","purposes":[1,3,4],"legIntPurposes":[2,5,6,7,9,10],"flexiblePurposes":[2,5,6,7,9,10],"specialPurposes":[1,2],"features":[1,2],"specialFeatures":[],"policyUrl":"https://policies.google.com/privacy"},"786":{"id":786,"name":"TargetVideo GmbH","purposes":[1,2,3,4],"legIntPurposes":[7,8,10],"flexiblePurposes":[2,3,4,7,8,10],"specialPurposes":[1,2],"features":[],"specialFeatures":[],"policyUrl":"https://www.target-video.com/datenschutz/"},"787":{"id":787,"name":"Resolution Media M\u00fcnchen GmbH","purposes":[1],"legIntPurposes":[],"flexiblePurposes":[],"specialPurposes":[1,2],"features":[],"specialFeatures":[],"policyUrl":"https://wwww.nonstoppartner.net"},"788":{"id":788,"name":"Ad Alliance GmbH","purposes":[1,2,3,4,5,6,7,8,9,10],"legIntPurposes":[],"flexiblePurposes":[],"specialPurposes":[],"features":[2],"specialFeatures":[1],"policyUrl":"https://www.ad-alliance.de/datenschutz/","overflow":{"httpGetLimit":128}},"789":{"id":789,"name":"IP Deutschland GmbH","purposes":[1,2,3,4,5,6,7,8,9,10],"legIntPurposes":[],"flexiblePurposes":[],"specialPurposes":[],"features":[2],"specialFeatures":[1],"policyUrl":"https://www.ip.de/lp/impressum/datenschutz.cfm","overflow":{"httpGetLimit":32}},"790":{"id":790,"name":"AdGear Technologies, Inc.","purposes":[1,3,4],"legIntPurposes":[2,7,9,10],"flexiblePurposes":[],"specialPurposes":[1,2],"features":[1,2,3],"specialFeatures":[],"policyUrl":"https://adgear.com/en/privacy"},"791":{"id":791,"name":"Media Square","purposes":[1,2],"legIntPurposes":[],"flexiblePurposes":[],"specialPurposes":[2],"features":[],"specialFeatures":[],"policyUrl":"http://www.mediasquare.fr/e-privacy/"},"792":{"id":792,"name":"BritePool Inc","purposes":[1],"legIntPurposes":[3,7,10],"flexiblePurposes":[3,7,10],"specialPurposes":[1],"features":[1,2],"specialFeatures":[],"policyUrl":"https://britepool.com/gdpr-privacy-notice"},"794":{"id":794,"name":"Kubient Inc. ","purposes":[1,2,3,4,5,6,7,8,9,10],"legIntPurposes":[],"flexiblePurposes":[],"specialPurposes":[1,2],"features":[2,3],"specialFeatures":[1,2],"policyUrl":"https://kubient.com/privacy-policy/"},"795":{"id":795,"name":"Factor Eleven GmbH","purposes":[1,2,3,4,7,9],"legIntPurposes":[],"flexiblePurposes":[],"specialPurposes":[1,2],"features":[3],"specialFeatures":[],"policyUrl":"https://www.factor-eleven.de/datenschutz/"},"796":{"id":796,"name":"EASY Marketing GmbH","purposes":[1,7],"legIntPurposes":[],"flexiblePurposes":[7],"specialPurposes":[1,2],"features":[3],"specialFeatures":[],"policyUrl":"https://easy-m.de/"},"797":{"id":797,"name":"Artefact Deutschland GmbH","purposes":[1,7],"legIntPurposes":[],"flexiblePurposes":[7],"specialPurposes":[1,2],"features":[2,3],"specialFeatures":[],"policyUrl":"https://aaa.artefact.com/privacy-policy.do"},"798":{"id":798,"name":"Adverticum cPlc.","purposes":[1,2,3,4,5,6,8,9,10],"legIntPurposes":[7],"flexiblePurposes":[2,3,4,5,6,7,8,9,10],"specialPurposes":[1,2],"features":[],"specialFeatures":[],"policyUrl":"https://adverticum.net/english/privacy-and-data-processing-information/"},"799":{"id":799,"name":"Adpone SL","purposes":[1,2,4,5,7,9],"legIntPurposes":[],"flexiblePurposes":[],"specialPurposes":[2],"features":[2],"specialFeatures":[],"policyUrl":"http://www.adpone.com/privacy-policy/"},"800":{"id":800,"name":"Reppublika- The Research Toolbox GmbH","purposes":[1,2,3,4,5,6,7,8,9,10],"legIntPurposes":[],"flexiblePurposes":[10],"specialPurposes":[1],"features":[2],"specialFeatures":[1],"policyUrl":"https://www.reppublika.com/privacy-policy"},"801":{"id":801,"name":"Bannernow, Inc.","purposes":[1,4],"legIntPurposes":[2,7],"flexiblePurposes":[],"specialPurposes":[1,2],"features":[3],"specialFeatures":[],"policyUrl":"https://bannernow.com/privacy"},"802":{"id":802,"name":"NOW GmbH","purposes":[1,3,4,7],"legIntPurposes":[2,5,6,8,9,10],"flexiblePurposes":[2,3,4,5,6,7,8,9,10],"specialPurposes":[1,2],"features":[1,2,3],"specialFeatures":[1,2],"policyUrl":"https://static.now-services.de/privacy/index.html"},"803":{"id":803,"name":"Click Tech Limited","purposes":[1,2],"legIntPurposes":[3],"flexiblePurposes":[],"specialPurposes":[1,2],"features":[1],"specialFeatures":[],"policyUrl":"https://en.yeahmobi.com/html/privacypolicy/","overflow":{"httpGetLimit":128}},"804":{"id":804,"name":"LinkedIn Ireland Unlimited Company","purposes":[1,3,4],"legIntPurposes":[2,7,10],"flexiblePurposes":[2,3,4,7,10],"specialPurposes":[1,2],"features":[],"specialFeatures":[],"policyUrl":"https://www.linkedin.com/legal/privacy-policy"},"805":{"id":805,"name":"LEESTEN INC","purposes":[1,2,3,4,5,6,7,8,9,10],"legIntPurposes":[],"flexiblePurposes":[],"specialPurposes":[1,2],"features":[],"specialFeatures":[1,2],"policyUrl":"https://www.leesten.io/privacy-policy"},"807":{"id":807,"name":"Moloco, Inc.","purposes":[1],"legIntPurposes":[2,3,4,7,8,9,10],"flexiblePurposes":[2,3,4,7,8,9,10],"specialPurposes":[1,2],"features":[3],"specialFeatures":[2],"policyUrl":"http://www.molocoads.com/private-policy.html"},"808":{"id":808,"name":"Pure Local Media GmbH","purposes":[],"legIntPurposes":[2,7,10],"flexiblePurposes":[],"specialPurposes":[1,2],"features":[],"specialFeatures":[],"policyUrl":"https://purelocalmedia.de/?page_id=593"},"809":{"id":809,"name":"adnanny.com SLU","purposes":[1,2,3,4,7],"legIntPurposes":[],"flexiblePurposes":[],"specialPurposes":[1,2],"features":[],"specialFeatures":[],"policyUrl":"http://adnanny.com/en/privacy/"},"811":{"id":811,"name":"iPROM","purposes":[1,2,3,4,5,6,7,8,9,10],"legIntPurposes":[],"flexiblePurposes":[],"specialPurposes":[1,2],"features":[],"specialFeatures":[],"policyUrl":"https://iprom.eu/privacy_policy/GDPR"},"793":{"id":793,"name":"Amazon Advertising","purposes":[1,2,3,4,7,9,10],"legIntPurposes":[],"flexiblePurposes":[2,3,4,7,9,10],"specialPurposes":[1,2],"features":[],"specialFeatures":[],"policyUrl":"https://www.amazon.co.uk/gp/help/customer/display.html?nodeId=201909010"}}} \ No newline at end of file diff --git a/iabgpp-extras-jackson/src/test/resources/vendorlist/v2/vendor-list.json b/iabgpp-extras-jackson/src/test/resources/vendorlist/v2/vendor-list.json new file mode 120000 index 00000000..1898b29f --- /dev/null +++ b/iabgpp-extras-jackson/src/test/resources/vendorlist/v2/vendor-list.json @@ -0,0 +1 @@ +vendor-list-v51.json \ No newline at end of file diff --git a/iabgpp-extras-jackson/src/test/resources/vendorlist/v3.0/purposes-fr.json b/iabgpp-extras-jackson/src/test/resources/vendorlist/v3.0/purposes-fr.json new file mode 100644 index 00000000..98cfa81b --- /dev/null +++ b/iabgpp-extras-jackson/src/test/resources/vendorlist/v3.0/purposes-fr.json @@ -0,0 +1 @@ +{"vendorListVersion":29,"lastUpdated":"2020-03-12T16:40:38Z","purposes":{"1":{"id":1,"name":"Stocker et/ou acc\u00e9der \u00e0 des informations stock\u00e9es sur un terminal","description":"Les cookies, identifiants de votre terminal ou autres informations peuvent \u00eatre stock\u00e9s ou consult\u00e9s sur votre terminal pour les finalit\u00e9s qui vous sont pr\u00e9sent\u00e9es.","descriptionLegal":"Les partenaires peuvent :\n* Stocker des informations et acc\u00e9der \u00e0 des informations stock\u00e9es sur le terminal, comme les cookies et les identifiants du terminal pr\u00e9sent\u00e9s \u00e0 un utilisateur.\n"},"2":{"id":2,"name":"S\u00e9lectionner des publicit\u00e9s standard","description":"Les publicit\u00e9s peuvent vous \u00eatre pr\u00e9sent\u00e9es en fonction du contenu \u00e9ditorial que vous consultez, de l\u2019application que vous utilisez, de votre localisation approximative, ou de votre type de terminal\n","descriptionLegal":"Pour s\u00e9lectionner des publicit\u00e9s standard, les partenaires peuvent :\n* Utiliser des informations en temps r\u00e9el sur le contexte dans lequel la publicit\u00e9 sera affich\u00e9e, pour afficher la publicit\u00e9, y compris des informations sur le contenu et le terminal, telles que : type de terminal et capacit\u00e9s, user agent, URL, adresse IP \n* Utiliser des donn\u00e9es de g\u00e9olocalisation non-pr\u00e9cises d\u2019un utilisateur\n* Contr\u00f4ler la fr\u00e9quence de diffusion des publicit\u00e9s \u00e0 un utilisateur.\n* D\u00e9finir l\u2019ordre dans lequel les publicit\u00e9s sont pr\u00e9sent\u00e9es \u00e0 un utilisateur.\n* Emp\u00eacher une publicit\u00e9 de s\u2019afficher dans un contexte \u00e9ditorial inadapt\u00e9 (dangereux pour la marque)\nLes partenaires ne peuvent pas :\n* Cr\u00e9er un profil publicitaire personnalis\u00e9 \u00e0 l\u2019aide de ces informations pour la s\u00e9lection de publicit\u00e9s futures sans base l\u00e9gale distincte. \nN.B. \u00ab Non-pr\u00e9cises \u00bb signifie qu\u2019une g\u00e9olocalisation approximative dans un rayon d\u2019au moins 500 m\u00e8tres est autoris\u00e9e.\n"},"3":{"id":3,"name":"Cr\u00e9er un profil personnalis\u00e9 de publicit\u00e9s","description":"Un profil peut \u00eatre cr\u00e9\u00e9 sur vous et sur vos centres d\u2019int\u00e9r\u00eat pour vous pr\u00e9senter des publicit\u00e9s personnalis\u00e9es susceptibles de vous int\u00e9resser.","descriptionLegal":"Pour cr\u00e9er un profil de publicit\u00e9s personnalis\u00e9es, les partenaires peuvent :\n* Collecter des informations sur un utilisateur, notamment son activit\u00e9, ses centres d\u2019int\u00e9r\u00eat, les sites ou applications consult\u00e9s, les donn\u00e9es d\u00e9mographiques ou la g\u00e9olocalisation d\u2019un utilisateur, pour cr\u00e9er ou modifier un profil utilisateur \u00e0 utiliser dans des publicit\u00e9s personnalis\u00e9es.\n"},"4":{"id":4,"name":"S\u00e9lectionner des publicit\u00e9s personnalis\u00e9es","description":"Des publicit\u00e9s personnalis\u00e9es peuvent vous \u00eatre pr\u00e9sent\u00e9es sur la base d\u2019un profil cr\u00e9\u00e9 sur vous.","descriptionLegal":"Pour s\u00e9lectionner des publicit\u00e9s personnalis\u00e9es, les partenaires peuvent :\n* S\u00e9lectionner des publicit\u00e9s personnalis\u00e9es sur la base d\u2019un profil utilisateur ou d\u2019autres donn\u00e9es d\u2019utilisateur historiques, y compris l\u2019activit\u00e9 pass\u00e9e d\u2019un utilisateur, ses centres d\u2019int\u00e9r\u00eat, les sites qu\u2019il a visit\u00e9s ou les applications qu\u2019il a utilis\u00e9es, sa localisation ou ses donn\u00e9es d\u00e9mographiques.\n"},"5":{"id":5,"name":"Cr\u00e9er un profil pour afficher un contenu personnalis\u00e9","description":"Un profil peut \u00eatre cr\u00e9\u00e9 sur vous et sur vos centres d\u2019int\u00e9r\u00eat afin de vous pr\u00e9senter du contenu personnalis\u00e9 susceptible de vous int\u00e9resser.","descriptionLegal":"Pour cr\u00e9er un profil pour afficher du contenu personnalis\u00e9, les partenaires peuvent :\n* Collecter des informations sur un utilisateur, y compris l\u2019activit\u00e9 d\u2019un utilisateur, ses centres d\u2019int\u00e9r\u00eat, les sites qu\u2019il a visit\u00e9s ou les applications qu\u2019il a utilis\u00e9es, ses donn\u00e9es d\u00e9mographiques ou sa localisation, pour cr\u00e9er ou modifier un profil utilisateur pour afficher du contenu personnalis\u00e9.\n"},"6":{"id":6,"name":"S\u00e9lectionner du contenu personnalis\u00e9","description":"Du contenu personnalis\u00e9 peut vous \u00eatre pr\u00e9sent\u00e9 sur la base de votre profil utilisateur. ","descriptionLegal":"Pour s\u00e9lectionner du contenu personnalis\u00e9, les partenaires peuvent :\n* S\u00e9lectionner du contenu personnalis\u00e9 sur la base d\u2019un profil utilisateur induit des donn\u00e9es relatives \u00e0 son activit\u00e9 en ligne, ses centres d\u2019int\u00e9r\u00eat, les sites qu\u2019il a visit\u00e9s, les applications qu\u2019il a utilis\u00e9es, sa localisation ou ses donn\u00e9es socio-d\u00e9mographiques.\n"},"7":{"id":7,"name":"Mesurer la performance des publicit\u00e9s","description":"La performance et l\u2019efficacit\u00e9 des publicit\u00e9s que vous voyez ou avec lesquelles vous interagissez peuvent \u00eatre mesur\u00e9es.","descriptionLegal":"Pour mesurer la performance des publicit\u00e9s, les partenaires peuvent:\n* Mesurer si et comment des publicit\u00e9s ont \u00e9t\u00e9 pr\u00e9sent\u00e9e \u00e0 un utilisateur et comment celui-ci a interagi avec celles-ci\n* G\u00e9n\u00e9rer des rapports sur les publicit\u00e9s, notamment sur leur performance\n* G\u00e9n\u00e9rer des rapports sur les utilisateurs ayant interagi avec des publicit\u00e9s en utilisant des donn\u00e9es issues de cette interaction \n* Fournir des rapports aux \u00e9diteurs sur les publicit\u00e9s pr\u00e9sent\u00e9es/affich\u00e9es sur leurs propri\u00e9t\u00e9s num\u00e9riques \n* \u00c9valuer si une publicit\u00e9 diffus\u00e9e dans un contexte \u00e9ditorial appropri\u00e9 (conforme \u00e0 l\u2019image de la marque) sans danger pour la marque)\n* D\u00e9terminer le pourcentage du visionnage \u00e9ventuel de la publicit\u00e9 et sa dur\u00e9e \n* Combiner ces informations avec d\u2019autres informations collect\u00e9es au pr\u00e9alable, pouvant provenir de sites internet et applications\nLes partenaires ne peuvent pas: \n* Croiser des donn\u00e9es d\u2019audience, issues ou d\u00e9riv\u00e9es d\u2019un panel, avec des donn\u00e9es de mesure de performance, sans base l\u00e9gale pour titre \"Finalit\u00e9 9\". \n"},"8":{"id":8,"name":"Mesurer la performance du contenu","description":"La performance et l\u2019efficacit\u00e9 du contenu que vous voyez ou avec lequel vous interagissez peuvent \u00eatre mesur\u00e9es.","descriptionLegal":"Pour mesurer la performance du contenu, les partenaires peuvent:\n* Mesurer comment le contenu a \u00e9t\u00e9 diffus\u00e9 et comment les utilisateurs ont interagi avec, et g\u00e9n\u00e9rer des rapports.\n* G\u00e9n\u00e9rer des rapports \u00e0 l\u2019aide d\u2019informations directement mesurables ou connues, sur les utilisateurs qui ont interagi avec le contenu\nLes partenaires ne peuvent pas:\n* Mesurer si et comment des publicit\u00e9s (y compris des publicit\u00e9s natives) ont \u00e9t\u00e9 pr\u00e9sent\u00e9es \u00e0 un utilisateur et comment celui-ci a interagi avec, sans base l\u00e9gale distincte\n* Croiser des donn\u00e9es d\u2019audience, issues ou d\u00e9riv\u00e9es d\u2019un panel, avec des donn\u00e9es de mesure de performance, sans base l\u00e9gale pour titre \"Finalit\u00e9 9\u201d. "},"9":{"id":9,"name":"Exploiter des \u00e9tudes de march\u00e9 afin de g\u00e9n\u00e9rer des donn\u00e9es d\u2019audience","description":"Les \u00e9tudes de march\u00e9 peuvent servir \u00e0 en apprendre davantage sur les audiences qui visitent des sites/utilisent des applications et voient des publicit\u00e9s.","descriptionLegal":"Pour utiliser des \u00e9tudes de march\u00e9 afin de g\u00e9n\u00e9rer des donn\u00e9es d\u2019audience, les partenaires peuvent:\n* Fournir des rapports agr\u00e9g\u00e9s aux annonceurs ou \u00e0 leurs repr\u00e9sentants sur les audiences expos\u00e9es \u00e0 leurs publicit\u00e9s, en utilisant des donn\u00e9es issues d\u2019un panel ou d\u2019un autre dispositif.\n* Fournir des rapports agr\u00e9g\u00e9s aux \u00e9diteurs sur les audiences expos\u00e9es \u00e0 des contenus et/ou des publicit\u00e9s ou qui ont interagi avec des contenus et/ou les publicit\u00e9s sur leurs sites, en utilisant des donn\u00e9es issues d\u2019un panel ou d\u2019un autre dispositif. \n* Combiner des donn\u00e9es hors ligne \u00e0 celles d\u2019un utilisateur en ligne dans le cadre d\u2019\u00e9tudes de march\u00e9 pour g\u00e9n\u00e9rer des donn\u00e9es d\u2019audience si les partenaires ont d\u00e9clar\u00e9 faire correspondre et associer des sources de donn\u00e9es hors ligne (Fonctionnalit\u00e9 1)\n* Texte dans la version anglaise : Combiner ces informations avec des donn\u00e9es d\u00e9j\u00e0 collect\u00e9es que ce soit sur le web ou via des applications. \nLes partenaires ne peuvent pas : \n* Mesurer la performance et l\u2019efficacit\u00e9 des publicit\u00e9s qui ont \u00e9t\u00e9 pr\u00e9sent\u00e9es \u00e0 un utilisateur en particulier, ou avec lesquelles il a interagi, sans s\u2019appuyer sur une base l\u00e9gale sp\u00e9cifique pour la mesure de la performance publicitaire.\n* \u00c9valuer le contenu qui a \u00e9t\u00e9 pr\u00e9sent\u00e9 \u00e0 un utilisateur en particulier et la fa\u00e7on dont ce dernier a r\u00e9agi sans s\u2019appuyer sur une base l\u00e9gale sp\u00e9cifique pour la mesure de la performance des contenus.\n"},"10":{"id":10,"name":"D\u00e9velopper et am\u00e9liorer les produits","description":"Vos donn\u00e9es peuvent \u00eatre utilis\u00e9es pour am\u00e9liorer les syst\u00e8mes et logiciels existants et pour d\u00e9velopper de nouveaux produits.","descriptionLegal":"Pour d\u00e9velopper de nouveaux produits et am\u00e9liorer des produits existants, les partenaires peuvent:\n* Utiliser des informations pour am\u00e9liorer leurs produits existants en y ajoutant de nouvelles fonctionnalit\u00e9s et pour d\u00e9velopper de nouveaux produits\n* Cr\u00e9er de nouveaux mod\u00e8les et algorithmes gr\u00e2ce au machine-learning \nLes partenaires ne peuvent pas:\n* Effectuer toute autre op\u00e9ration de traitement des donn\u00e9es autoris\u00e9e par une autre finalit\u00e9 dans le cadre de cette finalit\u00e9\n"}},"specialPurposes":{"1":{"id":1,"name":"Assurer la s\u00e9curit\u00e9, pr\u00e9venir la fraude et d\u00e9boguer","description":"Vos donn\u00e9es peuvent \u00eatre utilis\u00e9es pour surveiller et pr\u00e9venir les activit\u00e9s frauduleuses, et s\u2019assurer que les syst\u00e8mes et processus fonctionnent correctement et en toute s\u00e9curit\u00e9.","descriptionLegal":"Pour garantir la s\u00e9curit\u00e9, pr\u00e9venir la fraude et d\u00e9boguer, les partenaires peuvent:\n* Veiller \u00e0 ce que les donn\u00e9es soient transmises en toute s\u00e9curit\u00e9 \n* D\u00e9tecter et pr\u00e9venir les activit\u00e9s malveillantes, frauduleuses, inappropri\u00e9es ou ill\u00e9gales.\n* Assurer un fonctionnement correct et efficace des syst\u00e8mes et des processus, y compris surveiller et am\u00e9liorer la performance des syst\u00e8mes et processus utilis\u00e9s pour des finalit\u00e9s autoris\u00e9es\nLes partenaires ne peuvent pas:\n* Effectuer, au titre de cette finalit\u00e9, toute autre op\u00e9ration de traitement des donn\u00e9es autoris\u00e9e pour une finalit\u00e9 diff\u00e9rente .\nRemarque: Les donn\u00e9es collect\u00e9es et utilis\u00e9es pour assurer la s\u00e9curit\u00e9, pr\u00e9venir la fraude et d\u00e9boguer peuvent inclure des caract\u00e9ristiques d\u2019appareil envoy\u00e9es automatiquement \u00e0 des fins d'identification, des donn\u00e9es de g\u00e9olocalisation pr\u00e9cises et des donn\u00e9es obtenues par l\u2019analyse active des caract\u00e9ristiques de l\u2019appareil \u00e0 des fins d\u2019identification sans notification distincte et/ou opt-in distinct \n"},"2":{"id":2,"name":"Diffuser techniquement les publicit\u00e9s ou le contenu","description":"Votre terminal peut recevoir et envoyer des informations qui vous permettent de voir des publicit\u00e9s et du contenu et d\u2019interagir avec eux.","descriptionLegal":"Pour fournir des informations et r\u00e9pondre aux appels techniques, les partenaires peuvent:\n* Utiliser l\u2019adresse IP d\u2019un utilisateur pour diffuser une publicit\u00e9 sur Internet\n* R\u00e9agir \u00e0 l\u2019interaction d\u2019un utilisateur avec une publicit\u00e9 en dirigeant l\u2019utilisateur vers une page d\u2019accueil\n* Utiliser l\u2019adresse IP d\u2019un utilisateur pour diffuser du contenu sur Internet\n* R\u00e9agir \u00e0 l\u2019interaction d\u2019un utilisateur avec du contenu en dirigeant l\u2019utilisateur vers une page d\u2019accueil\n* Utiliser des informations sur le type de terminal et les capacit\u00e9s du terminal pour pr\u00e9senter des publicit\u00e9s ou du contenu, par exemple, pour pr\u00e9senter une publicit\u00e9 \u00e0 la bonne taille ou une vid\u00e9o dans un format pris en charge par le terminal \nLes partenaires ne peuvent pas:\n* Effectuer, au titre de cette finalit\u00e9, toute autre op\u00e9ration de traitement des donn\u00e9es autoris\u00e9e pour une finalit\u00e9 diff\u00e9rente \n"}},"features":{"1":{"id":1,"name":"Mettre en correspondance et combiner des sources de donn\u00e9es hors ligne","description":"Les donn\u00e9es issues de sources de donn\u00e9es hors ligne peuvent \u00eatre combin\u00e9es \u00e0 votre activit\u00e9 en ligne \u00e0 l\u2019appui d\u2019une ou de plusieurs finalit\u00e9s.","descriptionLegal":"Les partenaires peuvent : \n* Combiner des donn\u00e9es obtenues hors ligne avec des donn\u00e9es collect\u00e9es en ligne \u00e0 l\u2019appui d\u2019une ou de plusieurs Finalit\u00e9s ou Finalit\u00e9s sp\u00e9ciales.\n"},"2":{"id":2,"name":"Relier diff\u00e9rents terminaux","description":"Diff\u00e9rents terminaux peuvent \u00eatre identifi\u00e9s comme vous appartenant ou appartenant \u00e0 votre foyer \u00e0 l\u2019appui d\u2019une ou de plusieurs finalit\u00e9s","descriptionLegal":"Les partnenaires peuvent :\n* D\u00e9terminer, selon une approche d\u00e9terministe, que deux terminaux ou plus appartiennent au m\u00eame utilisateur ou au m\u00eame foyer\n* D\u00e9terminer, selon une approche probabiliste, que deux terminaux ou plus appartiennent au m\u00eame utilisateur ou au m\u00eame foyer\n* Analyser activement les caract\u00e9ristiques du terminal pour l\u2019identification probabiliste si les utilisateurs ont autoris\u00e9 les partenanaires \u00e0 analyser activement les caract\u00e9ristiques du terminal pour l\u2019identification (Fonctionnalit\u00e9 sp\u00e9ciale 2)\n"},"3":{"id":3,"name":"Recevoir et utiliser des caract\u00e9ristiques d\u2019identification d\u2019appareil envoy\u00e9es automatiquement","description":"Votre appareil peut \u00eatre distingu\u00e9 d\u2019autres appareils en fonction des informations qu\u2019il envoie automatiquement, telles que l\u2019adresse IP ou le type de navigateur.","descriptionLegal":"Les partenaires peuvent :\n* Cr\u00e9er un identifiant \u00e0 l\u2019aide des donn\u00e9es collect\u00e9es automatiquement \u00e0 partir d\u2019un appareil pour des caract\u00e9ristiques sp\u00e9cifiques ; par ex., adresse IP, cha\u00eene d\u2019agent utilisateur.\n* Utiliser cet identifiant pour r\u00e9identifier un appareil.\nLes partenaires ne peuvent pas :\n* Cr\u00e9er un identifiant \u00e0 l\u2019aide des donn\u00e9es collect\u00e9es via une analyse active d\u2019un terminal pour l\u2019identification de caract\u00e9ristiques sp\u00e9cifiques (par exemple, des polices install\u00e9es ou la r\u00e9solution d\u2019\u00e9cran) sans une adh\u00e9sion distincte de l\u2019utilisateur \u00e0 l\u2019analyse active des caract\u00e9ristiques de l\u2019appareil \u00e0 des fins d\u2019identification.\n* Utiliser cet identifiant pour r\u00e9-identifier un terminal.\n"}},"specialFeatures":{"1":{"id":1,"name":"Utiliser des donn\u00e9es de g\u00e9olocalisation pr\u00e9cises","description":"Vos donn\u00e9es de g\u00e9olocalisation pr\u00e9cises peuvent \u00eatre utilis\u00e9es \u00e0 l\u2019appui d\u2019une ou de plusieurs finalit\u00e9s. Cela signifie que votre localisation peut \u00eatre pr\u00e9cise \u00e0 plusieurs m\u00e8tres pr\u00e8s.","descriptionLegal":"Les partnenaires peuvent :\n* Collecter et traiter des donn\u00e9es de g\u00e9olocalisation pr\u00e9cises \u00e0 l\u2019appui d\u2019une ou de plusieurs finalit\u00e9s.\nN.B. Une g\u00e9olocalisation pr\u00e9cise signifie qu\u2019il n\u2019y a aucune restriction \u00e0 la pr\u00e9cision de la localisation d\u2019un utilisateur ; elle peut \u00eatre pr\u00e9cise \u00e0 quelques m\u00e8tres pr\u00e8s.\n"},"2":{"id":2,"name":"Analyser activement les caract\u00e9ristiques du terminal pour l\u2019identification","description":"Votre terminal peut \u00eatre identifi\u00e9 sur la base d\u2019une analyse de la combinaison unique de caract\u00e9ristiques de votre terminal.","descriptionLegal":"Les partenaires peuvent :\n* Cr\u00e9er un identifiant \u00e0 l\u2019aide des donn\u00e9es collect\u00e9es via une analyse active d\u2019un terminal pour l\u2019identification de caract\u00e9ristiques sp\u00e9cifiques, par exemple des polices install\u00e9es ou la r\u00e9solution d\u2019\u00e9cran. \n* Utiliser cet identifiant pour r\u00e9-identifier un terminal.\n"}},"stacks":{"1":{"id":1,"purposes":[],"specialFeatures":[1,2],"name":"Donn\u00e9es de g\u00e9olocalisation pr\u00e9cises et identification par analyse du terminal","description":"Des informations de g\u00e9olocalisation pr\u00e9cises et des informations sur les caract\u00e9ristiques de l\u2019appareil peuvent \u00eatre utilis\u00e9es."},"2":{"id":2,"purposes":[2,7],"specialFeatures":[],"name":"Publicit\u00e9s standards et mesure de performance des publicit\u00e9s","description":"Des publicit\u00e9s standards peuvent \u00eatre diffus\u00e9es. La performance des publicit\u00e9s peut \u00eatre mesur\u00e9e."},"3":{"id":3,"purposes":[2,3,4],"specialFeatures":[],"name":"Publicit\u00e9s personnalis\u00e9es","description":"Les publicit\u00e9s peuvent \u00eatre personnalis\u00e9es sur la base d\u2019un profil. Des donn\u00e9es suppl\u00e9mentaires peuvent \u00eatre ajout\u00e9es pour mieux personnaliser les publicit\u00e9s."},"4":{"id":4,"purposes":[2,7,9],"specialFeatures":[],"name":"Publicit\u00e9s standards et mesure de performance des publicit\u00e9s","description":"Des publicit\u00e9s standards peuvent \u00eatre diffus\u00e9es. La performance des publicit\u00e9s peut \u00eatre mesur\u00e9e. Des informations peuvent \u00eatre g\u00e9n\u00e9r\u00e9es sur les audiences qui ont vu les publicit\u00e9s et le contenu."},"5":{"id":5,"purposes":[2,3,7],"specialFeatures":[],"name":"Publicit\u00e9s standards, profil de publicit\u00e9s personnalis\u00e9es et mesure de performance des publicit\u00e9s","description":"Des publicit\u00e9s standards peuvent \u00eatre diffus\u00e9es. Des donn\u00e9es suppl\u00e9mentaires peuvent \u00eatre ajout\u00e9es pour mieux personnaliser les publicit\u00e9s. La performance des publicit\u00e9s peut \u00eatre mesur\u00e9e."},"6":{"id":6,"purposes":[2,4,7],"specialFeatures":[],"name":"Affichage de publicit\u00e9s personnalis\u00e9es et mesure de performance des publicit\u00e9s","description":"Les publicit\u00e9s peuvent \u00eatre personnalis\u00e9es sur la base d\u2019un profil. La performance des publicit\u00e9s peut \u00eatre mesur\u00e9e."},"7":{"id":7,"purposes":[2,4,7,9],"specialFeatures":[],"name":"Affichage de publicit\u00e9s personnalis\u00e9es, mesure de performance des publicit\u00e9s, et donn\u00e9es d\u2019audience","description":"Les publicit\u00e9s peuvent \u00eatre personnalis\u00e9es sur la base d\u2019un profil. La performance des publicit\u00e9s peut \u00eatre mesur\u00e9e. Des informations peuvent \u00eatre g\u00e9n\u00e9r\u00e9es sur les audiences qui ont vu les publicit\u00e9s et le contenu."},"8":{"id":8,"purposes":[2,3,4,7],"specialFeatures":[],"name":"Publicit\u00e9s personnalis\u00e9es et mesure de performance des annonces","description":"Les publicit\u00e9s peuvent \u00eatre personnalis\u00e9es sur la base d\u2019un profil. Des donn\u00e9es suppl\u00e9mentaires peuvent \u00eatre ajout\u00e9es pour mieux personnaliser les publicit\u00e9s. La performance des publicit\u00e9s peut \u00eatre mesur\u00e9e."},"9":{"id":9,"purposes":[2,3,4,7,9],"specialFeatures":[],"name":"Publicit\u00e9s personnalis\u00e9es, mesure de performance des publicit\u00e9s, et donn\u00e9es d\u2019audience","description":"Les publicit\u00e9s peuvent \u00eatre personnalis\u00e9es sur la base d\u2019un profil. Des donn\u00e9es suppl\u00e9mentaires peuvent \u00eatre ajout\u00e9es pour mieux personnaliser les publicit\u00e9s. La performance des publicit\u00e9s peut \u00eatre mesur\u00e9e. Des informations peuvent \u00eatre g\u00e9n\u00e9r\u00e9es sur les audiences qui ont vu les publicit\u00e9s et le contenu."},"10":{"id":10,"purposes":[3,4],"specialFeatures":[],"name":"Profil de publicit\u00e9s personnalis\u00e9es et affichage","description":"Les publicit\u00e9s peuvent \u00eatre personnalis\u00e9es sur la base d\u2019un profil. Des donn\u00e9es suppl\u00e9mentaires peuvent \u00eatre ajout\u00e9es pour mieux personnaliser les publicit\u00e9s. "},"11":{"id":11,"purposes":[5,6],"specialFeatures":[],"name":"Contenu personnalis\u00e9","description":"Le contenu peut \u00eatre personnalis\u00e9 sur la base d\u2019un profil. Des donn\u00e9es suppl\u00e9mentaires peuvent \u00eatre ajout\u00e9es pour mieux personnaliser le contenu."},"12":{"id":12,"purposes":[6,8],"specialFeatures":[],"name":"Affichage de contenu personnalis\u00e9 et mesure de performance du contenu","description":"Le contenu peut \u00eatre personnalis\u00e9 sur la base d\u2019un profil. La performance du contenu peut \u00eatre mesur\u00e9e."},"13":{"id":13,"purposes":[6,8,9],"specialFeatures":[],"name":"Affichage de contenu personnalis\u00e9, mesure de performance du contenu et donn\u00e9es d\u2019audience","description":"Le contenu peut \u00eatre personnalis\u00e9 sur la base d\u2019un profil. La performance du contenu peut \u00eatre mesur\u00e9e. Des informations peuvent \u00eatre g\u00e9n\u00e9r\u00e9es sur les audiences qui ont vu les publicit\u00e9s et le contenu."},"14":{"id":14,"purposes":[5,6,8],"specialFeatures":[],"name":"Contenu personnalis\u00e9 et mesure de performance du contenu","description":"Le contenu peut \u00eatre personnalis\u00e9 sur la base d\u2019un profil. Des donn\u00e9es suppl\u00e9mentaires peuvent \u00eatre ajout\u00e9es pour mieux personnaliser le contenu. La performance du contenu peut \u00eatre mesur\u00e9e."},"15":{"id":15,"purposes":[5,6,8,9],"specialFeatures":[],"name":"Contenu personnalis\u00e9, mesure de performance du contenu et donn\u00e9es d\u2019audience","description":"Le contenu peut \u00eatre personnalis\u00e9 sur la base d\u2019un profil. Des donn\u00e9es suppl\u00e9mentaires peuvent \u00eatre ajout\u00e9es pour mieux personnaliser le contenu. La performance du contenu peut \u00eatre mesur\u00e9e. Des informations peuvent \u00eatre g\u00e9n\u00e9r\u00e9es sur les audiences qui ont vu les publicit\u00e9s et le contenu."},"16":{"id":16,"purposes":[5,6,8,9,10],"specialFeatures":[],"name":"Contenu personnalis\u00e9, mesure de performance du contenu, donn\u00e9es d\u2019audience, et d\u00e9veloppement produit","description":"Le contenu peut \u00eatre personnalis\u00e9 sur la base d\u2019un profil. Des donn\u00e9es suppl\u00e9mentaires peuvent \u00eatre ajout\u00e9es pour mieux personnaliser le contenu. La performance du contenu peut \u00eatre mesur\u00e9e. Des informations peuvent \u00eatre g\u00e9n\u00e9r\u00e9es sur les audiences qui ont vu les publicit\u00e9s et le contenu. Les donn\u00e9es peuvent \u00eatre utilis\u00e9es pour cr\u00e9er ou am\u00e9liorer l\u2019exp\u00e9rience utilisateur, des syst\u00e8mes et logiciels"},"17":{"id":17,"purposes":[7,8,9],"specialFeatures":[],"name":"Mesure de performance des annonces et du contenu et donn\u00e9es d\u2019audience","description":"La performance des publicit\u00e9s et du contenu peut \u00eatre mesur\u00e9e. Des informations peuvent \u00eatre g\u00e9n\u00e9r\u00e9es sur les audiences qui ont vu les publicit\u00e9s et le contenu."},"18":{"id":18,"purposes":[7,8],"specialFeatures":[],"name":"Mesure de performance des publicit\u00e9s et du contenu","description":"La performance des publicit\u00e9s et du contenu peut \u00eatre mesur\u00e9e."},"19":{"id":19,"purposes":[7,9],"specialFeatures":[],"name":"Mesure de performance des publicit\u00e9s et donn\u00e9es d\u2019audience","description":"La performance des publicit\u00e9s peut \u00eatre mesur\u00e9e. Des informations peuvent \u00eatre g\u00e9n\u00e9r\u00e9es sur les audiences qui ont vu les publicit\u00e9s et le contenu"},"20":{"id":20,"purposes":[7,8,9,10],"specialFeatures":[],"name":"Mesure de performance des publicit\u00e9s et du contenu, donn\u00e9es d\u2019audience, et d\u00e9veloppement produit","description":"La performance des publicit\u00e9s et du contenu peut \u00eatre mesur\u00e9e. Des informations peuvent \u00eatre g\u00e9n\u00e9r\u00e9es sur les audiences qui ont vu les publicit\u00e9s et le contenu. Les donn\u00e9es peuvent \u00eatre utilis\u00e9es pour cr\u00e9er ou am\u00e9liorer l\u2019exp\u00e9rience utilisateur, les syst\u00e8mes et les logiciels. Des informations peuvent \u00eatre g\u00e9n\u00e9r\u00e9es sur les audiences qui ont vu les publicit\u00e9s et le contenu."},"21":{"id":21,"purposes":[8,9,10],"specialFeatures":[],"name":"Mesure de performance du contenu, donn\u00e9es d\u2019audience, et d\u00e9veloppement produit.","description":"La performance du contenu peut \u00eatre mesur\u00e9e. Des informations peuvent \u00eatre g\u00e9n\u00e9r\u00e9es sur les audiences qui ont vu les publicit\u00e9s et le contenu. Les donn\u00e9es peuvent \u00eatre utilis\u00e9es pour cr\u00e9er ou am\u00e9liorer l\u2019exp\u00e9rience utilisateur, les syst\u00e8mes et les logiciels."},"22":{"id":22,"purposes":[8,10],"specialFeatures":[],"name":"Mesure de performance du contenu, et d\u00e9veloppement produit","description":"La performance du contenu peut \u00eatre mesur\u00e9e. Les donn\u00e9es peuvent \u00eatre utilis\u00e9es pour cr\u00e9er ou am\u00e9liorer l\u2019exp\u00e9rience utilisateur, les syst\u00e8mes et les logiciels."},"23":{"id":23,"purposes":[2,4,6,7,8],"specialFeatures":[],"name":"Affichage de publicit\u00e9s et de contenu personnalis\u00e9s, mesure de performance des publicit\u00e9s et du contenu","description":"Les publicit\u00e9s et le contenu peuvent \u00eatre personnalis\u00e9s sur la base d\u2019un profil. La performance des publicit\u00e9s et du contenu peut \u00eatre mesur\u00e9e."},"24":{"id":24,"purposes":[2,4,6,7,8,9],"specialFeatures":[],"name":"Affichage de publicit\u00e9s et de contenu personnalis\u00e9s, mesure de performance des publicit\u00e9s et du contenu, et donn\u00e9es d\u2019audience","description":"Les publicit\u00e9s et le contenu peuvent \u00eatre personnalis\u00e9s sur la base d\u2019un profil. La performance des publicit\u00e9s et du contenu peut \u00eatre mesur\u00e9e. Des informations peuvent \u00eatre g\u00e9n\u00e9r\u00e9es sur les audiences qui ont vu les publicit\u00e9s et le contenu. Les donn\u00e9es peuvent \u00eatre utilis\u00e9es pour cr\u00e9er ou am\u00e9liorer l\u2019exp\u00e9rience utilisateur, les syst\u00e8mes et les logiciels."},"25":{"id":25,"purposes":[2,3,4,5,6,7,8],"specialFeatures":[],"name":"Publicit\u00e9s et contenu personnalis\u00e9s, mesure de performance des publicit\u00e9s et du contenu","description":"Les publicit\u00e9s et le contenu peuvent \u00eatre personnalis\u00e9s sur la base d\u2019un profil. Des donn\u00e9es suppl\u00e9mentaires peuvent \u00eatre ajout\u00e9es pour mieux personnaliser les publicit\u00e9s et le contenu. La performance des publicit\u00e9s et du contenu peut \u00eatre mesur\u00e9e."},"26":{"id":26,"purposes":[2,3,4,5,6,7,8,9],"specialFeatures":[],"name":"Publicit\u00e9s et contenu personnalis\u00e9s, mesure de performance des publicit\u00e9s et du contenu, et donn\u00e9es d\u2019audience","description":"Les publicit\u00e9s et le contenu peuvent \u00eatre personnalis\u00e9s sur la base d\u2019un profil. Des donn\u00e9es suppl\u00e9mentaires peuvent \u00eatre ajout\u00e9es pour mieux personnaliser les publicit\u00e9s et le contenu. La performance des publicit\u00e9s et du contenu peut \u00eatre mesur\u00e9e. Des informations peuvent \u00eatre g\u00e9n\u00e9r\u00e9es sur les audiences qui ont vu les publicit\u00e9s et le contenu."},"27":{"id":27,"purposes":[3,5],"specialFeatures":[],"name":"Publicit\u00e9s personnalis\u00e9es et profil de contenu","description":"Des donn\u00e9es suppl\u00e9mentaires peuvent \u00eatre ajout\u00e9es pour personnaliser les publicit\u00e9s et le contenu. "},"28":{"id":28,"purposes":[2,4,6],"specialFeatures":[],"name":"Affichage de publicit\u00e9s et de contenu personnalis\u00e9s","description":"Les publicit\u00e9s et le contenu peuvent \u00eatre personnalis\u00e9s sur la base d\u2019un profil. "},"29":{"id":29,"purposes":[2,7,8,9],"specialFeatures":[],"name":"Publicit\u00e9s standards, mesure de performance des publicit\u00e9s et du contenu, et donn\u00e9es d\u2019audience","description":"Des publicit\u00e9s standards peuvent \u00eatre diffus\u00e9es. La performance des publicit\u00e9s et du contenu peut \u00eatre mesur\u00e9e. Des informations peuvent \u00eatre g\u00e9n\u00e9r\u00e9es sur les audiences qui ont vu les publicit\u00e9s et le contenu."},"30":{"id":30,"purposes":[2,4,5,6,7,8,9],"specialFeatures":[],"name":"Affichage de publicit\u00e9s personnalis\u00e9es, contenu personnalis\u00e9, mesure de performance des publicit\u00e9s et du contenu, et donn\u00e9es d\u2019audience","description":"Les publicit\u00e9s et le contenu peuvent \u00eatre personnalis\u00e9s sur la base d\u2019un profil. Des donn\u00e9es suppl\u00e9mentaires peuvent \u00eatre ajout\u00e9es pour mieux personnaliser le contenu. La performance des publicit\u00e9s et du contenu peut \u00eatre mesur\u00e9e. Des informations peuvent \u00eatre g\u00e9n\u00e9r\u00e9es sur les audiences qui ont vu les publicit\u00e9s et le contenu."},"31":{"id":31,"purposes":[2,4,5,6,7,8,9,10],"specialFeatures":[],"name":"Affichage de publicit\u00e9s personnalis\u00e9es, contenu personnalis\u00e9, mesure de performance des publicit\u00e9s et du contenu, donn\u00e9es d\u2019audience et d\u00e9veloppement de produit","description":"Les publicit\u00e9s et le contenu peuvent \u00eatre personnalis\u00e9s sur la base d\u2019un profil. Des donn\u00e9es suppl\u00e9mentaires peuvent \u00eatre ajout\u00e9es pour mieux personnaliser le contenu. La performance des publicit\u00e9s et du contenu peut \u00eatre mesur\u00e9e. Des informations peuvent \u00eatre g\u00e9n\u00e9r\u00e9es sur les audiences qui ont vu les publicit\u00e9s et le contenu. Les donn\u00e9es peuvent \u00eatre utilis\u00e9es pour cr\u00e9er ou am\u00e9liorer l\u2019exp\u00e9rience utilisateur, les syst\u00e8mes et les logiciels."},"32":{"id":32,"purposes":[2,5,6,7,8,9],"specialFeatures":[],"name":"Publicit\u00e9s standards, contenu personnalis\u00e9, mesure de performance des publicit\u00e9s et du contenu, et donn\u00e9es d\u2019audience","description":"Des publicit\u00e9s standards peuvent \u00eatre diffus\u00e9es. Le contenu peut \u00eatre personnalis\u00e9 sur la base d\u2019un profil. Des donn\u00e9es suppl\u00e9mentaires peuvent \u00eatre ajout\u00e9es pour mieux personnaliser le contenu. La performance des publicit\u00e9s et du contenu peut \u00eatre mesur\u00e9e. Des informations peuvent \u00eatre g\u00e9n\u00e9r\u00e9es sur les audiences qui ont vu les publicit\u00e9s et le contenu."},"33":{"id":33,"purposes":[2,5,6,7,8,9,10],"specialFeatures":[],"name":"Publicit\u00e9s standards, contenu personnalis\u00e9, mesure de performance des publicit\u00e9s et du contenu, donn\u00e9es d\u2019audience, et d\u00e9veloppement produit","description":"Des publicit\u00e9s standards peuvent \u00eatre diffus\u00e9es. Le contenu peut \u00eatre personnalis\u00e9 sur la base d\u2019un profil. Des donn\u00e9es suppl\u00e9mentaires peuvent \u00eatre ajout\u00e9es pour mieux personnaliser le contenu. La performance des publicit\u00e9s et du contenu peut \u00eatre mesur\u00e9e. Des informations peuvent \u00eatre g\u00e9n\u00e9r\u00e9es sur les audiences qui ont vu les publicit\u00e9s et le contenu. Les donn\u00e9es peuvent \u00eatre utilis\u00e9es pour cr\u00e9er ou am\u00e9liorer l\u2019exp\u00e9rience utilisateur, les syst\u00e8mes et les logiciels."},"34":{"id":34,"purposes":[2,5,6,8,9],"specialFeatures":[],"name":"Publicit\u00e9s standards, contenu personnalis\u00e9, mesure de performance du contenu, et donn\u00e9es d\u2019audience","description":"Des publicit\u00e9s standards peuvent \u00eatre diffus\u00e9es. Le contenu peut \u00eatre personnalis\u00e9 sur la base d\u2019un profil. Des donn\u00e9es suppl\u00e9mentaires peuvent \u00eatre ajout\u00e9es pour mieux personnaliser le contenu. La performance des publicit\u00e9s et du contenu peut \u00eatre mesur\u00e9e. Des informations peuvent \u00eatre g\u00e9n\u00e9r\u00e9es sur les audiences qui ont vu les publicit\u00e9s et le contenu."},"35":{"id":35,"purposes":[2,5,6,8,9,10],"specialFeatures":[],"name":"Publicit\u00e9s standards, contenu personnalis\u00e9, mesure de performance du contenu, donn\u00e9es d\u2019audience et d\u00e9veloppement de produit ","description":"Des publicit\u00e9s standards peuvent \u00eatre diffus\u00e9es. Le contenu peut \u00eatre personnalis\u00e9 sur la base d\u2019un profil. Des donn\u00e9es suppl\u00e9mentaires peuvent \u00eatre ajout\u00e9es pour mieux personnaliser le contenu. La performance du contenu peut \u00eatre mesur\u00e9e. Des informations peuvent \u00eatre g\u00e9n\u00e9r\u00e9es sur les audiences qui ont vu les publicit\u00e9s et le contenu. Les donn\u00e9es peuvent \u00eatre utilis\u00e9es pour cr\u00e9er ou am\u00e9liorer l\u2019exp\u00e9rience utilisateur, les syst\u00e8mes et les logiciels."},"36":{"id":36,"purposes":[2,5,6,7],"specialFeatures":[],"name":"Publicit\u00e9s standard, contenu personnalis\u00e9 et mesure de performance des publicit\u00e9s","description":"Des publicit\u00e9s standards peuvent \u00eatre diffus\u00e9es. Le contenu peut \u00eatre personnalis\u00e9 sur la base d\u2019un profil. Des donn\u00e9es suppl\u00e9mentaires peuvent \u00eatre ajout\u00e9es pour mieux personnaliser le contenu. La performance des publicit\u00e9s peut \u00eatre mesur\u00e9e."},"37":{"id":37,"purposes":[2,5,6,7,10],"specialFeatures":[],"name":"Publicit\u00e9s standards, contenu personnalis\u00e9, mesure de performance des publicit\u00e9s, et d\u00e9veloppement produit","description":"Des publicit\u00e9s standards peuvent \u00eatre diffus\u00e9es. Le contenu peut \u00eatre personnalis\u00e9 sur la base d\u2019un profil. Des donn\u00e9es suppl\u00e9mentaires peuvent \u00eatre ajout\u00e9es pour mieux personnaliser le contenu. La performance des publicit\u00e9s peut \u00eatre mesur\u00e9e. Les donn\u00e9es peuvent \u00eatre utilis\u00e9es pour cr\u00e9er ou am\u00e9liorer l\u2019exp\u00e9rience utilisateur, les syst\u00e8mes et les logiciels."}}} \ No newline at end of file diff --git a/iabgpp-extras-jackson/src/test/resources/vendorlist/v3.0/vendor-list.json b/iabgpp-extras-jackson/src/test/resources/vendorlist/v3.0/vendor-list.json new file mode 100644 index 00000000..9c9e1481 --- /dev/null +++ b/iabgpp-extras-jackson/src/test/resources/vendorlist/v3.0/vendor-list.json @@ -0,0 +1,20907 @@ +{ + "gvlSpecificationVersion": 3, + "vendorListVersion": 7, + "tcfPolicyVersion": 4, + "lastUpdated": "2023-06-29T16:07:26Z", + "purposes": { + "1": { + "id": 1, + "name": "Store and/or access information on a device", + "description": "Cookies, device or similar online identifiers (e.g. login-based identifiers, randomly assigned identifiers, network based identifiers) together with other information (e.g. browser type and information, language, screen size, supported technologies etc.) can be stored or read on your device to recognise it each time it connects to an app or to a website, for one or several of the purposes presented here. ", + "illustrations": [ + "Most purposes explained in this notice rely on the storage or accessing of information from your device when you use an app or visit a website. For example, a vendor or publisher might need to store a cookie on your device during your first visit on a website, to be able to recognise your device during your next visits (by accessing this cookie each time)." + ] + }, + "2": { + "id": 2, + "name": "Use limited data to select advertising", + "description": "Advertising presented to you on this service can be based on limited data, such as the website or app you are using, your non-precise location, your device type or which content you are (or have been) interacting with (for example, to limit the number of times an ad is presented to you).", + "illustrations": [ + "A car manufacturer wants to promote its electric vehicles to environmentally conscious users living in the city after office hours. The advertising is presented on a page with related content (such as an article on climate change actions) after 6:30 p.m. to users whose non-precise location suggests that they are in an urban zone.", + "A large producer of watercolour paints wants to carry out an online advertising campaign for its latest watercolour range, diversifying its audience to reach as many amateur and professional artists as possible and avoiding showing the ad next to mismatched content (for instance, articles about how to paint your house). The number of times that the ad has been presented to you is detected and limited, to avoid presenting it too often." + ] + }, + "3": { + "id": 3, + "name": "Create profiles for personalised advertising", + "description": "Information about your activity on this service (such as forms you submit, content you look at) can be stored and combined with other information about you (for example, information from your previous activity on this service and other websites or apps) or similar users. This is then used to build or improve a profile about you (that might include possible interests and personal aspects). Your profile can be used (also later) to present advertising that appears more relevant based on your possible interests by this and other entities.", + "illustrations": [ + "If you read several articles about the best bike accessories to buy, this information could be used to create a profile about your interest in bike accessories. Such a profile may be used or improved later on, on the same or a different website or app to present you with advertising for a particular bike accessory brand. If you also look at a configurator for a vehicle on a luxury car manufacturer website, this information could be combined with your interest in bikes to refine your profile and make an assumption that you are interested in luxury cycling gear.", + "An apparel company wishes to promote its new line of high-end baby clothes. It gets in touch with an agency that has a network of clients with high income customers (such as high-end supermarkets) and asks the agency to create profiles of young parents or couples who can be assumed to be wealthy and to have a new child, so that these can later be used to present advertising within partner apps based on those profiles." + ] + }, + "4": { + "id": 4, + "name": "Use profiles to select personalised advertising", + "description": "Advertising presented to you on this service can be based on your advertising profiles, which can reflect your activity on this service or other websites or apps (like the forms you submit, content you look at), possible interests and personal aspects.", + "illustrations": [ + "An online retailer wants to advertise a limited sale on running shoes. It wants to target advertising to users who previously looked at running shoes on its mobile app. Tracking technologies might be used to recognise that you have previously used the mobile app to consult running shoes, in order to present you with the corresponding advertisement on the app.", + "A profile created for personalised advertising in relation to a person having searched for bike accessories on a website can be used to present the relevant advertisement for bike accessories on a mobile app of another organisation." + ] + }, + "5": { + "id": 5, + "name": "Create profiles to personalise content", + "description": "Information about your activity on this service (for instance, forms you submit, non-advertising content you look at) can be stored and combined with other information about you (such as your previous activity on this service or other websites or apps) or similar users. This is then used to build or improve a profile about you (which might for example include possible interests and personal aspects). Your profile can be used (also later) to present content that appears more relevant based on your possible interests, such as by adapting the order in which content is shown to you, so that it is even easier for you to find content that matches your interests. \n", + "illustrations": [ + "You read several articles on how to build a treehouse on a social media platform. This information might be added to a profile to mark your interest in content related to outdoors as well as do-it-yourself guides (with the objective of allowing the personalisation of content, so that for example you are presented with more blog posts and articles on treehouses and wood cabins in the future).", + "You have viewed three videos on space exploration across different TV apps. An unrelated news platform with which you have had no contact builds a profile based on that viewing behaviour, marking space exploration as a topic of possible interest for other videos." + ] + }, + "6": { + "id": 6, + "name": "Use profiles to select personalised content", + "description": "Content presented to you on this service can be based on your content personalisation profiles, which can reflect your activity on this or other services (for instance, the forms you submit, content you look at), possible interests and personal aspects, such as by adapting the order in which content is shown to you, so that it is even easier for you to find (non-advertising) content that matches your interests.", + "illustrations": [ + "You read articles on vegetarian food on a social media platform and then use the cooking app of an unrelated company. The profile built about you on the social media platform will be used to present you vegetarian recipes on the welcome screen of the cooking app.", + "You have viewed three videos about rowing across different websites. An unrelated video sharing platform will recommend five other videos on rowing that may be of interest to you when you use your TV app, based on a profile built about you when you visited those different websites to watch online videos." + ] + }, + "7": { + "id": 7, + "name": "Measure advertising performance", + "description": "Information regarding which advertising is presented to you and how you interact with it can be used to determine how well an advert has worked for you or other users and whether the goals of the advertising were reached. For instance, whether you saw an ad, whether you clicked on it, whether it led you to buy a product or visit a website, etc. This is very helpful to understand the relevance of advertising campaigns.", + "illustrations": [ + "You have clicked on an advertisement about a “black Friday” discount by an online shop on the website of a publisher and purchased a product. Your click will be linked to this purchase. Your interaction and that of other users will be measured to know how many clicks on the ad led to a purchase.", + "You are one of very few to have clicked on an advertisement about an “international appreciation day” discount by an online gift shop within the app of a publisher. The publisher wants to have reports to understand how often a specific ad placement within the app, and notably the “international appreciation day” ad, has been viewed or clicked by you and other users, in order to help the publisher and its partners (such as agencies) optimise ad placements." + ] + }, + "8": { + "id": 8, + "name": "Measure content performance", + "description": "Information regarding which content is presented to you and how you interact with it can be used to determine whether the (non-advertising) content e.g. reached its intended audience and matched your interests. For instance, whether you read an article, watch a video, listen to a podcast or look at a product description, how long you spent on this service and the web pages you visit etc. This is very helpful to understand the relevance of (non-advertising) content that is shown to you. \n", + "illustrations": [ + "You have read a blog post about hiking on a mobile app of a publisher and followed a link to a recommended and related post. Your interactions will be recorded as showing that the initial hiking post was useful to you and that it was successful in interesting you in the related post. This will be measured to know whether to produce more posts on hiking in the future and where to place them on the home screen of the mobile app.", + "You were presented a video on fashion trends, but you and several other users stopped watching after 30 seconds. This information is then used to evaluate the right length of future videos on fashion trends." + ] + }, + "9": { + "id": 9, + "name": "Understand audiences through statistics or combinations of data from different sources", + "description": "Reports can be generated based on the combination of data sets (like user profiles, statistics, market research, analytics data) regarding your interactions and those of other users with advertising or (non-advertising) content to identify common characteristics (for instance, to determine which target audiences are more receptive to an ad campaign or to certain contents).", + "illustrations": [ + "The owner of an online bookstore wants commercial reporting showing the proportion of visitors who consulted and left its site without buying, or consulted and bought the last celebrity autobiography of the month, as well as the average age and the male/female distribution of each category. Data relating to your navigation on its site and to your personal characteristics is then used and combined with other such data to produce these statistics.", + "An advertiser wants to better understand the type of audience interacting with its adverts. It calls upon a research institute to compare the characteristics of users who interacted with the ad with typical attributes of users of similar platforms, across different devices. This comparison reveals to the advertiser that its ad audience is mainly accessing the adverts through mobile devices and is likely in the 45-60 age range." + ] + }, + "10": { + "id": 10, + "name": "Develop and improve services", + "description": "Information about your activity on this service, such as your interaction with ads or content, can be very helpful to improve products and services and to build new products and services based on user interactions, the type of audience, etc. This specific purpose does not include the development or improvement of user profiles and identifiers.", + "illustrations": [ + "A technology platform working with a social media provider notices a growth in mobile app users, and sees based on their profiles that many of them are connecting through mobile connections. It uses a new technology to deliver ads that are formatted for mobile devices and that are low-bandwidth, to improve their performance.", + "An advertiser is looking for a way to display ads on a new type of consumer device. It collects information regarding the way users interact with this new kind of device to determine whether it can build a new mechanism for displaying advertising on this type of device." + ] + }, + "11": { + "id": 11, + "name": "Use limited data to select content", + "description": "Content presented to you on this service can be based on limited data, such as the website or app you are using, your non-precise location, your device type, or which content you are (or have been) interacting with (for example, to limit the number of times a video or an article is presented to you).\n", + "illustrations": [ + "A travel magazine has published an article on its website about the new online courses proposed by a language school, to improve travelling experiences abroad. The school’s blog posts are inserted directly at the bottom of the page, and selected on the basis of your non-precise location (for instance, blog posts explaining the course curriculum for different languages than the language of the country you are situated in).\n", + "A sports news mobile app has started a new section of articles covering the most recent football games. Each article includes videos hosted by a separate streaming platform showcasing the highlights of each match. If you fast-forward a video, this information may be used to select a shorter video to play next.\n" + ] + } + }, + "specialPurposes": { + "1": { + "id": 1, + "name": "Ensure security, prevent and detect fraud, and fix errors\n", + "description": "Your data can be used to monitor for and prevent unusual and possibly fraudulent activity (for example, regarding advertising, ad clicks by bots), and ensure systems and processes work properly and securely. It can also be used to correct any problems you, the publisher or the advertiser may encounter in the delivery of content and ads and in your interaction with them.", + "illustrations": [ + "An advertising intermediary delivers ads from various advertisers to its network of partnering websites. It notices a large increase in clicks on ads relating to one advertiser, and uses data regarding the source of the clicks to determine that 80% of the clicks come from bots rather than humans." + ] + }, + "2": { + "id": 2, + "name": "Deliver and present advertising and content", + "description": "Certain information (like an IP address or device capabilities) is used to ensure the technical compatibility of the content or advertising, and to facilitate the transmission of the content or ad to your device.", + "illustrations": [ + "Clicking on a link in an article might normally send you to another page or part of the article. To achieve this, 1°) your browser sends a request to a server linked to the website, 2°) the server answers back (“here is the article you asked for”), using technical information automatically included in the request sent by your device, to properly display the information / images that are part of the article you asked for. Technically, such exchange of information is necessary to deliver the content that appears on your screen." + ] + } + }, + "features": { + "1": { + "id": 1, + "name": "Match and combine data from other data sources", + "description": "Information about your activity on this service may be matched and combined with other information relating to you and originating from various sources (for instance your activity on a separate online service, your use of a loyalty card in-store, or your answers to a survey), in support of the purposes explained in this notice.", + "illustrations": [] + }, + "2": { + "id": 2, + "name": "Link different devices", + "description": "In support of the purposes explained in this notice, your device might be considered as likely linked to other devices that belong to you or your household (for instance because you are logged in to the same service on both your phone and your computer, or because you may use the same Internet connection on both devices).", + "illustrations": [] + }, + "3": { + "id": 3, + "name": "Identify devices based on information transmitted automatically", + "description": "Your device might be distinguished from other devices based on information it automatically sends when accessing the Internet (for instance, the IP address of your Internet connection or the type of browser you are using) in support of the purposes exposed in this notice.", + "illustrations": [] + } + }, + "specialFeatures": { + "1": { + "id": 1, + "name": "Use precise geolocation data", + "description": "With your acceptance, your precise location (within a radius of less than 500 metres) may be used in support of the purposes explained in this notice.", + "illustrations": [] + }, + "2": { + "id": 2, + "name": "Actively scan device characteristics for identification", + "description": "With your acceptance, certain characteristics specific to your device might be requested and used to distinguish it from other devices (such as the installed fonts or plugins, the resolution of your screen) in support of the purposes explained in this notice.", + "illustrations": [] + } + }, + "stacks": { + "1": { + "id": 1, + "purposes": [], + "specialFeatures": [ + 1, + 2 + ], + "name": "Precise geolocation data, and identification through device scanning", + "description": "Precise geolocation and information about device characteristics can be used.\n\n" + }, + "2": { + "id": 2, + "purposes": [ + 2, + 7 + ], + "specialFeatures": [], + "name": "Advertising based on limited data and advertising measurement", + "description": "Advertising can be presented based on limited data. Advertising performance can be measured." + }, + "3": { + "id": 3, + "purposes": [ + 2, + 3, + 4 + ], + "specialFeatures": [], + "name": "Personalised advertising \n", + "description": "Advertising can be personalised based on your profile. Your activity on this service can be used to build or improve a profile about you for personalised advertising.\n" + }, + "4": { + "id": 4, + "purposes": [ + 2, + 7, + 9 + ], + "specialFeatures": [], + "name": "Advertising based on limited data, advertising measurement, and understanding of the audiences", + "description": "Advertising can be presented based on limited data. Advertising performance can be measured. Reports can be generated based on your activity and those of others." + }, + "5": { + "id": 5, + "purposes": [ + 2, + 3, + 7 + ], + "specialFeatures": [], + "name": "Advertising based on limited data, personalised advertising profile, and advertising measurement\n\n", + "description": "Advertising can be presented based on limited data. Your activity on this service can be used to build or improve a profile about you for personalised advertising. Advertising performance can be measured." + }, + "6": { + "id": 6, + "purposes": [ + 2, + 4, + 7 + ], + "specialFeatures": [], + "name": "Selection of personalised advertising and advertising measurement", + "description": "Advertising can be personalised based on your profile. Advertising performance can be measured." + }, + "7": { + "id": 7, + "purposes": [ + 2, + 4, + 7, + 9 + ], + "specialFeatures": [], + "name": "Selection of personalised advertising, advertising measurement, and audience research", + "description": "Advertising can be personalised based on your profile. Advertising performance can be measured. Reports can be generated based on your activity and those of others." + }, + "8": { + "id": 8, + "purposes": [ + 2, + 3, + 4, + 7 + ], + "specialFeatures": [], + "name": "Personalised advertising and advertising measurement", + "description": "Advertising can be personalised based on your profile. Your activity on this service can be used to build or improve a profile about you for personalised advertising. Advertising performance can be measured.\n" + }, + "9": { + "id": 9, + "purposes": [ + 2, + 3, + 4, + 7, + 9 + ], + "specialFeatures": [], + "name": "Personalised advertising, advertising measurement, and audience research", + "description": "Advertising can be personalised based on your profile. Your activity on this service can be used to build or improve a profile about you for personalised advertising. Advertising performance can be measured. Reports can be generated based on your activity and those of others." + }, + "10": { + "id": 10, + "purposes": [ + 3, + 4 + ], + "specialFeatures": [], + "name": "Personalised advertising", + "description": "Advertising can be personalised based on your profile. Your activity on this service can be used to build or improve a profile about you for personalised advertising." + }, + "11": { + "id": 11, + "purposes": [ + 5, + 6 + ], + "specialFeatures": [], + "name": "Personalised content", + "description": "Content can be personalised based on your profile. Your activity on this service can be used to build or improve a profile about you for personalised content." + }, + "12": { + "id": 12, + "purposes": [ + 6, + 8, + 11 + ], + "specialFeatures": [], + "name": "Selection of personalised content and content measurement", + "description": "Content can be personalised based on your profile. Content performance can be measured.\n" + }, + "13": { + "id": 13, + "purposes": [ + 6, + 8, + 11 + ], + "specialFeatures": [], + "name": "Selection of personalised content, content measurement and audience research\n", + "description": "Content can be personalised based on your profile. Content performance can be measured. Reports can be generated based on your activity and those of others.Content can be personalised based on your profile. Content performance can be measured. Reports can be generated based on your activity and those of others. " + }, + "14": { + "id": 14, + "purposes": [ + 5, + 6, + 8, + 11 + ], + "specialFeatures": [], + "name": "Personalised content and content measurement", + "description": "Content can be personalised based on your profile. Your activity on this service can be used to build or improve a profile about you for personalised content. Content performance can be measured." + }, + "15": { + "id": 15, + "purposes": [ + 5, + 6, + 8, + 9, + 11 + ], + "specialFeatures": [], + "name": "Personalised content, content measurement and audience research", + "description": "Content can be personalised based on your profile. Your activity on this service can be used to build or improve a profile about you for personalised content. Content performance can be measured. Reports can be generated based on your activity and those of others." + }, + "16": { + "id": 16, + "purposes": [ + 5, + 6, + 8, + 9, + 10, + 11 + ], + "specialFeatures": [], + "name": "Personalised content, content measurement, audience research, and services development", + "description": "Content can be personalised based on your profile. Your activity on this service can be used to build or improve a profile about you for personalised content. Content performance can be measured. Reports can be generated based on your activity and those of others. Your activity on this service can help develop and improve products and services." + }, + "17": { + "id": 17, + "purposes": [ + 7, + 8, + 9 + ], + "specialFeatures": [], + "name": "Advertising and content measurement, and audience research", + "description": "Advertising and content performance can be measured. Reports can be generated based on your activity and those of others." + }, + "18": { + "id": 18, + "purposes": [ + 7, + 8 + ], + "specialFeatures": [], + "name": "Advertising and content measurement\n\n", + "description": "Advertising and content performance can be measured." + }, + "19": { + "id": 19, + "purposes": [ + 7, + 9 + ], + "specialFeatures": [], + "name": "Advertising measurement and audience research", + "description": "Advertising can be measured. Reports can be generated based on your activity and those of others." + }, + "20": { + "id": 20, + "purposes": [ + 7, + 8, + 9, + 10 + ], + "specialFeatures": [], + "name": "Advertising and content measurement, audience research, and services development", + "description": "Advertising and content performance can be measured. Your activity on this service can help develop and improve products and services. Reports can be generated based on your activity and those of others. \n" + }, + "21": { + "id": 21, + "purposes": [ + 8, + 9, + 10 + ], + "specialFeatures": [], + "name": "Content measurement, audience research and services development.", + "description": "Content performance can be measured. Reports can be generated based on your activity and those of others. Your activity on this service can help develop and improve products and services." + }, + "22": { + "id": 22, + "purposes": [ + 8, + 10 + ], + "specialFeatures": [], + "name": "Content measurement and services development", + "description": "Content performance can be measured. Your activity on this service can help develop and improve products and services.\n" + }, + "23": { + "id": 23, + "purposes": [ + 2, + 4, + 6, + 7, + 8, + 11 + ], + "specialFeatures": [], + "name": "Selection of personalised advertising and content, advertising and content measurement", + "description": "Advertising and content can be personalised based on your profile. Advertising and content performance can be measured.\n" + }, + "24": { + "id": 24, + "purposes": [ + 2, + 4, + 6, + 7, + 8, + 9, + 11 + ], + "specialFeatures": [], + "name": "Selection of personalised advertising and content, advertising and content measurement, and audience research", + "description": "Advertising and content can be personalised based on your profile. Advertising and content performance can be measured. Reports can be generated based on your activity and those of others. Data can be used to build or improve user experience, systems, and software." + }, + "25": { + "id": 25, + "purposes": [ + 2, + 3, + 4, + 5, + 6, + 7, + 8, + 11 + ], + "specialFeatures": [], + "name": "Personalised advertising and content, advertising and content measurement", + "description": "Advertising and content can be personalised based on your profile. Your activity on this service can be used to build or improve a profile about you for personalised advertising or content. Advertising and content performance can be measured." + }, + "26": { + "id": 26, + "purposes": [ + 2, + 3, + 4, + 5, + 6, + 7, + 8, + 9, + 11 + ], + "specialFeatures": [], + "name": "Personalised advertising and content, advertising and content measurement, and audience research", + "description": "Advertising and content can be personalised based on your profile. Your activity on this service can be used to build or improve a profile about you for personalised advertising or content. Advertising and content performance can be measured. Reports can be generated based on your activity and those of others. \n" + }, + "27": { + "id": 27, + "purposes": [ + 3, + 5 + ], + "specialFeatures": [], + "name": "Personalised advertising and content profile", + "description": "Your activity on this service can be used to build or improve a profile about you for personalised advertising or content.\n" + }, + "28": { + "id": 28, + "purposes": [ + 2, + 4, + 6, + 11 + ], + "specialFeatures": [], + "name": "Selection of personalised advertising and content", + "description": "Advertising and content can be personalised based on your profile." + }, + "29": { + "id": 29, + "purposes": [ + 2, + 7, + 8, + 9 + ], + "specialFeatures": [], + "name": "Advertising based on limited data, advertising and content measurement, and audience research\n\n", + "description": "Advertising can be presented based on limited data. Advertising and content performance can be measured. Reports can be generated based on your activity and those of others. \n" + }, + "30": { + "id": 30, + "purposes": [ + 2, + 4, + 5, + 6, + 7, + 8, + 9, + 11 + ], + "specialFeatures": [], + "name": "Selection of personalised advertising, personalised content, advertising and content measurement, and audience research\n", + "description": "Advertising and content can be personalised based on your profile. Your activity on this service can be used to build or improve a profile about you for personalised advertising or content. Advertising and content performance can be measured. Reports can be generated based on your activity and those of others." + }, + "31": { + "id": 31, + "purposes": [ + 2, + 4, + 5, + 6, + 7, + 8, + 9, + 10, + 11 + ], + "specialFeatures": [], + "name": "Selection of personalised advertising, personalised content, advertising and content measurement, audience research, and services development", + "description": "Advertising and content can be personalised based on your profile. Your activity on this service can be used to build or improve a profile about you for personalised content. Advertising and content performance can be measured. Reports can be generated based on your activity and those of others. Your activity on this service can help develop and improve products and services.\n" + }, + "32": { + "id": 32, + "purposes": [ + 2, + 5, + 6, + 7, + 8, + 9, + 11 + ], + "specialFeatures": [], + "name": "Advertising based on limited data, personalised content, advertising and content measurement, and audience research", + "description": "Advertising can be presented based on limited data. Content can be personalised based on your profile. Your activity on this service can be used to build or improve a profile about you for personalised content. Advertising and content performance can be measured. Reports can be generated based on your activity and those of others. \n" + }, + "33": { + "id": 33, + "purposes": [ + 2, + 5, + 6, + 7, + 8, + 9, + 10, + 11 + ], + "specialFeatures": [], + "name": "Advertising based on limited data, personalised content, advertising and content measurement, audience research, and services development", + "description": "Advertising can be presented based on limited data. Content can be personalised based on your profile. Your activity on this service can be used to build or improve a profile about you for personalised content. Advertising and content performance can be measured. Reports can be generated based on your activity and those of others. Your activity on this service can help develop and improve products and services." + }, + "34": { + "id": 34, + "purposes": [ + 2, + 5, + 6, + 8, + 9, + 11 + ], + "specialFeatures": [], + "name": "Advertising based on limited data, personalised content, content measurement, and audience research", + "description": "Advertising can be presented based on limited data. Content can be personalised based on your profile. Your activity on this service can be used to build or improve a profile about you for personalised content. Advertising and content performance can be measured. Reports can be generated based on your activity and those of others." + }, + "35": { + "id": 35, + "purposes": [ + 2, + 5, + 6, + 8, + 9, + 10, + 11 + ], + "specialFeatures": [], + "name": "Advertising based on limited data, personalised content, content measurement, audience research and services development", + "description": "Advertising can be presented based on limited data. Content can be personalised based on your profile. Your activity on this service can be used to build or improve a profile about you for personalised content. Content performance can be measured. Reports can be generated based on your activity and those of others. Your activity on this service can help develop and improve products and services.\n" + }, + "36": { + "id": 36, + "purposes": [ + 2, + 5, + 6, + 7, + 11 + ], + "specialFeatures": [], + "name": "Advertising based on limited data, personalised content, and advertising measurement", + "description": "Advertising can be presented based on limited data. Content can be personalised based on your profile. Your activity on this service can be used to build or improve a profile about you for personalised content. Advertising performance can be measured.\n" + }, + "37": { + "id": 37, + "purposes": [ + 2, + 5, + 6, + 7, + 10, + 11 + ], + "specialFeatures": [], + "name": "Advertising based on limited data, personalised content, advertising measurement, and services development", + "description": "Advertising can be presented based on limited data. Content can be personalised based on your profile. Your activity on this service can be used to build or improve a profile about you for personalised content. Advertising performance can be measured. Your activity on this service can help develop and improve products and services.\n" + }, + "38": { + "id": 38, + "purposes": [ + 2, + 3, + 4, + 7, + 10 + ], + "specialFeatures": [], + "name": "Personalised advertising, advertising measurement, and services development", + "description": "Advertising can be personalised based on your profile.Your activity on this service can be used to build or improve a profile about you for personalised advertising. Advertising performance can be measured. Your activity on this service can help develop and improve products and services." + }, + "39": { + "id": 39, + "purposes": [ + 2, + 3, + 4, + 7, + 9, + 10 + ], + "specialFeatures": [], + "name": "Personalised advertising, advertising measurement, audience research and services development", + "description": "Advertising can be personalised based on your profile. Your activity on this service can be used to build or improve a profile about you for personalised advertising. Advertising performance can be measured. Reports can be generated based on your activity and those of others. Your activity on this service can help develop and improve products and services." + }, + "40": { + "id": 40, + "purposes": [ + 2, + 3, + 4, + 7, + 8, + 9, + 10 + ], + "specialFeatures": [], + "name": "Personalised advertising, advertising and content measurement, audience research and services development", + "description": "Advertising can be personalised based on your profile.Your activity on this service can be used to build or improve a profile about you for personalised advertising. Advertising and content performance can be measured. Reports can be generated based on your activity and those of others. Your activity on this service can help develop and improve products and services.\n" + }, + "41": { + "id": 41, + "purposes": [ + 2, + 3, + 4, + 6, + 7, + 8, + 9, + 10, + 11 + ], + "specialFeatures": [], + "name": "Personalised advertising, selection of personalised content, advertising and content measurement, audience research and services development", + "description": "Advertising and content can be personalised based on your profile. Your activity on this service can be used to build or improve a profile about you for personalised advertising. Advertising and content performance can be measured. Reports can be generated based on your activity and those of others. Your activity on this service can help develop and improve products and services.\n" + }, + "42": { + "id": 42, + "purposes": [ + 2, + 3, + 4, + 5, + 6, + 7, + 8, + 9, + 10, + 11 + ], + "specialFeatures": [], + "name": "Personalised advertising and content, advertising and content measurement, audience research and services development\n", + "description": "Advertising and content can be personalised based on your profile. Your activity on this service can be used to build or improve a profile about you for personalised advertising and content. Advertising and content performance can be measured. Reports can be generated based on your activity and those of others. Your activity on this service can help develop and improve products and services." + }, + "43": { + "id": 43, + "purposes": [ + 8, + 11 + ], + "specialFeatures": [], + "name": "Content based on limited data and content measurement", + "description": "Content can be selected based on limited data. Content performance can be measured." + } + }, + "dataCategories": { + "1": { + "id": 1, + "name": "IP addresses", + "description": "Your IP address is a number assigned by your Internet Service Provider to any Internet connection. It is not always specific to your device and is not always a stable identifier.\nIt is used to route information on the Internet and display online content (including ads) on your connected device." + }, + "2": { + "id": 2, + "name": "Device characteristics", + "description": "Technical characteristics about the device you are using that are not unique to you, such as the language, the time zone or the operating system." + }, + "3": { + "id": 3, + "name": "Device identifiers", + "description": "A device identifier is a unique string of characters assigned to your device or browser by means of a cookie or other storage technologies. \nIt may be created or accessed to recognise your device e.g. across web pages from the same site or across multiple sites or apps." + }, + "4": { + "id": 4, + "name": "Probabilistic identifiers", + "description": "A probabilistic identifier can be created by combining characteristics associated with your device (the type of browser or operating system used) and the IP address of the Internet connection. If you give your agreement, additional characteristics (e.g. the installed font or screen resolution) can also be combined to improve precision of the probabilistic identifier.\nSuch an identifier is considered \"probabilistic\" because several devices can share the same characteristics and Internet connection. It may be used to recognise your device across e.g. web pages from the same site or across multiple sites or apps." + }, + "5": { + "id": 5, + "name": "Authentication-derived identifiers", + "description": "Where an identifier is created on the basis of authentication data, such as contact details associated with online accounts you have created on websites or apps (e.g. e-mail address, phone number) or customer identifiers (e.g. identifier provided by your telecom operator), that identifier may be used to recognise you across websites, apps and devices when you are logged-in with the same contact details." + }, + "6": { + "id": 6, + "name": "Browsing and interaction data", + "description": "Your online activity such as the websites you visit, apps you are using, the content you search for on this service, or your interactions with content or ads, such as the number of times you have seen a specific content or ad or whether you clicked on it.\n" + }, + "7": { + "id": 7, + "name": "User-provided data", + "description": "The information you may have provided by way of declaration via a form (e.g. feedback, a comment) or when creating an account (e.g. your age, your occupation)." + }, + "8": { + "id": 8, + "name": "Non-precise location data", + "description": "An approximation of your location, expressed as an area with a radius of at least 500 meters. Your approximate location can be deduced from e.g. the IP address of your connection." + }, + "9": { + "id": 9, + "name": "Precise location data", + "description": "Your precise location within a radius of less than 500 meters based on your GPS coordinates. It may be used only with your acceptance." + }, + "10": { + "id": 10, + "name": "Users’ profiles", + "description": "Certain characteristics (e.g. your possible interests, your purchase intentions, your consumer profile) may be inferred or modeled from your previous online activity (e.g. the content you viewed or the service you used, your time spent on various online content and services) or the information you have provided (e.g. your age, your occupation)." + }, + "11": { + "id": 11, + "name": "Privacy choices", + "description": "Your preferences regarding the processing of your data, based on the information you have received." + } + }, + "vendors": { + "1": { + "id": 1, + "name": "Exponential Interactive, Inc d/b/a VDX.tv", + "purposes": [ + 1, + 2, + 3, + 4, + 7, + 8, + 9, + 10 + ], + "legIntPurposes": [], + "flexiblePurposes": [ + 7, + 8, + 9, + 10 + ], + "specialPurposes": [ + 1, + 2 + ], + "features": [ + 1, + 2, + 3 + ], + "specialFeatures": [], + "cookieMaxAgeSeconds": 7776000, + "usesCookies": true, + "cookieRefresh": true, + "usesNonCookieAccess": false, + "dataRetention": { + "stdRetention": 397, + "purposes": {}, + "specialPurposes": {} + }, + "urls": [ + { + "langId": "en", + "privacy": "https://vdx.tv/privacy/", + "legIntClaim": "https://cdnx.exponential.com/wp-content/uploads/2018/04/Balancing-Assessment-for-Legitimate-Interest-Publishers-v2.pdf" + } + ], + "dataDeclaration": [ + 1, + 3, + 4, + 6, + 8, + 10, + 11 + ], + "deviceStorageDisclosureUrl": "https://vdxtv.expo.workers.dev" + }, + "2": { + "id": 2, + "name": "Captify Technologies Limited", + "purposes": [ + 1, + 2, + 3, + 4, + 7, + 9, + 10 + ], + "legIntPurposes": [], + "flexiblePurposes": [], + "specialPurposes": [ + 1, + 2 + ], + "features": [ + 2 + ], + "specialFeatures": [ + 2 + ], + "cookieMaxAgeSeconds": 31536000, + "usesCookies": true, + "cookieRefresh": true, + "usesNonCookieAccess": true, + "dataRetention": { + "stdRetention": 365, + "purposes": {}, + "specialPurposes": {} + }, + "urls": [ + { + "langId": "en", + "privacy": "https://www.captifytechnologies.com/privacy-notice/", + "legIntClaim": "https://www.captifytechnologies.com/privacy-notice/" + } + ], + "dataDeclaration": [ + 1, + 2, + 4, + 6, + 11 + ], + "deviceStorageDisclosureUrl": "https://static.cpx.to/gvl/deviceStorageDisclosure.json" + }, + "6": { + "id": 6, + "name": "AdSpirit GmbH", + "purposes": [ + 1, + 2, + 3, + 4, + 7, + 9 + ], + "legIntPurposes": [], + "flexiblePurposes": [], + "specialPurposes": [ + 1, + 2 + ], + "features": [ + 3 + ], + "specialFeatures": [], + "overflow": { + "httpGetLimit": 32 + }, + "cookieMaxAgeSeconds": 2592000, + "usesCookies": true, + "cookieRefresh": true, + "usesNonCookieAccess": false, + "dataRetention": { + "stdRetention": 60, + "purposes": { + "2": 14, + "7": 14 + }, + "specialPurposes": {} + }, + "urls": [ + { + "langId": "en", + "privacy": "https://help.adspirit.de/privacy.php", + "legIntClaim": "https://help.adspirit.de/privacy.php" + }, + { + "langId": "de", + "privacy": "https://help.adspirit.de/privacy.php", + "legIntClaim": "https://help.adspirit.de/privacy.php" + } + ], + "dataDeclaration": [ + 1, + 2, + 3, + 4, + 6, + 8, + 10, + 11 + ], + "deviceStorageDisclosureUrl": "https://help.adspirit.de/deviceStorage.json" + }, + "8": { + "id": 8, + "name": "Emerse Sverige AB", + "purposes": [ + 1, + 3, + 4 + ], + "legIntPurposes": [ + 2, + 7, + 8, + 9 + ], + "flexiblePurposes": [ + 2, + 9 + ], + "specialPurposes": [ + 1, + 2 + ], + "features": [ + 1, + 2 + ], + "specialFeatures": [], + "cookieMaxAgeSeconds": 2592000, + "usesCookies": true, + "cookieRefresh": false, + "usesNonCookieAccess": false, + "dataRetention": { + "stdRetention": 0, + "purposes": {}, + "specialPurposes": {} + }, + "urls": [ + { + "langId": "en", + "privacy": "https://www.emerse.com/privacy-policy/", + "legIntClaim": "https://www.emerse.com/privacy-policy/" + } + ], + "dataDeclaration": [ + 1, + 2, + 6, + 8, + 11 + ], + "deviceStorageDisclosureUrl": "https://s3.eu-west-1.amazonaws.com/cors.emerse.com/gdpr-tcf.json" + }, + "12": { + "id": 12, + "name": "BeeswaxIO Corporation", + "purposes": [ + 1, + 2, + 3, + 4, + 7 + ], + "legIntPurposes": [], + "flexiblePurposes": [], + "specialPurposes": [ + 1, + 2 + ], + "features": [ + 1, + 3 + ], + "specialFeatures": [ + 1 + ], + "cookieMaxAgeSeconds": 34109999, + "usesCookies": true, + "cookieRefresh": true, + "usesNonCookieAccess": true, + "dataRetention": { + "stdRetention": 0, + "purposes": { + "7": 4320 + }, + "specialPurposes": { + "1": 392, + "2": 4320 + } + }, + "urls": [ + { + "langId": "en", + "privacy": "https://www.beeswax.com/privacy/", + "legIntClaim": "https://www.beeswax.com/privacy/" + } + ], + "dataDeclaration": [ + 1, + 2, + 3, + 4, + 6, + 8, + 9, + 11 + ], + "deviceStorageDisclosureUrl": "https://beeswax.com/devicedisclosure.json" + }, + "20": { + "id": 20, + "name": "N.Rich Technologies Inc.", + "purposes": [ + 1, + 3, + 4, + 5 + ], + "legIntPurposes": [ + 2, + 7, + 8, + 9, + 10 + ], + "flexiblePurposes": [ + 2, + 7, + 8, + 9, + 10 + ], + "specialPurposes": [ + 1, + 2 + ], + "features": [ + 1, + 2 + ], + "specialFeatures": [ + 1 + ], + "cookieMaxAgeSeconds": 46656000, + "usesCookies": true, + "cookieRefresh": true, + "usesNonCookieAccess": false, + "dataRetention": { + "stdRetention": 540, + "purposes": {}, + "specialPurposes": {} + }, + "urls": [ + { + "langId": "en", + "privacy": "https://n.rich/privacy-notice", + "legIntClaim": "https://n.rich/privacy-notice" + } + ], + "dataDeclaration": [ + 1, + 2, + 3, + 5, + 6, + 7, + 8, + 10, + 11 + ], + "deviceStorageDisclosureUrl": "https://privacy.nrich.ai/.well-known/deviceStorage.json" + }, + "21": { + "id": 21, + "name": "The UK Trade Desk Ltd", + "purposes": [ + 1, + 3, + 4 + ], + "legIntPurposes": [ + 2, + 7, + 10 + ], + "flexiblePurposes": [ + 2, + 7, + 10 + ], + "specialPurposes": [ + 1, + 2 + ], + "features": [ + 1, + 2, + 3 + ], + "specialFeatures": [ + 1 + ], + "cookieMaxAgeSeconds": 313536000, + "usesCookies": true, + "cookieRefresh": true, + "usesNonCookieAccess": true, + "dataRetention": { + "stdRetention": 99, + "purposes": { + "2": 365, + "4": 132 + }, + "specialPurposes": {} + }, + "urls": [ + { + "langId": "en", + "privacy": "https://www.thetradedesk.com/us/privacy", + "legIntClaim": "https://www.thetradedesk.com/us/privacy" + } + ], + "dataDeclaration": [ + 1, + 2, + 3, + 4, + 5, + 6, + 8, + 9, + 10, + 11 + ], + "deviceStorageDisclosureUrl": " https://ttd-misc-public-assets.s3.us-west-2.amazonaws.com/deviceStorageDisclosureURL.json" + }, + "26": { + "id": 26, + "name": "Venatus Media Limited", + "purposes": [ + 1, + 2, + 3, + 4, + 7, + 8, + 9, + 10 + ], + "legIntPurposes": [], + "flexiblePurposes": [], + "specialPurposes": [], + "features": [ + 3 + ], + "specialFeatures": [], + "cookieMaxAgeSeconds": null, + "usesCookies": false, + "cookieRefresh": false, + "usesNonCookieAccess": true, + "dataRetention": { + "stdRetention": 0, + "purposes": {}, + "specialPurposes": {} + }, + "urls": [ + { + "langId": "en", + "privacy": "https://www.venatus.com/privacy/" + } + ], + "dataDeclaration": [ + 1, + 2, + 8 + ], + "deviceStorageDisclosureUrl": "https://www.venatus.com/tcf-gvl-disclosure.json" + }, + "27": { + "id": 27, + "name": "ADventori SAS", + "purposes": [ + 1, + 2, + 4, + 7 + ], + "legIntPurposes": [], + "flexiblePurposes": [ + 2, + 7 + ], + "specialPurposes": [ + 1, + 2 + ], + "features": [], + "specialFeatures": [], + "overflow": { + "httpGetLimit": 128 + }, + "cookieMaxAgeSeconds": 7776000, + "usesCookies": true, + "cookieRefresh": true, + "usesNonCookieAccess": true, + "dataRetention": { + "stdRetention": 400, + "purposes": { + "2": 90, + "4": 90 + }, + "specialPurposes": {} + }, + "urls": [ + { + "langId": "en", + "privacy": "https://www.adventori.com/with-us/legal-notice/", + "legIntClaim": "https://www.adventori.com/with-us/legal-notice/" + } + ], + "dataDeclaration": [ + 1, + 3, + 5, + 6, + 7, + 8 + ], + "deviceStorageDisclosureUrl": "https://adventori.com/.well-known/tcf-adventori-device-storage-disclosure.json" + }, + "29": { + "id": 29, + "name": "ETARGET SE", + "purposes": [ + 1, + 2, + 3, + 4, + 7, + 8, + 10 + ], + "legIntPurposes": [], + "flexiblePurposes": [], + "specialPurposes": [], + "features": [ + 1 + ], + "specialFeatures": [], + "cookieMaxAgeSeconds": 31536000, + "usesCookies": true, + "cookieRefresh": false, + "usesNonCookieAccess": false, + "dataRetention": { + "stdRetention": 60, + "purposes": {}, + "specialPurposes": {} + }, + "urls": [ + { + "langId": "en", + "privacy": "https://sk.search.etargetnet.com/policy.html" + } + ], + "dataDeclaration": [ + 1 + ], + "deviceStorageDisclosureUrl": "https://www.etarget.sk/cookies2.json" + }, + "30": { + "id": 30, + "name": "BidTheatre AB", + "purposes": [ + 1, + 3, + 4, + 7 + ], + "legIntPurposes": [ + 2 + ], + "flexiblePurposes": [ + 2 + ], + "specialPurposes": [ + 1, + 2 + ], + "features": [ + 2 + ], + "specialFeatures": [], + "cookieMaxAgeSeconds": 7776000, + "usesCookies": true, + "cookieRefresh": true, + "usesNonCookieAccess": false, + "dataRetention": { + "stdRetention": 7, + "purposes": { + "3": 60, + "4": 0, + "7": 180 + }, + "specialPurposes": { + "1": 30 + } + }, + "urls": [ + { + "langId": "en", + "privacy": "https://www.bidtheatre.com/privacy-policy", + "legIntClaim": "https://www.bidtheatre.com/resource/LIA_ferq.pdf" + } + ], + "dataDeclaration": [ + 1, + 2, + 3, + 4, + 5, + 6, + 8, + 10, + 11 + ], + "deviceStorageDisclosureUrl": "https://www.bidtheatre.com/deviceStorage.json" + }, + "31": { + "id": 31, + "name": "Ogury Ltd", + "purposes": [ + 1 + ], + "legIntPurposes": [ + 2, + 7, + 9, + 10 + ], + "flexiblePurposes": [ + 2, + 7, + 9, + 10 + ], + "specialPurposes": [ + 1, + 2 + ], + "features": [ + 1 + ], + "specialFeatures": [], + "cookieMaxAgeSeconds": 182, + "usesCookies": true, + "cookieRefresh": true, + "usesNonCookieAccess": true, + "dataRetention": { + "stdRetention": 400, + "purposes": {}, + "specialPurposes": {} + }, + "urls": [ + { + "langId": "en", + "privacy": "https://ogury.com/privacy-policy/", + "legIntClaim": "https://ogury.com/privacy-policy/" + } + ], + "dataDeclaration": [ + 1, + 2, + 3, + 6, + 7, + 8, + 11 + ], + "deviceStorageDisclosureUrl": "https://consent-form.ogury.co/disclosure.json" + }, + "32": { + "id": 32, + "name": "Xandr, Inc.", + "purposes": [ + 1, + 3, + 4 + ], + "legIntPurposes": [ + 2, + 7, + 10 + ], + "flexiblePurposes": [ + 2, + 7, + 10 + ], + "specialPurposes": [ + 1, + 2 + ], + "features": [ + 2, + 3 + ], + "specialFeatures": [ + 1 + ], + "cookieMaxAgeSeconds": 7776000, + "usesCookies": true, + "cookieRefresh": true, + "usesNonCookieAccess": true, + "dataRetention": { + "stdRetention": 0, + "purposes": { + "2": 180, + "7": 60, + "10": 60 + }, + "specialPurposes": { + "1": 540 + } + }, + "urls": [ + { + "langId": "en", + "privacy": "https://www.xandr.com/privacy/platform-privacy-policy/", + "legIntClaim": "https://about.ads.microsoft.com/en-us/solutions/xandr/platform-privacy-policy#p_lt_ctl01_pageplaceholder_p_lt_ctl00_pageplaceholder_p_lt_WebPartZone3_zonePageBody_BingAds_PageContentViewer_PageContentViewerAll_ctl18_ctl00_ColumnsContainer" + }, + { + "langId": "pt", + "privacy": "https://about.ads.microsoft.com/pt-br/solutions/xandr/politica-de-privacidade-da-plataforma", + "legIntClaim": "https://about.ads.microsoft.com/pt-br/solutions/xandr/politica-de-privacidade-da-plataforma#p_lt_ctl01_pageplaceholder_p_lt_ctl00_pageplaceholder_p_lt_WebPartZone3_zonePageBody_BingAds_PageContentViewer_PageContentViewerAll_ctl16_ctl00_ColumnsContainer" + } + ], + "dataDeclaration": [ + 1, + 2, + 3, + 5, + 6, + 8, + 9, + 10, + 11 + ], + "deviceStorageDisclosureUrl": "https://acdn.adnxs.com/gvl/1d/xandrdevicestoragedisclosures.json" + }, + "33": { + "id": 33, + "name": "ShareThis, Inc", + "purposes": [ + 1, + 3, + 5 + ], + "legIntPurposes": [], + "flexiblePurposes": [], + "specialPurposes": [], + "features": [ + 1, + 2, + 3 + ], + "specialFeatures": [], + "cookieMaxAgeSeconds": 33696000, + "usesCookies": true, + "cookieRefresh": false, + "usesNonCookieAccess": false, + "dataRetention": { + "stdRetention": 365, + "purposes": {}, + "specialPurposes": {} + }, + "urls": [ + { + "langId": "en", + "privacy": "https://sharethis.com/privacy/" + }, + { + "langId": "fr", + "privacy": "https://pcdn.sharethis.com/wp-content/uploads/2021/11/ShareThis-Privacy-Policy-11.2.21_FR.pdf" + }, + { + "langId": "es", + "privacy": "https://pcdn.sharethis.com/wp-content/uploads/2021/11/ShareThis-Privacy-Policy-11.2.21_ES.pdf" + }, + { + "langId": "it", + "privacy": "https://pcdn.sharethis.com/wp-content/uploads/2021/11/ShareThis-Privacy-Policy-11.2.21_IT.pdf" + } + ], + "dataDeclaration": [ + 1, + 2, + 3, + 4, + 6, + 8, + 10, + 11 + ], + "deviceStorageDisclosureUrl": "https://c.sharethis.mgr.consensu.org/disclosures.json" + }, + "34": { + "id": 34, + "name": "NEORY GmbH", + "purposes": [ + 1, + 2, + 3, + 4, + 5, + 6, + 7, + 8, + 9, + 10, + 11 + ], + "legIntPurposes": [], + "flexiblePurposes": [ + 2, + 7, + 8, + 9, + 10, + 11 + ], + "specialPurposes": [ + 1, + 2 + ], + "features": [ + 2, + 3 + ], + "specialFeatures": [], + "overflow": { + "httpGetLimit": 128 + }, + "cookieMaxAgeSeconds": 7776000, + "usesCookies": true, + "cookieRefresh": true, + "usesNonCookieAccess": false, + "dataRetention": { + "stdRetention": 90, + "purposes": {}, + "specialPurposes": {} + }, + "urls": [ + { + "langId": "en", + "privacy": "https://www.neory.com/privacy.html", + "legIntClaim": "https://www.neory.com/privacy.html" + } + ], + "dataDeclaration": [ + 1, + 2, + 3, + 4, + 5, + 6, + 7, + 8, + 10, + 11 + ], + "deviceStorageDisclosureUrl": "https://ad.ad-srv.net/privacy/tcf/deviceStorage/6505e3798148a611.json" + }, + "37": { + "id": 37, + "name": "NEURAL.ONE", + "purposes": [ + 1, + 3, + 4, + 7 + ], + "legIntPurposes": [], + "flexiblePurposes": [], + "specialPurposes": [ + 1, + 2 + ], + "features": [ + 1, + 2 + ], + "specialFeatures": [ + 2 + ], + "cookieMaxAgeSeconds": 31536000, + "usesCookies": true, + "cookieRefresh": true, + "usesNonCookieAccess": true, + "dataRetention": { + "stdRetention": 90, + "purposes": {}, + "specialPurposes": {} + }, + "urls": [ + { + "langId": "en", + "privacy": "https://web.neural.one/privacy-policy/", + "legIntClaim": "https://web.neural.one/privacy-policy/" + } + ], + "dataDeclaration": [ + 1, + 2, + 4, + 6, + 8, + 11 + ], + "deviceStorageDisclosureUrl": "https://web.neural.one/.well-known/deviceStorage.json" + }, + "39": { + "id": 39, + "name": "ADITION (Virtual Minds GmbH)", + "purposes": [ + 1, + 2, + 3, + 4, + 7, + 9, + 10 + ], + "legIntPurposes": [], + "flexiblePurposes": [ + 2, + 7, + 9, + 10 + ], + "specialPurposes": [ + 1, + 2 + ], + "features": [ + 1, + 2, + 3 + ], + "specialFeatures": [ + 1 + ], + "cookieMaxAgeSeconds": 31536000, + "usesCookies": true, + "cookieRefresh": true, + "usesNonCookieAccess": false, + "dataRetention": { + "stdRetention": 90, + "purposes": { + "7": 30, + "9": 7, + "10": 7 + }, + "specialPurposes": { + "1": 3, + "2": 3 + } + }, + "urls": [ + { + "langId": "en", + "privacy": "https://www.adition.com/en/privacy-platform", + "legIntClaim": "https://www.adition.com/en/privacy-platform" + }, + { + "langId": "de", + "privacy": "https://www.adition.com/datenschutz-plattform/", + "legIntClaim": "https://www.adition.com/datenschutz-plattform/" + } + ], + "dataDeclaration": [ + 1, + 2, + 3, + 4, + 6, + 7, + 8, + 9, + 10, + 11 + ], + "deviceStorageDisclosureUrl": "https://imagesrv.adition.com/tcf/deviceStorage_adition.json" + }, + "40": { + "id": 40, + "name": "Active Agent (Virtual Minds GmbH)", + "purposes": [ + 1, + 2, + 3, + 4, + 7, + 9, + 10 + ], + "legIntPurposes": [], + "flexiblePurposes": [ + 2, + 7, + 9, + 10 + ], + "specialPurposes": [ + 1, + 2 + ], + "features": [ + 1, + 2, + 3 + ], + "specialFeatures": [ + 1 + ], + "cookieMaxAgeSeconds": 31536000, + "usesCookies": true, + "cookieRefresh": true, + "usesNonCookieAccess": false, + "dataRetention": { + "stdRetention": 90, + "purposes": { + "7": 30, + "9": 7, + "10": 7 + }, + "specialPurposes": { + "1": 3, + "2": 3 + } + }, + "urls": [ + { + "langId": "en", + "privacy": "https://www.adition.com/en/privacy-platform", + "legIntClaim": "https://www.adition.com/en/privacy-platform" + }, + { + "langId": "de", + "privacy": "https://www.adition.com/datenschutz-plattform/", + "legIntClaim": "https://www.adition.com/datenschutz-plattform/" + } + ], + "dataDeclaration": [ + 1, + 2, + 3, + 4, + 6, + 7, + 8, + 9, + 10, + 11 + ], + "deviceStorageDisclosureUrl": "https://imagesrv.adition.com/tcf/deviceStorage_activeagent.json" + }, + "44": { + "id": 44, + "name": "Adex (Virtual Minds GmbH)", + "purposes": [ + 1, + 2, + 3, + 4, + 5, + 6, + 7, + 8, + 9, + 10, + 11 + ], + "legIntPurposes": [], + "flexiblePurposes": [], + "specialPurposes": [ + 1, + 2 + ], + "features": [ + 1, + 2, + 3 + ], + "specialFeatures": [ + 1 + ], + "cookieMaxAgeSeconds": 7776000, + "usesCookies": true, + "cookieRefresh": true, + "usesNonCookieAccess": true, + "dataRetention": { + "stdRetention": 90, + "purposes": {}, + "specialPurposes": {} + }, + "urls": [ + { + "langId": "en", + "privacy": "https://theadex.com/privacy-platform/", + "legIntClaim": "https://theadex.com/privacy-platform/" + }, + { + "langId": "de", + "privacy": "https://theadex.com/datenschutz-plattform/", + "legIntClaim": "https://theadex.com/datenschutz-plattform/" + } + ], + "dataDeclaration": [ + 1, + 2, + 3, + 4, + 6, + 7, + 8, + 9, + 10, + 11 + ], + "deviceStorageDisclosureUrl": "https://dmp.theadex.com/.well-known/deviceStorage.json" + }, + "45": { + "id": 45, + "name": "Smart Adserver", + "purposes": [ + 1, + 2, + 4, + 7, + 10 + ], + "legIntPurposes": [], + "flexiblePurposes": [], + "specialPurposes": [ + 1, + 2 + ], + "features": [ + 3 + ], + "specialFeatures": [ + 1 + ], + "cookieMaxAgeSeconds": 34214395, + "usesCookies": true, + "cookieRefresh": false, + "usesNonCookieAccess": true, + "dataRetention": { + "stdRetention": 40, + "purposes": {}, + "specialPurposes": {} + }, + "urls": [ + { + "langId": "en", + "privacy": "https://smartadserver.com/end-user-privacy-policy/", + "legIntClaim": "https://smartadserver.com/end-user-privacy-policy/" + } + ], + "dataDeclaration": [ + 1, + 2, + 3, + 4, + 5, + 6, + 8, + 9, + 10, + 11 + ], + "deviceStorageDisclosureUrl": "https://apps.smartadserver.com/device-storage-disclosures/equativDeviceStorageDisclosures.json" + }, + "46": { + "id": 46, + "name": "Skimbit Ltd", + "purposes": [], + "legIntPurposes": [ + 7, + 8 + ], + "flexiblePurposes": [ + 7, + 8 + ], + "specialPurposes": [ + 1, + 2 + ], + "features": [ + 3 + ], + "specialFeatures": [], + "cookieMaxAgeSeconds": null, + "usesCookies": false, + "cookieRefresh": false, + "usesNonCookieAccess": false, + "dataRetention": { + "stdRetention": 0, + "purposes": {}, + "specialPurposes": {} + }, + "urls": [ + { + "langId": "en", + "privacy": "https://skimlinks.com/privacy-policies/", + "legIntClaim": "https://skimlinks.com/privacy-policies/" + } + ], + "dataDeclaration": [ + 1, + 2, + 6, + 8, + 11 + ], + "deviceStorageDisclosureUrl": "https://storage.googleapis.com/skimthru-js/js/skimlinks_tcf_disclosures.json" + }, + "52": { + "id": 52, + "name": "Magnite, Inc. ", + "purposes": [ + 1, + 3, + 4, + 5 + ], + "legIntPurposes": [ + 2, + 7, + 10, + 11 + ], + "flexiblePurposes": [ + 2, + 7, + 10, + 11 + ], + "specialPurposes": [ + 1, + 2 + ], + "features": [ + 2, + 3 + ], + "specialFeatures": [ + 1 + ], + "overflow": { + "httpGetLimit": 128 + }, + "cookieMaxAgeSeconds": 31536000, + "usesCookies": true, + "cookieRefresh": false, + "usesNonCookieAccess": true, + "dataRetention": { + "stdRetention": 28, + "purposes": { + "10": 90 + }, + "specialPurposes": {} + }, + "urls": [ + { + "langId": "en", + "privacy": "https://www.magnite.com/legal/advertising-technology-privacy-policy/", + "legIntClaim": "https://www.magnite.com/legal/advertising-technology-privacy-policy/" + } + ], + "dataDeclaration": [ + 1, + 2, + 3, + 4, + 6, + 8, + 9, + 11 + ], + "deviceStorageDisclosureUrl": "https://gdpr.rubiconproject.com/dvplus/devicestoragedisclosure.json" + }, + "53": { + "id": 53, + "name": "Sirdata", + "purposes": [ + 1, + 3, + 4, + 5, + 6 + ], + "legIntPurposes": [ + 2, + 7, + 8, + 9, + 10, + 11 + ], + "flexiblePurposes": [ + 2, + 7, + 8, + 9, + 10, + 11 + ], + "specialPurposes": [ + 1, + 2 + ], + "features": [ + 1, + 2, + 3 + ], + "specialFeatures": [], + "overflow": { + "httpGetLimit": 128 + }, + "cookieMaxAgeSeconds": 31536000, + "usesCookies": true, + "cookieRefresh": true, + "usesNonCookieAccess": true, + "dataRetention": { + "stdRetention": 185, + "purposes": {}, + "specialPurposes": {} + }, + "urls": [ + { + "langId": "en", + "privacy": "https://www.sirdata.com/en/Privacy", + "legIntClaim": "https://www.sirdata.com/en/Privacy#legitimateinterest" + }, + { + "langId": "fr", + "privacy": "https://www.sirdata.com/fr/Vie-Privee", + "legIntClaim": "https://www.sirdata.com/fr/Vie-Privee#legitimateinterest" + }, + { + "langId": "bg", + "privacy": "https://www.sirdata.com/en/Privacy-bg", + "legIntClaim": "https://www.sirdata.com/en/Privacy-bg#legitimateinterest" + }, + { + "langId": "zh", + "privacy": "https://www.sirdata.com/en/Privacy-zh", + "legIntClaim": "https://www.sirdata.com/en/Privacy-zh#legitimateinterest" + }, + { + "langId": "cs", + "privacy": "https://www.sirdata.com/en/Privacy-cs", + "legIntClaim": "https://www.sirdata.com/en/Privacy-cs#legitimateinterest" + }, + { + "langId": "da", + "privacy": "https://www.sirdata.com/en/Privacy-da", + "legIntClaim": "https://www.sirdata.com/en/Privacy-da#legitimateinterest" + }, + { + "langId": "nl", + "privacy": "https://www.sirdata.com/en/Privacy-nl", + "legIntClaim": "https://www.sirdata.com/en/Privacy-nl#legitimateinterest" + }, + { + "langId": "et", + "privacy": "https://www.sirdata.com/en/Privacy-et", + "legIntClaim": "https://www.sirdata.com/en/Privacy-et#legitimateinterest" + }, + { + "langId": "fi", + "privacy": "https://www.sirdata.com/en/Privacy-fi", + "legIntClaim": "https://www.sirdata.com/en/Privacy-fi#legitimateinterest" + }, + { + "langId": "de", + "privacy": "https://www.sirdata.com/en/Privacy-de", + "legIntClaim": "https://www.sirdata.com/en/Privacy-de#legitimateinterest" + }, + { + "langId": "el", + "privacy": "https://www.sirdata.com/en/Privacy-el", + "legIntClaim": "https://www.sirdata.com/en/Privacy-el#legitimateinterest" + }, + { + "langId": "hu", + "privacy": "https://www.sirdata.com/en/Privacy-hu", + "legIntClaim": "https://www.sirdata.com/en/Privacy-hu#legitimateinterest" + }, + { + "langId": "it", + "privacy": "https://www.sirdata.com/en/Privacy-it", + "legIntClaim": "https://www.sirdata.com/en/Privacy-it#legitimateinterest" + }, + { + "langId": "ja", + "privacy": "https://www.sirdata.com/en/Privacy-ja", + "legIntClaim": "https://www.sirdata.com/en/Privacy-ja#legitimateinterest" + }, + { + "langId": "lv", + "privacy": "https://www.sirdata.com/en/Privacy-lv", + "legIntClaim": "https://www.sirdata.com/en/Privacy-lv#legitimateinterest" + }, + { + "langId": "lt", + "privacy": "https://www.sirdata.com/en/Privacy-lt", + "legIntClaim": "https://www.sirdata.com/en/Privacy-lt#legitimateinterest" + }, + { + "langId": "no", + "privacy": "https://www.sirdata.com/en/Privacy-no", + "legIntClaim": "https://www.sirdata.com/en/Privacy-no#legitimateinterest" + }, + { + "langId": "pl", + "privacy": "https://www.sirdata.com/en/Privacy-pl", + "legIntClaim": "https://www.sirdata.com/en/Privacy-pl#legitimateinterest" + }, + { + "langId": "pt", + "privacy": "https://www.sirdata.com/en/Privacy-pt-PT", + "legIntClaim": "https://www.sirdata.com/en/Privacy-pt-PT#legitimateinterest" + }, + { + "langId": "ro", + "privacy": "https://www.sirdata.com/en/Privacy-ro", + "legIntClaim": "https://www.sirdata.com/en/Privacy-ro#legitimateinterest" + }, + { + "langId": "ru", + "privacy": "https://www.sirdata.com/en/Privacy-ru", + "legIntClaim": "https://www.sirdata.com/en/Privacy-ru#legitimateinterest" + }, + { + "langId": "sk", + "privacy": "https://www.sirdata.com/en/Privacy-sk", + "legIntClaim": "https://www.sirdata.com/en/Privacy-sk#legitimateinterest" + }, + { + "langId": "sl", + "privacy": "https://www.sirdata.com/en/Privacy-sl", + "legIntClaim": "https://www.sirdata.com/en/Privacy-sl#legitimateinterest" + }, + { + "langId": "es", + "privacy": "https://www.sirdata.com/en/Privacy-es", + "legIntClaim": "https://www.sirdata.com/en/Privacy-es#legitimateinterest" + }, + { + "langId": "sv", + "privacy": "https://www.sirdata.com/en/Privacy-sv", + "legIntClaim": "https://www.sirdata.com/en/Privacy-sv#legitimateinterest" + }, + { + "langId": "tr", + "privacy": "https://www.sirdata.com/en/Privacy-tr", + "legIntClaim": "https://www.sirdata.com/en/Privacy-tr#legitimateinterest" + } + ], + "dataDeclaration": [ + 1, + 2, + 3, + 4, + 5, + 6, + 7, + 8, + 10, + 11 + ], + "deviceStorageDisclosureUrl": "https://cdn.sirdata.eu/sirdata_device_storage_disclosure.json" + }, + "57": { + "id": 57, + "name": "RATEGAIN ADARA INC", + "purposes": [ + 1, + 2, + 3, + 4, + 7, + 9, + 10 + ], + "legIntPurposes": [], + "flexiblePurposes": [], + "specialPurposes": [ + 1, + 2 + ], + "features": [ + 1, + 2, + 3 + ], + "specialFeatures": [], + "cookieMaxAgeSeconds": 63072000, + "usesCookies": true, + "cookieRefresh": false, + "usesNonCookieAccess": false, + "dataRetention": { + "purposes": { + "2": 365, + "3": 365, + "4": 365, + "7": 730, + "9": 730, + "10": 730 + }, + "specialPurposes": { + "1": 730, + "2": 365 + } + }, + "urls": [ + { + "langId": "en", + "privacy": "https://adara.com/privacy-promise/", + "legIntClaim": "https://adara.com/privacy-promise/" + } + ], + "dataDeclaration": [ + 1, + 2, + 3, + 5, + 6, + 7, + 8, + 10, + 11 + ], + "deviceStorageDisclosureUrl": "https://storage.googleapis.com/adara-public/iab/device-storage-disclosure.json" + }, + "61": { + "id": 61, + "name": "GumGum, Inc.", + "purposes": [ + 1, + 2, + 3, + 4, + 7 + ], + "legIntPurposes": [], + "flexiblePurposes": [ + 2, + 7 + ], + "specialPurposes": [ + 1, + 2 + ], + "features": [ + 3 + ], + "specialFeatures": [], + "cookieMaxAgeSeconds": 31536000, + "usesCookies": true, + "cookieRefresh": false, + "usesNonCookieAccess": false, + "dataRetention": { + "stdRetention": 400, + "purposes": { + "3": 720, + "4": 720 + }, + "specialPurposes": {} + }, + "urls": [ + { + "langId": "en", + "privacy": "https://www.gumgum.com/terms-and-policies/privacy-policy", + "legIntClaim": "https://gumgum.com/terms-and-policies/privacy-policy" + } + ], + "dataDeclaration": [ + 1, + 2, + 3, + 4, + 6, + 8, + 10, + 11 + ], + "deviceStorageDisclosureUrl": "https://marketing.gumgum.com/devicestoragedisclosures.json" + }, + "62": { + "id": 62, + "name": "Justpremium BV", + "purposes": [ + 1, + 2, + 7 + ], + "legIntPurposes": [], + "flexiblePurposes": [], + "specialPurposes": [ + 1, + 2 + ], + "features": [], + "specialFeatures": [], + "cookieMaxAgeSeconds": 31536000, + "usesCookies": true, + "cookieRefresh": true, + "usesNonCookieAccess": false, + "dataRetention": { + "stdRetention": 400, + "purposes": {}, + "specialPurposes": {} + }, + "urls": [ + { + "langId": "en", + "privacy": "https://justpremium.com/privacy-policy/", + "legIntClaim": "https://justpremium.com/privacy-policy/" + } + ], + "dataDeclaration": [ + 1, + 2, + 6, + 8, + 11 + ], + "deviceStorageDisclosureUrl": "https://cdn.justpremium.com/devicestoragedisclosures.json" + }, + "66": { + "id": 66, + "name": "adsquare GmbH", + "purposes": [ + 1, + 2, + 3, + 4, + 5, + 6, + 7, + 8, + 9, + 10, + 11 + ], + "legIntPurposes": [], + "flexiblePurposes": [ + 2, + 7, + 8, + 9, + 10, + 11 + ], + "specialPurposes": [], + "features": [ + 1, + 2, + 3 + ], + "specialFeatures": [ + 1 + ], + "cookieMaxAgeSeconds": null, + "usesCookies": false, + "cookieRefresh": false, + "usesNonCookieAccess": true, + "dataRetention": { + "stdRetention": 400, + "purposes": { + "2": 0, + "11": 0 + }, + "specialPurposes": {} + }, + "urls": [ + { + "langId": "en", + "privacy": "https://adsquare.com/privacy/", + "legIntClaim": "https://adsquare.com/privacy/" + } + ], + "dataDeclaration": [ + 1, + 2, + 3, + 4, + 5, + 6, + 7, + 8, + 9, + 10 + ], + "deviceStorageDisclosureUrl": "https://adsquare.com/deviceStorage.json" + }, + "70": { + "id": 70, + "name": "Yieldlab (Virtual Minds GmbH)", + "purposes": [ + 1, + 2, + 3, + 4, + 7, + 10 + ], + "legIntPurposes": [], + "flexiblePurposes": [], + "specialPurposes": [ + 1, + 2 + ], + "features": [ + 1, + 2, + 3 + ], + "specialFeatures": [ + 1 + ], + "overflow": { + "httpGetLimit": 128 + }, + "cookieMaxAgeSeconds": 31536000, + "usesCookies": true, + "cookieRefresh": true, + "usesNonCookieAccess": false, + "dataRetention": { + "stdRetention": 4, + "purposes": { + "2": 30, + "3": 30, + "4": 30 + }, + "specialPurposes": {} + }, + "urls": [ + { + "langId": "de", + "privacy": "https://www.yieldlab.com/datenschutz/", + "legIntClaim": "https://www.yieldlab.com/datenschutz/" + }, + { + "langId": "en", + "privacy": "https://yieldlab.com/privacy-platform/", + "legIntClaim": "https://yieldlab.com/privacy-platform/" + } + ], + "dataDeclaration": [ + 1, + 2, + 3, + 6, + 7, + 8, + 9, + 10, + 11 + ], + "deviceStorageDisclosureUrl": "https://ad.yieldlab.net/deviceStorage.json" + }, + "75": { + "id": 75, + "name": "M32 Connect Inc", + "purposes": [ + 1, + 2, + 3, + 4, + 8, + 10 + ], + "legIntPurposes": [], + "flexiblePurposes": [], + "specialPurposes": [], + "features": [ + 1, + 2, + 3 + ], + "specialFeatures": [ + 2 + ], + "cookieMaxAgeSeconds": 2592000, + "usesCookies": true, + "cookieRefresh": true, + "usesNonCookieAccess": false, + "dataRetention": { + "stdRetention": 180, + "purposes": {}, + "specialPurposes": {} + }, + "urls": [ + { + "langId": "en", + "privacy": "https://m32connect.com/privacy-consent-management/privacy-cookie-policy/", + "legIntClaim": "https://m32connect.com/privacy-consent-management/privacy-cookie-policy/" + }, + { + "langId": "fr", + "privacy": "https://m32connect.com/fr/vie-privee-et-gestion-du-consentement/politique-de-confidentialite/", + "legIntClaim": "https://m32connect.com/fr/vie-privee-et-gestion-du-consentement/politique-de-confidentialite/" + } + ], + "dataDeclaration": [ + 1, + 2, + 5, + 6, + 8 + ], + "deviceStorageDisclosureUrl": "https://rdc.m32.media/gdpr/vendors_disclosure.json" + }, + "77": { + "id": 77, + "name": "Comscore B.V.", + "purposes": [ + 1, + 7, + 8, + 9, + 10 + ], + "legIntPurposes": [], + "flexiblePurposes": [], + "specialPurposes": [], + "features": [ + 1, + 2, + 3 + ], + "specialFeatures": [], + "cookieMaxAgeSeconds": 62208000, + "usesCookies": true, + "cookieRefresh": true, + "usesNonCookieAccess": true, + "dataRetention": { + "stdRetention": 90, + "purposes": {}, + "specialPurposes": {} + }, + "urls": [ + { + "langId": "en", + "privacy": "https://www.scorecardresearch.com/privacy.aspx" + } + ], + "dataDeclaration": [ + 1, + 2, + 3, + 4, + 5, + 6, + 7, + 11 + ], + "deviceStorageDisclosureUrl": "https://census-web.scorecardresearch.com/tcf_vendor_disclosures.json" + }, + "83": { + "id": 83, + "name": "Visarity Technologies GmbH", + "purposes": [], + "legIntPurposes": [ + 8 + ], + "flexiblePurposes": [ + 8 + ], + "specialPurposes": [ + 2 + ], + "features": [], + "specialFeatures": [], + "cookieMaxAgeSeconds": null, + "usesCookies": false, + "cookieRefresh": false, + "usesNonCookieAccess": false, + "dataRetention": { + "stdRetention": 0, + "purposes": {}, + "specialPurposes": {} + }, + "urls": [ + { + "langId": "en", + "privacy": "https://primo.design/docs/PrivacyPolicyPrimo.html", + "legIntClaim": "https://primo.design/docs/PrivacyPolicyPrimo.html" + } + ], + "dataDeclaration": [ + 1 + ], + "deviceStorageDisclosureUrl": "https://script.visarity.com/tcf/tcf-visarity.json" + }, + "85": { + "id": 85, + "name": "Crimtan Holdings Limited", + "purposes": [ + 1, + 3, + 4 + ], + "legIntPurposes": [ + 2, + 7, + 8, + 9, + 10 + ], + "flexiblePurposes": [ + 2, + 7, + 8, + 9, + 10 + ], + "specialPurposes": [ + 1, + 2 + ], + "features": [ + 1, + 3 + ], + "specialFeatures": [ + 1 + ], + "cookieMaxAgeSeconds": 31536000, + "usesCookies": true, + "cookieRefresh": true, + "usesNonCookieAccess": false, + "dataRetention": { + "stdRetention": 365, + "purposes": { + "7": 1095, + "10": 1095 + }, + "specialPurposes": { + "2": 1095 + } + }, + "urls": [ + { + "langId": "en", + "privacy": "https://www.crimtan.com/privacy-policy/", + "legIntClaim": "https://www.crimtan.com/privacy-policy/" + } + ], + "dataDeclaration": [ + 1, + 2, + 3, + 4, + 5, + 6, + 7, + 8, + 9, + 10, + 11 + ], + "deviceStorageDisclosureUrl": "https://a.ctnsnet.com/tcf.json" + }, + "87": { + "id": 87, + "name": "Betgenius Ltd", + "purposes": [ + 1, + 2, + 3, + 4, + 7, + 8, + 9, + 10 + ], + "legIntPurposes": [], + "flexiblePurposes": [], + "specialPurposes": [], + "features": [ + 1, + 2, + 3 + ], + "specialFeatures": [], + "cookieMaxAgeSeconds": 31536000, + "usesCookies": true, + "cookieRefresh": true, + "usesNonCookieAccess": false, + "dataRetention": { + "stdRetention": 365, + "purposes": {}, + "specialPurposes": {} + }, + "urls": [ + { + "langId": "en", + "privacy": "https://geniussports.com/policies/privacy-policy/" + } + ], + "dataDeclaration": [ + 1, + 2, + 3, + 4, + 5, + 6, + 8, + 10, + 11 + ], + "deviceStorageDisclosureUrl": "https://gsm-tcf.s3.eu-west-1.amazonaws.com/gsm-tcf.json" + }, + "90": { + "id": 90, + "name": "Teroa S.A.", + "purposes": [ + 1, + 2, + 7, + 9 + ], + "legIntPurposes": [], + "flexiblePurposes": [], + "specialPurposes": [ + 1 + ], + "features": [], + "specialFeatures": [], + "cookieMaxAgeSeconds": 220752000, + "usesCookies": true, + "cookieRefresh": true, + "usesNonCookieAccess": false, + "dataRetention": { + "stdRetention": 3650, + "purposes": { + "2": 0 + }, + "specialPurposes": {} + }, + "urls": [ + { + "langId": "en", + "privacy": "https://www.e-planning.net/privacy-policy.html", + "legIntClaim": "https://www.e-planning.net/privacy-policy.html" + } + ], + "dataDeclaration": [ + 1, + 2, + 3, + 6, + 8 + ], + "deviceStorageDisclosureUrl": "https://www.e-planning.net/deviceStorageDisclosureUrl.json" + }, + "92": { + "id": 92, + "name": "1plusX AG", + "purposes": [ + 1, + 3, + 5 + ], + "legIntPurposes": [ + 7, + 8, + 9 + ], + "flexiblePurposes": [ + 7, + 8, + 9 + ], + "specialPurposes": [], + "features": [ + 1, + 2 + ], + "specialFeatures": [], + "cookieMaxAgeSeconds": 31536000, + "usesCookies": true, + "cookieRefresh": false, + "usesNonCookieAccess": true, + "dataRetention": { + "stdRetention": 90, + "purposes": {}, + "specialPurposes": {} + }, + "urls": [ + { + "langId": "en", + "privacy": "https://www.1plusx.com/privacy-policy/", + "legIntClaim": "https://www.1plusx.com/privacy-policy/" + } + ], + "dataDeclaration": [ + 1, + 2, + 3, + 6, + 7, + 10, + 11 + ], + "deviceStorageDisclosureUrl": "https://device-storage-disclosure.1plusx.io" + }, + "93": { + "id": 93, + "name": "Adloox SA", + "purposes": [ + 1 + ], + "legIntPurposes": [ + 7 + ], + "flexiblePurposes": [ + 7 + ], + "specialPurposes": [ + 1 + ], + "features": [], + "specialFeatures": [], + "overflow": { + "httpGetLimit": 128 + }, + "cookieMaxAgeSeconds": null, + "usesCookies": false, + "cookieRefresh": false, + "usesNonCookieAccess": true, + "dataRetention": { + "stdRetention": 396, + "purposes": {}, + "specialPurposes": {} + }, + "urls": [ + { + "langId": "en", + "privacy": "https://www.adloox.com/legal/privacy-policy", + "legIntClaim": "https://www.adloox.com/legal/privacy-policy" + } + ], + "dataDeclaration": [ + 1, + 2, + 3, + 4, + 6, + 8 + ], + "deviceStorageDisclosureUrl": "https://j.adlooxtracking.com/ads/tcf.json" + }, + "94": { + "id": 94, + "name": "Blis Global Limited", + "purposes": [ + 1, + 2, + 3, + 4, + 7, + 9, + 10 + ], + "legIntPurposes": [], + "flexiblePurposes": [ + 2 + ], + "specialPurposes": [ + 1, + 2 + ], + "features": [ + 1, + 2, + 3 + ], + "specialFeatures": [ + 1 + ], + "cookieMaxAgeSeconds": 34560000, + "usesCookies": true, + "cookieRefresh": true, + "usesNonCookieAccess": true, + "dataRetention": { + "stdRetention": 400, + "purposes": {}, + "specialPurposes": { + "2": 0 + } + }, + "urls": [ + { + "langId": "en", + "privacy": "https://blis.com/blis-privacy-policy-for-online-advertising-and-related-uses/", + "legIntClaim": "https://blis.com/legitimate-interests-statement/" + } + ], + "dataDeclaration": [ + 1, + 2, + 3, + 4, + 5, + 6, + 7, + 8, + 9, + 10, + 11 + ], + "deviceStorageDisclosureUrl": "https://privacy.blismedia.com/.well-known/deviceStorage.json" + }, + "100": { + "id": 100, + "name": "Fifty Technology Limited", + "purposes": [ + 1, + 2, + 3, + 4, + 9, + 10 + ], + "legIntPurposes": [], + "flexiblePurposes": [], + "specialPurposes": [ + 1, + 2 + ], + "features": [ + 1, + 2, + 3 + ], + "specialFeatures": [], + "cookieMaxAgeSeconds": 31536000, + "usesCookies": true, + "cookieRefresh": true, + "usesNonCookieAccess": false, + "dataRetention": { + "stdRetention": 183, + "purposes": {}, + "specialPurposes": {} + }, + "urls": [ + { + "langId": "en", + "privacy": "https://fifty.io/privacy-policy", + "legIntClaim": "https://fifty.io/privacy-policy" + } + ], + "dataDeclaration": [ + 1, + 2, + 3, + 4, + 6, + 8, + 10, + 11 + ], + "deviceStorageDisclosureUrl": "https://fifty.io/privacy/deviceStorage.json" + }, + "104": { + "id": 104, + "name": "Sonobi, Inc", + "purposes": [ + 1, + 2, + 3, + 4 + ], + "legIntPurposes": [ + 7, + 8 + ], + "flexiblePurposes": [], + "specialPurposes": [ + 2 + ], + "features": [ + 1 + ], + "specialFeatures": [], + "cookieMaxAgeSeconds": 5184000, + "usesCookies": true, + "cookieRefresh": false, + "usesNonCookieAccess": false, + "dataRetention": { + "stdRetention": 548, + "purposes": {}, + "specialPurposes": {} + }, + "urls": [ + { + "langId": "en", + "privacy": "https://sonobi.com/privacy-policy/", + "legIntClaim": "https://sonobi.com/privacy-policy/" + } + ], + "dataDeclaration": [ + 1, + 3, + 8 + ], + "deviceStorageDisclosureUrl": "https://sonobi.com/tcf2-device-storage-disclosure.json" + }, + "108": { + "id": 108, + "name": "Rich Audience Technologies SL", + "purposes": [ + 1, + 2, + 3, + 4, + 7, + 8, + 9, + 10, + 11 + ], + "legIntPurposes": [], + "flexiblePurposes": [], + "specialPurposes": [], + "features": [ + 2, + 3 + ], + "specialFeatures": [], + "overflow": { + "httpGetLimit": 128 + }, + "cookieMaxAgeSeconds": 31536000, + "usesCookies": true, + "cookieRefresh": true, + "usesNonCookieAccess": false, + "dataRetention": { + "stdRetention": 90, + "purposes": {}, + "specialPurposes": {} + }, + "urls": [ + { + "langId": "en", + "privacy": "https://richaudience.com/en/privacy/" + }, + { + "langId": "es", + "privacy": "https://richaudience.com/es/privacy/" + } + ], + "dataDeclaration": [ + 1, + 2, + 3, + 4, + 8 + ], + "deviceStorageDisclosureUrl": "https://cdnj.richaudience.com/52a26ab9400b2a9f5aabfa20acf3196g.json" + }, + "109": { + "id": 109, + "name": "LoopMe Limited", + "purposes": [ + 1, + 2, + 3, + 4, + 7, + 9 + ], + "legIntPurposes": [ + 10 + ], + "flexiblePurposes": [ + 2, + 7 + ], + "specialPurposes": [ + 1, + 2 + ], + "features": [ + 1, + 2, + 3 + ], + "specialFeatures": [ + 1, + 2 + ], + "overflow": { + "httpGetLimit": 32 + }, + "cookieMaxAgeSeconds": 7776000, + "usesCookies": true, + "cookieRefresh": true, + "usesNonCookieAccess": true, + "dataRetention": { + "stdRetention": 396, + "purposes": {}, + "specialPurposes": {} + }, + "urls": [ + { + "langId": "en", + "privacy": "https://legal.loopme.com/privacy-center#contract-hyartvn1o", + "legIntClaim": "https://legal.loopme.com/privacy-center#contract-hyartvn1o" + } + ], + "dataDeclaration": [ + 1, + 2, + 3, + 4, + 6, + 7, + 8, + 9, + 10, + 11 + ], + "deviceStorageDisclosureUrl": "https://co.loopme.com/deviceStorageDisclosure.json" + }, + "111": { + "id": 111, + "name": "Showheroes SE", + "purposes": [ + 1, + 3, + 4, + 9, + 10 + ], + "legIntPurposes": [ + 2, + 7, + 8, + 11 + ], + "flexiblePurposes": [ + 2, + 7, + 8 + ], + "specialPurposes": [ + 1, + 2 + ], + "features": [ + 1 + ], + "specialFeatures": [], + "cookieMaxAgeSeconds": 33955200, + "usesCookies": true, + "cookieRefresh": false, + "usesNonCookieAccess": false, + "dataRetention": { + "stdRetention": 393, + "purposes": {}, + "specialPurposes": {} + }, + "urls": [ + { + "langId": "en", + "privacy": "https://showheroes.com/privacy-policy/", + "legIntClaim": "https://showheroes.com/privacy-policy/" + } + ], + "dataDeclaration": [ + 1, + 3, + 8, + 11 + ], + "deviceStorageDisclosureUrl": "https://static-origin.showheroes.com/gvl_storage_disclosure.json" + }, + "114": { + "id": 114, + "name": "Sublime", + "purposes": [ + 1, + 2, + 3, + 4, + 7, + 9, + 10 + ], + "legIntPurposes": [], + "flexiblePurposes": [], + "specialPurposes": [], + "features": [], + "specialFeatures": [], + "cookieMaxAgeSeconds": 34164060, + "usesCookies": true, + "cookieRefresh": true, + "usesNonCookieAccess": true, + "dataRetention": { + "stdRetention": 90, + "purposes": { + "2": 0, + "7": 365, + "9": 365 + }, + "specialPurposes": {} + }, + "urls": [ + { + "langId": "en", + "privacy": "https://ayads.co/privacy.php" + } + ], + "dataDeclaration": [ + 1, + 6, + 11 + ], + "deviceStorageDisclosureUrl": "https://gdpr.ayads.co/cookiepolicy.json" + }, + "115": { + "id": 115, + "name": "smartclip Europe GmbH", + "purposes": [ + 1, + 3, + 4 + ], + "legIntPurposes": [ + 2, + 7, + 10 + ], + "flexiblePurposes": [ + 2, + 7, + 10 + ], + "specialPurposes": [ + 1, + 2 + ], + "features": [ + 2, + 3 + ], + "specialFeatures": [], + "cookieMaxAgeSeconds": 31536000, + "usesCookies": true, + "cookieRefresh": true, + "usesNonCookieAccess": true, + "dataRetention": { + "stdRetention": 120, + "purposes": { + "2": 30, + "3": 365, + "4": 365 + }, + "specialPurposes": {} + }, + "urls": [ + { + "langId": "de", + "privacy": "https://privacy-portal.smartclip.net/de/privacy-policy", + "legIntClaim": "https://privacy-portal.smartclip.net/de/privacy-policy" + }, + { + "langId": "en", + "privacy": "https://privacy-portal.smartclip.net/en/privacy-policy", + "legIntClaim": "https://privacy-portal.smartclip.net/en/privacy-policy" + } + ], + "dataDeclaration": [ + 1, + 2, + 3, + 6, + 7, + 8, + 10, + 11 + ], + "deviceStorageDisclosureUrl": "https://cdn.smartclip.net/iab/deviceStorageDisclosure.json" + }, + "124": { + "id": 124, + "name": "Near Intelligence", + "purposes": [ + 1, + 2, + 3, + 4, + 7 + ], + "legIntPurposes": [], + "flexiblePurposes": [], + "specialPurposes": [ + 1, + 2 + ], + "features": [ + 1 + ], + "specialFeatures": [ + 1 + ], + "cookieMaxAgeSeconds": null, + "usesCookies": false, + "cookieRefresh": false, + "usesNonCookieAccess": true, + "dataRetention": { + "stdRetention": 90, + "purposes": { + "7": 180 + }, + "specialPurposes": { + "1": 30, + "2": 30 + } + }, + "urls": [ + { + "langId": "en", + "privacy": "https://near.com/fr/privacy-policy/", + "legIntClaim": "https://near.com/fr/privacy-policy/" + } + ], + "dataDeclaration": [ + 1, + 2, + 3, + 6, + 8, + 9 + ], + "deviceStorageDisclosureUrl": "https://near.com/iab/disclosures.json" + }, + "126": { + "id": 126, + "name": "DoubleVerify Inc.​", + "purposes": [], + "legIntPurposes": [ + 2, + 7, + 10 + ], + "flexiblePurposes": [ + 2, + 7, + 10 + ], + "specialPurposes": [ + 1, + 2 + ], + "features": [], + "specialFeatures": [], + "cookieMaxAgeSeconds": null, + "usesCookies": false, + "cookieRefresh": false, + "usesNonCookieAccess": false, + "dataRetention": { + "stdRetention": 31, + "purposes": {}, + "specialPurposes": {} + }, + "urls": [ + { + "langId": "en", + "privacy": "https://doubleverify.com/privacy-notice/solutions-privacy-notice", + "legIntClaim": "https://doubleverify.com/privacy-notice/solutions-privacy-notice" + } + ], + "dataDeclaration": [ + 1, + 2, + 4, + 6, + 8, + 11 + ], + "deviceStorageDisclosureUrl": "https://cdn.doubleverify.com/static/Doubleverify_TCF.json" + }, + "131": { + "id": 131, + "name": "ID5 Technology Ltd", + "purposes": [ + 1 + ], + "legIntPurposes": [], + "flexiblePurposes": [], + "specialPurposes": [], + "features": [ + 2, + 3 + ], + "specialFeatures": [], + "cookieMaxAgeSeconds": 7776000, + "usesCookies": true, + "cookieRefresh": true, + "usesNonCookieAccess": true, + "dataRetention": { + "purposes": {}, + "specialPurposes": {} + }, + "urls": [ + { + "langId": "en", + "privacy": "https://id5.io/privacy" + } + ], + "dataDeclaration": [ + 1, + 2, + 3, + 4, + 5, + 6, + 11 + ], + "deviceStorageDisclosureUrl": "https://id5-sync.com/tcf/disclosures.json" + }, + "132": { + "id": 132, + "name": "Teads France SAS", + "purposes": [ + 1, + 3, + 4, + 7, + 9, + 10 + ], + "legIntPurposes": [ + 2 + ], + "flexiblePurposes": [ + 2 + ], + "specialPurposes": [ + 1, + 2 + ], + "features": [ + 1, + 2, + 3 + ], + "specialFeatures": [], + "cookieMaxAgeSeconds": 31536000, + "usesCookies": true, + "cookieRefresh": false, + "usesNonCookieAccess": true, + "dataRetention": { + "stdRetention": 120, + "purposes": {}, + "specialPurposes": {} + }, + "urls": [ + { + "langId": "en", + "privacy": "https://www.teads.com/privacy-policy/", + "legIntClaim": "https://privacy-policy.teads.com/privacy-policy/european-privacy-notice/" + }, + { + "langId": "fr", + "privacy": "https://privacy-policy.teads.com/privacy-policy/privacy-policy-general-notice-fr/", + "legIntClaim": "https://privacy-policy.teads.com/privacy-policy/politique-de-confidentialite-europe/" + } + ], + "dataDeclaration": [ + 1, + 2, + 3, + 4, + 6, + 8, + 10, + 11 + ], + "deviceStorageDisclosureUrl": "https://iab-cookie-disclosure.teads.tv/deviceStorage.json" + }, + "133": { + "id": 133, + "name": "digitalAudience B.V.", + "purposes": [ + 1, + 3, + 5, + 7, + 9 + ], + "legIntPurposes": [], + "flexiblePurposes": [], + "specialPurposes": [], + "features": [ + 1, + 2, + 3 + ], + "specialFeatures": [], + "cookieMaxAgeSeconds": 31557600, + "usesCookies": true, + "cookieRefresh": true, + "usesNonCookieAccess": false, + "dataRetention": { + "stdRetention": 365, + "purposes": {}, + "specialPurposes": {} + }, + "urls": [ + { + "langId": "en", + "privacy": "https://digitalaudience.io/legal/" + } + ], + "dataDeclaration": [ + 1, + 3, + 5, + 10, + 11 + ], + "deviceStorageDisclosureUrl": "https://dadocuments.blob.core.windows.net/documents/IAB-dA-Device-Storage-Disclosure-08092022.json" + }, + "134": { + "id": 134, + "name": "SMARTSTREAM.TV GmbH", + "purposes": [ + 1, + 3, + 4 + ], + "legIntPurposes": [ + 2, + 7, + 9, + 10 + ], + "flexiblePurposes": [ + 2, + 7, + 9, + 10 + ], + "specialPurposes": [ + 1, + 2 + ], + "features": [ + 1, + 2, + 3 + ], + "specialFeatures": [], + "overflow": { + "httpGetLimit": 32 + }, + "cookieMaxAgeSeconds": 31536000, + "usesCookies": true, + "cookieRefresh": true, + "usesNonCookieAccess": true, + "dataRetention": { + "stdRetention": 365, + "purposes": {}, + "specialPurposes": {} + }, + "urls": [ + { + "langId": "en", + "privacy": "https://www.smartstream.tv/en/productprivacy", + "legIntClaim": "https://www.smartstream.tv/en/productprivacy" + }, + { + "langId": "de", + "privacy": "https://www.smartstream.tv/de/produktdatenschutz", + "legIntClaim": "https://www.smartstream.tv/de/produktdatenschutz" + } + ], + "dataDeclaration": [ + 1, + 2, + 3, + 6, + 8, + 10, + 11 + ], + "deviceStorageDisclosureUrl": "https://tcf.adtech.app/gen/deviceStorageDisclosure/stv.json" + }, + "136": { + "id": 136, + "name": "Ströer SSP GmbH (SSP)", + "purposes": [ + 1, + 4 + ], + "legIntPurposes": [ + 2, + 7, + 9, + 10 + ], + "flexiblePurposes": [ + 2, + 7, + 9, + 10 + ], + "specialPurposes": [ + 1, + 2 + ], + "features": [], + "specialFeatures": [], + "cookieMaxAgeSeconds": 31536000, + "usesCookies": true, + "cookieRefresh": false, + "usesNonCookieAccess": true, + "dataRetention": { + "stdRetention": 730, + "purposes": { + "2": 0 + }, + "specialPurposes": { + "1": 183, + "2": 0 + } + }, + "urls": [ + { + "langId": "de", + "privacy": "https://www.stroeer.de/ssp-datenschutz", + "legIntClaim": "https://www.stroeer.de/ssp-datenschutz" + } + ], + "dataDeclaration": [ + 1, + 2, + 3, + 4, + 6, + 8, + 10, + 11 + ], + "deviceStorageDisclosureUrl": "https://www.stroeer.de/StroeerSSP_deviceStorage.json" + }, + "137": { + "id": 137, + "name": "OS Data Solutions GmbH & Co. KG", + "purposes": [ + 1, + 3, + 5 + ], + "legIntPurposes": [ + 9, + 10 + ], + "flexiblePurposes": [ + 9, + 10 + ], + "specialPurposes": [ + 1, + 2 + ], + "features": [ + 1, + 2, + 3 + ], + "specialFeatures": [], + "cookieMaxAgeSeconds": 7776000, + "usesCookies": true, + "cookieRefresh": false, + "usesNonCookieAccess": true, + "dataRetention": { + "stdRetention": 730, + "purposes": {}, + "specialPurposes": {} + }, + "urls": [ + { + "langId": "de", + "privacy": "https://osdatasolutions.de/datenschutz/", + "legIntClaim": "https://osdatasolutions.de/datenschutz/" + } + ], + "dataDeclaration": [ + 1, + 2, + 3, + 4, + 6, + 7, + 8, + 10, + 11 + ], + "deviceStorageDisclosureUrl": "https://www.stroeer.de/StroeerDSP_deviceStorage.json" + }, + "138": { + "id": 138, + "name": "ConnectAd Demand GmbH", + "purposes": [ + 1, + 2, + 3, + 4, + 7, + 10 + ], + "legIntPurposes": [], + "flexiblePurposes": [ + 2, + 7, + 10 + ], + "specialPurposes": [ + 1, + 2 + ], + "features": [ + 3 + ], + "specialFeatures": [ + 1 + ], + "cookieMaxAgeSeconds": 2628000, + "usesCookies": true, + "cookieRefresh": true, + "usesNonCookieAccess": false, + "dataRetention": { + "stdRetention": 30, + "purposes": {}, + "specialPurposes": {} + }, + "urls": [ + { + "langId": "en", + "privacy": "https://connectadrealtime.com/privacy/", + "legIntClaim": "https://connectadrealtime.com/privacy/" + } + ], + "dataDeclaration": [ + 1, + 2, + 3, + 4, + 11 + ], + "deviceStorageDisclosureUrl": "https://connectad.io/tcf_storage.json" + }, + "139": { + "id": 139, + "name": "Permodo GmbH", + "purposes": [ + 1, + 2, + 3, + 4, + 7, + 9, + 10 + ], + "legIntPurposes": [], + "flexiblePurposes": [], + "specialPurposes": [ + 1, + 2 + ], + "features": [], + "specialFeatures": [], + "overflow": { + "httpGetLimit": 32 + }, + "cookieMaxAgeSeconds": null, + "usesCookies": false, + "cookieRefresh": false, + "usesNonCookieAccess": true, + "dataRetention": { + "stdRetention": 90, + "purposes": {}, + "specialPurposes": {} + }, + "urls": [ + { + "langId": "de", + "privacy": "https://permodo.com/de/privacy.html", + "legIntClaim": "https://permodo.com/de/privacy.html" + } + ], + "dataDeclaration": [ + 1, + 2, + 3, + 6, + 8, + 10, + 11 + ], + "deviceStorageDisclosureUrl": "https://tcf.adtech.app/gen/deviceStorageDisclosure/per.json" + }, + "140": { + "id": 140, + "name": "Platform161 B.V.", + "purposes": [ + 1, + 2, + 3, + 4, + 7, + 10 + ], + "legIntPurposes": [], + "flexiblePurposes": [], + "specialPurposes": [ + 1, + 2 + ], + "features": [ + 2, + 3 + ], + "specialFeatures": [ + 1 + ], + "cookieMaxAgeSeconds": 34164000, + "usesCookies": true, + "cookieRefresh": true, + "usesNonCookieAccess": true, + "dataRetention": { + "stdRetention": 0, + "purposes": { + "3": 390, + "7": 30, + "10": 365 + }, + "specialPurposes": { + "1": 7 + } + }, + "urls": [ + { + "langId": "en", + "privacy": "https://verve.com/dsp-cookies-privacy/", + "legIntClaim": "https://verve.com/dsp-cookies-privacy/" + } + ], + "dataDeclaration": [ + 1, + 2, + 3, + 4, + 6, + 8, + 9, + 10, + 11 + ], + "deviceStorageDisclosureUrl": "https://static2.creative-serving.com/deviceStorage.json" + }, + "149": { + "id": 149, + "name": "ADman Interactive SLU", + "purposes": [ + 1, + 2, + 3, + 4, + 5, + 6, + 7, + 8, + 9, + 10 + ], + "legIntPurposes": [], + "flexiblePurposes": [ + 2 + ], + "specialPurposes": [], + "features": [ + 2, + 3 + ], + "specialFeatures": [], + "cookieMaxAgeSeconds": 31535998, + "usesCookies": true, + "cookieRefresh": true, + "usesNonCookieAccess": false, + "dataRetention": { + "stdRetention": 0, + "purposes": {}, + "specialPurposes": {} + }, + "urls": [ + { + "langId": "es", + "privacy": "https://admanmedia.com/politica.html", + "legIntClaim": "https://admanmedia.com/politica.html" + } + ], + "dataDeclaration": [ + 2 + ], + "deviceStorageDisclosureUrl": "https://admanmedia.com/deviceStorage.json" + }, + "150": { + "id": 150, + "name": "Inskin Media LTD", + "purposes": [ + 1, + 3, + 4, + 9, + 10 + ], + "legIntPurposes": [ + 2, + 7 + ], + "flexiblePurposes": [ + 2, + 7 + ], + "specialPurposes": [ + 1, + 2 + ], + "features": [ + 2, + 3 + ], + "specialFeatures": [], + "cookieMaxAgeSeconds": 31622400, + "usesCookies": true, + "cookieRefresh": true, + "usesNonCookieAccess": true, + "dataRetention": { + "purposes": { + "2": 4320, + "3": 90, + "4": 90, + "7": 4320, + "9": 90, + "10": 4320 + }, + "specialPurposes": { + "1": 90, + "2": 4320 + } + }, + "urls": [ + { + "langId": "en", + "privacy": "https://www.inskinmedia.com/privacy-policy.html", + "legIntClaim": "https://www.inskinmedia.com/privacy-policy.html" + } + ], + "dataDeclaration": [ + 1, + 2, + 6, + 8, + 10, + 11 + ], + "deviceStorageDisclosureUrl": "https://www.inskinad.com/deviceStorageDisclosure.json" + }, + "151": { + "id": 151, + "name": "MOOT TECHNOLOGY LTD", + "purposes": [ + 1, + 2, + 3, + 4, + 7 + ], + "legIntPurposes": [], + "flexiblePurposes": [], + "specialPurposes": [], + "features": [], + "specialFeatures": [ + 1 + ], + "cookieMaxAgeSeconds": 0, + "usesCookies": true, + "cookieRefresh": false, + "usesNonCookieAccess": false, + "dataRetention": { + "stdRetention": 390, + "purposes": {}, + "specialPurposes": {} + }, + "urls": [ + { + "langId": "en", + "privacy": "https://admedo.com/privacy-policy" + } + ], + "dataDeclaration": [ + 1, + 6, + 8 + ], + "deviceStorageDisclosureUrl": "https://admedo.com/admedo_device_storage_url.json" + }, + "153": { + "id": 153, + "name": "MADVERTISE MEDIA", + "purposes": [ + 1, + 2, + 3, + 4, + 5, + 6, + 7, + 8, + 9, + 10 + ], + "legIntPurposes": [], + "flexiblePurposes": [], + "specialPurposes": [ + 1, + 2 + ], + "features": [ + 1, + 2, + 3 + ], + "specialFeatures": [ + 1, + 2 + ], + "overflow": { + "httpGetLimit": 128 + }, + "cookieMaxAgeSeconds": 10368000, + "usesCookies": true, + "cookieRefresh": false, + "usesNonCookieAccess": true, + "dataRetention": { + "stdRetention": 120, + "purposes": {}, + "specialPurposes": {} + }, + "urls": [ + { + "langId": "en", + "privacy": "https://madvertise.com/en/gdpr/", + "legIntClaim": "https://madvertise.com/en/gdpr/" + } + ], + "dataDeclaration": [ + 1, + 2, + 3, + 4, + 8, + 9, + 11 + ], + "deviceStorageDisclosureUrl": "https://mobile.mng-ads.com/deviceStorage.json" + }, + "154": { + "id": 154, + "name": "YOC AG", + "purposes": [ + 1, + 3, + 4, + 10 + ], + "legIntPurposes": [ + 2, + 7 + ], + "flexiblePurposes": [ + 2, + 7 + ], + "specialPurposes": [ + 1, + 2 + ], + "features": [ + 1, + 3 + ], + "specialFeatures": [ + 1 + ], + "cookieMaxAgeSeconds": 31536000, + "usesCookies": true, + "cookieRefresh": true, + "usesNonCookieAccess": true, + "dataRetention": { + "stdRetention": 365, + "purposes": {}, + "specialPurposes": {} + }, + "urls": [ + { + "langId": "en", + "privacy": "https://yoc.com/privacy/", + "legIntClaim": "https://yoc.com/privacy/" + }, + { + "langId": "de", + "privacy": "https://yoc.com/de/datenschutz/", + "legIntClaim": "https://yoc.com/de/datenschutz/" + } + ], + "dataDeclaration": [ + 1, + 2, + 3, + 4, + 5, + 6, + 7, + 8, + 9, + 10, + 11 + ], + "deviceStorageDisclosureUrl": "https://cdn.yoc.com/visx/sellers/deviceStorage.json" + }, + "155": { + "id": 155, + "name": "AntVoice", + "purposes": [ + 1, + 2, + 3, + 4, + 7 + ], + "legIntPurposes": [], + "flexiblePurposes": [], + "specialPurposes": [ + 2 + ], + "features": [], + "specialFeatures": [], + "cookieMaxAgeSeconds": 34819200, + "usesCookies": true, + "cookieRefresh": true, + "usesNonCookieAccess": false, + "dataRetention": { + "stdRetention": 403, + "purposes": {}, + "specialPurposes": {} + }, + "urls": [ + { + "langId": "en", + "privacy": "https://www.antvoice.com/en/privacypolicy/", + "legIntClaim": "https://www.antvoice.com/en/privacypolicy/" + } + ], + "dataDeclaration": [ + 1, + 2, + 3, + 6, + 8, + 10, + 11 + ], + "deviceStorageDisclosureUrl": "https://av-eu-marketing.storage.googleapis.com/deviceStorage.json" + }, + "156": { + "id": 156, + "name": "Basis Global Technologies, Inc.", + "purposes": [ + 1, + 3, + 4 + ], + "legIntPurposes": [ + 2, + 7, + 10 + ], + "flexiblePurposes": [ + 7 + ], + "specialPurposes": [ + 1, + 2 + ], + "features": [ + 2, + 3 + ], + "specialFeatures": [ + 1 + ], + "cookieMaxAgeSeconds": 31536000, + "usesCookies": true, + "cookieRefresh": true, + "usesNonCookieAccess": false, + "dataRetention": { + "purposes": { + "2": 0, + "3": 180, + "4": 180, + "7": 35, + "10": 540 + }, + "specialPurposes": { + "1": 540, + "2": 0 + } + }, + "urls": [ + { + "langId": "en", + "privacy": "https://privacy.basis.net/", + "legIntClaim": "https://privacy.basis.net/#gdpr" + } + ], + "dataDeclaration": [ + 1, + 2, + 3, + 5, + 6, + 8, + 9, + 10, + 11 + ], + "deviceStorageDisclosureUrl": "https://privacy.basis.net/devicestorage.json" + }, + "160": { + "id": 160, + "name": "Audience Solutions S.A.", + "purposes": [ + 1, + 2, + 3, + 4, + 5, + 6, + 7, + 8, + 9, + 10 + ], + "legIntPurposes": [], + "flexiblePurposes": [], + "specialPurposes": [], + "features": [ + 1, + 2, + 3 + ], + "specialFeatures": [ + 1, + 2 + ], + "overflow": { + "httpGetLimit": 32 + }, + "cookieMaxAgeSeconds": 31536000, + "usesCookies": true, + "cookieRefresh": true, + "usesNonCookieAccess": false, + "dataRetention": { + "stdRetention": 365, + "purposes": {}, + "specialPurposes": {} + }, + "urls": [ + { + "langId": "pl", + "privacy": "https://audience-solutions.com/privacy.html" + } + ], + "dataDeclaration": [ + 1, + 2, + 3, + 5, + 6, + 7, + 8, + 10, + 11 + ], + "deviceStorageDisclosureUrl": "https://audience-solutions.com/.well-known/deviceStorage.json" + }, + "161": { + "id": 161, + "name": "SMADEX, S.L.U.", + "purposes": [ + 1, + 2, + 3, + 4, + 7, + 10 + ], + "legIntPurposes": [], + "flexiblePurposes": [], + "specialPurposes": [ + 1, + 2 + ], + "features": [ + 1, + 2, + 3 + ], + "specialFeatures": [ + 1 + ], + "cookieMaxAgeSeconds": 31536000, + "usesCookies": true, + "cookieRefresh": true, + "usesNonCookieAccess": false, + "dataRetention": { + "stdRetention": 365, + "purposes": {}, + "specialPurposes": {} + }, + "urls": [ + { + "langId": "en", + "privacy": "https://smadex.com/privacy-policy/", + "legIntClaim": "https://smadex.com/privacy-policy/" + } + ], + "dataDeclaration": [ + 1, + 2, + 3, + 4, + 7, + 8, + 10, + 11 + ], + "deviceStorageDisclosureUrl": "https://statics.smadex.com/tcf-storage.json" + }, + "163": { + "id": 163, + "name": "Bombora Inc.", + "purposes": [ + 1, + 3 + ], + "legIntPurposes": [ + 7, + 9, + 10 + ], + "flexiblePurposes": [ + 7, + 9, + 10 + ], + "specialPurposes": [ + 1 + ], + "features": [ + 1, + 3 + ], + "specialFeatures": [], + "cookieMaxAgeSeconds": 31536000, + "usesCookies": true, + "cookieRefresh": true, + "usesNonCookieAccess": true, + "dataRetention": { + "stdRetention": 730, + "purposes": {}, + "specialPurposes": {} + }, + "urls": [ + { + "langId": "en", + "privacy": "https://bombora.com/privacy", + "legIntClaim": "https://bombora.com/privacy" + } + ], + "dataDeclaration": [ + 1, + 2, + 3, + 5, + 6, + 8, + 10 + ], + "deviceStorageDisclosureUrl": "https://ml314.com/deviceStorage.json" + }, + "164": { + "id": 164, + "name": "Outbrain UK Ltd", + "purposes": [ + 1, + 2, + 3, + 4, + 5, + 6, + 7, + 8, + 9, + 10, + 11 + ], + "legIntPurposes": [], + "flexiblePurposes": [], + "specialPurposes": [ + 1, + 2 + ], + "features": [ + 1, + 2, + 3 + ], + "specialFeatures": [ + 2 + ], + "cookieMaxAgeSeconds": 7776000, + "usesCookies": true, + "cookieRefresh": true, + "usesNonCookieAccess": true, + "dataRetention": { + "stdRetention": 396, + "purposes": {}, + "specialPurposes": {} + }, + "urls": [ + { + "langId": "en", + "privacy": "https://www.outbrain.com/privacy", + "legIntClaim": "https://www.outbrain.com/privacy" + }, + { + "langId": "fr", + "privacy": "https://www.outbrain.com/privacy/fr", + "legIntClaim": "https://www.outbrain.com/privacy/fr" + }, + { + "langId": "de", + "privacy": "https://www.outbrain.com/privacy/de/", + "legIntClaim": "https://www.outbrain.com/privacy/de/" + }, + { + "langId": "it", + "privacy": "https://www.outbrain.com/privacy/it/", + "legIntClaim": "https://www.outbrain.com/privacy/it/" + }, + { + "langId": "ja", + "privacy": "https://www.outbrain.com/privacy/jp/", + "legIntClaim": "https://www.outbrain.com/privacy/jp/" + }, + { + "langId": "nl", + "privacy": "https://www.outbrain.com/privacy/nl/", + "legIntClaim": "https://www.outbrain.com/privacy/nl/" + }, + { + "langId": "pt", + "privacy": "https://www.outbrain.com/privacy/pt/", + "legIntClaim": "https://www.outbrain.com/privacy/pt/" + } + ], + "dataDeclaration": [ + 1, + 2, + 3, + 4, + 6, + 8, + 10, + 11 + ], + "deviceStorageDisclosureUrl": "https://www.outbrain.com/privacy/wp-json/privacy/v2/devicestorage.json" + }, + "173": { + "id": 173, + "name": "Yieldmo, Inc.", + "purposes": [ + 1, + 2, + 3, + 4, + 7, + 9, + 10 + ], + "legIntPurposes": [], + "flexiblePurposes": [ + 2, + 7, + 9, + 10 + ], + "specialPurposes": [ + 1, + 2 + ], + "features": [ + 1, + 2, + 3 + ], + "specialFeatures": [], + "cookieMaxAgeSeconds": 31536000, + "usesCookies": true, + "cookieRefresh": true, + "usesNonCookieAccess": false, + "dataRetention": { + "stdRetention": 390, + "purposes": {}, + "specialPurposes": {} + }, + "urls": [ + { + "langId": "en", + "privacy": "https://www.yieldmo.com/privacy/", + "legIntClaim": "https://www.yieldmo.com/privacy/" + } + ], + "dataDeclaration": [ + 1, + 2, + 3, + 4, + 5, + 6, + 8, + 10, + 11 + ], + "deviceStorageDisclosureUrl": "https://s3.amazonaws.com/devicestoragedisclosureurl.yieldmo.com/deviceStorage.json" + }, + "185": { + "id": 185, + "name": "Bidtellect, Inc", + "purposes": [ + 2, + 3, + 4, + 5, + 6, + 7, + 11 + ], + "legIntPurposes": [], + "flexiblePurposes": [], + "specialPurposes": [], + "features": [ + 1, + 2, + 3 + ], + "specialFeatures": [], + "overflow": { + "httpGetLimit": 128 + }, + "cookieMaxAgeSeconds": 7776000, + "usesCookies": true, + "cookieRefresh": true, + "usesNonCookieAccess": true, + "dataRetention": { + "stdRetention": 28, + "purposes": { + "5": 365, + "6": 365 + }, + "specialPurposes": {} + }, + "urls": [ + { + "langId": "en", + "privacy": "https://www.bidtellect.com/privacy-policy/" + } + ], + "dataDeclaration": [ + 1, + 2, + 3, + 6, + 10 + ], + "deviceStorageDisclosureUrl": "https://cdn.bttrack.com/iab/deviceStorageDisclosure.json" + }, + "190": { + "id": 190, + "name": "video intelligence AG", + "purposes": [ + 1, + 2, + 3, + 4, + 7, + 8, + 9, + 10 + ], + "legIntPurposes": [], + "flexiblePurposes": [], + "specialPurposes": [ + 1, + 2 + ], + "features": [ + 1, + 3 + ], + "specialFeatures": [], + "cookieMaxAgeSeconds": 7776000, + "usesCookies": true, + "cookieRefresh": true, + "usesNonCookieAccess": true, + "dataRetention": { + "stdRetention": 90, + "purposes": {}, + "specialPurposes": {} + }, + "urls": [ + { + "langId": "en", + "privacy": "https://www.vi.ai/legal/privacy-policy/", + "legIntClaim": "https://www.vi.ai/legal/privacy-policy/" + } + ], + "dataDeclaration": [ + 1, + 2, + 3, + 4, + 6, + 8, + 10, + 11 + ], + "deviceStorageDisclosureUrl": "https://www.vi.ai/deviceStorage.json" + }, + "195": { + "id": 195, + "name": "advanced store GmbH", + "purposes": [ + 1, + 3, + 4 + ], + "legIntPurposes": [ + 2, + 7 + ], + "flexiblePurposes": [ + 2, + 7 + ], + "specialPurposes": [ + 1, + 2 + ], + "features": [], + "specialFeatures": [], + "cookieMaxAgeSeconds": 31536000, + "usesCookies": true, + "cookieRefresh": true, + "usesNonCookieAccess": true, + "dataRetention": { + "stdRetention": 60, + "purposes": {}, + "specialPurposes": {} + }, + "urls": [ + { + "langId": "de", + "privacy": "https://www.advanced-store.com/de/datenschutz/", + "legIntClaim": "https://www.advanced-store.com/de/datenschutz/" + }, + { + "langId": "en", + "privacy": "https://www.advanced-store.com/en/data-privacy/", + "legIntClaim": "https://www.advanced-store.com/en/data-privacy/" + } + ], + "dataDeclaration": [ + 3 + ], + "deviceStorageDisclosureUrl": "https://ad4m.at/.well-known/deviceStorage.json" + }, + "206": { + "id": 206, + "name": "Hybrid Adtech GmbH", + "purposes": [ + 1, + 2, + 3, + 4, + 7, + 8, + 9, + 10 + ], + "legIntPurposes": [], + "flexiblePurposes": [ + 2 + ], + "specialPurposes": [], + "features": [ + 1, + 2, + 3 + ], + "specialFeatures": [ + 1, + 2 + ], + "cookieMaxAgeSeconds": 31536000, + "usesCookies": true, + "cookieRefresh": false, + "usesNonCookieAccess": true, + "dataRetention": { + "stdRetention": 180, + "purposes": {}, + "specialPurposes": {} + }, + "urls": [ + { + "langId": "en", + "privacy": "https://hybrid.ai/data_protection_policy", + "legIntClaim": "https://hybrid.ai/data_protection_policy" + } + ], + "dataDeclaration": [ + 2, + 3 + ], + "deviceStorageDisclosureUrl": "https://st.hybrid.ai/policy/deviceStorage.json" + }, + "209": { + "id": 209, + "name": "Delta Projects AB", + "purposes": [ + 1, + 2, + 3, + 4 + ], + "legIntPurposes": [ + 7, + 10 + ], + "flexiblePurposes": [ + 2, + 7, + 10 + ], + "specialPurposes": [ + 1, + 2 + ], + "features": [], + "specialFeatures": [ + 1 + ], + "cookieMaxAgeSeconds": 31536000, + "usesCookies": true, + "cookieRefresh": false, + "usesNonCookieAccess": false, + "dataRetention": { + "stdRetention": 547, + "purposes": {}, + "specialPurposes": {} + }, + "urls": [ + { + "langId": "en", + "privacy": "https://deltaprojects.com/data-collection-policy", + "legIntClaim": "https://deltaprojects.com/data-collection-policy" + } + ], + "dataDeclaration": [ + 1, + 2, + 3, + 4, + 5, + 6, + 7, + 8, + 9, + 10, + 11 + ], + "deviceStorageDisclosureUrl": "https://cdn.de17a.com/policy/deviceStorage.json" + }, + "210": { + "id": 210, + "name": "Zemanta Inc.", + "purposes": [ + 1, + 2, + 3, + 4, + 7, + 9, + 10 + ], + "legIntPurposes": [], + "flexiblePurposes": [], + "specialPurposes": [ + 1, + 2 + ], + "features": [ + 1, + 3 + ], + "specialFeatures": [ + 2 + ], + "cookieMaxAgeSeconds": 31536000, + "usesCookies": true, + "cookieRefresh": true, + "usesNonCookieAccess": true, + "dataRetention": { + "stdRetention": 365, + "purposes": {}, + "specialPurposes": {} + }, + "urls": [ + { + "langId": "en", + "privacy": "https://www.zemanta.com/privacy/", + "legIntClaim": "https://www.zemanta.com/privacy/" + } + ], + "dataDeclaration": [ + 1, + 2, + 3, + 4, + 6, + 8, + 10, + 11 + ], + "deviceStorageDisclosureUrl": "https://www.zemanta.com/wp-content/uploads/2022/06/deviceStorage.json" + }, + "211": { + "id": 211, + "name": "AdTheorent, Inc", + "purposes": [ + 1, + 2, + 3, + 4, + 5, + 6, + 7, + 8, + 9, + 10 + ], + "legIntPurposes": [], + "flexiblePurposes": [], + "specialPurposes": [], + "features": [ + 1, + 2, + 3 + ], + "specialFeatures": [ + 1, + 2 + ], + "overflow": { + "httpGetLimit": 128 + }, + "cookieMaxAgeSeconds": 63071995, + "usesCookies": true, + "cookieRefresh": true, + "usesNonCookieAccess": false, + "dataRetention": { + "stdRetention": 365, + "purposes": {}, + "specialPurposes": {} + }, + "urls": [ + { + "langId": "en", + "privacy": "https://adtheorent.com/privacy-policy", + "legIntClaim": "https://adtheorent.com/privacy-policy" + } + ], + "dataDeclaration": [ + 1, + 2, + 3, + 4, + 8, + 9, + 11 + ], + "deviceStorageDisclosureUrl": "https://public-cdn.adtheorent.com/iab/AdTheorent-IAB-TCFv2-deviceStorageDisclosure.json" + }, + "215": { + "id": 215, + "name": "ARMIS SAS", + "purposes": [ + 1, + 7 + ], + "legIntPurposes": [], + "flexiblePurposes": [], + "specialPurposes": [], + "features": [], + "specialFeatures": [], + "cookieMaxAgeSeconds": 33696000, + "usesCookies": true, + "cookieRefresh": true, + "usesNonCookieAccess": false, + "dataRetention": { + "purposes": { + "7": 180 + }, + "specialPurposes": {} + }, + "urls": [ + { + "langId": "en", + "privacy": "https://armis.tech/en/armis-personal-data-privacy-policy/" + } + ], + "dataDeclaration": [ + 1, + 2, + 3, + 8 + ], + "deviceStorageDisclosureUrl": "https://armis-rgpd-acotedemoi.acotedemoi.com/" + }, + "216": { + "id": 216, + "name": "Mindlytix SAS", + "purposes": [ + 1, + 2, + 3, + 5, + 7, + 8, + 9, + 10 + ], + "legIntPurposes": [], + "flexiblePurposes": [], + "specialPurposes": [ + 1 + ], + "features": [ + 1 + ], + "specialFeatures": [], + "cookieMaxAgeSeconds": 5356800, + "usesCookies": true, + "cookieRefresh": false, + "usesNonCookieAccess": false, + "dataRetention": { + "stdRetention": 185, + "purposes": {}, + "specialPurposes": {} + }, + "urls": [ + { + "langId": "fr", + "privacy": "https://mindlytix.com/privacy/", + "legIntClaim": "https://mindlytix.com/privacy/" + } + ], + "dataDeclaration": [ + 1, + 2, + 3, + 4, + 5, + 6, + 7, + 8, + 9, + 10, + 11 + ], + "deviceStorageDisclosureUrl": "https://mindlytix.com/tcf/tcf.json" + }, + "226": { + "id": 226, + "name": "Publicis Media GmbH", + "purposes": [ + 1, + 2, + 3, + 4, + 5, + 6, + 7, + 8, + 9, + 10 + ], + "legIntPurposes": [], + "flexiblePurposes": [], + "specialPurposes": [], + "features": [ + 1, + 2, + 3 + ], + "specialFeatures": [], + "cookieMaxAgeSeconds": 7776000, + "usesCookies": true, + "cookieRefresh": true, + "usesNonCookieAccess": true, + "dataRetention": { + "stdRetention": 730, + "purposes": {}, + "specialPurposes": {} + }, + "urls": [ + { + "langId": "de", + "privacy": "https://www.publicismedia.de/datenschutz/" + } + ], + "dataDeclaration": [ + 1, + 2, + 3, + 4, + 5, + 6, + 7, + 8, + 10, + 11 + ], + "deviceStorageDisclosureUrl": "https://cdn.vtracy.de/iab/deviceStorage.json" + }, + "227": { + "id": 227, + "name": "Opt Out Advertising B.V. ", + "purposes": [ + 1, + 2, + 3, + 4, + 7, + 9, + 10 + ], + "legIntPurposes": [], + "flexiblePurposes": [ + 2, + 7, + 9, + 10 + ], + "specialPurposes": [ + 1, + 2 + ], + "features": [ + 3 + ], + "specialFeatures": [ + 1 + ], + "cookieMaxAgeSeconds": 31622400, + "usesCookies": true, + "cookieRefresh": true, + "usesNonCookieAccess": true, + "dataRetention": { + "stdRetention": 90, + "purposes": {}, + "specialPurposes": { + "1": 30 + } + }, + "urls": [ + { + "langId": "en", + "privacy": "https://optoutadvertising.com/privacy-policy/", + "legIntClaim": "https://optoutadvertising.com/privacy-policy/" + } + ], + "dataDeclaration": [ + 1, + 2, + 3, + 6, + 7, + 8, + 9, + 10, + 11 + ], + "deviceStorageDisclosureUrl": "https://adserving.optoutadvertising.com/dsd" + }, + "228": { + "id": 228, + "name": "M.D. Primis Technologies Ltd.", + "purposes": [ + 1, + 2, + 3, + 4, + 5, + 6 + ], + "legIntPurposes": [ + 7, + 8, + 10 + ], + "flexiblePurposes": [], + "specialPurposes": [ + 1, + 2 + ], + "features": [ + 3 + ], + "specialFeatures": [], + "cookieMaxAgeSeconds": 2160000, + "usesCookies": true, + "cookieRefresh": false, + "usesNonCookieAccess": false, + "dataRetention": { + "stdRetention": 30, + "purposes": {}, + "specialPurposes": {} + }, + "urls": [ + { + "langId": "en", + "privacy": "https://www.primis.tech/privacy-policy/", + "legIntClaim": "https://www.primis.tech/privacy-policy/" + } + ], + "dataDeclaration": [ + 1, + 2, + 3, + 4, + 6, + 7, + 8, + 11 + ], + "deviceStorageDisclosureUrl": "https://www.primis.tech/deviceStorage.json" + }, + "231": { + "id": 231, + "name": "AcuityAds Inc.", + "purposes": [ + 1, + 3, + 4 + ], + "legIntPurposes": [ + 2, + 7, + 8, + 10 + ], + "flexiblePurposes": [ + 2, + 7, + 8, + 10 + ], + "specialPurposes": [ + 1, + 2 + ], + "features": [ + 2 + ], + "specialFeatures": [], + "overflow": { + "httpGetLimit": 128 + }, + "cookieMaxAgeSeconds": 31536000, + "usesCookies": true, + "cookieRefresh": true, + "usesNonCookieAccess": false, + "dataRetention": { + "stdRetention": 180, + "purposes": {}, + "specialPurposes": {} + }, + "urls": [ + { + "langId": "en", + "privacy": "https://privacy.acuityads.com/corporate-privacy-policy.html", + "legIntClaim": "https://privacy.acuityads.com/corporate-privacy-policy.html" + } + ], + "dataDeclaration": [ + 1, + 2, + 3, + 5, + 6, + 8, + 10, + 11 + ], + "deviceStorageDisclosureUrl": "https://privacy.acuityads.com/deviceStorageDisclosure.json" + }, + "237": { + "id": 237, + "name": "VGI CTV, Inc", + "purposes": [ + 1, + 2, + 3, + 4, + 7, + 9, + 10 + ], + "legIntPurposes": [], + "flexiblePurposes": [], + "specialPurposes": [ + 1, + 2 + ], + "features": [ + 1, + 2, + 3 + ], + "specialFeatures": [ + 1 + ], + "cookieMaxAgeSeconds": 31536000, + "usesCookies": true, + "cookieRefresh": true, + "usesNonCookieAccess": true, + "dataRetention": { + "stdRetention": 30, + "purposes": {}, + "specialPurposes": {} + }, + "urls": [ + { + "langId": "en", + "privacy": "https://verve.com/privacy-policy/index.html", + "legIntClaim": "https://verve.com/website-privacy-policy/" + } + ], + "dataDeclaration": [ + 1, + 2, + 3, + 4, + 6, + 8, + 9, + 10, + 11 + ], + "deviceStorageDisclosureUrl": "https://lkqd.com/disclosures.json" + }, + "241": { + "id": 241, + "name": "OneTag Limited", + "purposes": [ + 1, + 2, + 3, + 4, + 7, + 9, + 10 + ], + "legIntPurposes": [], + "flexiblePurposes": [ + 2, + 7 + ], + "specialPurposes": [ + 1, + 2 + ], + "features": [ + 1, + 2, + 3 + ], + "specialFeatures": [ + 1 + ], + "cookieMaxAgeSeconds": 34160000, + "usesCookies": true, + "cookieRefresh": true, + "usesNonCookieAccess": true, + "dataRetention": { + "stdRetention": 548, + "purposes": {}, + "specialPurposes": {} + }, + "urls": [ + { + "langId": "en", + "privacy": "https://www.onetag.com/privacy/", + "legIntClaim": "https://www.onetag.com/privacy/" + } + ], + "dataDeclaration": [ + 1, + 2, + 3, + 6, + 8, + 11 + ], + "deviceStorageDisclosureUrl": "https://onetag-cdn.com/privacy/tcf_storage.json" + }, + "242": { + "id": 242, + "name": "twiago GmbH", + "purposes": [ + 1, + 2, + 3, + 4, + 7 + ], + "legIntPurposes": [], + "flexiblePurposes": [], + "specialPurposes": [], + "features": [ + 3 + ], + "specialFeatures": [], + "cookieMaxAgeSeconds": 2592000, + "usesCookies": true, + "cookieRefresh": true, + "usesNonCookieAccess": false, + "dataRetention": { + "stdRetention": 60, + "purposes": { + "7": 14 + }, + "specialPurposes": {} + }, + "urls": [ + { + "langId": "de", + "privacy": "https://a.twiago.com/privacy.php", + "legIntClaim": "https://a.twiago.com/privacy.php" + }, + { + "langId": "en", + "privacy": "https://a.twiago.com/privacy.php", + "legIntClaim": "https://a.twiago.com/privacy.php" + } + ], + "dataDeclaration": [ + 1, + 2, + 3, + 4, + 6, + 8, + 10, + 11 + ], + "deviceStorageDisclosureUrl": "https://control.twiago.com/deviceStorage.json" + }, + "244": { + "id": 244, + "name": "Ermes", + "purposes": [ + 1, + 2, + 3, + 4, + 7, + 9, + 10 + ], + "legIntPurposes": [], + "flexiblePurposes": [], + "specialPurposes": [], + "features": [ + 1, + 2, + 3 + ], + "specialFeatures": [], + "cookieMaxAgeSeconds": 33696000, + "usesCookies": true, + "cookieRefresh": false, + "usesNonCookieAccess": false, + "dataRetention": { + "stdRetention": 395, + "purposes": {}, + "specialPurposes": {} + }, + "urls": [ + { + "langId": "fr", + "privacy": "https://www.ermes.ai/politique-de-confidentialite/" + } + ], + "dataDeclaration": [ + 1, + 2, + 3, + 4, + 5, + 6, + 7, + 8, + 10, + 11 + ], + "deviceStorageDisclosureUrl": "https://tag.leadplace.fr/consents/consents.json" + }, + "246": { + "id": 246, + "name": "Smartology Limited", + "purposes": [ + 1, + 3, + 4, + 8 + ], + "legIntPurposes": [ + 2, + 7 + ], + "flexiblePurposes": [ + 2, + 7 + ], + "specialPurposes": [ + 1, + 2 + ], + "features": [], + "specialFeatures": [], + "cookieMaxAgeSeconds": null, + "usesCookies": false, + "cookieRefresh": false, + "usesNonCookieAccess": true, + "dataRetention": { + "stdRetention": 30, + "purposes": { + "3": 0, + "4": 0 + }, + "specialPurposes": {} + }, + "urls": [ + { + "langId": "en", + "privacy": "https://www.smartology.net/privacy-policy/", + "legIntClaim": "https://www.smartology.net/legitimate-interest-assessments/" + } + ], + "dataDeclaration": [ + 1 + ], + "deviceStorageDisclosureUrl": "https://www.smartology.net/deviceStorageDisclosure.json" + }, + "248": { + "id": 248, + "name": "Converge-Digital", + "purposes": [ + 1 + ], + "legIntPurposes": [ + 2 + ], + "flexiblePurposes": [ + 2 + ], + "specialPurposes": [ + 2 + ], + "features": [ + 3 + ], + "specialFeatures": [], + "overflow": { + "httpGetLimit": 32 + }, + "cookieMaxAgeSeconds": 15552000, + "usesCookies": true, + "cookieRefresh": false, + "usesNonCookieAccess": false, + "dataRetention": { + "stdRetention": 30, + "purposes": {}, + "specialPurposes": {} + }, + "urls": [ + { + "langId": "en", + "privacy": "https://converge-digital.com/privacy-policy/", + "legIntClaim": "https://converge-digital.com/privacy-policy/" + } + ], + "dataDeclaration": [ + 1, + 2 + ], + "deviceStorageDisclosureUrl": "https://data.converge-digital.com/deviceStorage.json" + }, + "251": { + "id": 251, + "name": "Yieldlove GmbH", + "purposes": [ + 1 + ], + "legIntPurposes": [ + 2, + 7, + 10 + ], + "flexiblePurposes": [ + 2, + 7 + ], + "specialPurposes": [ + 1, + 2 + ], + "features": [], + "specialFeatures": [], + "cookieMaxAgeSeconds": 2592000, + "usesCookies": true, + "cookieRefresh": false, + "usesNonCookieAccess": false, + "dataRetention": { + "purposes": { + "2": 7, + "7": 0, + "10": 183 + }, + "specialPurposes": { + "1": 183, + "2": 7 + } + }, + "urls": [ + { + "langId": "de", + "privacy": "https://www.yieldlove.com/de-de/datenschutz/", + "legIntClaim": "https://www.yieldlove.com/de-de/datenschutz/" + } + ], + "dataDeclaration": [ + 1, + 2, + 3, + 6, + 8, + 11 + ], + "deviceStorageDisclosureUrl": "https://cdn-a.yieldlove.com/deviceStorage.json" + }, + "252": { + "id": 252, + "name": "Jaduda GmbH", + "purposes": [ + 3, + 4 + ], + "legIntPurposes": [ + 2, + 7, + 9, + 10 + ], + "flexiblePurposes": [ + 2, + 7, + 9, + 10 + ], + "specialPurposes": [ + 1, + 2 + ], + "features": [ + 3 + ], + "specialFeatures": [ + 1 + ], + "cookieMaxAgeSeconds": 2592000, + "usesCookies": true, + "cookieRefresh": true, + "usesNonCookieAccess": false, + "dataRetention": { + "stdRetention": 180, + "purposes": {}, + "specialPurposes": { + "2": 3650 + } + }, + "urls": [ + { + "langId": "en", + "privacy": "https://www.splicky.com/en/web/privacy-delivery", + "legIntClaim": "https://splicky.com/en/web/privacy-policy/legitimate-interests" + }, + { + "langId": "de", + "privacy": "https://www.splicky.com/de/web/privacy-delivery", + "legIntClaim": "https://splicky.com/de/web/privacy-policy/legitimate-interests" + } + ], + "dataDeclaration": [ + 1, + 2, + 3, + 4, + 5, + 6, + 7, + 8, + 9, + 10, + 11 + ], + "deviceStorageDisclosureUrl": "https://cdn-global.splicky.com/devicestorage.json" + }, + "253": { + "id": 253, + "name": "Improve Digital", + "purposes": [ + 1, + 3, + 4, + 9 + ], + "legIntPurposes": [ + 2, + 7, + 10 + ], + "flexiblePurposes": [ + 2, + 7, + 10 + ], + "specialPurposes": [ + 1, + 2 + ], + "features": [ + 3 + ], + "specialFeatures": [ + 1 + ], + "overflow": { + "httpGetLimit": 128 + }, + "cookieMaxAgeSeconds": 7776000, + "usesCookies": true, + "cookieRefresh": false, + "usesNonCookieAccess": false, + "dataRetention": { + "stdRetention": 90, + "purposes": {}, + "specialPurposes": {} + }, + "urls": [ + { + "langId": "en", + "privacy": "https://www.improvedigital.com/platform-privacy-policy", + "legIntClaim": "https://www.improvedigital.com/platform-privacy-policy" + } + ], + "dataDeclaration": [ + 1, + 2, + 3, + 4, + 5, + 6, + 7, + 8, + 9, + 10, + 11 + ], + "deviceStorageDisclosureUrl": "https://sellers.improvedigital.com/tcf-cookies.json" + }, + "254": { + "id": 254, + "name": "LiquidM Technology GmbH", + "purposes": [ + 1, + 2, + 3, + 4, + 7 + ], + "legIntPurposes": [], + "flexiblePurposes": [], + "specialPurposes": [ + 1, + 2 + ], + "features": [ + 3 + ], + "specialFeatures": [ + 1 + ], + "cookieMaxAgeSeconds": 31536000, + "usesCookies": true, + "cookieRefresh": true, + "usesNonCookieAccess": true, + "dataRetention": { + "stdRetention": 14, + "purposes": {}, + "specialPurposes": {} + }, + "urls": [ + { + "langId": "en", + "privacy": "https://liquidm.com/privacy-policy/", + "legIntClaim": "https://liquidm.com/privacy-policy/" + } + ], + "dataDeclaration": [ + 1, + 2, + 3, + 4, + 5, + 6, + 7, + 8, + 9, + 11 + ], + "deviceStorageDisclosureUrl": "https://liquidm.com/disclosures.json" + }, + "255": { + "id": 255, + "name": "Onnetwork Sp. z o.o.", + "purposes": [ + 1, + 3, + 4, + 5, + 6 + ], + "legIntPurposes": [ + 2, + 7, + 8 + ], + "flexiblePurposes": [ + 2, + 7, + 8 + ], + "specialPurposes": [ + 2 + ], + "features": [], + "specialFeatures": [], + "cookieMaxAgeSeconds": 4320000, + "usesCookies": true, + "cookieRefresh": true, + "usesNonCookieAccess": false, + "dataRetention": { + "stdRetention": 0, + "purposes": { + "5": 30, + "6": 30 + }, + "specialPurposes": { + "2": 30 + } + }, + "urls": [ + { + "langId": "pl", + "privacy": "https://www.onnetwork.tv/pp_services.php#pl", + "legIntClaim": "https://www.onnetwork.tv/pp_services.php#pl" + }, + { + "langId": "en", + "privacy": "https://www.onnetwork.tv/pp_services.php#en", + "legIntClaim": "https://www.onnetwork.tv/pp_services.php#en" + } + ], + "dataDeclaration": [ + 10 + ], + "deviceStorageDisclosureUrl": "https://video.onnetwork.tv/vendor255.json" + }, + "259": { + "id": 259, + "name": "ADYOULIKE SA", + "purposes": [ + 1, + 3, + 4 + ], + "legIntPurposes": [ + 2, + 7 + ], + "flexiblePurposes": [ + 2, + 7 + ], + "specialPurposes": [ + 1, + 2 + ], + "features": [ + 3 + ], + "specialFeatures": [], + "cookieMaxAgeSeconds": 31536000, + "usesCookies": true, + "cookieRefresh": true, + "usesNonCookieAccess": false, + "dataRetention": { + "stdRetention": 60, + "purposes": {}, + "specialPurposes": {} + }, + "urls": [ + { + "langId": "fr", + "privacy": "https://www.adyoulike.com/pages/privacy", + "legIntClaim": "https://www.adyoulike.com/pages/privacy" + } + ], + "dataDeclaration": [ + 1, + 2, + 4, + 8, + 11 + ], + "deviceStorageDisclosureUrl": "https://adyoulike.com/deviceStorageDisclosureURL.json" + }, + "270": { + "id": 270, + "name": "Marfeel Solutions, SL", + "purposes": [ + 1 + ], + "legIntPurposes": [], + "flexiblePurposes": [], + "specialPurposes": [], + "features": [], + "specialFeatures": [], + "cookieMaxAgeSeconds": 7776000, + "usesCookies": true, + "cookieRefresh": false, + "usesNonCookieAccess": false, + "dataRetention": { + "purposes": {}, + "specialPurposes": {} + }, + "urls": [ + { + "langId": "en", + "privacy": "https://www.marfeel.com/privacy-policy/" + } + ], + "dataDeclaration": [ + 1, + 2, + 8 + ], + "deviceStorageDisclosureUrl": "https://live.mrf.io/statics/marfeel/resources/lib/deviceStorage/touch.json" + }, + "272": { + "id": 272, + "name": "A.Mob", + "purposes": [ + 1, + 2, + 3, + 4, + 7, + 9, + 10 + ], + "legIntPurposes": [], + "flexiblePurposes": [], + "specialPurposes": [], + "features": [ + 1, + 2, + 3 + ], + "specialFeatures": [ + 1 + ], + "cookieMaxAgeSeconds": 34128000, + "usesCookies": true, + "cookieRefresh": false, + "usesNonCookieAccess": true, + "dataRetention": { + "stdRetention": 395, + "purposes": {}, + "specialPurposes": {} + }, + "urls": [ + { + "langId": "fr", + "privacy": "https://www.we-are-adot.com/privacy-policy/" + }, + { + "langId": "en", + "privacy": "https://we-are-adot.com/en/privacy-policy/" + } + ], + "dataDeclaration": [ + 1, + 2, + 3, + 6, + 7, + 8, + 9, + 10, + 11 + ], + "deviceStorageDisclosureUrl": "https://adserver.adotmob.com/tcf/tcf.json" + }, + "274": { + "id": 274, + "name": "Golden Bees", + "purposes": [ + 1, + 2, + 3, + 4, + 7, + 9, + 10 + ], + "legIntPurposes": [], + "flexiblePurposes": [], + "specialPurposes": [ + 1, + 2 + ], + "features": [ + 2 + ], + "specialFeatures": [], + "overflow": { + "httpGetLimit": 32 + }, + "cookieMaxAgeSeconds": 31536000, + "usesCookies": true, + "cookieRefresh": true, + "usesNonCookieAccess": false, + "dataRetention": { + "stdRetention": 365, + "purposes": {}, + "specialPurposes": {} + }, + "urls": [ + { + "langId": "fr", + "privacy": "https://applies.goldenbees.fr/privacyPolicy/fr", + "legIntClaim": "https://applies.goldenbees.fr/privacyPolicy/fr" + } + ], + "dataDeclaration": [ + 2 + ], + "deviceStorageDisclosureUrl": "https://cdn.goldenbees.fr/proxy?url=http%3A%2F%2Fstatic.goldenbees.fr%2Fcdn%2Fjs%2Fcmp%2FdeviceStorage.json&attachment=0" + }, + "279": { + "id": 279, + "name": "Mirando GmbH & Co KG", + "purposes": [], + "legIntPurposes": [ + 2, + 7 + ], + "flexiblePurposes": [ + 2, + 7 + ], + "specialPurposes": [ + 1, + 2 + ], + "features": [], + "specialFeatures": [], + "cookieMaxAgeSeconds": null, + "usesCookies": false, + "cookieRefresh": false, + "usesNonCookieAccess": false, + "dataRetention": { + "stdRetention": 30, + "purposes": {}, + "specialPurposes": {} + }, + "urls": [ + { + "langId": "de", + "privacy": "https://get.mirando.de/download/gdpr.php", + "legIntClaim": "https://get.mirando.de/download/gdpr.php" + } + ], + "dataDeclaration": [ + 1, + 2, + 6, + 8, + 11 + ], + "deviceStorageDisclosureUrl": "https://get.mirando.de/download/gdpr.php" + }, + "281": { + "id": 281, + "name": "Wizaly", + "purposes": [ + 1, + 7, + 8, + 9 + ], + "legIntPurposes": [], + "flexiblePurposes": [ + 7, + 8, + 9 + ], + "specialPurposes": [], + "features": [ + 1, + 2 + ], + "specialFeatures": [], + "cookieMaxAgeSeconds": 31536000, + "usesCookies": true, + "cookieRefresh": true, + "usesNonCookieAccess": true, + "dataRetention": { + "stdRetention": 1095, + "purposes": {}, + "specialPurposes": {} + }, + "urls": [ + { + "langId": "en", + "privacy": "https://www.wizaly.com/terms-of-use#privacy-policy", + "legIntClaim": "https://www.wizaly.com/terms-of-use#privacy-policy" + }, + { + "langId": "fr", + "privacy": "https://www.wizaly.fr/mentions-legales#politique-de-confidentialite", + "legIntClaim": "https://www.wizaly.fr/mentions-legales#politique-de-confidentialite" + } + ], + "dataDeclaration": [ + 1, + 2, + 5, + 6, + 8, + 11 + ], + "deviceStorageDisclosureUrl": "https://t.wizaly.com/iab-tcf-vendor-device-storage-and-operational-disclosures.json" + }, + "282": { + "id": 282, + "name": "Welect GmbH", + "purposes": [ + 1 + ], + "legIntPurposes": [ + 2 + ], + "flexiblePurposes": [ + 2 + ], + "specialPurposes": [ + 2 + ], + "features": [], + "specialFeatures": [], + "overflow": { + "httpGetLimit": 128 + }, + "cookieMaxAgeSeconds": 1209600, + "usesCookies": true, + "cookieRefresh": true, + "usesNonCookieAccess": false, + "dataRetention": { + "stdRetention": 0, + "purposes": {}, + "specialPurposes": {} + }, + "urls": [ + { + "langId": "de", + "privacy": "https://www.welect.de/datenschutz", + "legIntClaim": "https://www.welect.de/datenschutz" + }, + { + "langId": "en", + "privacy": "https://www.de.welect.de/en/privacy-policy/", + "legIntClaim": "https://www.de.welect.de/en/privacy-policy/" + } + ], + "dataDeclaration": [ + 1 + ], + "deviceStorageDisclosureUrl": "https://www.welect.de/deviceStorage.json" + }, + "284": { + "id": 284, + "name": "Weborama", + "purposes": [ + 1, + 3, + 4, + 5, + 6, + 10 + ], + "legIntPurposes": [ + 2, + 7, + 8, + 9, + 11 + ], + "flexiblePurposes": [], + "specialPurposes": [ + 2 + ], + "features": [ + 1, + 2 + ], + "specialFeatures": [ + 1 + ], + "cookieMaxAgeSeconds": 33955200, + "usesCookies": true, + "cookieRefresh": false, + "usesNonCookieAccess": false, + "dataRetention": { + "stdRetention": 395, + "purposes": {}, + "specialPurposes": {} + }, + "urls": [ + { + "langId": "fr", + "privacy": "https://weborama.com/respect-de-la-vie-privee-2-2/", + "legIntClaim": "https://weborama.com/politique-de-confidentialite/#interet-legitime-weborama" + }, + { + "langId": "en", + "privacy": "https://weborama.com/en/privacy-2/", + "legIntClaim": "https://weborama.com/en/privacy-2/#legitimate-interest" + }, + { + "langId": "it", + "privacy": "https://weborama.com/it/privacy-3/", + "legIntClaim": "https://weborama.com/it/privacy-3/#interesse-legittimo" + }, + { + "langId": "es", + "privacy": "https://weborama.com/es/privacidad/", + "legIntClaim": "https://weborama.com/it/privacy-3/#interesse-legittimo" + } + ], + "dataDeclaration": [ + 1, + 2, + 3, + 5, + 6, + 7, + 8, + 9, + 10, + 11 + ], + "deviceStorageDisclosureUrl": "https://weborama.com/deviceStorage.json" + }, + "285": { + "id": 285, + "name": "Comcast International France SAS", + "purposes": [ + 1, + 2, + 4 + ], + "legIntPurposes": [ + 7, + 10 + ], + "flexiblePurposes": [ + 2, + 7, + 10 + ], + "specialPurposes": [ + 1, + 2 + ], + "features": [ + 3 + ], + "specialFeatures": [], + "cookieMaxAgeSeconds": 15768000, + "usesCookies": true, + "cookieRefresh": true, + "usesNonCookieAccess": true, + "dataRetention": { + "stdRetention": 547, + "purposes": {}, + "specialPurposes": {} + }, + "urls": [ + { + "langId": "en", + "privacy": "https://www.freewheel.com/privacy-policy", + "legIntClaim": "https://www.freewheel.com/privacy-policy#tab2_section2_4" + }, + { + "langId": "nl", + "privacy": "https://www.freewheel.com/privacy-policy/nl", + "legIntClaim": "https://www.freewheel.com/privacy-policy/nl#tab2_section2_4" + }, + { + "langId": "fr", + "privacy": "https://www.freewheel.com/privacy-policy/fr", + "legIntClaim": "https://www.freewheel.com/privacy-policy/fr#tab2_section2_4" + }, + { + "langId": "it", + "privacy": "https://www.freewheel.com/privacy-policy/it", + "legIntClaim": "https://www.freewheel.com/privacy-policy/it#tab2_section2_4" + }, + { + "langId": "es", + "privacy": "https://www.freewheel.com/privacy-policy/es", + "legIntClaim": "https://www.freewheel.com/privacy-policy/es#tab2_section2_4" + }, + { + "langId": "de", + "privacy": "https://www.freewheel.com/privacy-policy/de", + "legIntClaim": "https://www.freewheel.com/privacy-policy/de#tab2_section2_4" + } + ], + "dataDeclaration": [ + 1, + 2, + 3, + 4, + 6, + 8, + 10, + 11 + ], + "deviceStorageDisclosureUrl": "https://iab.fwmrm.net/g/devicedisclosure.json" + }, + "290": { + "id": 290, + "name": "Readpeak Oy", + "purposes": [ + 1, + 2, + 3, + 4, + 7, + 10 + ], + "legIntPurposes": [], + "flexiblePurposes": [ + 7, + 10 + ], + "specialPurposes": [ + 1, + 2 + ], + "features": [ + 3 + ], + "specialFeatures": [], + "cookieMaxAgeSeconds": 7776000, + "usesCookies": true, + "cookieRefresh": true, + "usesNonCookieAccess": false, + "dataRetention": { + "stdRetention": 180, + "purposes": { + "7": 4320, + "10": 4320 + }, + "specialPurposes": { + "2": 4320 + } + }, + "urls": [ + { + "langId": "en", + "privacy": "https://www.readpeak.com/terms/readpeak-privacy-policy", + "legIntClaim": "https://www.readpeak.com/terms/legitimate-interest-assessment-lia" + } + ], + "dataDeclaration": [ + 1, + 2, + 3, + 6, + 8, + 11 + ], + "deviceStorageDisclosureUrl": "https://static.readpeak.com/tcf/deviceStorage.json" + }, + "294": { + "id": 294, + "name": "Jivox Corporation", + "purposes": [ + 1, + 3, + 4 + ], + "legIntPurposes": [ + 2, + 7 + ], + "flexiblePurposes": [ + 2, + 7 + ], + "specialPurposes": [ + 1, + 2 + ], + "features": [ + 1, + 2, + 3 + ], + "specialFeatures": [ + 1 + ], + "overflow": { + "httpGetLimit": 32 + }, + "cookieMaxAgeSeconds": 2592000, + "usesCookies": true, + "cookieRefresh": true, + "usesNonCookieAccess": false, + "dataRetention": { + "stdRetention": 30, + "purposes": {}, + "specialPurposes": {} + }, + "urls": [ + { + "langId": "en", + "privacy": "https://www.jivox.com/privacy", + "legIntClaim": "https://www.jivox.com/privacy" + } + ], + "dataDeclaration": [ + 1, + 3, + 6, + 8, + 9, + 10, + 11 + ], + "deviceStorageDisclosureUrl": "https://cdn.jivox.com/files/privacy/deviceStorage.json" + }, + "301": { + "id": 301, + "name": "zeotap GmbH", + "purposes": [ + 1, + 3, + 4, + 5, + 6, + 9, + 10 + ], + "legIntPurposes": [], + "flexiblePurposes": [], + "specialPurposes": [], + "features": [ + 1, + 2, + 3 + ], + "specialFeatures": [], + "cookieMaxAgeSeconds": 31536000, + "usesCookies": true, + "cookieRefresh": false, + "usesNonCookieAccess": true, + "dataRetention": { + "stdRetention": 365, + "purposes": {}, + "specialPurposes": {} + }, + "urls": [ + { + "langId": "en", + "privacy": "https://zeotap.com/product-privacy-policy/" + } + ], + "dataDeclaration": [ + 1, + 2, + 3, + 5, + 6, + 7, + 8, + 10, + 11 + ], + "deviceStorageDisclosureUrl": "https://spl.zeotap.com/assets/iab-disclosure.json" + }, + "304": { + "id": 304, + "name": "On Device Research Limited", + "purposes": [ + 1, + 2, + 3 + ], + "legIntPurposes": [], + "flexiblePurposes": [], + "specialPurposes": [], + "features": [ + 1, + 2, + 3 + ], + "specialFeatures": [ + 1 + ], + "cookieMaxAgeSeconds": 2592000, + "usesCookies": true, + "cookieRefresh": false, + "usesNonCookieAccess": false, + "dataRetention": { + "stdRetention": 90, + "purposes": {}, + "specialPurposes": {} + }, + "urls": [ + { + "langId": "en", + "privacy": "https://s.on-device.com/privacyPolicy" + } + ], + "dataDeclaration": [ + 1, + 2, + 3, + 6, + 7, + 8, + 9 + ], + "deviceStorageDisclosureUrl": "https://on-device.com/deviceStorage.json" + }, + "311": { + "id": 311, + "name": "Mobfox US LLC", + "purposes": [ + 1, + 2, + 3, + 4, + 5, + 6, + 7, + 8, + 9, + 10 + ], + "legIntPurposes": [], + "flexiblePurposes": [], + "specialPurposes": [ + 1, + 2 + ], + "features": [ + 3 + ], + "specialFeatures": [ + 1 + ], + "cookieMaxAgeSeconds": 1209600, + "usesCookies": true, + "cookieRefresh": true, + "usesNonCookieAccess": false, + "dataRetention": { + "stdRetention": 0, + "purposes": {}, + "specialPurposes": { + "1": 365 + } + }, + "urls": [ + { + "langId": "en", + "privacy": "https://www.mobfox.com/privacy-policy/", + "legIntClaim": "https://www.mobfox.com/privacy-policy/" + } + ], + "dataDeclaration": [ + 1, + 2, + 3, + 4, + 8, + 9 + ], + "deviceStorageDisclosureUrl": "https://www.mobfox.com/disclosures.json" + }, + "312": { + "id": 312, + "name": "Exactag GmbH", + "purposes": [ + 1, + 7, + 8 + ], + "legIntPurposes": [], + "flexiblePurposes": [], + "specialPurposes": [ + 1 + ], + "features": [ + 2 + ], + "specialFeatures": [], + "overflow": { + "httpGetLimit": 128 + }, + "cookieMaxAgeSeconds": 15552000, + "usesCookies": true, + "cookieRefresh": true, + "usesNonCookieAccess": false, + "dataRetention": { + "stdRetention": 210, + "purposes": {}, + "specialPurposes": {} + }, + "urls": [ + { + "langId": "en", + "privacy": "https://exactag.com/privacy-policy/", + "legIntClaim": "https://exactag.com/privacy-policy/" + } + ], + "dataDeclaration": [ + 2, + 3, + 5, + 6, + 11 + ], + "deviceStorageDisclosureUrl": "https://cdn.exactag.com/.well-known/deviceStorage.json" + }, + "314": { + "id": 314, + "name": "Keymantics", + "purposes": [ + 1, + 2, + 3, + 4, + 7, + 9, + 10 + ], + "legIntPurposes": [], + "flexiblePurposes": [ + 2, + 7, + 9, + 10 + ], + "specialPurposes": [ + 1, + 2 + ], + "features": [], + "specialFeatures": [], + "cookieMaxAgeSeconds": 2592000, + "usesCookies": true, + "cookieRefresh": true, + "usesNonCookieAccess": false, + "dataRetention": { + "stdRetention": 30, + "purposes": {}, + "specialPurposes": {} + }, + "urls": [ + { + "langId": "en", + "privacy": "https://www.kmtx.com/privacy/", + "legIntClaim": "https://www.kmtx.com/privacy/" + } + ], + "dataDeclaration": [ + 2, + 6 + ], + "deviceStorageDisclosureUrl": "https://cdn.keymantics.com/.well-known/deviceStorage.json" + }, + "318": { + "id": 318, + "name": "Accorp Sp. z o.o.", + "purposes": [ + 1, + 2, + 3, + 4, + 5, + 6, + 7, + 8, + 9, + 10 + ], + "legIntPurposes": [], + "flexiblePurposes": [], + "specialPurposes": [ + 1, + 2 + ], + "features": [ + 1, + 2, + 3 + ], + "specialFeatures": [], + "cookieMaxAgeSeconds": 31536000, + "usesCookies": true, + "cookieRefresh": false, + "usesNonCookieAccess": false, + "dataRetention": { + "stdRetention": 720, + "purposes": {}, + "specialPurposes": {} + }, + "urls": [ + { + "langId": "en", + "privacy": "https://instytut-pollster.pl/privacy-policy/index.html", + "legIntClaim": "https://instytut-pollster.pl/privacy-policy/index.html" + }, + { + "langId": "pl", + "privacy": "https://instytut-pollster.pl/privacy-policy/index.html", + "legIntClaim": "https://instytut-pollster.pl/privacy-policy/index.html" + } + ], + "dataDeclaration": [ + 1, + 2, + 3, + 6, + 7, + 10, + 11 + ], + "deviceStorageDisclosureUrl": "https://content.pollster.pl/deviceStorage" + }, + "321": { + "id": 321, + "name": "Ziff Davis LLC", + "purposes": [ + 1, + 3, + 4, + 5, + 6, + 9 + ], + "legIntPurposes": [ + 2, + 7, + 8, + 10 + ], + "flexiblePurposes": [ + 2, + 7, + 8, + 10 + ], + "specialPurposes": [ + 1, + 2 + ], + "features": [ + 2 + ], + "specialFeatures": [], + "cookieMaxAgeSeconds": 15552000, + "usesCookies": true, + "cookieRefresh": false, + "usesNonCookieAccess": false, + "dataRetention": { + "stdRetention": 1080, + "purposes": { + "2": 360, + "3": 360, + "4": 360, + "5": 360, + "6": 360 + }, + "specialPurposes": {} + }, + "urls": [ + { + "langId": "en", + "privacy": "https://www.ziffdavis.com/privacy-policy", + "legIntClaim": "https://www.ziffdavis.com/privacy-policy#lawful" + }, + { + "langId": "fr", + "privacy": "https://www.ziffdavis.com/privacy-policy-f/", + "legIntClaim": "https://www.ziffdavis.com/privacy-policy-f/#lawful" + } + ], + "dataDeclaration": [ + 1, + 2, + 3, + 5, + 6, + 7, + 8, + 10, + 11 + ], + "deviceStorageDisclosureUrl": "https://static.ziffdavis.com/jst/zdcookiedisclosure.json" + }, + "323": { + "id": 323, + "name": "Footballco Media Limited", + "purposes": [ + 1, + 2, + 3, + 4, + 5, + 6, + 7, + 8, + 9, + 10 + ], + "legIntPurposes": [], + "flexiblePurposes": [], + "specialPurposes": [], + "features": [ + 1, + 2, + 3 + ], + "specialFeatures": [ + 1, + 2 + ], + "cookieMaxAgeSeconds": 34190000, + "usesCookies": true, + "cookieRefresh": true, + "usesNonCookieAccess": false, + "dataRetention": { + "stdRetention": 0, + "purposes": {}, + "specialPurposes": {} + }, + "urls": [ + { + "langId": "en", + "privacy": "https://www.goal.com/en-gb/legal/privacy-policy" + } + ], + "dataDeclaration": [ + 1 + ], + "deviceStorageDisclosureUrl": "https://www.footballco.com/gvl-device-storage.json" + }, + "325": { + "id": 325, + "name": "Knorex", + "purposes": [ + 1, + 2, + 3, + 4, + 5, + 6, + 7, + 8, + 9, + 10, + 11 + ], + "legIntPurposes": [], + "flexiblePurposes": [], + "specialPurposes": [ + 1, + 2 + ], + "features": [ + 1, + 2, + 3 + ], + "specialFeatures": [ + 1 + ], + "cookieMaxAgeSeconds": 63071999, + "usesCookies": true, + "cookieRefresh": true, + "usesNonCookieAccess": true, + "dataRetention": { + "stdRetention": 90, + "purposes": {}, + "specialPurposes": {} + }, + "urls": [ + { + "langId": "en", + "privacy": "https://www.knorex.com/privacy", + "legIntClaim": "https://www.knorex.com/privacy" + } + ], + "dataDeclaration": [ + 3, + 4, + 7, + 11 + ], + "deviceStorageDisclosureUrl": "https://cdn.brand-display.com/gvl/deviceStorageDisclosure.json" + }, + "326": { + "id": 326, + "name": "AdTiming Technology Company Limited", + "purposes": [ + 1, + 2, + 3, + 4, + 7 + ], + "legIntPurposes": [], + "flexiblePurposes": [], + "specialPurposes": [ + 1, + 2 + ], + "features": [], + "specialFeatures": [], + "cookieMaxAgeSeconds": 2592000, + "usesCookies": true, + "cookieRefresh": true, + "usesNonCookieAccess": true, + "dataRetention": { + "stdRetention": 30, + "purposes": {}, + "specialPurposes": {} + }, + "urls": [ + { + "langId": "en", + "privacy": "https://www.adtiming.com/en/privacypolicy.html", + "legIntClaim": "https://www.adtiming.com/en/privacypolicy.html" + } + ], + "dataDeclaration": [ + 1, + 2, + 3, + 6 + ], + "deviceStorageDisclosureUrl": "https://img.adtiming.com/webrt/AdTiming.TCFv2.json" + }, + "328": { + "id": 328, + "name": "Gemius SA", + "purposes": [ + 1, + 2, + 3, + 4, + 7, + 8, + 9, + 10 + ], + "legIntPurposes": [], + "flexiblePurposes": [], + "specialPurposes": [], + "features": [ + 2 + ], + "specialFeatures": [], + "cookieMaxAgeSeconds": 157680000, + "usesCookies": true, + "cookieRefresh": true, + "usesNonCookieAccess": true, + "dataRetention": { + "stdRetention": 1096, + "purposes": { + "3": 1, + "4": 30, + "8": 1827, + "10": 1827 + }, + "specialPurposes": {} + }, + "urls": [ + { + "langId": "en", + "privacy": "https://www.gemius.com/privacy-policy.html" + } + ], + "dataDeclaration": [ + 2, + 3, + 6, + 10, + 11 + ], + "deviceStorageDisclosureUrl": "https://gemius.com/Gemius_SA_Vendor_Device_Storage.json" + }, + "329": { + "id": 329, + "name": "Browsi", + "purposes": [ + 1, + 7, + 8 + ], + "legIntPurposes": [], + "flexiblePurposes": [], + "specialPurposes": [], + "features": [], + "specialFeatures": [], + "cookieMaxAgeSeconds": 31536000, + "usesCookies": true, + "cookieRefresh": true, + "usesNonCookieAccess": true, + "dataRetention": { + "purposes": { + "7": 730, + "8": 400 + }, + "specialPurposes": {} + }, + "urls": [ + { + "langId": "en", + "privacy": "https://browsi.com/privacy-policy-2/" + } + ], + "dataDeclaration": [ + 1, + 2, + 4, + 6, + 11 + ], + "deviceStorageDisclosureUrl": "https://cdn.browsiprod.com/ads/tcf.json" + }, + "331": { + "id": 331, + "name": "ad6media", + "purposes": [ + 1, + 3, + 4, + 5, + 6 + ], + "legIntPurposes": [ + 2, + 7, + 8, + 9, + 10 + ], + "flexiblePurposes": [], + "specialPurposes": [ + 1, + 2 + ], + "features": [ + 2, + 3 + ], + "specialFeatures": [ + 2 + ], + "cookieMaxAgeSeconds": 31536000, + "usesCookies": true, + "cookieRefresh": true, + "usesNonCookieAccess": true, + "dataRetention": { + "stdRetention": 4320, + "purposes": {}, + "specialPurposes": {} + }, + "urls": [ + { + "langId": "fr", + "privacy": "https://www.ad6media.fr/privacy", + "legIntClaim": "https://www.ad6media.fr/privacy" + } + ], + "dataDeclaration": [ + 1, + 2, + 3, + 4, + 5, + 6, + 7, + 8, + 10 + ], + "deviceStorageDisclosureUrl": "https://www.ad6media.fr/tcf.json" + }, + "333": { + "id": 333, + "name": "InMobi Pte Ltd", + "purposes": [ + 1, + 2, + 3, + 4, + 7, + 9, + 10 + ], + "legIntPurposes": [], + "flexiblePurposes": [ + 9, + 10 + ], + "specialPurposes": [ + 1 + ], + "features": [ + 1, + 2, + 3 + ], + "specialFeatures": [ + 1 + ], + "cookieMaxAgeSeconds": null, + "usesCookies": false, + "cookieRefresh": false, + "usesNonCookieAccess": true, + "dataRetention": { + "stdRetention": 30, + "purposes": { + "2": 0, + "3": 395, + "4": 395 + }, + "specialPurposes": {} + }, + "urls": [ + { + "langId": "en", + "privacy": "https://www.inmobi.com/privacy-policy-for-eea", + "legIntClaim": "https://www.inmobi.com/privacy-policy-for-eea" + }, + { + "langId": "pt", + "privacy": "https://www.inmobi.com/privacy-policy-por", + "legIntClaim": "https://www.inmobi.com/privacy-policy-por" + }, + { + "langId": "es", + "privacy": "https://www.inmobi.com/privacy-policy-es", + "legIntClaim": "https://www.inmobi.com/privacy-policy-es" + } + ], + "dataDeclaration": [ + 1, + 3, + 8, + 9 + ], + "deviceStorageDisclosureUrl": "https://publisher.inmobi.com/public/disclosure" + }, + "336": { + "id": 336, + "name": "Telecoming S.A.", + "purposes": [], + "legIntPurposes": [ + 2, + 7, + 9 + ], + "flexiblePurposes": [ + 2 + ], + "specialPurposes": [ + 1, + 2 + ], + "features": [ + 3 + ], + "specialFeatures": [], + "overflow": { + "httpGetLimit": 128 + }, + "cookieMaxAgeSeconds": null, + "usesCookies": false, + "cookieRefresh": false, + "usesNonCookieAccess": false, + "dataRetention": { + "stdRetention": 3650, + "purposes": {}, + "specialPurposes": {} + }, + "urls": [ + { + "langId": "en", + "privacy": "https://www.telecoming.com/privacy-policy/", + "legIntClaim": "https://www.telecoming.com/privacy-policy/" + } + ], + "dataDeclaration": [ + 1, + 3, + 4 + ], + "deviceStorageDisclosureUrl": "https://telecoming.rtb.lynxio.org/deviceStorageDisclosureURL.json" + }, + "337": { + "id": 337, + "name": "SheMedia, LLC", + "purposes": [ + 1, + 2, + 3, + 4, + 5, + 6, + 7, + 8, + 9, + 10 + ], + "legIntPurposes": [], + "flexiblePurposes": [], + "specialPurposes": [], + "features": [ + 2, + 3 + ], + "specialFeatures": [], + "cookieMaxAgeSeconds": 31536000, + "usesCookies": true, + "cookieRefresh": true, + "usesNonCookieAccess": true, + "dataRetention": { + "stdRetention": 365, + "purposes": {}, + "specialPurposes": {} + }, + "urls": [ + { + "langId": "en", + "privacy": "https://www.shemedia.com/ad-services-privacy-policy" + } + ], + "dataDeclaration": [ + 1, + 2, + 5, + 6, + 7, + 8, + 10, + 11 + ], + "deviceStorageDisclosureUrl": "https://ads.shemedia.com/static/tcfdisclosures.json" + }, + "345": { + "id": 345, + "name": "The Kantar Group Limited", + "purposes": [ + 1, + 7, + 8, + 9, + 10 + ], + "legIntPurposes": [], + "flexiblePurposes": [], + "specialPurposes": [], + "features": [ + 1, + 2, + 3 + ], + "specialFeatures": [ + 1, + 2 + ], + "cookieMaxAgeSeconds": 78892380, + "usesCookies": true, + "cookieRefresh": true, + "usesNonCookieAccess": true, + "dataRetention": { + "stdRetention": 4320, + "purposes": {}, + "specialPurposes": {} + }, + "urls": [ + { + "langId": "en", + "privacy": "https://www.kantar.com/cookies-policies" + } + ], + "dataDeclaration": [ + 1, + 2, + 3, + 6, + 8, + 11 + ], + "deviceStorageDisclosureUrl": "https://secure.insightexpressai.com/DeviceStorageDisclosure.json" + }, + "347": { + "id": 347, + "name": "Ezoic Inc.", + "purposes": [ + 1, + 7, + 8, + 9, + 10 + ], + "legIntPurposes": [], + "flexiblePurposes": [], + "specialPurposes": [], + "features": [ + 3 + ], + "specialFeatures": [ + 1 + ], + "cookieMaxAgeSeconds": 220752000, + "usesCookies": true, + "cookieRefresh": true, + "usesNonCookieAccess": false, + "dataRetention": { + "stdRetention": 4320, + "purposes": {}, + "specialPurposes": {} + }, + "urls": [ + { + "langId": "en", + "privacy": "https://www.ezoic.com/terms/" + } + ], + "dataDeclaration": [ + 1, + 2, + 6, + 11 + ], + "deviceStorageDisclosureUrl": "https://privacy.ezodn.com/storage_disclosure.json" + }, + "350": { + "id": 350, + "name": "Samba TV, Inc.", + "purposes": [ + 1, + 2, + 3, + 4, + 5, + 6, + 7, + 8, + 9, + 10 + ], + "legIntPurposes": [], + "flexiblePurposes": [ + 7, + 8, + 9, + 10 + ], + "specialPurposes": [ + 1 + ], + "features": [ + 1, + 2, + 3 + ], + "specialFeatures": [], + "overflow": { + "httpGetLimit": 128 + }, + "cookieMaxAgeSeconds": 33696000, + "usesCookies": true, + "cookieRefresh": true, + "usesNonCookieAccess": false, + "dataRetention": { + "purposes": { + "2": 395, + "3": 395, + "4": 395, + "5": 395, + "6": 395, + "7": 1125, + "8": 1125, + "9": 1125, + "10": 1125 + }, + "specialPurposes": { + "1": 1125 + } + }, + "urls": [ + { + "langId": "en", + "privacy": "https://samba.tv/legal/privacy-policy/", + "legIntClaim": "https://samba.tv/legal/privacy-policy/" + }, + { + "langId": "ar", + "privacy": "https://samba.tv/legal/privacy-policy/", + "legIntClaim": "https://samba.tv/legal/privacy-policy/" + }, + { + "langId": "bg", + "privacy": "https://samba.tv/legal/privacy-policy/", + "legIntClaim": "https://samba.tv/legal/privacy-policy/" + }, + { + "langId": "bs", + "privacy": "https://samba.tv/legal/privacy-policy/", + "legIntClaim": "https://samba.tv/legal/privacy-policy/" + }, + { + "langId": "ca", + "privacy": "https://samba.tv/legal/privacy-policy/", + "legIntClaim": "https://samba.tv/legal/privacy-policy/" + }, + { + "langId": "cs", + "privacy": "https://samba.tv/legal/privacy-policy/", + "legIntClaim": "https://samba.tv/legal/privacy-policy/" + }, + { + "langId": "da", + "privacy": "https://samba.tv/legal/privacy-policy/", + "legIntClaim": "https://samba.tv/legal/privacy-policy/" + }, + { + "langId": "de", + "privacy": "https://samba.tv/legal/privacy-policy/", + "legIntClaim": "https://samba.tv/legal/privacy-policy/" + }, + { + "langId": "el", + "privacy": "https://samba.tv/legal/privacy-policy/", + "legIntClaim": "https://samba.tv/legal/privacy-policy/" + }, + { + "langId": "es", + "privacy": "https://samba.tv/legal/privacy-policy/", + "legIntClaim": "https://samba.tv/legal/privacy-policy/" + }, + { + "langId": "et", + "privacy": "https://samba.tv/legal/privacy-policy/", + "legIntClaim": "https://samba.tv/legal/privacy-policy/" + }, + { + "langId": "fi", + "privacy": "https://samba.tv/legal/privacy-policy/", + "legIntClaim": "https://samba.tv/legal/privacy-policy/" + }, + { + "langId": "fr", + "privacy": "https://samba.tv/legal/privacy-policy/", + "legIntClaim": "https://samba.tv/legal/privacy-policy/" + }, + { + "langId": "hr", + "privacy": "https://samba.tv/legal/privacy-policy/", + "legIntClaim": "https://samba.tv/legal/privacy-policy/" + }, + { + "langId": "hu", + "privacy": "https://samba.tv/legal/privacy-policy/", + "legIntClaim": "https://samba.tv/legal/privacy-policy/" + }, + { + "langId": "it", + "privacy": "https://samba.tv/legal/privacy-policy/", + "legIntClaim": "https://samba.tv/legal/privacy-policy/" + }, + { + "langId": "ja", + "privacy": "https://samba.tv/legal/privacy-policy/", + "legIntClaim": "https://samba.tv/legal/privacy-policy/" + }, + { + "langId": "lt", + "privacy": "https://samba.tv/legal/privacy-policy/", + "legIntClaim": "https://samba.tv/legal/privacy-policy/" + }, + { + "langId": "lv", + "privacy": "https://samba.tv/legal/privacy-policy/", + "legIntClaim": "https://samba.tv/legal/privacy-policy/" + }, + { + "langId": "nl", + "privacy": "https://samba.tv/legal/privacy-policy/", + "legIntClaim": "https://samba.tv/legal/privacy-policy/" + }, + { + "langId": "no", + "privacy": "https://samba.tv/legal/privacy-policy/", + "legIntClaim": "https://samba.tv/legal/privacy-policy/" + }, + { + "langId": "pl", + "privacy": "https://samba.tv/legal/privacy-policy/", + "legIntClaim": "https://samba.tv/legal/privacy-policy/" + }, + { + "langId": "pt", + "privacy": "https://samba.tv/legal/privacy-policy/", + "legIntClaim": "https://samba.tv/legal/privacy-policy/" + }, + { + "langId": "ro", + "privacy": "https://samba.tv/legal/privacy-policy/", + "legIntClaim": "https://samba.tv/legal/privacy-policy/" + }, + { + "langId": "ru", + "privacy": "https://samba.tv/legal/privacy-policy/", + "legIntClaim": "https://samba.tv/legal/privacy-policy/" + }, + { + "langId": "sk", + "privacy": "https://samba.tv/legal/privacy-policy/", + "legIntClaim": "https://samba.tv/legal/privacy-policy/" + }, + { + "langId": "sl", + "privacy": "https://samba.tv/legal/privacy-policy/", + "legIntClaim": "https://samba.tv/legal/privacy-policy/" + }, + { + "langId": "sv", + "privacy": "https://samba.tv/legal/privacy-policy/", + "legIntClaim": "https://samba.tv/legal/privacy-policy/" + }, + { + "langId": "tr", + "privacy": "https://samba.tv/legal/privacy-policy/", + "legIntClaim": "https://samba.tv/legal/privacy-policy/" + }, + { + "langId": "zh", + "privacy": "https://samba.tv/legal/privacy-policy/", + "legIntClaim": "https://samba.tv/legal/privacy-policy/" + }, + { + "langId": "sr - cyrl", + "privacy": "https://samba.tv/legal/privacy-policy/", + "legIntClaim": "https://samba.tv/legal/privacy-policy/" + } + ], + "dataDeclaration": [ + 1, + 3, + 4, + 6, + 8, + 10, + 11 + ], + "deviceStorageDisclosureUrl": "https://ads.samba.tv/disclosures.json" + }, + "351": { + "id": 351, + "name": "Samba TV UK Limited", + "purposes": [ + 1, + 2, + 3, + 4, + 5, + 6, + 7, + 8, + 9, + 10 + ], + "legIntPurposes": [], + "flexiblePurposes": [ + 7, + 8, + 9, + 10 + ], + "specialPurposes": [ + 1 + ], + "features": [ + 1, + 2, + 3 + ], + "specialFeatures": [], + "overflow": { + "httpGetLimit": 128 + }, + "cookieMaxAgeSeconds": 33696000, + "usesCookies": true, + "cookieRefresh": true, + "usesNonCookieAccess": false, + "dataRetention": { + "purposes": { + "2": 395, + "3": 395, + "4": 395, + "5": 395, + "6": 395, + "7": 1125, + "8": 1125, + "9": 1125, + "10": 1125 + }, + "specialPurposes": { + "1": 1125 + } + }, + "urls": [ + { + "langId": "en", + "privacy": "https://samba.tv/users/privacy-policy", + "legIntClaim": "https://samba.tv/users/privacy-policy" + }, + { + "langId": "ar", + "privacy": "https://samba.tv/users/privacy-policy", + "legIntClaim": "https://samba.tv/users/privacy-policy" + }, + { + "langId": "bg", + "privacy": "https://samba.tv/users/privacy-policy", + "legIntClaim": "https://samba.tv/users/privacy-policy" + }, + { + "langId": "bs", + "privacy": "https://samba.tv/users/privacy-policy", + "legIntClaim": "https://samba.tv/users/privacy-policy" + }, + { + "langId": "ca", + "privacy": "https://samba.tv/users/privacy-policy", + "legIntClaim": "https://samba.tv/users/privacy-policy" + }, + { + "langId": "cs", + "privacy": "https://samba.tv/users/privacy-policy", + "legIntClaim": "https://samba.tv/users/privacy-policy" + }, + { + "langId": "da", + "privacy": "https://samba.tv/users/privacy-policy", + "legIntClaim": "https://samba.tv/users/privacy-policy" + }, + { + "langId": "de", + "privacy": "https://samba.tv/users/privacy-policy", + "legIntClaim": "https://samba.tv/users/privacy-policy" + }, + { + "langId": "el", + "privacy": "https://samba.tv/users/privacy-policy", + "legIntClaim": "https://samba.tv/users/privacy-policy" + }, + { + "langId": "es", + "privacy": "https://samba.tv/users/privacy-policy", + "legIntClaim": "https://samba.tv/users/privacy-policy" + }, + { + "langId": "et", + "privacy": "https://samba.tv/users/privacy-policy", + "legIntClaim": "https://samba.tv/users/privacy-policy" + }, + { + "langId": "fi", + "privacy": "https://samba.tv/users/privacy-policy", + "legIntClaim": "https://samba.tv/users/privacy-policy" + }, + { + "langId": "fr", + "privacy": "https://samba.tv/users/privacy-policy", + "legIntClaim": "https://samba.tv/users/privacy-policy" + }, + { + "langId": "hu", + "privacy": "https://samba.tv/users/privacy-policy", + "legIntClaim": "https://samba.tv/users/privacy-policy" + }, + { + "langId": "it", + "privacy": "https://samba.tv/users/privacy-policy", + "legIntClaim": "https://samba.tv/users/privacy-policy" + }, + { + "langId": "ja", + "privacy": "https://samba.tv/users/privacy-policy", + "legIntClaim": "https://samba.tv/users/privacy-policy" + }, + { + "langId": "lt", + "privacy": "https://samba.tv/users/privacy-policy", + "legIntClaim": "https://samba.tv/users/privacy-policy" + }, + { + "langId": "lv", + "privacy": "https://samba.tv/users/privacy-policy", + "legIntClaim": "https://samba.tv/users/privacy-policy" + }, + { + "langId": "nl", + "privacy": "https://samba.tv/users/privacy-policy", + "legIntClaim": "https://samba.tv/users/privacy-policy" + }, + { + "langId": "no", + "privacy": "https://samba.tv/users/privacy-policy", + "legIntClaim": "https://samba.tv/users/privacy-policy" + }, + { + "langId": "pl", + "privacy": "https://samba.tv/users/privacy-policy", + "legIntClaim": "https://samba.tv/users/privacy-policy" + }, + { + "langId": "pt", + "privacy": "https://samba.tv/users/privacy-policy", + "legIntClaim": "https://samba.tv/users/privacy-policy" + }, + { + "langId": "ro", + "privacy": "https://samba.tv/users/privacy-policy", + "legIntClaim": "https://samba.tv/users/privacy-policy" + }, + { + "langId": "sr - cyrl", + "privacy": "https://samba.tv/users/privacy-policy", + "legIntClaim": "https://samba.tv/users/privacy-policy" + }, + { + "langId": "ru", + "privacy": "https://samba.tv/users/privacy-policy", + "legIntClaim": "https://samba.tv/users/privacy-policy" + }, + { + "langId": "sk", + "privacy": "https://samba.tv/users/privacy-policy", + "legIntClaim": "https://samba.tv/users/privacy-policy" + }, + { + "langId": "sl", + "privacy": "https://samba.tv/users/privacy-policy", + "legIntClaim": "https://samba.tv/users/privacy-policy" + }, + { + "langId": "sv", + "privacy": "https://samba.tv/users/privacy-policy", + "legIntClaim": "https://samba.tv/users/privacy-policy" + }, + { + "langId": "tr", + "privacy": "https://samba.tv/users/privacy-policy", + "legIntClaim": "https://samba.tv/users/privacy-policy" + }, + { + "langId": "zh", + "privacy": "https://samba.tv/users/privacy-policy", + "legIntClaim": "https://samba.tv/users/privacy-policy1" + }, + { + "langId": "hr", + "privacy": "https://samba.tv/users/privacy-policy", + "legIntClaim": "https://samba.tv/users/privacy-policy" + } + ], + "dataDeclaration": [ + 1, + 3, + 4, + 6, + 8, + 10, + 11 + ], + "deviceStorageDisclosureUrl": "https://pixel.mtrcs.samba.tv/disclosures.json" + }, + "358": { + "id": 358, + "name": "MGID Inc.", + "purposes": [ + 1, + 2, + 3, + 4, + 5, + 6, + 7, + 8, + 9, + 10 + ], + "legIntPurposes": [], + "flexiblePurposes": [], + "specialPurposes": [ + 1, + 2 + ], + "features": [ + 1, + 2, + 3 + ], + "specialFeatures": [], + "cookieMaxAgeSeconds": 31536000, + "usesCookies": true, + "cookieRefresh": true, + "usesNonCookieAccess": true, + "dataRetention": { + "stdRetention": 30, + "purposes": {}, + "specialPurposes": {} + }, + "urls": [ + { + "langId": "en", + "privacy": "https://www.mgid.com/privacy-policy", + "legIntClaim": "https://www.mgid.com/privacy-policy" + } + ], + "dataDeclaration": [ + 1, + 2, + 3, + 4, + 6, + 8, + 10, + 11 + ], + "deviceStorageDisclosureUrl": "https://www.mgid.com/assets/devicestorage.json" + }, + "368": { + "id": 368, + "name": "VECTAURY", + "purposes": [ + 1, + 2, + 3, + 4, + 7, + 9 + ], + "legIntPurposes": [], + "flexiblePurposes": [], + "specialPurposes": [ + 1, + 2 + ], + "features": [ + 1, + 2, + 3 + ], + "specialFeatures": [ + 1 + ], + "cookieMaxAgeSeconds": null, + "usesCookies": false, + "cookieRefresh": false, + "usesNonCookieAccess": true, + "dataRetention": { + "stdRetention": 365, + "purposes": {}, + "specialPurposes": {} + }, + "urls": [ + { + "langId": "en", + "privacy": "https://www.mobsuccess.com/en/privacy", + "legIntClaim": "https://www.mobsuccess.com/en/privacy" + } + ], + "dataDeclaration": [ + 1, + 2, + 3, + 6, + 8, + 9, + 10, + 11 + ], + "deviceStorageDisclosureUrl": "https://www.mobsuccess.com/deviceStorage.json" + }, + "371": { + "id": 371, + "name": "Seeding Alliance GmbH", + "purposes": [ + 1, + 3, + 4, + 5, + 6 + ], + "legIntPurposes": [ + 2, + 7, + 8, + 9, + 10 + ], + "flexiblePurposes": [ + 2, + 7, + 8, + 9, + 10 + ], + "specialPurposes": [ + 1, + 2 + ], + "features": [], + "specialFeatures": [ + 1 + ], + "cookieMaxAgeSeconds": 15552000, + "usesCookies": true, + "cookieRefresh": true, + "usesNonCookieAccess": false, + "dataRetention": { + "stdRetention": 30, + "purposes": {}, + "specialPurposes": {} + }, + "urls": [ + { + "langId": "de", + "privacy": "https://seeding-alliance.de/datenschutz/", + "legIntClaim": "https://seeding-alliance.de/datenschutz/" + } + ], + "dataDeclaration": [ + 1, + 2 + ], + "deviceStorageDisclosureUrl": "https://c.nativendo.de/cdn/asset/tcf/purpose-specific-storage-and-access-information.json" + }, + "373": { + "id": 373, + "name": "Nielsen Media Research Ltd.", + "purposes": [ + 1, + 3 + ], + "legIntPurposes": [ + 10 + ], + "flexiblePurposes": [], + "specialPurposes": [ + 1 + ], + "features": [ + 1, + 2, + 3 + ], + "specialFeatures": [], + "cookieMaxAgeSeconds": 10368000, + "usesCookies": true, + "cookieRefresh": true, + "usesNonCookieAccess": true, + "dataRetention": { + "stdRetention": 396, + "purposes": { + "3": 45 + }, + "specialPurposes": {} + }, + "urls": [ + { + "langId": "en", + "privacy": "https://www.nielsen.com/us/en/legal/privacy-statement/nielsen-marketing-cloud-privacy-notice/", + "legIntClaim": "https://www.nielsen.com/us/en/legal/privacy-statement/nielsen-marketing-cloud-privacy-notice/" + }, + { + "langId": "de", + "privacy": "https://www.nielsen.com/us/en/legal/privacy-statement/nielsen-marketing-cloud-privacy-notice/", + "legIntClaim": "https://www.nielsen.com/us/en/legal/privacy-statement/nielsen-marketing-cloud-privacy-notice/" + }, + { + "langId": "fr", + "privacy": "https://www.nielsen.com/us/en/legal/privacy-statement/nielsen-marketing-cloud-privacy-notice/", + "legIntClaim": "https://www.nielsen.com/us/en/legal/privacy-statement/nielsen-marketing-cloud-privacy-notice/" + }, + { + "langId": "it", + "privacy": "https://www.nielsen.com/us/en/legal/privacy-statement/nielsen-marketing-cloud-privacy-notice/", + "legIntClaim": "https://www.nielsen.com/us/en/legal/privacy-statement/nielsen-marketing-cloud-privacy-notice/" + }, + { + "langId": "es", + "privacy": "https://www.nielsen.com/us/en/legal/privacy-statement/nielsen-marketing-cloud-privacy-notice/", + "legIntClaim": "https://www.nielsen.com/us/en/legal/privacy-statement/nielsen-marketing-cloud-privacy-notice/" + } + ], + "dataDeclaration": [ + 1, + 2, + 3, + 6, + 11 + ], + "deviceStorageDisclosureUrl": "https://iab-privacy-disclosure.exelator.com/.json" + }, + "375": { + "id": 375, + "name": "RevX", + "purposes": [ + 2, + 3, + 4, + 5, + 6, + 7, + 8, + 9, + 10 + ], + "legIntPurposes": [], + "flexiblePurposes": [], + "specialPurposes": [], + "features": [ + 3 + ], + "specialFeatures": [], + "cookieMaxAgeSeconds": null, + "usesCookies": false, + "cookieRefresh": false, + "usesNonCookieAccess": false, + "dataRetention": { + "stdRetention": 180, + "purposes": {}, + "specialPurposes": {} + }, + "urls": [ + { + "langId": "en", + "privacy": "https://revx.io/privacy-policy" + } + ], + "dataDeclaration": [ + 1, + 2, + 3, + 6, + 10, + 11 + ], + "deviceStorageDisclosureUrl": "https://storage.googleapis.com/revx-product/privacy/tcf/deviceStorage/device_storage_disclosure.json" + }, + "377": { + "id": 377, + "name": "AddApptr GmbH", + "purposes": [ + 1, + 2, + 3, + 4, + 5, + 6, + 8, + 9 + ], + "legIntPurposes": [ + 7, + 10 + ], + "flexiblePurposes": [ + 7, + 10 + ], + "specialPurposes": [ + 1, + 2 + ], + "features": [ + 1, + 2, + 3 + ], + "specialFeatures": [ + 1, + 2 + ], + "cookieMaxAgeSeconds": null, + "usesCookies": false, + "cookieRefresh": false, + "usesNonCookieAccess": true, + "dataRetention": { + "stdRetention": 4320, + "purposes": {}, + "specialPurposes": {} + }, + "urls": [ + { + "langId": "en", + "privacy": "https://www.gravite.net/data-privacy", + "legIntClaim": "https://www.gravite.net/data-privacy" + }, + { + "langId": "de", + "privacy": "https://www.gravite.net/data-privacy", + "legIntClaim": "https://www.gravite.net/data-privacy" + } + ], + "dataDeclaration": [ + 2, + 3, + 6, + 9 + ], + "deviceStorageDisclosureUrl": "https://addapptr.com/tcfDeviceStorageDisclosures.json" + }, + "381": { + "id": 381, + "name": "Solocal SA", + "purposes": [ + 1, + 3, + 4, + 5, + 6, + 7, + 9, + 10 + ], + "legIntPurposes": [ + 2, + 8 + ], + "flexiblePurposes": [], + "specialPurposes": [ + 1 + ], + "features": [ + 1, + 3 + ], + "specialFeatures": [ + 1, + 2 + ], + "cookieMaxAgeSeconds": 34164000, + "usesCookies": true, + "cookieRefresh": true, + "usesNonCookieAccess": true, + "dataRetention": { + "purposes": { + "2": 0, + "3": 91, + "4": 91, + "5": 91, + "6": 91, + "7": 4320, + "8": 4320, + "9": 4320, + "10": 4320 + }, + "specialPurposes": { + "1": 372 + } + }, + "urls": [ + { + "langId": "fr", + "privacy": "https://www.solocal.com/protection-de-la-vie-privee", + "legIntClaim": "https://www.solocal.com/protection-de-la-vie-privee" + } + ], + "dataDeclaration": [ + 2, + 3, + 6, + 7, + 8, + 9, + 10, + 11 + ], + "deviceStorageDisclosureUrl": "https://prd-cdn.adhslx.com/ui/login/assets/tcf/tcf-registration.json" + }, + "382": { + "id": 382, + "name": "The Reach Group GmbH", + "purposes": [ + 1, + 2, + 3, + 4, + 5, + 6, + 7, + 8, + 9, + 10, + 11 + ], + "legIntPurposes": [], + "flexiblePurposes": [ + 2, + 7, + 8, + 9, + 10, + 11 + ], + "specialPurposes": [ + 1, + 2 + ], + "features": [ + 3 + ], + "specialFeatures": [], + "overflow": { + "httpGetLimit": 128 + }, + "cookieMaxAgeSeconds": 7776000, + "usesCookies": true, + "cookieRefresh": true, + "usesNonCookieAccess": false, + "dataRetention": { + "stdRetention": 90, + "purposes": {}, + "specialPurposes": {} + }, + "urls": [ + { + "langId": "en", + "privacy": "https://trg.de/en/privacy-statement/", + "legIntClaim": "https://trg.de/en/privacy-statement/" + }, + { + "langId": "de", + "privacy": "https://trg.de/datenschutzerklarung/", + "legIntClaim": "https://trg.de/datenschutzerklarung/" + } + ], + "dataDeclaration": [ + 1, + 2, + 4, + 6, + 8, + 10, + 11 + ], + "deviceStorageDisclosureUrl": "https://hal9000.redintelligence.net/privacy/tcf/deviceStorage/2723ad85dc4fd6c3.json" + }, + "388": { + "id": 388, + "name": "Numberly", + "purposes": [ + 1, + 2, + 3, + 4, + 5, + 6, + 7, + 8, + 9, + 10 + ], + "legIntPurposes": [], + "flexiblePurposes": [], + "specialPurposes": [], + "features": [ + 1, + 2, + 3 + ], + "specialFeatures": [], + "cookieMaxAgeSeconds": 15552000, + "usesCookies": true, + "cookieRefresh": true, + "usesNonCookieAccess": false, + "dataRetention": { + "stdRetention": 183, + "purposes": {}, + "specialPurposes": {} + }, + "urls": [ + { + "langId": "en", + "privacy": "https://numberly.com/en/privacy/" + }, + { + "langId": "fr", + "privacy": "https://numberly.com/fr/privacy-fr/" + } + ], + "dataDeclaration": [ + 1, + 2, + 3, + 5, + 6, + 7, + 8, + 10, + 11 + ], + "deviceStorageDisclosureUrl": "https://dco.mmtro.com/a?tagid=6575638-eec14e25c2d8ce8f341c134e24e9de46&campid=0&banid=2712&output=json" + }, + "394": { + "id": 394, + "name": "AudienceProject Aps", + "purposes": [ + 1, + 3, + 4, + 5, + 6 + ], + "legIntPurposes": [ + 2, + 7, + 8, + 9, + 10 + ], + "flexiblePurposes": [ + 2, + 7, + 8, + 9, + 10 + ], + "specialPurposes": [ + 1, + 2 + ], + "features": [ + 1, + 2, + 3 + ], + "specialFeatures": [], + "cookieMaxAgeSeconds": 31536000, + "usesCookies": true, + "cookieRefresh": true, + "usesNonCookieAccess": true, + "dataRetention": { + "stdRetention": 1826, + "purposes": {}, + "specialPurposes": {} + }, + "urls": [ + { + "langId": "en", + "privacy": "https://privacy.audienceproject.com", + "legIntClaim": "https://privacy.audienceproject.com/en-GB/for-users/privacy-policy#transparency-and-consent-framework-tcf" + } + ], + "dataDeclaration": [ + 1, + 2, + 3, + 4, + 5, + 6, + 7, + 8, + 10, + 11 + ], + "deviceStorageDisclosureUrl": "https://sak.userreport.com/tcf.json" + }, + "410": { + "id": 410, + "name": "Adtelligent Inc.", + "purposes": [ + 1, + 2, + 7 + ], + "legIntPurposes": [], + "flexiblePurposes": [], + "specialPurposes": [ + 1, + 2 + ], + "features": [ + 3 + ], + "specialFeatures": [], + "cookieMaxAgeSeconds": 8035200, + "usesCookies": true, + "cookieRefresh": true, + "usesNonCookieAccess": true, + "dataRetention": { + "stdRetention": 90, + "purposes": {}, + "specialPurposes": { + "2": 0 + } + }, + "urls": [ + { + "langId": "en", + "privacy": "https://adtelligent.com/privacy-policy/", + "legIntClaim": "https://adtelligent.com/tos/" + } + ], + "dataDeclaration": [ + 1, + 2, + 3, + 4, + 6, + 7, + 8, + 11 + ], + "deviceStorageDisclosureUrl": "https://adtelligent.com/.well-known/deviceStorage.json" + }, + "412": { + "id": 412, + "name": "Piano Software Inc.", + "purposes": [ + 1, + 2, + 3, + 4, + 5, + 6, + 7, + 8, + 9, + 11 + ], + "legIntPurposes": [], + "flexiblePurposes": [ + 8, + 9, + 11 + ], + "specialPurposes": [], + "features": [ + 1, + 2, + 3 + ], + "specialFeatures": [], + "cookieMaxAgeSeconds": 31536000, + "usesCookies": true, + "cookieRefresh": false, + "usesNonCookieAccess": true, + "dataRetention": { + "stdRetention": 1096, + "purposes": {}, + "specialPurposes": {} + }, + "urls": [ + { + "langId": "en", + "privacy": "https://www.piano.io/privacy-policy", + "legIntClaim": "https://www.piano.io/privacy-policy" + } + ], + "dataDeclaration": [ + 1, + 2, + 3, + 5, + 6, + 7, + 10, + 11 + ], + "deviceStorageDisclosureUrl": "https://cdn.cxense.com/.well-known/deviceStorage.json" + }, + "413": { + "id": 413, + "name": "Eulerian Technologies", + "purposes": [ + 1, + 2, + 3, + 4, + 5, + 6, + 7, + 8, + 9, + 10 + ], + "legIntPurposes": [], + "flexiblePurposes": [], + "specialPurposes": [], + "features": [ + 1, + 2, + 3 + ], + "specialFeatures": [], + "cookieMaxAgeSeconds": 33696000, + "usesCookies": true, + "cookieRefresh": true, + "usesNonCookieAccess": true, + "dataRetention": { + "stdRetention": 180, + "purposes": {}, + "specialPurposes": {} + }, + "urls": [ + { + "langId": "en", + "privacy": "https://www.eulerian.com/en/privacy/" + }, + { + "langId": "fr", + "privacy": "https://www.eulerian.com/vie-privee" + }, + { + "langId": "es", + "privacy": "https://www.eulerian.com/es/privacidad" + }, + { + "langId": "it", + "privacy": "https://www.eulerian.com/it/privacy" + } + ], + "dataDeclaration": [ + 1, + 2, + 3, + 5, + 7 + ], + "deviceStorageDisclosureUrl": "https://eu.euleriancdn.net/ea-rt/tcfDeviceStorage.json" + }, + "416": { + "id": 416, + "name": "Commanders Act", + "purposes": [ + 1, + 2, + 3, + 4, + 5, + 6, + 7, + 9, + 10 + ], + "legIntPurposes": [], + "flexiblePurposes": [], + "specialPurposes": [], + "features": [ + 1, + 2, + 3 + ], + "specialFeatures": [], + "cookieMaxAgeSeconds": 31536000, + "usesCookies": true, + "cookieRefresh": false, + "usesNonCookieAccess": false, + "dataRetention": { + "stdRetention": 90, + "purposes": { + "7": 730, + "10": 30 + }, + "specialPurposes": {} + }, + "urls": [ + { + "langId": "en", + "privacy": "https://www.commandersact.com/en/privacy/" + }, + { + "langId": "fr", + "privacy": "https://www.commandersact.com/fr/vie-privee/" + }, + { + "langId": "de", + "privacy": "https://www.commandersact.com/de/datenschutz/" + }, + { + "langId": "it", + "privacy": "https://www.commandersact.com/it/privacy/" + } + ], + "dataDeclaration": [ + 1, + 3 + ], + "deviceStorageDisclosureUrl": "https://cdn.trustcommander.net/iab-v2/additional_vendor_information_list.json" + }, + "422": { + "id": 422, + "name": "Brand Metrics Sweden AB", + "purposes": [ + 1, + 7, + 8 + ], + "legIntPurposes": [], + "flexiblePurposes": [], + "specialPurposes": [], + "features": [], + "specialFeatures": [], + "cookieMaxAgeSeconds": 33350400, + "usesCookies": true, + "cookieRefresh": true, + "usesNonCookieAccess": true, + "dataRetention": { + "stdRetention": 386, + "purposes": {}, + "specialPurposes": {} + }, + "urls": [ + { + "langId": "en", + "privacy": "https://collector.brandmetrics.com/brandmetrics_privacypolicy.pdf", + "legIntClaim": "https://collector.brandmetrics.com/brandmetrics_privacypolicy.pdf" + } + ], + "dataDeclaration": [ + 6, + 7 + ], + "deviceStorageDisclosureUrl": "https://collector.brandmetrics.com/deviceStorageDisclosure.json" + }, + "423": { + "id": 423, + "name": "travel audience GmbH", + "purposes": [ + 1, + 2, + 3, + 4, + 5, + 7, + 9, + 10 + ], + "legIntPurposes": [], + "flexiblePurposes": [], + "specialPurposes": [], + "features": [ + 1, + 2 + ], + "specialFeatures": [ + 1 + ], + "cookieMaxAgeSeconds": 34300800, + "usesCookies": true, + "cookieRefresh": true, + "usesNonCookieAccess": false, + "dataRetention": { + "stdRetention": 397, + "purposes": {}, + "specialPurposes": {} + }, + "urls": [ + { + "langId": "en", + "privacy": "https://travelaudience.com/product-privacy-notice/" + } + ], + "dataDeclaration": [ + 1, + 2, + 3, + 5, + 6, + 8, + 10 + ], + "deviceStorageDisclosureUrl": "https://ads.travelaudience.com/deviceStorage.json" + }, + "430": { + "id": 430, + "name": "AdServing Factory srl", + "purposes": [ + 7 + ], + "legIntPurposes": [], + "flexiblePurposes": [], + "specialPurposes": [ + 1, + 2 + ], + "features": [ + 3 + ], + "specialFeatures": [], + "cookieMaxAgeSeconds": null, + "usesCookies": false, + "cookieRefresh": false, + "usesNonCookieAccess": false, + "dataRetention": { + "stdRetention": 1, + "purposes": { + "7": 30 + }, + "specialPurposes": {} + }, + "urls": [ + { + "langId": "en", + "privacy": "https://www.adservingfactory.com/privacy-policy.html", + "legIntClaim": "https://www.adservingfactory.com/privacy-policy.html" + } + ], + "dataDeclaration": [ + 2 + ], + "deviceStorageDisclosureUrl": "https://content.adunity.com/tcf-vdso.json" + }, + "431": { + "id": 431, + "name": "HUMAN", + "purposes": [], + "legIntPurposes": [ + 10 + ], + "flexiblePurposes": [], + "specialPurposes": [ + 1 + ], + "features": [ + 1, + 3 + ], + "specialFeatures": [ + 2 + ], + "cookieMaxAgeSeconds": null, + "usesCookies": false, + "cookieRefresh": false, + "usesNonCookieAccess": false, + "dataRetention": { + "stdRetention": 1095, + "purposes": {}, + "specialPurposes": {} + }, + "urls": [ + { + "langId": "en", + "privacy": "https://www.humansecurity.com/privacy", + "legIntClaim": "https://www.humansecurity.com/privacy" + } + ], + "dataDeclaration": [ + 1, + 2, + 3, + 4, + 8 + ], + "deviceStorageDisclosureUrl": "https://humansecurity.com/hubfs/devicestoragedisclosure.json" + }, + "434": { + "id": 434, + "name": "DynAdmic", + "purposes": [ + 1, + 2, + 3, + 4, + 7 + ], + "legIntPurposes": [], + "flexiblePurposes": [], + "specialPurposes": [ + 1, + 2 + ], + "features": [ + 1, + 3 + ], + "specialFeatures": [], + "cookieMaxAgeSeconds": 31536000, + "usesCookies": true, + "cookieRefresh": true, + "usesNonCookieAccess": false, + "dataRetention": { + "stdRetention": 360, + "purposes": {}, + "specialPurposes": {} + }, + "urls": [ + { + "langId": "en", + "privacy": "https://eu.dynadmic.com/privacy-policy/", + "legIntClaim": "https://eu.dynadmic.com/privacy-policy/" + } + ], + "dataDeclaration": [ + 1, + 2, + 3, + 4, + 5, + 6, + 8, + 10, + 11 + ], + "deviceStorageDisclosureUrl": "https://www.dynadmic.com/device-storage-disclosures.json" + }, + "435": { + "id": 435, + "name": "SINGLESPOT SAS ", + "purposes": [ + 1, + 3, + 4, + 7, + 9 + ], + "legIntPurposes": [], + "flexiblePurposes": [], + "specialPurposes": [ + 1 + ], + "features": [ + 1, + 2, + 3 + ], + "specialFeatures": [ + 1, + 2 + ], + "cookieMaxAgeSeconds": null, + "usesCookies": false, + "cookieRefresh": false, + "usesNonCookieAccess": true, + "dataRetention": { + "stdRetention": 385, + "purposes": {}, + "specialPurposes": {} + }, + "urls": [ + { + "langId": "fr", + "privacy": "https://www.singlespot.com/privacy_policy", + "legIntClaim": "https://www.singlespot.com/privacy_policy" + } + ], + "dataDeclaration": [ + 1, + 2, + 3, + 9, + 10, + 11 + ], + "deviceStorageDisclosureUrl": "https://singlespot-public.s3.eu-west-1.amazonaws.com/disclosures.json" + }, + "436": { + "id": 436, + "name": "INVIBES GROUP", + "purposes": [ + 1, + 3, + 4, + 5, + 6, + 9 + ], + "legIntPurposes": [ + 2, + 7, + 8, + 10 + ], + "flexiblePurposes": [ + 2, + 7, + 8, + 10 + ], + "specialPurposes": [ + 1, + 2 + ], + "features": [ + 1, + 2, + 3 + ], + "specialFeatures": [], + "cookieMaxAgeSeconds": 31536000, + "usesCookies": true, + "cookieRefresh": true, + "usesNonCookieAccess": true, + "dataRetention": { + "stdRetention": 365, + "purposes": {}, + "specialPurposes": {} + }, + "urls": [ + { + "langId": "en", + "privacy": "https://www.invibes.com/terms.html", + "legIntClaim": "https://www.invibes.com/terms.html" + } + ], + "dataDeclaration": [ + 1, + 2, + 3, + 4, + 5, + 6, + 8, + 10, + 11 + ], + "deviceStorageDisclosureUrl": "https://www.invibes.com/deviceStorage.json" + }, + "438": { + "id": 438, + "name": "INVIDI technologies AB", + "purposes": [ + 1, + 2, + 3, + 4, + 7, + 9, + 10 + ], + "legIntPurposes": [], + "flexiblePurposes": [ + 2, + 7, + 9, + 10 + ], + "specialPurposes": [], + "features": [ + 1, + 2 + ], + "specialFeatures": [], + "cookieMaxAgeSeconds": 315360000, + "usesCookies": true, + "cookieRefresh": false, + "usesNonCookieAccess": true, + "dataRetention": { + "stdRetention": 30, + "purposes": { + "3": 0, + "7": 765, + "9": 765 + }, + "specialPurposes": {} + }, + "urls": [ + { + "langId": "en", + "privacy": "https://www.invidi.com/privacy-policy-ad-tech-services/", + "legIntClaim": "https://www.invidi.com/privacy-policy-ad-tech-services/#legal-basis" + } + ], + "dataDeclaration": [ + 1, + 2, + 3, + 6, + 7, + 10, + 11 + ], + "deviceStorageDisclosureUrl": "https://storage.googleapis.com/iab-consent-framework/device-storage.json" + }, + "440": { + "id": 440, + "name": "DEFINE MEDIA GMBH", + "purposes": [ + 1, + 4 + ], + "legIntPurposes": [ + 2, + 7, + 10 + ], + "flexiblePurposes": [ + 2, + 7, + 10 + ], + "specialPurposes": [ + 1, + 2 + ], + "features": [ + 3 + ], + "specialFeatures": [], + "cookieMaxAgeSeconds": null, + "usesCookies": false, + "cookieRefresh": false, + "usesNonCookieAccess": true, + "dataRetention": { + "stdRetention": 0, + "purposes": {}, + "specialPurposes": {} + }, + "urls": [ + { + "langId": "de", + "privacy": "https://www.definemedia.de/datenschutz-conative/", + "legIntClaim": "https://definemedia.de/de/datenschutz-conative" + } + ], + "dataDeclaration": [ + 1, + 2, + 6, + 8, + 11 + ], + "deviceStorageDisclosureUrl": "https://definemedia.de/tcf/deviceStorageDisclosureURL.json" + }, + "450": { + "id": 450, + "name": "Neodata Group srl", + "purposes": [ + 1, + 2, + 3, + 4, + 5, + 6, + 7, + 8, + 9, + 10 + ], + "legIntPurposes": [], + "flexiblePurposes": [], + "specialPurposes": [], + "features": [ + 1, + 2, + 3 + ], + "specialFeatures": [ + 1 + ], + "cookieMaxAgeSeconds": 31556952, + "usesCookies": true, + "cookieRefresh": true, + "usesNonCookieAccess": true, + "dataRetention": { + "stdRetention": 180, + "purposes": {}, + "specialPurposes": {} + }, + "urls": [ + { + "langId": "en", + "privacy": "https://www.neodatagroup.com/en/services-privacy-policy-en/", + "legIntClaim": "https://www.neodatagroup.com/en/services-privacy-policy-en/" + } + ], + "dataDeclaration": [ + 1, + 2, + 3, + 5, + 6, + 7, + 8, + 10, + 11 + ], + "deviceStorageDisclosureUrl": "https://support.neodatagroup.com/deviceStorage.json" + }, + "452": { + "id": 452, + "name": "Innovid LLC", + "purposes": [ + 1, + 4 + ], + "legIntPurposes": [ + 2, + 7 + ], + "flexiblePurposes": [ + 2, + 7 + ], + "specialPurposes": [ + 1, + 2 + ], + "features": [ + 1, + 2 + ], + "specialFeatures": [], + "cookieMaxAgeSeconds": 7776000, + "usesCookies": true, + "cookieRefresh": true, + "usesNonCookieAccess": false, + "dataRetention": { + "stdRetention": 365, + "purposes": {}, + "specialPurposes": {} + }, + "urls": [ + { + "langId": "en", + "privacy": "https://www.innovid.com/privacy-policy", + "legIntClaim": "https://www.innovid.com/privacy-policy/#additional-information-europe-residents" + } + ], + "dataDeclaration": [ + 1, + 2, + 3, + 8, + 11 + ], + "deviceStorageDisclosureUrl": "https://iab.inbake.com/Innovid-IAB-TCFv2-disclosure.json" + }, + "459": { + "id": 459, + "name": "uppr GmbH", + "purposes": [ + 1 + ], + "legIntPurposes": [], + "flexiblePurposes": [], + "specialPurposes": [ + 1, + 2 + ], + "features": [ + 3 + ], + "specialFeatures": [], + "cookieMaxAgeSeconds": 7776000, + "usesCookies": true, + "cookieRefresh": false, + "usesNonCookieAccess": true, + "dataRetention": { + "stdRetention": 0, + "purposes": {}, + "specialPurposes": {} + }, + "urls": [ + { + "langId": "de", + "privacy": "https://netzwerk.uppr.de/privacy-policy.do", + "legIntClaim": "https://uppr.emcustomers.de/api/tcf/definitions/disclosures.json" + } + ], + "dataDeclaration": [ + 7 + ], + "deviceStorageDisclosureUrl": "https://uppr.emcustomers.de/api/tcf/definitions/disclosures.json" + }, + "461": { + "id": 461, + "name": "B2B Media Group GmbH", + "purposes": [ + 1, + 2, + 3, + 4, + 5, + 6, + 7, + 8, + 9, + 10, + 11 + ], + "legIntPurposes": [], + "flexiblePurposes": [ + 2, + 7, + 9, + 10 + ], + "specialPurposes": [ + 1, + 2 + ], + "features": [ + 1, + 2, + 3 + ], + "specialFeatures": [ + 1 + ], + "cookieMaxAgeSeconds": 7776000, + "usesCookies": true, + "cookieRefresh": true, + "usesNonCookieAccess": false, + "dataRetention": { + "stdRetention": 4320, + "purposes": {}, + "specialPurposes": {} + }, + "urls": [ + { + "langId": "en", + "privacy": "https://www.b2bmg.com/en/data-privacy/", + "legIntClaim": "https://www.b2bmg.com/en/data-privacy" + }, + { + "langId": "de", + "privacy": "https://www.b2bmg.com/de/datenschutz", + "legIntClaim": "https://www.b2bmg.com/de/datenschutz" + } + ], + "dataDeclaration": [ + 1, + 2, + 3, + 6, + 7, + 8, + 9, + 11 + ], + "deviceStorageDisclosureUrl": "https://b2biq.net/iab_vendor_storage.json" + }, + "466": { + "id": 466, + "name": "Papirfly AS", + "purposes": [], + "legIntPurposes": [ + 7 + ], + "flexiblePurposes": [], + "specialPurposes": [ + 1, + 2 + ], + "features": [], + "specialFeatures": [], + "cookieMaxAgeSeconds": null, + "usesCookies": false, + "cookieRefresh": false, + "usesNonCookieAccess": false, + "dataRetention": { + "stdRetention": 0, + "purposes": { + "7": 4320 + }, + "specialPurposes": {} + }, + "urls": [ + { + "langId": "en", + "privacy": "https://tacticrealtime.com/privacy/", + "legIntClaim": "https://tacticrealtime.com/privacy/dsar/" + } + ], + "dataDeclaration": [ + 2 + ], + "deviceStorageDisclosureUrl": "https://tacticrealtime.com/privacy/iab-device-storage.json" + }, + "468": { + "id": 468, + "name": "Neustar, Inc., a TransUnion company", + "purposes": [ + 1, + 3 + ], + "legIntPurposes": [ + 7, + 8, + 9, + 10 + ], + "flexiblePurposes": [ + 7, + 8, + 9, + 10 + ], + "specialPurposes": [ + 1 + ], + "features": [ + 1, + 2, + 3 + ], + "specialFeatures": [], + "cookieMaxAgeSeconds": 31536000, + "usesCookies": true, + "cookieRefresh": true, + "usesNonCookieAccess": true, + "dataRetention": { + "stdRetention": 540, + "purposes": {}, + "specialPurposes": {} + }, + "urls": [ + { + "langId": "en", + "privacy": "https://www.home.neustar/privacy", + "legIntClaim": "https://www.home.neustar/privacy" + } + ], + "dataDeclaration": [ + 1, + 2, + 3, + 4, + 5, + 6, + 7, + 8, + 10, + 11 + ], + "deviceStorageDisclosureUrl": "https://gdpr-tcf.agkn.com/NeustarDeviceStorage.json" + }, + "473": { + "id": 473, + "name": "Sub2 Technologies Ltd", + "purposes": [ + 1, + 2, + 3, + 4, + 7, + 10 + ], + "legIntPurposes": [], + "flexiblePurposes": [ + 2, + 7, + 10 + ], + "specialPurposes": [], + "features": [], + "specialFeatures": [], + "cookieMaxAgeSeconds": 63072000, + "usesCookies": true, + "cookieRefresh": true, + "usesNonCookieAccess": true, + "dataRetention": { + "stdRetention": 365, + "purposes": {}, + "specialPurposes": {} + }, + "urls": [ + { + "langId": "en", + "privacy": "https://www.sub2tech.com/privacy-policy/", + "legIntClaim": "https://www.sub2tech.com/privacy-policy/" + } + ], + "dataDeclaration": [ + 6, + 8, + 10 + ], + "deviceStorageDisclosureUrl": "https://cdn.sub2tech.com/privacy/devicestorage.json" + }, + "479": { + "id": 479, + "name": "INFINIA MOBILE S.L.", + "purposes": [ + 2, + 3, + 4, + 7, + 9 + ], + "legIntPurposes": [], + "flexiblePurposes": [], + "specialPurposes": [ + 2 + ], + "features": [ + 1, + 2 + ], + "specialFeatures": [], + "cookieMaxAgeSeconds": null, + "usesCookies": false, + "cookieRefresh": false, + "usesNonCookieAccess": false, + "dataRetention": { + "stdRetention": 90, + "purposes": {}, + "specialPurposes": {} + }, + "urls": [ + { + "langId": "es", + "privacy": "https://www.infiniamobile.com/avisopolitica.html#pri", + "legIntClaim": "https://www.infiniamobile.com/avisopolitica.html#pri" + }, + { + "langId": "en", + "privacy": "https://www.infiniamobile.com/avisopolitica-us.html#pri", + "legIntClaim": "https://www.infiniamobile.com/avisopolitica-us.html#pri" + } + ], + "dataDeclaration": [ + 1, + 2, + 3, + 6, + 8, + 10, + 11 + ], + "deviceStorageDisclosureUrl": "https://www.infiniamobile.com/tcf/tcf2.0.json" + }, + "488": { + "id": 488, + "name": "Opinary GmbH", + "purposes": [ + 1, + 2, + 3, + 4, + 5, + 6, + 7, + 8, + 9, + 10, + 11 + ], + "legIntPurposes": [], + "flexiblePurposes": [], + "specialPurposes": [ + 1, + 2 + ], + "features": [], + "specialFeatures": [], + "cookieMaxAgeSeconds": 5184000, + "usesCookies": true, + "cookieRefresh": true, + "usesNonCookieAccess": true, + "dataRetention": { + "stdRetention": 90, + "purposes": { + "2": 60, + "3": 0, + "4": 60, + "5": 0, + "7": 60 + }, + "specialPurposes": {} + }, + "urls": [ + { + "langId": "en", + "privacy": "https://opinary.com/privacy-policy/", + "legIntClaim": "https://opinary.com/opt-out" + }, + { + "langId": "de", + "privacy": "https://opinary.com/datenschutz/", + "legIntClaim": "https://opinary.com/opt-out" + } + ], + "dataDeclaration": [ + 1, + 2, + 6, + 7, + 8, + 10, + 11 + ], + "deviceStorageDisclosureUrl": "https://cdn.opinary.com/.well-known/device-storage.json" + }, + "490": { + "id": 490, + "name": "PLAYGROUND XYZ EMEA LTD", + "purposes": [ + 1, + 2, + 3, + 4, + 7, + 10 + ], + "legIntPurposes": [], + "flexiblePurposes": [ + 2, + 7, + 10 + ], + "specialPurposes": [ + 1 + ], + "features": [], + "specialFeatures": [], + "cookieMaxAgeSeconds": 15552200, + "usesCookies": true, + "cookieRefresh": true, + "usesNonCookieAccess": false, + "dataRetention": { + "stdRetention": 45, + "purposes": {}, + "specialPurposes": { + "1": 30 + } + }, + "urls": [ + { + "langId": "en", + "privacy": "https://playground.xyz/privacy", + "legIntClaim": "https://playground.xyz/privacy" + } + ], + "dataDeclaration": [ + 1, + 2, + 6, + 8 + ], + "deviceStorageDisclosureUrl": "https://playground.xyz/tcf-disclosure.json" + }, + "491": { + "id": 491, + "name": "SevenData S.p.a.", + "purposes": [ + 1, + 2, + 3, + 4, + 5, + 6, + 7, + 8, + 9, + 10 + ], + "legIntPurposes": [], + "flexiblePurposes": [], + "specialPurposes": [], + "features": [], + "specialFeatures": [], + "cookieMaxAgeSeconds": 15552000, + "usesCookies": true, + "cookieRefresh": true, + "usesNonCookieAccess": true, + "dataRetention": { + "stdRetention": 180, + "purposes": {}, + "specialPurposes": {} + }, + "urls": [ + { + "langId": "it", + "privacy": "https://www.shinystat.com/it/informativa_privacy_generale.html" + } + ], + "dataDeclaration": [ + 2, + 3, + 4, + 6 + ], + "deviceStorageDisclosureUrl": "https://www.shinystat.com/shinystat_cookie.json" + }, + "493": { + "id": 493, + "name": "Magnite, Inc. (Carbon AI Limited)", + "purposes": [ + 1, + 2, + 3, + 4, + 5, + 6, + 7, + 8, + 9 + ], + "legIntPurposes": [ + 10 + ], + "flexiblePurposes": [ + 2, + 7, + 8, + 10 + ], + "specialPurposes": [ + 1, + 2 + ], + "features": [ + 1, + 2, + 3 + ], + "specialFeatures": [], + "cookieMaxAgeSeconds": 7689600, + "usesCookies": true, + "cookieRefresh": true, + "usesNonCookieAccess": true, + "dataRetention": { + "stdRetention": 90, + "purposes": {}, + "specialPurposes": {} + }, + "urls": [ + { + "langId": "en", + "privacy": "https://www.magnite.com/legal/advertising-technology-privacy-policy/", + "legIntClaim": "https://www.magnite.com/legal/advertising-technology-privacy-policy/" + } + ], + "dataDeclaration": [ + 1, + 2, + 3, + 6, + 8, + 11 + ], + "deviceStorageDisclosureUrl": "https://nai-edge.ccgateway.net/privacy/disclosure" + }, + "495": { + "id": 495, + "name": "Arcspire Limited", + "purposes": [ + 2, + 7, + 9, + 10 + ], + "legIntPurposes": [], + "flexiblePurposes": [], + "specialPurposes": [ + 1, + 2 + ], + "features": [ + 3 + ], + "specialFeatures": [ + 1 + ], + "overflow": { + "httpGetLimit": 128 + }, + "cookieMaxAgeSeconds": null, + "usesCookies": false, + "cookieRefresh": false, + "usesNonCookieAccess": true, + "dataRetention": { + "stdRetention": 365, + "purposes": {}, + "specialPurposes": {} + }, + "urls": [ + { + "langId": "en", + "privacy": "https://public.arcspire.io/privacy.pdf", + "legIntClaim": "https://public.arcspire.io/privacy.pdf" + } + ], + "dataDeclaration": [ + 1, + 2, + 3, + 6, + 8, + 9, + 10, + 11 + ], + "deviceStorageDisclosureUrl": "https://public.arcspire.io/disclosures.json" + }, + "496": { + "id": 496, + "name": "Automattic Ads", + "purposes": [ + 1, + 2, + 4, + 7, + 9, + 10 + ], + "legIntPurposes": [], + "flexiblePurposes": [], + "specialPurposes": [ + 1, + 2 + ], + "features": [ + 3 + ], + "specialFeatures": [], + "cookieMaxAgeSeconds": 63072000, + "usesCookies": true, + "cookieRefresh": true, + "usesNonCookieAccess": false, + "dataRetention": { + "stdRetention": 4320, + "purposes": { + "2": 730, + "4": 90 + }, + "specialPurposes": {} + }, + "urls": [ + { + "langId": "en", + "privacy": "https://automattic.com/privacy/", + "legIntClaim": "https://automattic.com/privacy/" + } + ], + "dataDeclaration": [ + 1, + 2, + 3, + 4, + 6, + 7, + 8, + 10, + 11 + ], + "deviceStorageDisclosureUrl": "https://c0.pubmine.com/device-storage.json" + }, + "497": { + "id": 497, + "name": "Little Big Data sp. z o.o.", + "purposes": [ + 1, + 3, + 9 + ], + "legIntPurposes": [], + "flexiblePurposes": [], + "specialPurposes": [ + 2 + ], + "features": [ + 1 + ], + "specialFeatures": [], + "cookieMaxAgeSeconds": 94608001, + "usesCookies": true, + "cookieRefresh": false, + "usesNonCookieAccess": true, + "dataRetention": { + "stdRetention": 2555, + "purposes": {}, + "specialPurposes": {} + }, + "urls": [ + { + "langId": "pl", + "privacy": "https://www.dataexchanger.pl/privacy-policy", + "legIntClaim": "https://www.dataexchanger.pl/privacy-policy" + } + ], + "dataDeclaration": [ + 2, + 6, + 8 + ], + "deviceStorageDisclosureUrl": "https://dtxngr.com/additional-vendor-information-list.json" + }, + "498": { + "id": 498, + "name": "Mediakeys Platform", + "purposes": [ + 1, + 2, + 3, + 4, + 6, + 7, + 9, + 10 + ], + "legIntPurposes": [], + "flexiblePurposes": [], + "specialPurposes": [ + 1, + 2 + ], + "features": [ + 1 + ], + "specialFeatures": [ + 1 + ], + "cookieMaxAgeSeconds": null, + "usesCookies": false, + "cookieRefresh": false, + "usesNonCookieAccess": true, + "dataRetention": { + "stdRetention": 1825, + "purposes": {}, + "specialPurposes": {} + }, + "urls": [ + { + "langId": "en", + "privacy": "https://arago.com/fr/politique-de-confidentialite/", + "legIntClaim": "https://arago.com/fr/politique-de-confidentialite/" + } + ], + "dataDeclaration": [ + 1, + 2, + 3, + 4, + 6, + 8, + 9, + 11 + ], + "deviceStorageDisclosureUrl": "https://resourcekeys.com/deviceStorageDisclosure.json" + }, + "507": { + "id": 507, + "name": "AdsWizz Inc.", + "purposes": [ + 1, + 2, + 3, + 4, + 5, + 6, + 7, + 8, + 9, + 10 + ], + "legIntPurposes": [], + "flexiblePurposes": [ + 2, + 7, + 8, + 9, + 10 + ], + "specialPurposes": [ + 1, + 2 + ], + "features": [ + 1, + 2, + 3 + ], + "specialFeatures": [ + 1 + ], + "cookieMaxAgeSeconds": 7776000, + "usesCookies": true, + "cookieRefresh": true, + "usesNonCookieAccess": false, + "dataRetention": { + "stdRetention": 90, + "purposes": {}, + "specialPurposes": {} + }, + "urls": [ + { + "langId": "en", + "privacy": "https://www.adswizz.com/privacy-policy/", + "legIntClaim": "https://www.adswizz.com/privacy-policy/" + } + ], + "dataDeclaration": [ + 1, + 2, + 3, + 4, + 6, + 7, + 8, + 9, + 10, + 11 + ], + "deviceStorageDisclosureUrl": "https://www.adswizz.com/deviceStorage.json" + }, + "511": { + "id": 511, + "name": "Admixer EU GmbH", + "purposes": [ + 1, + 2, + 3, + 4, + 5, + 7, + 9 + ], + "legIntPurposes": [ + 10 + ], + "flexiblePurposes": [], + "specialPurposes": [ + 1, + 2 + ], + "features": [ + 1, + 2 + ], + "specialFeatures": [ + 1 + ], + "overflow": { + "httpGetLimit": 128 + }, + "cookieMaxAgeSeconds": 7776000, + "usesCookies": true, + "cookieRefresh": true, + "usesNonCookieAccess": false, + "dataRetention": { + "stdRetention": 90, + "purposes": {}, + "specialPurposes": {} + }, + "urls": [ + { + "langId": "en", + "privacy": "https://admixer.com/privacy/", + "legIntClaim": "https://admixer.com/privacy/" + } + ], + "dataDeclaration": [ + 1, + 2, + 3, + 7, + 8, + 11 + ], + "deviceStorageDisclosureUrl": "https://admixer.com/tcf.json" + }, + "512": { + "id": 512, + "name": "Verve Group Europe GmbH", + "purposes": [ + 1, + 2, + 3, + 4, + 7, + 8, + 10 + ], + "legIntPurposes": [], + "flexiblePurposes": [], + "specialPurposes": [ + 1, + 2 + ], + "features": [ + 3 + ], + "specialFeatures": [ + 1 + ], + "cookieMaxAgeSeconds": null, + "usesCookies": false, + "cookieRefresh": false, + "usesNonCookieAccess": true, + "dataRetention": { + "stdRetention": 365, + "purposes": { + "7": 4320, + "8": 4320, + "10": 4320 + }, + "specialPurposes": { + "2": 0 + } + }, + "urls": [ + { + "langId": "en", + "privacy": "https://pubnative.net/privacy-notice/", + "legIntClaim": "https://pubnative.net/privacy-notice/" + } + ], + "dataDeclaration": [ + 1, + 2, + 3, + 5, + 6, + 7, + 8, + 9, + 10, + 11 + ], + "deviceStorageDisclosureUrl": "https://resources.verve.com/hubfs/deviceStorage.json" + }, + "516": { + "id": 516, + "name": "Pexi B.V.", + "purposes": [ + 1, + 2, + 3, + 4, + 5, + 6, + 7, + 8, + 9, + 10 + ], + "legIntPurposes": [], + "flexiblePurposes": [], + "specialPurposes": [], + "features": [], + "specialFeatures": [], + "cookieMaxAgeSeconds": null, + "usesCookies": false, + "cookieRefresh": false, + "usesNonCookieAccess": true, + "dataRetention": { + "stdRetention": 0, + "purposes": {}, + "specialPurposes": {} + }, + "urls": [ + { + "langId": "nl", + "privacy": "https://pexi.nl/privacy-policy/" + } + ], + "dataDeclaration": [ + 1, + 2, + 3 + ], + "deviceStorageDisclosureUrl": "https://dash.pexi.nl/api/public/device-storage-url.json" + }, + "517": { + "id": 517, + "name": "SunMedia ", + "purposes": [ + 1, + 2, + 3, + 4, + 7, + 8, + 9, + 10, + 11 + ], + "legIntPurposes": [], + "flexiblePurposes": [], + "specialPurposes": [], + "features": [ + 2, + 3 + ], + "specialFeatures": [], + "overflow": { + "httpGetLimit": 128 + }, + "cookieMaxAgeSeconds": 10368000, + "usesCookies": true, + "cookieRefresh": false, + "usesNonCookieAccess": true, + "dataRetention": { + "stdRetention": 120, + "purposes": {}, + "specialPurposes": {} + }, + "urls": [ + { + "langId": "en", + "privacy": "https://www.sunmedia.tv/en/cookies-users/" + }, + { + "langId": "es", + "privacy": "https://www.sunmedia.tv/cookies-users/" + } + ], + "dataDeclaration": [ + 1, + 2, + 3, + 4, + 8 + ], + "deviceStorageDisclosureUrl": "https://vod.sunmedia.tv/sunmedia/cookies.json" + }, + "530": { + "id": 530, + "name": "Near Intelligence Pte. Ltd.", + "purposes": [ + 2, + 3, + 4, + 7, + 8, + 9, + 10 + ], + "legIntPurposes": [], + "flexiblePurposes": [ + 2, + 7, + 8, + 9, + 10 + ], + "specialPurposes": [ + 1, + 2 + ], + "features": [ + 1, + 2 + ], + "specialFeatures": [ + 1 + ], + "overflow": { + "httpGetLimit": 128 + }, + "cookieMaxAgeSeconds": null, + "usesCookies": false, + "cookieRefresh": false, + "usesNonCookieAccess": false, + "dataRetention": { + "stdRetention": 1460, + "purposes": {}, + "specialPurposes": {} + }, + "urls": [ + { + "langId": "en", + "privacy": "https://near.com/privacy-policy/", + "legIntClaim": "https://near.com/privacy-policy/#services-policy" + } + ], + "dataDeclaration": [ + 1, + 2, + 3, + 6, + 8, + 9, + 11 + ], + "deviceStorageDisclosureUrl": "https://near.com/iab/disclosures.json" + }, + "531": { + "id": 531, + "name": "Smartclip Hispania S.L.", + "purposes": [ + 1, + 2, + 3, + 4, + 7 + ], + "legIntPurposes": [], + "flexiblePurposes": [], + "specialPurposes": [], + "features": [ + 1, + 2, + 3 + ], + "specialFeatures": [ + 1 + ], + "cookieMaxAgeSeconds": 0, + "usesCookies": true, + "cookieRefresh": false, + "usesNonCookieAccess": false, + "dataRetention": { + "stdRetention": 120, + "purposes": {}, + "specialPurposes": {} + }, + "urls": [ + { + "langId": "es", + "privacy": "https://rgpd-smartclip.com/" + } + ], + "dataDeclaration": [ + 1, + 3, + 4, + 6, + 7, + 8, + 10 + ], + "deviceStorageDisclosureUrl": "https://cdn.smartclip-services.com/.well-known/deviceStorage.json" + }, + "535": { + "id": 535, + "name": "INNITY", + "purposes": [ + 1, + 2, + 4, + 5, + 6, + 7, + 8, + 9, + 10 + ], + "legIntPurposes": [], + "flexiblePurposes": [], + "specialPurposes": [ + 1, + 2 + ], + "features": [ + 1, + 2 + ], + "specialFeatures": [], + "cookieMaxAgeSeconds": 63072000, + "usesCookies": true, + "cookieRefresh": false, + "usesNonCookieAccess": true, + "dataRetention": { + "purposes": { + "2": 365, + "4": 720, + "5": 720, + "6": 720, + "7": 365, + "8": 365, + "9": 720, + "10": 720 + }, + "specialPurposes": { + "1": 365, + "2": 365 + } + }, + "urls": [ + { + "langId": "en", + "privacy": "https://www.innity.com/privacy-policy.php", + "legIntClaim": "https://www.innity.com/privacy-policy.php" + } + ], + "dataDeclaration": [ + 1, + 4, + 6, + 11 + ], + "deviceStorageDisclosureUrl": "https://www.advenueplatform.com/tcf" + }, + "536": { + "id": 536, + "name": "GlobalWebIndex", + "purposes": [ + 1, + 7, + 8, + 9 + ], + "legIntPurposes": [], + "flexiblePurposes": [], + "specialPurposes": [], + "features": [ + 1, + 2, + 3 + ], + "specialFeatures": [], + "cookieMaxAgeSeconds": 31622400, + "usesCookies": true, + "cookieRefresh": true, + "usesNonCookieAccess": false, + "dataRetention": { + "stdRetention": 365, + "purposes": {}, + "specialPurposes": {} + }, + "urls": [ + { + "langId": "en", + "privacy": "https://legal.trendstream.net/non-panellist_privacy_policy" + } + ], + "dataDeclaration": [ + 1, + 2, + 3, + 4, + 6, + 7, + 10, + 11 + ], + "deviceStorageDisclosureUrl": "https://gwiq.globalwebindex.net/tcf2/deviceStorage.json" + }, + "539": { + "id": 539, + "name": "AdDefend GmbH", + "purposes": [ + 1, + 2, + 3, + 4, + 7 + ], + "legIntPurposes": [], + "flexiblePurposes": [], + "specialPurposes": [ + 1, + 2 + ], + "features": [ + 3 + ], + "specialFeatures": [], + "cookieMaxAgeSeconds": 2592000, + "usesCookies": true, + "cookieRefresh": true, + "usesNonCookieAccess": false, + "dataRetention": { + "stdRetention": 30, + "purposes": {}, + "specialPurposes": {} + }, + "urls": [ + { + "langId": "en", + "privacy": "https://www.addefend.com/en/privacy-policy/", + "legIntClaim": "https://www.addefend.com/en/privacy-policy/" + } + ], + "dataDeclaration": [ + 1, + 2, + 4 + ], + "deviceStorageDisclosureUrl": "https://www.addefend.com/deviceStorage.json" + }, + "544": { + "id": 544, + "name": "Kochava Inc.", + "purposes": [ + 7 + ], + "legIntPurposes": [], + "flexiblePurposes": [], + "specialPurposes": [], + "features": [ + 1, + 2, + 3 + ], + "specialFeatures": [ + 1, + 2 + ], + "cookieMaxAgeSeconds": null, + "usesCookies": false, + "cookieRefresh": false, + "usesNonCookieAccess": false, + "dataRetention": { + "purposes": { + "7": 395 + }, + "specialPurposes": {} + }, + "urls": [ + { + "langId": "en", + "privacy": "https://www.kochava.com/support-privacy/" + }, + { + "langId": "de", + "privacy": "https://www.kochava.com/support-privacy/" + }, + { + "langId": "ru", + "privacy": "https://www.kochava.com/support-privacy/" + }, + { + "langId": "es", + "privacy": "https://www.kochava.com/support-privacy/" + }, + { + "langId": "ja", + "privacy": "https://www.kochava.com/support-privacy/" + }, + { + "langId": "zh", + "privacy": "https://www.kochava.com/support-privacy/" + } + ], + "dataDeclaration": [ + 1, + 2, + 3, + 4, + 5, + 6, + 11 + ], + "deviceStorageDisclosureUrl": "https://iab.kochava.com/DeviceStorageDisclosure.json" + }, + "546": { + "id": 546, + "name": "Smart Traffik", + "purposes": [ + 1, + 3, + 7 + ], + "legIntPurposes": [], + "flexiblePurposes": [], + "specialPurposes": [ + 1 + ], + "features": [ + 1, + 2, + 3 + ], + "specialFeatures": [ + 1, + 2 + ], + "cookieMaxAgeSeconds": 34187400, + "usesCookies": true, + "cookieRefresh": true, + "usesNonCookieAccess": true, + "dataRetention": { + "stdRetention": 730, + "purposes": {}, + "specialPurposes": { + "1": 90 + } + }, + "urls": [ + { + "langId": "fr", + "privacy": "https://okube-attribution.com/politique-de-confidentialite/", + "legIntClaim": "https://okube-attribution.com/politique-de-confidentialite-precisions-sur-la-source-de-donnee-smartbox/" + }, + { + "langId": "en", + "privacy": "https://okube-attribution.com/en/privacy-policy/", + "legIntClaim": "https://okube-attribution.com/en/privacy-policy/privacy-policy-details-of-the-smartbox-data-source/" + } + ], + "dataDeclaration": [ + 1, + 2, + 3, + 4, + 5, + 6, + 7, + 8, + 9, + 10, + 11 + ], + "deviceStorageDisclosureUrl": "https://std-prod-static-crossorigin.s3.eu-west-1.amazonaws.com/public/deviceStorage.json" + }, + "550": { + "id": 550, + "name": "Happydemics", + "purposes": [ + 1, + 2 + ], + "legIntPurposes": [ + 9, + 10 + ], + "flexiblePurposes": [ + 9, + 10 + ], + "specialPurposes": [ + 2 + ], + "features": [ + 3 + ], + "specialFeatures": [], + "cookieMaxAgeSeconds": 129600, + "usesCookies": true, + "cookieRefresh": false, + "usesNonCookieAccess": false, + "dataRetention": { + "purposes": { + "2": 90, + "9": 1095, + "10": 1095 + }, + "specialPurposes": { + "2": 90 + } + }, + "urls": [ + { + "langId": "en", + "privacy": "https://happydemics.com/en/terms_and_conditions", + "legIntClaim": "https://happydemics.com/en/terms_and_conditions" + }, + { + "langId": "fr", + "privacy": "https://happydemics.com/fr/conditions-generales", + "legIntClaim": "https://happydemics.com/fr/conditions-generales" + } + ], + "dataDeclaration": [ + 1, + 2, + 3, + 8, + 11 + ], + "deviceStorageDisclosureUrl": "https://files.happydemics.com/iab-tcf/device_storage_disclosure.json" + }, + "565": { + "id": 565, + "name": "Adobe Audience Manager, Adobe Experience Platform", + "purposes": [ + 1, + 10 + ], + "legIntPurposes": [], + "flexiblePurposes": [], + "specialPurposes": [ + 1 + ], + "features": [ + 1, + 2, + 3 + ], + "specialFeatures": [], + "cookieMaxAgeSeconds": 15552000, + "usesCookies": true, + "cookieRefresh": true, + "usesNonCookieAccess": false, + "dataRetention": { + "stdRetention": 0, + "purposes": {}, + "specialPurposes": {} + }, + "urls": [ + { + "langId": "en", + "privacy": "https://www.adobe.com/privacy/policy.html", + "legIntClaim": "https://www.adobe.com/privacy/policy.html" + } + ], + "dataDeclaration": [ + 1, + 2, + 3, + 4, + 5, + 6, + 7, + 8, + 9, + 10, + 11 + ], + "deviceStorageDisclosureUrl": "https://aam-iab-tcf-vendor.s3.amazonaws.com/aam_device_storage_disclosures.json" + }, + "568": { + "id": 568, + "name": "Next Media SRL", + "purposes": [ + 1, + 2, + 3, + 4, + 5, + 6, + 7, + 8, + 9, + 10 + ], + "legIntPurposes": [], + "flexiblePurposes": [], + "specialPurposes": [], + "features": [ + 1, + 2, + 3 + ], + "specialFeatures": [ + 1, + 2 + ], + "cookieMaxAgeSeconds": 15552000, + "usesCookies": true, + "cookieRefresh": true, + "usesNonCookieAccess": true, + "dataRetention": { + "stdRetention": 180, + "purposes": {}, + "specialPurposes": {} + }, + "urls": [ + { + "langId": "it", + "privacy": "https://next14.com/media/privacy" + } + ], + "dataDeclaration": [ + 1, + 2, + 3, + 6, + 9, + 11 + ], + "deviceStorageDisclosureUrl": "https://js.datafront.co/next14_dmp_device_storage_information.json" + }, + "570": { + "id": 570, + "name": "Czech Publisher Exchange z.s.p.o.", + "purposes": [ + 1, + 2, + 3, + 4, + 5, + 6, + 7, + 8, + 9, + 10, + 11 + ], + "legIntPurposes": [], + "flexiblePurposes": [], + "specialPurposes": [], + "features": [ + 1, + 2, + 3 + ], + "specialFeatures": [], + "cookieMaxAgeSeconds": 31622389, + "usesCookies": true, + "cookieRefresh": true, + "usesNonCookieAccess": false, + "dataRetention": { + "stdRetention": 365, + "purposes": {}, + "specialPurposes": {} + }, + "urls": [ + { + "langId": "cs", + "privacy": "https://www.cpex.cz/pro-uzivatele/ochrana-soukromi/" + } + ], + "dataDeclaration": [ + 1, + 2, + 5, + 6, + 7, + 10, + 11 + ], + "deviceStorageDisclosureUrl": "https://cpex.cz/storagedisclosure.json" + }, + "573": { + "id": 573, + "name": "Dailymotion SA", + "purposes": [ + 1, + 3, + 4, + 5, + 6 + ], + "legIntPurposes": [ + 2, + 7, + 8, + 9, + 10, + 11 + ], + "flexiblePurposes": [ + 2, + 7, + 8, + 9, + 10 + ], + "specialPurposes": [ + 1, + 2 + ], + "features": [ + 1, + 2 + ], + "specialFeatures": [], + "overflow": { + "httpGetLimit": 32 + }, + "cookieMaxAgeSeconds": 34214390, + "usesCookies": true, + "cookieRefresh": false, + "usesNonCookieAccess": true, + "dataRetention": { + "stdRetention": 92, + "purposes": { + "3": 366, + "4": 366, + "5": 186, + "6": 186, + "8": 731, + "9": 731, + "10": 2192, + "11": 30 + }, + "specialPurposes": { + "1": 1096 + } + }, + "urls": [ + { + "langId": "en", + "privacy": "https://legal.dailymotion.com/en/privacy-policy/", + "legIntClaim": "https://legal.dailymotion.com/en/legitimate-interest/" + }, + { + "langId": "fr", + "privacy": "https://legal.dailymotion.com/fr/politique-de-confidentialite/", + "legIntClaim": "https://legal.dailymotion.com/en/legitimate-interest/" + } + ], + "dataDeclaration": [ + 1, + 2, + 3, + 5, + 6, + 7, + 8, + 10, + 11 + ], + "deviceStorageDisclosureUrl": "https://statics.dmcdn.net/a/vds.json" + }, + "580": { + "id": 580, + "name": "Goldbach Group AG", + "purposes": [ + 1, + 3, + 4 + ], + "legIntPurposes": [ + 2, + 7, + 9, + 10 + ], + "flexiblePurposes": [ + 2, + 7, + 9, + 10 + ], + "specialPurposes": [ + 1, + 2 + ], + "features": [ + 1, + 2, + 3 + ], + "specialFeatures": [ + 1 + ], + "cookieMaxAgeSeconds": 94670856, + "usesCookies": true, + "cookieRefresh": false, + "usesNonCookieAccess": true, + "dataRetention": { + "stdRetention": 4320, + "purposes": {}, + "specialPurposes": {} + }, + "urls": [ + { + "langId": "de", + "privacy": "https://goldbach.com/ch/de/datenschutzerklaerung/goldbach-group-ag", + "legIntClaim": "https://goldbach.com/ch/de/datenschutzerklaerung/goldbach-group-ag" + }, + { + "langId": "en", + "privacy": "https://goldbach.com/ch/en/privacy-policy/goldbach-group", + "legIntClaim": "https://goldbach.com/ch/en/privacy-policy/goldbach-group" + }, + { + "langId": "fr", + "privacy": "https://goldbach.com/ch/fr/politique-de-confidentialite/goldbach-group", + "legIntClaim": "https://goldbach.com/ch/fr/politique-de-confidentialite/goldbach-group" + } + ], + "dataDeclaration": [ + 1, + 2, + 3, + 5, + 6, + 7, + 8, + 9, + 10, + 11 + ], + "deviceStorageDisclosureUrl": "https://dai-video.s3.eu-central-1.amazonaws.com/JSON/TcfGoldbachDeviceStorage.json" + }, + "601": { + "id": 601, + "name": "WebAds B.V", + "purposes": [ + 1, + 2 + ], + "legIntPurposes": [], + "flexiblePurposes": [], + "specialPurposes": [ + 2 + ], + "features": [], + "specialFeatures": [], + "cookieMaxAgeSeconds": null, + "usesCookies": false, + "cookieRefresh": false, + "usesNonCookieAccess": true, + "dataRetention": { + "stdRetention": 28, + "purposes": {}, + "specialPurposes": {} + }, + "urls": [ + { + "langId": "en", + "privacy": "https://privacy.webads.eu/", + "legIntClaim": "https://privacy.webads.eu/" + } + ], + "dataDeclaration": [ + 1 + ], + "deviceStorageDisclosureUrl": "https://nojazz.eu/int/iab/tcf-storage.json" + }, + "602": { + "id": 602, + "name": "Online Solution", + "purposes": [ + 1, + 2, + 3, + 4, + 7, + 8, + 9, + 10 + ], + "legIntPurposes": [], + "flexiblePurposes": [ + 2, + 7, + 8, + 10 + ], + "specialPurposes": [ + 1, + 2 + ], + "features": [ + 1, + 3 + ], + "specialFeatures": [ + 1 + ], + "cookieMaxAgeSeconds": 31536000, + "usesCookies": true, + "cookieRefresh": true, + "usesNonCookieAccess": true, + "dataRetention": { + "stdRetention": 30, + "purposes": {}, + "specialPurposes": { + "1": 365 + } + }, + "urls": [ + { + "langId": "de", + "privacy": "https://adsafety.net/privacy.html", + "legIntClaim": "https://adsafety.net/privacy.html" + } + ], + "dataDeclaration": [ + 1, + 2, + 3, + 4, + 6, + 7, + 8, + 9, + 10, + 11 + ], + "deviceStorageDisclosureUrl": "https://tcf.adtech.app/gen/deviceStorageDisclosure/os.json" + }, + "606": { + "id": 606, + "name": "Impactify SARL", + "purposes": [ + 1, + 2, + 3, + 4, + 5, + 6, + 7, + 8, + 9, + 10 + ], + "legIntPurposes": [], + "flexiblePurposes": [ + 2, + 7, + 8, + 9, + 10 + ], + "specialPurposes": [ + 1, + 2 + ], + "features": [], + "specialFeatures": [], + "cookieMaxAgeSeconds": 2592000, + "usesCookies": true, + "cookieRefresh": true, + "usesNonCookieAccess": true, + "dataRetention": { + "stdRetention": 30, + "purposes": { + "7": 7, + "8": 7, + "9": 7, + "10": 7 + }, + "specialPurposes": { + "1": 14 + } + }, + "urls": [ + { + "langId": "en", + "privacy": "https://impactify.io/privacy-policy/", + "legIntClaim": "https://impactify.io/privacy-policy/#legal-basis-and-purposes-for-processing" + } + ], + "dataDeclaration": [ + 1, + 2, + 3, + 6, + 11 + ], + "deviceStorageDisclosureUrl": "https://ad.impactify.io/tcfvendors.json" + }, + "612": { + "id": 612, + "name": "Adnami Aps", + "purposes": [], + "legIntPurposes": [ + 7 + ], + "flexiblePurposes": [ + 7 + ], + "specialPurposes": [ + 1, + 2 + ], + "features": [], + "specialFeatures": [], + "cookieMaxAgeSeconds": null, + "usesCookies": false, + "cookieRefresh": false, + "usesNonCookieAccess": false, + "dataRetention": { + "stdRetention": 0, + "purposes": {}, + "specialPurposes": {} + }, + "urls": [ + { + "langId": "en", + "privacy": "https://www.adnami.io/privacy-policy-services", + "legIntClaim": "https://www.adnami.io/privacy-policy-services" + }, + { + "langId": "de", + "privacy": "https://www.adnami.io/privacy-policy-services-de", + "legIntClaim": "https://www.adnami.io/privacy-policy-services-de" + } + ], + "dataDeclaration": [ + 1, + 8, + 11 + ], + "deviceStorageDisclosureUrl": "https://macro.adnami.io/macro/iab/deviceStorage.json" + }, + "613": { + "id": 613, + "name": "Adserve.zone / Artworx AS", + "purposes": [ + 10 + ], + "legIntPurposes": [ + 2, + 7 + ], + "flexiblePurposes": [ + 10 + ], + "specialPurposes": [ + 1, + 2 + ], + "features": [], + "specialFeatures": [], + "overflow": { + "httpGetLimit": 32 + }, + "cookieMaxAgeSeconds": 2592000, + "usesCookies": true, + "cookieRefresh": false, + "usesNonCookieAccess": true, + "dataRetention": { + "stdRetention": 30, + "purposes": {}, + "specialPurposes": {} + }, + "urls": [ + { + "langId": "en", + "privacy": "https://adserve.zone/adserveprivacypolicy.html", + "legIntClaim": "https://adserve.zone/adserveprivacypolicy.html#legitimateinterestclaim" + } + ], + "dataDeclaration": [ + 1, + 8 + ], + "deviceStorageDisclosureUrl": "https://adserve.zone/tcf/deviceStorageDisclosure.json" + }, + "620": { + "id": 620, + "name": "Blue", + "purposes": [ + 1, + 2, + 3, + 4, + 5, + 6, + 7, + 8, + 9, + 10 + ], + "legIntPurposes": [], + "flexiblePurposes": [], + "specialPurposes": [ + 1, + 2 + ], + "features": [ + 2, + 3 + ], + "specialFeatures": [ + 1 + ], + "cookieMaxAgeSeconds": 2592000, + "usesCookies": true, + "cookieRefresh": false, + "usesNonCookieAccess": false, + "dataRetention": { + "stdRetention": 30, + "purposes": {}, + "specialPurposes": {} + }, + "urls": [ + { + "langId": "en", + "privacy": "https://www.getblue.io/privacy/", + "legIntClaim": "https://www.getblue.io/privacy/" + } + ], + "dataDeclaration": [ + 1, + 2, + 6, + 8, + 9, + 10, + 11 + ], + "deviceStorageDisclosureUrl": "https://getblue.io/iab/iab.json" + }, + "621": { + "id": 621, + "name": "Seznam.cz, a.s.", + "purposes": [ + 1, + 3, + 4, + 5, + 6 + ], + "legIntPurposes": [ + 2, + 7, + 8, + 9, + 10 + ], + "flexiblePurposes": [], + "specialPurposes": [ + 1, + 2 + ], + "features": [ + 1, + 2, + 3 + ], + "specialFeatures": [ + 1, + 2 + ], + "cookieMaxAgeSeconds": 31556926, + "usesCookies": true, + "cookieRefresh": true, + "usesNonCookieAccess": true, + "dataRetention": { + "stdRetention": 30, + "purposes": { + "2": 540, + "5": 1460, + "6": 1460, + "10": 14 + }, + "specialPurposes": { + "1": 540 + } + }, + "urls": [ + { + "langId": "cs", + "privacy": "https://www.seznam.cz/ochranaudaju", + "legIntClaim": "https://o.seznam.cz/personalizace-obsahu-a-reklamy/" + } + ], + "dataDeclaration": [ + 1, + 2, + 3, + 4, + 5, + 6, + 7, + 8, + 9, + 10, + 11 + ], + "deviceStorageDisclosureUrl": "https://h.seznam.cz/js/deviceStorage.json" + }, + "624": { + "id": 624, + "name": "Norstat AS", + "purposes": [ + 1, + 9 + ], + "legIntPurposes": [], + "flexiblePurposes": [], + "specialPurposes": [], + "features": [ + 1, + 2, + 3 + ], + "specialFeatures": [], + "cookieMaxAgeSeconds": 63113904, + "usesCookies": true, + "cookieRefresh": true, + "usesNonCookieAccess": true, + "dataRetention": { + "purposes": { + "9": 1080 + }, + "specialPurposes": {} + }, + "urls": [ + { + "langId": "en", + "privacy": "https://www.norstatpanel.com/en/data-protection" + }, + { + "langId": "no", + "privacy": "https://www.norstatpanel.com/nb/personvern" + }, + { + "langId": "de", + "privacy": "https://www.norstatpanel.com/de/datenschutz" + }, + { + "langId": "sv", + "privacy": "https://www.norstatpanel.com/sv/dataskydd" + }, + { + "langId": "da", + "privacy": "https://www.norstatpanel.com/da/data-beskyttelse" + }, + { + "langId": "fi", + "privacy": "https://www.norstatpanel.com/fi/tietosuoja" + }, + { + "langId": "pl", + "privacy": "https://www.norstatpanel.com/pl/ochrona-danych" + }, + { + "langId": "it", + "privacy": "https://www.norstatpanel.com/it/protezione-dati" + }, + { + "langId": "fr", + "privacy": "https://www.norstatpanel.com/fr/protection-des-donnees" + }, + { + "langId": "et", + "privacy": "https://www.norstatpanel.com/et/andmekaitse" + }, + { + "langId": "nl", + "privacy": "https://www.norstatpanel.com/nl/data-protection" + }, + { + "langId": "lv", + "privacy": "https://www.norstatpanel.com/lv/datu-aizsardziba" + }, + { + "langId": "lt", + "privacy": "https://www.norstatpanel.com/lt/privatumo-politika" + }, + { + "langId": "es", + "privacy": "https://www.norstatpanel.com/es/proteccion-de-datos" + }, + { + "langId": "ru", + "privacy": "https://www.norstatpanel.com/ru/zaschita-dannykh" + } + ], + "dataDeclaration": [ + 7 + ], + "deviceStorageDisclosureUrl": "https://aws.norstat.no/iab/tcf.json" + }, + "626": { + "id": 626, + "name": "Hivestack Inc.", + "purposes": [ + 1, + 3, + 4, + 7, + 9, + 10 + ], + "legIntPurposes": [], + "flexiblePurposes": [], + "specialPurposes": [], + "features": [], + "specialFeatures": [ + 1 + ], + "cookieMaxAgeSeconds": null, + "usesCookies": false, + "cookieRefresh": false, + "usesNonCookieAccess": true, + "dataRetention": { + "stdRetention": 394, + "purposes": {}, + "specialPurposes": {} + }, + "urls": [ + { + "langId": "en", + "privacy": "https://hivestack.com/privacy-policy" + } + ], + "dataDeclaration": [ + 3, + 9 + ], + "deviceStorageDisclosureUrl": "https://tcf.hivestack.com/TCF_File.json" + }, + "628": { + "id": 628, + "name": ": Tappx", + "purposes": [ + 1, + 2, + 4, + 7, + 10 + ], + "legIntPurposes": [], + "flexiblePurposes": [], + "specialPurposes": [ + 1, + 2 + ], + "features": [ + 1, + 2 + ], + "specialFeatures": [ + 1, + 2 + ], + "cookieMaxAgeSeconds": 10800, + "usesCookies": true, + "cookieRefresh": false, + "usesNonCookieAccess": false, + "dataRetention": { + "stdRetention": 365, + "purposes": {}, + "specialPurposes": {} + }, + "urls": [ + { + "langId": "en", + "privacy": "https://www.tappx.com/en/privacy-policy/", + "legIntClaim": "https://www.tappx.com/en/privacy-policy/" + } + ], + "dataDeclaration": [ + 1, + 2, + 3, + 11 + ], + "deviceStorageDisclosureUrl": "https://tappx.com/devicestorage.json" + }, + "630": { + "id": 630, + "name": "Contact Impact GmbH/Axel Springer Teaser Ad GmbH", + "purposes": [ + 1, + 3, + 4 + ], + "legIntPurposes": [ + 2, + 7, + 10 + ], + "flexiblePurposes": [ + 2, + 7, + 10 + ], + "specialPurposes": [ + 1, + 2 + ], + "features": [ + 3 + ], + "specialFeatures": [], + "cookieMaxAgeSeconds": 43200000, + "usesCookies": true, + "cookieRefresh": true, + "usesNonCookieAccess": false, + "dataRetention": { + "stdRetention": 365, + "purposes": {}, + "specialPurposes": {} + }, + "urls": [ + { + "langId": "de", + "privacy": "https://contactimpact.de/privacy", + "legIntClaim": "https://contactimpact.de/privacy.html#section-3" + } + ], + "dataDeclaration": [ + 1, + 2, + 8, + 10, + 11 + ], + "deviceStorageDisclosureUrl": "https://cdn.c-i.as/d/gdpr/deviceStorage.json" + }, + "631": { + "id": 631, + "name": "Relay42 Netherlands B.V.", + "purposes": [ + 1, + 2, + 3, + 4, + 5, + 6, + 7, + 8, + 9, + 10 + ], + "legIntPurposes": [], + "flexiblePurposes": [], + "specialPurposes": [], + "features": [ + 1, + 2 + ], + "specialFeatures": [ + 2 + ], + "cookieMaxAgeSeconds": 63072000, + "usesCookies": true, + "cookieRefresh": false, + "usesNonCookieAccess": false, + "dataRetention": { + "stdRetention": 1096, + "purposes": {}, + "specialPurposes": {} + }, + "urls": [ + { + "langId": "en", + "privacy": "https://relay42.com/privacy" + } + ], + "dataDeclaration": [ + 1, + 2, + 3, + 4, + 6, + 7, + 10, + 11 + ], + "deviceStorageDisclosureUrl": "https://relay42.com/relay42-iab-disclosures.json" + }, + "646": { + "id": 646, + "name": "Notify", + "purposes": [ + 9 + ], + "legIntPurposes": [], + "flexiblePurposes": [], + "specialPurposes": [], + "features": [ + 1 + ], + "specialFeatures": [], + "cookieMaxAgeSeconds": 31536000, + "usesCookies": true, + "cookieRefresh": false, + "usesNonCookieAccess": false, + "dataRetention": { + "purposes": { + "9": 390 + }, + "specialPurposes": {} + }, + "urls": [ + { + "langId": "fr", + "privacy": "https://fr.notify-group.com/en/mentions-legales/" + } + ], + "dataDeclaration": [ + 7 + ], + "deviceStorageDisclosureUrl": "https://notify-group.com/cookies/tcf.json" + }, + "647": { + "id": 647, + "name": "Axel Springer Teaser Ad GmbH", + "purposes": [ + 1, + 3, + 4 + ], + "legIntPurposes": [ + 2, + 7, + 10 + ], + "flexiblePurposes": [ + 2, + 7, + 10 + ], + "specialPurposes": [ + 1, + 2 + ], + "features": [ + 3 + ], + "specialFeatures": [], + "cookieMaxAgeSeconds": 31536000, + "usesCookies": true, + "cookieRefresh": true, + "usesNonCookieAccess": true, + "dataRetention": { + "stdRetention": 365, + "purposes": {}, + "specialPurposes": {} + }, + "urls": [ + { + "langId": "en", + "privacy": "https://www.adup-tech.com/privacy", + "legIntClaim": "https://www.adup-tech.com/en/privacy-policy/#c4489" + }, + { + "langId": "de", + "privacy": "https://www.adup-tech.com/rechtliches/datenschutz/", + "legIntClaim": "https://www.adup-tech.com/rechtliches/datenschutz/#c4488" + } + ], + "dataDeclaration": [ + 1, + 2, + 3, + 6, + 8, + 10, + 11 + ], + "deviceStorageDisclosureUrl": "https://s.d.adup-tech.com/gdpr/deviceStorage.json" + }, + "655": { + "id": 655, + "name": "Sportradar AG", + "purposes": [ + 1, + 3, + 4, + 10 + ], + "legIntPurposes": [ + 2, + 7, + 9 + ], + "flexiblePurposes": [ + 2, + 7, + 9, + 10 + ], + "specialPurposes": [ + 1, + 2 + ], + "features": [ + 1, + 2, + 3 + ], + "specialFeatures": [ + 1, + 2 + ], + "cookieMaxAgeSeconds": 31536000, + "usesCookies": true, + "cookieRefresh": true, + "usesNonCookieAccess": true, + "dataRetention": { + "stdRetention": 100, + "purposes": { + "4": 1095 + }, + "specialPurposes": {} + }, + "urls": [ + { + "langId": "en", + "privacy": "https://www.sportradar.com/about-us/privacy/", + "legIntClaim": "https://www.sportradar.com/about-us/privacy/" + } + ], + "dataDeclaration": [ + 1, + 2, + 3, + 4, + 5, + 6, + 7, + 8, + 9, + 10, + 11 + ], + "deviceStorageDisclosureUrl": "https://creatives.sportradarserving.com/TCF_Sportradar_device_storage_url/sportradar_device_storage_url.json" + }, + "656": { + "id": 656, + "name": "Content Ignite", + "purposes": [], + "legIntPurposes": [ + 2, + 11 + ], + "flexiblePurposes": [], + "specialPurposes": [ + 1, + 2 + ], + "features": [], + "specialFeatures": [], + "cookieMaxAgeSeconds": null, + "usesCookies": false, + "cookieRefresh": false, + "usesNonCookieAccess": false, + "dataRetention": { + "stdRetention": 0, + "purposes": {}, + "specialPurposes": { + "1": 7 + } + }, + "urls": [ + { + "langId": "en", + "privacy": "https://www.contentignite.com/privacy-policy/", + "legIntClaim": "https://www.contentignite.com/privacy-policy/" + } + ], + "deviceStorageDisclosureUrl": "https://contentignite.com/deviceStorage.json" + }, + "658": { + "id": 658, + "name": "BLIINK SAS", + "purposes": [ + 1, + 2, + 3, + 4, + 7, + 8, + 9, + 10 + ], + "legIntPurposes": [], + "flexiblePurposes": [ + 2, + 7, + 8, + 9, + 10 + ], + "specialPurposes": [ + 2 + ], + "features": [], + "specialFeatures": [ + 1 + ], + "cookieMaxAgeSeconds": 34186669, + "usesCookies": true, + "cookieRefresh": false, + "usesNonCookieAccess": false, + "dataRetention": { + "stdRetention": 395, + "purposes": {}, + "specialPurposes": {} + }, + "urls": [ + { + "langId": "en", + "privacy": "https://bliink.io/privacy-policy", + "legIntClaim": "https://bliink.io/privacy-policy" + } + ], + "dataDeclaration": [ + 1, + 2, + 3, + 4, + 6, + 8 + ], + "deviceStorageDisclosureUrl": "https://bliink.io/disclosures.json" + }, + "659": { + "id": 659, + "name": "Research and Analysis of Media in Sweden AB", + "purposes": [ + 1 + ], + "legIntPurposes": [ + 7, + 8, + 9 + ], + "flexiblePurposes": [], + "specialPurposes": [ + 1 + ], + "features": [ + 2 + ], + "specialFeatures": [ + 2 + ], + "cookieMaxAgeSeconds": 32000000, + "usesCookies": true, + "cookieRefresh": false, + "usesNonCookieAccess": false, + "dataRetention": { + "stdRetention": 0, + "purposes": {}, + "specialPurposes": {} + }, + "urls": [ + { + "langId": "en", + "privacy": "https://www2.rampanel.com/privacy-policy/", + "legIntClaim": "https://www2.rampanel.com/privacy-policy/" + } + ], + "dataDeclaration": [ + 1, + 3 + ], + "deviceStorageDisclosureUrl": "https://www.rampanel.com/tcf/deviceStorage.json" + }, + "662": { + "id": 662, + "name": "SoundCast", + "purposes": [ + 1, + 2, + 7 + ], + "legIntPurposes": [], + "flexiblePurposes": [], + "specialPurposes": [], + "features": [ + 3 + ], + "specialFeatures": [ + 1 + ], + "overflow": { + "httpGetLimit": 128 + }, + "cookieMaxAgeSeconds": 0, + "usesCookies": true, + "cookieRefresh": false, + "usesNonCookieAccess": false, + "dataRetention": { + "stdRetention": 390, + "purposes": {}, + "specialPurposes": {} + }, + "urls": [ + { + "langId": "en", + "privacy": "https://soundcast.fm/en/data-privacy" + } + ], + "dataDeclaration": [ + 1, + 2, + 11 + ], + "deviceStorageDisclosureUrl": "https://soundcast.io/devicestorage.json" + }, + "663": { + "id": 663, + "name": "Mobsuccess", + "purposes": [ + 1, + 2, + 3, + 4, + 7, + 9 + ], + "legIntPurposes": [], + "flexiblePurposes": [ + 2 + ], + "specialPurposes": [ + 1 + ], + "features": [ + 1, + 2, + 3 + ], + "specialFeatures": [ + 1 + ], + "cookieMaxAgeSeconds": 31536000, + "usesCookies": true, + "cookieRefresh": true, + "usesNonCookieAccess": true, + "dataRetention": { + "stdRetention": 150, + "purposes": { + "2": 730 + }, + "specialPurposes": { + "1": 730 + } + }, + "urls": [ + { + "langId": "en", + "privacy": "https://www.mobsuccess.com/en/privacy", + "legIntClaim": "https://www.mobsuccess.com/en/privacy" + }, + { + "langId": "fr", + "privacy": "https://www.mobsuccess.com/fr/privacy", + "legIntClaim": "https://www.mobsuccess.com/fr/privacy" + } + ], + "dataDeclaration": [ + 1, + 2, + 3, + 6, + 7, + 8, + 9, + 10, + 11 + ], + "deviceStorageDisclosureUrl": "https://www.mobsuccess.com/deviceStorage.json" + }, + "667": { + "id": 667, + "name": "Liftoff Mobile, Inc.", + "purposes": [], + "legIntPurposes": [ + 2, + 7, + 10 + ], + "flexiblePurposes": [ + 2, + 7, + 10 + ], + "specialPurposes": [ + 1, + 2 + ], + "features": [ + 3 + ], + "specialFeatures": [ + 2 + ], + "cookieMaxAgeSeconds": null, + "usesCookies": false, + "cookieRefresh": false, + "usesNonCookieAccess": true, + "dataRetention": { + "stdRetention": 90, + "purposes": {}, + "specialPurposes": {} + }, + "urls": [ + { + "langId": "en", + "privacy": "https://liftoff.io/privacy-policy/", + "legIntClaim": "https://liftoff.io/privacy-policy/" + } + ], + "dataDeclaration": [ + 1, + 2, + 3, + 4, + 6, + 8, + 11 + ], + "deviceStorageDisclosureUrl": "https://vungle2-cdn-prod.s3.amazonaws.com/sdks/IAB/IABVendorDisclosure.json" + }, + "671": { + "id": 671, + "name": "MEDIA FORCE COMMUNICATIONS (2007) LTD", + "purposes": [ + 1, + 3, + 4, + 5, + 6, + 7, + 8, + 9 + ], + "legIntPurposes": [ + 2, + 10 + ], + "flexiblePurposes": [], + "specialPurposes": [ + 1, + 2 + ], + "features": [ + 1, + 3 + ], + "specialFeatures": [], + "cookieMaxAgeSeconds": 63072000, + "usesCookies": true, + "cookieRefresh": true, + "usesNonCookieAccess": true, + "dataRetention": { + "stdRetention": 365, + "purposes": {}, + "specialPurposes": {} + }, + "urls": [ + { + "langId": "en", + "privacy": "https://comparisons.org/privacy.php", + "legIntClaim": "https://comparisons.org/privacy.php" + } + ], + "dataDeclaration": [ + 1, + 2, + 3, + 6, + 9 + ], + "deviceStorageDisclosureUrl": "https://comparisons.org/privacy.json" + }, + "674": { + "id": 674, + "name": "Duration Media, LLC.", + "purposes": [ + 7 + ], + "legIntPurposes": [], + "flexiblePurposes": [], + "specialPurposes": [ + 2 + ], + "features": [], + "specialFeatures": [], + "overflow": { + "httpGetLimit": 128 + }, + "cookieMaxAgeSeconds": null, + "usesCookies": false, + "cookieRefresh": false, + "usesNonCookieAccess": false, + "dataRetention": { + "stdRetention": 365, + "purposes": {}, + "specialPurposes": {} + }, + "urls": [ + { + "langId": "en", + "privacy": "https://www.durationmedia.net/privacy-policy", + "legIntClaim": "https://www.durationmedia.net/privacy-policy" + } + ], + "dataDeclaration": [ + 1, + 2 + ], + "deviceStorageDisclosureUrl": "https://duration-media.s3.amazonaws.com/dm-vendor-device-storage-and-operational-disclosures.json" + }, + "676": { + "id": 676, + "name": "Businessclick Sp. z o.o.", + "purposes": [ + 1, + 2, + 3, + 4, + 5, + 6, + 7, + 8, + 9 + ], + "legIntPurposes": [ + 10 + ], + "flexiblePurposes": [ + 7, + 8, + 9 + ], + "specialPurposes": [ + 1, + 2 + ], + "features": [ + 1, + 2, + 3 + ], + "specialFeatures": [ + 2 + ], + "cookieMaxAgeSeconds": 94608000, + "usesCookies": true, + "cookieRefresh": true, + "usesNonCookieAccess": true, + "dataRetention": { + "stdRetention": 365, + "purposes": { + "7": 1095, + "8": 1095, + "10": 1095 + }, + "specialPurposes": { + "1": 1095, + "2": 1095 + } + }, + "urls": [ + { + "langId": "pl", + "privacy": "https://www.businessclick.com/documents/Polityka_prywatnosci.pdf", + "legIntClaim": "https://www.businessclick.com/documents/Polityka_prywatnosci.pdf#page=7" + }, + { + "langId": "en", + "privacy": "https://www.businessclick.com/documents/Privacy_Policy.pdf", + "legIntClaim": "https://www.businessclick.com/documents/Privacy_Policy.pdf#page=7" + } + ], + "dataDeclaration": [ + 1, + 2, + 3, + 4, + 5, + 6, + 7, + 8, + 10, + 11 + ], + "deviceStorageDisclosureUrl": "https://ssp.wp.pl/deviceStorage.json" + }, + "677": { + "id": 677, + "name": "Intercept Interactive Inc. dba Undertone", + "purposes": [ + 1, + 2, + 3, + 4, + 5, + 6 + ], + "legIntPurposes": [ + 7, + 8, + 10 + ], + "flexiblePurposes": [ + 2 + ], + "specialPurposes": [ + 1, + 2 + ], + "features": [ + 3 + ], + "specialFeatures": [], + "cookieMaxAgeSeconds": 31556926, + "usesCookies": true, + "cookieRefresh": true, + "usesNonCookieAccess": false, + "dataRetention": { + "stdRetention": 30, + "purposes": {}, + "specialPurposes": {} + }, + "urls": [ + { + "langId": "en", + "privacy": "https://www.undertone.com/privacy-center/", + "legIntClaim": "https://www.undertone.com/privacy-center/" + } + ], + "dataDeclaration": [ + 1, + 2, + 3, + 4, + 6, + 8 + ], + "deviceStorageDisclosureUrl": "https://cdn.undertone.com/js/deviceStorage.json" + }, + "681": { + "id": 681, + "name": "MyTraffic", + "purposes": [ + 1, + 9 + ], + "legIntPurposes": [], + "flexiblePurposes": [], + "specialPurposes": [], + "features": [], + "specialFeatures": [ + 1 + ], + "overflow": { + "httpGetLimit": 128 + }, + "cookieMaxAgeSeconds": null, + "usesCookies": false, + "cookieRefresh": false, + "usesNonCookieAccess": true, + "dataRetention": { + "purposes": { + "9": 105 + }, + "specialPurposes": {} + }, + "urls": [ + { + "langId": "en", + "privacy": "https://www.mytraffic.io/en/privacy" + }, + { + "langId": "fr", + "privacy": "https://www.mytraffic.io/fr/privacy" + } + ], + "dataDeclaration": [ + 2, + 3, + 9, + 11 + ], + "deviceStorageDisclosureUrl": "https://app.mytraffic.io/static/json/iab/disclosures.json" + }, + "702": { + "id": 702, + "name": "Kwanko", + "purposes": [ + 1, + 2, + 7, + 8 + ], + "legIntPurposes": [], + "flexiblePurposes": [ + 2, + 7, + 8 + ], + "specialPurposes": [ + 1, + 2 + ], + "features": [ + 3 + ], + "specialFeatures": [], + "cookieMaxAgeSeconds": 5184000, + "usesCookies": true, + "cookieRefresh": true, + "usesNonCookieAccess": true, + "dataRetention": { + "stdRetention": 180, + "purposes": { + "2": 30 + }, + "specialPurposes": {} + }, + "urls": [ + { + "langId": "fr", + "privacy": "https://www.kwanko.com/fr/rgpd/politique-gestion-donnees/", + "legIntClaim": "https://www.kwanko.com/fr/rgpd/politique-gestion-donnees/" + }, + { + "langId": "en", + "privacy": "https://www.kwanko.com/gdpr/privacy-policy/", + "legIntClaim": "https://www.kwanko.com/gdpr/privacy-policy/" + } + ], + "dataDeclaration": [ + 1, + 2, + 3, + 6, + 8, + 11 + ], + "deviceStorageDisclosureUrl": "https://cdn.kwanko.com/.well-known/deviceStorage.json" + }, + "703": { + "id": 703, + "name": "MindTake Research GmbH", + "purposes": [ + 1, + 2, + 3, + 4, + 5, + 6, + 7, + 8, + 9, + 10 + ], + "legIntPurposes": [], + "flexiblePurposes": [ + 10 + ], + "specialPurposes": [ + 1 + ], + "features": [ + 2, + 3 + ], + "specialFeatures": [ + 2 + ], + "cookieMaxAgeSeconds": 15552000, + "usesCookies": true, + "cookieRefresh": false, + "usesNonCookieAccess": true, + "dataRetention": { + "stdRetention": 180, + "purposes": {}, + "specialPurposes": {} + }, + "urls": [ + { + "langId": "en", + "privacy": "https://www.mindtake.com/en/reppublika-privacy-policy", + "legIntClaim": "https://www.mindtake.com/en/reppublika-privacy-policy" + }, + { + "langId": "de", + "privacy": "https://www.mindtake.com/de/reppublika-datenschutzordnung", + "legIntClaim": "https://www.mindtake.com/de/reppublika-datenschutzordnung" + } + ], + "dataDeclaration": [ + 1, + 2, + 3, + 4, + 6, + 10 + ], + "deviceStorageDisclosureUrl": "https://pub.mindtake.com/TCF_DeviceStorageDisclosure/703/ " + }, + "707": { + "id": 707, + "name": "Dentsu Italia SpA", + "purposes": [ + 1, + 2, + 3, + 4, + 7, + 9, + 10 + ], + "legIntPurposes": [], + "flexiblePurposes": [], + "specialPurposes": [ + 1 + ], + "features": [ + 1, + 2, + 3 + ], + "specialFeatures": [ + 1, + 2 + ], + "cookieMaxAgeSeconds": 5184000, + "usesCookies": true, + "cookieRefresh": true, + "usesNonCookieAccess": false, + "dataRetention": { + "stdRetention": 365, + "purposes": {}, + "specialPurposes": {} + }, + "urls": [ + { + "langId": "it", + "privacy": "https://www.dentsu.com/it/it/policies/info-cookie", + "legIntClaim": "https://www.dentsu.com/it/it/policies/legittimo-interesse" + } + ], + "dataDeclaration": [ + 1, + 2, + 3, + 6, + 8, + 11 + ], + "deviceStorageDisclosureUrl": "https://cloud.thebignow.it/data/" + }, + "713": { + "id": 713, + "name": "Dataseat Ltd", + "purposes": [ + 1, + 2, + 3, + 4, + 5, + 6, + 7, + 8, + 9 + ], + "legIntPurposes": [], + "flexiblePurposes": [ + 2, + 7, + 8 + ], + "specialPurposes": [], + "features": [ + 3 + ], + "specialFeatures": [], + "cookieMaxAgeSeconds": 86400, + "usesCookies": true, + "cookieRefresh": false, + "usesNonCookieAccess": true, + "dataRetention": { + "stdRetention": 365, + "purposes": {}, + "specialPurposes": {} + }, + "urls": [ + { + "langId": "en", + "privacy": "https://dataseat.com/privacy-policy", + "legIntClaim": "https://dataseat.com/privacy-policy" + } + ], + "dataDeclaration": [ + 1, + 2, + 3 + ], + "deviceStorageDisclosureUrl": "https://assets.dataseat.com/GDPR_TCF.json" + }, + "714": { + "id": 714, + "name": "Upwave Inc.", + "purposes": [ + 1 + ], + "legIntPurposes": [ + 7, + 8, + 9 + ], + "flexiblePurposes": [ + 7, + 8, + 9 + ], + "specialPurposes": [], + "features": [ + 3 + ], + "specialFeatures": [], + "cookieMaxAgeSeconds": 32000000, + "usesCookies": true, + "cookieRefresh": false, + "usesNonCookieAccess": false, + "dataRetention": { + "stdRetention": 400, + "purposes": {}, + "specialPurposes": {} + }, + "urls": [ + { + "langId": "en", + "privacy": "https://www.upwave.com/privacy-policy/", + "legIntClaim": "https://www.upwave.com/privacy-policy/" + } + ], + "dataDeclaration": [ + 1, + 2, + 3 + ], + "deviceStorageDisclosureUrl": "https://www.upwave.com/tcf.json" + }, + "715": { + "id": 715, + "name": "BidBerry SRL", + "purposes": [ + 1, + 2, + 3, + 4, + 5, + 6, + 7, + 8, + 9, + 10 + ], + "legIntPurposes": [], + "flexiblePurposes": [], + "specialPurposes": [ + 1, + 2 + ], + "features": [ + 2, + 3 + ], + "specialFeatures": [], + "cookieMaxAgeSeconds": 31536000, + "usesCookies": true, + "cookieRefresh": false, + "usesNonCookieAccess": false, + "dataRetention": { + "stdRetention": 30, + "purposes": {}, + "specialPurposes": {} + }, + "urls": [ + { + "langId": "en", + "privacy": "https://www.bidberrymedia.com/service-privacy-policy/", + "legIntClaim": "https://www.bidberrymedia.com/service-privacy-policy/" + } + ], + "dataDeclaration": [ + 1, + 2, + 3, + 4, + 5, + 6, + 7, + 8, + 9, + 10, + 11 + ], + "deviceStorageDisclosureUrl": "https://www.bidberrymedia.com/deviceStorage.php" + }, + "717": { + "id": 717, + "name": "Audience Network", + "purposes": [ + 1, + 2, + 3, + 4, + 7, + 9, + 10 + ], + "legIntPurposes": [], + "flexiblePurposes": [], + "specialPurposes": [ + 1 + ], + "features": [ + 1, + 2, + 3 + ], + "specialFeatures": [], + "cookieMaxAgeSeconds": 31536000, + "usesCookies": true, + "cookieRefresh": true, + "usesNonCookieAccess": false, + "dataRetention": { + "stdRetention": 365, + "purposes": {}, + "specialPurposes": {} + }, + "urls": [ + { + "langId": "en", + "privacy": "https://audiencenetwork.pl/en/internet-advertising-privacy-policy", + "legIntClaim": "https://audiencenetwork.pl/en/internet-advertising-privacy-policy" + } + ], + "dataDeclaration": [ + 1, + 2, + 3, + 5, + 6, + 8, + 10, + 11 + ], + "deviceStorageDisclosureUrl": "https://audiencenetwork.pl/deviceStorage.json" + }, + "718": { + "id": 718, + "name": "XChange by SFBX®", + "purposes": [ + 1, + 2, + 3, + 4, + 5, + 6, + 7, + 8, + 9, + 10, + 11 + ], + "legIntPurposes": [], + "flexiblePurposes": [], + "specialPurposes": [], + "features": [ + 1, + 2, + 3 + ], + "specialFeatures": [], + "overflow": { + "httpGetLimit": 32 + }, + "cookieMaxAgeSeconds": 12, + "usesCookies": true, + "cookieRefresh": false, + "usesNonCookieAccess": true, + "dataRetention": { + "stdRetention": 30, + "purposes": { + "2": 90 + }, + "specialPurposes": {} + }, + "urls": [ + { + "langId": "fr", + "privacy": "https://sfbx.io/politique-de-confidentialite/" + }, + { + "langId": "en", + "privacy": "https://sfbx.io/en/politique-de-confidentialite/" + } + ], + "dataDeclaration": [ + 1, + 2, + 3, + 5, + 6, + 7, + 11 + ], + "deviceStorageDisclosureUrl": "https://cdn.appconsent.io/iab/xchange-by-sfbx.json" + }, + "724": { + "id": 724, + "name": "Between Exchange", + "purposes": [ + 1 + ], + "legIntPurposes": [ + 7 + ], + "flexiblePurposes": [], + "specialPurposes": [ + 1, + 2 + ], + "features": [], + "specialFeatures": [], + "cookieMaxAgeSeconds": 31536000, + "usesCookies": true, + "cookieRefresh": true, + "usesNonCookieAccess": false, + "dataRetention": { + "stdRetention": 90, + "purposes": {}, + "specialPurposes": {} + }, + "urls": [ + { + "langId": "en", + "privacy": "https://en.betweenx.com/pdata.pdf", + "legIntClaim": "https://en.betweenx.com/pdata.pdf" + } + ], + "dataDeclaration": [ + 1, + 2, + 3, + 6, + 8 + ], + "deviceStorageDisclosureUrl": "https://en.betweenx.com/deviceStorage.json" + }, + "726": { + "id": 726, + "name": "YouGov", + "purposes": [ + 1, + 3, + 5, + 7, + 8, + 9, + 10 + ], + "legIntPurposes": [], + "flexiblePurposes": [ + 9, + 10 + ], + "specialPurposes": [], + "features": [ + 1, + 2, + 3 + ], + "specialFeatures": [], + "cookieMaxAgeSeconds": 31557600, + "usesCookies": true, + "cookieRefresh": false, + "usesNonCookieAccess": true, + "dataRetention": { + "stdRetention": 4320, + "purposes": {}, + "specialPurposes": {} + }, + "urls": [ + { + "langId": "en", + "privacy": "https://account.yougov.com/gb-en/account/privacy-policy", + "legIntClaim": "https://account.yougov.com/gb-en/account/privacy-policy" + }, + { + "langId": "de", + "privacy": "https://account.yougov.com/de-de/account/privacy-policy", + "legIntClaim": "https://account.yougov.com/de-de/account/privacy-policy" + }, + { + "langId": "fr", + "privacy": "https://account.yougov.com/fr-fr/account/privacy-policy", + "legIntClaim": "https://account.yougov.com/fr-fr/account/privacy-policy" + }, + { + "langId": "es", + "privacy": "https://account.yougov.com/es-es/account/privacy-policy", + "legIntClaim": "https://account.yougov.com/es-es/account/privacy-policy" + }, + { + "langId": "it", + "privacy": "https://account.yougov.com/it-it/account/privacy-policy", + "legIntClaim": "https://account.yougov.com/it-it/account/privacy-policy" + }, + { + "langId": "da", + "privacy": "https://account.yougov.com/dk-da/account/privacy-policy", + "legIntClaim": "https://account.yougov.com/dk-da/account/privacy-policy" + }, + { + "langId": "cs", + "privacy": "https://account.yougov.com/cz-cs/account/privacy-policy", + "legIntClaim": "https://account.yougov.com/cz-cs/account/privacy-policy" + }, + { + "langId": "nl", + "privacy": "https://account.yougov.com/nl-nl/account/privacy-policy", + "legIntClaim": "https://account.yougov.com/nl-nl/account/privacy-policy" + }, + { + "langId": "no", + "privacy": "https://account.yougov.com/no-nb/account/privacy-policy", + "legIntClaim": "https://account.yougov.com/no-nb/account/privacy-policy" + }, + { + "langId": "el", + "privacy": "https://account.yougov.com/gr-el/account/privacy-policy", + "legIntClaim": "https://account.yougov.com/gr-el/account/privacy-policy" + }, + { + "langId": "tr", + "privacy": "https://account.yougov.com/tr-tr/account/privacy-policy", + "legIntClaim": "https://account.yougov.com/tr-tr/account/privacy-policy" + }, + { + "langId": "ar", + "privacy": "https://account.yougov.com/ae-ar/account/privacy-policy", + "legIntClaim": "https://account.yougov.com/ae-ar/account/privacy-policy" + }, + { + "langId": "fi", + "privacy": "https://account.yougov.com/ae-ar/account/privacy-policy", + "legIntClaim": "https://account.yougov.com/ae-ar/account/privacy-policy" + }, + { + "langId": "sv", + "privacy": "https://account.yougov.com/se-sv/account/privacy-policy", + "legIntClaim": "https://account.yougov.com/se-sv/account/privacy-policy" + }, + { + "langId": "hr", + "privacy": "https://account.yougov.com/hr-hr/account/privacy-policy", + "legIntClaim": "https://account.yougov.com/hr-hr/account/privacy-policy" + }, + { + "langId": "hu", + "privacy": "https://account.yougov.com/hu-hu/account/privacy-policy", + "legIntClaim": "https://account.yougov.com/hu-hu/account/privacy-policy" + }, + { + "langId": "pl", + "privacy": "https://account.yougov.com/pl-pl/account/privacy-policy", + "legIntClaim": "https://account.yougov.com/pl-pl/account/privacy-policy" + }, + { + "langId": "pt", + "privacy": "https://account.yougov.com/pt-pt/account/privacy-policy", + "legIntClaim": "https://account.yougov.com/pt-pt/account/privacy-policy" + }, + { + "langId": "ro", + "privacy": "https://account.yougov.com/ro-ro/account/privacy-policy", + "legIntClaim": "https://account.yougov.com/ro-ro/account/privacy-policy" + }, + { + "langId": "sk", + "privacy": "https://account.yougov.com/sk-sk/account/privacy-policy", + "legIntClaim": "https://account.yougov.com/sk-sk/account/privacy-policy" + } + ], + "dataDeclaration": [ + 1, + 3, + 5, + 7, + 11 + ], + "deviceStorageDisclosureUrl": "https://d4a766y0k7kjw.cloudfront.net/global-panel/static/tcf/TCF-1.json" + }, + "727": { + "id": 727, + "name": "Pinpoll GmbH", + "purposes": [ + 1, + 2, + 3, + 4, + 5, + 6, + 7, + 8, + 9, + 10 + ], + "legIntPurposes": [], + "flexiblePurposes": [], + "specialPurposes": [ + 1, + 2 + ], + "features": [ + 1 + ], + "specialFeatures": [], + "cookieMaxAgeSeconds": 2592000, + "usesCookies": true, + "cookieRefresh": true, + "usesNonCookieAccess": true, + "dataRetention": { + "stdRetention": 30, + "purposes": {}, + "specialPurposes": {} + }, + "urls": [ + { + "langId": "en", + "privacy": "https://www.pinpoll.com/pdf/data-protection-declaration.pdf", + "legIntClaim": "https://www.pinpoll.com/pdf/data-protection-declaration.pdf" + } + ], + "dataDeclaration": [ + 1, + 7 + ], + "deviceStorageDisclosureUrl": "https://www.pinpoll.com/deviceStorage.json" + }, + "728": { + "id": 728, + "name": "Appier PTE Ltd", + "purposes": [ + 1, + 3, + 4, + 5, + 6, + 11 + ], + "legIntPurposes": [ + 2, + 7, + 9, + 10 + ], + "flexiblePurposes": [ + 2, + 7, + 9, + 10 + ], + "specialPurposes": [ + 1, + 2 + ], + "features": [ + 1, + 2, + 3 + ], + "specialFeatures": [ + 1 + ], + "cookieMaxAgeSeconds": 31536000, + "usesCookies": true, + "cookieRefresh": true, + "usesNonCookieAccess": true, + "dataRetention": { + "stdRetention": 397, + "purposes": {}, + "specialPurposes": {} + }, + "urls": [ + { + "langId": "en", + "privacy": "https://www.appier.com/en/about/privacy-policy/", + "legIntClaim": "https://www.appier.com/en/about/privacy-policy/" + }, + { + "langId": "ja", + "privacy": "https://www.appier.com/ja-jp/about/privacy-policy", + "legIntClaim": "https://www.appier.com/ja-jp/about/privacy-policy" + }, + { + "langId": "zh", + "privacy": "https://www.appier.com/zh-tw/about/privacy-policy", + "legIntClaim": "https://www.appier.com/zh-tw/about/privacy-policy" + } + ], + "dataDeclaration": [ + 1, + 2, + 3, + 5, + 6, + 7, + 8, + 9, + 10, + 11 + ], + "deviceStorageDisclosureUrl": "https://tcf.appier.com/deviceStorage.json" + }, + "730": { + "id": 730, + "name": "INFOnline GmbH", + "purposes": [ + 1, + 8 + ], + "legIntPurposes": [], + "flexiblePurposes": [], + "specialPurposes": [], + "features": [ + 3 + ], + "specialFeatures": [ + 2 + ], + "cookieMaxAgeSeconds": 31536000, + "usesCookies": true, + "cookieRefresh": true, + "usesNonCookieAccess": true, + "dataRetention": { + "purposes": { + "8": 180 + }, + "specialPurposes": {} + }, + "urls": [ + { + "langId": "de", + "privacy": "https://www.infonline.de/datenschutz/" + }, + { + "langId": "en", + "privacy": "https://www.infonline.de/en/datenschutzerklaerung/" + } + ], + "dataDeclaration": [ + 1, + 2, + 3, + 4, + 6 + ], + "deviceStorageDisclosureUrl": "https://www.infonline.de/deviceStorage.json" + }, + "732": { + "id": 732, + "name": "Performax.cz, s.r.o.", + "purposes": [ + 1, + 3, + 4, + 5, + 6, + 8 + ], + "legIntPurposes": [ + 2, + 7, + 9, + 10 + ], + "flexiblePurposes": [], + "specialPurposes": [ + 1 + ], + "features": [], + "specialFeatures": [], + "cookieMaxAgeSeconds": 34164000, + "usesCookies": true, + "cookieRefresh": false, + "usesNonCookieAccess": true, + "dataRetention": { + "stdRetention": 90, + "purposes": {}, + "specialPurposes": {} + }, + "urls": [ + { + "langId": "cs", + "privacy": "https://www.performax.cz/cs/privacy-policy/", + "legIntClaim": "https://www.performax.cz/cs/privacy-policy/" + } + ], + "dataDeclaration": [ + 1, + 2, + 3 + ], + "deviceStorageDisclosureUrl": "https://www.performax.cz/sellers.json" + }, + "742": { + "id": 742, + "name": "Audiencerate LTD", + "purposes": [ + 1, + 3, + 5 + ], + "legIntPurposes": [], + "flexiblePurposes": [], + "specialPurposes": [], + "features": [ + 1, + 2, + 3 + ], + "specialFeatures": [], + "overflow": { + "httpGetLimit": 32 + }, + "cookieMaxAgeSeconds": 1296000, + "usesCookies": true, + "cookieRefresh": false, + "usesNonCookieAccess": false, + "dataRetention": { + "stdRetention": 30, + "purposes": {}, + "specialPurposes": {} + }, + "urls": [ + { + "langId": "en", + "privacy": "https://www.audiencerate.com/full-data-privacy-compliance" + } + ], + "dataDeclaration": [ + 1, + 2, + 3, + 10, + 11 + ], + "deviceStorageDisclosureUrl": "https://a.audrte.com/tcfDeviceDisclosures.json" + }, + "744": { + "id": 744, + "name": "Vidazoo Ltd", + "purposes": [ + 1, + 2, + 3, + 4 + ], + "legIntPurposes": [ + 7, + 10 + ], + "flexiblePurposes": [ + 2 + ], + "specialPurposes": [ + 1, + 2 + ], + "features": [ + 3 + ], + "specialFeatures": [], + "overflow": { + "httpGetLimit": 128 + }, + "cookieMaxAgeSeconds": 2600000, + "usesCookies": true, + "cookieRefresh": false, + "usesNonCookieAccess": false, + "dataRetention": { + "stdRetention": 30, + "purposes": {}, + "specialPurposes": {} + }, + "urls": [ + { + "langId": "en", + "privacy": "https://vidazoo.gitbook.io/vidazoo-legal/privacy-policy", + "legIntClaim": "https://vidazoo.gitbook.io/vidazoo-legal/privacy-policy" + } + ], + "dataDeclaration": [ + 1, + 2, + 3, + 4, + 6, + 8, + 11 + ], + "deviceStorageDisclosureUrl": "https://vidazoo.com/gdpr-tcf/deviceStorage.json" + }, + "745": { + "id": 745, + "name": "Justtag Sp. z o.o.", + "purposes": [ + 1, + 3, + 4, + 7, + 9 + ], + "legIntPurposes": [], + "flexiblePurposes": [], + "specialPurposes": [ + 1, + 2 + ], + "features": [ + 1, + 2, + 3 + ], + "specialFeatures": [ + 1 + ], + "cookieMaxAgeSeconds": null, + "usesCookies": false, + "cookieRefresh": false, + "usesNonCookieAccess": true, + "dataRetention": { + "stdRetention": 730, + "purposes": {}, + "specialPurposes": {} + }, + "urls": [ + { + "langId": "pl", + "privacy": "https://www.justtag.com/POLITYKA_PRYWATNOSCI.pdf", + "legIntClaim": "https://www.justtag.com/POLITYKA_PRYWATNOSCI.pdf" + } + ], + "dataDeclaration": [ + 1, + 2, + 3, + 5, + 8, + 9, + 10 + ], + "deviceStorageDisclosureUrl": "https://www.justtag.com/.well-known/deviceStorage.json" + }, + "748": { + "id": 748, + "name": "AUDIOMOB LTD", + "purposes": [ + 1, + 2, + 7, + 8, + 9 + ], + "legIntPurposes": [], + "flexiblePurposes": [ + 2, + 7, + 8, + 9 + ], + "specialPurposes": [ + 1, + 2 + ], + "features": [ + 1, + 2 + ], + "specialFeatures": [ + 1 + ], + "cookieMaxAgeSeconds": null, + "usesCookies": false, + "cookieRefresh": false, + "usesNonCookieAccess": true, + "dataRetention": { + "stdRetention": 90, + "purposes": {}, + "specialPurposes": {} + }, + "urls": [ + { + "langId": "en", + "privacy": "https://www.audiomob.com/privacy", + "legIntClaim": "https://www.audiomob.com/privacy" + } + ], + "dataDeclaration": [ + 1, + 2, + 3, + 6, + 8, + 9, + 10, + 11 + ], + "deviceStorageDisclosureUrl": "https://www.audiomob.com/deviceStorage.json" + }, + "749": { + "id": 749, + "name": "Good-Loop Ltd", + "purposes": [ + 1 + ], + "legIntPurposes": [ + 7, + 10 + ], + "flexiblePurposes": [ + 7, + 10 + ], + "specialPurposes": [ + 1, + 2 + ], + "features": [], + "specialFeatures": [], + "cookieMaxAgeSeconds": 2678400, + "usesCookies": true, + "cookieRefresh": false, + "usesNonCookieAccess": false, + "dataRetention": { + "stdRetention": 31, + "purposes": {}, + "specialPurposes": {} + }, + "urls": [ + { + "langId": "en", + "privacy": "https://doc.good-loop.com/policy/privacy-policy.html", + "legIntClaim": "https://localdoc.good-loop.com/policy/privacy-policy.html#2a-legitimate-interests" + } + ], + "dataDeclaration": [ + 1, + 2 + ], + "deviceStorageDisclosureUrl": "https://portal.good-loop.com/gvl.json" + }, + "751": { + "id": 751, + "name": "Kiosked Ltd", + "purposes": [], + "legIntPurposes": [ + 2, + 7 + ], + "flexiblePurposes": [ + 2, + 7 + ], + "specialPurposes": [ + 1, + 2 + ], + "features": [], + "specialFeatures": [], + "cookieMaxAgeSeconds": null, + "usesCookies": false, + "cookieRefresh": false, + "usesNonCookieAccess": false, + "dataRetention": { + "stdRetention": 0, + "purposes": {}, + "specialPurposes": {} + }, + "urls": [ + { + "langId": "en", + "privacy": "https://kiosked.com/privacy-policy/", + "legIntClaim": "https://www.kiosked.com/data-processing-policy" + } + ], + "dataDeclaration": [ + 1, + 2, + 11 + ], + "deviceStorageDisclosureUrl": "https://resources.kiosked.com/tcf.json" + }, + "755": { + "id": 755, + "name": "Google Advertising Products", + "purposes": [ + 1, + 3, + 4 + ], + "legIntPurposes": [ + 2, + 7, + 9, + 10 + ], + "flexiblePurposes": [ + 2, + 7, + 9, + 10 + ], + "specialPurposes": [ + 1, + 2 + ], + "features": [ + 1, + 2 + ], + "specialFeatures": [], + "cookieMaxAgeSeconds": 34190000, + "usesCookies": true, + "cookieRefresh": false, + "usesNonCookieAccess": true, + "dataRetention": { + "stdRetention": 548, + "purposes": { + "3": 180, + "4": 180 + }, + "specialPurposes": { + "1": 1096 + } + }, + "urls": [ + { + "langId": "en", + "privacy": "https://business.safety.google/privacy/", + "legIntClaim": "https://policies.google.com/privacy#europeanrequirements" + } + ], + "dataDeclaration": [ + 1, + 2, + 3, + 5, + 6, + 7, + 8, + 10, + 11 + ], + "deviceStorageDisclosureUrl": "https://www.gstatic.com/iabtcf/deviceStorageDisclosure.json" + }, + "756": { + "id": 756, + "name": "Fandom, Inc.", + "purposes": [ + 1, + 2, + 3, + 4, + 5, + 6, + 7, + 8, + 9, + 10 + ], + "legIntPurposes": [], + "flexiblePurposes": [ + 2, + 7, + 8, + 9, + 10 + ], + "specialPurposes": [ + 1, + 2 + ], + "features": [ + 3 + ], + "specialFeatures": [], + "cookieMaxAgeSeconds": 99999999, + "usesCookies": true, + "cookieRefresh": true, + "usesNonCookieAccess": true, + "dataRetention": { + "stdRetention": 365, + "purposes": {}, + "specialPurposes": {} + }, + "urls": [ + { + "langId": "en", + "privacy": "https://www.fandom.com/privacy-policy", + "legIntClaim": "https://www.fandom.com/privacy-policy" + } + ], + "dataDeclaration": [ + 1, + 2, + 3, + 6, + 7, + 8, + 10, + 11 + ], + "deviceStorageDisclosureUrl": "https://script.wikia.nocookie.net/fandom-ae-assets/tcf/v2/deviceStorage.json" + }, + "758": { + "id": 758, + "name": "GfK SE", + "purposes": [ + 1, + 7, + 8, + 9 + ], + "legIntPurposes": [], + "flexiblePurposes": [], + "specialPurposes": [], + "features": [ + 2 + ], + "specialFeatures": [], + "cookieMaxAgeSeconds": 63072000, + "usesCookies": true, + "cookieRefresh": false, + "usesNonCookieAccess": true, + "dataRetention": { + "stdRetention": 720, + "purposes": {}, + "specialPurposes": {} + }, + "urls": [ + { + "langId": "en", + "privacy": "https://help.sensic.net/privacypolicy_en.html" + } + ], + "dataDeclaration": [ + 1, + 2, + 3, + 5, + 6, + 7, + 8, + 10, + 11 + ], + "deviceStorageDisclosureUrl": "https://sensic.net/deviceStorage.json" + }, + "759": { + "id": 759, + "name": "RevJet", + "purposes": [ + 1, + 2, + 3, + 4, + 5, + 6, + 7, + 8, + 9, + 10 + ], + "legIntPurposes": [], + "flexiblePurposes": [], + "specialPurposes": [ + 1, + 2 + ], + "features": [ + 1, + 3 + ], + "specialFeatures": [], + "overflow": { + "httpGetLimit": 128 + }, + "cookieMaxAgeSeconds": 63072000, + "usesCookies": true, + "cookieRefresh": true, + "usesNonCookieAccess": false, + "dataRetention": { + "stdRetention": 90, + "purposes": {}, + "specialPurposes": {} + }, + "urls": [ + { + "langId": "en", + "privacy": "https://www.innervate.com/privacy", + "legIntClaim": "https://www.innervate.com/privacy" + } + ], + "dataDeclaration": [ + 1, + 3, + 8, + 10, + 11 + ], + "deviceStorageDisclosureUrl": "https://tcf.revjet.com/TCFV2-disclosures.json" + }, + "768": { + "id": 768, + "name": "Global Media Group Services Limited", + "purposes": [ + 1, + 2, + 3, + 4, + 5, + 6, + 7, + 8, + 9, + 10, + 11 + ], + "legIntPurposes": [], + "flexiblePurposes": [], + "specialPurposes": [ + 1, + 2 + ], + "features": [ + 1, + 2, + 3 + ], + "specialFeatures": [ + 1, + 2 + ], + "cookieMaxAgeSeconds": 46657000, + "usesCookies": true, + "cookieRefresh": false, + "usesNonCookieAccess": true, + "dataRetention": { + "stdRetention": 37, + "purposes": { + "5": 3285, + "6": 3285, + "11": 3285 + }, + "specialPurposes": {} + }, + "urls": [ + { + "langId": "en", + "privacy": "https://global.com/legal/privacy-policy/", + "legIntClaim": "https://global.com/legal/privacy-policy/" + }, + { + "langId": "nl", + "privacy": "https://global.com/nl/privacy-policy/", + "legIntClaim": "https://global.com/nl/privacy-policy/" + }, + { + "langId": "es", + "privacy": "https://global.com/es/legal/politica-de-privacidad/", + "legIntClaim": "https://global.com/es/legal/politica-de-privacidad/" + } + ], + "dataDeclaration": [ + 1, + 2, + 3, + 4, + 5, + 6, + 7, + 8, + 9, + 10 + ], + "deviceStorageDisclosureUrl": "https://thisisdax.com/tcfdeviceStorage.json" + }, + "769": { + "id": 769, + "name": "MEDIAMETRIE", + "purposes": [ + 1, + 8 + ], + "legIntPurposes": [], + "flexiblePurposes": [], + "specialPurposes": [], + "features": [ + 1, + 3 + ], + "specialFeatures": [], + "cookieMaxAgeSeconds": null, + "usesCookies": false, + "cookieRefresh": false, + "usesNonCookieAccess": true, + "dataRetention": { + "purposes": { + "8": 1095 + }, + "specialPurposes": {} + }, + "urls": [ + { + "langId": "fr", + "privacy": "https://www.mediametrie.fr/fr/gestion-des-cookies" + }, + { + "langId": "en", + "privacy": "https://www.mediametrie.fr/en/management-cookies" + } + ], + "dataDeclaration": [ + 1, + 2, + 3, + 4, + 6, + 11 + ], + "deviceStorageDisclosureUrl": "https://tcf.mediametrie.com/Mediametrie_deviceStorageDisclosure.json" + }, + "770": { + "id": 770, + "name": "MARKETPERF CORP", + "purposes": [ + 1, + 3, + 4, + 5, + 6 + ], + "legIntPurposes": [ + 2, + 7, + 8, + 9, + 10 + ], + "flexiblePurposes": [], + "specialPurposes": [ + 1, + 2 + ], + "features": [ + 3 + ], + "specialFeatures": [], + "cookieMaxAgeSeconds": 31536000, + "usesCookies": true, + "cookieRefresh": true, + "usesNonCookieAccess": true, + "dataRetention": { + "stdRetention": 4320, + "purposes": {}, + "specialPurposes": {} + }, + "urls": [ + { + "langId": "en", + "privacy": "https://www.marketperf.com/assets/images/app/marketperf/pdf/privacy-policy.pdf", + "legIntClaim": "https://www.marketperf.com/assets/images/app/marketperf/pdf/privacy-policy.pdf" + } + ], + "dataDeclaration": [ + 1, + 2, + 4, + 5, + 6, + 8, + 10, + 11 + ], + "deviceStorageDisclosureUrl": "https://s.marketperf.com/tcf.json" + }, + "771": { + "id": 771, + "name": "bam! interactive marketing GmbH ", + "purposes": [ + 1, + 3, + 7, + 10 + ], + "legIntPurposes": [], + "flexiblePurposes": [], + "specialPurposes": [ + 1, + 2 + ], + "features": [], + "specialFeatures": [ + 1 + ], + "overflow": { + "httpGetLimit": 128 + }, + "cookieMaxAgeSeconds": 86400, + "usesCookies": true, + "cookieRefresh": false, + "usesNonCookieAccess": false, + "dataRetention": { + "stdRetention": 7, + "purposes": {}, + "specialPurposes": {} + }, + "urls": [ + { + "langId": "de", + "privacy": "https://bam-interactive.de/datenschutz/", + "legIntClaim": "https://bam-interactive.de/datenschutz/" + } + ], + "dataDeclaration": [ + 2, + 6, + 8 + ], + "deviceStorageDisclosureUrl": "https://libs.adtron.io/iab_tcf.json" + }, + "774": { + "id": 774, + "name": "Wagawin GmbH", + "purposes": [], + "legIntPurposes": [ + 2, + 7 + ], + "flexiblePurposes": [ + 2, + 7 + ], + "specialPurposes": [ + 1, + 2 + ], + "features": [], + "specialFeatures": [], + "cookieMaxAgeSeconds": null, + "usesCookies": false, + "cookieRefresh": false, + "usesNonCookieAccess": false, + "dataRetention": { + "stdRetention": 7, + "purposes": {}, + "specialPurposes": {} + }, + "urls": [ + { + "langId": "en", + "privacy": "https://www.wagawin.com/privacy-en/productprivacy", + "legIntClaim": "https://www.wagawin.com/product-privacy-policy" + }, + { + "langId": "de", + "privacy": "https://www.wagawin.com/product-privacy-policy", + "legIntClaim": "https://www.wagawin.com/product-privacy-policy" + } + ], + "dataDeclaration": [ + 1 + ], + "deviceStorageDisclosureUrl": "https://docs.wagawin.com/deviceStorage.json" + }, + "778": { + "id": 778, + "name": "Discover-Tech ltd", + "purposes": [ + 2, + 3, + 4, + 7 + ], + "legIntPurposes": [], + "flexiblePurposes": [], + "specialPurposes": [], + "features": [ + 3 + ], + "specialFeatures": [], + "cookieMaxAgeSeconds": null, + "usesCookies": false, + "cookieRefresh": false, + "usesNonCookieAccess": false, + "dataRetention": { + "stdRetention": 93, + "purposes": {}, + "specialPurposes": {} + }, + "urls": [ + { + "langId": "en", + "privacy": "https://www.discover-tech.io/privacy-policy" + } + ], + "dataDeclaration": [ + 1, + 3 + ], + "deviceStorageDisclosureUrl": "https://www.discover-tech.io/_functions/api/disclosure.json" + }, + "780": { + "id": 780, + "name": "Aniview LTD", + "purposes": [ + 1, + 2, + 3, + 4, + 7, + 8, + 9, + 10, + 11 + ], + "legIntPurposes": [], + "flexiblePurposes": [], + "specialPurposes": [ + 1 + ], + "features": [ + 3 + ], + "specialFeatures": [], + "cookieMaxAgeSeconds": 7776000, + "usesCookies": true, + "cookieRefresh": false, + "usesNonCookieAccess": true, + "dataRetention": { + "stdRetention": 4320, + "purposes": {}, + "specialPurposes": { + "1": 100 + } + }, + "urls": [ + { + "langId": "en", + "privacy": "https://www.aniview.com/privacy-policy/", + "legIntClaim": "https://www.aniview.com/privacy-policy/" + } + ], + "dataDeclaration": [ + 1, + 2, + 3, + 6, + 8 + ], + "deviceStorageDisclosureUrl": "https://player.aniview.com/gdpr/gdpr.json" + }, + "781": { + "id": 781, + "name": "FeedAd GmbH", + "purposes": [ + 1, + 3, + 4, + 5, + 6, + 8, + 9 + ], + "legIntPurposes": [ + 2, + 7, + 10 + ], + "flexiblePurposes": [ + 2, + 7, + 10 + ], + "specialPurposes": [ + 1, + 2 + ], + "features": [ + 2, + 3 + ], + "specialFeatures": [ + 1, + 2 + ], + "overflow": { + "httpGetLimit": 128 + }, + "cookieMaxAgeSeconds": 2592000, + "usesCookies": true, + "cookieRefresh": true, + "usesNonCookieAccess": true, + "dataRetention": { + "stdRetention": 30, + "purposes": {}, + "specialPurposes": {} + }, + "urls": [ + { + "langId": "en", + "privacy": "https://feedad.com/privacy/", + "legIntClaim": "https://feedad.com/privacy/" + } + ], + "dataDeclaration": [ + 1, + 2, + 3, + 6, + 7, + 8, + 9, + 10, + 11 + ], + "deviceStorageDisclosureUrl": "https://api.feedad.com/tcf-device-disclosures.json" + }, + "784": { + "id": 784, + "name": "Nubo LTD", + "purposes": [ + 1 + ], + "legIntPurposes": [ + 2, + 7 + ], + "flexiblePurposes": [], + "specialPurposes": [ + 1, + 2 + ], + "features": [ + 3 + ], + "specialFeatures": [], + "cookieMaxAgeSeconds": 86400, + "usesCookies": true, + "cookieRefresh": false, + "usesNonCookieAccess": false, + "dataRetention": { + "stdRetention": 1, + "purposes": {}, + "specialPurposes": {} + }, + "urls": [ + { + "langId": "en", + "privacy": "https://api.recod3suite.com/privacypolicy.php", + "legIntClaim": "https://api.recod3suite.com/privacypolicy.php" + } + ], + "dataDeclaration": [ + 1, + 2, + 8 + ], + "deviceStorageDisclosureUrl": "https://api.recod3suite.com/deviceStorage.json" + }, + "786": { + "id": 786, + "name": "TargetVideo GmbH", + "purposes": [ + 8 + ], + "legIntPurposes": [], + "flexiblePurposes": [], + "specialPurposes": [], + "features": [], + "specialFeatures": [], + "cookieMaxAgeSeconds": null, + "usesCookies": false, + "cookieRefresh": false, + "usesNonCookieAccess": false, + "dataRetention": { + "purposes": { + "8": 1 + }, + "specialPurposes": {} + }, + "urls": [ + { + "langId": "de", + "privacy": "https://www.target-video.com/datenschutz/" + } + ], + "dataDeclaration": [ + 2 + ], + "deviceStorageDisclosureUrl": "https://www.target-video.com/vendors-device-storage-and-operational-disclosures.json" + }, + "787": { + "id": 787, + "name": "Hearts and Science München GmbH", + "purposes": [ + 1, + 7 + ], + "legIntPurposes": [], + "flexiblePurposes": [], + "specialPurposes": [ + 1, + 2 + ], + "features": [], + "specialFeatures": [], + "cookieMaxAgeSeconds": 5184000, + "usesCookies": true, + "cookieRefresh": true, + "usesNonCookieAccess": false, + "dataRetention": { + "stdRetention": 45, + "purposes": {}, + "specialPurposes": {} + }, + "urls": [ + { + "langId": "de", + "privacy": "https://www.nonstoppartner.net", + "legIntClaim": "https://www.nonstoppartner.net" + } + ], + "dataDeclaration": [ + 1 + ], + "deviceStorageDisclosureUrl": "https://a.nonstoppartner.net/tcf.php" + }, + "788": { + "id": 788, + "name": "Ad Alliance GmbH", + "purposes": [ + 1, + 2, + 3, + 4, + 5, + 6, + 7, + 8, + 9, + 10 + ], + "legIntPurposes": [], + "flexiblePurposes": [], + "specialPurposes": [], + "features": [ + 2 + ], + "specialFeatures": [ + 1 + ], + "overflow": { + "httpGetLimit": 128 + }, + "cookieMaxAgeSeconds": 31536000, + "usesCookies": true, + "cookieRefresh": false, + "usesNonCookieAccess": true, + "dataRetention": { + "stdRetention": 395, + "purposes": {}, + "specialPurposes": {} + }, + "urls": [ + { + "langId": "de", + "privacy": "https://www.ad-alliance.de/datenschutz/" + } + ], + "dataDeclaration": [ + 1, + 2, + 3, + 4, + 5, + 6, + 7, + 10 + ], + "deviceStorageDisclosureUrl": "https://static.emsservice.de/iabtcf/deviceStorageDisclosure.json" + }, + "791": { + "id": 791, + "name": "Media Square", + "purposes": [ + 1, + 2 + ], + "legIntPurposes": [], + "flexiblePurposes": [ + 2 + ], + "specialPurposes": [ + 2 + ], + "features": [], + "specialFeatures": [], + "cookieMaxAgeSeconds": 7776000, + "usesCookies": true, + "cookieRefresh": true, + "usesNonCookieAccess": false, + "dataRetention": { + "stdRetention": 90, + "purposes": {}, + "specialPurposes": {} + }, + "urls": [ + { + "langId": "fr", + "privacy": "https://www.mediasquare.fr/e-privacy/", + "legIntClaim": "https://www.mediasquare.fr/e-privacy/" + } + ], + "dataDeclaration": [ + 2, + 3, + 11 + ], + "deviceStorageDisclosureUrl": "https://mediasquare.fr/deviceStorage.json" + }, + "794": { + "id": 794, + "name": "Kubient Inc. ", + "purposes": [ + 1, + 2, + 3, + 4, + 5, + 6, + 7, + 8, + 9, + 10 + ], + "legIntPurposes": [], + "flexiblePurposes": [ + 10 + ], + "specialPurposes": [ + 1, + 2 + ], + "features": [ + 1, + 2, + 3 + ], + "specialFeatures": [ + 1, + 2 + ], + "cookieMaxAgeSeconds": 31104000, + "usesCookies": true, + "cookieRefresh": false, + "usesNonCookieAccess": false, + "dataRetention": { + "stdRetention": 30, + "purposes": {}, + "specialPurposes": {} + }, + "urls": [ + { + "langId": "en", + "privacy": "https://kubient.com/privacy-policy/", + "legIntClaim": "https://kubient.com/privacy-policy/" + } + ], + "dataDeclaration": [ + 1, + 2, + 3, + 6, + 8 + ], + "deviceStorageDisclosureUrl": "https://kubient.com/wp-content/uploads/2022/08/TCFv2.json" + }, + "795": { + "id": 795, + "name": "Factor Eleven GmbH", + "purposes": [ + 1, + 2, + 4, + 7 + ], + "legIntPurposes": [], + "flexiblePurposes": [], + "specialPurposes": [ + 1, + 2 + ], + "features": [ + 3 + ], + "specialFeatures": [ + 1 + ], + "cookieMaxAgeSeconds": 2592000, + "usesCookies": true, + "cookieRefresh": true, + "usesNonCookieAccess": true, + "dataRetention": { + "stdRetention": 30, + "purposes": {}, + "specialPurposes": {} + }, + "urls": [ + { + "langId": "de", + "privacy": "https://de.f11-ads.com/privacy.php", + "legIntClaim": "https://de.f11-ads.com/privacy.php" + }, + { + "langId": "en", + "privacy": "https://de.f11-ads.com/privacy.php", + "legIntClaim": "https://de.f11-ads.com/privacy.php" + } + ], + "dataDeclaration": [ + 1, + 2, + 8, + 11 + ], + "deviceStorageDisclosureUrl": "https://www.factor-eleven.de/tcf/deviceStorage2.json" + }, + "796": { + "id": 796, + "name": "EASY Marketing GmbH", + "purposes": [ + 1, + 2, + 7, + 8 + ], + "legIntPurposes": [], + "flexiblePurposes": [ + 2, + 7, + 8 + ], + "specialPurposes": [ + 1, + 2 + ], + "features": [ + 1, + 2, + 3 + ], + "specialFeatures": [], + "cookieMaxAgeSeconds": 31536000, + "usesCookies": true, + "cookieRefresh": true, + "usesNonCookieAccess": true, + "dataRetention": { + "stdRetention": 365, + "purposes": {}, + "specialPurposes": {} + }, + "urls": [ + { + "langId": "de", + "privacy": "https://trck.easy-m.de/privacy-policy.do", + "legIntClaim": "https://trck.easy-m.de/privacy-policy.do" + }, + { + "langId": "en", + "privacy": "https://trck.easy-m.de/privacy-policy.do", + "legIntClaim": "https://trck.easy-m.de/privacy-policy.do" + } + ], + "dataDeclaration": [ + 2, + 3, + 4, + 6, + 11 + ], + "deviceStorageDisclosureUrl": "https://trck.easy-m.de/api/tcf/definitions/disclosures.json" + }, + "798": { + "id": 798, + "name": "Adverticum cPlc.", + "purposes": [ + 1, + 2, + 3, + 4, + 8, + 9, + 10 + ], + "legIntPurposes": [ + 7 + ], + "flexiblePurposes": [ + 2, + 7, + 8, + 9, + 10 + ], + "specialPurposes": [ + 1, + 2 + ], + "features": [ + 3 + ], + "specialFeatures": [ + 2 + ], + "cookieMaxAgeSeconds": 63072000, + "usesCookies": true, + "cookieRefresh": false, + "usesNonCookieAccess": true, + "dataRetention": { + "stdRetention": 0, + "purposes": {}, + "specialPurposes": {} + }, + "urls": [ + { + "langId": "en", + "privacy": "https://adverticum.net/english/privacy-and-data-processing-information/", + "legIntClaim": "https://adverticum.net/english/privacy-and-data-processing-information/" + } + ], + "dataDeclaration": [ + 1, + 2 + ], + "deviceStorageDisclosureUrl": "https://adverticum.net/static/deviceStorageDisclosure.json" + }, + "800": { + "id": 800, + "name": "Reppublika Data Analytics and Technologies GmbH", + "purposes": [ + 1, + 2, + 3, + 4, + 5, + 6, + 7, + 8, + 9, + 10 + ], + "legIntPurposes": [], + "flexiblePurposes": [ + 10 + ], + "specialPurposes": [ + 1 + ], + "features": [ + 2, + 3 + ], + "specialFeatures": [ + 2 + ], + "cookieMaxAgeSeconds": 15552000, + "usesCookies": true, + "cookieRefresh": false, + "usesNonCookieAccess": true, + "dataRetention": { + "stdRetention": 180, + "purposes": {}, + "specialPurposes": {} + }, + "urls": [ + { + "langId": "en", + "privacy": "https://www.reppublika.com/privacy-policy", + "legIntClaim": "https://www.reppublika.com/privacy-policy" + }, + { + "langId": "de", + "privacy": "https://www.reppublika.com/datenschutzordnung", + "legIntClaim": "https://www.reppublika.com/datenschutzordnung" + } + ], + "dataDeclaration": [ + 1, + 2, + 3, + 4, + 6, + 10 + ], + "deviceStorageDisclosureUrl": "https://pub.mindtake.com/TCF_DeviceStorageDisclosure/?vendorID=800" + }, + "806": { + "id": 806, + "name": "Aarki, Inc.", + "purposes": [ + 1, + 2, + 3, + 4 + ], + "legIntPurposes": [ + 7, + 10 + ], + "flexiblePurposes": [], + "specialPurposes": [ + 1, + 2 + ], + "features": [ + 3 + ], + "specialFeatures": [], + "cookieMaxAgeSeconds": null, + "usesCookies": false, + "cookieRefresh": false, + "usesNonCookieAccess": true, + "dataRetention": { + "stdRetention": 365, + "purposes": { + "3": 3650, + "4": 3650, + "7": 1500 + }, + "specialPurposes": {} + }, + "urls": [ + { + "langId": "en", + "privacy": "https://corp.aarki.com/privacy", + "legIntClaim": "https://corp.aarki.com/privacy" + } + ], + "dataDeclaration": [ + 1, + 2, + 3, + 7, + 8 + ], + "deviceStorageDisclosureUrl": "https://www.aarki.com/hubfs/device_storage_disclosure.json" + }, + "807": { + "id": 807, + "name": "Moloco, Inc.", + "purposes": [ + 3, + 4 + ], + "legIntPurposes": [ + 2, + 7, + 8, + 9, + 10 + ], + "flexiblePurposes": [ + 2, + 7, + 8, + 9, + 10 + ], + "specialPurposes": [ + 1, + 2 + ], + "features": [ + 3 + ], + "specialFeatures": [ + 2 + ], + "cookieMaxAgeSeconds": 63072000, + "usesCookies": true, + "cookieRefresh": true, + "usesNonCookieAccess": true, + "dataRetention": { + "stdRetention": 730, + "purposes": {}, + "specialPurposes": { + "2": 0 + } + }, + "urls": [ + { + "langId": "en", + "privacy": "https://www.moloco.com/privacy-policy", + "legIntClaim": "https://www.moloco.com/advertising-policy" + } + ], + "dataDeclaration": [ + 1, + 2, + 3, + 8 + ], + "deviceStorageDisclosureUrl": "https://www.moloco.com/device-storage-disclosure-json" + }, + "810": { + "id": 810, + "name": "lead alliance GmbH", + "purposes": [ + 1 + ], + "legIntPurposes": [ + 7 + ], + "flexiblePurposes": [ + 7 + ], + "specialPurposes": [ + 1, + 2 + ], + "features": [ + 3 + ], + "specialFeatures": [], + "cookieMaxAgeSeconds": 7776000, + "usesCookies": true, + "cookieRefresh": false, + "usesNonCookieAccess": true, + "dataRetention": { + "stdRetention": 90, + "purposes": {}, + "specialPurposes": {} + }, + "urls": [ + { + "langId": "de", + "privacy": "https://www.lead-alliance.net/dataprotection2", + "legIntClaim": "https://www.lead-alliance.net/dataprotection2" + } + ], + "dataDeclaration": [ + 1, + 6, + 11 + ], + "deviceStorageDisclosureUrl": "https://files.leadalliance.eu/devicestorage.json" + }, + "812": { + "id": 812, + "name": "Nielsen International SA", + "purposes": [ + 1 + ], + "legIntPurposes": [ + 7, + 9, + 10 + ], + "flexiblePurposes": [ + 7, + 10 + ], + "specialPurposes": [ + 1 + ], + "features": [ + 1, + 2, + 3 + ], + "specialFeatures": [], + "cookieMaxAgeSeconds": 33696000, + "usesCookies": true, + "cookieRefresh": false, + "usesNonCookieAccess": true, + "dataRetention": { + "stdRetention": 390, + "purposes": {}, + "specialPurposes": {} + }, + "urls": [ + { + "langId": "en", + "privacy": "https://www.nielsen.com/eu/en/legal/privacy-statement/digital-measurement/", + "legIntClaim": "https://www.nielsen.com/legal/privacy-principles/digital-measurement-privacy-statement/#personal-data" + }, + { + "langId": "sv", + "privacy": "https://www.nielsen.com/legal/privacy-principles/digital-measurement-privacy-statement/", + "legIntClaim": "https://www.nielsen.com/legal/privacy-principles/digital-measurement-privacy-statement/#personal-data" + }, + { + "langId": "pt", + "privacy": "https://www.nielsen.com/legal/privacy-principles/digital-measurement-privacy-statement/", + "legIntClaim": "https://www.nielsen.com/legal/privacy-principles/digital-measurement-privacy-statement/#personal-data" + }, + { + "langId": "it", + "privacy": "https://www.nielsen.com/legal/privacy-principles/digital-measurement-privacy-statement/", + "legIntClaim": "https://www.nielsen.com/legal/privacy-principles/digital-measurement-privacy-statement/#personal-data" + }, + { + "langId": "fr", + "privacy": "https://www.nielsen.com/legal/privacy-principles/digital-measurement-privacy-statement/", + "legIntClaim": "https://www.nielsen.com/legal/privacy-principles/digital-measurement-privacy-statement/#personal-data" + }, + { + "langId": "es", + "privacy": "https://www.nielsen.com/legal/privacy-principles/digital-measurement-privacy-statement/", + "legIntClaim": "https://www.nielsen.com/legal/privacy-principles/digital-measurement-privacy-statement/#personal-data" + }, + { + "langId": "cs", + "privacy": "https://www.nielsen.com/legal/privacy-principles/digital-measurement-privacy-statement/", + "legIntClaim": "https://www.nielsen.com/legal/privacy-principles/digital-measurement-privacy-statement/#personal-data" + }, + { + "langId": "no", + "privacy": "https://www.nielsen.com/legal/privacy-principles/digital-measurement-privacy-statement/", + "legIntClaim": "https://www.nielsen.com/legal/privacy-principles/digital-measurement-privacy-statement/#personal-data" + }, + { + "langId": "pl", + "privacy": "https://www.nielsen.com/legal/privacy-principles/digital-measurement-privacy-statement/", + "legIntClaim": "https://www.nielsen.com/legal/privacy-principles/digital-measurement-privacy-statement/#personal-data" + }, + { + "langId": "da", + "privacy": "https://www.nielsen.com/legal/privacy-principles/digital-measurement-privacy-statement/", + "legIntClaim": "https://www.nielsen.com/legal/privacy-principles/digital-measurement-privacy-statement/#personal-data" + }, + { + "langId": "gl", + "privacy": "https://www.nielsen.com/legal/privacy-principles/digital-measurement-privacy-statement/", + "legIntClaim": "https://www.nielsen.com/legal/privacy-principles/digital-measurement-privacy-statement/#personal-data" + } + ], + "dataDeclaration": [ + 1, + 2, + 3, + 11 + ], + "deviceStorageDisclosureUrl": "https://files.imrworldwide.com/deviceStorageDisclosure.json" + }, + "820": { + "id": 820, + "name": "Kameleoon SAS", + "purposes": [ + 1, + 3, + 4, + 5, + 6, + 7, + 8, + 10 + ], + "legIntPurposes": [], + "flexiblePurposes": [ + 10 + ], + "specialPurposes": [], + "features": [ + 1, + 2 + ], + "specialFeatures": [], + "cookieMaxAgeSeconds": 31536000, + "usesCookies": true, + "cookieRefresh": true, + "usesNonCookieAccess": true, + "dataRetention": { + "stdRetention": 730, + "purposes": {}, + "specialPurposes": {} + }, + "urls": [ + { + "langId": "en", + "privacy": "https://developers.kameleoon.com/local-storage.html#list-of-collected-data", + "legIntClaim": "https://www.kameleoon.com/en/privacy-policy" + } + ], + "dataDeclaration": [ + 1, + 2, + 3, + 4, + 8, + 11 + ], + "deviceStorageDisclosureUrl": "https://developers.kameleoon.com/tcf/kameleoon-tcf.json" + }, + "821": { + "id": 821, + "name": "vitrado GmbH", + "purposes": [ + 1, + 7, + 10 + ], + "legIntPurposes": [], + "flexiblePurposes": [ + 7, + 10 + ], + "specialPurposes": [ + 1, + 2 + ], + "features": [ + 3 + ], + "specialFeatures": [], + "cookieMaxAgeSeconds": 31536000, + "usesCookies": true, + "cookieRefresh": true, + "usesNonCookieAccess": false, + "dataRetention": { + "stdRetention": 365, + "purposes": { + "7": 4320 + }, + "specialPurposes": {} + }, + "urls": [ + { + "langId": "de", + "privacy": "https://www.vitrado.de/datenschutz", + "legIntClaim": "https://www.vitrado.de/datenschutz" + } + ], + "dataDeclaration": [ + 2 + ], + "deviceStorageDisclosureUrl": "https://static.ppro.de/deviceStorage.json" + }, + "826": { + "id": 826, + "name": "DNA-I.COM", + "purposes": [ + 7, + 8 + ], + "legIntPurposes": [], + "flexiblePurposes": [], + "specialPurposes": [ + 1, + 2 + ], + "features": [], + "specialFeatures": [], + "cookieMaxAgeSeconds": null, + "usesCookies": false, + "cookieRefresh": false, + "usesNonCookieAccess": false, + "dataRetention": { + "purposes": { + "7": 1095, + "8": 1095 + }, + "specialPurposes": { + "1": 30, + "2": 30 + } + }, + "urls": [ + { + "langId": "fr", + "privacy": "https://www.adn.ai/fr/politique-confidentialite-adserver", + "legIntClaim": "https://www.adn.ai/fr/politique-confidentialite-adserver" + } + ], + "dataDeclaration": [ + 2, + 6 + ], + "deviceStorageDisclosureUrl": "https://static.adn.ai/deploymanuel/tcf/deviceStorageDisclosure.json" + }, + "828": { + "id": 828, + "name": "TX Group AG", + "purposes": [ + 1, + 3, + 5, + 6 + ], + "legIntPurposes": [ + 8, + 9, + 10 + ], + "flexiblePurposes": [], + "specialPurposes": [ + 1, + 2 + ], + "features": [ + 1, + 2, + 3 + ], + "specialFeatures": [ + 1 + ], + "cookieMaxAgeSeconds": 94608000, + "usesCookies": true, + "cookieRefresh": false, + "usesNonCookieAccess": true, + "dataRetention": { + "stdRetention": 730, + "purposes": {}, + "specialPurposes": {} + }, + "urls": [ + { + "langId": "de", + "privacy": "https://tx.group/de/datenschutzerklaerung/", + "legIntClaim": "https://tx.group/de/datenschutzerklaerung/#process_personal_data" + }, + { + "langId": "en", + "privacy": "https://tx.group/privacy-policy/", + "legIntClaim": "https://tx.group/privacy-policy/#process_personal_data" + }, + { + "langId": "fr", + "privacy": "https://tx.group/fr/declaration-de-confidentialite/", + "legIntClaim": "https://tx.group/fr/declaration-de-confidentialite/#process_personal_data" + } + ], + "dataDeclaration": [ + 1, + 2, + 3, + 5, + 6, + 7, + 9, + 10, + 11 + ], + "deviceStorageDisclosureUrl": "https://tx.group/iab/tcf-glv.json" + }, + "831": { + "id": 831, + "name": "United Internet Media GmbH", + "purposes": [ + 1, + 2, + 3, + 4, + 5, + 6, + 7, + 8, + 9, + 10, + 11 + ], + "legIntPurposes": [], + "flexiblePurposes": [], + "specialPurposes": [ + 1, + 2 + ], + "features": [ + 1, + 2 + ], + "specialFeatures": [], + "cookieMaxAgeSeconds": 31536000, + "usesCookies": true, + "cookieRefresh": true, + "usesNonCookieAccess": false, + "dataRetention": { + "stdRetention": 90, + "purposes": {}, + "specialPurposes": {} + }, + "urls": [ + { + "langId": "de", + "privacy": "https://www.united-internet-media.de/de/datenschutzhinweis/", + "legIntClaim": "https://www.united-internet-media.de/de/datenschutzhinweis/" + } + ], + "dataDeclaration": [ + 1, + 2, + 3, + 5, + 6, + 8, + 10, + 11 + ], + "deviceStorageDisclosureUrl": "https://www.united-internet-media.de/services/deviceStorage.json" + }, + "835": { + "id": 835, + "name": "Quality Media Network GmbH", + "purposes": [ + 1, + 2, + 3, + 4, + 7, + 9 + ], + "legIntPurposes": [], + "flexiblePurposes": [], + "specialPurposes": [ + 1, + 2 + ], + "features": [], + "specialFeatures": [], + "cookieMaxAgeSeconds": 25920000, + "usesCookies": true, + "cookieRefresh": false, + "usesNonCookieAccess": false, + "dataRetention": { + "stdRetention": 30, + "purposes": {}, + "specialPurposes": {} + }, + "urls": [ + { + "langId": "de", + "privacy": "https://www.qualitymedianetwork.de/datenschutz/", + "legIntClaim": "https://ads.qualitymedianetwork.de/privacy.php" + } + ], + "dataDeclaration": [ + 1, + 2, + 6, + 8, + 11 + ], + "deviceStorageDisclosureUrl": "https://www.qualitymedianetwork.de/json-file/deviceStorage2.json" + }, + "836": { + "id": 836, + "name": "Bring! Labs AG", + "purposes": [ + 1 + ], + "legIntPurposes": [ + 7, + 8, + 10 + ], + "flexiblePurposes": [ + 7, + 8 + ], + "specialPurposes": [], + "features": [], + "specialFeatures": [ + 1 + ], + "cookieMaxAgeSeconds": null, + "usesCookies": false, + "cookieRefresh": false, + "usesNonCookieAccess": true, + "dataRetention": { + "stdRetention": 365, + "purposes": {}, + "specialPurposes": {} + }, + "urls": [ + { + "langId": "en", + "privacy": "https://www.getbring.com/en/privacy-policy", + "legIntClaim": "https://www.getbring.com/en/privacy-policy" + } + ], + "dataDeclaration": [ + 1, + 5, + 7, + 9, + 10, + 11 + ], + "deviceStorageDisclosureUrl": "https://files.getbring.com/iab/DeviceStorageDisclosure.json" + }, + "839": { + "id": 839, + "name": "PIXFUTURE MEDIA INC.", + "purposes": [ + 1 + ], + "legIntPurposes": [ + 2, + 7, + 10 + ], + "flexiblePurposes": [], + "specialPurposes": [ + 1, + 2 + ], + "features": [], + "specialFeatures": [ + 1, + 2 + ], + "cookieMaxAgeSeconds": 31536000, + "usesCookies": true, + "cookieRefresh": true, + "usesNonCookieAccess": false, + "dataRetention": { + "stdRetention": 365, + "purposes": {}, + "specialPurposes": {} + }, + "urls": [ + { + "langId": "en", + "privacy": "https://www.pixfuture.com/terms-and-conditions#platform-terms", + "legIntClaim": "https://www.pixfuture.com/terms-and-conditions#platform-terms" + } + ], + "dataDeclaration": [ + 4 + ], + "deviceStorageDisclosureUrl": "https://pixfuture.com/vendor-disclosures.json" + }, + "844": { + "id": 844, + "name": "SPICY MOBILE Karczewski Zawadzki Spółka Jawna", + "purposes": [ + 1, + 2, + 3, + 4, + 7 + ], + "legIntPurposes": [], + "flexiblePurposes": [], + "specialPurposes": [], + "features": [], + "specialFeatures": [ + 1 + ], + "overflow": { + "httpGetLimit": 128 + }, + "cookieMaxAgeSeconds": 2419200, + "usesCookies": true, + "cookieRefresh": true, + "usesNonCookieAccess": false, + "dataRetention": { + "stdRetention": 180, + "purposes": {}, + "specialPurposes": {} + }, + "urls": [ + { + "langId": "en", + "privacy": "https://spicymobile.pl/polityka-prywatnosci" + } + ], + "dataDeclaration": [ + 1, + 2, + 3, + 6, + 7 + ], + "deviceStorageDisclosureUrl": "https://spicyrtb.com/static/iab-disclosure.json" + }, + "848": { + "id": 848, + "name": "BSmartData GmbH", + "purposes": [ + 1, + 2, + 3, + 4, + 7, + 9, + 10 + ], + "legIntPurposes": [], + "flexiblePurposes": [], + "specialPurposes": [ + 1, + 2 + ], + "features": [], + "specialFeatures": [], + "overflow": { + "httpGetLimit": 128 + }, + "cookieMaxAgeSeconds": 2592000, + "usesCookies": true, + "cookieRefresh": false, + "usesNonCookieAccess": false, + "dataRetention": { + "stdRetention": 0, + "purposes": { + "3": 7, + "4": 7 + }, + "specialPurposes": { + "1": 7 + } + }, + "urls": [ + { + "langId": "en", + "privacy": "https://www.bsmartdata.com/en/privacy/", + "legIntClaim": "https://www.bsmartdata.com/en/privacy/" + } + ], + "dataDeclaration": [ + 1, + 2, + 6, + 10 + ], + "deviceStorageDisclosureUrl": "https://ad.bsmartdata.com/DeviceStorage.json" + }, + "849": { + "id": 849, + "name": "Epom Ltd.", + "purposes": [ + 1, + 2, + 7 + ], + "legIntPurposes": [], + "flexiblePurposes": [], + "specialPurposes": [ + 2 + ], + "features": [ + 1 + ], + "specialFeatures": [], + "cookieMaxAgeSeconds": 63072000, + "usesCookies": true, + "cookieRefresh": true, + "usesNonCookieAccess": true, + "dataRetention": { + "stdRetention": 3, + "purposes": { + "2": 730 + }, + "specialPurposes": {} + }, + "urls": [ + { + "langId": "en", + "privacy": "https://epom.com/privacy-policy", + "legIntClaim": "https://epom.com/privacy-policy" + } + ], + "dataDeclaration": [ + 1, + 2, + 8 + ], + "deviceStorageDisclosureUrl": "https://epom.com/deviceStorage.json" + }, + "850": { + "id": 850, + "name": "Publisher First, Inc.", + "purposes": [ + 1 + ], + "legIntPurposes": [ + 10 + ], + "flexiblePurposes": [], + "specialPurposes": [ + 2 + ], + "features": [], + "specialFeatures": [], + "overflow": { + "httpGetLimit": 128 + }, + "cookieMaxAgeSeconds": 604800, + "usesCookies": true, + "cookieRefresh": true, + "usesNonCookieAccess": false, + "dataRetention": { + "stdRetention": 730, + "purposes": {}, + "specialPurposes": {} + }, + "urls": [ + { + "langId": "en", + "privacy": "https://freestar.com/privacy-policy/", + "legIntClaim": "https://freestar.com/privacy-policy/" + } + ], + "dataDeclaration": [ + 1, + 2, + 3, + 4, + 6, + 8 + ], + "deviceStorageDisclosureUrl": "https://iab.pub.network/json/freestar-us.json" + }, + "855": { + "id": 855, + "name": "Adnuntius AS", + "purposes": [ + 1, + 2, + 3, + 4, + 7 + ], + "legIntPurposes": [], + "flexiblePurposes": [ + 2, + 7 + ], + "specialPurposes": [ + 1, + 2 + ], + "features": [ + 3 + ], + "specialFeatures": [ + 1 + ], + "cookieMaxAgeSeconds": 214748364, + "usesCookies": true, + "cookieRefresh": true, + "usesNonCookieAccess": true, + "dataRetention": { + "stdRetention": 30, + "purposes": {}, + "specialPurposes": { + "2": 0 + } + }, + "urls": [ + { + "langId": "en", + "privacy": "https://adnuntius.com/resources/privacy-policy/", + "legIntClaim": "https://adnuntius.com/resources/privacy-policy/" + } + ], + "dataDeclaration": [ + 1, + 2, + 3, + 4, + 5, + 6, + 7, + 8, + 9, + 10, + 11 + ], + "deviceStorageDisclosureUrl": "https://delivery.adnuntius.com/.well-known/deviceStorage.json" + }, + "856": { + "id": 856, + "name": "Petal Ads", + "purposes": [ + 1, + 3, + 4 + ], + "legIntPurposes": [ + 2, + 7, + 9, + 10 + ], + "flexiblePurposes": [ + 2, + 7, + 9, + 10 + ], + "specialPurposes": [ + 1, + 2 + ], + "features": [], + "specialFeatures": [], + "cookieMaxAgeSeconds": null, + "usesCookies": false, + "cookieRefresh": false, + "usesNonCookieAccess": true, + "dataRetention": { + "stdRetention": 365, + "purposes": { + "2": 7 + }, + "specialPurposes": {} + }, + "urls": [ + { + "langId": "en", + "privacy": "https://www.aspiegel.com/en/privacy", + "legIntClaim": "https://h5hosting.dbankcdn.com/cch5/PPS/ads/interests/legitimate_interests.htm" + } + ], + "dataDeclaration": [ + 1, + 2, + 3, + 6, + 7, + 8, + 10, + 11 + ], + "deviceStorageDisclosureUrl": "https://h5hosting-dre.dbankcdn.com/cch5/PPS/ads/tcfvendor/disclosure.json" + }, + "857": { + "id": 857, + "name": "SOMQUERY SOMTAG - (SevenOne Media)", + "purposes": [ + 1, + 3, + 4 + ], + "legIntPurposes": [ + 2, + 10 + ], + "flexiblePurposes": [ + 2, + 10 + ], + "specialPurposes": [ + 1, + 2 + ], + "features": [ + 1, + 2, + 3 + ], + "specialFeatures": [], + "cookieMaxAgeSeconds": 31536000, + "usesCookies": true, + "cookieRefresh": true, + "usesNonCookieAccess": true, + "dataRetention": { + "stdRetention": 365, + "purposes": {}, + "specialPurposes": {} + }, + "urls": [ + { + "langId": "de", + "privacy": "https://www.seven.one/datenschutzhinweise/somquery-somtag", + "legIntClaim": "https://www.seven.one/datenschutzhinweise/somquery-somtag" + } + ], + "dataDeclaration": [ + 1, + 2, + 3, + 4, + 6, + 8, + 10, + 11 + ], + "deviceStorageDisclosureUrl": "https://ad.71i.de/consent/deviceStorage.json" + }, + "858": { + "id": 858, + "name": "Mediavine, Inc.", + "purposes": [ + 1, + 2, + 3, + 4, + 5, + 6, + 7, + 8, + 9, + 10, + 11 + ], + "legIntPurposes": [], + "flexiblePurposes": [ + 2, + 7, + 8, + 9, + 10, + 11 + ], + "specialPurposes": [ + 1, + 2 + ], + "features": [ + 1, + 2, + 3 + ], + "specialFeatures": [], + "cookieMaxAgeSeconds": 31560000, + "usesCookies": true, + "cookieRefresh": true, + "usesNonCookieAccess": true, + "dataRetention": { + "stdRetention": 365, + "purposes": {}, + "specialPurposes": {} + }, + "urls": [ + { + "langId": "en", + "privacy": "https://www.mediavine.com/privacy-policy", + "legIntClaim": "https://www.mediavine.com/privacy-policy" + } + ], + "dataDeclaration": [ + 1, + 2, + 3, + 4, + 5, + 6, + 7, + 8, + 10, + 11 + ], + "deviceStorageDisclosureUrl": "https://www.mediavine.com/deviceStorage.json" + }, + "861": { + "id": 861, + "name": "Triple13 Ltd", + "purposes": [ + 1, + 2, + 3, + 4, + 5, + 6, + 7, + 8, + 9, + 10 + ], + "legIntPurposes": [], + "flexiblePurposes": [], + "specialPurposes": [], + "features": [ + 1, + 2, + 3 + ], + "specialFeatures": [ + 2 + ], + "overflow": { + "httpGetLimit": 128 + }, + "cookieMaxAgeSeconds": 7776000, + "usesCookies": true, + "cookieRefresh": true, + "usesNonCookieAccess": true, + "dataRetention": { + "stdRetention": 0, + "purposes": { + "7": 730, + "8": 730, + "9": 730, + "10": 730 + }, + "specialPurposes": {} + }, + "urls": [ + { + "langId": "en", + "privacy": "https://freestar.com/privacy-policy/" + } + ], + "dataDeclaration": [ + 1, + 2, + 3, + 4, + 6, + 8 + ], + "deviceStorageDisclosureUrl": "https://static.s2s.t13.io/iab/deviceStorageDisclosure.json" + }, + "862": { + "id": 862, + "name": "Truvid Inc.", + "purposes": [ + 1, + 2, + 3, + 4, + 5, + 6, + 8 + ], + "legIntPurposes": [ + 7, + 10 + ], + "flexiblePurposes": [ + 2 + ], + "specialPurposes": [ + 1, + 2 + ], + "features": [], + "specialFeatures": [], + "cookieMaxAgeSeconds": 5184000, + "usesCookies": true, + "cookieRefresh": false, + "usesNonCookieAccess": false, + "dataRetention": { + "stdRetention": 60, + "purposes": {}, + "specialPurposes": {} + }, + "urls": [ + { + "langId": "en", + "privacy": "https://www.truvid.com/terms/privacy_policy", + "legIntClaim": "https://www.truvid.com/terms/privacy_policy" + } + ], + "dataDeclaration": [ + 2, + 7, + 8 + ], + "deviceStorageDisclosureUrl": "https://www.truvid.com/deviceStorage.json" + }, + "864": { + "id": 864, + "name": "I.R.V. D.O.O.", + "purposes": [ + 1, + 2, + 3, + 4, + 5, + 6, + 7, + 8, + 9, + 10, + 11 + ], + "legIntPurposes": [], + "flexiblePurposes": [], + "specialPurposes": [], + "features": [ + 1, + 2, + 3 + ], + "specialFeatures": [], + "cookieMaxAgeSeconds": 63072000, + "usesCookies": true, + "cookieRefresh": true, + "usesNonCookieAccess": true, + "dataRetention": { + "stdRetention": 4320, + "purposes": {}, + "specialPurposes": {} + }, + "urls": [ + { + "langId": "en", + "privacy": "https://www.contentexchange.me/privacy-policy/" + } + ], + "dataDeclaration": [ + 1, + 2, + 4, + 6, + 8, + 10 + ], + "deviceStorageDisclosureUrl": "https://hb.contentexchange.me/template/deviceStorage.json" + }, + "866": { + "id": 866, + "name": "YieldLift LLC", + "purposes": [ + 1, + 2, + 7 + ], + "legIntPurposes": [], + "flexiblePurposes": [], + "specialPurposes": [ + 2 + ], + "features": [], + "specialFeatures": [], + "cookieMaxAgeSeconds": null, + "usesCookies": false, + "cookieRefresh": false, + "usesNonCookieAccess": true, + "dataRetention": { + "stdRetention": 0, + "purposes": {}, + "specialPurposes": {} + }, + "urls": [ + { + "langId": "en", + "privacy": "https://yieldlift.com/privacy-policy.html", + "legIntClaim": "https://yieldlift.com/privacy-policy.html" + } + ], + "dataDeclaration": [ + 11 + ], + "deviceStorageDisclosureUrl": "https://yieldlift.s3.amazonaws.com/yl-vendor-device-storage-and-operational-disclosures.json" + }, + "868": { + "id": 868, + "name": "Converto AG", + "purposes": [ + 1, + 2, + 3, + 4, + 5, + 6, + 7, + 8, + 9 + ], + "legIntPurposes": [], + "flexiblePurposes": [], + "specialPurposes": [], + "features": [ + 3 + ], + "specialFeatures": [], + "cookieMaxAgeSeconds": 31536000, + "usesCookies": true, + "cookieRefresh": false, + "usesNonCookieAccess": false, + "dataRetention": { + "stdRetention": 360, + "purposes": {}, + "specialPurposes": {} + }, + "urls": [ + { + "langId": "de", + "privacy": "https://www.converto.com/datenschutz-privacy-policy" + } + ], + "dataDeclaration": [ + 1, + 2, + 3, + 4, + 5, + 6, + 7, + 8, + 9, + 10, + 11 + ], + "deviceStorageDisclosureUrl": "https://converto-docs.s3.eu-central-1.amazonaws.com/TCD+2.0+json/converto-tcf-vendor-cookie.json" + }, + "878": { + "id": 878, + "name": "Natív Hirdetés Korlátolt Felelősségű Társaság", + "purposes": [ + 1 + ], + "legIntPurposes": [ + 2, + 7, + 8 + ], + "flexiblePurposes": [], + "specialPurposes": [ + 1, + 2 + ], + "features": [ + 3 + ], + "specialFeatures": [], + "cookieMaxAgeSeconds": 5184000, + "usesCookies": true, + "cookieRefresh": true, + "usesNonCookieAccess": false, + "dataRetention": { + "stdRetention": 60, + "purposes": {}, + "specialPurposes": {} + }, + "urls": [ + { + "langId": "hu", + "privacy": "https://related.hu/adatkezeles/", + "legIntClaim": "https://related.hu/adatkezeles/" + }, + { + "langId": "en", + "privacy": "https://related.hu/en/privacy-policy", + "legIntClaim": "https://related.hu/en/privacy-policy" + } + ], + "dataDeclaration": [ + 1, + 2, + 3, + 8 + ], + "deviceStorageDisclosureUrl": "https://related.hu/tcf/tcf.json" + }, + "881": { + "id": 881, + "name": "Hillside (Sports) GP Limited", + "purposes": [ + 1, + 2, + 7, + 8, + 10 + ], + "legIntPurposes": [], + "flexiblePurposes": [], + "specialPurposes": [ + 2 + ], + "features": [], + "specialFeatures": [], + "cookieMaxAgeSeconds": 388800, + "usesCookies": true, + "cookieRefresh": false, + "usesNonCookieAccess": false, + "dataRetention": { + "stdRetention": 45, + "purposes": {}, + "specialPurposes": {} + }, + "urls": [ + { + "langId": "en", + "privacy": "https://www.bet365partners.com/privacypolicy", + "legIntClaim": "https://www.bet365partners.com/privacypolicy" + } + ], + "dataDeclaration": [ + 1, + 2, + 4, + 11 + ], + "deviceStorageDisclosureUrl": "https://www.bet365partners.com/privacypolicy/iab_tcf/device_storage.json" + }, + "882": { + "id": 882, + "name": "NumberEight Technologies Ltd", + "purposes": [ + 1, + 3, + 5, + 10 + ], + "legIntPurposes": [ + 9 + ], + "flexiblePurposes": [], + "specialPurposes": [ + 1 + ], + "features": [ + 2, + 3 + ], + "specialFeatures": [ + 1 + ], + "cookieMaxAgeSeconds": null, + "usesCookies": false, + "cookieRefresh": false, + "usesNonCookieAccess": true, + "dataRetention": { + "stdRetention": 183, + "purposes": {}, + "specialPurposes": {} + }, + "urls": [ + { + "langId": "en", + "privacy": "https://portal.eu.numbereight.ai/policies-license#software-privacy-notice", + "legIntClaim": "https://portal.eu.numbereight.ai/policies-license#software-privacy-notice" + } + ], + "dataDeclaration": [ + 1, + 2, + 6, + 8, + 9, + 11 + ], + "deviceStorageDisclosureUrl": "https://server.eu.numbereight.ai/.well-known/deviceStorage.json" + }, + "885": { + "id": 885, + "name": "Dianomi PLC", + "purposes": [ + 1, + 3, + 4, + 5, + 6, + 8, + 9 + ], + "legIntPurposes": [ + 2, + 7, + 10 + ], + "flexiblePurposes": [ + 2, + 7, + 10 + ], + "specialPurposes": [ + 1, + 2 + ], + "features": [ + 3 + ], + "specialFeatures": [], + "cookieMaxAgeSeconds": 15552000, + "usesCookies": true, + "cookieRefresh": true, + "usesNonCookieAccess": true, + "dataRetention": { + "stdRetention": 180, + "purposes": {}, + "specialPurposes": {} + }, + "urls": [ + { + "langId": "en", + "privacy": "https://www.dianomi.com/legal/privacy.epl", + "legIntClaim": "https://www.dianomi.com/legal/privacy.epl" + } + ], + "dataDeclaration": [ + 1, + 2, + 3, + 6, + 7, + 8, + 10, + 11 + ], + "deviceStorageDisclosureUrl": "https://www.dianomi.com/device_storage.json" + }, + "889": { + "id": 889, + "name": "Admo.tv (Clickon)", + "purposes": [ + 8, + 9 + ], + "legIntPurposes": [], + "flexiblePurposes": [], + "specialPurposes": [], + "features": [], + "specialFeatures": [], + "cookieMaxAgeSeconds": 32000000, + "usesCookies": true, + "cookieRefresh": true, + "usesNonCookieAccess": false, + "dataRetention": { + "stdRetention": 390, + "purposes": {}, + "specialPurposes": {} + }, + "urls": [ + { + "langId": "en", + "privacy": "https://www.admo.tv/en/privacy-policy" + } + ], + "dataDeclaration": [ + 1, + 2, + 3, + 6, + 8, + 11 + ], + "deviceStorageDisclosureUrl": "https://vol.admo.tv/cookie-properties.json" + }, + "890": { + "id": 890, + "name": "Channel Pilot Solutions GmbH", + "purposes": [ + 1, + 7 + ], + "legIntPurposes": [], + "flexiblePurposes": [], + "specialPurposes": [], + "features": [], + "specialFeatures": [], + "cookieMaxAgeSeconds": 12690000, + "usesCookies": true, + "cookieRefresh": false, + "usesNonCookieAccess": false, + "dataRetention": { + "purposes": { + "7": 30 + }, + "specialPurposes": {} + }, + "urls": [ + { + "langId": "en", + "privacy": "https://channelpilot.co.uk/privacy-policy" + } + ], + "dataDeclaration": [ + 1 + ], + "deviceStorageDisclosureUrl": "https://static.content.channelpilot.com/tcf.json" + }, + "896": { + "id": 896, + "name": "IPSOS MORI UK LTD", + "purposes": [ + 1 + ], + "legIntPurposes": [ + 8, + 9 + ], + "flexiblePurposes": [ + 8, + 9 + ], + "specialPurposes": [ + 1 + ], + "features": [ + 3 + ], + "specialFeatures": [ + 2 + ], + "cookieMaxAgeSeconds": 31536000, + "usesCookies": true, + "cookieRefresh": true, + "usesNonCookieAccess": true, + "dataRetention": { + "stdRetention": 40, + "purposes": {}, + "specialPurposes": {} + }, + "urls": [ + { + "langId": "en", + "privacy": "https://iris.ipsos.com/site-centric-privacy/", + "legIntClaim": "https://iris.ipsos.com/site-centric-privacy/#legitimateInterests" + } + ], + "dataDeclaration": [ + 1, + 2, + 4, + 6, + 8, + 11 + ], + "deviceStorageDisclosureUrl": "https://download.dotmetrics.net/Privacy/deviceStorage.json" + }, + "898": { + "id": 898, + "name": "Mobkoi Ltd", + "purposes": [], + "legIntPurposes": [ + 2, + 10 + ], + "flexiblePurposes": [ + 2, + 10 + ], + "specialPurposes": [ + 1, + 2 + ], + "features": [], + "specialFeatures": [], + "cookieMaxAgeSeconds": null, + "usesCookies": false, + "cookieRefresh": false, + "usesNonCookieAccess": false, + "dataRetention": { + "purposes": { + "2": 365, + "10": 365 + }, + "specialPurposes": { + "1": 0, + "2": 0 + } + }, + "urls": [ + { + "langId": "en", + "privacy": "https://www.mobkoi.com/advertising-platform-privacy-policy/", + "legIntClaim": "https://www.mobkoi.com/advertising-platform-privacy-policy/" + } + ], + "dataDeclaration": [ + 1, + 2, + 8, + 11 + ], + "deviceStorageDisclosureUrl": "https://cdn.maximus.mobkoi.com/tcf/deviceStorageDisclosure.json" + }, + "900": { + "id": 900, + "name": "Advisible AB", + "purposes": [ + 1, + 2, + 3, + 4, + 5, + 6, + 7, + 8, + 9, + 10 + ], + "legIntPurposes": [], + "flexiblePurposes": [], + "specialPurposes": [ + 1, + 2 + ], + "features": [], + "specialFeatures": [], + "cookieMaxAgeSeconds": 31536000, + "usesCookies": true, + "cookieRefresh": true, + "usesNonCookieAccess": false, + "dataRetention": { + "stdRetention": 90, + "purposes": {}, + "specialPurposes": {} + }, + "urls": [ + { + "langId": "en", + "privacy": "https://www.advisible.com/privacy", + "legIntClaim": "https://www.advisible.com/privacy" + } + ], + "dataDeclaration": [ + 1, + 2, + 8 + ], + "deviceStorageDisclosureUrl": "https://misc.advisible.com/static/deviceStorage.json" + }, + "901": { + "id": 901, + "name": "STUDIO GONG GmbH & Co. Studiobetriebs KG", + "purposes": [ + 1, + 2, + 3, + 4, + 5, + 6, + 7, + 8, + 9, + 10 + ], + "legIntPurposes": [], + "flexiblePurposes": [], + "specialPurposes": [ + 1, + 2 + ], + "features": [ + 1, + 2, + 3 + ], + "specialFeatures": [ + 1 + ], + "cookieMaxAgeSeconds": 34128000, + "usesCookies": true, + "cookieRefresh": true, + "usesNonCookieAccess": false, + "dataRetention": { + "stdRetention": 90, + "purposes": {}, + "specialPurposes": {} + }, + "urls": [ + { + "langId": "de", + "privacy": "https://www.studio-gong.de/datenschutzerklaerung", + "legIntClaim": "https://www.studio-gong.de/datenschutzerklaerung" + } + ], + "dataDeclaration": [ + 1, + 2, + 3 + ], + "deviceStorageDisclosureUrl": "https://www.studio-gong.de/devicedisclosure_vendor_studiogong.json" + }, + "907": { + "id": 907, + "name": "AWIN AG", + "purposes": [ + 1 + ], + "legIntPurposes": [ + 7 + ], + "flexiblePurposes": [ + 7 + ], + "specialPurposes": [ + 1, + 2 + ], + "features": [ + 2, + 3 + ], + "specialFeatures": [], + "overflow": { + "httpGetLimit": 32 + }, + "cookieMaxAgeSeconds": 31536000, + "usesCookies": true, + "cookieRefresh": false, + "usesNonCookieAccess": true, + "dataRetention": { + "stdRetention": 1096, + "purposes": {}, + "specialPurposes": {} + }, + "urls": [ + { + "langId": "en", + "privacy": "https://www.awin.com/gb/privacy", + "legIntClaim": "https://www.awin.com/gb/privacy" + }, + { + "langId": "de", + "privacy": "https://www.awin.com/de/datenschutzerklarung", + "legIntClaim": "https://www.awin.com/de/datenschutzerklarung" + }, + { + "langId": "fr", + "privacy": "https://www.awin.com/fr/politique-de-confidentialite", + "legIntClaim": "https://www.awin.com/fr/politique-de-confidentialite" + }, + { + "langId": "it", + "privacy": "https://www.awin.com/it/privacy", + "legIntClaim": "https://www.awin.com/it/privacy" + }, + { + "langId": "pl", + "privacy": "https://www.awin.com/pl/prywatnosc", + "legIntClaim": "https://www.awin.com/pl/prywatnosc" + }, + { + "langId": "sv", + "privacy": "https://www.awin.com/se/privacy", + "legIntClaim": "https://www.awin.com/se/privacy" + }, + { + "langId": "nl", + "privacy": "https://www.awin.com/nl/privacy", + "legIntClaim": "https://www.awin.com/nl/privacy" + }, + { + "langId": "pt", + "privacy": "https://www.awin.com/pt/privacy", + "legIntClaim": "https://www.awin.com/pt/privacy" + }, + { + "langId": "es", + "privacy": "https://www.awin.com/es/privacidad", + "legIntClaim": "https://www.awin.com/es/privacidad" + } + ], + "dataDeclaration": [ + 1, + 2, + 4, + 5, + 6, + 11 + ], + "deviceStorageDisclosureUrl": "https://privacy.awin.com/AwinDeviceStorage.json" + }, + "909": { + "id": 909, + "name": "MobileFuse LLC", + "purposes": [ + 1, + 7, + 9, + 10 + ], + "legIntPurposes": [], + "flexiblePurposes": [], + "specialPurposes": [ + 1, + 2 + ], + "features": [ + 1, + 3 + ], + "specialFeatures": [], + "cookieMaxAgeSeconds": null, + "usesCookies": false, + "cookieRefresh": false, + "usesNonCookieAccess": true, + "dataRetention": { + "stdRetention": 90, + "purposes": {}, + "specialPurposes": {} + }, + "urls": [ + { + "langId": "en", + "privacy": "https://mobilefuse.com/privacy-policy/", + "legIntClaim": "https://mobilefuse.com/privacy-policy/" + } + ], + "dataDeclaration": [ + 1, + 2, + 3, + 4, + 5, + 7, + 8, + 11 + ], + "deviceStorageDisclosureUrl": "https://mobilefuse.com/storage-disclosures.json" + }, + "918": { + "id": 918, + "name": "SPORTORITY UK LTD", + "purposes": [ + 1, + 2, + 5, + 6 + ], + "legIntPurposes": [ + 7, + 8, + 9, + 10, + 11 + ], + "flexiblePurposes": [ + 2 + ], + "specialPurposes": [ + 1, + 2 + ], + "features": [], + "specialFeatures": [], + "cookieMaxAgeSeconds": 1800, + "usesCookies": true, + "cookieRefresh": true, + "usesNonCookieAccess": true, + "dataRetention": { + "stdRetention": 2555, + "purposes": { + "2": 0 + }, + "specialPurposes": {} + }, + "urls": [ + { + "langId": "en", + "privacy": "https://www.90min.com/privacy", + "legIntClaim": "https://www.90min.com/privacy" + } + ], + "dataDeclaration": [ + 1, + 2, + 3, + 4, + 6, + 7, + 8, + 11 + ], + "deviceStorageDisclosureUrl": "https://disclosures.mmctsvc.com/device-storage.json" + }, + "919": { + "id": 919, + "name": "Livewrapped AB", + "purposes": [ + 1 + ], + "legIntPurposes": [ + 2, + 7, + 10 + ], + "flexiblePurposes": [ + 2, + 7, + 10 + ], + "specialPurposes": [ + 1, + 2 + ], + "features": [], + "specialFeatures": [], + "cookieMaxAgeSeconds": 2592000, + "usesCookies": true, + "cookieRefresh": false, + "usesNonCookieAccess": false, + "dataRetention": { + "stdRetention": 30, + "purposes": {}, + "specialPurposes": {} + }, + "urls": [ + { + "langId": "en", + "privacy": "https://livewrapped.com/privacy-policy", + "legIntClaim": "https://livewrapped.com/privacy-policy" + } + ], + "dataDeclaration": [ + 1, + 2, + 3, + 5, + 7, + 8, + 10, + 11 + ], + "deviceStorageDisclosureUrl": "https://content.lwadm.com/deviceStorageDisclosure.json" + }, + "922": { + "id": 922, + "name": "Amnet GmbH", + "purposes": [ + 1, + 2, + 3, + 4, + 7, + 9, + 10 + ], + "legIntPurposes": [], + "flexiblePurposes": [], + "specialPurposes": [], + "features": [ + 1, + 2, + 3 + ], + "specialFeatures": [ + 1, + 2 + ], + "cookieMaxAgeSeconds": 30758400, + "usesCookies": true, + "cookieRefresh": true, + "usesNonCookieAccess": true, + "dataRetention": { + "stdRetention": 365, + "purposes": {}, + "specialPurposes": {} + }, + "urls": [ + { + "langId": "de", + "privacy": "https://mediaintelligence.de/privacy-policy.do", + "legIntClaim": "https://mediaintelligence.de/privacy-policy.do" + }, + { + "langId": "en", + "privacy": "https://mediaintelligence.de/privacy-policyeng.do", + "legIntClaim": "https://mediaintelligence.de/privacy-policyeng.do" + } + ], + "dataDeclaration": [ + 1, + 2, + 4, + 5, + 6, + 8, + 9, + 11 + ], + "deviceStorageDisclosureUrl": "https://min.easyapi.de/api/tcf/definitions/disclosures" + }, + "931": { + "id": 931, + "name": "Traffective GmbH", + "purposes": [ + 1, + 8 + ], + "legIntPurposes": [], + "flexiblePurposes": [], + "specialPurposes": [ + 2 + ], + "features": [], + "specialFeatures": [], + "cookieMaxAgeSeconds": 365, + "usesCookies": true, + "cookieRefresh": false, + "usesNonCookieAccess": false, + "dataRetention": { + "stdRetention": 30, + "purposes": {}, + "specialPurposes": {} + }, + "urls": [ + { + "langId": "de", + "privacy": "https://www.iubenda.com/privacy-policy/30563919", + "legIntClaim": "https://www.iubenda.com/privacy-policy/30563919/legal" + } + ], + "dataDeclaration": [ + 11 + ], + "deviceStorageDisclosureUrl": "https://cdn.opencmp.net/vendor-device-storage-disclosures.json" + }, + "935": { + "id": 935, + "name": "INIS sp. zo.o.", + "purposes": [ + 1, + 3, + 4, + 5, + 6, + 7, + 8, + 10 + ], + "legIntPurposes": [], + "flexiblePurposes": [ + 7, + 8 + ], + "specialPurposes": [], + "features": [], + "specialFeatures": [], + "cookieMaxAgeSeconds": 31536000, + "usesCookies": true, + "cookieRefresh": true, + "usesNonCookieAccess": true, + "dataRetention": { + "stdRetention": 30, + "purposes": { + "3": 365, + "5": 365, + "10": 365 + }, + "specialPurposes": {} + }, + "urls": [ + { + "langId": "pl", + "privacy": "https://www.inis.pl/polityka-prywatnosci", + "legIntClaim": "https://www.inis.pl/polityka-prywatnosci" + } + ], + "dataDeclaration": [ + 1, + 2, + 7 + ], + "deviceStorageDisclosureUrl": "https://www.inis.pl/tcf/vendor.json" + }, + "938": { + "id": 938, + "name": "dataXtrade GmbH", + "purposes": [ + 1, + 2, + 3, + 4, + 7, + 8, + 9, + 10 + ], + "legIntPurposes": [], + "flexiblePurposes": [ + 2, + 7, + 8 + ], + "specialPurposes": [ + 1, + 2 + ], + "features": [ + 1, + 3 + ], + "specialFeatures": [ + 1 + ], + "overflow": { + "httpGetLimit": 128 + }, + "cookieMaxAgeSeconds": 31536000, + "usesCookies": true, + "cookieRefresh": true, + "usesNonCookieAccess": true, + "dataRetention": { + "stdRetention": 30, + "purposes": {}, + "specialPurposes": { + "1": 365 + } + }, + "urls": [ + { + "langId": "de", + "privacy": "https://dataxtrade.com/de/privacy.html", + "legIntClaim": "https://dataxtrade.com/de/privacy.html" + } + ], + "dataDeclaration": [ + 1, + 2, + 3, + 4, + 6, + 7, + 8, + 9, + 10, + 11 + ], + "deviceStorageDisclosureUrl": "https://tcf.adtech.app/gen/deviceStorageDisclosure/dxt.json" + }, + "940": { + "id": 940, + "name": "Terminus Software Inc.", + "purposes": [], + "legIntPurposes": [ + 7 + ], + "flexiblePurposes": [], + "specialPurposes": [], + "features": [ + 1 + ], + "specialFeatures": [], + "cookieMaxAgeSeconds": 31536000, + "usesCookies": true, + "cookieRefresh": false, + "usesNonCookieAccess": false, + "dataRetention": { + "purposes": { + "7": 4320 + }, + "specialPurposes": {} + }, + "urls": [ + { + "langId": "en", + "privacy": "https://terminus.com/privacy-policy/", + "legIntClaim": "https://terminus.com/privacy-policy/" + } + ], + "dataDeclaration": [ + 1 + ], + "deviceStorageDisclosureUrl": "https://iabdisclosure.terminusplatform.com/deviceStorageDisclosureURL.json" + }, + "941": { + "id": 941, + "name": "ADSOCY", + "purposes": [ + 1, + 2, + 3, + 4, + 5, + 6, + 7, + 8, + 9, + 10, + 11 + ], + "legIntPurposes": [], + "flexiblePurposes": [], + "specialPurposes": [], + "features": [], + "specialFeatures": [], + "cookieMaxAgeSeconds": 25920000, + "usesCookies": true, + "cookieRefresh": true, + "usesNonCookieAccess": true, + "dataRetention": { + "stdRetention": 60, + "purposes": {}, + "specialPurposes": {} + }, + "urls": [ + { + "langId": "es", + "privacy": "https://adsocy.com/politica-de-privacidad-y-aviso-legal/", + "legIntClaim": "https://adsocy.com/politica-de-privacidad-y-aviso-legal/" + } + ], + "dataDeclaration": [ + 1, + 6, + 8, + 11 + ], + "deviceStorageDisclosureUrl": "https://adsocy.com/vendor.json" + }, + "943": { + "id": 943, + "name": "Marfeel Solutions, SL (Compass)", + "purposes": [ + 1, + 5, + 6, + 7, + 8, + 9, + 10 + ], + "legIntPurposes": [], + "flexiblePurposes": [], + "specialPurposes": [], + "features": [ + 2 + ], + "specialFeatures": [], + "cookieMaxAgeSeconds": 15552000, + "usesCookies": true, + "cookieRefresh": false, + "usesNonCookieAccess": true, + "dataRetention": { + "stdRetention": 780, + "purposes": {}, + "specialPurposes": {} + }, + "urls": [ + { + "langId": "en", + "privacy": "https://community.marfeel.com/t/marfeel-saas-privacy-policy/7500" + } + ], + "dataDeclaration": [ + 1, + 2, + 6, + 8, + 11 + ], + "deviceStorageDisclosureUrl": "https://live.mrf.io/statics/marfeel/resources/lib/deviceStorage/compass.json" + }, + "944": { + "id": 944, + "name": "AudienceRun corp", + "purposes": [ + 1, + 3, + 4, + 5, + 6 + ], + "legIntPurposes": [ + 2, + 7, + 8, + 9, + 10 + ], + "flexiblePurposes": [], + "specialPurposes": [ + 1, + 2 + ], + "features": [ + 3 + ], + "specialFeatures": [], + "cookieMaxAgeSeconds": 31536000, + "usesCookies": true, + "cookieRefresh": true, + "usesNonCookieAccess": true, + "dataRetention": { + "stdRetention": 4320, + "purposes": {}, + "specialPurposes": {} + }, + "urls": [ + { + "langId": "en", + "privacy": "https://www.audiencerun.com/privacy-policy", + "legIntClaim": "https://www.audiencerun.com/privacy-policy" + } + ], + "dataDeclaration": [ + 1, + 5, + 7, + 8 + ], + "deviceStorageDisclosureUrl": "https://www.audiencerun.com/tcf.json" + }, + "950": { + "id": 950, + "name": "Stream Eye OOD", + "purposes": [], + "legIntPurposes": [], + "flexiblePurposes": [], + "specialPurposes": [ + 2 + ], + "features": [], + "specialFeatures": [], + "cookieMaxAgeSeconds": null, + "usesCookies": false, + "cookieRefresh": false, + "usesNonCookieAccess": false, + "dataRetention": { + "purposes": {}, + "specialPurposes": { + "2": 0 + } + }, + "urls": [ + { + "langId": "en", + "privacy": "https://app.streameye.com/policy/net", + "legIntClaim": "https://app.streameye.com/policy/net" + } + ], + "dataDeclaration": [ + 1 + ], + "deviceStorageDisclosureUrl": "https://static.streameye.net/iab/dsdu.json" + }, + "952": { + "id": 952, + "name": "ProSiebenSat.1 Digital Data GmbH", + "purposes": [ + 1, + 3, + 4, + 7, + 10 + ], + "legIntPurposes": [], + "flexiblePurposes": [], + "specialPurposes": [], + "features": [ + 2, + 3 + ], + "specialFeatures": [ + 1 + ], + "cookieMaxAgeSeconds": 7776000, + "usesCookies": true, + "cookieRefresh": true, + "usesNonCookieAccess": true, + "dataRetention": { + "stdRetention": 1110, + "purposes": {}, + "specialPurposes": {} + }, + "urls": [ + { + "langId": "de", + "privacy": "https://www.7pass.de/psdd/datenschutzbestimmungen-cdb.html" + } + ], + "dataDeclaration": [ + 1, + 2, + 3, + 4, + 5, + 6, + 7, + 8, + 9, + 10, + 11 + ], + "deviceStorageDisclosureUrl": "https://www.7pass.de/psdd/deviceStorage.json" + }, + "953": { + "id": 953, + "name": "adbalancer Werbeagentur GmbH", + "purposes": [], + "legIntPurposes": [], + "flexiblePurposes": [], + "specialPurposes": [ + 2 + ], + "features": [], + "specialFeatures": [], + "cookieMaxAgeSeconds": null, + "usesCookies": false, + "cookieRefresh": false, + "usesNonCookieAccess": false, + "dataRetention": { + "purposes": {}, + "specialPurposes": { + "2": 0 + } + }, + "urls": [ + { + "langId": "de", + "privacy": "https://www.adbalancer.com/hosting-datenschutzerklaerung", + "legIntClaim": "https://www.adbalancer.com/legitimes-interesse" + } + ], + "dataDeclaration": [ + 8 + ], + "deviceStorageDisclosureUrl": "https://streaming-cdn.ad-balancer.at/deviceStorageDisclosure.json" + }, + "955": { + "id": 955, + "name": "Konodrac S.L.", + "purposes": [ + 1, + 2, + 3, + 4, + 5, + 6, + 7, + 8, + 9, + 10, + 11 + ], + "legIntPurposes": [], + "flexiblePurposes": [], + "specialPurposes": [], + "features": [ + 1, + 2, + 3 + ], + "specialFeatures": [], + "cookieMaxAgeSeconds": 31536000, + "usesCookies": true, + "cookieRefresh": true, + "usesNonCookieAccess": false, + "dataRetention": { + "stdRetention": 730, + "purposes": {}, + "specialPurposes": {} + }, + "urls": [ + { + "langId": "es", + "privacy": "https://konodrac.com/politica-privacidad/" + }, + { + "langId": "en", + "privacy": "https://konodrac.com/privacy-policy/" + } + ], + "dataDeclaration": [ + 1, + 2, + 3, + 4, + 5, + 6, + 7, + 8, + 9, + 10, + 11 + ], + "deviceStorageDisclosureUrl": "https://www.konograma.com/public/device_storage_disclosure.json" + }, + "956": { + "id": 956, + "name": "Avantis Video Ltd", + "purposes": [ + 1, + 2, + 7, + 8, + 10, + 11 + ], + "legIntPurposes": [], + "flexiblePurposes": [], + "specialPurposes": [ + 1, + 2 + ], + "features": [ + 1 + ], + "specialFeatures": [], + "cookieMaxAgeSeconds": 31536000, + "usesCookies": true, + "cookieRefresh": false, + "usesNonCookieAccess": true, + "dataRetention": { + "stdRetention": 400, + "purposes": { + "2": 0, + "11": 0 + }, + "specialPurposes": {} + }, + "urls": [ + { + "langId": "en", + "privacy": "https://www.avantisvideo.com/privacy-policy/", + "legIntClaim": "https://www.avantisvideo.com/privacy-policy/" + } + ], + "dataDeclaration": [ + 1, + 2, + 6, + 11 + ], + "deviceStorageDisclosureUrl": "https://avantisvideo.com/local-storage-disclosure.json" + }, + "966": { + "id": 966, + "name": "socoto gmbh & co. kg", + "purposes": [ + 7 + ], + "legIntPurposes": [], + "flexiblePurposes": [], + "specialPurposes": [], + "features": [], + "specialFeatures": [], + "cookieMaxAgeSeconds": null, + "usesCookies": false, + "cookieRefresh": false, + "usesNonCookieAccess": false, + "dataRetention": { + "purposes": { + "7": 0 + }, + "specialPurposes": {} + }, + "urls": [ + { + "langId": "de", + "privacy": "https://www.socoto.com/datenschutz/" + } + ], + "deviceStorageDisclosureUrl": "https://www.socoto.com/.iab/deviceStorage.json" + }, + "968": { + "id": 968, + "name": "WEMASS MEDIA AUDIENCE SAFE SOLUTIONS, S.L. ", + "purposes": [ + 1, + 3, + 4, + 7, + 10 + ], + "legIntPurposes": [], + "flexiblePurposes": [], + "specialPurposes": [ + 1, + 2 + ], + "features": [ + 2, + 3 + ], + "specialFeatures": [], + "cookieMaxAgeSeconds": 94608000, + "usesCookies": true, + "cookieRefresh": true, + "usesNonCookieAccess": true, + "dataRetention": { + "stdRetention": 365, + "purposes": {}, + "specialPurposes": {} + }, + "urls": [ + { + "langId": "es", + "privacy": "https://wemass.com/privacidad/", + "legIntClaim": "https://wemass.com/privacidad/" + } + ], + "dataDeclaration": [ + 2, + 4, + 8, + 11 + ], + "deviceStorageDisclosureUrl": "https://sellers.wemass.com/deviceStorage.json" + }, + "970": { + "id": 970, + "name": "Frameplay Corporation", + "purposes": [ + 1 + ], + "legIntPurposes": [ + 2, + 7, + 8, + 9, + 10 + ], + "flexiblePurposes": [], + "specialPurposes": [ + 1, + 2 + ], + "features": [ + 1, + 3 + ], + "specialFeatures": [ + 2 + ], + "cookieMaxAgeSeconds": null, + "usesCookies": false, + "cookieRefresh": false, + "usesNonCookieAccess": true, + "dataRetention": { + "stdRetention": 547, + "purposes": {}, + "specialPurposes": {} + }, + "urls": [ + { + "langId": "en", + "privacy": "https://www.frameplay.gg/terms", + "legIntClaim": "https://www.frameplay.gg/terms" + } + ], + "dataDeclaration": [ + 1, + 2, + 3, + 4, + 8 + ], + "deviceStorageDisclosureUrl": "https://www.frameplay.gg/deviceStorageDisclosure.json" + }, + "978": { + "id": 978, + "name": "ARKHEUS", + "purposes": [ + 1, + 2, + 3, + 4, + 7 + ], + "legIntPurposes": [], + "flexiblePurposes": [], + "specialPurposes": [], + "features": [], + "specialFeatures": [ + 1 + ], + "cookieMaxAgeSeconds": 2592000, + "usesCookies": true, + "cookieRefresh": false, + "usesNonCookieAccess": false, + "dataRetention": { + "stdRetention": 30, + "purposes": {}, + "specialPurposes": {} + }, + "urls": [ + { + "langId": "fr", + "privacy": "https://www.arkheus.fr/conditions-d-utilisation/" + } + ], + "dataDeclaration": [ + 1, + 2, + 3, + 5, + 6, + 7, + 8, + 10, + 11 + ], + "deviceStorageDisclosureUrl": "https://www.arkheus.fr/tcf.json" + }, + "982": { + "id": 982, + "name": "Netpoint Media GmbH", + "purposes": [ + 1, + 2 + ], + "legIntPurposes": [], + "flexiblePurposes": [], + "specialPurposes": [], + "features": [], + "specialFeatures": [], + "cookieMaxAgeSeconds": 3600, + "usesCookies": true, + "cookieRefresh": false, + "usesNonCookieAccess": true, + "dataRetention": { + "purposes": { + "2": 30 + }, + "specialPurposes": {} + }, + "urls": [ + { + "langId": "de", + "privacy": "https://www.netpoint-media.de/technik/datenschutz" + } + ], + "dataDeclaration": [ + 6 + ], + "deviceStorageDisclosureUrl": "https://cdn.netpoint-media.de/iab/deviceStorage.json" + }, + "987": { + "id": 987, + "name": "Media16 ltd", + "purposes": [ + 1, + 7 + ], + "legIntPurposes": [], + "flexiblePurposes": [], + "specialPurposes": [], + "features": [ + 1, + 3 + ], + "specialFeatures": [ + 1 + ], + "overflow": { + "httpGetLimit": 32 + }, + "cookieMaxAgeSeconds": null, + "usesCookies": false, + "cookieRefresh": false, + "usesNonCookieAccess": true, + "dataRetention": { + "purposes": { + "7": 30 + }, + "specialPurposes": {} + }, + "urls": [ + { + "langId": "en", + "privacy": "https://media16.tv/privacy-policy/" + } + ], + "dataDeclaration": [ + 1 + ], + "deviceStorageDisclosureUrl": "https://media16.tv/disclosure.json" + }, + "991": { + "id": 991, + "name": "iProspect GmbH", + "purposes": [ + 1, + 2, + 3, + 4, + 7 + ], + "legIntPurposes": [], + "flexiblePurposes": [], + "specialPurposes": [], + "features": [ + 3 + ], + "specialFeatures": [ + 2 + ], + "cookieMaxAgeSeconds": 30758400, + "usesCookies": true, + "cookieRefresh": true, + "usesNonCookieAccess": true, + "dataRetention": { + "stdRetention": 365, + "purposes": {}, + "specialPurposes": {} + }, + "urls": [ + { + "langId": "en", + "privacy": "https://inetpro.io/privacy-policyeng.do", + "legIntClaim": "https://inetpro.io/privacy-policyeng.do" + }, + { + "langId": "de", + "privacy": "https://inetpro.io/privacy-policy.do", + "legIntClaim": "https://inetpro.io/privacy-policy.do" + } + ], + "dataDeclaration": [ + 1, + 2, + 4, + 6, + 11 + ], + "deviceStorageDisclosureUrl": "https://n2.min.emcustomers.de/api/tcf/definitions/disclosures" + }, + "993": { + "id": 993, + "name": "QUARTER MEDIA GmbH", + "purposes": [ + 1, + 2, + 3, + 7, + 8, + 10 + ], + "legIntPurposes": [], + "flexiblePurposes": [], + "specialPurposes": [], + "features": [], + "specialFeatures": [], + "cookieMaxAgeSeconds": 90, + "usesCookies": true, + "cookieRefresh": false, + "usesNonCookieAccess": false, + "dataRetention": { + "stdRetention": 90, + "purposes": {}, + "specialPurposes": {} + }, + "urls": [ + { + "langId": "de", + "privacy": "https://quartermedia.de/daten/" + } + ], + "dataDeclaration": [ + 1, + 2, + 3, + 11 + ], + "deviceStorageDisclosureUrl": "https://cdn.quartermedia-ad-service.net/prebid/device-storage.json" + }, + "994": { + "id": 994, + "name": "Leadoo Marketing Technologies Ltd", + "purposes": [ + 3, + 4, + 5, + 6, + 9 + ], + "legIntPurposes": [ + 7, + 8, + 10 + ], + "flexiblePurposes": [ + 9 + ], + "specialPurposes": [ + 1, + 2 + ], + "features": [ + 1, + 3 + ], + "specialFeatures": [], + "cookieMaxAgeSeconds": null, + "usesCookies": false, + "cookieRefresh": false, + "usesNonCookieAccess": true, + "dataRetention": { + "stdRetention": 1825, + "purposes": {}, + "specialPurposes": {} + }, + "urls": [ + { + "langId": "en", + "privacy": "https://leadoo.com/privacy-policy/", + "legIntClaim": "https://leadoo.com/privacy-policy/" + } + ], + "dataDeclaration": [ + 2, + 3, + 4, + 5, + 6, + 7, + 10, + 11 + ], + "deviceStorageDisclosureUrl": "https://res.leadoo.com/tcf/deviceStorage.json" + }, + "1001": { + "id": 1001, + "name": "wetter.com GmbH", + "purposes": [ + 1, + 3, + 4, + 5, + 6 + ], + "legIntPurposes": [ + 2, + 7, + 8, + 9, + 10, + 11 + ], + "flexiblePurposes": [ + 2, + 7, + 8, + 9, + 10, + 11 + ], + "specialPurposes": [ + 1, + 2 + ], + "features": [ + 1, + 2, + 3 + ], + "specialFeatures": [ + 1 + ], + "cookieMaxAgeSeconds": null, + "usesCookies": false, + "cookieRefresh": false, + "usesNonCookieAccess": true, + "dataRetention": { + "stdRetention": 400, + "purposes": {}, + "specialPurposes": {} + }, + "urls": [ + { + "langId": "de", + "privacy": "https://www.wetter.com/internal/news/datenschutzhinweise_aid_607698849b8ecf79e21584fa.html", + "legIntClaim": "https://www.wetter.com/internal/news/datenschutzhinweise_aid_607698849b8ecf79e21584fa.html" + } + ], + "dataDeclaration": [ + 1, + 2, + 3, + 6, + 8, + 9, + 11 + ], + "deviceStorageDisclosureUrl": "https://cs3.wettercomassets.com/iab/disclosure.json" + }, + "1002": { + "id": 1002, + "name": "Extreme Reach, Inc", + "purposes": [ + 1, + 2, + 7, + 10 + ], + "legIntPurposes": [], + "flexiblePurposes": [ + 7, + 10 + ], + "specialPurposes": [], + "features": [ + 2 + ], + "specialFeatures": [], + "cookieMaxAgeSeconds": 15552000, + "usesCookies": true, + "cookieRefresh": true, + "usesNonCookieAccess": false, + "dataRetention": { + "stdRetention": 730, + "purposes": {}, + "specialPurposes": {} + }, + "urls": [ + { + "langId": "en", + "privacy": "https://extremereach.com/privacy-policies/", + "legIntClaim": "https://NotApplicableConsetOnly" + } + ], + "dataDeclaration": [ + 1, + 2, + 3, + 6, + 8, + 11 + ], + "deviceStorageDisclosureUrl": "https://beacons.extremereach.io/gdpr-tcfv2.json" + }, + "1015": { + "id": 1015, + "name": "Samsung Ads", + "purposes": [ + 1, + 3, + 4 + ], + "legIntPurposes": [ + 2, + 7, + 9, + 10 + ], + "flexiblePurposes": [], + "specialPurposes": [ + 1, + 2 + ], + "features": [ + 1, + 2, + 3 + ], + "specialFeatures": [ + 1 + ], + "cookieMaxAgeSeconds": null, + "usesCookies": false, + "cookieRefresh": false, + "usesNonCookieAccess": true, + "dataRetention": { + "stdRetention": 730, + "purposes": {}, + "specialPurposes": {} + }, + "urls": [ + { + "langId": "en", + "privacy": "https://policy.samsungrs.com/consent/eu/privacy_policy_en.html", + "legIntClaim": "https://policy.samsungrs.com/consent/eu/privacy_policy_en.html#use-information" + }, + { + "langId": "de", + "privacy": "https://policy.samsungrs.com/consent/eu/v1.0.0/privacy_policy_de.html", + "legIntClaim": "https://policy.samsungrs.com/consent/eu/v1.0.0/privacy_policy_de.html#use-information" + }, + { + "langId": "it", + "privacy": "https://policy.samsungrs.com/consent/eu/v1.0.0/privacy_policy_it.html", + "legIntClaim": "https://policy.samsungrs.com/consent/eu/v1.0.0/privacy_policy_it.html#use-information" + }, + { + "langId": "fr", + "privacy": "https://policy.samsungrs.com/consent/eu/v1.0.0/privacy_policy_fr.html", + "legIntClaim": "https://policy.samsungrs.com/consent/eu/v1.0.0/privacy_policy_fr.html#use-information" + }, + { + "langId": "es", + "privacy": "https://policy.samsungrs.com/consent/eu/v1.0.0/privacy_policy_es.html", + "legIntClaim": "https://policy.samsungrs.com/consent/eu/v1.0.0/privacy_policy_es.html#use-information" + } + ], + "dataDeclaration": [ + 1, + 2, + 3, + 6, + 7, + 8, + 10, + 11 + ], + "deviceStorageDisclosureUrl": "https://policy.samsungrs.com/consent/eu/deviceStorageDisclosure.json" + }, + "1020": { + "id": 1020, + "name": "Baidu USA", + "purposes": [ + 1, + 2, + 3, + 4, + 7, + 9, + 10 + ], + "legIntPurposes": [], + "flexiblePurposes": [], + "specialPurposes": [ + 1, + 2 + ], + "features": [ + 1, + 3 + ], + "specialFeatures": [], + "cookieMaxAgeSeconds": 31622400, + "usesCookies": true, + "cookieRefresh": false, + "usesNonCookieAccess": false, + "dataRetention": { + "stdRetention": 180, + "purposes": {}, + "specialPurposes": {} + }, + "urls": [ + { + "langId": "en", + "privacy": "https://www.mediago.io/policy/", + "legIntClaim": "https://www.mediago.io/policy/" + } + ], + "dataDeclaration": [ + 6 + ], + "deviceStorageDisclosureUrl": "https://cdn.mediago.io/js/tcf.json" + }, + "1027": { + "id": 1027, + "name": "Exit Bee Limited", + "purposes": [ + 1, + 2, + 3, + 4, + 5, + 7, + 10 + ], + "legIntPurposes": [], + "flexiblePurposes": [], + "specialPurposes": [], + "features": [], + "specialFeatures": [], + "overflow": { + "httpGetLimit": 128 + }, + "cookieMaxAgeSeconds": 31536000, + "usesCookies": true, + "cookieRefresh": false, + "usesNonCookieAccess": true, + "dataRetention": { + "stdRetention": 365, + "purposes": {}, + "specialPurposes": {} + }, + "urls": [ + { + "langId": "en", + "privacy": "https://www.exitbee.com/privacy/" + } + ], + "dataDeclaration": [ + 1, + 2, + 6, + 7, + 8, + 11 + ], + "deviceStorageDisclosureUrl": "https://cdn.exitbee.com/DeviceStorageDisclosure.json" + }, + "1028": { + "id": 1028, + "name": "Sparteo", + "purposes": [ + 1, + 3, + 4, + 5, + 6 + ], + "legIntPurposes": [ + 2, + 7, + 8, + 9, + 10, + 11 + ], + "flexiblePurposes": [], + "specialPurposes": [ + 1, + 2 + ], + "features": [ + 3 + ], + "specialFeatures": [], + "cookieMaxAgeSeconds": 31536000, + "usesCookies": true, + "cookieRefresh": true, + "usesNonCookieAccess": true, + "dataRetention": { + "stdRetention": 365, + "purposes": {}, + "specialPurposes": {} + }, + "urls": [ + { + "langId": "en", + "privacy": "https://www.bricks-co.com/confidentialite", + "legIntClaim": "https://www.bricksfounders.com/privacy-policy" + } + ], + "dataDeclaration": [ + 1, + 2, + 6, + 8, + 10, + 11 + ], + "deviceStorageDisclosureUrl": "https://bid.bricks-co.com/.well-known/deviceStorage.json" + }, + "1032": { + "id": 1032, + "name": "Project Agora Ltd", + "purposes": [ + 1, + 7, + 8 + ], + "legIntPurposes": [], + "flexiblePurposes": [], + "specialPurposes": [ + 1 + ], + "features": [ + 3 + ], + "specialFeatures": [], + "cookieMaxAgeSeconds": null, + "usesCookies": false, + "cookieRefresh": false, + "usesNonCookieAccess": true, + "dataRetention": { + "stdRetention": 0, + "purposes": {}, + "specialPurposes": {} + }, + "urls": [ + { + "langId": "en", + "privacy": "https://projectagora.com/privacy-policy/", + "legIntClaim": "https://projectagora.com/privacy-policy/" + } + ], + "dataDeclaration": [ + 2, + 6, + 11 + ], + "deviceStorageDisclosureUrl": "https://projectagora.net/1032_deviceStorageDisclosure.json" + }, + "1035": { + "id": 1035, + "name": "Allegro sp. z o.o.", + "purposes": [ + 1, + 2, + 3, + 4, + 7, + 9, + 10 + ], + "legIntPurposes": [], + "flexiblePurposes": [], + "specialPurposes": [], + "features": [ + 2, + 3 + ], + "specialFeatures": [], + "cookieMaxAgeSeconds": 31536000, + "usesCookies": true, + "cookieRefresh": true, + "usesNonCookieAccess": true, + "dataRetention": { + "stdRetention": 4320, + "purposes": { + "3": 180 + }, + "specialPurposes": {} + }, + "urls": [ + { + "langId": "pl", + "privacy": "https://allegro.pl/terms/attachment/5" + }, + { + "langId": "cs", + "privacy": "https://allegro.cz/podminky/priloha/5" + } + ], + "dataDeclaration": [ + 1, + 2, + 3, + 4, + 5, + 6, + 7, + 8, + 9, + 10, + 11 + ], + "deviceStorageDisclosureUrl": "https://naanalle.pl/iab/deviceStorage.json" + }, + "1036": { + "id": 1036, + "name": "VIADS ADVERTISING S.L.", + "purposes": [ + 1, + 3, + 4, + 7, + 9 + ], + "legIntPurposes": [ + 2, + 10 + ], + "flexiblePurposes": [], + "specialPurposes": [ + 1, + 2 + ], + "features": [ + 3 + ], + "specialFeatures": [ + 1 + ], + "cookieMaxAgeSeconds": 2592000, + "usesCookies": true, + "cookieRefresh": false, + "usesNonCookieAccess": true, + "dataRetention": { + "stdRetention": 30, + "purposes": {}, + "specialPurposes": {} + }, + "urls": [ + { + "langId": "en", + "privacy": "https://viads.com/privacy-policy", + "legIntClaim": "https://viads.com/privacy-policy" + } + ], + "dataDeclaration": [ + 1 + ], + "deviceStorageDisclosureUrl": "https://viads.com/deviceStorage.json" + }, + "1041": { + "id": 1041, + "name": "Sqreem Technologies Private Limited", + "purposes": [], + "legIntPurposes": [ + 2, + 7, + 9 + ], + "flexiblePurposes": [], + "specialPurposes": [ + 1, + 2 + ], + "features": [ + 3 + ], + "specialFeatures": [], + "cookieMaxAgeSeconds": null, + "usesCookies": false, + "cookieRefresh": false, + "usesNonCookieAccess": false, + "dataRetention": { + "stdRetention": 180, + "purposes": {}, + "specialPurposes": {} + }, + "urls": [ + { + "langId": "en", + "privacy": "https://sqreemtech.com/privacy/", + "legIntClaim": "https://sqreemtech.com/privacy/" + } + ], + "dataDeclaration": [ + 1, + 3 + ], + "deviceStorageDisclosureUrl": "https://ttd-misc-public-assets.s3.us-west-2.amazonaws.com/deviceStorageDisclosureURL.json" + }, + "1044": { + "id": 1044, + "name": "TMT Digital Inc", + "purposes": [], + "legIntPurposes": [], + "flexiblePurposes": [], + "specialPurposes": [ + 1 + ], + "features": [], + "specialFeatures": [], + "cookieMaxAgeSeconds": null, + "usesCookies": false, + "cookieRefresh": false, + "usesNonCookieAccess": false, + "dataRetention": { + "purposes": {}, + "specialPurposes": { + "1": 0 + } + }, + "urls": [ + { + "langId": "en", + "privacy": "https://mediatrust.com/privacy-statement/", + "legIntClaim": "https://mediatrust.com/privacy-statement/" + } + ], + "dataDeclaration": [ + 1 + ], + "deviceStorageDisclosureUrl": "https://webcontentassessor.com/tcf.json" + }, + "1048": { + "id": 1048, + "name": "Questpass Sp. z o.o.", + "purposes": [ + 1, + 3, + 4 + ], + "legIntPurposes": [ + 2, + 7, + 8, + 9, + 10 + ], + "flexiblePurposes": [ + 2, + 7, + 8, + 9, + 10 + ], + "specialPurposes": [ + 1, + 2 + ], + "features": [ + 3 + ], + "specialFeatures": [], + "cookieMaxAgeSeconds": null, + "usesCookies": false, + "cookieRefresh": false, + "usesNonCookieAccess": true, + "dataRetention": { + "stdRetention": 4320, + "purposes": {}, + "specialPurposes": {} + }, + "urls": [ + { + "langId": "pl", + "privacy": "https://questpass.pl/pl/regulaminy/polityka-prywatnosci/", + "legIntClaim": "https://questpass.pl/pl/regulaminy/polityka-prywatnosci/" + } + ], + "dataDeclaration": [ + 1, + 2, + 6, + 10, + 11 + ], + "deviceStorageDisclosureUrl": "https://cdn.dqst.pl/static/prod/consents/tcf_disclosures.json" + }, + "1050": { + "id": 1050, + "name": "Hurra Communications GmbH", + "purposes": [ + 1, + 2, + 4, + 7 + ], + "legIntPurposes": [], + "flexiblePurposes": [ + 2, + 7 + ], + "specialPurposes": [ + 1 + ], + "features": [ + 2 + ], + "specialFeatures": [ + 1 + ], + "cookieMaxAgeSeconds": 31536500, + "usesCookies": true, + "cookieRefresh": true, + "usesNonCookieAccess": false, + "dataRetention": { + "stdRetention": 396, + "purposes": {}, + "specialPurposes": {} + }, + "urls": [ + { + "langId": "en", + "privacy": "https://privacy.hurra.com/tcf/", + "legIntClaim": "https://privacy.hurra.com/tcf/" + } + ], + "dataDeclaration": [ + 1, + 2, + 3, + 5, + 8, + 9 + ], + "deviceStorageDisclosureUrl": "https://privacy.hurra.com/tcf/disclosures.json" + }, + "1051": { + "id": 1051, + "name": "Samoukale Enterprises Limited dba ADEX", + "purposes": [ + 1 + ], + "legIntPurposes": [ + 7, + 8, + 10 + ], + "flexiblePurposes": [], + "specialPurposes": [ + 1 + ], + "features": [ + 2, + 3 + ], + "specialFeatures": [ + 2 + ], + "cookieMaxAgeSeconds": 63072000, + "usesCookies": true, + "cookieRefresh": true, + "usesNonCookieAccess": true, + "dataRetention": { + "stdRetention": 180, + "purposes": {}, + "specialPurposes": {} + }, + "urls": [ + { + "langId": "en", + "privacy": "https://adex.com/privacy", + "legIntClaim": "https://adex.com/privacy" + } + ], + "dataDeclaration": [ + 1, + 2, + 4, + 5, + 7, + 11 + ], + "deviceStorageDisclosureUrl": "https://adex.com/gdpr.json" + }, + "1060": { + "id": 1060, + "name": "Next Millennium Media INC", + "purposes": [ + 1, + 2, + 3, + 4, + 7 + ], + "legIntPurposes": [], + "flexiblePurposes": [], + "specialPurposes": [ + 2 + ], + "features": [ + 1, + 3 + ], + "specialFeatures": [], + "overflow": { + "httpGetLimit": 128 + }, + "cookieMaxAgeSeconds": 36000, + "usesCookies": true, + "cookieRefresh": false, + "usesNonCookieAccess": false, + "dataRetention": { + "stdRetention": 7, + "purposes": {}, + "specialPurposes": {} + }, + "urls": [ + { + "langId": "en", + "privacy": "https://nextmillennium.io/privacy-policy/", + "legIntClaim": "https://nextmillennium.io/privacy-policy/" + } + ], + "dataDeclaration": [ + 3, + 4, + 6 + ], + "deviceStorageDisclosureUrl": "https://nextmillennium.io/deviceStorage.json" + }, + "1064": { + "id": 1064, + "name": "optimise-it GmbH", + "purposes": [ + 1 + ], + "legIntPurposes": [ + 8 + ], + "flexiblePurposes": [ + 8 + ], + "specialPurposes": [], + "features": [], + "specialFeatures": [], + "cookieMaxAgeSeconds": 0, + "usesCookies": true, + "cookieRefresh": false, + "usesNonCookieAccess": true, + "dataRetention": { + "purposes": { + "8": 13 + }, + "specialPurposes": {} + }, + "urls": [ + { + "langId": "de", + "privacy": "https://optimise-it.de/datenschutz", + "legIntClaim": "https://optimise-it.de/datenschutz" + } + ], + "dataDeclaration": [ + 1, + 2, + 7 + ], + "deviceStorageDisclosureUrl": "https://optimise-it.de/.well-known/deviceStorage.json" + }, + "1067": { + "id": 1067, + "name": "Arpeely Ltd.", + "purposes": [ + 1, + 3, + 4 + ], + "legIntPurposes": [ + 2, + 7, + 8, + 10 + ], + "flexiblePurposes": [], + "specialPurposes": [ + 1, + 2 + ], + "features": [], + "specialFeatures": [], + "cookieMaxAgeSeconds": 7776000, + "usesCookies": true, + "cookieRefresh": true, + "usesNonCookieAccess": false, + "dataRetention": { + "stdRetention": 540, + "purposes": {}, + "specialPurposes": {} + }, + "urls": [ + { + "langId": "en", + "privacy": "https://www.arpeely.com/privacy", + "legIntClaim": "https://www.arpeely.com/privacy" + } + ], + "dataDeclaration": [ + 1 + ], + "deviceStorageDisclosureUrl": "https://cdn.rtbrain.app/deviceStorageDisclosureUrl.json" + }, + "1069": { + "id": 1069, + "name": "BCOVERY SAS", + "purposes": [ + 1, + 3, + 4 + ], + "legIntPurposes": [ + 2, + 7, + 8, + 10 + ], + "flexiblePurposes": [ + 2, + 7, + 8, + 10 + ], + "specialPurposes": [ + 1, + 2 + ], + "features": [], + "specialFeatures": [ + 1 + ], + "cookieMaxAgeSeconds": null, + "usesCookies": false, + "cookieRefresh": false, + "usesNonCookieAccess": true, + "dataRetention": { + "stdRetention": 90, + "purposes": { + "10": 365 + }, + "specialPurposes": {} + }, + "urls": [ + { + "langId": "en", + "privacy": "https://www.bcovery.com/politique-de-confidentialite.html", + "legIntClaim": "https://www.bcovery.com/legitimate-interest-claim.html" + } + ], + "dataDeclaration": [ + 1, + 2, + 6, + 8, + 9, + 11 + ], + "deviceStorageDisclosureUrl": "https://www.bcovery.com/dsd-bcovery.json" + }, + "1070": { + "id": 1070, + "name": "Playhill Limited", + "purposes": [ + 1 + ], + "legIntPurposes": [ + 2 + ], + "flexiblePurposes": [ + 2 + ], + "specialPurposes": [ + 1, + 2 + ], + "features": [ + 3 + ], + "specialFeatures": [ + 2 + ], + "cookieMaxAgeSeconds": 2592000, + "usesCookies": true, + "cookieRefresh": true, + "usesNonCookieAccess": false, + "dataRetention": { + "stdRetention": 30, + "purposes": {}, + "specialPurposes": {} + }, + "urls": [ + { + "langId": "en", + "privacy": "https://playhill.com/privacy", + "legIntClaim": "https://playhill.com/privacy" + } + ], + "dataDeclaration": [ + 1, + 2 + ], + "deviceStorageDisclosureUrl": "https://playhill.com/iab.json" + }, + "1072": { + "id": 1072, + "name": "Adrino Mobile Sp. z o.o.", + "purposes": [ + 1, + 2, + 3, + 4, + 5, + 6, + 7, + 8, + 9, + 10, + 11 + ], + "legIntPurposes": [], + "flexiblePurposes": [], + "specialPurposes": [], + "features": [ + 1, + 2, + 3 + ], + "specialFeatures": [ + 1, + 2 + ], + "cookieMaxAgeSeconds": 31536000, + "usesCookies": true, + "cookieRefresh": true, + "usesNonCookieAccess": false, + "dataRetention": { + "stdRetention": 360, + "purposes": {}, + "specialPurposes": {} + }, + "urls": [ + { + "langId": "pl", + "privacy": "https://adrino.pl/wp-content/uploads/2021/01/POLITYKA-PRYWATNOS%CC%81CI-Adrino-Mobile.pdf" + } + ], + "dataDeclaration": [ + 1, + 8 + ], + "deviceStorageDisclosureUrl": "https://cdn.adrino.cloud/iab/gvl.json" + }, + "1080": { + "id": 1080, + "name": "CITISERVI EUROPE, S.L.", + "purposes": [ + 1, + 2, + 3, + 4, + 5, + 6, + 7, + 8, + 9, + 10, + 11 + ], + "legIntPurposes": [], + "flexiblePurposes": [ + 2, + 7, + 8, + 10 + ], + "specialPurposes": [ + 1, + 2 + ], + "features": [ + 1, + 2, + 3 + ], + "specialFeatures": [ + 2 + ], + "cookieMaxAgeSeconds": 5000000, + "usesCookies": true, + "cookieRefresh": true, + "usesNonCookieAccess": true, + "dataRetention": { + "stdRetention": 365, + "purposes": {}, + "specialPurposes": {} + }, + "urls": [ + { + "langId": "es", + "privacy": "https://www.citiservimedia.com/politica-de-privacidad-plataforma-citiservimedia/", + "legIntClaim": "https://www.citiservimedia.com/politica-de-privacidad-plataforma-citiservimedia/#legitimate-interest" + } + ], + "dataDeclaration": [ + 2, + 3, + 4, + 5, + 7, + 8, + 10, + 11 + ], + "deviceStorageDisclosureUrl": "https://csm.citiservi.es/static/device-storage-disclosure.json" + }, + "1081": { + "id": 1081, + "name": "C Wire AG", + "purposes": [ + 1 + ], + "legIntPurposes": [ + 2, + 7, + 10 + ], + "flexiblePurposes": [ + 2, + 7, + 10 + ], + "specialPurposes": [ + 1, + 2 + ], + "features": [], + "specialFeatures": [], + "cookieMaxAgeSeconds": null, + "usesCookies": false, + "cookieRefresh": false, + "usesNonCookieAccess": true, + "dataRetention": { + "stdRetention": 365, + "purposes": {}, + "specialPurposes": {} + }, + "urls": [ + { + "langId": "en", + "privacy": "https://www.cwire.com/privacy-policy", + "legIntClaim": "https://www.cwire.com/privacy-policy" + } + ], + "dataDeclaration": [ + 1, + 2, + 6, + 8, + 11 + ], + "deviceStorageDisclosureUrl": "https://cdn.cwi.re/artifacts/iab/iab.json" + }, + "1085": { + "id": 1085, + "name": "Njuice AB", + "purposes": [ + 1, + 3, + 4, + 5, + 6 + ], + "legIntPurposes": [ + 2, + 7, + 8, + 9, + 10 + ], + "flexiblePurposes": [ + 2, + 7, + 8, + 9, + 10 + ], + "specialPurposes": [ + 1, + 2 + ], + "features": [ + 3 + ], + "specialFeatures": [], + "cookieMaxAgeSeconds": 34560000, + "usesCookies": true, + "cookieRefresh": true, + "usesNonCookieAccess": true, + "dataRetention": { + "stdRetention": 400, + "purposes": {}, + "specialPurposes": {} + }, + "urls": [ + { + "langId": "en", + "privacy": "https://squidapp.co/en/privacy-policy.php", + "legIntClaim": "https://squidapp.co/en/privacy-policy.php" + } + ], + "dataDeclaration": [ + 1, + 2, + 3, + 6, + 8, + 11 + ], + "deviceStorageDisclosureUrl": "https://squid-tcf.s3.eu-central-1.amazonaws.com/disclosure.json" + }, + "1087": { + "id": 1087, + "name": "CASTOOLA D.O.O.", + "purposes": [ + 1, + 3, + 4, + 5, + 6, + 7, + 8, + 9, + 10 + ], + "legIntPurposes": [ + 2 + ], + "flexiblePurposes": [ + 2 + ], + "specialPurposes": [ + 1, + 2 + ], + "features": [ + 1, + 2, + 3 + ], + "specialFeatures": [ + 1, + 2 + ], + "cookieMaxAgeSeconds": 31536000, + "usesCookies": true, + "cookieRefresh": true, + "usesNonCookieAccess": true, + "dataRetention": { + "stdRetention": 365, + "purposes": {}, + "specialPurposes": {} + }, + "urls": [ + { + "langId": "en", + "privacy": "https://castoola.com/wp-content/uploads/2022/01/castoola_pp_06.01.2022.pdf", + "legIntClaim": "https://castoola.com/wp-content/uploads/2022/01/castoola_pp_06.01.2022.pdf" + } + ], + "dataDeclaration": [ + 1, + 2, + 6, + 7, + 8, + 9, + 10, + 11 + ], + "deviceStorageDisclosureUrl": "https://privacy.castoola.tv/deviceStorage.json" + }, + "1089": { + "id": 1089, + "name": "Teavaro", + "purposes": [ + 1, + 2, + 3, + 4, + 5, + 6, + 7, + 8, + 9, + 10, + 11 + ], + "legIntPurposes": [], + "flexiblePurposes": [], + "specialPurposes": [], + "features": [ + 1, + 2, + 3 + ], + "specialFeatures": [], + "cookieMaxAgeSeconds": 7776000, + "usesCookies": true, + "cookieRefresh": true, + "usesNonCookieAccess": true, + "dataRetention": { + "stdRetention": 120, + "purposes": {}, + "specialPurposes": {} + }, + "urls": [ + { + "langId": "en", + "privacy": "https://www.teavaro.com/privacy-policy/" + }, + { + "langId": "de", + "privacy": "https://teavaro.com/de/datenschutz-bestimmungen/" + }, + { + "langId": "es", + "privacy": "https://teavaro.com/es/politica-de-privacidad/" + } + ], + "dataDeclaration": [ + 1, + 2, + 8, + 11 + ], + "deviceStorageDisclosureUrl": "https://service.tvtestenv1.net/utiq/prebid/deviceStorage.json" + }, + "1090": { + "id": 1090, + "name": "Score Media Group GmbH & Co. KG", + "purposes": [ + 1, + 2, + 3, + 4, + 5, + 6, + 7, + 8, + 9, + 10, + 11 + ], + "legIntPurposes": [], + "flexiblePurposes": [ + 2, + 7, + 8, + 9, + 10, + 11 + ], + "specialPurposes": [ + 1, + 2 + ], + "features": [ + 2, + 3 + ], + "specialFeatures": [], + "overflow": { + "httpGetLimit": 128 + }, + "cookieMaxAgeSeconds": 7776000, + "usesCookies": true, + "cookieRefresh": true, + "usesNonCookieAccess": false, + "dataRetention": { + "stdRetention": 90, + "purposes": {}, + "specialPurposes": {} + }, + "urls": [ + { + "langId": "de", + "privacy": "https://score-media.de/datenschutzerklaerung/", + "legIntClaim": "https://score-media.de/datenschutzerklaerung/" + } + ], + "dataDeclaration": [ + 1, + 2, + 3, + 4, + 5, + 6, + 7, + 8, + 10, + 11 + ], + "deviceStorageDisclosureUrl": "https://ad.tag.score-media.de/privacy/tcf/deviceStorage/93a705a5f5d52cf1.json" + }, + "1091": { + "id": 1091, + "name": "Octave IP Limited", + "purposes": [ + 1, + 2, + 3, + 4, + 7, + 9, + 10 + ], + "legIntPurposes": [], + "flexiblePurposes": [], + "specialPurposes": [], + "features": [ + 2, + 3 + ], + "specialFeatures": [ + 1 + ], + "cookieMaxAgeSeconds": 34190000, + "usesCookies": true, + "cookieRefresh": true, + "usesNonCookieAccess": true, + "dataRetention": { + "stdRetention": 90, + "purposes": {}, + "specialPurposes": {} + }, + "urls": [ + { + "langId": "en", + "privacy": "https://octaveip.com/policy/" + } + ], + "dataDeclaration": [ + 1, + 2, + 3, + 5, + 6, + 7, + 8, + 9, + 10, + 11 + ], + "deviceStorageDisclosureUrl": "https://octaveip.com/deviceStorage.json" + }, + "1094": { + "id": 1094, + "name": "ADMAX", + "purposes": [ + 1 + ], + "legIntPurposes": [], + "flexiblePurposes": [], + "specialPurposes": [ + 1, + 2 + ], + "features": [], + "specialFeatures": [ + 1 + ], + "cookieMaxAgeSeconds": null, + "usesCookies": false, + "cookieRefresh": false, + "usesNonCookieAccess": true, + "dataRetention": { + "stdRetention": 0, + "purposes": {}, + "specialPurposes": {} + }, + "urls": [ + { + "langId": "en", + "privacy": "https://admaxmedia.io/privacy-policy/", + "legIntClaim": "https://admaxmedia.io/privacy-policy/" + }, + { + "langId": "fr", + "privacy": "https://admaxmedia.io/privacy-policy-fr/", + "legIntClaim": "https://admaxmedia.io/privacy-policy-fr/" + } + ], + "dataDeclaration": [ + 1, + 2, + 3, + 8, + 9, + 11 + ], + "deviceStorageDisclosureUrl": "https://cdn.admaxmedia.io/deviceStorage.json" + }, + "1100": { + "id": 1100, + "name": "Relevant Digital Oy", + "purposes": [ + 1 + ], + "legIntPurposes": [], + "flexiblePurposes": [], + "specialPurposes": [], + "features": [], + "specialFeatures": [], + "cookieMaxAgeSeconds": 7776000, + "usesCookies": true, + "cookieRefresh": true, + "usesNonCookieAccess": false, + "dataRetention": { + "purposes": {}, + "specialPurposes": {} + }, + "urls": [ + { + "langId": "en", + "privacy": "https://www.relevant-digital.com/privacy-policy" + } + ], + "dataDeclaration": [ + 1 + ], + "deviceStorageDisclosureUrl": "https://cdn.relevant-digital.com/resources/deviceStorage.json" + }, + "1101": { + "id": 1101, + "name": "PIA Advertising GmbH", + "purposes": [ + 1, + 2, + 3, + 4, + 5, + 6, + 7, + 8, + 9, + 10, + 11 + ], + "legIntPurposes": [], + "flexiblePurposes": [], + "specialPurposes": [], + "features": [ + 1, + 2, + 3 + ], + "specialFeatures": [ + 1 + ], + "cookieMaxAgeSeconds": 7776000, + "usesCookies": true, + "cookieRefresh": true, + "usesNonCookieAccess": false, + "dataRetention": { + "stdRetention": 365, + "purposes": {}, + "specialPurposes": {} + }, + "urls": [ + { + "langId": "de", + "privacy": "https://www.performance-advertising.de/datenschutz/" + } + ], + "dataDeclaration": [ + 1, + 2, + 3, + 4, + 5, + 6, + 7, + 8, + 9, + 10, + 11 + ], + "deviceStorageDisclosureUrl": "https://imagesrv.adition.com/banners/268/xml/cm/ts/tcf/deviceStorage.json" + }, + "1104": { + "id": 1104, + "name": "Covatic Ltd", + "purposes": [ + 1, + 2, + 3, + 4, + 8, + 9 + ], + "legIntPurposes": [], + "flexiblePurposes": [], + "specialPurposes": [], + "features": [], + "specialFeatures": [ + 1 + ], + "cookieMaxAgeSeconds": null, + "usesCookies": false, + "cookieRefresh": false, + "usesNonCookieAccess": true, + "dataRetention": { + "stdRetention": 0, + "purposes": {}, + "specialPurposes": {} + }, + "urls": [ + { + "langId": "en", + "privacy": "https://covatic.com/terms/" + } + ], + "dataDeclaration": [ + 1, + 2, + 6, + 8 + ], + "deviceStorageDisclosureUrl": "https://tcf.covatic.io/onDeviceStorage.json" + }, + "1110": { + "id": 1110, + "name": "KÖNIGSTEINER digital GmbH", + "purposes": [ + 1, + 2, + 3, + 4, + 7, + 10 + ], + "legIntPurposes": [], + "flexiblePurposes": [], + "specialPurposes": [ + 2 + ], + "features": [ + 1, + 2, + 3 + ], + "specialFeatures": [ + 1 + ], + "cookieMaxAgeSeconds": 31536000, + "usesCookies": true, + "cookieRefresh": true, + "usesNonCookieAccess": false, + "dataRetention": { + "stdRetention": 90, + "purposes": {}, + "specialPurposes": {} + }, + "urls": [ + { + "langId": "de", + "privacy": "https://www.koenigsteiner.digital/datenschutzerklaerung", + "legIntClaim": "https://www.koenigsteiner.digital/datenschutzerklaerung" + } + ], + "dataDeclaration": [ + 1, + 2, + 3, + 4, + 8 + ], + "deviceStorageDisclosureUrl": "https://roqad-public.s3.eu-central-1.amazonaws.com/tcf-disclosure.json" + }, + "1116": { + "id": 1116, + "name": "Anonymised", + "purposes": [ + 1, + 2, + 3, + 4, + 7, + 9, + 10 + ], + "legIntPurposes": [], + "flexiblePurposes": [], + "specialPurposes": [], + "features": [], + "specialFeatures": [], + "cookieMaxAgeSeconds": 31536000, + "usesCookies": true, + "cookieRefresh": true, + "usesNonCookieAccess": true, + "dataRetention": { + "stdRetention": 365, + "purposes": {}, + "specialPurposes": {} + }, + "urls": [ + { + "langId": "en", + "privacy": "https://www.anonymised.io/privacy" + } + ], + "dataDeclaration": [ + 1, + 2, + 6, + 7, + 8, + 10 + ], + "deviceStorageDisclosureUrl": "https://static.anonymised.io/deviceStorage.json" + }, + "1119": { + "id": 1119, + "name": "Novatiq limited ", + "purposes": [ + 3, + 4, + 7, + 9 + ], + "legIntPurposes": [], + "flexiblePurposes": [], + "specialPurposes": [], + "features": [ + 2 + ], + "specialFeatures": [], + "cookieMaxAgeSeconds": null, + "usesCookies": false, + "cookieRefresh": false, + "usesNonCookieAccess": true, + "dataRetention": { + "stdRetention": 1, + "purposes": { + "7": 0 + }, + "specialPurposes": {} + }, + "urls": [ + { + "langId": "en", + "privacy": "https://novatiq.com/privacy-policy/" + } + ], + "dataDeclaration": [ + 4, + 5, + 11 + ], + "deviceStorageDisclosureUrl": "https://novatiq.com/privacy/iab/novatiq.json" + }, + "1120": { + "id": 1120, + "name": "Bababam", + "purposes": [ + 1, + 2, + 3 + ], + "legIntPurposes": [ + 7, + 8, + 9, + 10, + 11 + ], + "flexiblePurposes": [], + "specialPurposes": [ + 1, + 2 + ], + "features": [ + 3 + ], + "specialFeatures": [], + "cookieMaxAgeSeconds": 31536000, + "usesCookies": true, + "cookieRefresh": true, + "usesNonCookieAccess": true, + "dataRetention": { + "stdRetention": 730, + "purposes": {}, + "specialPurposes": {} + }, + "urls": [ + { + "langId": "fr", + "privacy": "https://www.bababam.com/terms", + "legIntClaim": "https://www.bababam.com/terms" + } + ], + "dataDeclaration": [ + 1, + 2, + 6, + 8, + 10, + 11 + ], + "deviceStorageDisclosureUrl": "https://www.bababam.com/.well-known/deviceStorage.json" + }, + "1122": { + "id": 1122, + "name": "Arbeitsgemeinschaft Media-Analyse", + "purposes": [ + 1, + 9 + ], + "legIntPurposes": [], + "flexiblePurposes": [], + "specialPurposes": [], + "features": [ + 2, + 3 + ], + "specialFeatures": [], + "cookieMaxAgeSeconds": 31622400, + "usesCookies": true, + "cookieRefresh": true, + "usesNonCookieAccess": false, + "dataRetention": { + "purposes": { + "9": 180 + }, + "specialPurposes": {} + }, + "urls": [ + { + "langId": "de", + "privacy": "https://www.agma-mmc.de/datenschutz" + } + ], + "dataDeclaration": [ + 1, + 2, + 4, + 5, + 6, + 8, + 11 + ], + "deviceStorageDisclosureUrl": "https://www.agma-mmc.de/ioam/deviceStorage.json" + }, + "1127": { + "id": 1127, + "name": "XAD spoteffects GmbH", + "purposes": [ + 1, + 3, + 5, + 7, + 8, + 10 + ], + "legIntPurposes": [], + "flexiblePurposes": [], + "specialPurposes": [], + "features": [ + 2, + 3 + ], + "specialFeatures": [], + "cookieMaxAgeSeconds": 63072000, + "usesCookies": true, + "cookieRefresh": true, + "usesNonCookieAccess": false, + "dataRetention": { + "stdRetention": 396, + "purposes": {}, + "specialPurposes": {} + }, + "urls": [ + { + "langId": "en", + "privacy": "https://xadspoteffects.com/en/privacy-policy/" + } + ], + "dataDeclaration": [ + 2, + 3, + 4, + 6, + 8, + 11 + ], + "deviceStorageDisclosureUrl": "https://trck.spoteffects.net/tcf2/ops-disclosure.json" + }, + "1129": { + "id": 1129, + "name": "Brandhouse/Subsero A/S", + "purposes": [], + "legIntPurposes": [ + 8 + ], + "flexiblePurposes": [], + "specialPurposes": [ + 1, + 2 + ], + "features": [], + "specialFeatures": [], + "cookieMaxAgeSeconds": null, + "usesCookies": false, + "cookieRefresh": false, + "usesNonCookieAccess": false, + "dataRetention": { + "stdRetention": 360, + "purposes": {}, + "specialPurposes": {} + }, + "urls": [ + { + "langId": "en", + "privacy": "https://subserohost.com/privacy_policy.aspx", + "legIntClaim": "https://subserohost.com/privacy_policy.aspx#datacoll_legitimateinterest" + } + ], + "dataDeclaration": [ + 1 + ], + "deviceStorageDisclosureUrl": "https://subserohost.com/device_storage_disclosure_tcfv2.json" + }, + "1130": { + "id": 1130, + "name": "WebMedia", + "purposes": [ + 1, + 2, + 3, + 4, + 5, + 6, + 7, + 8, + 9, + 10 + ], + "legIntPurposes": [], + "flexiblePurposes": [ + 2, + 7, + 8, + 9, + 10 + ], + "specialPurposes": [ + 1, + 2 + ], + "features": [ + 3 + ], + "specialFeatures": [ + 1, + 2 + ], + "cookieMaxAgeSeconds": 120960, + "usesCookies": true, + "cookieRefresh": true, + "usesNonCookieAccess": false, + "dataRetention": { + "stdRetention": 4320, + "purposes": {}, + "specialPurposes": {} + }, + "urls": [ + { + "langId": "en", + "privacy": "https://mobupps.com/pdf/Mobupps_Privacy_policy.pdf", + "legIntClaim": "https://mobupps.com/pdf/Mobupps_Privacy_policy.pdf" + } + ], + "dataDeclaration": [ + 1, + 2, + 3, + 8 + ], + "deviceStorageDisclosureUrl": "https://mobupps.com/tcf.json" + }, + "1134": { + "id": 1134, + "name": "Bidmatic Inc", + "purposes": [ + 1, + 2, + 7 + ], + "legIntPurposes": [], + "flexiblePurposes": [], + "specialPurposes": [ + 1, + 2 + ], + "features": [ + 3 + ], + "specialFeatures": [], + "cookieMaxAgeSeconds": 8035200, + "usesCookies": true, + "cookieRefresh": true, + "usesNonCookieAccess": true, + "dataRetention": { + "stdRetention": 90, + "purposes": {}, + "specialPurposes": { + "2": 0 + } + }, + "urls": [ + { + "langId": "en", + "privacy": "https://bidmatic.io/privacy-policy/", + "legIntClaim": "https://bidmatic.io/tos/" + } + ], + "dataDeclaration": [ + 1, + 2, + 3, + 4, + 6, + 7, + 8, + 11 + ], + "deviceStorageDisclosureUrl": "https://bidmatic.io/.well-known/deviceStorage.json" + }, + "1136": { + "id": 1136, + "name": "Infolinks Media, LLC", + "purposes": [ + 1, + 2, + 3, + 4, + 7, + 10 + ], + "legIntPurposes": [], + "flexiblePurposes": [], + "specialPurposes": [ + 2 + ], + "features": [ + 1, + 2, + 3 + ], + "specialFeatures": [ + 1 + ], + "cookieMaxAgeSeconds": 31536000, + "usesCookies": true, + "cookieRefresh": true, + "usesNonCookieAccess": true, + "dataRetention": { + "stdRetention": 4320, + "purposes": {}, + "specialPurposes": {} + }, + "urls": [ + { + "langId": "en", + "privacy": "https://www.infolinks.com/privacy-policy", + "legIntClaim": "https://www.infolinks.com/privacy-policy" + } + ], + "dataDeclaration": [ + 1, + 2, + 3, + 4, + 6, + 8 + ], + "deviceStorageDisclosureUrl": "https://resources.infolinks.com/static/tcf/devicestoragedisclosure.json" + }, + "1144": { + "id": 1144, + "name": "Unicredit BankAustria AG", + "purposes": [ + 1, + 2, + 3, + 4, + 7, + 8, + 9, + 10 + ], + "legIntPurposes": [], + "flexiblePurposes": [], + "specialPurposes": [], + "features": [ + 1, + 2, + 3 + ], + "specialFeatures": [], + "cookieMaxAgeSeconds": 31536000, + "usesCookies": true, + "cookieRefresh": true, + "usesNonCookieAccess": true, + "dataRetention": { + "stdRetention": 180, + "purposes": {}, + "specialPurposes": {} + }, + "urls": [ + { + "langId": "de", + "privacy": "https://www.bankaustria.at/rechtliches-datenschutz.jsp" + } + ], + "dataDeclaration": [ + 1, + 3, + 4, + 10 + ], + "deviceStorageDisclosureUrl": "https://js.ucg-at.datafront.co/next14_dmp_ucg-at_device_storage_information.json" + }, + "1147": { + "id": 1147, + "name": "MADINAD PC", + "purposes": [ + 1, + 2, + 3, + 4, + 5, + 7 + ], + "legIntPurposes": [ + 10 + ], + "flexiblePurposes": [], + "specialPurposes": [ + 1, + 2 + ], + "features": [ + 3 + ], + "specialFeatures": [ + 1, + 2 + ], + "cookieMaxAgeSeconds": 604800, + "usesCookies": true, + "cookieRefresh": true, + "usesNonCookieAccess": true, + "dataRetention": { + "stdRetention": 7, + "purposes": {}, + "specialPurposes": {} + }, + "urls": [ + { + "langId": "en", + "privacy": "https://madinad.com/privacy-policy/", + "legIntClaim": "https://madinad.com/privacy-policy/" + } + ], + "dataDeclaration": [ + 1, + 2, + 6 + ], + "deviceStorageDisclosureUrl": "https://static.madinad.com/static/iab-tcf.json" + }, + "1149": { + "id": 1149, + "name": "AdInMo LTD", + "purposes": [], + "legIntPurposes": [ + 2, + 7, + 10 + ], + "flexiblePurposes": [ + 2, + 7, + 10 + ], + "specialPurposes": [ + 1, + 2 + ], + "features": [ + 1, + 3 + ], + "specialFeatures": [], + "cookieMaxAgeSeconds": null, + "usesCookies": false, + "cookieRefresh": false, + "usesNonCookieAccess": false, + "dataRetention": { + "stdRetention": 365, + "purposes": { + "2": 30, + "10": 4320 + }, + "specialPurposes": {} + }, + "urls": [ + { + "langId": "en", + "privacy": "https://www.adinmo.com/privacy-policy/", + "legIntClaim": "https://www.adinmo.com/privacy-policy/" + } + ], + "dataDeclaration": [ + 1, + 2, + 3, + 4, + 11 + ], + "deviceStorageDisclosureUrl": "https://rtb.adinmo.com/iab-tcf-vendor" + }, + "1154": { + "id": 1154, + "name": "Alphonso Inc. ", + "purposes": [ + 1, + 2, + 3, + 4, + 5, + 6, + 7, + 8, + 9, + 10, + 11 + ], + "legIntPurposes": [], + "flexiblePurposes": [], + "specialPurposes": [], + "features": [ + 1, + 2, + 3 + ], + "specialFeatures": [ + 2 + ], + "cookieMaxAgeSeconds": null, + "usesCookies": false, + "cookieRefresh": false, + "usesNonCookieAccess": true, + "dataRetention": { + "stdRetention": 800, + "purposes": {}, + "specialPurposes": {} + }, + "urls": [ + { + "langId": "en", + "privacy": "https://alphonso.tv/privacy/smart-tvs/smart-tv-privacy-policy-eu/", + "legIntClaim": "https://alphonso.tv/privacy/smart-tvs/smart-tv-privacy-policy-eu/" + }, + { + "langId": "bg", + "privacy": "https://alphonso.tv/privacy/smart-tvs/smart-tv-privacy-policy-eu-bulgarian/", + "legIntClaim": "https://alphonso.tv/privacy/smart-tvs/smart-tv-privacy-policy-eu-bulgarian/" + }, + { + "langId": "hr", + "privacy": "https://alphonso.tv/privacy/smart-tvs/smart-tv-privacy-policy-eu-croatian/", + "legIntClaim": "https://alphonso.tv/privacy/smart-tvs/smart-tv-privacy-policy-eu-croatian/" + }, + { + "langId": "cs", + "privacy": "https://alphonso.tv/privacy/smart-tvs/smart-tv-privacy-policy-eu-czech/", + "legIntClaim": "https://alphonso.tv/privacy/smart-tvs/smart-tv-privacy-policy-eu-czech/" + }, + { + "langId": "da", + "privacy": "https://alphonso.tv/privacy/smart-tvs/smart-tv-privacy-policy-eu-danish/", + "legIntClaim": "https://alphonso.tv/privacy/smart-tvs/smart-tv-privacy-policy-eu-danish/" + }, + { + "langId": "nl", + "privacy": "https://alphonso.tv/privacy/smart-tvs/smart-tv-privacy-policy-eu-dutch/", + "legIntClaim": "https://alphonso.tv/privacy/smart-tvs/smart-tv-privacy-policy-eu-dutch/" + }, + { + "langId": "fi", + "privacy": "https://alphonso.tv/privacy/smart-tvs/smart-tv-privacy-policy-eu-finnish/", + "legIntClaim": "https://alphonso.tv/privacy/smart-tvs/smart-tv-privacy-policy-eu-finnish/" + }, + { + "langId": "et", + "privacy": "https://alphonso.tv/privacy/smart-tvs/smart-tv-privacy-policy-eu-estonian/", + "legIntClaim": "https://alphonso.tv/privacy/smart-tvs/smart-tv-privacy-policy-eu-estonian/" + }, + { + "langId": "fr", + "privacy": "https://alphonso.tv/privacy/smart-tvs/smart-tv-privacy-policy-eu-fr/", + "legIntClaim": "https://alphonso.tv/privacy/smart-tvs/smart-tv-privacy-policy-eu-fr/" + }, + { + "langId": "gl", + "privacy": "https://alphonso.tv/privacy/smart-tvs/smart-tv-privacy-policy-eu-gaelic/", + "legIntClaim": "https://alphonso.tv/privacy/smart-tvs/smart-tv-privacy-policy-eu-gaelic/" + }, + { + "langId": "de", + "privacy": "https://alphonso.tv/privacy/smart-tvs/smart-tv-privacy-policy-eu-de/", + "legIntClaim": "https://alphonso.tv/privacy/smart-tvs/smart-tv-privacy-policy-eu-de/" + }, + { + "langId": "el", + "privacy": "https://alphonso.tv/privacy/smart-tvs/smart-tv-privacy-policy-eu-greek/", + "legIntClaim": "https://alphonso.tv/privacy/smart-tvs/smart-tv-privacy-policy-eu-greek/" + }, + { + "langId": "hu", + "privacy": "https://alphonso.tv/privacy/smart-tvs/smart-tv-privacy-policy-eu-hungarian/", + "legIntClaim": "https://alphonso.tv/privacy/smart-tvs/smart-tv-privacy-policy-eu-hungarian/" + }, + { + "langId": "it", + "privacy": "https://alphonso.tv/privacy/smart-tvs/smart-tv-privacy-policy-eu-it/", + "legIntClaim": "https://alphonso.tv/privacy/smart-tvs/smart-tv-privacy-policy-eu-it/" + }, + { + "langId": "lv", + "privacy": "https://alphonso.tv/privacy/smart-tvs/smart-tv-privacy-policy-eu-latvian/", + "legIntClaim": "https://alphonso.tv/privacy/smart-tvs/smart-tv-privacy-policy-eu-latvian/" + }, + { + "langId": "lt", + "privacy": "https://alphonso.tv/privacy/smart-tvs/smart-tv-privacy-policy-eu-lithuanian/", + "legIntClaim": "https://alphonso.tv/privacy/smart-tvs/smart-tv-privacy-policy-eu-lithuanian/" + }, + { + "langId": "mt", + "privacy": "https://alphonso.tv/privacy/smart-tvs/smart-tv-privacy-policy-eu-maltese/", + "legIntClaim": "https://alphonso.tv/privacy/smart-tvs/smart-tv-privacy-policy-eu-maltese/" + }, + { + "langId": "pl", + "privacy": "https://alphonso.tv/privacy/smart-tvs/smart-tv-privacy-policy-eu-polish/", + "legIntClaim": "https://alphonso.tv/privacy/smart-tvs/smart-tv-privacy-policy-eu-polish/" + }, + { + "langId": "pt", + "privacy": "https://alphonso.tv/privacy/smart-tvs/smart-tv-privacy-policy-eu-portuguese/", + "legIntClaim": "https://alphonso.tv/privacy/smart-tvs/smart-tv-privacy-policy-eu-portuguese/" + }, + { + "langId": "ro", + "privacy": "https://alphonso.tv/privacy/smart-tvs/smart-tv-privacy-policy-eu-romanian/", + "legIntClaim": "https://alphonso.tv/privacy/smart-tvs/smart-tv-privacy-policy-eu-romanian/" + }, + { + "langId": "sk", + "privacy": "https://alphonso.tv/privacy/smart-tvs/smart-tv-privacy-policy-eu-slovak/", + "legIntClaim": "https://alphonso.tv/privacy/smart-tvs/smart-tv-privacy-policy-eu-slovak/" + }, + { + "langId": "sl", + "privacy": "https://alphonso.tv/privacy/smart-tvs/smart-tv-privacy-policy-eu-slovenian/", + "legIntClaim": "https://alphonso.tv/privacy/smart-tvs/smart-tv-privacy-policy-eu-slovenian/" + }, + { + "langId": "es", + "privacy": "https://alphonso.tv/privacy/smart-tvs/smart-tv-privacy-policy-eu-es/", + "legIntClaim": "https://alphonso.tv/privacy/smart-tvs/smart-tv-privacy-policy-eu-es/" + }, + { + "langId": "sv", + "privacy": "https://alphonso.tv/privacy/smart-tvs/smart-tv-privacy-policy-eu-swedish/", + "legIntClaim": "https://alphonso.tv/privacy/smart-tvs/smart-tv-privacy-policy-eu-swedish/" + } + ], + "dataDeclaration": [ + 1, + 2, + 3, + 4, + 6, + 8, + 11 + ], + "deviceStorageDisclosureUrl": "https://cdn.alphonso.tv/static-assets/iab-tcf/policy/device-storage-disclosure.json" + }, + "1157": { + "id": 1157, + "name": "Refine Direct Srl", + "purposes": [ + 1, + 7, + 10 + ], + "legIntPurposes": [], + "flexiblePurposes": [], + "specialPurposes": [ + 1, + 2 + ], + "features": [ + 3 + ], + "specialFeatures": [], + "cookieMaxAgeSeconds": null, + "usesCookies": false, + "cookieRefresh": false, + "usesNonCookieAccess": true, + "dataRetention": { + "stdRetention": 1, + "purposes": {}, + "specialPurposes": {} + }, + "urls": [ + { + "langId": "it", + "privacy": "https://www.refine.direct/it/cookie-policy/", + "legIntClaim": "https://www.refine.direct/it/legitimate-interest-assessment/" + }, + { + "langId": "en", + "privacy": "https://www.refine.direct/en/cookie-policy/", + "legIntClaim": "https://www.refine.direct/en/legitimate-interest-assessment/" + } + ], + "dataDeclaration": [ + 1, + 2, + 4 + ], + "deviceStorageDisclosureUrl": "https://cdn.refine.direct/tcf2/tcf2.json" + }, + "1160": { + "id": 1160, + "name": "streaMonkey GmbH", + "purposes": [], + "legIntPurposes": [], + "flexiblePurposes": [], + "specialPurposes": [ + 1, + 2 + ], + "features": [], + "specialFeatures": [], + "cookieMaxAgeSeconds": null, + "usesCookies": false, + "cookieRefresh": false, + "usesNonCookieAccess": false, + "dataRetention": { + "stdRetention": 90, + "purposes": {}, + "specialPurposes": {} + }, + "urls": [ + { + "langId": "de", + "privacy": "https://www.streamonkey.de/de/datenschutz", + "legIntClaim": "https://www.streamonkey.de/de/datenschutz" + } + ], + "dataDeclaration": [ + 1 + ], + "deviceStorageDisclosureUrl": "https://www.streamonkey.de/iab_disclosures.json" + }, + "1161": { + "id": 1161, + "name": "freenet DLS GmbH", + "purposes": [ + 1, + 2, + 3, + 4, + 5, + 6, + 7, + 8, + 9, + 10 + ], + "legIntPurposes": [], + "flexiblePurposes": [], + "specialPurposes": [ + 1, + 2 + ], + "features": [ + 1, + 2 + ], + "specialFeatures": [ + 1 + ], + "cookieMaxAgeSeconds": 7884000, + "usesCookies": true, + "cookieRefresh": true, + "usesNonCookieAccess": true, + "dataRetention": { + "stdRetention": 90, + "purposes": {}, + "specialPurposes": {} + }, + "urls": [ + { + "langId": "de", + "privacy": "https://www.freenet-mobilfunk.de/legal/datenschutz/", + "legIntClaim": "https://www.freenet-mobilfunk.de/legal/datenschutz/" + } + ], + "dataDeclaration": [ + 2, + 3, + 6, + 10, + 11 + ], + "deviceStorageDisclosureUrl": "https://www.freenet-mobilfunk.de/deviceStorage.json" + }, + "1165": { + "id": 1165, + "name": "Kueez Entertainment Ltd.", + "purposes": [ + 1, + 3, + 4, + 5, + 6 + ], + "legIntPurposes": [ + 2, + 7, + 8, + 9, + 10, + 11 + ], + "flexiblePurposes": [], + "specialPurposes": [ + 1, + 2 + ], + "features": [ + 1, + 2, + 3 + ], + "specialFeatures": [ + 1, + 2 + ], + "cookieMaxAgeSeconds": 2592000, + "usesCookies": true, + "cookieRefresh": true, + "usesNonCookieAccess": true, + "dataRetention": { + "stdRetention": 30, + "purposes": {}, + "specialPurposes": {} + }, + "urls": [ + { + "langId": "en", + "privacy": "https://www.kueez.com/en/privacy", + "legIntClaim": "https://www.kueez.com/en/privacy" + } + ], + "dataDeclaration": [ + 1, + 2, + 3, + 4, + 6, + 8, + 11 + ], + "deviceStorageDisclosureUrl": "https://en.kueez.com/tcf.json" + }, + "1168": { + "id": 1168, + "name": "Voxnest Inc", + "purposes": [ + 3, + 4 + ], + "legIntPurposes": [ + 2, + 7, + 8, + 9, + 10 + ], + "flexiblePurposes": [ + 2, + 7, + 8, + 9, + 10 + ], + "specialPurposes": [ + 1, + 2 + ], + "features": [ + 3 + ], + "specialFeatures": [], + "cookieMaxAgeSeconds": null, + "usesCookies": false, + "cookieRefresh": false, + "usesNonCookieAccess": false, + "dataRetention": { + "stdRetention": 30, + "purposes": {}, + "specialPurposes": { + "1": 180, + "2": 4320 + } + }, + "urls": [ + { + "langId": "en", + "privacy": "https://www.voxnest.com/privacy/", + "legIntClaim": "https://www.voxnest.com/privacy/" + } + ], + "dataDeclaration": [ + 1, + 2, + 4, + 6, + 10, + 11 + ], + "deviceStorageDisclosureUrl": "https://www.voxnest.com/iab-tcf-disclosures.json" + }, + "1170": { + "id": 1170, + "name": "Zeit Agency ApS", + "purposes": [], + "legIntPurposes": [ + 7, + 8, + 9, + 10 + ], + "flexiblePurposes": [], + "specialPurposes": [ + 1, + 2 + ], + "features": [], + "specialFeatures": [], + "cookieMaxAgeSeconds": null, + "usesCookies": false, + "cookieRefresh": false, + "usesNonCookieAccess": false, + "dataRetention": { + "stdRetention": 30, + "purposes": {}, + "specialPurposes": {} + }, + "urls": [ + { + "langId": "en", + "privacy": "https://zeitagency.com/privacy.html", + "legIntClaim": "https://zeitagency.com/privacy.html" + } + ], + "dataDeclaration": [ + 1, + 2 + ], + "deviceStorageDisclosureUrl": "https://zeitagency.com/domains.json" + }, + "1176": { + "id": 1176, + "name": "AlgoriX Technology Pte. Ltd.,", + "purposes": [ + 1, + 3, + 4, + 7 + ], + "legIntPurposes": [ + 2, + 10 + ], + "flexiblePurposes": [ + 2, + 10 + ], + "specialPurposes": [ + 1, + 2 + ], + "features": [ + 2, + 3 + ], + "specialFeatures": [ + 1, + 2 + ], + "overflow": { + "httpGetLimit": 32 + }, + "cookieMaxAgeSeconds": null, + "usesCookies": false, + "cookieRefresh": false, + "usesNonCookieAccess": true, + "dataRetention": { + "stdRetention": 7, + "purposes": {}, + "specialPurposes": {} + }, + "urls": [ + { + "langId": "en", + "privacy": "https://www.algorix.co/privacy-policy/", + "legIntClaim": "https://www.algorix.co/privacy-policy/#section-3-3" + } + ], + "dataDeclaration": [ + 1, + 2, + 3, + 4, + 5, + 6, + 8, + 9, + 11 + ], + "deviceStorageDisclosureUrl": "https://www.algorix.co/gdpr-disclosure.json" + }, + "1178": { + "id": 1178, + "name": "First-id", + "purposes": [ + 1, + 2, + 3, + 4, + 7 + ], + "legIntPurposes": [], + "flexiblePurposes": [], + "specialPurposes": [], + "features": [ + 3 + ], + "specialFeatures": [ + 2 + ], + "cookieMaxAgeSeconds": 34128000, + "usesCookies": true, + "cookieRefresh": true, + "usesNonCookieAccess": false, + "dataRetention": { + "stdRetention": 395, + "purposes": {}, + "specialPurposes": {} + }, + "urls": [ + { + "langId": "fr", + "privacy": "https://www.first-id.fr/fr/politique-de-confidentialite" + }, + { + "langId": "en", + "privacy": "https://www.first-id.fr/politique-de-confidentialite" + } + ], + "dataDeclaration": [ + 1, + 2, + 7, + 8, + 11 + ], + "deviceStorageDisclosureUrl": "https://static.first-id.fr/tcf/cookie.json" + }, + "1181": { + "id": 1181, + "name": "BotTalk UG (haftungsbeschränkt)", + "purposes": [ + 1, + 8, + 10 + ], + "legIntPurposes": [], + "flexiblePurposes": [], + "specialPurposes": [], + "features": [ + 3 + ], + "specialFeatures": [ + 1 + ], + "cookieMaxAgeSeconds": 2592000, + "usesCookies": true, + "cookieRefresh": true, + "usesNonCookieAccess": false, + "dataRetention": { + "stdRetention": 30, + "purposes": {}, + "specialPurposes": {} + }, + "urls": [ + { + "langId": "de", + "privacy": "https://bottalk.io/privacy", + "legIntClaim": "https://bottalk.io/privacy" + } + ], + "dataDeclaration": [ + 2 + ], + "deviceStorageDisclosureUrl": "https://bottalk.io/gvr.json" + }, + "1184": { + "id": 1184, + "name": "Schwarz Media GmbH ", + "purposes": [ + 1, + 2, + 3, + 4, + 7, + 9, + 10 + ], + "legIntPurposes": [], + "flexiblePurposes": [], + "specialPurposes": [ + 1, + 2 + ], + "features": [ + 1, + 2, + 3 + ], + "specialFeatures": [ + 1 + ], + "cookieMaxAgeSeconds": 7776000, + "usesCookies": true, + "cookieRefresh": true, + "usesNonCookieAccess": true, + "dataRetention": { + "stdRetention": 89, + "purposes": {}, + "specialPurposes": {} + }, + "urls": [ + { + "langId": "de", + "privacy": "https://gruppe.schwarz/datenschutz", + "legIntClaim": "https://gruppe.schwarz/datenschutz" + } + ], + "dataDeclaration": [ + 1, + 2, + 3, + 4, + 6, + 8, + 9, + 10, + 11 + ], + "deviceStorageDisclosureUrl": "https://dmp.theadex.com/.well-known/deviceStorage.json" + }, + "1187": { + "id": 1187, + "name": "AccountInsight Ltd", + "purposes": [], + "legIntPurposes": [], + "flexiblePurposes": [], + "specialPurposes": [ + 1, + 2 + ], + "features": [ + 1 + ], + "specialFeatures": [], + "cookieMaxAgeSeconds": null, + "usesCookies": false, + "cookieRefresh": false, + "usesNonCookieAccess": false, + "dataRetention": { + "purposes": {}, + "specialPurposes": { + "1": 180, + "2": 365 + } + }, + "urls": [ + { + "langId": "en", + "privacy": "https://www.accountinsight.ai/privacy-policy/", + "legIntClaim": "https://www.accountinsight.ai/privacy-policy/#IP_Processing" + } + ], + "dataDeclaration": [ + 1 + ], + "deviceStorageDisclosureUrl": "https://static.accountinsight.cloud/TCF/Device%20Storage%20Disclosure.json" + }, + "1195": { + "id": 1195, + "name": "Amplified IntelligenceTechnologies", + "purposes": [ + 7, + 9, + 10 + ], + "legIntPurposes": [], + "flexiblePurposes": [ + 7, + 9, + 10 + ], + "specialPurposes": [], + "features": [], + "specialFeatures": [], + "cookieMaxAgeSeconds": null, + "usesCookies": false, + "cookieRefresh": false, + "usesNonCookieAccess": false, + "dataRetention": { + "stdRetention": 3650, + "purposes": {}, + "specialPurposes": {} + }, + "urls": [ + { + "langId": "en", + "privacy": "https://www.amplifiedintelligence.com.au/privacy-policy/", + "legIntClaim": "https://www.amplifiedintelligence.com.au/privacy-policy/" + } + ], + "dataDeclaration": [ + 1, + 2, + 6, + 8 + ], + "deviceStorageDisclosureUrl": "https://www.amplifiedintelligence.com.au/tcfv2.json" + }, + "1196": { + "id": 1196, + "name": "MEDIAWAYSS Sp. z o.o.", + "purposes": [ + 1, + 2, + 3, + 4, + 5, + 7, + 8 + ], + "legIntPurposes": [], + "flexiblePurposes": [], + "specialPurposes": [ + 2 + ], + "features": [ + 3 + ], + "specialFeatures": [], + "cookieMaxAgeSeconds": 31449600, + "usesCookies": true, + "cookieRefresh": true, + "usesNonCookieAccess": false, + "dataRetention": { + "stdRetention": 364, + "purposes": {}, + "specialPurposes": {} + }, + "urls": [ + { + "langId": "en", + "privacy": "https://vidverto.io/privacy-policy/", + "legIntClaim": "https://vidverto.io/privacy-policy/#interest" + } + ], + "dataDeclaration": [ + 2, + 3, + 4, + 6, + 8, + 10, + 11 + ], + "deviceStorageDisclosureUrl": "https://ad.vidverto.io/delivery/iab_tcf_ds.json" + }, + "1199": { + "id": 1199, + "name": "Adsyield Inc", + "purposes": [ + 1, + 2, + 7, + 8, + 10 + ], + "legIntPurposes": [], + "flexiblePurposes": [ + 10 + ], + "specialPurposes": [ + 1, + 2 + ], + "features": [ + 3 + ], + "specialFeatures": [ + 2 + ], + "overflow": { + "httpGetLimit": 128 + }, + "cookieMaxAgeSeconds": null, + "usesCookies": false, + "cookieRefresh": false, + "usesNonCookieAccess": true, + "dataRetention": { + "stdRetention": 2, + "purposes": { + "2": 1, + "8": 1 + }, + "specialPurposes": {} + }, + "urls": [ + { + "langId": "en", + "privacy": "https://adsyield.com/privacy-policy/", + "legIntClaim": "https://adsyield.com/privacy-policy/" + } + ], + "dataDeclaration": [ + 1, + 2, + 4, + 6 + ], + "deviceStorageDisclosureUrl": "https://adsyield.com/sellers.json" + }, + "1201": { + "id": 1201, + "name": "hyScore.io GmbH", + "purposes": [ + 2, + 7, + 8, + 10 + ], + "legIntPurposes": [], + "flexiblePurposes": [], + "specialPurposes": [], + "features": [], + "specialFeatures": [], + "cookieMaxAgeSeconds": null, + "usesCookies": false, + "cookieRefresh": false, + "usesNonCookieAccess": false, + "dataRetention": { + "stdRetention": 365, + "purposes": {}, + "specialPurposes": {} + }, + "urls": [ + { + "langId": "en", + "privacy": "https://hyscore.io/data-privacy/" + } + ], + "dataDeclaration": [ + 8, + 9 + ], + "deviceStorageDisclosureUrl": "https://act.hyscore.io/tcf/tcf.json" + }, + "1202": { + "id": 1202, + "name": "Edge226 Ltd", + "purposes": [ + 2, + 7, + 10 + ], + "legIntPurposes": [], + "flexiblePurposes": [ + 2, + 7, + 10 + ], + "specialPurposes": [ + 2 + ], + "features": [ + 3 + ], + "specialFeatures": [ + 1 + ], + "cookieMaxAgeSeconds": null, + "usesCookies": false, + "cookieRefresh": false, + "usesNonCookieAccess": false, + "dataRetention": { + "stdRetention": 30, + "purposes": { + "2": 90 + }, + "specialPurposes": { + "2": 1 + } + }, + "urls": [ + { + "langId": "en", + "privacy": "https://edge226.com/privacy-policy/", + "legIntClaim": "https://edge226.com/privacy-policy/" + } + ], + "dataDeclaration": [ + 1, + 2, + 3, + 8 + ], + "deviceStorageDisclosureUrl": "https://snatch.adjns.com/cdn_storage/tcf/tcf.json" + }, + "1204": { + "id": 1204, + "name": "fraud0 GmbH", + "purposes": [], + "legIntPurposes": [], + "flexiblePurposes": [], + "specialPurposes": [ + 1 + ], + "features": [], + "specialFeatures": [], + "cookieMaxAgeSeconds": null, + "usesCookies": false, + "cookieRefresh": false, + "usesNonCookieAccess": false, + "dataRetention": { + "purposes": {}, + "specialPurposes": { + "1": 730 + } + }, + "urls": [ + { + "langId": "en", + "privacy": "https://www.fraud0.com/privacy-policy/", + "legIntClaim": "https://www.fraud0.com/privacy-policy/" + }, + { + "langId": "de", + "privacy": "https://www.fraud0.com/de/datenschutz/", + "legIntClaim": "https://www.fraud0.com/de/datenschutz/" + } + ], + "dataDeclaration": [ + 1, + 2, + 3, + 6 + ], + "deviceStorageDisclosureUrl": "https://api.fraud0.com/iab.json" + }, + "1207": { + "id": 1207, + "name": "Feeltapmedia Limited", + "purposes": [ + 1 + ], + "legIntPurposes": [ + 2 + ], + "flexiblePurposes": [ + 2 + ], + "specialPurposes": [], + "features": [], + "specialFeatures": [], + "overflow": { + "httpGetLimit": 128 + }, + "cookieMaxAgeSeconds": null, + "usesCookies": false, + "cookieRefresh": false, + "usesNonCookieAccess": true, + "dataRetention": { + "purposes": { + "2": 90 + }, + "specialPurposes": {} + }, + "urls": [ + { + "langId": "en", + "privacy": "https://feeltapmedia.com/Privacy-policy/", + "legIntClaim": "https://feeltapmedia.com/Privacy-policy/" + } + ], + "dataDeclaration": [ + 1, + 2, + 3 + ], + "deviceStorageDisclosureUrl": "https://feeltapmedia.com/ftm.json" + }, + "1209": { + "id": 1209, + "name": "Memob Plus FZ LLC", + "purposes": [ + 1, + 2, + 3, + 4, + 7, + 9 + ], + "legIntPurposes": [], + "flexiblePurposes": [], + "specialPurposes": [ + 1, + 2 + ], + "features": [ + 2 + ], + "specialFeatures": [ + 1 + ], + "overflow": { + "httpGetLimit": 128 + }, + "cookieMaxAgeSeconds": null, + "usesCookies": false, + "cookieRefresh": false, + "usesNonCookieAccess": true, + "dataRetention": { + "stdRetention": 90, + "purposes": {}, + "specialPurposes": {} + }, + "urls": [ + { + "langId": "en", + "privacy": "https://memob.com/privacy-policy/", + "legIntClaim": "https://memob.com/privacy-policy/" + } + ], + "dataDeclaration": [ + 1, + 2, + 3, + 4, + 6, + 7, + 9, + 10 + ], + "deviceStorageDisclosureUrl": "https://gdpr.memob.com/deviceStorage.json" + }, + "1210": { + "id": 1210, + "name": "ADNOW I RENODO MEDIA LTD", + "purposes": [ + 1, + 2 + ], + "legIntPurposes": [ + 7, + 8, + 9, + 10 + ], + "flexiblePurposes": [ + 2, + 7, + 8, + 9, + 10 + ], + "specialPurposes": [ + 1, + 2 + ], + "features": [ + 3 + ], + "specialFeatures": [ + 1, + 2 + ], + "overflow": { + "httpGetLimit": 128 + }, + "cookieMaxAgeSeconds": 1209600, + "usesCookies": true, + "cookieRefresh": true, + "usesNonCookieAccess": false, + "dataRetention": { + "stdRetention": 30, + "purposes": {}, + "specialPurposes": {} + }, + "urls": [ + { + "langId": "en", + "privacy": "https://adnow.com/privacy-policy", + "legIntClaim": "https://adnow.com/privacy-policy" + } + ], + "dataDeclaration": [ + 1, + 2, + 8 + ], + "deviceStorageDisclosureUrl": "https://adnow.com/vdsod.json" + }, + "1212": { + "id": 1212, + "name": "Ads Interactive Ltd.", + "purposes": [ + 1, + 2, + 3, + 4, + 7, + 10 + ], + "legIntPurposes": [], + "flexiblePurposes": [], + "specialPurposes": [ + 1, + 2 + ], + "features": [ + 3 + ], + "specialFeatures": [], + "overflow": { + "httpGetLimit": 32 + }, + "cookieMaxAgeSeconds": 4838400, + "usesCookies": true, + "cookieRefresh": false, + "usesNonCookieAccess": false, + "dataRetention": { + "stdRetention": 60, + "purposes": {}, + "specialPurposes": {} + }, + "urls": [ + { + "langId": "en", + "privacy": "https://adsinteractive.com/privacy-policy", + "legIntClaim": "https://adsinteractive.com/privacy-policy" + } + ], + "dataDeclaration": [ + 1, + 2, + 8, + 11 + ], + "deviceStorageDisclosureUrl": "https://adsinteractive.com/vendor.json" + }, + "1214": { + "id": 1214, + "name": "Kamino Retail", + "purposes": [ + 1, + 3, + 4 + ], + "legIntPurposes": [ + 2, + 7, + 9, + 10 + ], + "flexiblePurposes": [ + 2, + 7, + 9, + 10 + ], + "specialPurposes": [ + 1, + 2 + ], + "features": [ + 1 + ], + "specialFeatures": [], + "cookieMaxAgeSeconds": 365, + "usesCookies": true, + "cookieRefresh": true, + "usesNonCookieAccess": false, + "dataRetention": { + "stdRetention": 365, + "purposes": {}, + "specialPurposes": { + "2": 0 + } + }, + "urls": [ + { + "langId": "en", + "privacy": "https://www.kaminoretail.com/privacy-policy", + "legIntClaim": "https://www.kaminoretail.com/privacy-policy" + } + ], + "dataDeclaration": [ + 1, + 2, + 5, + 6, + 8, + 11 + ], + "deviceStorageDisclosureUrl": "https://privacy.kaminoretail.io/privacy/kaminoretaildevicesstoragedisclosures.json" + }, + "1218": { + "id": 1218, + "name": "AIDEM Technologies LTD", + "purposes": [ + 1, + 2, + 7, + 10, + 11 + ], + "legIntPurposes": [], + "flexiblePurposes": [], + "specialPurposes": [ + 1, + 2 + ], + "features": [ + 1, + 2, + 3 + ], + "specialFeatures": [], + "overflow": { + "httpGetLimit": 32 + }, + "cookieMaxAgeSeconds": null, + "usesCookies": false, + "cookieRefresh": false, + "usesNonCookieAccess": true, + "dataRetention": { + "stdRetention": 90, + "purposes": { + "7": 30, + "11": 0 + }, + "specialPurposes": {} + }, + "urls": [ + { + "langId": "en", + "privacy": "https://kb.aidem.com/privacy/policies/privacy-policy/", + "legIntClaim": "https://kb.aidem.com/privacy/policies/privacy-policy/#4-how-we-use-your-data" + } + ], + "dataDeclaration": [ + 1, + 2, + 6, + 11 + ], + "deviceStorageDisclosureUrl": "https://www.aidem.com/tcf.json" + } + } +} \ No newline at end of file diff --git a/iabgpp-extras/pom.xml b/iabgpp-extras/pom.xml index 30c6fd8d..0fc7a4f8 100644 --- a/iabgpp-extras/pom.xml +++ b/iabgpp-extras/pom.xml @@ -7,31 +7,34 @@ com.iabgpp iabgpp-core - 3.0.0-SNAPSHOT + 3.2.3-SNAPSHOT iabgpp-extras - IAB GPP Java GVL and CMP List jar - - - The Apache Software License, Version 2.0 - http://www.apache.org/licenses/LICENSE-2.0.txt - - - - - UTF-8 - 1.8 - 1.8 - + + + + maven-surefire-plugin + 2.22.2 + + + release + + org.apache.maven.plugins + maven-source-plugin + + + org.apache.maven.plugins + maven-javadoc-plugin + org.apache.maven.plugins maven-gpg-plugin @@ -40,50 +43,4 @@ - - - - - org.codehaus.mojo - license-maven-plugin - - - - org.apache.maven.plugins - maven-compiler-plugin - - - - org.apache.maven.plugins - maven-source-plugin - - - - org.apache.maven.plugins - maven-javadoc-plugin - - - - org.apache.maven.plugins - maven-checkstyle-plugin - - - - - - - - org.jacoco - jacoco-maven-plugin - 0.8.5 - - - - report - - - - - - diff --git a/iabgpp-extras/src/main/java/com/iab/gpp/extras/cmp/Cmp.java b/iabgpp-extras/src/main/java/com/iab/gpp/extras/cmp/Cmp.java index 3aacf32a..ed0e6615 100644 --- a/iabgpp-extras/src/main/java/com/iab/gpp/extras/cmp/Cmp.java +++ b/iabgpp-extras/src/main/java/com/iab/gpp/extras/cmp/Cmp.java @@ -25,38 +25,39 @@ public interface Cmp { - /** - * A CMP id: a numeric ID which is incrementally assigned and never re-used – inactive CMPs are marked as deleted - * - * @return CMP id - */ - int getId(); - - /** - * Name of the CMP - * - * @return CMP name - */ - String getName(); - - /** - * Whether or not the CMP is a commercial service - * - * @return true, if the CMP is available as a commercial service - */ - boolean isCommercial(); - - /** - * If available, the date/time after which CMP is considered inactive - * - * @return {@link Optional} time after which CMP is inactive - */ - Optional getDeletedDate(); - - /** - * Check whether the CMP is deleted - * - * @return true, if the CMP is considered deleted - */ - boolean isDeleted(); + /** + * A CMP id: a numeric ID which is incrementally assigned and never re-used – inactive CMPs are + * marked as deleted + * + * @return CMP id + */ + int getId(); + + /** + * Name of the CMP + * + * @return CMP name + */ + String getName(); + + /** + * Whether or not the CMP is a commercial service + * + * @return true, if the CMP is available as a commercial service + */ + boolean isCommercial(); + + /** + * If available, the date/time after which CMP is considered inactive + * + * @return {@link Optional} time after which CMP is inactive + */ + Optional getDeletedDate(); + + /** + * Check whether the CMP is deleted + * + * @return true, if the CMP is considered deleted + */ + boolean isDeleted(); } diff --git a/iabgpp-extras/src/main/java/com/iab/gpp/extras/cmp/CmpList.java b/iabgpp-extras/src/main/java/com/iab/gpp/extras/cmp/CmpList.java index 5b62d386..5f3c3d4a 100644 --- a/iabgpp-extras/src/main/java/com/iab/gpp/extras/cmp/CmpList.java +++ b/iabgpp-extras/src/main/java/com/iab/gpp/extras/cmp/CmpList.java @@ -25,26 +25,26 @@ public interface CmpList { - /** - * Last Updated Date - * - * @return {@link Instant} time when the record was last updated - */ - Instant getLastUpdated(); + /** + * Last Updated Date + * + * @return {@link Instant} time when the record was last updated + */ + Instant getLastUpdated(); - /** - * List of CMPs - * - * @return {@link List} of {@link Cmp} objects - */ - List getCmps(); + /** + * List of CMPs + * + * @return {@link List} of {@link Cmp} objects + */ + List getCmps(); - /** - * Get the CMP object for a give CMP id - * - * @param cmpId CMP id - * @return {@link Cmp} object - */ - Cmp getCmp(int cmpId); + /** + * Get the CMP object for a give CMP id + * + * @param cmpId CMP id + * @return {@link Cmp} object + */ + Cmp getCmp(int cmpId); } diff --git a/iabgpp-extras/src/main/java/com/iab/gpp/extras/gvl/DataCategory.java b/iabgpp-extras/src/main/java/com/iab/gpp/extras/gvl/DataCategory.java new file mode 100644 index 00000000..e7e62cc3 --- /dev/null +++ b/iabgpp-extras/src/main/java/com/iab/gpp/extras/gvl/DataCategory.java @@ -0,0 +1,29 @@ +package com.iab.gpp.extras.gvl; + +/* + * DataCategory + */ +public interface DataCategory { + + /** + * id + * + * @return id + */ + Integer getId(); + + /** + * name + * + * @return name + */ + String getName(); + + /** + * description + * + * @return description + */ + String getDescription(); + +} diff --git a/iabgpp-extras/src/main/java/com/iab/gpp/extras/gvl/DataRetention.java b/iabgpp-extras/src/main/java/com/iab/gpp/extras/gvl/DataRetention.java new file mode 100644 index 00000000..12615dfa --- /dev/null +++ b/iabgpp-extras/src/main/java/com/iab/gpp/extras/gvl/DataRetention.java @@ -0,0 +1,53 @@ +package com.iab.gpp.extras.gvl; + +import java.util.List; +import java.util.Map; +import java.util.Optional; + +/*- + * #%L + * IAB TCF Java GVL and CMP List + * %% + * Copyright (C) 2020 IAB Technology Laboratory, Inc + * %% + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * #L% + */ + +/* + * DataRetention + */ +public interface DataRetention { + + /** + * stdRetention + * + * @return stdRetention + */ + Optional getStdRetention(); + + /** + * purposes + * + * @return purposes + */ + Map getPurposes(); + + /** + * specialPurposes + * + * @return specialPurposes + */ + Map getSpecialPurposes(); + +} diff --git a/iabgpp-extras/src/main/java/com/iab/gpp/extras/gvl/Feature.java b/iabgpp-extras/src/main/java/com/iab/gpp/extras/gvl/Feature.java index e6f330f4..946fa856 100644 --- a/iabgpp-extras/src/main/java/com/iab/gpp/extras/gvl/Feature.java +++ b/iabgpp-extras/src/main/java/com/iab/gpp/extras/gvl/Feature.java @@ -1,5 +1,8 @@ package com.iab.gpp.extras.gvl; +import java.util.List; +import java.util.Optional; + /*- * #%L * IAB TCF Java GVL and CMP List @@ -25,31 +28,38 @@ */ public interface Feature { - /** - * A feature id - * - * @return feature id - */ - int getId(); - - /** - * Name of the feature - * - * @return feature name string - */ - String getName(); - - /** - * Description of the feature - * - * @return feature description string - */ - String getDescription(); - - /** - * Legal description of the feature - * - * @return legal description string - */ - String getDescriptionLegal(); + /** + * A feature id + * + * @return feature id + */ + int getId(); + + /** + * Name of the feature + * + * @return feature name string + */ + String getName(); + + /** + * Description of the feature + * + * @return feature description string + */ + String getDescription(); + + /** + * Legal description of the feature + * + * @return legal description string + */ + Optional getDescriptionLegal(); + + /** + * A list of illustrations + * + * @return A {@link List} of strings + */ + Optional> getIllustrations(); } diff --git a/iabgpp-extras/src/main/java/com/iab/gpp/extras/gvl/Gvl.java b/iabgpp-extras/src/main/java/com/iab/gpp/extras/gvl/Gvl.java index 29d29df4..a1a6e545 100644 --- a/iabgpp-extras/src/main/java/com/iab/gpp/extras/gvl/Gvl.java +++ b/iabgpp-extras/src/main/java/com/iab/gpp/extras/gvl/Gvl.java @@ -22,84 +22,93 @@ import java.time.Instant; import java.util.List; +import java.util.Optional; public interface Gvl { - /** - * A Global Vendor List Specification Version - * - * @return global vendor list specification version - */ - int getGvlSpecificationVersion(); + /** + * A Global Vendor List Specification Version + * + * @return global vendor list specification version + */ + int getGvlSpecificationVersion(); - /** - * A Global Vendor List version incremented with each published file change - * - * @return global vendor list version - */ - int getVendorListVersion(); + /** + * A Global Vendor List version incremented with each published file change + * + * @return global vendor list version + */ + int getVendorListVersion(); - /** - * A TCF Policy Version. - * - * @return tcf policy version - */ - int getTcfPolicyVersion(); + /** + * A TCF Policy Version. + * + * @return tcf policy version + */ + int getTcfPolicyVersion(); - /** - * Last Updated Date - * - * @return timestamp when the record was last updated - */ - Instant getLastUpdated(); + /** + * Last Updated Date + * + * @return timestamp when the record was last updated + */ + Instant getLastUpdated(); - /** - * A list of standard purposes - * - * @return A {@link List} of standard {@link Purpose} objects - */ - List getPurposes(); + /** + * A list of standard purposes + * + * @return A {@link List} of standard {@link Purpose} objects + */ + List getPurposes(); - /** - * A list of special purposes - * - * @return A {@link List} of {@link SpecialPurpose} objects - */ - List getSpecialPurposes(); + /** + * A list of special purposes + * + * @return A {@link List} of {@link SpecialPurpose} objects + */ + List getSpecialPurposes(); - /** - * A list of standard features - * - * @return A {@link List} of standard {@link Feature} objects - */ - List getFeatures(); + /** + * A list of standard features + * + * @return A {@link List} of standard {@link Feature} objects + */ + List getFeatures(); - /** - * A list of special features - * - * @return A {@link List} of special {@link SpecialFeature} objects - */ - List getSpecialFeatures(); + /** + * A list of special features + * + * @return A {@link List} of special {@link SpecialFeature} objects + */ + List getSpecialFeatures(); - /** - * A list of stacks - * - * @return A {@link List} of {@link Stack} objects - */ - List getStacks(); + /** + * A list of stacks + * + * @return A {@link List} of {@link Stack} objects + */ + List getStacks(); - /** - * A list of vendors - * - * @return A {@link List} of {@link Vendor} objects - */ - List getVendors(); + /** + * A list of vendors + * + * @return A {@link List} of {@link Vendor} objects + */ + List getVendors(); - /** - * Return the vendor object for a given id - * - * @param vendorId vendor id - * @return A {@link Vendor} object - */ - Vendor getVendor(int vendorId); + /** + * Return the vendor object for a given id + * + * @param vendorId vendor id + * @return A {@link Vendor} object + */ + Vendor getVendor(int vendorId); + + /** + * A list of data categories + * @since 3.0 + * + * @return A {@link List} of {@link DataCategory} objects + */ + Optional> getDataCategories(); } diff --git a/iabgpp-extras/src/main/java/com/iab/gpp/extras/gvl/Overflow.java b/iabgpp-extras/src/main/java/com/iab/gpp/extras/gvl/Overflow.java index 74c1a0b7..12a74b0e 100644 --- a/iabgpp-extras/src/main/java/com/iab/gpp/extras/gvl/Overflow.java +++ b/iabgpp-extras/src/main/java/com/iab/gpp/extras/gvl/Overflow.java @@ -23,10 +23,10 @@ public interface Overflow { - /** - * The vendor's http GET request length limit; 32 or 128 are the only supported options - * - * @return vendor's http GET request length limit - */ - int getHttpGetLimit(); + /** + * The vendor's http GET request length limit; 32 or 128 are the only supported options + * + * @return vendor's http GET request length limit + */ + int getHttpGetLimit(); } diff --git a/iabgpp-extras/src/main/java/com/iab/gpp/extras/gvl/Purpose.java b/iabgpp-extras/src/main/java/com/iab/gpp/extras/gvl/Purpose.java index 1b7fba69..2f2812d7 100644 --- a/iabgpp-extras/src/main/java/com/iab/gpp/extras/gvl/Purpose.java +++ b/iabgpp-extras/src/main/java/com/iab/gpp/extras/gvl/Purpose.java @@ -1,5 +1,8 @@ package com.iab.gpp.extras.gvl; +import java.util.List; +import java.util.Optional; + /*- * #%L * IAB TCF Java GVL and CMP List @@ -25,47 +28,53 @@ */ public interface Purpose { - /** - * A purpose id - * - * @return purpose id - */ - int getId(); + /** + * A purpose id + * + * @return purpose id + */ + int getId(); + + /** + * Name of the purpose + * + * @return purpose name string + */ + String getName(); - /** - * Name of the purpose - * - * @return purpose name string - */ - String getName(); + /** + * Description of the purpose + * + * @return purpose description string + */ + String getDescription(); - /** - * Description of the purpose - * - * @return purpose description string - */ - String getDescription(); + /** + * Legal description of the purpose + * @return legal description string + */ + Optional getDescriptionLegal(); - /** - * Legal description of the purpose - * - * @return legal description string - */ - String getDescriptionLegal(); + /** + * A list of illustrations + * @since 3.0 + * @return A {@link List} of strings + */ + Optional> getIllustrations(); - /** - * An optional flag where false means CMPs should never afford users the means to provide an - * opt-in consent choice - * - * @return consentable boolean - */ - boolean getConsentable(); + /** + * An optional flag where false means CMPs should never afford users the means to provide an opt-in + * consent choice + * + * @return consentable boolean + */ + boolean getConsentable(); - /** - * An optional flag where false means CMPs should never afford users the means to exercise a - * right to object - * - * @return consentable boolean - */ - boolean getRightToObject(); + /** + * An optional flag where false means CMPs should never afford users the means to exercise a right + * to object + * + * @return consentable boolean + */ + boolean getRightToObject(); } diff --git a/iabgpp-extras/src/main/java/com/iab/gpp/extras/gvl/Stack.java b/iabgpp-extras/src/main/java/com/iab/gpp/extras/gvl/Stack.java index e8c56df4..86c54421 100644 --- a/iabgpp-extras/src/main/java/com/iab/gpp/extras/gvl/Stack.java +++ b/iabgpp-extras/src/main/java/com/iab/gpp/extras/gvl/Stack.java @@ -28,38 +28,38 @@ */ public interface Stack { - /** - * Stack id - * - * @return stack id - */ - int getId(); + /** + * Stack id + * + * @return stack id + */ + int getId(); - /** - * A list of special features - * - * @return A {@link List} of special feature ids - */ - List getSpecialFeatures(); + /** + * A list of special features + * + * @return A {@link List} of special feature ids + */ + List getSpecialFeatures(); - /** - * A list of purposes - * - * @return A {@link List} of purpose ids - */ - List getPurposes(); + /** + * A list of purposes + * + * @return A {@link List} of purpose ids + */ + List getPurposes(); - /** - * Name of the stack - * - * @return stack name string - */ - String getName(); + /** + * Name of the stack + * + * @return stack name string + */ + String getName(); - /** - * Description of the stack - * - * @return stack description string - */ - String getDescription(); + /** + * Description of the stack + * + * @return stack description string + */ + String getDescription(); } diff --git a/iabgpp-extras/src/main/java/com/iab/gpp/extras/gvl/Vendor.java b/iabgpp-extras/src/main/java/com/iab/gpp/extras/gvl/Vendor.java index 8889d3c2..480a21b7 100644 --- a/iabgpp-extras/src/main/java/com/iab/gpp/extras/gvl/Vendor.java +++ b/iabgpp-extras/src/main/java/com/iab/gpp/extras/gvl/Vendor.java @@ -26,136 +26,171 @@ public interface Vendor { - /** - * A vendor id: a numeric ID which is incrementally assigned and never re-used – deleted Vendors - * are just marked as deleted - * - * @return vendor id - */ - int getId(); - - /** - * Name of the vendor - * - * @return vendor name - */ - String getName(); - - /** - * List of Purposes for which the vendor is requesting consent - * - * @return A {@link List} of purpose ids that require consent - */ - List getPurposes(); - - /** - * List of Purposes for which the vendor requires to be transparently disclosed as their - * legitimate interest - * - * @return A {@link List} of purpose ids disclosed as legitimate interests - */ - List getLegIntPurposes(); - - /** - * List of purposes where the vendor is flexible regarding the legal basis; they will perform - * the processing based on consent or a legitimate interest. The 'default' is determined by - * which of the other two mutually-exclusive purpose fields is used to declare the purpose for - * the vendor - * - * @return A {@link List} of flexible purpose ids - */ - List getFlexiblePurposes(); - - /** - * List of Special Purposes that the vendor transparently discloses as their legitimate interest - * that a user has no right to object - * - * @return A {@link List} of special purpose ids - */ - List getSpecialPurposes(); - - /** - * List of Features the vendor uses across Purposes - * - * @return A {@link List} of features - */ - List getFeatures(); - - /** - * List of Special Features the vendor uses across Purposes - * - * @return A {@link List} of special features - */ - List getSpecialFeatures(); - - /** - * GDPR/privacy policy page URL - * - * @return policy url string - */ - String getPolicyUrl(); - - /** - * If available, a date/time after which the vendor is deleted from the GVL - * - * @return {@link Optional} time after which the vendor is considered deleted - */ - Optional getDeletedDate(); - - /** - * object specifying the vendor's http GET request length limit. It is optional. If a vendor - * entry does not include this attribute then the vendor has no overflow options and none can be - * inferred. - * - * @return A {@link Overflow} object - */ - Optional getOverflow(); - - /** - * Check if the vendor is deleted based on the current time (UTC) - * - * @return true, if the vendor is deleted - */ - boolean isDeleted(); - - /** - * The number of seconds representing the longest potential duration for cookie storage on a device. - * If a Vendor uses multiple cookies with differing durations, cookieMaxAgeSeconds represents the cookie with - * the longest duration. Note: cookies are the only method of storage or device access that permit a predictable - * duration to be set. - * This is required only if usesCookies is set to true, else optional - * @return The number, in seconds, of the longest potential duration for storage on a device, as set when using - * the cookie method of storage. A negative number or a 0 indicate session storage similar to the Set-Cookie spec. - * A "-100" value no longer indicates no cookie usage. - * Note: this only includes what is declared when the storage is set and does not consider duration extensions - * should storage be refreshed - */ - Optional getCookieMaxAgeSeconds(); - - /** - * This boolean field indicates whether the vendor uses cookie storage (session or otherwise). - * @return True indicates cookie storage is used - */ - boolean getUsesCookies(); - - /** - * This true or false field indicates whether any cookies in scope for cookieMaxAgeSeconds are refreshed after - * being initially set. - * @return True indicates the vendor refreshes this cookie - */ - boolean getHasCookieRefresh(); - - /** - * This boolean field indicates whether the vendor uses other, non-cookie methods of storage or accessing - * information already stored on a user’s device. Examples of non-cookie storage and access may be localStorage, - * indexDB, mobile ad IDs, etc. - * @return True indicates non-cookie access is used - */ - boolean getUsesNonCookieAccess(); - - /** - * Link to a recommended, vendor-hosted, secure URL for disclosing additional storage information - * @return Location of vendor-hosted deviceStorage.json file - */ - Optional getDeviceStorageDisclosureUrl(); + /** + * A vendor id: a numeric ID which is incrementally assigned and never re-used – deleted Vendors are + * just marked as deleted + * + * @return vendor id + */ + int getId(); + + /** + * Name of the vendor + * + * @return vendor name + */ + String getName(); + + /** + * List of Purposes for which the vendor is requesting consent + * + * @return A {@link List} of purpose ids that require consent + */ + List getPurposes(); + + /** + * List of Purposes for which the vendor requires to be transparently disclosed as their legitimate + * interest + * + * @return A {@link List} of purpose ids disclosed as legitimate interests + */ + Optional> getLegIntPurposes(); + + /** + * List of Purposes for which the vendor requires to be transparently disclosed as implied Consent + * This is not applicable for EU, but for Canada + * + * @return A {@link List} of purpose ids disclosed as legitimate interests + */ + Optional> getImpConsPurposes(); + + /** + * List of purposes where the vendor is flexible regarding the legal basis; they will perform the + * processing based on consent or a legitimate interest. The 'default' is determined by which of the + * other two mutually-exclusive purpose fields is used to declare the purpose for the vendor + * + * @return A {@link List} of flexible purpose ids + */ + List getFlexiblePurposes(); + + /** + * List of Special Purposes that the vendor transparently discloses as their legitimate interest + * that a user has no right to object + * + * @return A {@link List} of special purpose ids + */ + List getSpecialPurposes(); + + /** + * List of Features the vendor uses across Purposes + * + * @return A {@link List} of features + */ + List getFeatures(); + + /** + * List of Special Features the vendor uses across Purposes + * + * @return A {@link List} of special features + */ + List getSpecialFeatures(); + + /** + * GDPR/privacy policy page URL + * @deprecated since 3.0 + * @return policy url string + */ + Optional getPolicyUrl(); + + /** + * If available, a date/time after which the vendor is deleted from the GVL + * + * @return {@link Optional} time after which the vendor is considered deleted + */ + Optional getDeletedDate(); + + /** + * object specifying the vendor's http GET request length limit. It is optional. If a vendor entry + * does not include this attribute then the vendor has no overflow options and none can be inferred. + * + * @return A {@link Overflow} object + */ + Optional getOverflow(); + + /** + * Check if the vendor is deleted based on the current time (UTC) + * + * @return true, if the vendor is deleted + */ + boolean isDeleted(); + + /** + * The number of seconds representing the longest potential duration for cookie storage on a device. + * If a Vendor uses multiple cookies with differing durations, cookieMaxAgeSeconds represents the + * cookie with the longest duration. Note: cookies are the only method of storage or device access + * that permit a predictable duration to be set. This is required only if usesCookies is set to + * true, else optional + * + * @return The number, in seconds, of the longest potential duration for storage on a device, as set + * when using the cookie method of storage. A negative number or a 0 indicate session + * storage similar to the Set-Cookie spec. A "-100" value no longer indicates no cookie + * usage. Note: this only includes what is declared when the storage is set and does not + * consider duration extensions should storage be refreshed + */ + Optional getCookieMaxAgeSeconds(); + + /** + * This boolean field indicates whether the vendor uses cookie storage (session or otherwise). + * + * @return True indicates cookie storage is used + */ + Optional getUsesCookies(); + + /** + * This true or false field indicates whether any cookies in scope for cookieMaxAgeSeconds are + * refreshed after being initially set. + * + * @return True indicates the vendor refreshes this cookie + */ + Optional getCookieRefresh(); + + /** + * This boolean field indicates whether the vendor uses other, non-cookie methods of storage or + * accessing information already stored on a user’s device. Examples of non-cookie storage and + * access may be localStorage, indexDB, mobile ad IDs, etc. + * + * @return True indicates non-cookie access is used + */ + Optional getUsesNonCookieAccess(); + + /** + * Link to a recommended, vendor-hosted, secure URL for disclosing additional storage information + * + * @return Location of vendor-hosted deviceStorage.json file + */ + Optional getDeviceStorageDisclosureUrl(); + + /** + * This object indicates how long vendors retain user's data for each declared purpose + * @since 3.0 + * + * @return {@link DataRetention} object + */ + Optional getDataRetention(); + + /** + * This list indicates unique urls to privacy policies by language and link to an + * explanation of their legitimate interests at stake + * @since 3.0 + * @return A {@link List} of {@link VendorUrl} objects + */ + Optional> getUrls(); + + /** + * This list of integers indicates data categories {@link DataCategory} that vendors collect and process + * @since 3.0 + * + * @return A {@link List} of integers + */ + Optional> getDataDeclaration(); } diff --git a/iabgpp-extras/src/main/java/com/iab/gpp/extras/gvl/VendorUrl.java b/iabgpp-extras/src/main/java/com/iab/gpp/extras/gvl/VendorUrl.java new file mode 100644 index 00000000..7a495de7 --- /dev/null +++ b/iabgpp-extras/src/main/java/com/iab/gpp/extras/gvl/VendorUrl.java @@ -0,0 +1,51 @@ +package com.iab.gpp.extras.gvl; + +import java.util.Optional; + +/*- + * #%L + * IAB TCF Java GVL and CMP List + * %% + * Copyright (C) 2020 IAB Technology Laboratory, Inc + * %% + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * #L% + */ + +/* + * VendorUrl + */ +public interface VendorUrl { + + /** + * langId + * + * @return lang id + */ + String getLangId(); + + /** + * privacy + * + * @return privacy + */ + String getPrivacy(); + + /** + * legIntClaim + * + * @return legIntClaim + */ + Optional getLegIntClaim(); + +} diff --git a/pom.xml b/pom.xml index ecc031cf..4a6d0211 100644 --- a/pom.xml +++ b/pom.xml @@ -6,8 +6,9 @@ com.iabgpp iabgpp-core - 3.0.0-SNAPSHOT + 3.2.3-SNAPSHOT IAB GPP Core Library + https://github.com/IABTechLabs/iabtcf-java Encode and decode consent information with the IAB GPP v3.0. pom @@ -18,10 +19,114 @@ + + + Mayank Mishra + mayank@iabtechlab.com + IAB Tech Lab + https://www.iabtechlab.com + + + + + scm:git:git@github.com:IABTechLabs/iabgpp-java.git + scm:git:git@github.com:IABTechLabs/iabgpp-java.git + https://github.com/IABTechLabs/iabgpp-java + + + + + sonatype-nexus-snapshots + Sonatype Nexus Snapshots + https://s01.oss.sonatype.org/content/repositories/snapshots/ + + + sonatype-nexus-staging + Nexus Release Repository + https://s01.oss.sonatype.org/service/local/staging/deploy/maven2/ + + + iabgpp-encoder iabgpp-extras iabgpp-extras-jackson + + UTF-8 + 1.8 + 1.8 + + + + + + + org.apache.maven.plugins + maven-source-plugin + 3.2.0 + + + attach-sources + verify + + jar-no-fork + + + + + + org.apache.maven.plugins + maven-javadoc-plugin + 3.3.1 + + + attach-javadoc + verify + + jar + + + + + + org.apache.maven.plugins + maven-gpg-plugin + 1.5 + + + sign-artifacts + verify + + sign + + + + + + + + + + + release + + + + org.apache.maven.plugins + maven-source-plugin + + + org.apache.maven.plugins + maven-javadoc-plugin + + + org.apache.maven.plugins + maven-gpg-plugin + + + + +