var iomAmp = function () {
  "use strict";

  function decodeBinary(string) {
    var result = "";
    for (var i = 0, length = string.length; i < length; i += 1) {
      var bits = string.charCodeAt(i).toString(2);
      var pad = "00000000".slice(0, 8 - bits.length);
      result += pad + bits;
    }
    return result;
  }

  function decodeBase64(string) {
    if (typeof atob === "function") {
      var stringFixed = string.replace(/_/g, "/").replace(/-/g, "+");
      try {
        return atob(stringFixed);
      } catch (error) {
        throw new Error("Unable to decode transparency and consent string");
      }
    }
    if (typeof Buffer === "function") {
      return Buffer.from(string, "base64").toString("binary");
    }
    throw new Error("Unable to detect base64 decoder");
  }

  function decodeInt(bits) {
    return parseInt(bits, 2) || 0;
  }

  function decodeDate(bits) {
    return decodeInt(bits) * 100;
  }

  function decodeString(bits) {
    var charOffset = "A".charCodeAt();
    var items = bits.match(/.{6}/g) || [];
    var result = "";
    for (var i = 0, length = items.length; i < length; i += 1) {
      var charCode = decodeInt(items[i]) + charOffset;
      result += String.fromCharCode(charCode);
    }
    return result;
  }

  function decodeBoolean(bit) {
    return Boolean(Number(bit));
  }

  function decodeFlags(bits) {
    var items = bits.split("");
    var result = {};
    for (var i = 0, length = items.length; i < length; i += 1) {
      if (decodeBoolean(items[i])) {
        result[i + 1] = true;
      }
    }
    return result;
  }

  function getSegments(string) {
    if (typeof string !== "string") {
      throw new Error("Invalid transparency and consent string specified");
    }
    var stringBlocks = string.split(".");
    var result = [];
    for (var i = 0, length = stringBlocks.length; i < length; i += 1) {
      result.push(decodeBinary(decodeBase64(stringBlocks[i])));
    }
    var version = decodeInt(result[0].slice(0, 6));
    if (version !== 2) {
      throw new Error("Unsupported transparency and consent string version “" + version + "”");
    }
    return result;
  }

  function getQueue(segments) {
    var queuePurposes = [{
      key: "purposeConsents",
      size: 24,
      decoder: decodeFlags
    }, {
      key: "purposeLegitimateInterests",
      size: 24,
      decoder: decodeFlags
    }];
    var queueVendors = [{
      key: "maxVendorId",
      size: 16
    }, {
      key: "isRangeEncoding",
      size: 1,
      decoder: decodeBoolean
    }];
    var queueCore = [{
      key: "version",
      size: 6
    }, {
      key: "created",
      size: 36,
      decoder: decodeDate
    }, {
      key: "lastUpdated",
      size: 36,
      decoder: decodeDate
    }, {
      key: "cmpId",
      size: 12
    }, {
      key: "cmpVersion",
      size: 12
    }, {
      key: "consentScreen",
      size: 6
    }, {
      key: "consentLanguage",
      size: 12,
      decoder: decodeString
    }, {
      key: "vendorListVersion",
      size: 12
    }, {
      key: "policyVersion",
      size: 6
    }, {
      key: "isServiceSpecified",
      size: 1,
      decoder: decodeBoolean
    }, {
      key: "useNonStandardStacks",
      size: 1,
      decoder: decodeBoolean
    }, {
      key: "specialFeatureOptins",
      size: 12,
      decoder: decodeFlags
    }].concat(queuePurposes).concat({
      key: "purposeOneTreatment",
      size: 1,
      decoder: decodeBoolean
    }, {
      key: "publisherCountryCode",
      size: 12,
      decoder: decodeString
    }, {
      key: "vendorConsents",
      queue: [{
        key: "maxVendorId",
        size: 16
      }, {
        key: "isRangeEncoding",
        size: 1,
        decoder: decodeBoolean
      }]
    }, {
      key: "vendorLegitimateInterests",
      queue: queueVendors
    }, {
      key: "publisherRestrictions",
      queue: [{
        key: "numPubRestrictions",
        size: 12
      }]
    });
    var queueSegment = [{
      size: 3
    }];
    var queueDisclosedVendors = [].concat(queueSegment).concat(queueVendors);
    var queueAllowedVendors = [].concat(queueSegment).concat(queueVendors);
    var queuePublisherTC = [].concat(queueSegment).concat(queuePurposes).concat({
      key: "numCustomPurposes",
      size: 6
    });
    var result = [{
      key: "core",
      queue: queueCore
    }];
    for (var i = 1; i < segments.length; i += 1) {
      var segment = segments[i];
      var type = decodeInt(segment.slice(0, 3));
      if (type === 1) {
        result.push({
          key: "disclosedVendors",
          queue: queueDisclosedVendors
        });
      } else if (type === 2) {
        result.push({
          key: "allowedVendors",
          queue: queueAllowedVendors
        });
      } else if (type === 3) {
        result.push({
          key: "publisherTC",
          queue: queuePublisherTC
        });
      }
    }
    return result;
  }

  function parse(string) {
    function reduceQueue(queue, schema, value, result) {
      function reduceNumPubEntries() {
        if (result.pubRestrictionEntry && result.rangeEntry) {
          for (var key in result.rangeEntry) {
            if (Object.prototype.hasOwnProperty.call(result.rangeEntry, key)) {
              result.pubRestrictionEntry[key] = (result.pubRestrictionEntry[key] || []).concat(result.rangeEntry[key]);
            }
          }
        }
        if (result.numPubRestrictions) {
          result.numPubRestrictions -= 1;
          queue.push({
            key: "purposeId",
            size: 6
          }, {
            key: "restrictionType",
            size: 2
          }, {
            key: "numEntries",
            size: 12
          });
        }
      }

      function reduceNumEntries() {
        if (result.numEntries) {
          result.numEntries -= 1;
          queue.push({
            key: "isRange",
            size: 1,
            decoder: decodeBoolean
          }, {
            key: "startVendorId",
            size: 16
          });
        } else {
          reduceNumPubEntries();
        }
      }

      function getRangeResult() {
        if (result.purposeId) {
          return [{
            purpose: result.purposeId,
            isAllowed: result.restrictionType !== 0,
            isConsentRequired: result.restrictionType === 1,
            isLegitimateInterestRequired: result.restrictionType === 2
          }];
        }
        return true;
      }
      if (schema.key === "isRangeEncoding") {
        queue.push(value ? {
          key: "numEntries",
          size: 12
        } : {
          key: "bitField",
          size: result.maxVendorId,
          decoder: decodeFlags
        });
      } else if (schema.key === "numEntries") {
        result.rangeEntry = {};
        reduceNumEntries();
      } else if (schema.key === "isRange") {
        if (value) {
          queue.push({
            key: "endVendorId",
            size: 16
          });
        }
      } else if (schema.key === "startVendorId") {
        if (!result.isRange) {
          result.rangeEntry[value] = getRangeResult();
          reduceNumEntries();
        }
      } else if (schema.key === "endVendorId") {
        for (var vendorId = result.startVendorId; vendorId <= result.endVendorId; vendorId += 1) {
          result.rangeEntry[vendorId] = getRangeResult();
        }
        reduceNumEntries();
      } else if (schema.key === "numCustomPurposes") {
        queue.push({
          key: "customPurposeConsents",
          size: result.numCustomPurposes,
          decoder: decodeFlags
        }, {
          key: "customPurposeLegitimateInterests",
          size: result.numCustomPurposes,
          decoder: decodeFlags
        });
      } else if (schema.key === "numPubRestrictions") {
        result.pubRestrictionEntry = {};
        reduceNumPubEntries();
      }
    }

    function reduceResult(result) {
      return result.pubRestrictionEntry || result.rangeEntry || result.bitField || result;
    }
    var offset = 0;

    function getSchemaResult(schema, bits) {
      var value = bits.slice(offset, offset + schema.size);
      offset += schema.size;
      return (schema.decoder || decodeInt)(value);
    }

    function getSectionResult(sectionSchema, bits) {
      if (!sectionSchema.queue) {
        return getSchemaResult(sectionSchema, bits);
      }
      var result = {};
      for (var i = 0; i < sectionSchema.queue.length; i += 1) {
        var schema = sectionSchema.queue[i];
        var value = getSchemaResult(schema, bits);
        if (schema.key) {
          result[schema.key] = value;
        }
        reduceQueue(sectionSchema.queue, schema, value, result);
      }
      return reduceResult(result);
    }

    function getBlockResult(blockSchema, bits) {
      var result = {};
      for (var i = 0; i < blockSchema.queue.length; i += 1) {
        var schema = blockSchema.queue[i];
        var value = getSectionResult(schema, bits);
        if (schema.key) {
          result[schema.key] = value;
        }
        reduceQueue(blockSchema.queue, schema, value, result);
      }
      return reduceResult(result);
    }

    function getResult() {
      var segments = getSegments(string);
      var queue = getQueue(segments);
      var result = {};
      for (var i = 0; i < queue.length; i += 1) {
        var schema = queue[i];
        var bits = segments[i];
        var value = getBlockResult(schema, bits);
        if (schema.key) {
          result[schema.key] = value;
        }
        offset = 0;
      }
      return result;
    }
    return getResult();
  }
  var parser = parse;

  function parseConsentString(consentString) {
    try {
      return parser(consentString);
    } catch (error) {
      return null;
    }
  }

  function filterPurposes(flags) {
    return function (value) {
      return flags[value] === true;
    };
  }

  function mapPurposes(offset) {
    return function (value) {
      var exp = parseInt(value) + offset;
      return Math.pow(2, exp);
    };
  }

  function merge(purposes1, purposes2) {
    return purposes1.concat(purposes2.filter((function (item) {
      return purposes1.indexOf(item) < 0;
    })));
  }

  function padStart(str, size) {
    while (str.length < size) {
      str = "0" + str;
    }
    return str;
  }

  function convertConsentToHexString(consent) {
    var result = "";
    for (var i = 0, iLen = consent.length; i < iLen; i += 1) {
      var hex = consent[i].toString(16);
      var hexLen = 4;
      if (i === 0) {
        hexLen = 2;
      }
      hex = padStart(hex, hexLen);
      result += hex;
    }
    return result;
  }

  function createPurposesBitfield(purposes) {
    var result = 0;
    for (var i = 0, iLen = purposes.length; i < iLen; i += 1) {
      result |= purposes[i];
    }
    return result;
  }

  function extractPurposes(tcData, vendor) {
    var purposes = [];
    var purposeConsents = [];
    var legitimateInterests = [];
    var specialFeatureOptins = [];
    purposeConsents = Object.keys(tcData.purposeConsents).filter(filterPurposes(tcData.purposeConsents)).map(mapPurposes(-1));
    if (tcData.vendorLegitimateInterests[vendor] === true) {
      legitimateInterests = Object.keys(tcData.purposeLegitimateInterests).filter(filterPurposes(tcData.purposeLegitimateInterests)).map(mapPurposes(-1));
    }
    if (legitimateInterests.length > 0) {
      purposes = merge(purposeConsents, legitimateInterests);
    } else {
      purposes = purposeConsents;
    }
    if (tcData.specialFeatureOptins && Object.keys(tcData.specialFeatureOptins).length > 0) {
      Object.keys(tcData.specialFeatureOptins).filter(filterPurposes(tcData.specialFeatureOptins)).map(mapPurposes(9));
      purposes = purposes.concat(specialFeatureOptins);
    }
    return purposes;
  }

  function convertConsentString(vendors, consentString) {
    var tcData = parseConsentString(consentString);
    if (tcData && tcData.core && tcData.core.version >= 2) {
      var consent = [1];
      vendors.forEach((function (vendor) {
        if (tcData.core.vendorConsents[vendor] === true || tcData.core.vendorLegitimateInterests[vendor] === true) {
          var purposes = extractPurposes(tcData.core, vendor);
          consent.push(createPurposesBitfield(purposes));
        } else {
          consent.push(0);
        }
      }));
      return convertConsentToHexString(consent);
    }
    return "00" + vendors.map((function () {
      return "0000";
    })).join("");
  }
  var converter = convertConsentString;
  var vendors = ("[730, 785]".match(/[0-9]+/g) || []).map((function (vendor) {
    return parseInt(vendor, 10);
  }));
  var match;
  var pl = /\+/g;
  var search = /([^&=]+)=?([^&]*)/g;
  var decode = function decode(s) {
    return decodeURIComponent(s.replace(pl, " "));
  };
  var query = window.location.search.substring(1);
  var params = {};
  while (match = search.exec(query)) {
    params[decode(match[1])] = decode(match[2]);
  }
  if (Object.keys(params).indexOf("act") !== -1) {
    if (params.act) {
      params.ct = converter(vendors, params.act);
    } else {
      params.acs = 0;
    }
    delete params.act;
  }
  if (params.host) {
    params.ach = params.host;
    delete params.host;
  }
  if (params.path) {
    params.acp = params.path;
    delete params.path;
  }
  if (params.type === "event") {
    delete params.type;
    window.iom.i(params, 2);
    window.iom.e(params.ev);
  } else {
    delete params.type;
    window.iom.c(params, 2);
  }
  var amp_tpl = {};
  return amp_tpl;
}();