var truste = window.truste || {};
truste.bn || (truste.bn = {});
truste.eu || (truste.eu = {});
truste.util || (truste.util = {});

    /**
     * Outputs an error to console but also reports it back to the server.
     * @param {String} msg message regarding the error
     * @param {Error=} error The error object
     * @param {Object=} data Object containing data regarding the error
     */
    truste.util.error = function(msg,error,data){
        data = data || {};
        var errorString = error && error.toString() || "",
            caller = data.caller || "";
        if(error && error.stack){
            errorString += "\n" +error.stack.match(/(@|at)[^\n\r\t]*/)[0]+"\n"+error.stack.match(/(@|at)[^\n\r\t]*$/)[0];
        }
        truste.util.trace(msg, errorString, data);
        if(truste.util.debug || !error && !msg) return;

        var b = {
            apigwlambdaUrl: 'https://api-js-log.trustarc.com/error',
            enableJsLog: false
        };

        if (b.enableJsLog) { // send to api gateway and lambda
            //clean data of params which are used elsewhere
            delete data.caller;
            delete data.mod;
            delete data.domain;
            delete data.authority;
            data.msg = msg;

            var req = new (self.XMLHttpRequest||self.XDomainRequest||self.ActiveXObject)("MSXML2.XMLHTTP.3.0");
            req.open("POST",b.apigwlambdaUrl,true);
            req.setRequestHeader && req.setRequestHeader('Content-type','application/json');
            req.send(truste.util.getJSON({
                info : truste.util.getJSON(data) || "",
                error : errorString,
                caller : caller
            }));
        }
    };

    /**
     * Passes arguments to console.log if console.log exists and debug mode enabled (by setting or by host name)
     */
    truste.util.trace = function(){
        if( self.console && console.log && (this.debug || this.debug!==false &&
            (self.location.hostname.indexOf(".")<0 || self.location.hostname.indexOf(".truste-svc.net")>0))) {
            if (console.log.apply) {
                console.log.apply(console, arguments);
            }
            else { //FOR IE9
                var log = Function.prototype.bind.call(console.log, console);
                log.apply(console, arguments);
            }
            return true;
        }
        return false;
    };

    /**
     * JSON Stringify alternative. Uses default JSON if available, unless that JSON is a custom implementation.
     * @param {Object} ob Object to stringify
     * @return {String}
     */
    truste.util.getJSON = function(ob){
        if(self.JSON && !(self.JSON["org"]||self.JSON["license"]||self.JSON["copyright"])) return self.JSON.stringify(ob);
        if(ob instanceof Array){
            var s = "[";
            if(ob.length){
                s+=truste.util.getJSON(ob[0]);
                for(var i=1;i<ob.length;i++) s+=","+truste.util.getJSON(ob[i]);
            }
            return s+"]";
        }else if(typeof ob=="string"){
            return "\""+ob+"\"";
        }else if((ob) instanceof Object){
            var comma = false, s = "{";
            for(var g in ob){
                s+=(comma?",":"")+"\""+g+"\":"+truste.util.getJSON(ob[g]);
                comma = true;
            }
            return s+"}";
        }else return ob === undefined ? undefined : ob + "";
    };

    //Add window error listener
    (function(){
        var old = self.onerror;
        self.onerror = function truste_error_listener(msg, url, lineNm, colNum, errorOb){
            var args = [].slice.call(arguments);
            var mess = msg+(url?"; "+url:"")+(lineNm?" "+lineNm:"")+(colNum?":"+colNum:"");
            if((mess+""+(errorOb && errorOb.stack)).match(/truste|trustarc|notice/)){
                truste.util.error("Got Window Error:",errorOb && errorOb.stack ? errorOb : mess,{product:"cm",tag:url});
            }
            old && old.apply(self,args);
        };
    })();

truste.bn.addScriptElem = function(src,callback,containerId) {
    if(!src && "string" != typeof src) {
        return null;
    }
    var ele = document.createElement("SCRIPT");
    ele.src = src;
    ele.setAttribute("async","async");
    ele.setAttribute("crossorigin","");
    ele.setAttribute("importance","high");

    var nonceElem = document.querySelector('[nonce]');
    nonceElem && ele.setAttribute("nonce", nonceElem.nonce || nonceElem.getAttribute("nonce"));

    var listener = function(event) {
        var status;
        if(event && event.type=="error") {
            status = 2;
        } else if(event && event.type=="load" || ele.readyState == "loaded") {
            status = 1;
        }
        if(status){
            ele.onload = ele.onreadystatechange = ele.onerror = null;
            callback instanceof Function && callback(ele, status);
        }
    };
    ele.onload = ele.onreadystatechange = ele.onerror = listener;
    (document.getElementById(containerId) || document.getElementsByTagName("body")[0] || document.getElementsByTagName("head")[0]).appendChild(ele);
    return ele;
};

truste.bn.msglog = function(action, msgURL) {
    truste.eu && truste.eu.msg && truste.eu.msg.log(action, truste.eu.bindMap, msgURL);
};

 /**
     * Checks bindMap prefCookie (preference cookie) to see if the user has set a permission.
     * If reconsent is enabled, checks if should repop.
     * If consent resolution is enabled, checks if should repop.
     * Sets isReconsentEvent, isRepopEvent and dropPopCookie when applicable.
     * @returns {boolean} true if the user has not set a permission or if repop event.
    */
truste.bn.checkPreference = function() {
        if (truste.eu.bindMap) {
            var b = truste.eu.bindMap;

            if ((b.feat.crossDomain && !b.feat.isConsentRetrieved) ||
            (truste.util.isConsentCenter() && !b.feat.isConsentCenterInitialized)){
                b.bnFlags.consentUnresolved = true;
                return false;
            }

            var isReconsent = shouldRepop();
            if (isReconsent) {
                // set flag to true. repop cookie should be dropped to indicate latest repop time retrieved
                b.feat.dropPopCookie = true;
            }

            // if DNT or GPC auto output has been executed, check dnt show ui
            if (b.feat.isDNTOptoutEvent || b.feat.isGPCOptoutEvent) {
                return b.feat.dntShowUI;
            }

            if (b.prefCookie) {
                // if preference is found, check if repop event
                if (isReconsent || shouldResolveConsent()) {
                    b.feat.isRepopEvent = true;
                    b.feat.isReconsentEvent = isReconsent;
                }
            }

            return !b.prefCookie || b.feat.isRepopEvent;
        }
        return false;
   };

truste.bn.checkConsentUnresolved = function(showBanner, dontShowBanner){
    if (truste.eu.bindMap) {
        var bm = truste.eu.bindMap;
        var ii = setInterval(function() {
            if ((ii && bm.feat.isConsentRetrieved && !truste.util.isConsentCenter()) ||
            (ii && truste.util.isConsentCenter() && bm.feat.isConsentCenterInitialized != undefined)) {
                bm.bnFlags.consentUnresolved = false;
                ii = clearInterval(ii);
                if (truste.bn.checkPreference()) {
                    showBanner();
                } else {
                    dontShowBanner();
                }
            }
        }
        ,100);

        setTimeout(function() {
            ii = clearInterval(ii);
        }, 5500);
    }
}

/**
 * Checks Reconsent Time.
 * @returns {boolean} true if last reconsent time is not equal to current reconsent time and reconsent time has passed.
 */
function shouldRepop() {
    if (truste.eu.bindMap.popTime) {
        var now = new Date().getTime();
        var lastRepop = truste.util.readCookie(truste.eu.COOKIE_REPOP, !0);
        var popTime = truste.eu.bindMap.popTime;
        return popTime && popTime != lastRepop && now >= popTime;
    }
    return false;
}

function shouldResolveConsent() {
    var bindMap = truste.eu.bindMap;
    // check if consent resolution is enabled and current behavior is EU (we only repop banner on EU)
    if (bindMap.feat.consentResolution && bindMap.behaviorManager == 'eu') {
        var noticePref = truste.util.readCookie(truste.eu.COOKIE_GDPR_PREF_NAME, true);
        if (noticePref) {
            noticePref = noticePref.split(":");
            var currentBehaviorPattern = new RegExp(bindMap.behavior + '.' + bindMap.behaviorManager);
            if(!currentBehaviorPattern.test(noticePref[2])) {
                if (/(us|none)/i.test(noticePref[2])) {
                    return true;
                }
            }
        }
    }
    return false;
}


