function _hbChangeLinkNames() {
	// Check all links
	for (i = 0; i < document.links.length; i++) {
		_link = document.links[i];
		//If child of link is an image, replace lid and lpos
		if ((_link.name != null) && (_link.name.indexOf("lid__") != -1)) { // Check if lid__ occurs
			_link.name = _link.name.replace("lid__", "&lid=").replace("lpos__","&lpos=");
		}
	}
}
_hbChangeLinkNames();

//----------- START minimized functions --------->
if(typeof(Adversitement) == 'undefined') {
  var Adversitement = {};
}


/**
 * Base functions used by all modules
 */
Adversitement.base = function() {
  //Private variables
  
  
  /**
   * Holds all functions that have to be executed just before Pageview request is constructed
   * @private   
   */     
  var onPrePVREvents = [];
  
  
  /**
   * Stores all event objects for use after a pageview gets send
   * @private
   */        
  var hbEvents = [];
  
  
  /**
   * Sets up all HBX Events interfaces with our own events
   * @private      
   */         
  var initEventInterfaces = function() {
    var oldOnPrePVR = function(r){};
    //if hbOnPrePVR already defined save its reference for later use
    if(typeof(_hbOnPrePVR) != 'undefined') {
       oldOnPrePVR = _hbOnPrePVR; 
    }
    // create global function _hbOnPrePVR
    _hbOnPrePVR = function(requestString) {
      oldOnPrePVR(requestString);
      storeEvents();
      for(var i=0; i<onPrePVREvents.length; i++) {
        onPrePVREvents[i](requestString);
      }
    }
  };
  
  
  /**
   * Store all events. Hbx code deletes these events after a pageview, but we may need them.
   * @private
   */        
  var storeEvents = function() {
    hbEvents = []; // delete all entries
    if(typeof(_hbE) != 'undefined') {
      for(var i=0; i<_hbE.length; i++) {
        hbEvents[i] = _hbE[i];
      }
    }
  };
  
  
  /**
   * Returns actual event object as defined with _hbEvent. Doesn't use our stored copies of event objects.
   * @param name Name of the event object
   * @returns HBX Event object or null if not found
   * @private   
   */   
  var getRealEventObject = function(name) {
    var ret = null;
    if(typeof(_hbE) != 'undefined') {
      for(var i=0; i<_hbE.length; i++) {
        if(typeof(_hbE[i]._N) != 'undefined' && _hbE[i]._N == name) {
          return _hbE[i];
        }
      }
    }
    return ret;
  };
  
  
  /**
   * Returns our stored copy of event object.
   * @param name Name of the event object
   * @returns HBX Event object or null if not found
   * @private   
   */   
  var getCopyEventObject = function(name) {
    var ret = null;
    for(var i=0; i<hbEvents.length; i++) {
      if(typeof(hbEvents[i]._N) != 'undefined' && hbEvents[i]._N == name) {
        return hbEvents[i];
      }
    }
    return ret;
  };


  //Public variables
  return /** @scope Adversitement.base */ {

    /**
     * Get parameter from URL. Not case sensitive.
     * @param parm Parameter name to be read from URL
     */              
    getParameter: function(parm) {
      var string = top.location.search.substring(1);
      var parameters = string.split("&");
      
      for(var i=0; i<parameters.length; i++) {
        var pair = parameters[i].split("=");
        if(pair.length > 0) {
          if(pair[0].toLowerCase() == parm) {
            return unescape(pair[1]);  
          }
        }
      }
      return '';
    },
    
    
    /**
     * Get parameter from Referrer URL. Not case sensitive.
     * @param parm Parameter name to be read from Referrer URL
     */              
    getReferrerParameter: function(parm) {
      var r = top.document.referrer;
      if(r.indexOf("?") != -1) {
        var string = r.substring(r.indexOf("?")).substring(1);
        var parameters = string.split("&");
        
        for(var i=0; i<parameters.length; i++) {
          var pair = parameters[i].split("=");
          if(pair.length > 0) {
            if(pair[0].toLowerCase() == parm) {
              return unescape(pair[1]);  
            }
          }
        }
      }
      return '';
    },
    
    
    /**
     * Returns referring domain
     */
    getReferringDomain: function() {
      if (document.referrer) {
        try {
          var d = document.referrer.match(/([^\/\/]+\.[^/.]+)\//);
          if(d && d.length>1) {
            d = d[1];
            if(d) {
              return d.replace(/www\./i, '').toLowerCase();
            }
          }
        } catch(err){}
      }
      return '';
    },
             
    
    
    /**
     * Get parameter from hash string. Not case sensitive.
     * @param parm Parameter name
     */              
    getHashParameter: function(parm) {
      var h = top.location.hash;
      if(h.indexOf("#") != -1) {
        var string = h.substring(1);
        var parameters = string.split("&");
        
        for(var i=0; i<parameters.length; i++) {
          var pair = parameters[i].split("=");
          if(pair.length > 0) {
            if(pair[0].toLowerCase() == parm) {
              return unescape(pair[1]);
            }
          }
        }
      }
      return '';
    },
    
    
    /**
     * Additional campaign parameters
     */         
    campaignParameters: [],
    
    
    /**
     * Use Organic campaigns
     */
    useOrganicCampaigns: [],          
    
    
    /**
     * Gets campaign from URL or hbx.cmp
     * @returns Campaign Id or empty string if no campaign
     */              
    getCampaign: function() {
      var cmp = '';
      
      if(cmp == '') {
        if(typeof(_cmp) != 'undefined') {
          cmp = _cmp;
        }
      }
      
      if(cmp == '') {
        if(typeof(_dcmp) != 'undefined') {
          cmp = _dcmp;
        }
      }
      
      if(cmp == '') {
        if(typeof(_cmpn) != 'undefined' && _cmpn != '') {
          cmp = Adversitement.base.getParameter(_cmpn);
        }
      }
      
      if(cmp == '') {
        if(typeof(_dcmpn) != 'undefined' && _dcmpn != '') {
          cmp = Adversitement.base.getParameter(_dcmpn);
        }
      }
      
      if(cmp == '') {
        cmp = Adversitement.base.getParameter('cmp');
      }
      
      if(cmp == '') {
        cmp = Adversitement.base.getHashParameter('cmp');
      }
      
      if(cmp == '') {
        cmp = Adversitement.base.getParameter('ecmp');
      }
      
      if(cmp == '') {
        cmp = Adversitement.base.getParameter('dcmp');
      }
      
      if(cmp == '') {
        cmp = Adversitement.base.getParameter('hbx.cmp');
      }
      
      if(cmp == '') {
        cmp = Adversitement.base.getParameter('hbx.dcmp');
      }
      
      if(cmp == '') {
        if(typeof(Adversitement.base.campaignParameters) != 'undefined' && Adversitement.base.campaignParameters) {
          for(var i=0; i<Adversitement.base.campaignParameters.length; i++) {
            if(cmp == '') {
              cmp = Adversitement.base.getHashParameter(Adversitement.base.campaignParameters[i]);
            }
            if(cmp == '') {
              cmp = Adversitement.base.getParameter(Adversitement.base.campaignParameters[i]);
            }
          }  
        }
      }
      
      // organic campaigns
      if(cmp == '' && typeof(Adversitement.base.useOrganicCampaigns) != 'undefined' && Adversitement.base.useOrganicCampaigns && Adversitement.base.useOrganicCampaigns.length>0) {
        var d = Adversitement.base.getReferringDomain();
        for(var j=0; j<Adversitement.base.useOrganicCampaigns.length; j++) {
          if(d.indexOf(Adversitement.base.useOrganicCampaigns[j].toLowerCase()) != -1) {
            cmp = "Organic";
            break;
          }
        }
      }
      
      if(cmp != '') {
        cmp = Adversitement.base.trim(cmp);
      }
      
      return cmp;
    },
    
    
    /**
     * Get hbEvent object
     * @param name Name of the event to return     
     * @returns HBX Event object or null if not found
     */     
    getEventObject: function(name) {
      var ret = null;
      ret = getRealEventObject(name);
      if(ret == null) {
        ret = getCopyEventObject(name);
      }
      return ret;
    },
    
    
    /**
     * Get Order event object. May be a copy.
     * @returns Order Event Object     
     */         
    getOrderEventObject: function() {
      var order = Adversitement.base.getEventObject("order");
      if(!order) {
        order = Adversitement.base.getEventObject("ord");
      }
      return order;
    },
    
    
    /**
     * Get the actual Order event object and never a copy. Use this function if you want to set a order variable
     * @returns Order Event Object     
     */         
    getRealOrderEventObject: function() {
      var order = getRealEventObject("order");
      if(!order) {
        order = getRealEventObject("ord");
      }
      return order;
    },
    
    
    /**
     * Remove leading and trailing white space
     * @param str Source string
     * @returns Trimmed string
     */                   
    trim: function(str) {
      return str.replace(/^\s*(\S*(\s+\S+)*)\s*$/, "$1");
    },
    
    
    /**
     * Return sum of comma delimited values
     * @returns Sum of comma delimited values
     */              
    sumOfAllValues: function(values) {
      var arr = values.split(',');
      var sum = 0;
      for(var i = 0; i<arr.length; i++) {
        var val = parseFloat(arr[i]);
        if(val) {
          sum += val;
        }
      }
      return sum;
    },
  
  
    /**
     * Replaces one string with another
     * @param str String where replacement takes place
     * @param pcFrom Source string
     * @param pcTo Destination String
     * @returns New string with replaced values
     */                              
    replaceAll: function(str, pcFrom, pcTo){
      var c = str;
      if(str) {
        var i = str.indexOf(pcFrom);
        while (i > -1){
          c = c.replace(pcFrom, pcTo);
          i = c.indexOf(pcFrom);
        }
      }
      return c;
    },
    
    
    /**
     * Sets Custom Metric to a value. Works also with Custom Metrics greater than 4.
     * @param customMetricNr Interger from 1 to 50 determines to which Custom Metric the value will be assigned
     * @param value Value to be assigned to a Custom Metric
     */                   
    setCustomMetric: function(customMetricNr, value) {
      var customMetricEvent = getRealEventObject("cv");
      if(customMetricNr <= 4) {
        //check if we are using events
        if(customMetricEvent) {
          if(typeof(customMetricEvent['c' + customMetricNr]) != 'undefined') {
            customMetricEvent['c' + customMetricNr] = value;
            return;
          }
        }
        if(customMetricNr == 1) {
          _hc1 = value;
        } else if(customMetricNr == 2) {
          _hc2 = value;
        } else if(customMetricNr == 3) {
          _hc3 = value;
        } else if(customMetricNr == 4) {
          _hc4 = value;
        }
      } else {
        //if event is not created, create one
        if(!customMetricEvent) {
          customMetricEvent = _hbEvent("cv");
        }
        customMetricEvent['c' + customMetricNr] = value;
      }
    },
    
    
    /**
     * Sets Order Level Commerce Custom Metric to a value. Works with Order Event only.
     * @param customMetricNr Interger from 1 to 10 determines to which Custom Metric the value will be assigned
     * @param value Value to be assigned to a Custom Metric
     */                   
    setOrderCustomMetric: function(customMetricNr, value) {
      var customMetricEvent = Adversitement.base.getRealOrderEventObject();
        //if event is not created, do nothing
        if(!customMetricEvent) {
          return
        }
        customMetricEvent['attr' + customMetricNr] = value;
    },
    
    
    /**
     * Determines if this is conversion page or order confirmation page
     * @returns true if either hbx.gp is not empty or this is order confirmation page
     */              
    isThisConversionPage: function() {
      // is this conversion page?
      if(typeof(_gp) != 'undefined' && _gp && _gp != "") {
        return true;
      }
      
      //is this order confirmation page?
      if(typeof(_oi) != 'undefined' && _oi && _oi != "" && _oi != "ORDER+ID") {
        return true;
      }
      
      //is this order confirmation page using events?
      var order = Adversitement.base.getOrderEventObject();
      if(order) {
        if(typeof(order.oi) != 'undefined' && order.oi && order.oi != "" && order.oi != "ORDER+ID") {
          return true;
        }
      }
      return false;
    },
    
    
    /**
     * Determines if this is order confirmation page
     * @returns true if this is oreder confirmation page
     */
    isThisOrderConfirmationPage: function() {
      //is this order confirmation page?
      if(typeof(_oi) != 'undefined' && _oi && _oi != "" && _oi != "ORDER+ID") {
        return true;
      }
      
      //is this order confirmation page using events?
      var order = Adversitement.base.getOrderEventObject();
      if(order) {
        if(typeof(order.oi) != 'undefined' && order.oi && order.oi != "" && order.oi != "ORDER+ID") {
          return true;
        }
      }
      return false;
    },
    
    
    /**
     * Gets value of HBX variable, either global or from pageview event.
     * @param eventVariableName Property name of the pageview Event(without underscore)
     * @param eventName Name of the event to use in case no global variable is defined. This variable can be an object(mostly used with Order events).
     * @returns Value of the HBX variable     
     */              
    getHbxVariable: function(eventVariableName, eventName) {
      if(!eventName) {
        eventName = 'pv';
      }
      if(typeof(window['_' + eventVariableName]) != 'undefined') {
        return window['_' + eventVariableName];
      } else {
        var event;
        if(typeof(eventName) == 'object') {
          event = eventName;
        } else {
          event = Adversitement.base.getEventObject(eventName);
        }
        if(event != null) {
          return event[eventVariableName];
        }
      }
      return null;
    },
    
    
    /**
     * Sets value of HBX variable both global and event.
     * @param eventVariableName Property name of the pageview Event(without underscore)
     * @param value Value to set     
     * @param eventName Name of the event to use in case no global variable is defined. This variable can be an object(mostly used with Order events).     
     */              
    setHbxVariable: function(eventVariableName, value, eventName) {
      if(!eventName) {
        eventName = 'pv';
      }
      
      window['_' + eventVariableName] = value;
      
      var event;
      if(typeof(eventName) == 'object') {
        event = eventName;
      } else {
        event = getRealEventObject(eventName);
      }
      // If event is not set do nothing
      if(event != null) {
        event[eventVariableName] = value;
        storeEvents();
      }
    },
    
    
    /**
     * Strip all illegal characters<br>
     * Usage: hbx.pn = _Adversitement.base.hbxStrip(hbx.pn); 
     * @param a Text to strip
     * @returns Text with illegal characters stripped
     */   
    hbxStrip: function(a) {
      a = a + '';
      a = a.split("|").join("");
      a = a.split("&").join("");
      a = a.split("'").join("");
      a = a.split("#").join("");
      a = a.split("$").join("");
      a = a.split("%").join("");
      a = a.split("^").join("");
      a = a.split("*").join("");
      a = a.split(":").join("");
      a = a.split("!").join("");
      a = a.split("<").join("");
      a = a.split(">").join("");
      a = a.split("~").join("");
      a = a.split(";").join("");
      a = a.split(" ").join("+");
      return a;    
    },
    
    
    /**
     * Add a function to be called in onPrePVR event
     * @param func function to be added
     */              
    addOnPrePVREvent: function(func) {
      onPrePVREvents.push(func);
    },
    
    
    /**
     * Version number
     * @returns version number
     */              
    version: function() {
      return 1.9;
    },
    
    
    /**
     * Init
     */         
    init: function() {
      initEventInterfaces();
    }
  };
}(); // create the actual object


/**
 * Create/Read/Delete cookies<br>
 */
Adversitement.cookie = {
  set: function(name, value, daysToExpire) {
    var expire = '';
    var domein = '';
    var path = '';
    var host = Adversitement.cookie.getHost();
    if (daysToExpire != undefined) {
      var d = new Date();
      d.setTime(d.getTime() + (86400000 * parseFloat(daysToExpire)));
      expire = '; expires=' + d.toGMTString();
      path = '; path=/';
      domein = '; domain='+host;
    }
    return (document.cookie = name + '=' + (value || '') + path + domein + expire);
  },
  
  get: function(name) {
    var cookie = document.cookie.match(new RegExp('(^|;)\\s*' + escape(name) + '=([^;\\s]*)'));
    return (cookie ? unescape(cookie[2]) : null);
  },
  
  erase: function(name) {
    var cookie = Adversitement.cookie.get(name) || true;
    Adversitement.cookie.set(name, '', -1);
    return cookie;
  },
  
  accept: function() {
    if (typeof navigator.cookieEnabled == 'boolean') {
      return navigator.cookieEnabled;
    }
    Adversitement.cookie.set('_test', '1');
    return (Adversitement.cookie.erase('_test') === '1');
  },
  
  
  /**
   * Gets host suitable for inclusion in cookies<br>
   * www.google.com becomes .google.com
   * @returns domain without subdomains
   */                   
  getHost: function() {
    var newHost = "";
    try {
      var host = document.location.host;
      var values = host.split('.');
      if(values.length > 1) {
        newHost = '.' + values[values.length-2] + '.' + values[values.length-1];
      }
    } catch(e) {}
    return newHost;
  }
};



/**
 * Custom convenience functions and hbx interfaces
 */
Adversitement.custom = function() {
  //Private variables
  
  /**
   * Prefix to all cookie variables
   * @private
   */        
  var cookieName = '_Adver_custom_';
  
  
  /**
   * Save response to first campaign in a cookie to be read later
   * @private    
   */   
  var firstCampaignResponse = function() {
    var cmp = Adversitement.base.getCampaign();
    if(cmp != '') {
      var c = Adversitement.cookie.get(cookieName + 'FIRST_hbx.cmp');
			if(c == null) {
			  Adversitement.cookie.set(cookieName + 'FIRST_hbx.cmp', cmp, 30);
      }
		}
  };
  
  
  /**
   * If hbx.gp = 'first' set hbx.gp to a first campaign read from cookie, then delete cookie
   * @private   
   */   
  var firstCampaignConversion = function() {
    if(typeof(_gp) != 'undefined' && _gp && _gp.toLowerCase() == "first") { 
  		var _c = Adversitement.cookie.get(cookieName + 'FIRST_hbx.cmp');
  		_gp = (_c != null)?_c:'LAST';
  		Adversitement.cookie.erase(cookieName + 'FIRST_hbx.cmp');
  	}
  };

  
  //Public variables
  return /** @scope Adversitement.custom */ {
  
    /**
     * Adds hbx referrer from URL variable<br>
     * Used with Emails and Newsletters<br>
     * Usage: www.mypage.com/?adv_ref=http://email.mypage.com
     */           
    addReferrer: function() {
      var ref = Adversitement.base.trim(Adversitement.base.getParameter('adv_ref'));
      if(ref != '') {
        if(typeof(_hrf) == 'undefined' || _hrf == "") {
          if(ref.indexOf('http://') == -1 && ref.indexOf('https://') == -1) {
            ref = 'http://' + ref;
          }
          _hrf = ref;
        }
      }
    },
    
    
    /**
     * If hbx.gp = FIRST set hbx.gp to first campaign the user has responded to.
     */         
    firstCampaign: function() {
      firstCampaignResponse();
      firstCampaignConversion();
    },
    
    
    /**
     * If hbx.gp = LAST_NO_REFRESH prevent from repeat conversions within 5 minutes of last conversion
     */         
    lastNoRefresh: function() {
      if(typeof(_gp) != 'undefined' && _gp && _gp.toLowerCase() == "last_no_refresh") { 
    		var _c = Adversitement.cookie.get(cookieName + 'LAST_NO_REFRESH_hbx.gp');
    		if(_c == null) {
    		  _gp = 'LAST';
          Adversitement.cookie.set(cookieName + 'LAST_NO_REFRESH_hbx.gp', '1', 0.0035);
        } else {
          _gp = '';
        }
    	}
    },
    
    
    /**
     * Fix hbx.cu, hbx.ds, hbx.po variables that cause problems with some versions of hbx
     */     
    fixCommerceVariables: function() {
      
      

      
      if(typeof(_cu) != 'undefined' && _cu && _cu == "CUSTOMER+TYPE") {
        _cu = "";
      }
      if(typeof(_ds) != 'undefined' && _ds && _ds == "DISCOUNT") {
        _ds = "";
      }
      if(typeof(_po) != 'undefined' && _po && _po == "PROMOTION") {
        _po = "";
      }
      
      // if we are using order event
      var order = Adversitement.base.getOrderEventObject();
      if(order) {
        if(typeof(order.cu) != 'undefined' && order.cu && order.cu == "CUSTOMER+TYPE") {
          order.cu = "";
        }
        if(typeof(order.ds) != 'undefined' && order.ds && order.ds == "DISCOUNT") {
          order.ds = "";
        }
        if(typeof(order.po) != 'undefined' && order.po && order.po == "PROMOTION") {
          order.po = "";
        }
     if(typeof(order.pr)!='undefined') {
         	 order.pr = order.pr.replace(/\,/g,'|s|'); 
         	 order.pr = decodeURIComponent(order.pr);
         	 order.pr = decodeURIComponent(order.pr);
          	 order.pr = order.pr.replace(/\,/g,'.'); 
          	 order.pr = order.pr.replace(/\|s\|/g,','); 
        }

      }
      
      if(typeof(hbx)!='undefined' && typeof(hbx.pr)!='undefined') {
        hbx.pr = hbx.pr.replace(/\,/g,'|s|'); 
        hbx.pr = decodeURIComponent(hbx.pr);
        hbx.pr = hbx.pr.replace(/\,/g,'.'); 
        hbx.pr = hbx.pr.replace(/\|s\|/g,','); 
        _epg="n&cam="+hbx.cam+"&pv="+(hbx.pv>0?"1":"0&abd_type=cart_add")+"&product="+$a(hbx.pr)+
        "&quantity="+$a(hbx.qn)+"&brand="+$a(hbx.bd)+"&category="+$a(hbx.ca)+"&price="+$a(hbx.pc)+
        "&store="+$a((hbx.sr=="S"+"TORE")?1:hbx.sr)+"&tz=ECT&aid="+hbx.cacct;
      }
      
      
    },
    
    
    /**
     * Get campaign from hash string
     */
    getCampaignFromHash: function() {
      if(typeof(_cmp) == 'undefined' || _cmp == '') {
        _cmp = Adversitement.base.getCampaign();
      }
    },         
    
    
    /*
      Static functions. These functions don't have to be called from an event but can be used at any time.
    */
    
    
    /**
     * Add to Cart Event
     * All lists comma delimited         
     * @param product Cart product
     * @param quantity Product quantity
     * @param price Product price
     * @param brand Product brand(optional)
     * @param category Product category(optional)
     * @param store Store(optional, defaults to 1)
     * @param pagename Page name(optional)
     * @param mlc Multi-Level Content(optionl)
     * @param commerce_id Commerce Account Id(optional)       
     */                                                     
    hbxAddCart: function(product, quantity, price, brand, category, store, pagename, mlc, commerce_id) {
      // strip illegal characters
      for(var i=0; i<arguments.length; i++) {
        arguments[i] = Adversitement.base.hbxStrip(arguments[i]);
      }

      var defPagename = Adversitement.base.getHbxVariable('pn');
      var defMlc = Adversitement.base.getHbxVariable('mlc');
      var defCommerceId = Adversitement.base.getHbxVariable('cacct', Adversitement.base.getOrderEventObject());
      
      _hbSet('epg', 'n'); //event gateway toggle
      _hbSet('cam', '0'); //cart add methodology: CAM = 0 indicates highwatermark, CAM = 1 indicates incremental
      _hbSet('pv', '0'); //product view flag: PV = 0 INDICATES cart add, PV = 1 Indicates product view
      _hbSet('abd_type', 'cart_add');
      _hbSet('product', product?product:'PRODUCT');
      _hbSet('quantity', quantity?quantity:'QUANTITY');
      _hbSet('brand', brand?brand:'BRAND');
      _hbSet('category', category?category:'CATEGORIES');
      _hbSet('price', price?price:'PRICE');
      _hbSet('store', store?store:'1');
      _hbSet('tz', 'ECT'); //customer time zone
      _hbSet('aid', commerce_id?commerce_id:defCommerceId?defCommerceId:'COMMERCE_ID');
      
      _hbPageView(pagename?pagename:defPagename?defPagename:"PUT+PAGE+NAME+HERE", mlc?mlc:defMlc?defMlc:"CONTENT+CATEGORY");
    },
    
    
    /**
     * Cart Checkout Event<br>
     * All lists comma delimited     
     * @param product List of products
     * @param quantity List of quantities
     * @param price List of prices
     * @param shippingtype Shipping type
     * @param shippingcost Shipping cost
     * @param store Store(optional, defaults to 1)
     * @param pagename Page name(optional)
     * @param mlc Multi-Level Content(optional)
     * @param commerce_id Commerce Account Id (optional)                        
     */              
    hbxCheckout: function(product, quantity, price, shippingtype, shippingcost, store, pagename, mlc, commerce_id) {
      // strip illegal characters
      for(var i=0; i<arguments.length; i++) {
        arguments[i] = Adversitement.base.hbxStrip(arguments[i]);
      }
      
      var defPagename = Adversitement.base.getHbxVariable('pn');
      var defMlc = Adversitement.base.getHbxVariable('mlc');
      var defCommerceId = Adversitement.base.getHbxVariable('cacct', Adversitement.base.getOrderEventObject());
      
      _hbSet('abd_type', 'checkout'); 
      _hbSet('tz', 'ECT'); //customer time zone
      _hbSet('product', product?product:'LIST_OF_PRODUCTS');
      _hbSet('quantity', quantity?quantity:'LIST_OF_QUANTITIES');
      _hbSet('price', price?price:'LIST_OF_PRICES');
      _hbSet('shippingtype', shippingtype?shippingtype:'SHIP_TYPE');
      _hbSet('shipping', shippingcost?shippingcost:'SHIP_COST');
      _hbSet('store', store?store:'1');
      _hbSet('aid', commerce_id?commerce_id:defCommerceId?defCommerceId:'COMMERCE_ID');
      
      _hbPageView(pagename?pagename:defPagename?defPagename:"PUT+PAGE+NAME+HERE", mlc?mlc:defMlc?defMlc:"CONTENT+CATEGORY");
    }
    
  };
}(); // create the actual object


/**
 * History Module.
 * Used by other modules to store multidimensional values in a cookie.
 */ 
Adversitement.history = function() {
  // private variables
  
  /**
   * Prefix to all cookie variables
   * @private
   */ 
  var cookieName = '_Adver_history_';
  
  
  //Public variables
  return /** @scope Adversitement.history */ {
  
    add: function() {
      var historyId = arguments[0];
      for(var i=1; i<arguments.length; i++) {
        var old = Adversitement.cookie.get(cookieName + historyId + '_' + i);
        if(old && old != '') {
          old = old + '~';
        } else {
          old = '';
        }
        if(!Adversitement.history.last(historyId, arguments[i], i)) {
          Adversitement.cookie.set(cookieName + historyId + '_' + i, old + arguments[i], 30);
        }
      }
    },
    
    clear: function(historyId) {
      for(var i=1; i<100; i++) {
        var c = Adversitement.cookie.get(cookieName + historyId + '_' + i);
        if(c && c != '') {
          Adversitement.cookie.erase(cookieName + historyId + '_' + i);
        } else {
          return;
        }
      }
    },
    
    read: function(historyId) {
      var arr = [];
      for(var i=1; i<100; i++) {
        var c = Adversitement.cookie.get(cookieName + historyId + '_' + i);
        if(c && c != '') {
          arr.push(c);
        } else {
          return arr;
        }
      }
      return arr;
    },
    
    last: function(historyId, value, dimension) {
      var c = Adversitement.cookie.get(cookieName + historyId + '_' + dimension);
      if(c && c != '') {
        values = c.split('~');
        if(values[(values.length - 1)]==value) {
          return true;
        }
      }
      return false;
    },
    
    exists: function(historyId, value, dimension) {
      var c = Adversitement.cookie.get(cookieName + historyId + '_' + dimension);
      if(c && c != '') {
        values = c.split('~');
        for(var j=0; j<values.length; j++) {
          if(values[j]==value) {
            return true;
          }
        }
      }
      return false;
    },
    
    getLastValue: function(historyId, dimension) {
      var ret = "";
      if(!dimension) {
        dimension = 0;
      }
      var h = Adversitement.history.read(historyId);
      if(h && h.length > 0) {
        var values = h[dimension];
        if(values && values != "") {
          var valuesArray = values.split('~');
          ret = valuesArray[valuesArray.length - 1];
        }
      }
      return ret;
    }
  };
}(); // create the actual object


/**
 * Track all campaigns that a visitor has responded to and save it in a custom metric<br>
 * Works only on tagged campaigns and tagged conversions
 */
Adversitement.campaignHistory = function() {
  // private variables
  
  /**
   * Adds current campaign if avaible to campaign history
   * @private   
   */         
  var addCampaign = function() {
    var cmp = Adversitement.base.getCampaign();
    if(cmp == '') {
      //Direct visits
      if(Adversitement.campaignHistory.useDirect && top.document.referrer == "") {
        cmp = "Direct";
      }
    }
    if(cmp) {
      cmp = cmp.split('_')[0];
      var keyword = '';
      if(Adversitement.campaignHistory.saveKeyword) {
         keyword = Adversitement.base.trim(Adversitement.base.getReferrerParameter('q'));
      }
      if(keyword) {
        Adversitement.history.add('campaign', cmp.toLowerCase() + '(' + keyword.toLowerCase() + ')');
      } else {
        Adversitement.history.add('campaign', cmp.toLowerCase());
      }
    }
  };
  
  /**
   * Returns all campaigns as a string, ready to be inserted in a custom metric
   * @param commerce If true returns first dimension only   
   * @private   
   */         
  var getCampaignsCustomMetric = function(commerce) {
    var campaigns = Adversitement.history.read('campaign');
    if(campaigns.length > 0) {
      var dimension1 = campaigns[0];
      var dimension2 = '';
      
      // If this is order confirmation page use Price instead of Conversion Value
      if(Adversitement.base.isThisOrderConfirmationPage()) {
        if(typeof(_pc) != 'undefined' && _pc && _pc != "" && _pc != "PRICE") {
          dimension2 = _pc;
        }
        var orderEvent = Adversitement.base.getOrderEventObject();
        if(orderEvent && typeof(orderEvent.pc) != 'undefined' && orderEvent.pc && orderEvent.pc != "" && orderEvent.pc != "PRICE") {
          dimension2 = orderEvent.pc;
        }
        if(dimension2 && dimension2.length>0) {
          // we want one price only, so get sum of all the prices
          dimension2 = Adversitement.base.sumOfAllValues(dimension2);
        } else {
          dimension2 = '';
        }
      } else {
        if(typeof(_hcv) != 'undefined') {
          dimension2 = _hcv;
        }
      }
      if(dimension1 != '') {
        Adversitement.history.clear('campaign');
        if((commerce && commerce == true) || dimension2 == '') {
          return dimension1;
        }
        if(dimension2) {
          dimension2 = Math.round(parseFloat(dimension2)*100);
        }
        return dimension1 + '|' + dimension2;
      } else {
        return '';
      }
    } else {
      return '';
    }
  };
  
  //Public variables
  return /** @scope Adversitement.campaignHistory */ {
    
    /**
     * Determines if direct visits will be added to campaign history
     */         
    useDirect: false,
    
    
    /**
     * Save keyword
     */
    saveKeyword: false,         
    
    /**
     * Places campaigns in history.
     * If it is conversion page or order confiramtion page sets custom metric to a value from campaign history
     * @param customMetricNr Integer from 1 to 50 indicating where to place the results
     * @param commerce If true sets Order Level Commerce Custom Metrics instead of standard Custom Metrics          
     */         
    init: function(customMetricNr, commerce) {
      addCampaign();
      if(Adversitement.base.isThisConversionPage()) {
        if(commerce && commerce == true) {
          Adversitement.base.setOrderCustomMetric(customMetricNr, getCampaignsCustomMetric(true));
        } else {
          Adversitement.base.setCustomMetric(customMetricNr, getCampaignsCustomMetric());
        }
      }
    }
  };
}(); // create the actual object


/**
 * Track all typed internal keywords and save them in a custom metric on conversion<br>  
 */
Adversitement.internalSearchHistory = function() {
  // private variables
  
  /**
   * Adds current keyword if avaible to search history
   * @private   
   */ 
  var addKeywords = function() {
    var search = Adversitement.base.getEventObject("search");
    if(search) {
      var keyword = Adversitement.base.trim(search.keywords);
      keyword = Adversitement.base.hbxStrip(keyword);
      var lastKeyword = Adversitement.history.getLastValue("search");
      if(search.results && search.results != "0" && keyword != "" && keyword != lastKeyword) {
        Adversitement.history.add("search", keyword);
      }
    }
  };
  
  
  /**
   * Returns all keywords as a string, ready to be inserted in a custom metric
   * @param commerce If true returns first dimension only   
   * @private   
   */
  var getKeywordsCustomMetric = function(commerce) {
    var ret = "";
    var keywords = Adversitement.history.read("search");
    if(keywords.length > 0) {
      //we are only interested in first dimension
      keywords = keywords[0];    
      
      if(keywords != "") {
        var dimension1 = keywords;
        var dimension2 = Adversitement.history.getLastValue("search");
        ret = dimension1 + '|' + dimension2;
        if(commerce && commerce == true) {
          ret = dimension1;
        }
        Adversitement.history.clear("search");
      }
    }
    return ret;
  };
  
  //Public variables
  return /** @scope Adversitement.internalSearchHistory */ {
  
    /**
     * Places internal search keywords in history.
     * If it is conversion page or order confiramtion page sets custom metric to a value from internal search history
     * @param customMetricNr Integer from 1 to 50 indicating where to place the results
     * @param commerce If true sets Order Level Commerce Custom Metrics instead of standard Custom Metrics     
     */ 
    init: function(customMetricNr, commerce) {
      addKeywords();
      if(Adversitement.base.isThisConversionPage()) {
        if(commerce && commerce == true) {
          Adversitement.base.setOrderCustomMetric(customMetricNr, getKeywordsCustomMetric(true));
        } else {
          Adversitement.base.setCustomMetric(customMetricNr, getKeywordsCustomMetric());
        }
      }
    }
  };
}(); // create the actual object


/**
 * Track last campaign attribute and save it as conversion attribute  
 */
Adversitement.campaignAttributeHistory = function() {
  // private variables
  
  
  var attributeNames = [];
  
  
  /**
   * Adds campaign response attribute if avaible to history
   * @private   
   */ 
  var addAttribute = function() {
    var attr = '';
    attr = Adversitement.base.getParameter('hbx.hra');
    if(attr == '') {
      if(typeof(_hra) != 'undefined' && _hra != '') {
        attr = _hra;
      }
    }
    if(attr == '') {
      var hqsp = Adversitement.base.getHbxVariable('hqsp');
      if(hqsp != null && hqsp != '') {
        attr = Adversitement.base.getParameter(hqsp);  
      }
    }
    
    if(attr == '') {
      var hqsr = Adversitement.base.getHbxVariable('hqsr');
      if(hqsr != null && hqsr != '') {
        attr = Adversitement.base.getReferrerParameter(hqsr);  
      }
    }
    if(attr == '') {
      for(var i=0; i<attributeNames.length; i++) {
        attr = Adversitement.base.getParameter(attributeNames[i]);
        if(attr != '') {
          break;
        }
      }
    }
    if(attr != '') {
      //we only want last campaign attribute
      Adversitement.history.clear("cmp_attribute");
      
      Adversitement.history.add("cmp_attribute", attr);
    } else {
      var cmp = Adversitement.base.getCampaign();
      if(cmp != '') {
        Adversitement.history.clear("cmp_attribute");
      }
    }
  };
  
  
  /**
   * Returns Campaign Attribute stored in history   
   * @private   
   */
  var getAttribute = function() {
    var ret = "";
    var attr = Adversitement.history.read("cmp_attribute");
    if(attr.length > 0) {
      //we are only interested in first dimension
      attr = attr[0];    
      
      if(attr != '') {
        ret = attr;
        Adversitement.history.clear("cmp_attribute");
      }
    }
    return ret;
  };
  
  //Public variables
  return /** @scope Adversitement.campaignAttributeHistory */ {
  
    /**
     * Places last campaign attribute in history.
     * If it is conversion page or order confiramtion page sets conversion attribute to a value from attributes history
     * @param attrs Array of attribute names to look for in a URL     
     */ 
    init: function(attrs) {
      if(typeof(attrs) != 'undefined' && attrs.length > 0) {
        attributeNames = attrs;
      }
      addAttribute();
      if(Adversitement.base.isThisConversionPage()) {
        var conversionAttribute =  Adversitement.base.getHbxVariable('hcn');
        if(conversionAttribute !== null && conversionAttribute == "") {
          Adversitement.base.setHbxVariable('hcn', getAttribute());
        }
      }
    }
  };
}(); // create the actual object


// Call init function to set up hooks to event interfaces
Adversitement.base.init();
//----------- START minimized functions --------->



// Everything below this line is optional

Adversitement.base.campaignParameters = ['cmpid'];
Adversitement.base.useOrganicCampaigns = ['google.', 'yahoo.', 'live.com', 'ilse.nl'];
Adversitement.campaignHistory.useDirect = true;
//Adversitement.campaignHistory.saveKeyword = true;

// functions to be executed just before request construction. You can delete these functions if you don't need them.
Adversitement.base.addOnPrePVREvent(Adversitement.custom.addReferrer);
Adversitement.base.addOnPrePVREvent(Adversitement.custom.fixCommerceVariables);
//Adversitement.base.addOnPrePVREvent(Adversitement.custom.firstCampaign);
Adversitement.base.addOnPrePVREvent(Adversitement.custom.lastNoRefresh);
Adversitement.base.addOnPrePVREvent(Adversitement.custom.getCampaignFromHash);

// Uncomment lines below to track history.
// Don't forget to set parameter to a Custom Metric that you want to use

Adversitement.base.addOnPrePVREvent(function() {Adversitement.campaignHistory.init(1, true)}); // uses commerce custom metrics
//Adversitement.base.addOnPrePVREvent(function() {Adversitement.internalSearchHistory.init(2)});
//Adversitement.base.addOnPrePVREvent(function() {Adversitement.campaignAttributeHistory.init(['banner', 'attr'])});