(function trustarcBanner(){
   
var bm = truste.eu.bindMap = {
        version: 'v1.7-675',
        domain: 'tpexpress.co.uk',
        //'assetsPath: 'asset/',
        width: parseInt('940'),
        height: parseInt('270'),
        baseName:'te-notice-clr1-b9902ff6-a304-4fbf-afb3-c156fbda9a22',
        showOverlay:'{ShowLink}',
        hideOverlay:'{HideLink}',
        anchName:'te-notice-clr1-b9902ff6-a304-4fbf-afb3-c156fbda9a22-anch',
        intDivName:'te-notice-clr1-b9902ff6-a304-4fbf-afb3-c156fbda9a22-itl',
        iconSpanId:'te-notice-clr1-b9902ff6-a304-4fbf-afb3-c156fbda9a22-icon',
        containerId: (!'teconsent' || /^_LB.*LB_$/.test('teconsent')) ? 'teconsent' : 'teconsent',
        messageBaseUrl:'http://consent.trustarc.com/noticemsg?',
        originBaseUrl: 'https://consent.trustarc.com/',
        daxSignature:'',
        privacyUrl:'',
        prefmgrUrl:'https://consent-pref.trustarc.com?type=tpexpress_co_uk_slider&layout=default_eu',
        text: 'true',
        icon:'Cookie Preferences',
        iframeTitle:'TrustArc Cookie Consent Manager',
        closeBtnAlt: 'close button',
        teconsentChildAriaLabel: 'Cookie Preferences, opens a dedicated popup modal window',
        locale:'en',
        language:'en',
        country:'zw',
        state: '',
        categoryCount: parseInt('3', 10) || 3,
        defaultCategory: 'Required cookies',
        noticeJsURL: ((parseInt('0') ? 'https://consent.trustarc.com/' : 'https://consent.trustarc.com/')) + 'asset/notice.js/v/v1.7-675',
        assetServerURL: (parseInt('0')? 'https://consent.trustarc.com/' : 'https://consent.trustarc.com/') + 'asset/',
        consensuUrl: 'https://consent.trustarc.com/',
        cdnURL: 'https://consent.trustarc.com/'.replace(/^(http:)?\/\//, "https://"),
        //baseUrl : 'https://consent.trustarc.com/notice?',
        iconBaseUrl: 'https://consent.trustarc.com/',
        behavior: 'implied',
        behaviorManager: 'eu',
        provisionedFeatures: '',
        cookiePreferenceIcon: 'cookiepref.png',
        cookieExpiry: parseInt('180', 10) || 395,
        closeButtonUrl: '//consent.trustarc.com/get?name=noticeclosebtn.png',
        apiDefaults: '{"reportlevel":16777215}',
        cmTimeout: parseInt('6000', 10),
        popTime: new Date(''.replace(' +0000', 'Z').replace(' ', 'T')).getTime() || null,
        popupMsg: '',
        bannerMsgURL: 'https://consent.trustarc.com/bannermsg?',
        IRMIntegrationURL: '',
        irmWidth: parseInt(''),
        irmHeight: parseInt(''),
        irmContainerId: (!'' || /^_LB.*LB_$/.test('')) ? 'teconsent' : '',
        irmText: '',
        lspa: '',
        ccpaText: '',
        containerRole: '',
        iconRole: '',
        atpIds: '',
        dntOptedIn: '',
        gpcOptedIn: '',
        seedUrl : '',
        cmId: '',
        feat: {
            iabGdprApplies:false,
            consentResolution: false,
            dropBehaviorCookie: true,
            crossDomain: true,
            uidEnabled : false,
            replaceDelimiter : false,
            optoutClose: false,
            enableIRM : false,
            enableCM: true,
            enableBanner : false,
            enableCCPA: false,
            enableCPRA: false,
            enableIrmAutoOptOut: false,
            ccpaApplies: false,
            unprovisionedDropBehavior: true,
            unprovisionedIab: false,
            unprovisionedCCPA: false,
            dnt: false && (navigator.doNotTrack == '1' || window.doNotTrack == '1'),
            dntShowUI: false,
            gpc: false && (navigator.globalPrivacyControl || window.globalPrivacyControl),
            gpcOvr: 'false' == 'true',
            iabBannerApplies: false,
            enableTwoStepVerification: false,
            enableContainerRole: true,
            enableContainerLabel: true,
            enableIconRole: true,
            enableIconLabel: true,
            enableHasPopUp: 'true' == 'true',
            enableReturnFocus: false,
            enableShopify: 0,
            enableTcfOptout: false,
            enableTcfVendorLegIntOptin: 'false' == 'true',
            enableTcfVendorPurposeOptinOverride: 'false' == 'true',
            enableTransparentAlt: true,
            enableACString: false,
            gcm: {
                ads: 2,
                analytics: 1,
                adPersonalization: 2,
                adUserData: 2,
                functionality: undefined,
                personalization: undefined,
                security: undefined,
            },
            gpp: {
                enabled: 'false' == 'true',
                mspaEnabled: 'false' == 'true',
                mspaMode: parseInt('0') || 0,
                enableStateSpecificString: 'false' == 'true',
                gppApplies: 'false' == 'true',
                gppShowCategories: 'false' == 'true',
                gppOptInAll: ''.replace(/\{GPPOptInAll\}/, '0,1,2')
            },
            autoblock: false,
            gtm: 1,
            enableStoredConsent: false,
            enableIab2_2: 'false' == 'true',
        },
        autoDisplayCloseButton : false,
        hideCloseButtonEnabled: 'false' == 'true', // can't use hideCloseButton cuz existing function name
        localization: {
            'modalTitle' : 'Your choices regarding the use of cookies on this site'
        },
        currentScript: self.document.currentScript
    };
    if (/layout=gdpr/.test(bm.prefmgrUrl)) {
        bm.isGdprLayout = true;
    }

    if (/layout=iab/.test(bm.prefmgrUrl)) {
        bm.isIabLayout = true;
    }

    if (/layout=gpp/.test(bm.prefmgrUrl)) {
        bm.isGppLayout = true;
    }

    if(self.location.protocol != "http:" ){
        for(var s in bm)
            if(bm[s] && bm[s].replace && typeof bm[s] === 'string'){
                bm[s] = bm[s].replace(/^(http:)?\/\//, "https://");
            }
    }

   
    (function() {
         // todo: remove backwards compatibility with old icon on subsequent release
        var cookieMatch = bm.seedUrl.match(/^{(SeedURL)}$/);
        if (cookieMatch && cookieMatch.length > 1) {
            bm.seedUrl = '';
        }

        cookieMatch = bm.cmId.match(/^{(CMID)}$/);
        if (cookieMatch && cookieMatch.length > 1) {
            bm.cmId = '';
        }
    })();

    truste.eu.noticeLP = truste.eu.noticeLP || {};
    truste.eu.noticeLP.pcookie = true;


   
truste.util.createCookie = function (name, value, exp, backupInStorage, skipConvert)
{
    if (truste.util.cookie && !skipConvert) {
        value = truste.util.cookie.convert(value);
    }

    var bm = truste.eu.bindMap || {},
        expires = "; expires=";
    var date;

    if (!exp) {
        date = new Date();
        date.setDate(date.getDate() + bm.cookieExpiry);
        expires += date.toGMTString();
    } else {
        if(exp=="0") {
            expires = "";
        } else {
            date = new Date(exp);
            expires += exp;
        }
    }

    // if dropping cookies with path, disable local storage backup since local storage is scoped to domain
    if (!bm.feat.cookiePath && backupInStorage && truste.util.createCookieStorage) {
        truste.util.createCookieStorage(name, value, date);
    }

    var b = bm.domain,
        host = self.location.hostname;
    var isIP = !!host.match(/^\d{0,3}\.\d{0,3}\.\d{0,3}\.\d{0,3}$/) || host == "localhost";

    var cookieDomain = isIP?host:host.replace(/^www\./,"");

    var isHttps = ((self.location.protocol == "https:") ? " Secure;" : "");
    var cookieAttrb = " SameSite=Strict;" + isHttps;

    //if client wants to use parent domain for the cookie
    if (typeof truste.eu.noticeLP.pcookie != 'undefined') {
        //delete existing cookie with complete domain to avoid inconsistent behavior due to duplicate cookies

        document.cookie = name+"=;expires=Thu, 01 Jan 1970 00:00:01 GMT; path=/;domain="+ (isIP?"":".") + cookieDomain.replace(/^\./,"") + ";" + cookieAttrb;

        if(!bm.topLevelDomain){
            //determine parent domain
            var i=0,domain=cookieDomain,p=domain.split('.'), cookieArray = [],s='_gd'+(new Date()).getTime();
            while(i<(p.length-1) && document.cookie.indexOf(s+'='+s)==-1){
                domain = p.slice(-1-(++i)).join('.');
                document.cookie = s+"="+s+";domain="+domain+";"+cookieAttrb;
                cookieArray.push(s);
            }
            bm.topLevelDomain = domain;
            //use-case for invalid first domains
            for(var index = 0; index < cookieArray.length; index++) {
                document.cookie = cookieArray[index] +"=;expires=Thu, 01 Jan 1970 00:00:01 GMT;domain="+domain+";";
            }

            document.cookie = s+"=;expires=Thu, 01 Jan 1970 00:00:01 GMT;domain="+domain+";" + cookieAttrb;
        }

        //assign parent domain as the domain to use for the cookie
        cookieDomain = bm.topLevelDomain;
    }

    var path = "/";
    if (bm.feat.cookiePath) {
        path += location.pathname.split('/')[1];
    }

    self.document.cookie = name + "=" + value + expires + "; path=" + path + ";domain="+ (isIP?"":".") + cookieDomain.replace(/^\./,"") + ";" + cookieAttrb;
};


   

truste.util.getRandomUUID = function () {
    var cryptoObj = window.crypto || window.msCrypto;

    return ([1e7]+-1e3+-4e3+-8e3+-1e11).replace(/[018]/g,
        function(c) {
            return (c ^ cryptoObj.getRandomValues(new Uint8Array(1))[0] & 15 >> c / 4).toString(16)
        }
    );
};



/**
 * Finds in the DOM the SCRIPT element matching the "search" regex.
 * In combination with withIdOK==false, this allows one to skip previously found elements.
 * 
 * @param {(String|RegExp)} search the regexp to search for
 * @param {Boolean} withIdOK Boolean when false, elements with an "id" are skipped.
 */
truste.util.getScriptElement = function(search,withIdOK,extraCheck) {
    if(typeof search == "string"){
        search = new RegExp(search);
    }
    if(typeof extraCheck == "string"){
        extraCheck = new RegExp(extraCheck);
    }

    if(!(search instanceof RegExp)) {
        return null;
    }
    if(typeof extraCheck != "undefined" && !(extraCheck instanceof RegExp)) {
        return null;
    }

	var list = self.document.getElementsByTagName("script");
    var hasCorrectDomain;
	for(var a, i = list.length; i-- > 0 && (a = list[i]); ) {
		hasCorrectDomain = (extraCheck) ? extraCheck.test(a.src) : true;
        if( (withIdOK || !a.id) && search.test(a.src) && hasCorrectDomain)
			return a;
	}
	return null;
};
truste.util.getUniqueID = function(){
  return "truste_"+Math.random();
};
/**
 * binds parameters on the element's URL to an object
 * special "_url" is the full URL
 * special "_query" is the full QUERY (search) portion of the URL
 * @param {HTMLScriptElement} ele The script element whose SRC you want to use
 * @param {!Object} map The object on to which to apply the bindings
 * @returns {Object} the map parameter
 */
truste.util.initParameterMap = function(ele,map) {
    if(!(map instanceof Object))
        map = {};
    if(!ele || typeof ele.src != "string"){
		map["_query"] = map["_url"] = "";
	}else{
		var i,url = map["_url"] = ele.src;
		url = (map["_query"] = url.replace(/^[^;?#]*[;?#]/,"")).replace(/[#;?&]+/g,"&");
		if (url) {
			for ( url = url.split('&'), i = url.length; i-- > 0;) {
				var s = url[i].split('='),
                    param = s.shift();
                if (!map[param]) {
                    if (s.length) {
                        map[param] = decodeURIComponent(s.join('='));
                    } else {
                        map[param] = "";
                    }
                }
			}
		}
		ele.id = map.sid = map.sid || truste.util.getUniqueID();
	}
	return map;
};



truste.eu.COOKIE_GDPR_PREF_NAME = 'notice_gdpr_prefs';
truste.eu.COOKIE_SESSION = 'TAsessionID';

truste.eu.SCRIPT_REGX = truste.eu.SCRIPT_REGX || /\.(truste|trustarc)\b.*\bnotice(\.0)?(\.exp)?(\.js)?\b.*\bdomain=/;
truste.eu.JS_REGX = truste.eu.JS_REGX || (truste.eu.bindMap && truste.eu.bindMap.domain ? 'domain=' + truste.eu.bindMap.domain : undefined);

truste.eu.jsNode1 = truste.eu.bindMap.currentScript || truste.util.getScriptElement(truste.eu.SCRIPT_REGX,true,truste.eu.JS_REGX);
truste.eu.noticeLP = truste.util.initParameterMap(truste.eu.jsNode1, truste.eu.noticeLP || {});

if (truste.eu.noticeLP.cookieName) {
    truste.eu.COOKIE_GDPR_PREF_NAME = truste.eu.noticeLP.cookieName + "_gdpr";
    truste.eu.COOKIE_SESSION = truste.eu.noticeLP.cookieName + "_session";
}

truste.util.readCookieSimple = function(name) {
    var rx = new RegExp("\\s*"+name.replace(".","\\.")+"\\s*=\\s*([^;]*)").exec(self.document.cookie);
    if(rx && rx.length > 1){
        return rx[1];
    }
    return null;
};

var sessionCookie = truste.util.readCookieSimple(truste.eu.COOKIE_SESSION);
if (sessionCookie == null) {
    userType = truste.util.readCookieSimple(truste.eu.COOKIE_GDPR_PREF_NAME) ? 'EXISTING' : 'NEW';
    sessionCookie = truste.util.getRandomUUID() + "|" + userType;
    var expire = new Date();
    expire.setTime(expire.getTime() + 30*60000);
    truste.util.createCookie(truste.eu.COOKIE_SESSION, sessionCookie, expire.toGMTString(), false);
}
var sessionCookieArray = sessionCookie.split(/[|,]/)
truste.eu.session = sessionCookieArray[0];
truste.eu.userType = sessionCookieArray[1];




   //impression logging
   (new Image(1,1)).src = ('https://consent.trustarc.com/log'.replace('http:', 'https:')) + '?domain=tpexpress.co.uk&country=zw&state=&behavior=implied&session='+truste.eu.session+'&userType='+truste.eu.userType+'&c=' + (((1+Math.random())*0x10000)|0).toString(16).substring(1)+'&referer='+window.origin+'&language=en';

   
(function (bm) {
    var appendCmpJs = function(url) {
        if (bm.feat.iab) return; // do not call cmp more than once
        var d = self.document,
            e = d.createElement("script");
        e.setAttribute("async","async");
        e.setAttribute("type","text/javascript");
        e.setAttribute("crossorigin","");
        e.setAttribute("importance","high");
        var nonceElem = document.querySelector('[nonce]');
        nonceElem && e.setAttribute("nonce", nonceElem.nonce || nonceElem.getAttribute("nonce"));
        e.src = url;
        (   d.getElementById(bm.containerId) ||
            d.getElementsByTagName("body")[0] ||
            d.getElementsByTagName("head")[0]
        ).appendChild(e);
        bm.feat.iab = true;
    };

    var executeOnCondition = function(condition, callback, interval, time) {
        if(condition()) {
            callback();
            return;
        }
        var ii, intervalCallback = function(){
            if(condition()) {
                ii = clearInterval(ii);
                callback();
            }
        };
        ii = setInterval(intervalCallback,interval);
        intervalCallback();

        setTimeout(function(){clearInterval(ii)}, time);
    };

    if(bm.isIabLayout) {
        // IAB v2
        // check if tcfapi script has been appended to head
        var tcfLoaded = false;
        var headScripts = document.head.getElementsByTagName("script");
        for(var ind = 0; ind < headScripts.length; ind++) {
            var hScript = headScripts[ind];
            if (hScript.id === 'trustarc-tcfapi') {
                tcfLoaded = true;
                bm.feat.iab = true;
            }
        }
        if (!tcfLoaded) {
            executeOnCondition(
                function v2StubExists() {
                    return typeof __tcfapi !== 'undefined';
                },
                function appendIABv2() {
                    if (bm.feat.enableIab2_2) {
                        appendCmpJs(bm.consensuUrl+"asset/tcfapi2.2.js");
                    } else {
                        appendCmpJs(bm.consensuUrl+"asset/tcfapi.js/v/2.1");
                    }
                }, 10,30000);
        }
    }
})(truste.eu.bindMap);


   
if (bm.feat.dropBehaviorCookie) {
    var delimeter = bm.feat.replaceDelimiter ? '|' : ',';
    truste.util.createCookie('notice_behavior', bm.behavior + delimeter + bm.behaviorManager, '0');
}


   
(function (bm) {
    if (bm.feat.crossDomain) {
        var addFrame = function() {
            if (!window.frames['trustarc_notice']) {
                if (document.body) {
                    var body = document.body,
                        iframe = document.createElement('iframe');
                    iframe.style.display = "none";
                    iframe.name = 'trustarc_notice';
                    iframe.id = 'trustarcNoticeFrame';
                    iframe.title = 'Trustarc Cross-Domain Consent Frame'
                    iframe.src = bm.cdnURL + 'get?name=crossdomain.html&domain=' + bm.domain;
                    body.appendChild(iframe);
                } else {
                    // this allows us to inject the iframe more quickly than
                    // relying on DOMContentLoaded or other events.
                    setTimeout(addFrame, 5);
                }
            }
        };
        addFrame();
    }
})(truste.eu.bindMap);



   
    $temp_box_overlay = {'margin':'20px auto!important'};
$temp_closebtn_style = {'top':'10px','right':'10px'};
$temp_box_overlay_border = {'display': 'none'};
$temp_externalcss = " @media screen and (max-width: 500px){.truste_box_overlay{padding: 0;top: unset !important;  margin: 10px auto !important; width: 97%;}.truste_popframe {border-radius: 4px;}} ";

var _i_ = setInterval(function() {
    waitForElem = function(condition, callback, interval, time) {
    if (typeof MutationObserver !== "undefined") {
        var observer = new MutationObserver(function taWaitElem(mutations) {
            if(condition()) {
                //stop observing
                observer.disconnect();
                callback();
            }
        });
        observer.observe(document, { attributes: false, childList: true, characterData: false, subtree: true });
        // limit stop observing
        setTimeout(function() { observer.disconnect(); }, time);
    }
    };
    
    var getShowConsent = () => {
            return document.getElementById('truste-show-consent');
        };
    
    waitForElem(getShowConsent, function () {
        var truste_show_consent = document.getElementById('truste-show-consent');
    
          if(truste_show_consent) {
            var _taShowModal = truste_show_consent.onclick;
            truste_show_consent.onclick = function() {
              var truste_consent_track = document.getElementById('truste-consent-track');
              if(truste_consent_track){ 
                // truste.bn.hide(document.getElementById('truste-consent-track'));
                truste_consent_track.style.display='none';
                _taShowModal();
                
                var observer = new MutationObserver(function(mutations) {
                    if (!document.getElementById(truste.eu.popdiv2)) {
                        if (truste.eu.bindMap.prefCookie) {
                            truste.bn.hide(document.getElementById('truste-consent-track'));
                            console.log('done hiding');
                        } else {
                            truste.bn.show(document.getElementById('truste-consent-track'));
                            console.log('done displaying');
                        }
                    }
                });
                observer.observe(document.body, {childList: true, subtree: true});
                setTimeout(() => {
                    observer.disconnect();
                    console.debug('closing observer after 30 seconds')
                }, 30 * 1000);
              }
            }
        
            var _taHideModal = truste.eu.prefclosebutton;
              truste.eu.prefclosebutton = function() {
              var truste_consent_track = document.getElementById('truste-consent-track');
              if(truste_consent_track){ 
                truste_consent_track.style.display='block';
                console.log('done hide');
                _taHideModal();
              }
            }
          }
        
    } , 500, 30000);
      
      _i_ = clearInterval(_i_);
}, 500);
    bm.styles = {};
    bm.externalcss = typeof $temp_externalcss != 'undefined' && $temp_externalcss;
    bm.styles.closebtnlink = typeof $temp_closebtnlink_style != 'undefined' && $temp_closebtnlink_style;
    bm.styles.closebtn = typeof $temp_closebtn_style != 'undefined' && $temp_closebtn_style;
    bm.styles.box_overlay = typeof $temp_box_overlay != 'undefined' && $temp_box_overlay;
    bm.styles.box_overlay_border = typeof $temp_box_overlay_border != 'undefined' && $temp_box_overlay_border;
    bm.styles.overlay = typeof $temp_overlay != 'undefined' && $temp_overlay;
    bm.styles.inner_iframe = typeof $temp_inner_iframe != 'undefined' && $temp_inner_iframe;
    bm.styles.outerdiv = typeof $temp_style_outerdiv != 'undefined' && $temp_style_outerdiv;
    bm.outerdiv = typeof $temp_outerdiv != 'undefined';
    bm.feat.target =  typeof $temp_target != 'undefined' && $temp_target;
    bm.feat.ccpadefault =  typeof $temp_ccpadefault != 'undefined' && $temp_ccpadefault;
    bm.feat.noscrolltop = typeof $temp_noscrolltop != 'undefined' && $temp_noscrolltop;


   bm.params = {};
   bm.bnFlags = {};
   truste.bn.addScriptElem(bm.noticeJsURL,
       function callNoticeCallback() {
           //notice js has loaded
           var interval;
           var checkNotice = function() {
               if(interval && truste.eu.flags && truste.eu.flags.init) {
                   interval = clearInterval(interval);
                   trustarcBanner.script = truste.eu.bindMap.currentScript || truste.util.getScriptElement(/\/\/([^\.]+\.)+(intranet\.)?(truste|trustarc)(-labs|-svc)?\.(com|net|eu)(:\n+)?\/[^\?#;]*(notice|banner).*?(js=bb|nj)/, true);
                   truste.util.initParameterMap(trustarcBanner.script, bm.params);

                   var dontShowBanner = function() {
                       var cmContainer = document.getElementById(bm.params.c || "teconsent");
                       if (cmContainer && cmContainer.style.display === "none") {
                           cmContainer.style.display = "";
                       }
                       truste.bn.msglog("returns", bm.bannerMsgURL);
                   };

                   if (bm.feat.ccpaApplies || shouldShowBanner()) {
                       truste.bn.bannerMain();
                   } else if(bm.bnFlags.consentUnresolved) {
                        truste.bn.checkConsentUnresolved(truste.bn.bannerMain, dontShowBanner);
                   } else {
                       dontShowBanner();
                   }

               }
           };
           interval = setInterval(checkNotice,7);
           //only attempt to track it for maximum of 10 seconds. for performance reasons.
           setTimeout(function(){ clearInterval(interval); }, 10000);
       }, bm.containerId);

   /**
    *  Check if the banner should be shown or not. Only shows on "eu" or if show banner is selected and if no user permission is set.
    *  @returns {Boolean}
   */
    function shouldShowBanner() {
      var isIOS = /ip(hone|od|ad)|iOS/i.test(navigator.userAgent || navigator.vendor || window.opera);
      return (truste.eu.bindMap.ios != 1 || !isIOS) && truste.bn.checkPreference();
    }

})();

truste.bn.isConsentTrack = true;

truste.bn.round = function(value, decimals) {
    return Number(Math.round(value+'e'+decimals)+'e-'+decimals);
};

truste.bn.getDefaultStyleProperty = function(propertyName, tagName) {
    var pseudoElem = document.createElement(tagName);
    document.body.appendChild(pseudoElem);
    var defaultStyle =  window.getComputedStyle(pseudoElem, null)[propertyName];
    pseudoElem.parentNode.removeChild(pseudoElem);
    return defaultStyle;
};

//returns default display property value of element if computed display is "none", otherwise returns computed display property value
truste.bn.getDisplayProperty = function (elem){
    var displayComputed = window.getComputedStyle(elem,null).display;
    return (displayComputed == "none") ? truste.bn.getDefaultStyleProperty('display',elem.nodeName) : displayComputed;
};

//doesn't necessarily reverse hide
truste.bn.show = function(elem){
    if (!elem) return;
    var displayProperty = truste.bn.getDisplayProperty(elem);
    if (typeof requestAnimationFrame !== 'undefined') {
        elem.style.opacity = 0;
        elem.style.display =  displayProperty;

        (function fadeIn(elem) {
            var val = truste.bn.round(parseFloat(elem.style.opacity),2);
            if (((val = val + 0.1) <= 1) && (elem.id != 'truste-consent-track'  || truste.bn.isConsentTrack)) {
                elem.style.opacity = val;
                requestAnimationFrame(function() {
                    fadeIn(elem);
                });
            }
        })(elem);
    } else {
        elem.style.display =  displayProperty;
    }
};

truste.bn.hide = function(elem) {
    if (!elem) return;
    if (typeof requestAnimationFrame !== 'undefined') {
        (function fadeOut(elem) {
            var val = truste.bn.round(parseFloat(elem.style.opacity || 1),2);
            val = val - 0.1;
            elem.style.opacity = val;
            if (val <= 0) {
                elem.style.display = "none";
            } else {
                requestAnimationFrame( function() {
                    fadeOut(elem);
                });
            }
        })(elem);
    } else {
        elem.style.display = 'none';
    }
};

truste.bn.isVisible = function(elem) {
    var style = window.getComputedStyle(elem);
    return style.display !== 'none' && style.opacity > 0 && style.visibility !== 'hidden';
};

truste.bn.removeEvent = function(obj, etype, fn) {
    if (obj && typeof etype == "string" && fn instanceof Function) {
        if (obj.removeEventListener) {
            obj.removeEventListener(etype, fn, false);
        } else if (obj.detachEvent) {
            obj.detachEvent('on' + etype, fn);
        }
    }
};

truste.bn.addEvent = function(obj, etype, fn) {
    if (obj && typeof etype == "string" && fn instanceof Function) {
        if (obj.addEventListener) {
            obj.addEventListener(etype, fn, false);
        } else if (obj.attachEvent) {
            obj.attachEvent('on' + etype, fn);
        }
    }
};

/* Black Bar Implementation
 *
 * Parameters:
 * 		domain  -  can override bindings from server
 * 		baseURL  -  can override bindings from server
 * 		country  -  can override bindings from server
 * 		c  -  div id for the cookie preferences icon (teconsent)
 * 		bb  -  div id for the black bar
 * 	    pn  - the page number of the Consent Manager, zero is default.
 * 		cm  -  scheme+host+path of the URL you want to use for the CM, if default is not desired
 * 		cdn  -  if exists, just means to forward the same URL you would have used to the CDN version instead.
 * 		cookieLink  -  URL which the 'cookie preferences' button will open a new tab to
 * 		privacypolicylink  -  URL which the 'privacy policy' button will open a new tab to
 * 		fade  -  if you wish the bar to fade after a certain time, can set a timeout, in ms, using this.
 * 		sl  -  if fade is used, and the bar fades, can optionally set a user preference on this event.
 * 				on fade, if sl is missing, no preference is set. If sl==-1, a 24hr temporary preference is set. If sl==0, required preference is set.
 * 				if sl==1, functional preference is set. if sl==2, advertising preference is set.
 *
 */

truste.bn.bannerMain = function(){
    var bm = truste.eu.bindMap;
    bm.bannerMsgURL = bm.iconBaseUrl + 'bannermsg?';
    var params = bm.params;
    //div id for the consent manager
    var divID = params.c || "teconsent";
    //div id for the black bar
    var bbdivID = params.bb || "consent_blackbar";

    //div id for the footer adicon text. if param is a number, default ID is used. else param is used.

    if(!document.getElementById(bbdivID)) {
        if (typeof MutationObserver !== "undefined") {
            var observer = new MutationObserver(function bannerObserver(mutations) {
                if(document.getElementById(bbdivID)) {
                    //stop observing
                    observer.disconnect();
                    cmBannerScript(params, divID, bbdivID);
                }

            });
            observer.observe(document.body || document.getElementsByTagName("body")[0] || document.documentElement, { attributes: false, childList: true, characterData: false, subtree: true });
            //stop observing after 60 seconds
            setTimeout(function() { observer.disconnect(); },60000);
        } else {
            var ii = setInterval(function waitForContainers(){
                if (document.getElementById(bbdivID)) {
                    ii = clearInterval(ii);
                    cmBannerScript(params, divID, bbdivID);
                }
            },150);
            //stop checking after 10 seconds
            setTimeout(function(){clearInterval(ii)}, 10000);
        }
    } else {
        cmBannerScript(params, divID, bbdivID);
    }

    function cmBannerScript(params, divID, bbdivID) {
        var category_count = 3;
            category_count = (category_count > 0) ? category_count : 3;

        var b = truste.eu.bindMap;
        var CM_CONSENT_COOKIE_VALUE = (function getGDPRConsent(maxValue) {
                                var consent=[];
                                for (var i = 0; i < maxValue; i++) {
                                    consent.push(i);
                                }
                                return consent.join(',');
                            })(category_count);

        if (b.feat.gpp.gppApplies && !b.feat.gpp.gppShowCategories) {
            CM_CONSENT_COOKIE_VALUE = b.feat.gpp.gppOptInAll;
        }

        var CM_BANNER_HOLDER = "truste-consent-track";
        var isIE = /MSEI|Trident/.test(navigator.userAgent);
        var androidVersion = /\bandroid (\d+(?:\.\d+)+);/gi.exec(navigator.userAgent);
        var isAndroid4 = (androidVersion && androidVersion[1] <= "4.4");
        var cmContainer =  document.getElementById(divID);
        var bbContainer =  document.getElementById(bbdivID);

        var BANNER_ELEM_IDS = {
            consentButton: "truste-consent-button",
            footerCallback: "truste-show-consent",
            cookieButton: "truste-cookie-button",
            privacyButton: "truste-privacy-button",
            bannerHolder: CM_BANNER_HOLDER,
            closeBanner: "truste-consent-close",
            repopDiv: "truste-repop-msg",
            requiredButton: "truste-consent-required",
            ccpaOptoutButton: "truste-ccpa-optout",
            ccpaOptedIn: "ccpa-opted-in",
            ccpaOptedOut: "ccpa-opted-out",
            ccpaNoPreference: "ccpa-no-preference",
            iabPartnersLink: "iab-partners-link",
            secondIabPartnersLink: "iab-second-partners-link"
        };
  
  		var CM_TARGET = truste.eu.bindMap.feat.target || "_blank";
  
        var readyState = document.readyState;
        if (readyState && (readyState == 'complete' || readyState == 'interactive')) {
            status("loaded");
        } else {
            truste.bn.addEvent(document, "DOMContentLoaded", function() {
                status("loaded");
            });
        }

        //This is the stateful Controller. Performs certain actions when receives a new state.
        //Cumulative State, meaning only accepts state additions.
        function status(topic) {
            if(status[topic]) return;
            status[topic] = 1;
            switch(topic) {
                case "loaded":
                    //Everything is loaded, let's go
                    if(bbContainer) {
                        setDocListeners();
                        makeBanner();
                        setBannerEvents();
                        if(truste.bn.checkPreference()){
                            showBanner();
                        } else if(bm.bnFlags.consentUnresolved) {
                            truste.bn.checkConsentUnresolved(showBanner, dontShowBanner);
                        } else {
                            dontShowBanner();
                        }

                    }
                    break;
                case "done":
                    truste.bn.isConsentTrack = false;
                    truste.bn.removeEvent(document, "click", ocListener);
                    truste.bn.removeEvent(document, "scroll", pxListener);
                    truste.bn.show(cmContainer);
                    truste.bn.hide(document.getElementById(CM_BANNER_HOLDER));
                    updateCmpApiDisplayStatus('hidden');
                    break;
                case "open":
                    try {
                        if (isIE || isAndroid4) {
                            var evt = document.createEvent('UIEvents');
                            evt.initUIEvent('resize', true, false, window, 0);
                            window.dispatchEvent(evt);
                        } else {
                            window.dispatchEvent(new Event('resize'));
                        }
                    }catch(e){
                        console && console.log("Resize event not supported.");
                    }
            }

        }

        /**
         * Contructs banner and inserts it into the DOM
         @param {String} hasPmIcon pm container id, for boolean usage. indicates whether or not pm icon container exists.
         @param {Object} pmContainer Element that holds pm icon.
         */
        function makeBanner() {
            var bannerContents = '<style>@font-face{    font-family:"Gotham Bold";    src:     url(https://consent.trustarc.com/get?name=Gotham-Bold.otf) format("opentype");}@font-face{    font-family:"Gotham Book";    src:     url(https://consent.trustarc.com/get?name=Gotham-Book.otf) format("opentype"),    url(https://consent.trustarc.com/get?name=GothamBook.eot) format("embedded-opentype"),    url(https://consent.trustarc.com/get?name=GothamBook.woff) format("woff");}#truste-consent-track {  margin: 0 auto;  position: fixed;  box-sizing: border-box;  bottom:20px;  right:0px;  left: 0px;}.truste-banner {  display: flex;  justify-content: space-between;  flex-direction: row;  flex-wrap: wrap;  width: 100%;  background: #fff;  border-radius: 5px !important;  max-width: 1130px;  height: 245px;  margin: 0 auto;/*   border: 1px solid red; */  padding: 50px 32px 0px 32px;}div.truste-consent-track-class {  position: relative;  z-index: 9999999;  display: flex;  align-items: center;  justify-content: center;  padding: 0px 10px;}.truste-title {  font-family: "Gotham Bold", sans-serif;  font-size: 22px;  font-weight: 700;/*   padding: 24px 32px; */  box-sizing: border-box;  width: 100%;  font-weight: 700;  line-height: 27px;  color: #1e234f;  width: 100%;  margin-bottom: 10px;}.truste-messageColumn {  font-family: "Gotham Book", sans-serif;  letter-spacing: 1px;  font-size: 14px;  font-weight: 400;  color: #1e234f;  width: 70%;/*   padding: 24px 32px; */}.truste-messageColumn p {  margin: 0px;}.truste-buttonsColumn {  display: flex;  width: auto;  box-sizing: border-box;/*   padding: 24px 32px; */  flex-direction: column;  align-self: flex-start;  width: 20%;  line-height: 1.5;  margin-top: -50px;}.truste-button {  font-family: "Gotham Book", sans-serif;  font-size: 16px;  padding: 12px 8px !important;  background: #fff;  text-decoration: none;  padding: 0px;  border-radius: 5px;  cursor: pointer !important;  }#truste-show-consent {  font-size: 16px;  color: #1e234f;   border: 1px solid #1e234f;  letter-spacing: 0.5px;    font-weight: 400; }#truste-consent-required {  font-size: 16px;  color: #1e234f;  border: 1px solid #1e234f;  margin: 15px 0px;  letter-spacing: 0.5px;    font-weight: 400; }#truste-consent-button {  font-size: 16px;  color: #fff;  background: #1e234f;  cursor: pointer;  border: 0;  letter-spacing: 0.5px;    font-weight: 400;}#truste-cookie-button {  color: #1e234f;  display: inline;  font-family: "Gotham Book", sans-serif;}.hidedesktop {  display: none;  font-family: "Gotham Book", sans-serif;  font-size: 14px;  cursor: pointer;  color: #00559c;  text-decoration: none;}.truste-cookie-link {  font-family: "Gotham Book", sans-serif;  font-size: 16px;  cursor: pointer;  color: #fff;  text-decoration: underline;  display: inline-block;  padding: 5px;  display: none;}#trustarc-banner-overlay {  background-color: #696e73;  opacity: 0.6;  position: fixed;  z-index: 1000000;  width: 100%;  height: 100%;  top: 0px;  left: 0px;  overflow: hidden;}.truste-consent-footer {  width: 100%;/*   padding: 24px 32px; */  display: flex;  align-items: center;  box-sizing: border-box;   color: #1e234f;  border-radius: 0px 0px 5px 5px;  width: 100%;  background: #fff;  width: 100%;   justify-content: space-between;  font-family: "Gotham Book", sans-serif;  font-size: 12px;}.truste-consent-footer a {  font-size: 12px;  color: #1e234f;  text-decoration: underline;}/* MEDIA QUERIES */@media screen and (min-width: 1px) and (max-width: 540px) {/*   .truste-buttonsColumn {    flex-direction: column-reverse !important;    align-items: center;  }  #truste-show-consent {    margin-right: 0;  }  .truste-title {    padding: 16px;  }  .truste-messageColumn {    padding: 16px;  }  .truste-buttonsColumn {    padding: 16px;  }  .truste-consent-footer {    padding: 16px;  }  #truste-consent-required {    margin: 24px 0px;  }  #truste-consent-button {    width: 100%;  } */}@media screen and (min-width: 1px) and (max-width: 686px) {  .truste-banner {    padding: 16px 16px 0px 16px;    height: 415px;    flex-direction: column !important;    flex-wrap: nowrap;    justify-content: space-around;    margin: 0 auto;  }  .truste-buttonsColumn {    margin-top: 0px !important;width: 200px;    margin: 0 auto;  }    .truste-title, .truste-messageColumn {    text-align: center;  }    .truste-title {    font-size: 18px !important;    margin: 0;  }    .truste-messageColumn p {    font-size: 12px !important;  }    .truste-button {    font-size: 14px !important;  }    .truste-messageColumn {width: 100%;}  #truste-consent-required {margin: 16px 0px;}}</style><div id="truste-consent-track" style="background-color:#fff;">	<div id="trustarc-banner-overlay"></div>    <div class="truste-consent-track-class">  <div id="truste-consent-content" class="truste-banner" style="overflow: hidden; max-height:auto;">    <div class="truste-title">Choo-choose cookies for a smoother ride!</div>    <div id="truste-consent-text" class="truste-messageColumn">       <p>We use cookies to improve your online experience and provide personalised services. By choosing “Accept all”,  you’re making sure your experience is as sweet as a real-life cookie.<br><br>Find out more about&nbsp;<a href="https://www.tpexpress.co.uk/privacy-policy#CookiesPolicy" id="truste-cookie-button" target="_blank" style="cursor:pointer; text-decoration: underline;">our cookie policy</a>.</p>      </div>      <div id="truste-consent-buttons" class="truste-buttonsColumn">              <button id="truste-consent-button" type="button" class="truste-button">Accept all</button>        <button id="truste-consent-required" type="button" class="truste-button">Only necessary cookies</button>        <button id="truste-show-consent" type="button" class="truste-button">Adjust my preferences<span class="truste-buttons-icon"></span></button>      </div>       <div class="truste-consent-footer">      <a id=truste-privacy-button href="https://www.tpexpress.co.uk/privacy-policy" target="_blank"><img style="padding-left:0px;height:20px;vertical-align:middle" target="_blank">Privacy Policy</a><span>Powered by: <a href="http://trustarc.com/" target="_blank"><img style="padding-left:0px;height:17px;vertical-align:sub" alt="Company logo for TrustArc" src="https://consent.trustarc.com/get?name=Powered-By-TrustArc.png" target="_blank"></a></span>   </div>  </div>  </div>  </div>';
            bannerContents = bannerContents.replace('&lt;i&gt;', '<i>').replace('&lt;/i&gt;', '</i>').replace('&lt;b&gt;', '<b>').replace('&lt;/b&gt;', '</b>');
            if(!bannerContents || bannerContents.length < 15) {
                bannerContents =
                    '<div id="truste-consent-track" style="display:none; background-color:#000;">' +
                    '<div id="truste-consent-content" style="overflow: hidden; margin: 0 auto; max-width: 1000px">' +
                    '<div id="truste-consent-text" style="float:left; margin:15px 0 10px 10px; width:500px;">' +
                    '<h2 style="color: #fff; font-size: 16px; font-weight:bold; font-family:arial;">' +
                    "Some functionality on this site requires your consent for cookies to work properly." +
                    "</h2>" +
                    '<div id="truste-repop-msg" style="padding: 0px 0px 5px 0px;font-size: 12px;color: #F0C36D; display:none; font-family: arial,sans-serif;"></div>' +
                    "</div>" +
                    '<div id="truste-consent-buttons" style="float:right; margin:20px 10px 20px 0;">' +
                    '<button id="truste-consent-button" type=button style="padding:5px; margin-right:5px; font-size:12px;">I consent to cookies</button>' +
                    '<button id="truste-show-consent" type=button style="padding:5px; margin-right:5px; font-size:12px;">I want more information</button>'+
                    "</div>" +
                    "</div>" +
                    "</div>";
            }

            if (params.responsive === 'false') {
                bannerContents = bannerContents.replace(/(class=["'].*?)[\s]?truste-responsive(.*?["'])/g, "$1$2");
            }

            if (bbContainer.insertAdjacentHTML) {
                bbContainer.insertAdjacentHTML('afterbegin', bannerContents);
            } else {
                bbContainer.innerHTML = bannerContents;
            }
        }
        function submitIabCookies(type){
        var s = (truste.util && truste.util.getJSON) || (truste.cma && truste.cma.cheapJSON) || window.JSON.stringify,
            ob = {
                 source: "preference_manager",
                 message: type,
                 data: {
                     useNonStandardStacks: false,
                     consentScreen: 1
                 }
             };

             window.postMessage && window.postMessage(s(ob),"*");
         }

        function submitGppCookies(message, data){
            var s = (truste.util && truste.util.getJSON) || (truste.cma && truste.cma.cheapJSON) || window.JSON.stringify,
                ob = {
                    source: "preference_manager",
                    message: message,
                    data: data
                };

            window.postMessage && window.postMessage(s(ob),"*");
        }

        function updateCmpApiDisplayStatus(display) {
            truste.eu.gpp && truste.eu.gpp.updateCmpDisplayStatus(display);
        }

        function acceptAll(){
            self.localStorage && self.localStorage.removeItem(truste.eu.COOKIE_CATEGORY_NAME);
            
            truste.eu.ccpa.dropCcpaCookie(false);
            makeSelection(CM_CONSENT_COOKIE_VALUE);
            // note: pcookie is not included due to issues w/ updating local storage between subdomains
            if (!truste.eu.noticeLP.pcookie) {
                truste.util.dropOptoutDomains(CM_CONSENT_COOKIE_VALUE);
            } 
        }

        function declineAll(){
            var b = truste.eu.bindMap;

            truste.eu.ccpa.dropCcpaCookie(true);

            if (b && b.prefmgrUrl && (params.gtm || truste.eu.noticeLP.gtm == 1)) {
                truste.bn.hide(document.getElementById(CM_BANNER_HOLDER));
                updateCmpApiDisplayStatus('hidden');
                makeSelection("0");
                truste.util.dropOptoutDomains();
            } else {
                if (truste.eu && truste.eu.clickListener) {
                    truste.eu.clickListener(3);
                }
            }
        }
        /**
         * Passes the result of user preferences if set by banner buttons to the CM API and Notice JS
         * @param {String} level The consent level set by the user, to pass along to the CM API
         */
        function makeSelection(pref) {
            var level = truste.util.getLowestConsent(pref);
            if (!isNaN(level = parseInt(level)) && truste.eu && truste.eu.actmessage) {
                var s = (truste.util && truste.util.getJSON) || (truste.cma && truste.cma.cheapJSON) || window.JSON.stringify,
                    ob = {
                        source: "preference_manager",
                        message: "submit_preferences",
                        data: {
                            value: pref
                        }
                    };
                truste.eu.actmessage(ob);
                if(window.PREF_MGR_API_DEBUG){
                    PREF_MGR_API_DEBUG.authorities.push(window.location.hostname);
                }
                window.postMessage && window.postMessage(s(ob),"*");

                var bindMap = truste.eu.bindMap;
                if (bindMap && bindMap.prefmgrUrl && !bindMap.feat.ccpaApplies) {
                    // Calls CM endpoint for GDPR reporting
                    truste.util.callCMEndpoint('/defaultconsentmanager/optin?', level, function() {}, true);
                }

                //Update state to indicate that a preferences selection has been made
                status("selection");
            }else status("done");
        }

        /**
         * Opens the banner. The "banner" element is the immediate child of the bbdivID element (params.bb)
         * @param {HTMLElement} n banner element
         */
        function setBannerEvents() {
            var b = truste.eu.bindMap;

            if (b.feat.isReconsentEvent && b.popupMsg.length > 0) {
                var repopDiv = document.getElementById(BANNER_ELEM_IDS.repopDiv);
                if (repopDiv) {
                    repopDiv.innerHTML = b.popupMsg;
                    var repopContainers = document.getElementsByClassName('tc-repop-msg');
                    if (repopContainers.length > 0) {
                        repopContainers[0].classList.replace('tc-hide', 'tc-show-flex');
                    } else {
                        truste.bn.show(repopDiv);
                    }
                }  
            }

            //Add button click callbacks for all the different buttons
            var e1 = document.getElementById(BANNER_ELEM_IDS.consentButton);
            if (e1) {
                var cookieRegex = new RegExp(("^"+CM_CONSENT_COOKIE_VALUE+"$").replace(/,/g,'.'));
                if (!params.gtm && !b.feat.enableCCPA && b.feat.isRepopEvent && !cookieRegex.test(b.prefCookie)) {
                    e1.style.display = 'none';
                } else {
                    e1.onclick = function () {
                        truste.bn.msglog("accepts", bm.bannerMsgURL);

                        if(bm.feat.iabBannerApplies){
                            submitIabCookies("process_iab_accept_all");
                        } else if (bm.feat.gpp.gppApplies) {
                            submitGppCookies("process_gpp_accept_all");
                        }

                        if ((b.feat.enableCCPA || b.feat.isReconsentEvent)
                            &&  b.feat.enableTwoStepVerification && truste.util.validConsent(b.prefCookie) && !cookieRegex.test(b.prefCookie)) {
                            if (truste.eu && truste.eu.clickListener) {
                                truste.eu.clickListener(6);
                            }
                        } else {
                            acceptAll();
                        }
                    };
                }
            }

            e1 = document.getElementById(BANNER_ELEM_IDS.footerCallback);
            if (e1) {
                e1.setAttribute("aria-haspopup", "true");
                e1.onclick= function () {
                    truste.bn.msglog("moreinfo", bm.bannerMsgURL);
                    if (truste.eu && truste.eu.clickListener) {
                        if(bm.feat.iabBannerApplies){
                            truste.eu.clickListener(4);
                        }else{
                            truste.eu.clickListener(parseInt(params.pn) || 0);
                        }
                        b.returnFocusTo=BANNER_ELEM_IDS.footerCallback.replace('#', '');
                    }
                };
            }

            e1 = document.getElementById(BANNER_ELEM_IDS.requiredButton);
            if (e1) {
                e1.onclick= function () {
                    truste.bn.msglog("requiredonly", bm.bannerMsgURL);

                    if (truste.eu.cpra && truste.eu.cpra.shouldShowFinProg()) {
                        // call financial prompt, do not proceed with optout
                        truste.eu.clickListener(7, true,
                            {
                                cpraConsent: "0",
                                cpraSource: "banner-decline"
                            });
                        return;
                    } else {
                        if(bm.feat.iabBannerApplies){
                            submitIabCookies("process_iab_reject_all");
                        } else if (bm.feat.gpp.gppApplies) {
                            submitGppCookies("process_gpp_reject_all");
                        }
                        declineAll();
                    }
                };
            }

            e1 = document.getElementById(BANNER_ELEM_IDS.ccpaOptoutButton);
            if (e1) {
                e1.onclick = function() {
                    truste.bn.msglog("requiredonly", bm.bannerMsgURL);
                    if (truste.eu.cpra && truste.eu.cpra.shouldShowFinProg()) {
                        // call financial prompt, do not proceed with optout
                        truste.eu.clickListener(7, true,
                            {
                                cpraConsent: "0",
                                cpraSource: "banner-decline-ccpa"
                            });
                        return;
                    } else {
                        truste.bn.declineCPRA();
                    }
                };
            }

            e1 = document.getElementById(BANNER_ELEM_IDS.cookieButton);
            if (e1) {
                if(params.cookieLink) {
                    e1.href = params.cookieLink;
                }
                e1.onclick = function (event) {
                    truste.bn.msglog("cookiepolicy", bm.bannerMsgURL);
                    if (params.cookieLink) {
                        event.preventDefault();
                        window.open(params.cookieLink, CM_TARGET);
                    }
                };
            }

            e1 = document.getElementById(BANNER_ELEM_IDS.privacyButton);
            if (e1) {
                if (params.privacypolicylink) {
                    e1.href = params.privacypolicylink;
                }
                e1.onclick = function (event) {
                    //truste.bn.msglog("privacypolicy", bm.bannerMsgURL);
                    if (params.privacypolicylink) {
                        event.preventDefault();
                        window.open(params.privacypolicylink, CM_TARGET);
                    }
                };
            }

            e1 = document.getElementById(BANNER_ELEM_IDS.closeBanner);
            if (e1) {
                e1.onclick = function() {
                    var b = truste.eu.bindMap;
                    var hasConsent = truste.util.validConsent(b.prefCookie);
                    var isOptoutClose = (b.feat.optoutClose && !hasConsent);
                    if (isOptoutClose) {
                        if (truste.eu.cpra && truste.eu.cpra.shouldShowFinProg()) {
                            // call financial prompt, do not proceed with optout
                            truste.eu.clickListener(7, true,
                                {
                                    cpraConsent: "0",
                                    cpraSource: "banner-decline"
                                });
                            return;
                        } else {
                            declineAll();
                        }
                    } else {
                        status("done");
                    }
                };
            }

            e1 = document.getElementById(BANNER_ELEM_IDS.iabPartnersLink);
            if(e1) {
                e1.onclick = function() {
                    truste.eu.clickListener(5);
                    b.returnFocusTo=BANNER_ELEM_IDS.iabPartnersLink.replace('#', '');
                };

                e1.onkeyup = function(e){
                    if(e.keyCode == 13){
                        truste.eu.clickListener(5);
                        b.returnFocusTo=BANNER_ELEM_IDS.iabPartnersLink.replace('#', '');
                    }
                };
            }

            e1 = document.getElementById(BANNER_ELEM_IDS.secondIabPartnersLink);
            if(e1){
                e1.onclick = function() {
                    truste.eu.clickListener(5);
                    b.returnFocusTo=BANNER_ELEM_IDS.secondIabPartnersLink.replace('#', '');
                };

                e1.onkeyup = function(e){
                    if(e.keyCode == 13){
                        truste.eu.clickListener(5);
                        b.returnFocusTo=BANNER_ELEM_IDS.secondIabPartnersLink.replace('#', '');
                    }
                };
            }

            setCCPAStatus();

            var tdpLinks = document.querySelectorAll('a[href*="https://tracker-detail-page"]');
            tdpLinks.forEach(
                function addLocaleToTdp(l) {
                    if (!l.href.includes('locale=')) {
                        l.href = l.href + '&locale=' + bm.locale;
                   }
                }
             );

            //if the banner is set to fade out, initiate that now.
            parseInt(params.fade) && setTimeout(function(){
                makeSelection(params.sl);
            }, parseInt(params.fade));

            //update state to indicate that the banner is open
            status("open");
        }

        function setCCPAStatus() {
            var b = truste.eu.bindMap;
            if (b.feat.ccpaApplies) {
                var ccpaPref = truste.eu.ccpa.getOptout();
                var optedout = document.getElementById(BANNER_ELEM_IDS.ccpaOptedOut);
                var optedin =  document.getElementById(BANNER_ELEM_IDS.ccpaOptedIn);
                var nopref =  document.getElementById(BANNER_ELEM_IDS.ccpaNoPreference);
                if (ccpaPref && b.prefCookie) {
                    var optedOutRegex = /^[yY]$/;
                    if(optedOutRegex.test(ccpaPref)) {
                        optedout && truste.bn.show(optedout);
                        optedin && truste.bn.hide(optedin);
                        nopref && truste.bn.hide(nopref);
                    } else {
                        optedout && truste.bn.hide(optedout);
                        optedin && truste.bn.show(optedin);
                        nopref && truste.bn.hide(nopref);
                    }
                } else {
                    optedout && truste.bn.hide(optedout);
                    optedin && truste.bn.hide(optedin);
                    nopref && truste.bn.show(nopref);
                }
            }
        }

        function setDocListeners() {
            if (params.oc) {
                truste.bn.addEvent(document, "click", ocListener);
            }

            if (params.px) {
                truste.bn.addEvent(document, "scroll", pxListener);
            }
        }

        function showBanner() {
            truste.bn.isConsentTrack = true;
            truste.bn.show(document.getElementById(CM_BANNER_HOLDER));
            updateCmpApiDisplayStatus('visible');
            truste.bn.msglog("views", bm.bannerMsgURL);
        }

        function dontShowBanner () {
            status("done");
            truste.bn.msglog("returns", bm.bannerMsgURL);
        }

        function isOnlyBannerOpen(blackbar){
            //checks if banner exists and is visible and that CM is closed
            return blackbar && truste.bn.isVisible(blackbar) && !document.getElementById(truste.eu.popdiv2);
        }

        function ocListener(event) {
            var blackbar = document.getElementById(CM_BANNER_HOLDER);
            if (isOnlyBannerOpen(blackbar) &&
                !blackbar.contains(event.target) &&        //click was not from banner
                event.target.id !== truste.eu.popclose) {  //click was not from cm
                makeSelection(CM_CONSENT_COOKIE_VALUE);
            }
        }

        function pxListener(event) {
            var blackbar = document.getElementById(CM_BANNER_HOLDER);
            if (isOnlyBannerOpen(blackbar) &&
                (document.scrollingElement.scrollTop || document.documentElement.scrollTop) >= params.px) {
                makeSelection(CM_CONSENT_COOKIE_VALUE);
            }
        }


        truste.bn.reopenBanner = function() {
            if (bbContainer) {
                truste.bn.isConsentTrack = true;
                status.done = 0;
                setDocListeners();
                setBannerEvents();
                truste.bn.show(document.getElementById(CM_BANNER_HOLDER));
                updateCmpApiDisplayStatus('visible');
            }
        }

        truste.bn.twoStepConfirmed = function(){
               truste.eu.ccpa.dropCcpaCookie(false);
               makeSelection(CM_CONSENT_COOKIE_VALUE);
               truste.bn.msglog("twostepoptin", bm.bannerMsgURL);
        }

        truste.bn.twoStepDeclined = function(){
                status("done");
        }

        truste.bn.acceptAll = function() {
            acceptAll();
        }

        truste.bn.declineAll = function() {
            declineAll();
        }

        truste.bn.declineCPRA = function() {
            truste.eu.ccpa.dropCcpaCookie(true);
            makeSelection("0");
        }

        /**
         * To be called by notice.js when submit_preferences message occurs
         */
        truste.bn.handleBannerDone = function() {
            var b = truste.eu.bindMap;
            // handle banner done on consent
            // set banner done (closes banner) if event is not GPC/DNT
            // OR if GPC/DNT event, set banner done when show UI feature is disabled
            if (!truste.eu.isGPCDNTEvent() || !b.feat.dntShowUI) {
                status("done");
            } else {
                setCCPAStatus();
            }
        }
    }
};
