Skip to content

Instantly share code, notes, and snippets.

@billfitzgerald
Last active August 26, 2020 04:16
Show Gist options
  • Select an option

  • Save billfitzgerald/ed45bc777b78fad5f9f18100f0c14e87 to your computer and use it in GitHub Desktop.

Select an option

Save billfitzgerald/ed45bc777b78fad5f9f18100f0c14e87 to your computer and use it in GitHub Desktop.
Javascript loaded on the College Board site 28 July 2020, referenced in this story: https://medium.com/cr-digital-lab/student-tracking-and-the-college-board-512a94d60ec3
This file has been truncated, but you can view the full file.
/**
* @license
* Adobe Visitor API for JavaScript version: 4.6.0
* Copyright 2020 Adobe, Inc. All Rights Reserved
* More info available at https://marketing.adobe.com/resources/help/en_US/mcvid/
*/
var e=function(){"use strict";function e(t){"@babel/helpers - typeof";return(e="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e})(t)}function t(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function n(){return{callbacks:{},add:function(e,t){this.callbacks[e]=this.callbacks[e]||[];var n=this.callbacks[e].push(t)-1,i=this;return function(){i.callbacks[e].splice(n,1)}},execute:function(e,t){if(this.callbacks[e]){t=void 0===t?[]:t,t=t instanceof Array?t:[t];try{for(;this.callbacks[e].length;){var n=this.callbacks[e].shift();"function"==typeof n?n.apply(null,t):n instanceof Array&&n[1].apply(n[0],t)}delete this.callbacks[e]}catch(e){}}},executeAll:function(e,t){(t||e&&!j.isObjectEmpty(e))&&Object.keys(this.callbacks).forEach(function(t){var n=void 0!==e[t]?e[t]:"";this.execute(t,n)},this)},hasCallbacks:function(){return Boolean(Object.keys(this.callbacks).length)}}}function i(e,t,n){var i=null==e?void 0:e[t];return void 0===i?n:i}function r(e){for(var t=/^\d+$/,n=0,i=e.length;n<i;n++)if(!t.test(e[n]))return!1;return!0}function a(e,t){for(;e.length<t.length;)e.push("0");for(;t.length<e.length;)t.push("0")}function o(e,t){for(var n=0;n<e.length;n++){var i=parseInt(e[n],10),r=parseInt(t[n],10);if(i>r)return 1;if(r>i)return-1}return 0}function s(e,t){if(e===t)return 0;var n=e.toString().split("."),i=t.toString().split(".");return r(n.concat(i))?(a(n,i),o(n,i)):NaN}function l(e){return e===Object(e)&&0===Object.keys(e).length}function c(e){return"function"==typeof e||e instanceof Array&&e.length}function u(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:"",t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:function(){return!0};this.log=_e("log",e,t),this.warn=_e("warn",e,t),this.error=_e("error",e,t)}function d(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{},t=e.isEnabled,n=e.cookieName,i=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{},r=i.cookies;return t&&n&&r?{remove:function(){r.remove(n)},get:function(){var e=r.get(n),t={};try{t=JSON.parse(e)}catch(e){t={}}return t},set:function(e,t){t=t||{},r.set(n,JSON.stringify(e),{domain:t.optInCookieDomain||"",cookieLifetime:t.optInStorageExpiry||3419e4,expires:!0})}}:{get:Pe,set:Pe,remove:Pe}}function f(e){this.name=this.constructor.name,this.message=e,"function"==typeof Error.captureStackTrace?Error.captureStackTrace(this,this.constructor):this.stack=new Error(e).stack}function p(){function e(e,t){var n=De(e);return n.length?n.every(function(e){return!!t[e]}):Se(t)}function t(){M(b),O(ce.COMPLETE),_(h.status,h.permissions),m.set(h.permissions,{optInCookieDomain:l,optInStorageExpiry:c}),C.execute(xe)}function n(e){return function(n,i){if(!Ae(n))throw new Error("[OptIn] Invalid category(-ies). Please use the `OptIn.Categories` enum.");return O(ce.CHANGED),Object.assign(b,ye(De(n),e)),i||t(),h}}var i=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{},r=i.doesOptInApply,a=i.previousPermissions,o=i.preOptInApprovals,s=i.isOptInStorageEnabled,l=i.optInCookieDomain,c=i.optInStorageExpiry,u=i.isIabContext,f=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{},p=f.cookies,g=Le(a);Re(g,"Invalid `previousPermissions`!"),Re(o,"Invalid `preOptInApprovals`!");var m=d({isEnabled:!!s,cookieName:"adobeujs-optin"},{cookies:p}),h=this,_=le(h),C=ge(),I=Me(g),v=Me(o),D=m.get(),S={},A=function(e,t){return ke(e)||t&&ke(t)?ce.COMPLETE:ce.PENDING}(I,D),y=function(e,t,n){var i=ye(pe,!r);return r?Object.assign({},i,e,t,n):i}(v,I,D),b=be(y),O=function(e){return A=e},M=function(e){return y=e};h.deny=n(!1),h.approve=n(!0),h.denyAll=h.deny.bind(h,pe),h.approveAll=h.approve.bind(h,pe),h.isApproved=function(t){return e(t,h.permissions)},h.isPreApproved=function(t){return e(t,v)},h.fetchPermissions=function(e){var t=arguments.length>1&&void 0!==arguments[1]&&arguments[1],n=t?h.on(ce.COMPLETE,e):Pe;return!r||r&&h.isComplete||!!o?e(h.permissions):t||C.add(xe,function(){return e(h.permissions)}),n},h.complete=function(){h.status===ce.CHANGED&&t()},h.registerPlugin=function(e){if(!e||!e.name||"function"!=typeof e.onRegister)throw new Error(je);S[e.name]||(S[e.name]=e,e.onRegister.call(e,h))},h.execute=Ne(S),Object.defineProperties(h,{permissions:{get:function(){return y}},status:{get:function(){return A}},Categories:{get:function(){return ue}},doesOptInApply:{get:function(){return!!r}},isPending:{get:function(){return h.status===ce.PENDING}},isComplete:{get:function(){return h.status===ce.COMPLETE}},__plugins:{get:function(){return Object.keys(S)}},isIabContext:{get:function(){return u}}})}function g(e,t){function n(){r=null,e.call(e,new f("The call took longer than you wanted!"))}function i(){r&&(clearTimeout(r),e.apply(e,arguments))}if(void 0===t)return e;var r=setTimeout(n,t);return i}function m(){if(window.__cmp)return window.__cmp;var e=window;if(e===window.top)return void Ie.error("__cmp not found");for(var t;!t;){e=e.parent;try{e.frames.__cmpLocator&&(t=e)}catch(e){}if(e===window.top)break}if(!t)return void Ie.error("__cmp not found");var n={};return window.__cmp=function(e,i,r){var a=Math.random()+"",o={__cmpCall:{command:e,parameter:i,callId:a}};n[a]=r,t.postMessage(o,"*")},window.addEventListener("message",function(e){var t=e.data;if("string"==typeof t)try{t=JSON.parse(e.data)}catch(e){}if(t.__cmpReturn){var i=t.__cmpReturn;n[i.callId]&&(n[i.callId](i.returnValue,i.success),delete n[i.callId])}},!1),window.__cmp}function h(){var e=this;e.name="iabPlugin",e.version="0.0.1";var t=ge(),n={allConsentData:null},i=function(e){var t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{};return n[e]=t};e.fetchConsentData=function(e){var t=e.callback,n=e.timeout,i=g(t,n);r({callback:i})},e.isApproved=function(e){var t=e.callback,i=e.category,a=e.timeout;if(n.allConsentData)return t(null,s(i,n.allConsentData.vendorConsents,n.allConsentData.purposeConsents));var o=g(function(e){var n=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{},r=n.vendorConsents,a=n.purposeConsents;t(e,s(i,r,a))},a);r({category:i,callback:o})},e.onRegister=function(t){var n=Object.keys(de),i=function(e){var i=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{},r=i.purposeConsents,a=i.gdprApplies,o=i.vendorConsents;!e&&a&&o&&r&&(n.forEach(function(e){var n=s(e,o,r);t[n?"approve":"deny"](e,!0)}),t.complete())};e.fetchConsentData({callback:i})};var r=function(e){var r=e.callback;if(n.allConsentData)return r(null,n.allConsentData);t.add("FETCH_CONSENT_DATA",r);var s={};o(function(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{},r=e.purposeConsents,o=e.gdprApplies,l=e.vendorConsents;(arguments.length>1?arguments[1]:void 0)&&(s={purposeConsents:r,gdprApplies:o,vendorConsents:l},i("allConsentData",s)),a(function(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{};(arguments.length>1?arguments[1]:void 0)&&(s.consentString=e.consentData,i("allConsentData",s)),t.execute("FETCH_CONSENT_DATA",[null,n.allConsentData])})})},a=function(e){var t=m();t&&t("getConsentData",null,e)},o=function(e){var t=Fe(de),n=m();n&&n("getVendorConsents",t,e)},s=function(e){var t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{},n=arguments.length>2&&void 0!==arguments[2]?arguments[2]:{},i=!!t[de[e]];return i&&function(){return fe[e].every(function(e){return n[e]})}()}}var _="undefined"!=typeof globalThis?globalThis:"undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self?self:{};Object.assign=Object.assign||function(e){for(var t,n,i=1;i<arguments.length;++i){n=arguments[i];for(t in n)Object.prototype.hasOwnProperty.call(n,t)&&(e[t]=n[t])}return e};var C,I,v={HANDSHAKE:"HANDSHAKE",GETSTATE:"GETSTATE",PARENTSTATE:"PARENTSTATE"},D={MCMID:"MCMID",MCAID:"MCAID",MCAAMB:"MCAAMB",MCAAMLH:"MCAAMLH",MCOPTOUT:"MCOPTOUT",CUSTOMERIDS:"CUSTOMERIDS"},S={MCMID:"getMarketingCloudVisitorID",MCAID:"getAnalyticsVisitorID",MCAAMB:"getAudienceManagerBlob",MCAAMLH:"getAudienceManagerLocationHint",MCOPTOUT:"isOptedOut",ALLFIELDS:"getVisitorValues"},A={CUSTOMERIDS:"getCustomerIDs"},y={MCMID:"getMarketingCloudVisitorID",MCAAMB:"getAudienceManagerBlob",MCAAMLH:"getAudienceManagerLocationHint",MCOPTOUT:"isOptedOut",MCAID:"getAnalyticsVisitorID",CUSTOMERIDS:"getCustomerIDs",ALLFIELDS:"getVisitorValues"},b={MC:"MCMID",A:"MCAID",AAM:"MCAAMB"},O={MCMID:"MCMID",MCOPTOUT:"MCOPTOUT",MCAID:"MCAID",MCAAMLH:"MCAAMLH",MCAAMB:"MCAAMB"},M={UNKNOWN:0,AUTHENTICATED:1,LOGGED_OUT:2},k={GLOBAL:"global"},E={MESSAGES:v,STATE_KEYS_MAP:D,ASYNC_API_MAP:S,SYNC_API_MAP:A,ALL_APIS:y,FIELDGROUP_TO_FIELD:b,FIELDS:O,AUTH_STATE:M,OPT_OUT:k},T=E.STATE_KEYS_MAP,P=function(e){function t(){}function n(t,n){var i=this;return function(){var r=e(0,t),a={};return a[t]=r,i.setStateAndPublish(a),n(r),r}}this.getMarketingCloudVisitorID=function(e){e=e||t;var i=this.findField(T.MCMID,e),r=n.call(this,T.MCMID,e);return void 0!==i?i:r()},this.getVisitorValues=function(e){this.getMarketingCloudVisitorID(function(t){e({MCMID:t})})}},L=E.MESSAGES,R=E.ASYNC_API_MAP,w=E.SYNC_API_MAP,F=function(){function e(){}function t(e,t){var n=this;return function(){return n.callbackRegistry.add(e,t),n.messageParent(L.GETSTATE),""}}function n(n){this[R[n]]=function(i){i=i||e;var r=this.findField(n,i),a=t.call(this,n,i);return void 0!==r?r:a()}}function i(t){this[w[t]]=function(){return this.findField(t,e)||{}}}Object.keys(R).forEach(n,this),Object.keys(w).forEach(i,this)},N=E.ASYNC_API_MAP,x=function(){Object.keys(N).forEach(function(e){this[N[e]]=function(t){this.callbackRegistry.add(e,t)}},this)},j=function(e,t){return t={exports:{}},e(t,t.exports),t.exports}(function(t,n){n.isObjectEmpty=function(e){return e===Object(e)&&0===Object.keys(e).length},n.isValueEmpty=function(e){return""===e||n.isObjectEmpty(e)};var i=function(){var e=navigator.appName,t=navigator.userAgent;return"Microsoft Internet Explorer"===e||t.indexOf("MSIE ")>=0||t.indexOf("Trident/")>=0&&t.indexOf("Windows NT 6")>=0};n.getIeVersion=function(){return document.documentMode?document.documentMode:i()?7:null},n.encodeAndBuildRequest=function(e,t){return e.map(encodeURIComponent).join(t)},n.isObject=function(t){return null!==t&&"object"===e(t)&&!1===Array.isArray(t)},n.defineGlobalNamespace=function(){return window.adobe=n.isObject(window.adobe)?window.adobe:{},window.adobe},n.pluck=function(e,t){return t.reduce(function(t,n){return e[n]&&(t[n]=e[n]),t},Object.create(null))},n.parseOptOut=function(e,t,n){t||(t=n,e.d_optout&&e.d_optout instanceof Array&&(t=e.d_optout.join(",")));var i=parseInt(e.d_ottl,10);return isNaN(i)&&(i=7200),{optOut:t,d_ottl:i}},n.normalizeBoolean=function(e){var t=e;return"true"===e?t=!0:"false"===e&&(t=!1),t}}),V=(j.isObjectEmpty,j.isValueEmpty,j.getIeVersion,j.encodeAndBuildRequest,j.isObject,j.defineGlobalNamespace,j.pluck,j.parseOptOut,j.normalizeBoolean,n),U=E.MESSAGES,H={0:"prefix",1:"orgID",2:"state"},B=function(e,t){this.parse=function(e){try{var t={};return e.data.split("|").forEach(function(e,n){if(void 0!==e){t[H[n]]=2!==n?e:JSON.parse(e)}}),t}catch(e){}},this.isInvalid=function(n){var i=this.parse(n);if(!i||Object.keys(i).length<2)return!0;var r=e!==i.orgID,a=!t||n.origin!==t,o=-1===Object.keys(U).indexOf(i.prefix);return r||a||o},this.send=function(n,i,r){var a=i+"|"+e;r&&r===Object(r)&&(a+="|"+JSON.stringify(r));try{n.postMessage(a,t)}catch(e){}}},G=E.MESSAGES,Y=function(e,t,n,i){function r(e){Object.assign(p,e)}function a(e){Object.assign(p.state,e),Object.assign(p.state.ALLFIELDS,e),p.callbackRegistry.executeAll(p.state)}function o(e){if(!h.isInvalid(e)){m=!1;var t=h.parse(e);p.setStateAndPublish(t.state)}}function s(e){!m&&g&&(m=!0,h.send(i,e))}function l(){r(new P(n._generateID)),p.getMarketingCloudVisitorID(),p.callbackRegistry.executeAll(p.state,!0),_.removeEventListener("message",c)}function c(e){if(!h.isInvalid(e)){var t=h.parse(e);m=!1,_.clearTimeout(p._handshakeTimeout),_.removeEventListener("message",c),r(new F(p)),_.addEventListener("message",o),p.setStateAndPublish(t.state),p.callbackRegistry.hasCallbacks()&&s(G.GETSTATE)}}function u(){g&&postMessage?(_.addEventListener("message",c),s(G.HANDSHAKE),p._handshakeTimeout=setTimeout(l,250)):l()}function d(){_.s_c_in||(_.s_c_il=[],_.s_c_in=0),p._c="Visitor",p._il=_.s_c_il,p._in=_.s_c_in,p._il[p._in]=p,_.s_c_in++}function f(){function e(e){0!==e.indexOf("_")&&"function"==typeof n[e]&&(p[e]=function(){})}Object.keys(n).forEach(e),p.getSupplementalDataID=n.getSupplementalDataID,p.isAllowed=function(){return!0}}var p=this,g=t.whitelistParentDomain;p.state={ALLFIELDS:{}},p.version=n.version,p.marketingCloudOrgID=e,p.cookieDomain=n.cookieDomain||"",p._instanceType="child";var m=!1,h=new B(e,g);p.callbackRegistry=V(),p.init=function(){d(),f(),r(new x(p)),u()},p.findField=function(e,t){if(void 0!==p.state[e])return t(p.state[e]),p.state[e]},p.messageParent=s,p.setStateAndPublish=a},q=E.MESSAGES,X=E.ALL_APIS,W=E.ASYNC_API_MAP,J=E.FIELDGROUP_TO_FIELD,K=function(e,t){function n(){var t={};return Object.keys(X).forEach(function(n){var i=X[n],r=e[i]();j.isValueEmpty(r)||(t[n]=r)}),t}function i(){var t=[];return e._loading&&Object.keys(e._loading).forEach(function(n){if(e._loading[n]){var i=J[n];t.push(i)}}),t.length?t:null}function r(t){return function n(r){var a=i();if(a){var o=W[a[0]];e[o](n,!0)}else t()}}function a(e,i){var r=n();t.send(e,i,r)}function o(e){l(e),a(e,q.HANDSHAKE)}function s(e){r(function(){a(e,q.PARENTSTATE)})()}function l(n){function i(i){r.call(e,i),t.send(n,q.PARENTSTATE,{CUSTOMERIDS:e.getCustomerIDs()})}var r=e.setCustomerIDs;e.setCustomerIDs=i}return function(e){if(!t.isInvalid(e)){(t.parse(e).prefix===q.HANDSHAKE?o:s)(e.source)}}},z=function(e,t){function n(e){return function(n){i[e]=n,r++,r===a&&t(i)}}var i={},r=0,a=Object.keys(e).length;Object.keys(e).forEach(function(t){var i=e[t];if(i.fn){var r=i.args||[];r.unshift(n(t)),i.fn.apply(i.context||null,r)}})},Q={get:function(e){e=encodeURIComponent(e);var t=(";"+document.cookie).split(" ").join(";"),n=t.indexOf(";"+e+"="),i=n<0?n:t.indexOf(";",n+1);return n<0?"":decodeURIComponent(t.substring(n+2+e.length,i<0?t.length:i))},set:function(e,t,n){var r=i(n,"cookieLifetime"),a=i(n,"expires"),o=i(n,"domain"),s=i(n,"secure"),l=s?"Secure":"";if(a&&"SESSION"!==r&&"NONE"!==r){var c=""!==t?parseInt(r||0,10):-60;if(c)a=new Date,a.setTime(a.getTime()+1e3*c);else if(1===a){a=new Date;var u=a.getYear();a.setYear(u+2+(u<1900?1900:0))}}else a=0;return e&&"NONE"!==r?(document.cookie=encodeURIComponent(e)+"="+encodeURIComponent(t)+"; path=/;"+(a?" expires="+a.toGMTString()+";":"")+(o?" domain="+o+";":"")+l,this.get(e)===t):0},remove:function(e,t){var n=i(t,"domain");n=n?" domain="+n+";":"",document.cookie=encodeURIComponent(e)+"=; Path=/; Expires=Thu, 01 Jan 1970 00:00:01 GMT;"+n}},$=function(e){var t;!e&&_.location&&(e=_.location.hostname),t=e;var n,i=t.split(".");for(n=i.length-2;n>=0;n--)if(t=i.slice(n).join("."),Q.set("test","cookie",{domain:t}))return Q.remove("test",{domain:t}),t;return""},Z={compare:s,isLessThan:function(e,t){return s(e,t)<0},areVersionsDifferent:function(e,t){return 0!==s(e,t)},isGreaterThan:function(e,t){return s(e,t)>0},isEqual:function(e,t){return 0===s(e,t)}},ee=!!_.postMessage,te={postMessage:function(e,t,n){var i=1;t&&(ee?n.postMessage(e,t.replace(/([^:]+:\/\/[^\/]+).*/,"$1")):t&&(n.location=t.replace(/#.*$/,"")+"#"+ +new Date+i+++"&"+e))},receiveMessage:function(e,t){var n;try{ee&&(e&&(n=function(n){if("string"==typeof t&&n.origin!==t||"[object Function]"===Object.prototype.toString.call(t)&&!1===t(n.origin))return!1;e(n)}),_.addEventListener?_[e?"addEventListener":"removeEventListener"]("message",n):_[e?"attachEvent":"detachEvent"]("onmessage",n))}catch(e){}}},ne=function(e){var t,n,i="0123456789",r="",a="",o=8,s=10,l=10;if(1==e){for(i+="ABCDEF",t=0;16>t;t++)n=Math.floor(Math.random()*o),r+=i.substring(n,n+1),n=Math.floor(Math.random()*o),a+=i.substring(n,n+1),o=16;return r+"-"+a}for(t=0;19>t;t++)n=Math.floor(Math.random()*s),r+=i.substring(n,n+1),0===t&&9==n?s=3:(1==t||2==t)&&10!=s&&2>n?s=10:2<t&&(s=10),n=Math.floor(Math.random()*l),a+=i.substring(n,n+1),0===t&&9==n?l=3:(1==t||2==t)&&10!=l&&2>n?l=10:2<t&&(l=10);return r+a},ie=function(e,t){return{corsMetadata:function(){var e="none",t=!0;return"undefined"!=typeof XMLHttpRequest&&XMLHttpRequest===Object(XMLHttpRequest)&&("withCredentials"in new XMLHttpRequest?e="XMLHttpRequest":"undefined"!=typeof XDomainRequest&&XDomainRequest===Object(XDomainRequest)&&(t=!1),Object.prototype.toString.call(_.HTMLElement).indexOf("Constructor")>0&&(t=!1)),{corsType:e,corsCookiesEnabled:t}}(),getCORSInstance:function(){return"none"===this.corsMetadata.corsType?null:new _[this.corsMetadata.corsType]},fireCORS:function(t,n,i){function r(e){var n;try{if((n=JSON.parse(e))!==Object(n))return void a.handleCORSError(t,null,"Response is not JSON")}catch(e){return void a.handleCORSError(t,e,"Error parsing response as JSON")}try{for(var i=t.callback,r=_,o=0;o<i.length;o++)r=r[i[o]];r(n)}catch(e){a.handleCORSError(t,e,"Error forming callback function")}}var a=this;n&&(t.loadErrorHandler=n);try{var o=this.getCORSInstance();o.open("get",t.corsUrl+"&ts="+(new Date).getTime(),!0),"XMLHttpRequest"===this.corsMetadata.corsType&&(o.withCredentials=!0,o.timeout=e.loadTimeout,o.setRequestHeader("Content-Type","application/x-www-form-urlencoded"),o.onreadystatechange=function(){4===this.readyState&&200===this.status&&r(this.responseText)}),o.onerror=function(e){a.handleCORSError(t,e,"onerror")},o.ontimeout=function(e){a.handleCORSError(t,e,"ontimeout")},o.send(),e._log.requests.push(t.corsUrl)}catch(e){this.handleCORSError(t,e,"try-catch")}},handleCORSError:function(t,n,i){e.CORSErrors.push({corsData:t,error:n,description:i}),t.loadErrorHandler&&("ontimeout"===i?t.loadErrorHandler(!0):t.loadErrorHandler(!1))}}},re={POST_MESSAGE_ENABLED:!!_.postMessage,DAYS_BETWEEN_SYNC_ID_CALLS:1,MILLIS_PER_DAY:864e5,ADOBE_MC:"adobe_mc",ADOBE_MC_SDID:"adobe_mc_sdid",VALID_VISITOR_ID_REGEX:/^[0-9a-fA-F\-]+$/,ADOBE_MC_TTL_IN_MIN:5,VERSION_REGEX:/vVersion\|((\d+\.)?(\d+\.)?(\*|\d+))(?=$|\|)/,FIRST_PARTY_SERVER_COOKIE:"s_ecid"},ae=function(e,t){var n=_.document;return{THROTTLE_START:3e4,MAX_SYNCS_LENGTH:649,throttleTimerSet:!1,id:null,onPagePixels:[],iframeHost:null,getIframeHost:function(e){if("string"==typeof e){var t=e.split("/");return t[0]+"//"+t[2]}},subdomain:null,url:null,getUrl:function(){var t,i="http://fast.",r="?d_nsid="+e.idSyncContainerID+"#"+encodeURIComponent(n.location.origin);return this.subdomain||(this.subdomain="nosubdomainreturned"),e.loadSSL&&(i=e.idSyncSSLUseAkamai?"https://fast.":"https://"),t=i+this.subdomain+".demdex.net/dest5.html"+r,this.iframeHost=this.getIframeHost(t),this.id="destination_publishing_iframe_"+this.subdomain+"_"+e.idSyncContainerID,t},checkDPIframeSrc:function(){var t="?d_nsid="+e.idSyncContainerID+"#"+encodeURIComponent(n.location.href);"string"==typeof e.dpIframeSrc&&e.dpIframeSrc.length&&(this.id="destination_publishing_iframe_"+(e._subdomain||this.subdomain||(new Date).getTime())+"_"+e.idSyncContainerID,this.iframeHost=this.getIframeHost(e.dpIframeSrc),this.url=e.dpIframeSrc+t)},idCallNotProcesssed:null,doAttachIframe:!1,startedAttachingIframe:!1,iframeHasLoaded:null,iframeIdChanged:null,newIframeCreated:null,originalIframeHasLoadedAlready:null,iframeLoadedCallbacks:[],regionChanged:!1,timesRegionChanged:0,sendingMessages:!1,messages:[],messagesPosted:[],messagesReceived:[],messageSendingInterval:re.POST_MESSAGE_ENABLED?null:100,onPageDestinationsFired:[],jsonForComparison:[],jsonDuplicates:[],jsonWaiting:[],jsonProcessed:[],canSetThirdPartyCookies:!0,receivedThirdPartyCookiesNotification:!1,readyToAttachIframePreliminary:function(){return!(e.idSyncDisableSyncs||e.disableIdSyncs||e.idSyncDisable3rdPartySyncing||e.disableThirdPartyCookies||e.disableThirdPartyCalls)},readyToAttachIframe:function(){return this.readyToAttachIframePreliminary()&&(this.doAttachIframe||e._doAttachIframe)&&(this.subdomain&&"nosubdomainreturned"!==this.subdomain||e._subdomain)&&this.url&&!this.startedAttachingIframe},attachIframe:function(){function e(){r=n.createElement("iframe"),r.sandbox="allow-scripts allow-same-origin",r.title="Adobe ID Syncing iFrame",r.id=i.id,r.name=i.id+"_name",r.style.cssText="display: none; width: 0; height: 0;",r.src=i.url,i.newIframeCreated=!0,t(),n.body.appendChild(r)}function t(e){r.addEventListener("load",function(){r.className="aamIframeLoaded",i.iframeHasLoaded=!0,i.fireIframeLoadedCallbacks(e),i.requestToProcess()})}this.startedAttachingIframe=!0;var i=this,r=n.getElementById(this.id);r?"IFRAME"!==r.nodeName?(this.id+="_2",this.iframeIdChanged=!0,e()):(this.newIframeCreated=!1,"aamIframeLoaded"!==r.className?(this.originalIframeHasLoadedAlready=!1,t("The destination publishing iframe already exists from a different library, but hadn't loaded yet.")):(this.originalIframeHasLoadedAlready=!0,this.iframeHasLoaded=!0,this.iframe=r,this.fireIframeLoadedCallbacks("The destination publishing iframe already exists from a different library, and had loaded alresady."),this.requestToProcess())):e(),this.iframe=r},fireIframeLoadedCallbacks:function(e){this.iframeLoadedCallbacks.forEach(function(t){"function"==typeof t&&t({message:e||"The destination publishing iframe was attached and loaded successfully."})}),this.iframeLoadedCallbacks=[]},requestToProcess:function(t){function n(){r.jsonForComparison.push(t),r.jsonWaiting.push(t),r.processSyncOnPage(t)}var i,r=this;if(t===Object(t)&&t.ibs)if(i=JSON.stringify(t.ibs||[]),this.jsonForComparison.length){var a,o,s,l=!1;for(a=0,o=this.jsonForComparison.length;a<o;a++)if(s=this.jsonForComparison[a],i===JSON.stringify(s.ibs||[])){l=!0;break}l?this.jsonDuplicates.push(t):n()}else n();if((this.receivedThirdPartyCookiesNotification||!re.POST_MESSAGE_ENABLED||this.iframeHasLoaded)&&this.jsonWaiting.length){var c=this.jsonWaiting.shift();this.process(c),this.requestToProcess()}e.idSyncDisableSyncs||e.disableIdSyncs||!this.iframeHasLoaded||!this.messages.length||this.sendingMessages||(this.throttleTimerSet||(this.throttleTimerSet=!0,setTimeout(function(){r.messageSendingInterval=re.POST_MESSAGE_ENABLED?null:150},this.THROTTLE_START)),this.sendingMessages=!0,this.sendMessages())},getRegionAndCheckIfChanged:function(t,n){var i=e._getField("MCAAMLH"),r=t.d_region||t.dcs_region;return i?r&&(e._setFieldExpire("MCAAMLH",n),e._setField("MCAAMLH",r),parseInt(i,10)!==r&&(this.regionChanged=!0,this.timesRegionChanged++,e._setField("MCSYNCSOP",""),e._setField("MCSYNCS",""),i=r)):(i=r)&&(e._setFieldExpire("MCAAMLH",n),e._setField("MCAAMLH",i)),i||(i=""),i},processSyncOnPage:function(e){var t,n,i,r;if((t=e.ibs)&&t instanceof Array&&(n=t.length))for(i=0;i<n;i++)r=t[i],r.syncOnPage&&this.checkFirstPartyCookie(r,"","syncOnPage")},process:function(e){var t,n,i,r,a,o=encodeURIComponent,s=!1;if((t=e.ibs)&&t instanceof Array&&(n=t.length))for(s=!0,i=0;i<n;i++)r=t[i],a=[o("ibs"),o(r.id||""),o(r.tag||""),j.encodeAndBuildRequest(r.url||[],","),o(r.ttl||""),"","",r.fireURLSync?"true":"false"],r.syncOnPage||(this.canSetThirdPartyCookies?this.addMessage(a.join("|")):r.fireURLSync&&this.checkFirstPartyCookie(r,a.join("|")));s&&this.jsonProcessed.push(e)},checkFirstPartyCookie:function(t,n,i){var r="syncOnPage"===i,a=r?"MCSYNCSOP":"MCSYNCS";e._readVisitor();var o,s,l=e._getField(a),c=!1,u=!1,d=Math.ceil((new Date).getTime()/re.MILLIS_PER_DAY);l?(o=l.split("*"),s=this.pruneSyncData(o,t.id,d),c=s.dataPresent,u=s.dataValid,c&&u||this.fireSync(r,t,n,o,a,d)):(o=[],this.fireSync(r,t,n,o,a,d))},pruneSyncData:function(e,t,n){var i,r,a,o=!1,s=!1;for(r=0;r<e.length;r++)i=e[r],a=parseInt(i.split("-")[1],10),i.match("^"+t+"-")?(o=!0,n<a?s=!0:(e.splice(r,1),r--)):n>=a&&(e.splice(r,1),r--);return{dataPresent:o,dataValid:s}},manageSyncsSize:function(e){if(e.join("*").length>this.MAX_SYNCS_LENGTH)for(e.sort(function(e,t){return parseInt(e.split("-")[1],10)-parseInt(t.split("-")[1],10)});e.join("*").length>this.MAX_SYNCS_LENGTH;)e.shift()},fireSync:function(t,n,i,r,a,o){var s=this;if(t){if("img"===n.tag){var l,c,u,d,f=n.url,p=e.loadSSL?"https:":"http:";for(l=0,c=f.length;l<c;l++){u=f[l],d=/^\/\//.test(u);var g=new Image;g.addEventListener("load",function(t,n,i,r){return function(){s.onPagePixels[t]=null,e._readVisitor();var o,l=e._getField(a),c=[];if(l){o=l.split("*");var u,d,f;for(u=0,d=o.length;u<d;u++)f=o[u],f.match("^"+n.id+"-")||c.push(f)}s.setSyncTrackingData(c,n,i,r)}}(this.onPagePixels.length,n,a,o)),g.src=(d?p:"")+u,this.onPagePixels.push(g)}}}else this.addMessage(i),this.setSyncTrackingData(r,n,a,o)},addMessage:function(t){var n=encodeURIComponent,i=n(e._enableErrorReporting?"---destpub-debug---":"---destpub---");this.messages.push((re.POST_MESSAGE_ENABLED?"":i)+t)},setSyncTrackingData:function(t,n,i,r){t.push(n.id+"-"+(r+Math.ceil(n.ttl/60/24))),this.manageSyncsSize(t),e._setField(i,t.join("*"))},sendMessages:function(){var e,t=this,n="",i=encodeURIComponent;this.regionChanged&&(n=i("---destpub-clear-dextp---"),this.regionChanged=!1),this.messages.length?re.POST_MESSAGE_ENABLED?(e=n+i("---destpub-combined---")+this.messages.join("%01"),this.postMessage(e),this.messages=[],this.sendingMessages=!1):(e=this.messages.shift(),this.postMessage(n+e),setTimeout(function(){t.sendMessages()},this.messageSendingInterval)):this.sendingMessages=!1},postMessage:function(e){te.postMessage(e,this.url,this.iframe.contentWindow),this.messagesPosted.push(e)},receiveMessage:function(e){var t,n=/^---destpub-to-parent---/;"string"==typeof e&&n.test(e)&&(t=e.replace(n,"").split("|"),"canSetThirdPartyCookies"===t[0]&&(this.canSetThirdPartyCookies="true"===t[1],this.receivedThirdPartyCookiesNotification=!0,this.requestToProcess()),this.messagesReceived.push(e))},processIDCallData:function(i){(null==this.url||i.subdomain&&"nosubdomainreturned"===this.subdomain)&&("string"==typeof e._subdomain&&e._subdomain.length?this.subdomain=e._subdomain:this.subdomain=i.subdomain||"",this.url=this.getUrl()),i.ibs instanceof Array&&i.ibs.length&&(this.doAttachIframe=!0),this.readyToAttachIframe()&&(e.idSyncAttachIframeOnWindowLoad?(t.windowLoaded||"complete"===n.readyState||"loaded"===n.readyState)&&this.attachIframe():this.attachIframeASAP()),"function"==typeof e.idSyncIDCallResult?e.idSyncIDCallResult(i):this.requestToProcess(i),"function"==typeof e.idSyncAfterIDCallResult&&e.idSyncAfterIDCallResult(i)},canMakeSyncIDCall:function(t,n){return e._forceSyncIDCall||!t||n-t>re.DAYS_BETWEEN_SYNC_ID_CALLS},attachIframeASAP:function(){function e(){t.startedAttachingIframe||(n.body?t.attachIframe():setTimeout(e,30))}var t=this;e()}}},oe={audienceManagerServer:{},audienceManagerServerSecure:{},cookieDomain:{},cookieLifetime:{},cookieName:{},doesOptInApply:{},disableThirdPartyCalls:{},discardTrackingServerECID:{},idSyncAfterIDCallResult:{},idSyncAttachIframeOnWindowLoad:{},idSyncContainerID:{},idSyncDisable3rdPartySyncing:{},disableThirdPartyCookies:{},idSyncDisableSyncs:{},disableIdSyncs:{},idSyncIDCallResult:{},idSyncSSLUseAkamai:{},isCoopSafe:{},isIabContext:{},isOptInStorageEnabled:{},loadSSL:{},loadTimeout:{},marketingCloudServer:{},marketingCloudServerSecure:{},optInCookieDomain:{},optInStorageExpiry:{},overwriteCrossDomainMCIDAndAID:{},preOptInApprovals:{},previousPermissions:{},resetBeforeVersion:{},sdidParamExpiry:{},serverState:{},sessionCookieName:{},secureCookie:{},takeTimeoutMetrics:{},trackingServer:{},trackingServerSecure:{},whitelistIframeDomains:{},whitelistParentDomain:{}},se={getConfigNames:function(){return Object.keys(oe)},getConfigs:function(){return oe},normalizeConfig:function(e){return"function"!=typeof e?e:e()}},le=function(e){var t={};return e.on=function(e,n,i){if(!n||"function"!=typeof n)throw new Error("[ON] Callback should be a function.");t.hasOwnProperty(e)||(t[e]=[]);var r=t[e].push({callback:n,context:i})-1;return function(){t[e].splice(r,1),t[e].length||delete t[e]}},e.off=function(e,n){t.hasOwnProperty(e)&&(t[e]=t[e].filter(function(e){if(e.callback!==n)return e}))},e.publish=function(e){if(t.hasOwnProperty(e)){var n=[].slice.call(arguments,1);t[e].slice(0).forEach(function(e){e.callback.apply(e.context,n)})}},e.publish},ce={PENDING:"pending",CHANGED:"changed",COMPLETE:"complete"},ue={AAM:"aam",ADCLOUD:"adcloud",ANALYTICS:"aa",CAMPAIGN:"campaign",ECID:"ecid",LIVEFYRE:"livefyre",TARGET:"target",MEDIA_ANALYTICS:"mediaaa"},de=(C={},t(C,ue.AAM,565),t(C,ue.ECID,565),C),fe=(I={},t(I,ue.AAM,[1,2,5]),t(I,ue.ECID,[1,2,5]),I),pe=function(e){return Object.keys(e).map(function(t){return e[t]})}(ue),ge=function(){var e={};return e.callbacks=Object.create(null),e.add=function(t,n){if(!c(n))throw new Error("[callbackRegistryFactory] Make sure callback is a function or an array of functions.");e.callbacks[t]=e.callbacks[t]||[];var i=e.callbacks[t].push(n)-1;return function(){e.callbacks[t].splice(i,1)}},e.execute=function(t,n){if(e.callbacks[t]){n=void 0===n?[]:n,n=n instanceof Array?n:[n];try{for(;e.callbacks[t].length;){var i=e.callbacks[t].shift();"function"==typeof i?i.apply(null,n):i instanceof Array&&i[1].apply(i[0],n)}delete e.callbacks[t]}catch(e){}}},e.executeAll=function(t,n){(n||t&&!l(t))&&Object.keys(e.callbacks).forEach(function(n){var i=void 0!==t[n]?t[n]:"";e.execute(n,i)},e)},e.hasCallbacks=function(){return Boolean(Object.keys(e.callbacks).length)},e},me=function(){},he=function(e){var t=window,n=t.console;return!!n&&"function"==typeof n[e]},_e=function(e,t,n){return n()?function(){if(he(e)){for(var n=arguments.length,i=new Array(n),r=0;r<n;r++)i[r]=arguments[r];console[e].apply(console,[t].concat(i))}}:me},Ce=u,Ie=new Ce("[ADOBE OPT-IN]"),ve=function(t,n){return e(t)===n},De=function(e,t){return e instanceof Array?e:ve(e,"string")?[e]:t||[]},Se=function(e){var t=Object.keys(e);return!!t.length&&t.every(function(t){return!0===e[t]})},Ae=function(e){return!(!e||Oe(e))&&De(e).every(function(e){return pe.indexOf(e)>-1})},ye=function(e,t){return e.reduce(function(e,n){return e[n]=t,e},{})},be=function(e){return JSON.parse(JSON.stringify(e))},Oe=function(e){return"[object Array]"===Object.prototype.toString.call(e)&&!e.length},Me=function(e){if(Te(e))return e;try{return JSON.parse(e)}catch(e){return{}}},ke=function(e){return void 0===e||(Te(e)?Ae(Object.keys(e)):Ee(e))},Ee=function(e){try{var t=JSON.parse(e);return!!e&&ve(e,"string")&&Ae(Object.keys(t))}catch(e){return!1}},Te=function(e){return null!==e&&ve(e,"object")&&!1===Array.isArray(e)},Pe=function(){},Le=function(e){return ve(e,"function")?e():e},Re=function(e,t){ke(e)||Ie.error("".concat(t))},we=function(e){return Object.keys(e).map(function(t){return e[t]})},Fe=function(e){return we(e).filter(function(e,t,n){return n.indexOf(e)===t})},Ne=function(e){return function(){var t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{},n=t.command,i=t.params,r=void 0===i?{}:i,a=t.callback,o=void 0===a?Pe:a;if(!n||-1===n.indexOf("."))throw new Error("[OptIn.execute] Please provide a valid command.");try{var s=n.split("."),l=e[s[0]],c=s[1];if(!l||"function"!=typeof l[c])throw new Error("Make sure the plugin and API name exist.");var u=Object.assign(r,{callback:o});l[c].call(l,u)}catch(e){Ie.error("[execute] Something went wrong: "+e.message)}}};f.prototype=Object.create(Error.prototype),f.prototype.constructor=f;var xe="fetchPermissions",je="[OptIn#registerPlugin] Plugin is invalid.";p.Categories=ue,p.TimeoutError=f;var Ve=Object.freeze({OptIn:p,IabPlugin:h}),Ue=function(e,t){e.publishDestinations=function(n){var i=arguments[1],r=arguments[2];try{r="function"==typeof r?r:n.callback}catch(e){r=function(){}}var a=t;if(!a.readyToAttachIframePreliminary())return void r({error:"The destination publishing iframe is disabled in the Visitor library."});if("string"==typeof n){if(!n.length)return void r({error:"subdomain is not a populated string."});if(!(i instanceof Array&&i.length))return void r({error:"messages is not a populated array."});var o=!1
;if(i.forEach(function(e){"string"==typeof e&&e.length&&(a.addMessage(e),o=!0)}),!o)return void r({error:"None of the messages are populated strings."})}else{if(!j.isObject(n))return void r({error:"Invalid parameters passed."});var s=n;if("string"!=typeof(n=s.subdomain)||!n.length)return void r({error:"config.subdomain is not a populated string."});var l=s.urlDestinations;if(!(l instanceof Array&&l.length))return void r({error:"config.urlDestinations is not a populated array."});var c=[];l.forEach(function(e){j.isObject(e)&&(e.hideReferrer?e.message&&a.addMessage(e.message):c.push(e))});!function e(){c.length&&setTimeout(function(){var t=new Image,n=c.shift();t.src=n.url,a.onPageDestinationsFired.push(n),e()},100)}()}a.iframe?(r({message:"The destination publishing iframe is already attached and loaded."}),a.requestToProcess()):!e.subdomain&&e._getField("MCMID")?(a.subdomain=n,a.doAttachIframe=!0,a.url=a.getUrl(),a.readyToAttachIframe()?(a.iframeLoadedCallbacks.push(function(e){r({message:"Attempted to attach and load the destination publishing iframe through this API call. Result: "+(e.message||"no result")})}),a.attachIframe()):r({error:"Encountered a problem in attempting to attach and load the destination publishing iframe through this API call."})):a.iframeLoadedCallbacks.push(function(e){r({message:"Attempted to attach and load the destination publishing iframe through normal Visitor API processing. Result: "+(e.message||"no result")})})}},He=function e(t){function n(e,t){return e>>>t|e<<32-t}for(var i,r,a=Math.pow,o=a(2,32),s="",l=[],c=8*t.length,u=e.h=e.h||[],d=e.k=e.k||[],f=d.length,p={},g=2;f<64;g++)if(!p[g]){for(i=0;i<313;i+=g)p[i]=g;u[f]=a(g,.5)*o|0,d[f++]=a(g,1/3)*o|0}for(t+="ร‚โ‚ฌ";t.length%64-56;)t+="\0";for(i=0;i<t.length;i++){if((r=t.charCodeAt(i))>>8)return;l[i>>2]|=r<<(3-i)%4*8}for(l[l.length]=c/o|0,l[l.length]=c,r=0;r<l.length;){var m=l.slice(r,r+=16),h=u;for(u=u.slice(0,8),i=0;i<64;i++){var _=m[i-15],C=m[i-2],I=u[0],v=u[4],D=u[7]+(n(v,6)^n(v,11)^n(v,25))+(v&u[5]^~v&u[6])+d[i]+(m[i]=i<16?m[i]:m[i-16]+(n(_,7)^n(_,18)^_>>>3)+m[i-7]+(n(C,17)^n(C,19)^C>>>10)|0);u=[D+((n(I,2)^n(I,13)^n(I,22))+(I&u[1]^I&u[2]^u[1]&u[2]))|0].concat(u),u[4]=u[4]+D|0}for(i=0;i<8;i++)u[i]=u[i]+h[i]|0}for(i=0;i<8;i++)for(r=3;r+1;r--){var S=u[i]>>8*r&255;s+=(S<16?0:"")+S.toString(16)}return s},Be=function(e,t){return"SHA-256"!==t&&"SHA256"!==t&&"sha256"!==t&&"sha-256"!==t||(e=He(e)),e},Ge=function(e){return String(e).trim().toLowerCase()},Ye=Ve.OptIn;j.defineGlobalNamespace(),window.adobe.OptInCategories=Ye.Categories;var qe=function(t,n,i){function r(e){var t=e;return function(e){var n=e||D.location.href;try{var i=m._extractParamFromUri(n,t);if(i)return N.parsePipeDelimetedKeyValues(i)}catch(e){}}}function a(e){function t(e,t,n){e&&e.match(re.VALID_VISITOR_ID_REGEX)&&(n===y&&(v=!0),t(e))}t(e[y],m.setMarketingCloudVisitorID,y),m._setFieldExpire(T,-1),t(e[M],m.setAnalyticsVisitorID)}function o(e){e=e||{},m._supplementalDataIDCurrent=e.supplementalDataIDCurrent||"",m._supplementalDataIDCurrentConsumed=e.supplementalDataIDCurrentConsumed||{},m._supplementalDataIDLast=e.supplementalDataIDLast||"",m._supplementalDataIDLastConsumed=e.supplementalDataIDLastConsumed||{}}function s(e){function t(e,t,n){return n=n?n+="|":n,n+=e+"="+encodeURIComponent(t)}function n(e,n){var i=n[0],r=n[1];return null!=r&&r!==P&&(e=t(i,r,e)),e}var i=e.reduce(n,"");return function(e){var t=N.getTimestampInSeconds();return e=e?e+="|":e,e+="TS="+t}(i)}function l(e){var t=e.minutesToLive,n="";return(m.idSyncDisableSyncs||m.disableIdSyncs)&&(n=n||"Error: id syncs have been disabled"),"string"==typeof e.dpid&&e.dpid.length||(n=n||"Error: config.dpid is empty"),"string"==typeof e.url&&e.url.length||(n=n||"Error: config.url is empty"),void 0===t?t=20160:(t=parseInt(t,10),(isNaN(t)||t<=0)&&(n=n||"Error: config.minutesToLive needs to be a positive number")),{error:n,ttl:t}}function c(){return!!m.configs.doesOptInApply&&!(h.optIn.isComplete&&u())}function u(){return m.configs.doesOptInApply&&m.configs.isIabContext?h.optIn.isApproved(h.optIn.Categories.ECID)&&I:h.optIn.isApproved(h.optIn.Categories.ECID)}function d(){[["getMarketingCloudVisitorID"],["setCustomerIDs",void 0],["getAnalyticsVisitorID"],["getAudienceManagerLocationHint"],["getLocationHint"],["getAudienceManagerBlob"]].forEach(function(e){var t=e[0],n=2===e.length?e[1]:"",i=m[t];m[t]=function(e){return u()&&m.isAllowed()?i.apply(m,arguments):("function"==typeof e&&m._callCallback(e,[n]),n)}})}function f(e,t){if(I=!0,e)throw new Error("[IAB plugin] : "+e);t.gdprApplies&&(C=t.consentString),m.init(),g()}function p(){h.optIn.isComplete&&(h.optIn.isApproved(h.optIn.Categories.ECID)?m.configs.isIabContext?h.optIn.execute({command:"iabPlugin.fetchConsentData",callback:f}):(m.init(),g()):(d(),g()))}function g(){h.optIn.off("complete",p)}if(!i||i.split("").reverse().join("")!==t)throw new Error("Please use `Visitor.getInstance` to instantiate Visitor.");var m=this,h=window.adobe,C="",I=!1,v=!1;m.version="4.6.0";var D=_,S=D.Visitor;S.version=m.version,S.AuthState=E.AUTH_STATE,S.OptOut=E.OPT_OUT,D.s_c_in||(D.s_c_il=[],D.s_c_in=0),m._c="Visitor",m._il=D.s_c_il,m._in=D.s_c_in,m._il[m._in]=m,D.s_c_in++,m._instanceType="regular",m._log={requests:[]},m.marketingCloudOrgID=t,m.cookieName="AMCV_"+t,m.sessionCookieName="AMCVS_"+t,m.cookieDomain=$(),m.loadSSL=!0,m.loadTimeout=3e4,m.CORSErrors=[],m.marketingCloudServer=m.audienceManagerServer="dpm.demdex.net",m.sdidParamExpiry=30;var A=null,y="MCMID",b="MCIDTS",O="A",M="MCAID",k="AAM",T="MCAAMB",P="NONE",L=function(e){return!Object.prototype[e]},R=ie(m);m.FIELDS=E.FIELDS,m.cookieRead=function(e){return Q.get(e)},m.cookieWrite=function(e,t,n){var i=m.cookieLifetime?(""+m.cookieLifetime).toUpperCase():"",r=!1;return m.configs&&m.configs.secureCookie&&"https:"===location.protocol&&(r=!0),Q.set(e,""+t,{expires:n,domain:m.cookieDomain,cookieLifetime:i,secure:r})},m.resetState=function(e){e?m._mergeServerState(e):o()},m._isAllowedDone=!1,m._isAllowedFlag=!1,m.isAllowed=function(){return m._isAllowedDone||(m._isAllowedDone=!0,(m.cookieRead(m.cookieName)||m.cookieWrite(m.cookieName,"T",1))&&(m._isAllowedFlag=!0)),"T"===m.cookieRead(m.cookieName)&&m._helpers.removeCookie(m.cookieName),m._isAllowedFlag},m.setMarketingCloudVisitorID=function(e){m._setMarketingCloudFields(e)},m._use1stPartyMarketingCloudServer=!1,m.getMarketingCloudVisitorID=function(e,t){m.marketingCloudServer&&m.marketingCloudServer.indexOf(".demdex.net")<0&&(m._use1stPartyMarketingCloudServer=!0);var n=m._getAudienceManagerURLData("_setMarketingCloudFields"),i=n.url;return m._getRemoteField(y,i,e,t,n)};var w=function(e,t){var n={};m.getMarketingCloudVisitorID(function(){t.forEach(function(e){n[e]=m._getField(e,!0)}),-1!==t.indexOf("MCOPTOUT")?m.isOptedOut(function(t){n.MCOPTOUT=t,e(n)},null,!0):e(n)},!0)};m.getVisitorValues=function(e,t){var n={MCMID:{fn:m.getMarketingCloudVisitorID,args:[!0],context:m},MCOPTOUT:{fn:m.isOptedOut,args:[void 0,!0],context:m},MCAID:{fn:m.getAnalyticsVisitorID,args:[!0],context:m},MCAAMLH:{fn:m.getAudienceManagerLocationHint,args:[!0],context:m},MCAAMB:{fn:m.getAudienceManagerBlob,args:[!0],context:m}},i=t&&t.length?j.pluck(n,t):n;t&&-1===t.indexOf("MCAID")?w(e,t):z(i,e)},m._currentCustomerIDs={},m._customerIDsHashChanged=!1,m._newCustomerIDsHash="",m.setCustomerIDs=function(t,n){function i(){m._customerIDsHashChanged=!1}if(!m.isOptedOut()&&t){if(!j.isObject(t)||j.isObjectEmpty(t))return!1;m._readVisitor();var r,a,o;for(r in t)if(L(r)&&(a=t[r],n=a.hasOwnProperty("hashType")?a.hashType:n,a))if("object"===e(a)){var s={};if(a.id){if(n){if(!(o=Be(Ge(a.id),n)))return;a.id=o,s.hashType=n}s.id=a.id}void 0!=a.authState&&(s.authState=a.authState),m._currentCustomerIDs[r]=s}else if(n){if(!(o=Be(Ge(a),n)))return;m._currentCustomerIDs[r]={id:o,hashType:n}}else m._currentCustomerIDs[r]={id:a};var l=m.getCustomerIDs(),c=m._getField("MCCIDH"),u="";c||(c=0);for(r in l)L(r)&&(a=l[r],u+=(u?"|":"")+r+"|"+(a.id?a.id:"")+(a.authState?a.authState:""));m._newCustomerIDsHash=String(m._hash(u)),m._newCustomerIDsHash!==c&&(m._customerIDsHashChanged=!0,m._mapCustomerIDs(i))}},m.getCustomerIDs=function(){m._readVisitor();var e,t,n={};for(e in m._currentCustomerIDs)L(e)&&(t=m._currentCustomerIDs[e],t.id&&(n[e]||(n[e]={}),n[e].id=t.id,void 0!=t.authState?n[e].authState=t.authState:n[e].authState=S.AuthState.UNKNOWN,t.hashType&&(n[e].hashType=t.hashType)));return n},m.setAnalyticsVisitorID=function(e){m._setAnalyticsFields(e)},m.getAnalyticsVisitorID=function(e,t,n){if(!N.isTrackingServerPopulated()&&!n)return m._callCallback(e,[""]),"";var i="";if(n||(i=m.getMarketingCloudVisitorID(function(t){m.getAnalyticsVisitorID(e,!0)})),i||n){var r=n?m.marketingCloudServer:m.trackingServer,a="";m.loadSSL&&(n?m.marketingCloudServerSecure&&(r=m.marketingCloudServerSecure):m.trackingServerSecure&&(r=m.trackingServerSecure));var o={};if(r){var s="http"+(m.loadSSL?"s":"")+"://"+r+"/id",l="d_visid_ver="+m.version+"&mcorgid="+encodeURIComponent(m.marketingCloudOrgID)+(i?"&mid="+encodeURIComponent(i):"")+(m.idSyncDisable3rdPartySyncing||m.disableThirdPartyCookies?"&d_coppa=true":""),c=["s_c_il",m._in,"_set"+(n?"MarketingCloud":"Analytics")+"Fields"];a=s+"?"+l+"&callback=s_c_il%5B"+m._in+"%5D._set"+(n?"MarketingCloud":"Analytics")+"Fields",o.corsUrl=s+"?"+l,o.callback=c}return o.url=a,m._getRemoteField(n?y:M,a,e,t,o)}return""},m.getAudienceManagerLocationHint=function(e,t){if(m.getMarketingCloudVisitorID(function(t){m.getAudienceManagerLocationHint(e,!0)})){var n=m._getField(M);if(!n&&N.isTrackingServerPopulated()&&(n=m.getAnalyticsVisitorID(function(t){m.getAudienceManagerLocationHint(e,!0)})),n||!N.isTrackingServerPopulated()){var i=m._getAudienceManagerURLData(),r=i.url;return m._getRemoteField("MCAAMLH",r,e,t,i)}}return""},m.getLocationHint=m.getAudienceManagerLocationHint,m.getAudienceManagerBlob=function(e,t){if(m.getMarketingCloudVisitorID(function(t){m.getAudienceManagerBlob(e,!0)})){var n=m._getField(M);if(!n&&N.isTrackingServerPopulated()&&(n=m.getAnalyticsVisitorID(function(t){m.getAudienceManagerBlob(e,!0)})),n||!N.isTrackingServerPopulated()){var i=m._getAudienceManagerURLData(),r=i.url;return m._customerIDsHashChanged&&m._setFieldExpire(T,-1),m._getRemoteField(T,r,e,t,i)}}return""},m._supplementalDataIDCurrent="",m._supplementalDataIDCurrentConsumed={},m._supplementalDataIDLast="",m._supplementalDataIDLastConsumed={},m.getSupplementalDataID=function(e,t){m._supplementalDataIDCurrent||t||(m._supplementalDataIDCurrent=m._generateID(1));var n=m._supplementalDataIDCurrent;return m._supplementalDataIDLast&&!m._supplementalDataIDLastConsumed[e]?(n=m._supplementalDataIDLast,m._supplementalDataIDLastConsumed[e]=!0):n&&(m._supplementalDataIDCurrentConsumed[e]&&(m._supplementalDataIDLast=m._supplementalDataIDCurrent,m._supplementalDataIDLastConsumed=m._supplementalDataIDCurrentConsumed,m._supplementalDataIDCurrent=n=t?"":m._generateID(1),m._supplementalDataIDCurrentConsumed={}),n&&(m._supplementalDataIDCurrentConsumed[e]=!0)),n};var F=!1;m._liberatedOptOut=null,m.getOptOut=function(e,t){var n=m._getAudienceManagerURLData("_setMarketingCloudFields"),i=n.url;if(u())return m._getRemoteField("MCOPTOUT",i,e,t,n);if(m._registerCallback("liberatedOptOut",e),null!==m._liberatedOptOut)return m._callAllCallbacks("liberatedOptOut",[m._liberatedOptOut]),F=!1,m._liberatedOptOut;if(F)return null;F=!0;var r="liberatedGetOptOut";return n.corsUrl=n.corsUrl.replace(/dpm\.demdex\.net\/id\?/,"dpm.demdex.net/optOutStatus?"),n.callback=[r],_[r]=function(e){if(e===Object(e)){var t,n,i=j.parseOptOut(e,t,P);t=i.optOut,n=1e3*i.d_ottl,m._liberatedOptOut=t,setTimeout(function(){m._liberatedOptOut=null},n)}m._callAllCallbacks("liberatedOptOut",[t]),F=!1},R.fireCORS(n),null},m.isOptedOut=function(e,t,n){t||(t=S.OptOut.GLOBAL);var i=m.getOptOut(function(n){var i=n===S.OptOut.GLOBAL||n.indexOf(t)>=0;m._callCallback(e,[i])},n);return i?i===S.OptOut.GLOBAL||i.indexOf(t)>=0:null},m._fields=null,m._fieldsExpired=null,m._hash=function(e){var t,n,i=0;if(e)for(t=0;t<e.length;t++)n=e.charCodeAt(t),i=(i<<5)-i+n,i&=i;return i},m._generateID=ne,m._generateLocalMID=function(){var e=m._generateID(0);return V.isClientSideMarketingCloudVisitorID=!0,e},m._callbackList=null,m._callCallback=function(e,t){try{"function"==typeof e?e.apply(D,t):e[1].apply(e[0],t)}catch(e){}},m._registerCallback=function(e,t){t&&(null==m._callbackList&&(m._callbackList={}),void 0==m._callbackList[e]&&(m._callbackList[e]=[]),m._callbackList[e].push(t))},m._callAllCallbacks=function(e,t){if(null!=m._callbackList){var n=m._callbackList[e];if(n)for(;n.length>0;)m._callCallback(n.shift(),t)}},m._addQuerystringParam=function(e,t,n,i){var r=encodeURIComponent(t)+"="+encodeURIComponent(n),a=N.parseHash(e),o=N.hashlessUrl(e);if(-1===o.indexOf("?"))return o+"?"+r+a;var s=o.split("?"),l=s[0]+"?",c=s[1];return l+N.addQueryParamAtLocation(c,r,i)+a},m._extractParamFromUri=function(e,t){var n=new RegExp("[\\?&#]"+t+"=([^&#]*)"),i=n.exec(e);if(i&&i.length)return decodeURIComponent(i[1])},m._parseAdobeMcFromUrl=r(re.ADOBE_MC),m._parseAdobeMcSdidFromUrl=r(re.ADOBE_MC_SDID),m._attemptToPopulateSdidFromUrl=function(e){var n=m._parseAdobeMcSdidFromUrl(e),i=1e9;n&&n.TS&&(i=N.getTimestampInSeconds()-n.TS),n&&n.SDID&&n.MCORGID===t&&i<m.sdidParamExpiry&&(m._supplementalDataIDCurrent=n.SDID,m._supplementalDataIDCurrentConsumed.SDID_URL_PARAM=!0)},m._attemptToPopulateIdsFromUrl=function(){var e=m._parseAdobeMcFromUrl();if(e&&e.TS){var n=N.getTimestampInSeconds(),i=n-e.TS;if(Math.floor(i/60)>re.ADOBE_MC_TTL_IN_MIN||e.MCORGID!==t)return;a(e)}},m._mergeServerState=function(e){if(e)try{if(e=function(e){return N.isObject(e)?e:JSON.parse(e)}(e),e[m.marketingCloudOrgID]){var t=e[m.marketingCloudOrgID];!function(e){N.isObject(e)&&m.setCustomerIDs(e)}(t.customerIDs),o(t.sdid)}}catch(e){throw new Error("`serverState` has an invalid format.")}},m._timeout=null,m._loadData=function(e,t,n,i){t=m._addQuerystringParam(t,"d_fieldgroup",e,1),i.url=m._addQuerystringParam(i.url,"d_fieldgroup",e,1),i.corsUrl=m._addQuerystringParam(i.corsUrl,"d_fieldgroup",e,1),V.fieldGroupObj[e]=!0,i===Object(i)&&i.corsUrl&&"XMLHttpRequest"===R.corsMetadata.corsType&&R.fireCORS(i,n,e)},m._clearTimeout=function(e){null!=m._timeout&&m._timeout[e]&&(clearTimeout(m._timeout[e]),m._timeout[e]=0)},m._settingsDigest=0,m._getSettingsDigest=function(){if(!m._settingsDigest){var e=m.version;m.audienceManagerServer&&(e+="|"+m.audienceManagerServer),m.audienceManagerServerSecure&&(e+="|"+m.audienceManagerServerSecure),m._settingsDigest=m._hash(e)}return m._settingsDigest},m._readVisitorDone=!1,m._readVisitor=function(){if(!m._readVisitorDone){m._readVisitorDone=!0;var e,t,n,i,r,a,o=m._getSettingsDigest(),s=!1,l=m.cookieRead(m.cookieName),c=new Date;if(l||v||m.discardTrackingServerECID||(l=m.cookieRead(re.FIRST_PARTY_SERVER_COOKIE)),null==m._fields&&(m._fields={}),l&&"T"!==l)for(l=l.split("|"),l[0].match(/^[\-0-9]+$/)&&(parseInt(l[0],10)!==o&&(s=!0),l.shift()),l.length%2==1&&l.pop(),e=0;e<l.length;e+=2)t=l[e].split("-"),n=t[0],i=l[e+1],t.length>1?(r=parseInt(t[1],10),a=t[1].indexOf("s")>0):(r=0,a=!1),s&&("MCCIDH"===n&&(i=""),r>0&&(r=c.getTime()/1e3-60)),n&&i&&(m._setField(n,i,1),r>0&&(m._fields["expire"+n]=r+(a?"s":""),(c.getTime()>=1e3*r||a&&!m.cookieRead(m.sessionCookieName))&&(m._fieldsExpired||(m._fieldsExpired={}),m._fieldsExpired[n]=!0)));!m._getField(M)&&N.isTrackingServerPopulated()&&(l=m.cookieRead("s_vi"))&&(l=l.split("|"),l.length>1&&l[0].indexOf("v1")>=0&&(i=l[1],e=i.indexOf("["),e>=0&&(i=i.substring(0,e)),i&&i.match(re.VALID_VISITOR_ID_REGEX)&&m._setField(M,i)))}},m._appendVersionTo=function(e){var t="vVersion|"+m.version,n=e?m._getCookieVersion(e):null;return n?Z.areVersionsDifferent(n,m.version)&&(e=e.replace(re.VERSION_REGEX,t)):e+=(e?"|":"")+t,e},m._writeVisitor=function(){var e,t,n=m._getSettingsDigest();for(e in m._fields)L(e)&&m._fields[e]&&"expire"!==e.substring(0,6)&&(t=m._fields[e],n+=(n?"|":"")+e+(m._fields["expire"+e]?"-"+m._fields["expire"+e]:"")+"|"+t);n=m._appendVersionTo(n),m.cookieWrite(m.cookieName,n,1)},m._getField=function(e,t){return null==m._fields||!t&&m._fieldsExpired&&m._fieldsExpired[e]?null:m._fields[e]},m._setField=function(e,t,n){null==m._fields&&(m._fields={}),m._fields[e]=t,n||m._writeVisitor()},m._getFieldList=function(e,t){var n=m._getField(e,t);return n?n.split("*"):null},m._setFieldList=function(e,t,n){m._setField(e,t?t.join("*"):"",n)},m._getFieldMap=function(e,t){var n=m._getFieldList(e,t);if(n){var i,r={};for(i=0;i<n.length;i+=2)r[n[i]]=n[i+1];return r}return null},m._setFieldMap=function(e,t,n){var i,r=null;if(t){r=[];for(i in t)L(i)&&(r.push(i),r.push(t[i]))}m._setFieldList(e,r,n)},m._setFieldExpire=function(e,t,n){var i=new Date;i.setTime(i.getTime()+1e3*t),null==m._fields&&(m._fields={}),m._fields["expire"+e]=Math.floor(i.getTime()/1e3)+(n?"s":""),t<0?(m._fieldsExpired||(m._fieldsExpired={}),m._fieldsExpired[e]=!0):m._fieldsExpired&&(m._fieldsExpired[e]=!1),n&&(m.cookieRead(m.sessionCookieName)||m.cookieWrite(m.sessionCookieName,"1"))},m._findVisitorID=function(t){return t&&("object"===e(t)&&(t=t.d_mid?t.d_mid:t.visitorID?t.visitorID:t.id?t.id:t.uuid?t.uuid:""+t),t&&"NOTARGET"===(t=t.toUpperCase())&&(t=P),t&&(t===P||t.match(re.VALID_VISITOR_ID_REGEX))||(t="")),t},m._setFields=function(t,n){if(m._clearTimeout(t),null!=m._loading&&(m._loading[t]=!1),V.fieldGroupObj[t]&&V.setState(t,!1),"MC"===t){!0!==V.isClientSideMarketingCloudVisitorID&&(V.isClientSideMarketingCloudVisitorID=!1);var i=m._getField(y);if(!i||m.overwriteCrossDomainMCIDAndAID){if(!(i="object"===e(n)&&n.mid?n.mid:m._findVisitorID(n))){if(m._use1stPartyMarketingCloudServer&&!m.tried1stPartyMarketingCloudServer)return m.tried1stPartyMarketingCloudServer=!0,void m.getAnalyticsVisitorID(null,!1,!0);i=m._generateLocalMID()}m._setField(y,i)}i&&i!==P||(i=""),"object"===e(n)&&((n.d_region||n.dcs_region||n.d_blob||n.blob)&&m._setFields(k,n),m._use1stPartyMarketingCloudServer&&n.mid&&m._setFields(O,{id:n.id})),m._callAllCallbacks(y,[i])}if(t===k&&"object"===e(n)){var r=604800;void 0!=n.id_sync_ttl&&n.id_sync_ttl&&(r=parseInt(n.id_sync_ttl,10));var a=x.getRegionAndCheckIfChanged(n,r);m._callAllCallbacks("MCAAMLH",[a]);var o=m._getField(T);(n.d_blob||n.blob)&&(o=n.d_blob,o||(o=n.blob),m._setFieldExpire(T,r),m._setField(T,o)),o||(o=""),m._callAllCallbacks(T,[o]),!n.error_msg&&m._newCustomerIDsHash&&m._setField("MCCIDH",m._newCustomerIDsHash)}if(t===O){var s=m._getField(M);s&&!m.overwriteCrossDomainMCIDAndAID||(s=m._findVisitorID(n),s?s!==P&&m._setFieldExpire(T,-1):s=P,m._setField(M,s)),s&&s!==P||(s=""),m._callAllCallbacks(M,[s])}if(m.idSyncDisableSyncs||m.disableIdSyncs)x.idCallNotProcesssed=!0;else{x.idCallNotProcesssed=!1;var l={};l.ibs=n.ibs,l.subdomain=n.subdomain,x.processIDCallData(l)}if(n===Object(n)){var c,d;u()&&m.isAllowed()&&(c=m._getField("MCOPTOUT"));var f=j.parseOptOut(n,c,P);c=f.optOut,d=f.d_ottl,m._setFieldExpire("MCOPTOUT",d,!0),m._setField("MCOPTOUT",c),m._callAllCallbacks("MCOPTOUT",[c])}},m._loading=null,m._getRemoteField=function(e,t,n,i,r){var a,o="",s=N.isFirstPartyAnalyticsVisitorIDCall(e),l={MCAAMLH:!0,MCAAMB:!0};if(u()&&m.isAllowed()){m._readVisitor(),o=m._getField(e,!0===l[e]);if(function(){return(!o||m._fieldsExpired&&m._fieldsExpired[e])&&(!m.disableThirdPartyCalls||s)}()){if(e===y||"MCOPTOUT"===e?a="MC":"MCAAMLH"===e||e===T?a=k:e===M&&(a=O),a)return!t||null!=m._loading&&m._loading[a]||(null==m._loading&&(m._loading={}),m._loading[a]=!0,m._loadData(a,t,function(t){if(!m._getField(e)){t&&V.setState(a,!0);var n="";e===y?n=m._generateLocalMID():a===k&&(n={error_msg:"timeout"}),m._setFields(a,n)}},r)),m._registerCallback(e,n),o||(t||m._setFields(a,{id:P}),"")}else o||(e===y?(m._registerCallback(e,n),o=m._generateLocalMID(),m.setMarketingCloudVisitorID(o)):e===M?(m._registerCallback(e,n),o="",m.setAnalyticsVisitorID(o)):(o="",i=!0))}return e!==y&&e!==M||o!==P||(o="",i=!0),n&&i&&m._callCallback(n,[o]),o},m._setMarketingCloudFields=function(e){m._readVisitor(),m._setFields("MC",e)},m._mapCustomerIDs=function(e){m.getAudienceManagerBlob(e,!0)},m._setAnalyticsFields=function(e){m._readVisitor(),m._setFields(O,e)},m._setAudienceManagerFields=function(e){m._readVisitor(),m._setFields(k,e)},m._getAudienceManagerURLData=function(e){var t=m.audienceManagerServer,n="",i=m._getField(y),r=m._getField(T,!0),a=m._getField(M),o=a&&a!==P?"&d_cid_ic=AVID%01"+encodeURIComponent(a):"";if(m.loadSSL&&m.audienceManagerServerSecure&&(t=m.audienceManagerServerSecure),t){var s,l,c=m.getCustomerIDs();if(c)for(s in c)L(s)&&(l=c[s],o+="&d_cid_ic="+encodeURIComponent(s)+"%01"+encodeURIComponent(l.id?l.id:"")+(l.authState?"%01"+l.authState:""));e||(e="_setAudienceManagerFields");var u="http"+(m.loadSSL?"s":"")+"://"+t+"/id",d="d_visid_ver="+m.version+(C&&-1!==u.indexOf("demdex.net")?"&gdpr=1&gdpr_force=1&gdpr_consent="+C:"")+"&d_rtbd=json&d_ver=2"+(!i&&m._use1stPartyMarketingCloudServer?"&d_verify=1":"")+"&d_orgid="+encodeURIComponent(m.marketingCloudOrgID)+"&d_nsid="+(m.idSyncContainerID||0)+(i?"&d_mid="+encodeURIComponent(i):"")+(m.idSyncDisable3rdPartySyncing||m.disableThirdPartyCookies?"&d_coppa=true":"")+(!0===A?"&d_coop_safe=1":!1===A?"&d_coop_unsafe=1":"")+(r?"&d_blob="+encodeURIComponent(r):"")+o,f=["s_c_il",m._in,e];return n=u+"?"+d+"&d_cb=s_c_il%5B"+m._in+"%5D."+e,{url:n,corsUrl:u+"?"+d,callback:f}}return{url:n}},m.appendVisitorIDsTo=function(e){try{var t=[[y,m._getField(y)],[M,m._getField(M)],["MCORGID",m.marketingCloudOrgID]];return m._addQuerystringParam(e,re.ADOBE_MC,s(t))}catch(t){return e}},m.appendSupplementalDataIDTo=function(e,t){if(!(t=t||m.getSupplementalDataID(N.generateRandomString(),!0)))return e;try{var n=s([["SDID",t],["MCORGID",m.marketingCloudOrgID]]);return m._addQuerystringParam(e,re.ADOBE_MC_SDID,n)}catch(t){return e}};var N={parseHash:function(e){var t=e.indexOf("#");return t>0?e.substr(t):""},hashlessUrl:function(e){var t=e.indexOf("#");return t>0?e.substr(0,t):e},addQueryParamAtLocation:function(e,t,n){var i=e.split("&");return n=null!=n?n:i.length,i.splice(n,0,t),i.join("&")},isFirstPartyAnalyticsVisitorIDCall:function(e,t,n){if(e!==M)return!1;var i;return t||(t=m.trackingServer),n||(n=m.trackingServerSecure),!("string"!=typeof(i=m.loadSSL?n:t)||!i.length)&&(i.indexOf("2o7.net")<0&&i.indexOf("omtrdc.net")<0)},isObject:function(e){return Boolean(e&&e===Object(e))},removeCookie:function(e){Q.remove(e,{domain:m.cookieDomain})},isTrackingServerPopulated:function(){return!!m.trackingServer||!!m.trackingServerSecure},getTimestampInSeconds:function(){return Math.round((new Date).getTime()/1e3)},parsePipeDelimetedKeyValues:function(e){return e.split("|").reduce(function(e,t){var n=t.split("=");return e[n[0]]=decodeURIComponent(n[1]),e},{})},generateRandomString:function(e){e=e||5;for(var t="",n="abcdefghijklmnopqrstuvwxyz0123456789";e--;)t+=n[Math.floor(Math.random()*n.length)];return t},normalizeBoolean:function(e){return"true"===e||"false"!==e&&e},parseBoolean:function(e){return"true"===e||"false"!==e&&null},replaceMethodsWithFunction:function(e,t){for(var n in e)e.hasOwnProperty(n)&&"function"==typeof e[n]&&(e[n]=t);return e}};m._helpers=N;var x=ae(m,S);m._destinationPublishing=x,m.timeoutMetricsLog=[];var V={isClientSideMarketingCloudVisitorID:null,MCIDCallTimedOut:null,AnalyticsIDCallTimedOut:null,AAMIDCallTimedOut:null,fieldGroupObj:{},setState:function(e,t){switch(e){case"MC":!1===t?!0!==this.MCIDCallTimedOut&&(this.MCIDCallTimedOut=!1):this.MCIDCallTimedOut=t;break;case O:!1===t?!0!==this.AnalyticsIDCallTimedOut&&(this.AnalyticsIDCallTimedOut=!1):this.AnalyticsIDCallTimedOut=t;break;case k:!1===t?!0!==this.AAMIDCallTimedOut&&(this.AAMIDCallTimedOut=!1):this.AAMIDCallTimedOut=t}}};m.isClientSideMarketingCloudVisitorID=function(){return V.isClientSideMarketingCloudVisitorID},m.MCIDCallTimedOut=function(){return V.MCIDCallTimedOut},m.AnalyticsIDCallTimedOut=function(){return V.AnalyticsIDCallTimedOut},m.AAMIDCallTimedOut=function(){return V.AAMIDCallTimedOut},m.idSyncGetOnPageSyncInfo=function(){return m._readVisitor(),m._getField("MCSYNCSOP")},m.idSyncByURL=function(e){if(!m.isOptedOut()){var t=l(e||{});if(t.error)return t.error;var n,i,r=e.url,a=encodeURIComponent,o=x;return r=r.replace(/^https:/,"").replace(/^http:/,""),n=j.encodeAndBuildRequest(["",e.dpid,e.dpuuid||""],","),i=["ibs",a(e.dpid),"img",a(r),t.ttl,"",n],o.addMessage(i.join("|")),o.requestToProcess(),"Successfully queued"}},m.idSyncByDataSource=function(e){if(!m.isOptedOut())return e===Object(e)&&"string"==typeof e.dpuuid&&e.dpuuid.length?(e.url="//dpm.demdex.net/ibs:dpid="+e.dpid+"&dpuuid="+e.dpuuid,m.idSyncByURL(e)):"Error: config or config.dpuuid is empty"},Ue(m,x),m._getCookieVersion=function(e){e=e||m.cookieRead(m.cookieName);var t=re.VERSION_REGEX.exec(e);return t&&t.length>1?t[1]:null},m._resetAmcvCookie=function(e){var t=m._getCookieVersion();t&&!Z.isLessThan(t,e)||N.removeCookie(m.cookieName)},m.setAsCoopSafe=function(){A=!0},m.setAsCoopUnsafe=function(){A=!1},function(){if(m.configs=Object.create(null),N.isObject(n))for(var e in n)L(e)&&(m[e]=n[e],m.configs[e]=n[e])}(),d();var U;m.init=function(){c()&&(h.optIn.fetchPermissions(p,!0),!h.optIn.isApproved(h.optIn.Categories.ECID))||U||(U=!0,function(){if(N.isObject(n)){m.idSyncContainerID=m.idSyncContainerID||0,A="boolean"==typeof m.isCoopSafe?m.isCoopSafe:N.parseBoolean(m.isCoopSafe),m.resetBeforeVersion&&m._resetAmcvCookie(m.resetBeforeVersion),m._attemptToPopulateIdsFromUrl(),m._attemptToPopulateSdidFromUrl(),m._readVisitor();var e=m._getField(b),t=Math.ceil((new Date).getTime()/re.MILLIS_PER_DAY);m.idSyncDisableSyncs||m.disableIdSyncs||!x.canMakeSyncIDCall(e,t)||(m._setFieldExpire(T,-1),m._setField(b,t)),m.getMarketingCloudVisitorID(),m.getAudienceManagerLocationHint(),m.getAudienceManagerBlob(),m._mergeServerState(m.serverState)}else m._attemptToPopulateIdsFromUrl(),m._attemptToPopulateSdidFromUrl()}(),function(){if(!m.idSyncDisableSyncs&&!m.disableIdSyncs){x.checkDPIframeSrc();var e=function(){var e=x;e.readyToAttachIframe()&&e.attachIframe()};D.addEventListener("load",function(){S.windowLoaded=!0,e()});try{te.receiveMessage(function(e){x.receiveMessage(e.data)},x.iframeHost)}catch(e){}}}(),function(){m.whitelistIframeDomains&&re.POST_MESSAGE_ENABLED&&(m.whitelistIframeDomains=m.whitelistIframeDomains instanceof Array?m.whitelistIframeDomains:[m.whitelistIframeDomains],m.whitelistIframeDomains.forEach(function(e){var n=new B(t,e),i=K(m,n);te.receiveMessage(i,e)}))}())}};qe.config=se,_.Visitor=qe;var Xe=qe,We=function(e){if(j.isObject(e))return Object.keys(e).filter(function(t){return""!==e[t]}).reduce(function(t,n){var i=se.normalizeConfig(e[n]),r=j.normalizeBoolean(i);return t[n]=r,t},Object.create(null))},Je=Ve.OptIn,Ke=Ve.IabPlugin;return Xe.getInstance=function(e,t){if(!e)throw new Error("Visitor requires Adobe Marketing Cloud Org ID.");e.indexOf("@")<0&&(e+="@AdobeOrg");var n=function(){var t=_.s_c_il;if(t)for(var n=0;n<t.length;n++){var i=t[n];if(i&&"Visitor"===i._c&&i.marketingCloudOrgID===e)return i}}();if(n)return n;var i=We(t);!function(e){_.adobe.optIn=_.adobe.optIn||function(){var t=j.pluck(e,["doesOptInApply","previousPermissions","preOptInApprovals","isOptInStorageEnabled","optInStorageExpiry","isIabContext"]),n=e.optInCookieDomain||e.cookieDomain;n=n||$(),n=n===window.location.hostname?"":n,t.optInCookieDomain=n;var i=new Je(t,{cookies:Q});if(t.isIabContext&&t.doesOptInApply){var r=new Ke(window.__cmp);i.registerPlugin(r)}return i}()}(i||{});var r=e,a=r.split("").reverse().join(""),o=new Xe(e,null,a);j.isObject(i)&&i.cookieDomain&&(o.cookieDomain=i.cookieDomain),function(){_.s_c_il.splice(--_.s_c_in,1)}();var s=j.getIeVersion();if("number"==typeof s&&s<10)return o._helpers.replaceMethodsWithFunction(o,function(){});var l=function(){try{return _.self!==_.parent}catch(e){return!0}}()&&!function(e){return e.cookieWrite("TEST_AMCV_COOKIE","T",1),"T"===e.cookieRead("TEST_AMCV_COOKIE")&&(e._helpers.removeCookie("TEST_AMCV_COOKIE"),!0)}(o)&&_.parent?new Y(e,i,o,_.parent):new Xe(e,i,a);return o=null,l.init(),l},function(){function e(){Xe.windowLoaded=!0}_.addEventListener?_.addEventListener("load",e):_.attachEvent&&_.attachEvent("onload",e),Xe.codeLoadEnd=(new Date).getTime()}(),Xe}();// Dynamic Tag Management Library
// Property: DTM - 2.0
// All code and conventions are protected by copyright
// Adobe Systems Incorporated
(function(window, document, undefined) {
// Satellite
// =========
//
// Satellite *core*. Yeah, you want it.
//
// In this first section, we have a some useful utility functions.
var ToString = Object.prototype.toString
var Overrides = window._satellite && window._satellite.override
function assert(cond, msg){
if (!cond){
throw new Error(msg || "Assertion Failure")
}
}
var SL = {
initialized: false,
// `$data(elm, prop, [val])`
// ----------------------------
//
// Our own `$data()` method, [a la jQuery](http://api.jquery.com/jQuery.data/)
// , used to get or set
// properties on DOM elements without going insane.
// `uuid` and `dataCache` are used by `$data()`
//
// Parameters:
//
// - `elm` - the element to get or set a property to
// - `prop` - the property name
// - `val` - the value of the property, if omitted, the method will
// return the existing value of the property, if any
$data: function(elm, prop, val){
if (!elm) return;
var __satellite__ = '__satellite__'
var cache = SL.dataCache
var uuid = elm[__satellite__]
if (!uuid) uuid = elm[__satellite__] = SL.uuid++
var datas = cache[uuid]
if (!datas) datas = cache[uuid] = {}
if (val === undefined)
return datas[prop]
else
datas[prop] = val
},
uuid: 1,
dataCache: {},
// `keys(object)`
// --------------
//
// Return all keys of an object in an array.
keys: function(obj){
var ret = []
for (var key in obj)
if (obj.hasOwnProperty(key))
ret.push(key)
return ret
},
// `values(object)`
// ----------------
//
// Return all values of an object in an array.
values: function(obj){
var ret = []
for (var key in obj)
if (obj.hasOwnProperty(key))
ret.push(obj[key])
return ret
},
// `isArray(thing)`
// --------------
//
// Returns whether the given thing is an array.
isArray: Array.isArray || function(thing){
return ToString.apply(thing) === "[object Array]"
},
// `isObject(thing)`
// -----------------
//
// Returns whether the given thing is a plain object.
isObject: function(thing){
return thing != null && !SL.isArray(thing) &&
typeof thing === 'object'
},
// `isString(thing)`
// -----------------
//
// Returns whether thing is a string
isString: function(thing){
return typeof thing === 'string'
},
// `isNumber(thing)`
// -----------------
//
// Returns whether thing is a number
isNumber: function(thing){
return ToString.apply(thing) === '[object Number]' && !SL.isNaN(thing)
},
// `isNaN(thing)`
// --------------
//
// Return whether thing is NaN
isNaN: function(thing){
return thing !== thing
},
// `isRegex(thing)`
// ----------------
//
// Returns whether thing is a RegExp object
isRegex: function(thing){
return thing instanceof RegExp
},
// `isLinkTag(thing)`
// ----------------
//
// Returns whether thing is a DOM link element
isLinkTag: function(thing){
return !!(thing && thing.nodeName &&
thing.nodeName.toLowerCase() === 'a')
},
// `each(arr, func, [context])`
// ------------------
//
// A handy method for array iteration wo having to write a for-loop.
//
// Parameters:
//
// - `arr` - an array
// - `func(item, index, arr)` - a function which accepts each item in the array
// once. I takes these arguments
// * `item` - an item
// * `index` - the array index of said item
// * `arr` - the array
// - `context` - the context to be bound to `func` when it is invoked
each: function(arr, func, context){
for (var i = 0, len = arr.length; i < len; i++)
func.call(context, arr[i], i, arr)
},
// `map(arr, func)`
// ----------------
//
// A handy method for mapping an array to another array using a 1-to-1 mapping
// for each element
//
// Parameters:
//
// Parameters are the same as `SL.each`, except that `func` is expected to return
// a the value you want in the corresponding index of the returned array.
map: function(arr, func, context){
var ret = []
for (var i = 0, len = arr.length; i < len; i++)
ret.push(func.call(context, arr[i], i, arr))
return ret
},
// `filter(arr, cond)`
// -------------------
//
// Handy method for take an array and filtering down to a subset of the elements.
//
// Parameters:
//
// Parameters are the same as `SL.each` except the second argument is `cond`
// instead of `func` and it is expected to return a truthy value respresenting
// whether to include this item in the return array or not.
filter: function(arr, cond, context){
var ret = []
for (var i = 0, len = arr.length; i < len; i++){
var item = arr[i]
if (cond.call(context, item, i, arr))
ret.push(item)
}
return ret
},
// `any(arr, cond, context)`
// -------------------------
//
// Another array helper function. Returns true if `cond(item)` returns true
// for any item in the array.
any: function(arr, cond, context){
for (var i = 0, len = arr.length; i < len; i++){
var item = arr[i]
if (cond.call(context, item, i, arr))
return true
}
return false
},
// `every(arr, cond, context)`
// ---------------------------
//
// Another array helper function. Returns true if `cond(item)` returns true
// for every item in the array.
every: function(arr, cond, context){
var retval = true
for (var i = 0, len = arr.length; i < len; i++){
var item = arr[i]
retval = retval && cond.call(context, item, i, arr)
}
return retval
},
// `contains(arr, obj)`
// -----------------------
//
// Tells you whether an array contains an object.
//
// Parameters:
//
// - `arr` - said array
// - `obj` - said object
contains: function(arr, obj){
return SL.indexOf(arr, obj) !== -1
},
// `indexOf(arr, obj)`
// -------------------
//
// Return the index of an object within an array.
//
// Parameters;
//
// - `arr` - said array
// - `obj` - said object
indexOf: function(arr, obj){
if (arr.indexOf)
return arr.indexOf(obj)
for (var i = arr.length; i--;)
if (obj === arr[i])
return i
return -1
},
// `find(arr, obj)`
// -------------------
//
// Return the index of an object within an array.
//
// Parameters;
//
// - `arr` - said array
// - `obj` - said object
find: function(arr, cond, context){
var ret = []
if (!arr) return null
for (var i = 0, len = arr.length; i < len; i++){
var item = arr[i]
if (cond.call(context, item, i, arr))
return item
}
return null
},
// `textMatch(str, str_or_regex)`
// ------------------------------
//
// Perform a string match based on another string or a regex.
//
// Parameters:
//
// `str` - the input string to be matched
// `str_or_regex` - the pattern to match against, if this is a string, it requires exact match, if
// it's a regex, then it will do regex match
textMatch: function(str, pattern){
if (pattern == null) throw new Error('Illegal Argument: Pattern is not present')
if (str == null) return false
if (typeof pattern === 'string') return str === pattern
else if (pattern instanceof RegExp) return pattern.test(str)
else return false
},
// `stringify(obj, [seenValues])`
// ------------------------------
//
// Stringify any type of object.
//
// Parameters:
//
// `obj` - the object that needs to be stringified
// `seenValues` - pool of parsed resources; used to avoid circular references;
stringify: function(obj, seenValues){
seenValues = seenValues || [];
if (SL.isObject(obj)) {
if (SL.contains(seenValues, obj)) {
return '<Cycle>';
} else {
seenValues.push(obj);
}
}
if (SL.isArray(obj)) {
return '[' + SL.map(obj, function(value){
return SL.stringify(value, seenValues)
}).join(',') + ']';
} else if (SL.isString(obj)) {
return '"' + String(obj) + '"';
} if (SL.isObject(obj)) {
var data = [];
for (var prop in obj) {
if (obj.hasOwnProperty(prop))
data.push(prop + ': ' + SL.stringify(obj[prop], seenValues));
}
return '{' + data.join(', ') + '}';
} else {
return String(obj);
}
},
// `trim(str)`
// -----------
//
// Trims a string.
//
// Parameters:
//
// `str` - the input string to be trimmed.
trim: function(str){
if (str == null) return null
if (str.trim){
return str.trim()
}else{
return str.replace(/^ */, '').replace(/ *$/, '')
}
},
// `bind(func, context)`
// ---------------------
//
// Binds a context permanently to a context. The returned function is a new function
// which - when called - will call the passed in function with `context` bound to it.
//
// Parameters:
//
// `func` - a function
// `context` - an object to be bound as the context of this function
bind: function(func, context) {
return function() {
return func.apply(context, arguments)
}
},
// `throttle(fn, delay)`
// ---------------------
//
// *Throttles* a function `fn` to be called no more than once during the interval
// specified by `delay`.
//
// Parameters:
//
// - `fn` - a function
// - `delay` - delay in milliseconds
//
// *Throttle function stolen from
// <http://remysharp.com/2010/07/21/throttling-function-calls/>*
throttle: function(fn, delay) {
var timer = null;
return function () {
var context = this, args = arguments;
clearTimeout(timer);
timer = setTimeout(function () {
fn.apply(context, args);
}, delay);
};
},
// `domReady(callback)`
// --------------------
//
// Registers a callback to be called when the DOM is fully parsed and loaded.
//
// Parameters:
//
// - `callback` - a function to be called at `domready`
//
// *domReady is borrowed from <https://github.com/ded/domready>*
domReady: (function (ready) {
var fns = [], fn, f = false
, doc = document
, testEl = doc.documentElement
, hack = testEl.doScroll
, domContentLoaded = 'DOMContentLoaded'
, addEventListener = 'addEventListener'
, onreadystatechange = 'onreadystatechange'
, loaded = /^loade|^c/.test(doc.readyState)
function flush(f) {
loaded = 1
while (f = fns.shift()) f()
}
doc[addEventListener] && doc[addEventListener](domContentLoaded, fn = function () {
doc.removeEventListener(domContentLoaded, fn, f)
flush()
}, f)
hack && doc.attachEvent(onreadystatechange, (fn = function () {
if (/^c/.test(doc.readyState)) {
doc.detachEvent(onreadystatechange, fn)
flush()
}
}))
return (ready = hack ?
function (fn) {
self != top ?
loaded ? fn() : fns.push(fn) :
function () {
try {
testEl.doScroll('left')
} catch (e) {
return setTimeout(function() { ready(fn) }, 50)
}
fn()
}()
} :
function (fn) {
loaded ? fn() : fns.push(fn)
})
}()),
// `loadScript(url, [callback])`
// -----------------------------
//
// Load an external script.
//
// Parameters:
//
// - `url` - the URL of the script
// - `callback`(optional) - the function to be called after the script has loaded.
loadScript: function(url, callback){
var script = document.createElement('script')
SL.scriptOnLoad(url, script, callback)
script.src = url
document.getElementsByTagName('head')[0]
.appendChild(script)
},
scriptOnLoad: function(url, script, callback){
function cb(err){
if (err) SL.logError(err)
if (callback) callback(err)
}
if ('onload' in script){
script.onload = function(){
cb()
}
script.onerror = function(){
cb(new Error('Failed to load script ' + url))
}
}else if ('readyState' in script){
script.onreadystatechange = function(){
var rs = script.readyState
if (rs === 'loaded' || rs === 'complete'){
script.onreadystatechange = null
cb()
}
}
}
},
// `loadScriptOnce(url, [callback])`
// -----------------------------
//
// Load an external script only if it hasn't been loaded until now.
//
// Parameters:
//
// - `url` - the URL of the script
// - `callback`(optional) - the function to be called after the script has loaded.
loadScriptOnce: function(url, callback){
if (SL.loadedScriptRegistry[url]) return
SL.loadScript(url, function(err) {
if (!err) {
SL.loadedScriptRegistry[url] = true
}
if (callback) callback(err)
})
},
loadedScriptRegistry: {},
// `loadScriptSync(url)`
// -----------------------------
//
// Load an external script using document.write.
//
// Parameters:
//
// - `url` - the URL of the script
loadScriptSync: function(url){
if (!document.write) {
SL.notify('Cannot load sync the "' + url + '" script because "document.write" is not available', 1)
return
}
if (SL.domReadyFired){
SL.notify('Cannot load sync the "' + url + '" script after DOM Ready.', 1)
return
}
// If the url contains a double quote, it could be someone trying to switch out of the
// attribute to introduce an XSS hack. On the other hand, it could just be that the URL
// was never escaped. We'll escape it to prevent the former while supporting the latter.
if (url.indexOf('"') > -1) {
url = encodeURI(url);
}
document.write('<script src="' + url + '"></scr' + 'ipt>');
},
// `pushAsyncScript(callback)`
// -------------------
//
// Called by an async custom user script.
pushAsyncScript: function(cb){
SL.tools['default'].pushAsyncScript(cb)
},
// `pushBlockingScript(callback)`
// ------------------------------
//
// Called by a blocking custom user script.
pushBlockingScript: function(cb){
SL.tools['default'].pushBlockingScript(cb)
},
// `addEventHandler(elm, evt, callback)`
// -------------------------------------
//
// Register an event handler for a element
//
// Parameters:
//
// - `elm` - the element in question
// - `evt` - the event type to listen to
// - `callback` - callback function
addEventHandler: window.addEventListener ?
function(node, evt, cb){ node.addEventListener(evt, cb, false) } :
function(node, evt, cb){ node.attachEvent('on' + evt, cb) },
removeEventHandler: window.removeEventListener ?
function(node, evt, cb){ node.removeEventListener(evt, cb, false) } :
function(node, evt, cb){ node.detachEvent('on' + evt, cb) },
// `preventDefault(evt)`
// ---------------------
//
// Prevent the default browser behavior for this event
//
// Parameters:
//
// `evt` - the event triggered
preventDefault: window.addEventListener ?
function(e){ e.preventDefault() } :
function(e){ e.returnValue = false },
// `stopPropagation(evt)`
// ----------------------
//
// Cross-browser `stopPropagation`
//
// Parameters:
//
// `evt` - the event triggered
stopPropagation: function(e){
e.cancelBubble = true
if (e.stopPropagation) e.stopPropagation()
},
// `containsElement(container, elm)`
// ----------------------
//
// Given DOM elements `container` and `elm`, returns whether `container` contains `elm`.
//
// Parameters:
//
// `elm1` - the possible parent
// `elm2` - the possible child
containsElement: function(container, elm) {
return container.contains ? container.contains(elm) :
!!(container.compareDocumentPosition(elm) & 16);
},
// `matchesCss(css, elm)`
// ----------------------
//
// Returns whether a DOM element matches a given css selector
//
// Parameters:
//
// - `css` - the CSS selector
// - `elm` - the element
matchesCss: (function(docEl){
function simpleTagMatch(selector, elm){
var tagName = elm.tagName
if (!tagName) return false
return selector.toLowerCase() === tagName.toLowerCase()
}
var matches =
docEl.matchesSelector ||
docEl.mozMatchesSelector ||
docEl.webkitMatchesSelector ||
docEl.oMatchesSelector ||
docEl.msMatchesSelector
if (matches) {
return function(selector, elm){
if (elm === document || elm === window) return false
try{
return matches.call(elm, selector)
}catch(e){
return false
}
}
} else if(docEl.querySelectorAll) {
return function(selector, elm) {
var parent = elm.parentNode
if (!parent) return false
if (selector.match(/^[a-z]+$/i)){
return simpleTagMatch(selector, elm)
}
try{
var nodeList = elm.parentNode.querySelectorAll(selector)
for (var i = nodeList.length; i--;)
if (nodeList[i] === elm) return true
}catch(e){
//
}
return false
}
}else{
return function(selector, elm){
if (selector.match(/^[a-z]+$/i)){
return simpleTagMatch(selector, elm)
}
try{
return SL.Sizzle.matches(selector, [elm]).length > 0
}catch(e){
return false
}
}
}
}(document.documentElement)),
// `cssQuery(css)`
// ---------------
//
// Return a list of element matching the given css selector
//
// Parameters:
//
// - `css` - the CSS selector
cssQuery: (function(doc){
if (doc.querySelectorAll) {
return function(css, cb){
var results
try{
results = doc.querySelectorAll(css)
}catch(e){
results = []
}
cb(results)
}
}else{
return function(css, cb){
if (SL.Sizzle){
var results
try{
results = SL.Sizzle(css)
}catch(e){
results = []
}
cb(results)
}else
SL.sizzleQueue.push([css, cb])
}
}
})(document),
// `hasAttr(elem, attrName)`
// ---------------
//
// Check if attribute is defined on element
//
// Parameters:
//
// - `elem` - the DOM element
// - `attrName` - attribute name
hasAttr: function(elem, attrName) {
return elem.hasAttribute ? elem.hasAttribute(attrName) : elem[attrName] !== undefined;
},
// `inherit(subClass, superClass)`
// -------------------------------
//
// Make `subClass` inherit `superClass`.
//
// Parameters:
//
// - `subClass` - a Javascript function representing a constructor - the inheritor
// - `superClass` - another constructor - the one to inherit from
inherit: function(subClass, superClass){
var f = function() {}
f.prototype = superClass.prototype
subClass.prototype = new f()
subClass.prototype.constructor = subClass
},
// `extend(dst, src)`
// ----------------
//
// Extend an object with the properties of another.
//
// Parameters:
//
// - `dst` - object to copy to
// - `src` - object to copy from
extend: function(dst, src){
for (var prop in src)
if (src.hasOwnProperty(prop))
dst[prop] = src[prop]
},
// `toArray(arrayLike)`
// --------------------
//
// Converts an array-like object to an array.
//
// Parameters:
//
// - `arrayLike` - an array-like object, meaning it has a length property
// which is a number
toArray: (function(){
try {
var slice = Array.prototype.slice
slice.call( document.documentElement.childNodes, 0 )[0].nodeType;
return function(thing){
return slice.call(thing, 0)
}
// Provide a fallback method if it does not work
} catch( e ) {
return function(thing){
var ret = []
for (var i = 0, len = thing.length; i < len; i++)
ret.push(thing[i])
return ret
}
}
})(),
// `equalsIgnoreCase(str1, str2)`
// ------------------------------
//
// Returns true iff str1 and str2 are equal ignoring case.
//
// Parameters:
//
// * `str1` - the first string
// * `str2` - the second string
equalsIgnoreCase: function(str1, str2){
if (str1 == null) return str2 == null
if (str2 == null) return false
return String(str1).toLowerCase() === String(str2).toLowerCase()
},
// `poll(fn, [freq], [max_retries])`
// ------------------
//
// Runs `fn` for every `freq` ms. `freq` defaults to 1000. If any
// invocation of `fn()` returns true, polling will stop.
// The polling will stop if the number or retries exceeds the
// provided `max_retries`.
//
// Parameters:
//
// * `fn` - function to be called repeatedly
// * `freq` - frequency to call the function
// * `max_retries` - number of times to retry
poll: function(fn, freq, max_retries){
var retries = 0
freq = freq || 1000
check()
function check(){
if (SL.isNumber(max_retries) && retries++ >= max_retries) {
return;
}
if (!fn()){
setTimeout(check, freq)
}
}
},
// ``Html(str)`
// --------------------
//
// Escapes a string for being used in an HTML context. Returns
// the escaped version of the string. Replaces the characters
// `&` `<` `>` `"` `'` and `/`.
//
// Parameters:
//
// * `str` - the string to be escaped
escapeForHtml: function(str){
if (!str) return str
return String(str)
.replace(/\&/g, '&amp;')
.replace(/\</g, '&lt;')
.replace(/\>/g, '&gt;')
.replace(/\"/g, '&quot;')
.replace(/\'/g, '&#x27;')
.replace(/\//g, '&#x2F;')
}
}
// The available tools to use.
SL.availableTools = {}
// The avaliable event emitters to use.
SL.availableEventEmitters = []
// The names of the events which can only fire once.
SL.fireOnceEvents = ['condition', 'elementexists']
// Initialize all event emitters.
SL.initEventEmitters = function(){
SL.eventEmitters = SL.map(SL.availableEventEmitters, function(ee){
return new ee()
})
}
// Call `registerElements` on all event emitters.
SL.eventEmitterBackgroundTasks = function(){
SL.each(SL.eventEmitters, function(ee){
if ('backgroundTasks' in ee)
ee.backgroundTasks()
})
}
// Initialize all tools.
SL.initTools = function(toolSpecs){
var tools = { 'default': new DefaultTool() }
var euCookieName = SL.settings.euCookieName || 'sat_track'
for (var id in toolSpecs){
if(toolSpecs.hasOwnProperty(id)) {
var toolSpec, ctr, tool
toolSpec = toolSpecs[id]
if (toolSpec.euCookie){
var cookieSet = SL.readCookie(euCookieName) !== 'true'
if (cookieSet) continue
}
ctr = SL.availableTools[toolSpec.engine]
if (!ctr){
var available = []
for (var key in SL.availableTools){
if (SL.availableTools.hasOwnProperty(key)) {
available.push(key)
}
}
throw new Error('No tool engine named ' + toolSpec.engine +
', available: ' + available.join(',') + '.')
}
tool = new ctr(toolSpec)
tool.id = id
tools[id] = tool
}
}
return tools
}
// Pre-process arguments (variable substitutions and lower-casing) before
// feeding them to the tools.
SL.preprocessArguments = function(args, elm, evt, forceLowerCase, escapeHtml){
if (!args) return args
return preprocessArray(args, forceLowerCase)
function forceLowerCaseIfNeeded(value) {
return forceLowerCase && SL.isString(value) ? value.toLowerCase() : value
}
function preprocessObject(obj){
var ret = {}
for (var key in obj){
if (obj.hasOwnProperty(key)){
var value = obj[key]
if (SL.isObject(value)){
ret[key] = preprocessObject(value)
}else if (SL.isArray(value)){
ret[key] = preprocessArray(value, forceLowerCase)
}else{
ret[key] = forceLowerCaseIfNeeded(SL.replace(value, elm, evt, escapeHtml))
}
}
}
return ret
}
function preprocessArray(args, forceLowerCase){
var ret = []
for (var i = 0, len = args.length; i < len; i++){
var value = args[i]
if (SL.isString(value)){
value = forceLowerCaseIfNeeded(SL.replace(value, elm, evt))
}else if (value && value.constructor === Object){
value = preprocessObject(value)
}
ret.push(value)
}
return ret
}
}
// Execute a command.
SL.execute = function(trig, elm, evt, tools){
if (_satellite.settings.hideActivity) return
tools = tools || SL.tools
function doit(toolName){
var tool = tools[toolName || 'default']
if (!tool)
return
try{
tool.triggerCommand(trig, elm, evt)
}catch(e){
SL.logError(e)
}
}
if (trig.engine){
var engine = trig.engine
for (var toolName in tools){
if (tools.hasOwnProperty(toolName)) {
var tool = tools[toolName]
if (tool.settings && tool.settings.engine === engine)
doit(toolName)
}
}
}else if (trig.tool instanceof Array)
SL.each(trig.tool, function(toolName){
doit(toolName)
})
else
doit(trig.tool)
}
// Wrapper object that handles Satellite internal logging.
//
// It saves all messages for future reference (up to `keepLimit`, default 100) and
// outputs to browser's console if `_satellite.settings.notifications` is `true`.
// -----------------------------------------------------
SL.Logger = {
outputEnabled: false,
messages: [],
keepLimit: 100,
flushed: false,
// @fixme: remove first 2 items when legacy code is updated
LEVELS: [null, null, 'log', 'info', 'warn', 'error'],
// `lvl` should be the index of a level defined in `LEVELS`
message: function(msg, lvl) {
var level = this.LEVELS[lvl] || 'log';
this.messages.push([level, msg]);
if (this.messages.length > this.keepLimit) {
this.messages.shift();
}
if (this.outputEnabled) {
this.echo(level, msg)
}
},
getHistory: function() {
return this.messages;
},
clearHistory: function() {
this.messages = [];
},
setOutputState: function(state) {
if (this.outputEnabled == state) return;
this.outputEnabled = state;
if (state) {
this.flush();
} else {
this.flushed = false;
}
},
// Private
// ----------------------------------------
echo: function(func, msg) {
if (!window.console) return;
window.console[func]("SATELLITE: " + msg);
},
flush: function() {
if (this.flushed) return;
SL.each(this.messages, function(item) {
if (item[2] === true) return; // message already flushed
this.echo(item[0], item[1]);
item[2] = true;
}, this);
this.flushed = true;
}
};
// `notify(msg, pty)`
// ------------------
//
// Notify the user of things happening in Satellite using `console.log`
//
// - msg - message to print
// - pty - priority
SL.notify = SL.bind(SL.Logger.message, SL.Logger);
// `cleanText(str)`
// ================
//
// "Cleans" the text from an element's innerText. This is used directly by the
// @cleanText special property.
SL.cleanText = function(str){
if (str == null) return null
return SL.trim(str).replace(/\s+/g, ' ')
}
SL.cleanText.legacy = function(str){
if (str == null) return null
return SL.trim(str).replace(/\s{2,}/g, ' ')
.replace(/[^\000-\177]*/g, '')
}
SL.text = function(obj){
return obj.textContent || obj.innerText
}
// Special Properties for DOM elements. You use special properties using
// the @ prefix. Example:
//
// this.@text
SL.specialProperties = {
text: SL.text,
cleanText: function(obj){
return SL.cleanText(SL.text(obj))
}
}
// `getObjectProperty(obj, property)`
// ============================
//
// Get property(potentially nested) from an object.
SL.getObjectProperty = function(obj, property, supportSpecial){
var propChain = property.split('.')
var currValue = obj
var special = SL.specialProperties
var attrMatch
for (var i = 0, len = propChain.length; i < len; i++){
if (currValue == null) return undefined
var prop = propChain[i]
if (supportSpecial && prop.charAt(0) === '@'){
var specialProp = prop.slice(1)
currValue = special[specialProp](currValue)
continue
}
if (currValue.getAttribute &&
(attrMatch = prop.match(/^getAttribute\((.+)\)$/))){
var attr = attrMatch[1]
currValue = currValue.getAttribute(attr)
continue
}
currValue = currValue[prop]
}
return currValue
}
// `getToolsByType(type)`
// ------------------------------------------------
//
// Returns an array containing all the tools whose engine property match
// the provided type.
//
// - `type` - The searched tool type
SL.getToolsByType = function(type){
if (!type) {
throw new Error('Tool type is missing')
}
var result = []
for (var t in SL.tools) {
if (SL.tools.hasOwnProperty(t)) {
var tool = SL.tools[t]
if (tool.settings && tool.settings.engine === type) {
result.push(tool)
}
}
}
return result
}
// `setVar(name, value)` or `setVar(mapping)`
// ==========================================
//
// Set a customer variable. Can be either called like this
//
// _satellite.setVar('name', 'value')
//
// Or by passing in a mapping(object literall) which allows setting multiple variables at
// the same time.
//
// _satellite.setVar({name: 'value', foo: 'bar'})
SL.setVar = function(){
var customVars = SL.data.customVars
if(customVars == null) SL.data.customVars = {}, customVars = SL.data.customVars
if (typeof arguments[0] === 'string'){
var prop = arguments[0]
customVars[prop] = arguments[1]
}else if (arguments[0]){ // assume an object literal
var mapping = arguments[0]
for (var key in mapping)
if (mapping.hasOwnProperty(key))
customVars[key] = mapping[key]
}
}
SL.dataElementSafe = function(key, length){
if (arguments.length > 2){
// setter
var value = arguments[2]
if (length === 'pageview'){
SL.dataElementSafe.pageviewCache[key] = value
}else if (length === 'session'){
SL.setCookie('_sdsat_' + key, value)
}else if (length === 'visitor') {
SL.setCookie('_sdsat_' + key, value, 365 * 2)
}
}else{
// getter
if (length === 'pageview'){
return SL.dataElementSafe.pageviewCache[key]
}else if (length === 'session' || length === 'visitor'){
return SL.readCookie('_sdsat_' + key)
}
}
}
SL.dataElementSafe.pageviewCache = {}
SL.realGetDataElement = function(dataDef){
var ret
if (dataDef.selector) {
if (SL.hasSelector) {
SL.cssQuery(dataDef.selector, function(elms) {
if (elms.length > 0) {
var elm = elms[0]
if (dataDef.property === 'text') {
ret = elm.innerText || elm.textContent
}else if (dataDef.property in elm){
ret = elm[dataDef.property]
}else if (SL.hasAttr(elm, dataDef.property)){
ret = elm.getAttribute(dataDef.property)
}
}
})
}
}else if (dataDef.queryParam) {
if (dataDef.ignoreCase){
ret = SL.getQueryParamCaseInsensitive(dataDef.queryParam)
}else{
ret = SL.getQueryParam(dataDef.queryParam)
}
}else if (dataDef.cookie) {
ret = SL.readCookie(dataDef.cookie)
}else if (dataDef.jsVariable) {
ret = SL.getObjectProperty(window, dataDef.jsVariable)
}else if (dataDef.customJS) {
ret = dataDef.customJS()
}else if (dataDef.contextHub) {
ret = dataDef.contextHub()
}
if (SL.isString(ret) && dataDef.cleanText){
ret = SL.cleanText(ret)
}
return ret
}
SL.getDataElement = function(variable, suppressDefault, dataDef) {
dataDef = dataDef || SL.dataElements[variable]
if (dataDef == null) {
return SL.settings.undefinedVarsReturnEmpty ? '' : null;
}
var ret = SL.realGetDataElement(dataDef)
if (ret === undefined && dataDef.storeLength) {
ret = SL.dataElementSafe(variable, dataDef.storeLength)
}else if (ret !== undefined && dataDef.storeLength) {
SL.dataElementSafe(variable, dataDef.storeLength, ret)
}
if (!ret && !suppressDefault) {
ret = dataDef['default'] || ''
}
if (SL.isString(ret) && dataDef.forceLowerCase) {
ret = ret.toLowerCase()
}
return ret
}
// getVar(variable, elm, evt)
// ==========================
//
// Return the value of a variable, where the variable
// can be a data element, defined in the "data" section
// of the initial settings, or reference properties on
// an element, event, or target of the event in question,
// a query parameter, or a random number.
//
// - `variable` - the name of the variable to get
// - `[elm]` - the associated element, if any
// - `[evt]` - the associated event, if any
SL.getVar = function(variable, elm, evt){
var custVars = SL.data.customVars
, target = evt ? (evt.target || evt.srcElement) : null
, randMatch
, value
var map = {
uri: SL.URI(),
protocol: document.location.protocol,
hostname: document.location.hostname
}
if (SL.dataElements && variable in SL.dataElements){
return SL.getDataElement(variable)
}
value = map[variable.toLowerCase()]
if (value === undefined){
if (variable.substring(0, 5) === 'this.'){
variable = variable.slice(5)
value = SL.getObjectProperty(elm, variable, true)
}else if(variable.substring(0, 6) === 'event.'){
variable = variable.slice(6)
value = SL.getObjectProperty(evt, variable)
}else if(variable.substring(0, 7) === 'target.'){
variable = variable.slice(7)
value = SL.getObjectProperty(target, variable)
}else if(variable.substring(0, 7) === 'window.'){
variable = variable.slice(7)
value = SL.getObjectProperty(window, variable)
}else if (variable.substring(0, 6) === 'param.'){
variable = variable.slice(6)
value = SL.getQueryParam(variable)
}else if(randMatch = variable.match(/^rand([0-9]+)$/)){
var len = Number(randMatch[1])
, s = (Math.random() * (Math.pow(10, len) - 1)).toFixed(0)
value = Array(len - s.length + 1).join('0') + s
}else{
value = SL.getObjectProperty(custVars, variable)
}
}
return value
}
SL.getVars = function(variables, elm, evt){
var ret = {}
SL.each(variables, function(variable){
ret[variable] = SL.getVar(variable, elm, evt)
})
return ret
}
// `replace(str, [elm], [target])`
// ---------------------
//
// Perform variable subtitutions substitute to a string where subtitions are
// specified in the form `"%foo%"`. Variables are lookup either in `SL.data.customVars`, or
// if the `elm` parameter is passed it, and the variable spec is of the form `"%this.tagName%"`, it
// is subsituted with the properties on `elm`, *i.e. `elm.tagName`.
//
// Parameters:
//
// - `str` - string to apply substitutions to
// - `elm`(optional) - object or element to use for substitutions of the form `%this.property%`
// - `target`(optional) - element to use for subsitution of the form `%target.property%`
// - `escapeHtml` (optional) - whether or not to escape substitutions for embedding in HTML
SL.replace = function(str, elm, evt, escapeHtml) {
if (typeof str !== 'string') return str
return str
.replace(/%(.*?)%/g, function(m, variable){
var val = SL.getVar(variable, elm, evt)
if (val == null) {
return SL.settings.undefinedVarsReturnEmpty ? '' : m;
} else {
if (escapeHtml) {
return SL.escapeForHtml(val);
} else {
return val;
}
}
});
}
SL.escapeHtmlParams = function(fn){
fn.escapeHtml = true
return fn
}
// From a object literal of variable, generate a query string.
SL.searchVariables = function(vars, elm, evt){
if (!vars || vars.length === 0) return ''
var qsParts = []
for (var i = 0, len = vars.length; i < len; i++){
var varr = vars[i]
, value = SL.getVar(varr, elm, evt)
qsParts.push(varr + '=' + escape(value))
}
return '?' + qsParts.join('&')
}
// Fire all the trigger actions associated with a rule.
SL.fireRule = function(rule, elm, evt){
var triggers = rule.trigger
if (!triggers) return
for (var i = 0, len = triggers.length; i < len; i++){
var trig = triggers[i]
SL.execute(trig, elm, evt)
}
if (SL.contains(SL.fireOnceEvents, rule.event))
rule.expired = true
}
// `isLinked(elm)`
// ---------------
//
// Returns whether the element is either an anchor or a descendant of an anchor or contains an anchor.
//
// `elm` - the element to test
SL.isLinked = function(elm){
for (var cur = elm; cur; cur = cur.parentNode) {
if (SL.isLinkTag(cur))
return true
}
return false
}
// Fire a page load event. `type` is one of `pagetop`, `pagebottom`, `domready` and
// `windowload`.
SL.firePageLoadEvent = function(type) {
var location = document.location
var evt = {type: type, target: location}
var rules = SL.pageLoadRules
var handlers = SL.evtHandlers[evt.type];
for (var i = rules.length; i--;){
var rule = rules[i]
if (SL.ruleMatches(rule, evt, location)){
SL.notify('Rule "' + rule.name + '" fired.', 1)
SL.fireRule(rule, location, evt)
}
}
for (var id in SL.tools){
if (SL.tools.hasOwnProperty(id)) {
var tool = SL.tools[id]
if (tool.endPLPhase) {
tool.endPLPhase(type)
}
}
}
if (handlers){
SL.each(handlers, function(cb){
cb(evt)
})
}
}
// `track(id)`
// -----------
//
// Directly fire a direct call rule by id.
SL.track = function(ruleName) {
// trim extra spaces that may exist at beginning or end of string
ruleName = ruleName.replace(/^\s*/,"").replace(/\s*$/,"")
for (var i = 0; i < SL.directCallRules.length; i++){
var rule = SL.directCallRules[i]
if (rule.name === ruleName){
SL.notify('Direct call Rule "' + ruleName + '" fired.', 1)
SL.fireRule(rule, location, {type: ruleName})
return
}
}
SL.notify('Direct call Rule "' + ruleName + '" not found.', 1)
}
// `basePath()`
// ------------
//
// Returns the base path of all Satellite generated assets.
SL.basePath = function(){
if (SL.data.host)
return (document.location.protocol === 'https:' ?
'https://' + SL.data.host.https :
'http://' + SL.data.host.http) + '/'
else
return this.settings.basePath
}
// `setLocation(url)`
// ------------------
//
// Set the current URL
//
// - `url` - the URL to set to
SL.setLocation = function(url){
window.location = url
}
SL.parseQueryParams = function(str){
var URIDecode = function (str) {
var result = str
try {
result = decodeURIComponent(str)
} catch(err) {}
return result
}
if (str === '' || SL.isString(str) === false) return {}
if (str.indexOf('?') === 0) {
str = str.substring(1)
}
var ret = {}
, pairs = str.split('&')
SL.each(pairs, function(pair){
pair = pair.split('=')
if (!pair[1]) {
return
}
ret[URIDecode(pair[0])] = URIDecode(pair[1])
})
return ret
}
SL.getCaseSensitivityQueryParamsMap = function (str) {
var normal = SL.parseQueryParams(str)
var insensitive = {}
for (var prop in normal)
if (normal.hasOwnProperty(prop))
insensitive[prop.toLowerCase()] = normal[prop]
return {
normal: normal,
caseInsensitive: insensitive
}
}
SL.updateQueryParams = function(){
SL.QueryParams = SL.getCaseSensitivityQueryParamsMap(window.location.search)
}
SL.updateQueryParams()
SL.getQueryParam = function(key){
return SL.QueryParams.normal[key]
}
SL.getQueryParamCaseInsensitive = function(key){
return SL.QueryParams.caseInsensitive[key.toLowerCase()]
}
SL.encodeObjectToURI = function(obj) {
if (SL.isObject(obj) === false) {
return ''
}
var uri = []
for (var key in obj) {
if (obj.hasOwnProperty(key)) {
uri.push(encodeURIComponent(key) + '=' + encodeURIComponent(obj[key]))
}
}
return uri.join('&')
}
SL.readCookie = function(name) {
var nameEQ = name + "="
var parts = document.cookie.split(';')
for(var i=0;i < parts.length;i++) {
var c = parts[i]
while (c.charAt(0)==' '){
c = c.substring(1,c.length)
}
if (c.indexOf(nameEQ) === 0){
return c.substring(nameEQ.length,c.length)
}
}
return undefined
}
SL.setCookie = function(name,value,days) {
var expires
if (days) {
var date = new Date()
date.setTime(date.getTime()+(days*24*60*60*1000))
expires = "; expires="+date.toGMTString()
}
else{
expires = ""
}
document.cookie = name+"="+value+expires+"; path=/"
}
SL.removeCookie = function(name) {
SL.setCookie(name,"",-1);
}
SL.getElementProperty = function(elm, prop){
if (prop.charAt(0) === '@'){
var special = SL.specialProperties[prop.substring(1)]
if (special){
return special(elm)
}
}
if (prop === 'innerText'){
return SL.text(elm)
}
if (prop in elm)
return elm[prop]
return elm.getAttribute ? elm.getAttribute(prop) : undefined
}
SL.propertiesMatch = function(property, elm){
if (property){
for (var prop in property){
if (property.hasOwnProperty(prop)) {
var target = property[prop]
var value = SL.getElementProperty(elm, prop)
if (typeof target === 'string' && target !== value) return false
if (target instanceof RegExp && !target.test(value)) return false
}
}
}
return true
}
// from http://www.quirksmode.org/js/events_properties.html
SL.isRightClick = function(e){
var ret
if (e.which){
ret = e.which == 3
}else if (e.button){
ret = e.button == 2
}
return ret
}
// `ruleMatches(rule, evt, elm, eventEntriesFound)`
// ------------------------------------------------
//
// - `rule` - the rules to match
// - `evt` - the event triggered
// - `elm` - the element the event was on
// - `eventEntriesFound` - number of rules matched so far
SL.ruleMatches = function(rule, evt, elm, eventEntriesFound){
var cnd = rule.condition
var cnds = rule.conditions
var property = rule.property
var eventType = evt.type
var matchValue = rule.value
var target = evt.target || evt.srcElement
var initialTarget = elm === target
if (rule.event !== eventType && (rule.event !== 'custom' || rule.customEvent !== eventType)) return false
if (!SL.ruleInScope(rule)) return false
// ignore all right-clicks
if (rule.event === 'click' && SL.isRightClick(evt)){
return false
}
if (rule.isDefault && eventEntriesFound > 0)
return false
if (rule.expired) return false
if (eventType === 'inview' && evt.inviewDelay !== rule.inviewDelay){
return false
}
if (!(initialTarget ||
((rule.bubbleFireIfParent !== false) && (eventEntriesFound === 0 || (rule.bubbleFireIfChildFired !== false))))) return false
if (rule.selector && !SL.matchesCss(rule.selector, elm)) return false
if (!SL.propertiesMatch(property, elm)) return false
if (matchValue != null){
if (typeof matchValue === 'string'){
if (matchValue !== elm.value)
return false
}else if (!matchValue.test(elm.value))
return false
}
if (cnd){
try{
if (!cnd.call(elm, evt, target)){
SL.notify('Condition for rule "' + rule.name + '" not met.', 1)
return false
}
}catch(e){
SL.notify('Condition for rule "' + rule.name + '" not met. Error: ' + e.message, 1)
return false
}
}
if (cnds){
var failed = SL.find(cnds, function(cnd){
try{
return !cnd.call(elm, evt, target)
}catch(e){
SL.notify('Condition for rule "' + rule.name + '" not met. Error: ' + e.message, 1)
return true
}
})
if (failed){
SL.notify('Condition ' + failed.toString() + ' for rule "' + rule.name + '" not met.', 1)
return false
}
}
return true
}
SL.evtHandlers = {}
// `bindEvent(evtName, callback)`
// ------------------------------
//
// Register for an event by name. Alias: `whenEvent`.
//
// `evtName` - the name of the event
// `callback` - the function to be called when even fires
SL.bindEvent = function(evtName, callback){
var handlers = SL.evtHandlers
if (!handlers[evtName])
handlers[evtName] = []
handlers[evtName].push(callback)
}
SL.whenEvent = SL.bindEvent
// `unbindEvent(evtName, callback)
// -------------------------------
//
// Unregister for an event by name.
//
// `evtName` - the name of the event
// `callback` - the function to unregister
SL.unbindEvent = function(evtName, callback){
var handlers = SL.evtHandlers
if (!handlers[evtName]) return
var idx = SL.indexOf(handlers[evtName], callback)
handlers[evtName].splice(idx, 1)
}
SL.bindEventOnce = function(evtName, callback){
var wrapped = function(){
SL.unbindEvent(evtName, wrapped)
callback.apply(null, arguments)
}
SL.bindEvent(evtName, wrapped)
}
// See <http://tobyho.com/2014/02/26/attribute-only-valid-on-v-image/>
SL.isVMLPoisoned = function(elm){
if (!elm) return false
try{
elm.nodeName
}catch(e){
if (e.message === 'Attribute only valid on v:image'){
return true
}
}
return false
}
SL.handleEvent = function(evt) {
// Don't process an event twice.
if (SL.$data(evt, 'eventProcessed')) return
var eventType = evt.type.toLowerCase()
, target = evt.target || evt.srcElement
, rulesMatched = 0
, rules = SL.rules
, tools = SL.tools
, handlers = SL.evtHandlers[evt.type]
if (SL.isVMLPoisoned(target)){
SL.notify('detected ' + eventType + ' on poisoned VML element, skipping.', 1)
return
}
if (handlers){
SL.each(handlers, function(cb){
cb(evt)
})
}
var nodeName = target && target.nodeName;
if (nodeName)
SL.notify("detected " + eventType + " on " + target.nodeName, 1)
else
SL.notify("detected " + eventType, 1)
for (var curr = target; curr; curr = curr.parentNode) {
var bubbleStop = false
SL.each(rules, function(rule){
if (SL.ruleMatches(rule, evt, curr, rulesMatched)){
SL.notify('Rule "' + rule.name + '" fired.', 1)
SL.fireRule(rule, curr, evt)
rulesMatched++
if (rule.bubbleStop)
bubbleStop = true
}
})
if (bubbleStop) break
}
SL.$data(evt, 'eventProcessed', true)
}
// `onEvent(evt)`
// ------------
//
// Handle an event, whether it is a DOM event or a synthetic event.
//
// - `evt` - the event triggered
SL.onEvent = document.querySelectorAll ?
function(evt){ SL.handleEvent(evt) } :
(function(){
var q = []
var onEvent = function(evt) {
if (evt.selector)
q.push(evt)
else
SL.handleEvent(evt)
}
onEvent.pendingEvents = q
return onEvent
})()
// `fireEvent(eventType, eventTarget)`
// ------------
//
// Conviniently programmatically fire an event.
//
// - `eventType` - the type of event
// - `eventTarget` - the target object that fired the event
SL.fireEvent = function(type, target){
SL.onEvent({type: type, target: target})
}
// `registerEvents(elm, events)`
// -----------------------------
//
// Register events for an element using `track` as the callback
//
// - `elm` - the element to listen for events on
// - `events` - an array of event types (strings)
SL.registerEvents = function(elm, events){
for (var i = events.length - 1; i >= 0; i--){
var event = events[i]
if (!SL.$data(elm, event + '.tracked')){
SL.addEventHandler(elm, event, SL.onEvent)
SL.$data(elm, event + '.tracked', true)
}
}
}
// `registerEventsForTags(tags, events)`
// -------------------------------------
//
// Register events for all element that have the specified tags
//
// - `tags` - an array of tags to match for (strings)
// - `events` - an array of event types (strings)
SL.registerEventsForTags = function(tags, events){
for (var i = tags.length - 1; i >= 0; i--){
var tag = tags[i]
var elms = document.getElementsByTagName(tag);
for (var j = elms.length - 1; j >= 0; j--)
SL.registerEvents(elms[j], events)
}
}
// `setListeners()`
// ----------------
//
// Set events for `document`
SL.setListeners = function() {
var events = ['click', 'submit'];
SL.each(SL.rules, function(rule) {
if (rule.event === 'custom' &&
rule.hasOwnProperty('customEvent') &&
!SL.contains(events, rule.customEvent)) {
events.push(rule.customEvent);
}
});
SL.registerEvents(document, events);
};
// `getUniqueRuleEvents()`
// -----------------------
//
// Returns an array of unique event types for which event-based rules
// have been configured.
SL.getUniqueRuleEvents = function() {
if (!SL._uniqueRuleEvents) {
SL._uniqueRuleEvents = [];
SL.each(SL.rules, function(rule) {
if (SL.indexOf(SL._uniqueRuleEvents, rule.event) === -1) {
SL._uniqueRuleEvents.push(rule.event);
}
});
}
return SL._uniqueRuleEvents;
};
// `setFormListeners()`
// --------------------
//
// Listen for events on form elements. Listeners for these events are added directly to form
// elements since they don't bubble (though some do in modern browsers).
SL.setFormListeners = function() {
if (!SL._relevantFormEvents) {
var formEvents = [
"change",
"focus",
"blur",
// Why do we add event listeners directly to form elements for the keypress event? The
// keypress event bubbles so we could add it directly to document. Note that keypress
// events can be triggered when any element has focus which means that by adding the event
// listener directly to form elements we're filtering any keypress events from other elements.
// Is this the intention? If so, we could still add a single listener directly to document
// and filter on event.target.nodeName.
"keypress"
];
SL._relevantFormEvents = SL.filter(SL.getUniqueRuleEvents(), function(event) {
return SL.indexOf(formEvents, event) !== -1;
});
}
if (SL._relevantFormEvents.length) {
SL.registerEventsForTags(['input', 'select', 'textarea', 'button'], SL._relevantFormEvents);
}
};
// `setVideoListeners()`
// ---------------------
//
// Listen for events on video elements. Listeners for these events are added directly to form
// elements since they don't bubble.
SL.setVideoListeners = function() {
if (!SL._relevantVideoEvents) {
var videoEvents = [
"play",
"pause",
"ended",
"volumechange",
"stalled",
"loadeddata"
];
SL._relevantVideoEvents = SL.filter(SL.getUniqueRuleEvents(), function(event) {
return SL.indexOf(videoEvents, event) !== -1;
});
}
if (SL._relevantVideoEvents.length) {
SL.registerEventsForTags(['video'], SL._relevantVideoEvents);
}
};
// `readStoredSetting(name)`
// ==================
//
// Reads the cookie of the given name.
// Stolen from <http://www.quirksmode.org/js/cookies.html>
SL.readStoredSetting = function(name) {
// When local storage is disabled on Safari, the mere act of referencing window.localStorage
// throws an error. For this reason, referencing window.localStorage without being inside
// a try-catch should be avoided.
try{
name = 'sdsat_' + name
return window.localStorage.getItem(name)
}catch(e){
SL.notify('Cannot read stored setting from localStorage: ' + e.message, 2)
return null
}
}
// Read satelliteUtilsCookie values to see about getting bookmarklet running / settings
SL.loadStoredSettings = function () {
var debug = SL.readStoredSetting('debug')
, hideActivity = SL.readStoredSetting('hide_activity')
if (debug)
SL.settings.notifications = debug === 'true'
if (hideActivity)
SL.settings.hideActivity = hideActivity === 'true'
}
SL.isRuleActive = function(rule, date){
var schd = rule.schedule
if (!schd) return true
var utc = schd.utc
, getDate = utc ? 'getUTCDate' : 'getDate'
, getDay = utc ? 'getUTCDay' : 'getDay'
, getFullYear = utc ? 'getUTCFullYear' : 'getFullYear'
, getMonth = utc ? 'getUTCMonth' : 'getMonth'
, getHours = utc ? 'getUTCHours' : 'getHours'
, getMinutes = utc ? 'getUTCMinutes' : 'getMinutes'
, setHours = utc ? 'setUTCHours' : 'setHours'
, setMinutes = utc ? 'setUTCMinutes' : 'setMinutes'
, setDate = utc ? 'setUTCDate' : 'setDate'
date = date || new Date()
function dayDiff(one, other){
other = modifyDate(other, {
hour: one[getHours](),
minute: one[getMinutes]()
})
return Math.floor(Math.abs((one.getTime() - other.getTime()) / (1000 * 60 * 60 * 24)))
}
function monthDiff(one, other){
function months(date){
return date[getFullYear]() * 12 + date[getMonth]()
}
return Math.abs(months(one) - months(other))
}
function modifyDate(date, fields){
var retval = new Date(date.getTime())
for (var field in fields){
if (fields.hasOwnProperty(field)) {
var val = fields[field]
switch(field){
case 'hour':
retval[setHours](val)
break
case 'minute':
retval[setMinutes](val)
break
case 'date':
retval[setDate](val)
break
}
}
}
return retval
}
function timeGreaterThan(one, other){
var h1 = one[getHours]()
, m1 = one[getMinutes]()
, h2 = other[getHours]()
, m2 = other[getMinutes]()
return (h1 * 60 + m1) > (h2 * 60 + m2)
}
function timeLessThan(one, other){
var h1 = one[getHours]()
, m1 = one[getMinutes]()
, h2 = other[getHours]()
, m2 = other[getMinutes]()
return (h1 * 60 + m1) < (h2 * 60 + m2)
}
if (schd.repeat){
if (timeGreaterThan(schd.start, date)) return false
if (timeLessThan(schd.end, date)) return false
if (date < schd.start) return false
if (schd.endRepeat && date >= schd.endRepeat) return false
if (schd.repeat === 'daily'){
if (schd.repeatEvery){
var dd = dayDiff(schd.start, date)
if (dd % schd.repeatEvery !== 0) return false
}
}else if (schd.repeat === 'weekly'){
if (schd.days){
if (!SL.contains(schd.days, date[getDay]())) return false
}else
if (schd.start[getDay]() !== date[getDay]()) return false
if (schd.repeatEvery){
var diff = dayDiff(schd.start, date)
if (diff % (7 * schd.repeatEvery) !== 0)
return false
}
}else if (schd.repeat === 'monthly'){
if (schd.repeatEvery){
var md = monthDiff(schd.start, date)
if (md % schd.repeatEvery !== 0) return false
}
if (schd.nthWeek && schd.mthDay){
if (schd.mthDay !== date[getDay]()) return false
var nthWeek = Math.floor((date[getDate]() - date[getDay]() + 1) / 7)
if (schd.nthWeek !== nthWeek) return false
}else
if (schd.start[getDate]() !== date[getDate]()) return false
}else if (schd.repeat === 'yearly'){
if (schd.start[getMonth]() !== date[getMonth]()) return false
if (schd.start[getDate]() !== date[getDate]()) return false
if (schd.repeatEvery){
var diff = Math.abs(schd.start[getFullYear]() - date[getFullYear]())
if (diff % schd.repeatEvery !== 0) return false
}
}
}else{
if (schd.start > date) return false
if (schd.end < date) return false
}
return true
}
SL.isOutboundLink = function(elm){
if (!elm.getAttribute('href')) return false
var hostname = elm.hostname
var href = elm.href
var protocol = elm.protocol
if (protocol !== 'http:' && protocol !== 'https:') return false
var isMyDomain = SL.any(SL.settings.domainList, function(domain){
return SL.isSubdomainOf(hostname, domain)
})
if (isMyDomain) return false
return hostname !== location.hostname
}
SL.isLinkerLink = function(elm){
if (!elm.getAttribute || !elm.getAttribute('href')) return false
return SL.hasMultipleDomains() &&
elm.hostname != location.hostname &&
!elm.href.match(/^javascript/i) &&
!SL.isOutboundLink(elm)
}
SL.isSubdomainOf = function(sub, root){
if (sub === root) return true
var idx = sub.length - root.length
if (idx > 0)
return SL.equalsIgnoreCase(sub.substring(idx), root)
return false
}
// `getVisitorId()`
// ------------------------------------------------
//
// Returns the library instance associated to a VisitorId tool if the tool exists
//
SL.getVisitorId = function(){
var visitorIdTools = SL.getToolsByType('visitor_id')
if (visitorIdTools.length === 0) {
return null;
}
return visitorIdTools[0].getInstance()
}
SL.URI = function(){
var ret = document.location.pathname + document.location.search
if (SL.settings.forceLowerCase){
ret = ret.toLowerCase()
}
return ret
}
SL.URL = function(){
var ret = document.location.href
if (SL.settings.forceLowerCase){
ret = ret.toLowerCase()
}
return ret
}
// Filter `SL.rules` down to only the once relevant for the current page.
SL.filterRules = function(){
function matches(rule){
if (!SL.isRuleActive(rule)) return false
return true
}
SL.rules = SL.filter(SL.rules, matches)
SL.pageLoadRules = SL.filter(SL.pageLoadRules, matches)
}
SL.ruleInScope = function(rule, location){
location = location || document.location
var scope = rule.scope
if (!scope) return true
var URI = scope.URI
var subdomains = scope.subdomains
var domains = scope.domains
var protocols = scope.protocols
var hashes = scope.hashes
if (URI && includeExcludeFails(URI, location.pathname + location.search)) return false
if (subdomains && includeExcludeFails(subdomains, location.hostname)) return false
if (domains && matchFails(domains, location.hostname)) return false
if (protocols && matchFails(protocols, location.protocol)) return false
if (hashes && includeExcludeFails(hashes, location.hash)) return false
function includeExcludeFails(matcher, matchee){
var include = matcher.include
var exclude = matcher.exclude
if (include && matchFails(include, matchee)) return true
if (exclude){
if (SL.isString(exclude) && exclude === matchee)
return true
if (SL.isArray(exclude) && SL.any(exclude, matches))
return true
if (SL.isRegex(exclude) && matches(exclude))
return true
}
return false
function matches(regex){
return matchee.match(regex)
}
}
function matchFails(matcher, matchee){
if (SL.isString(matcher) && matcher !== matchee)
return true
if (SL.isArray(matcher) && !SL.any(matcher, matches))
return true
if (SL.isRegex(matcher) && !matches(matcher))
return true
return false
function matches(regex){
return matchee.match(regex)
}
}
return true
}
// Run background tasks once. This will get invoked periodically.
SL.backgroundTasks = function(){
var start = +new Date()
SL.setFormListeners()
SL.setVideoListeners()
SL.loadStoredSettings()
SL.registerNewElementsForDynamicRules()
SL.eventEmitterBackgroundTasks()
// Trigger condition events
//SL.onEvent({type: 'condition', target: 'document'})
var end = +new Date()
// We want to keep an eye on the execution time here.
// If it gets to around 50ms for any customer site,
// we want to either optimize or start using a task queue
//SL.notify('Background tasks executed in ' + (end - start) + 'ms', 3)
}
// For rules that poll for dynamically injected elements on the page,
// find them and register events for them.
SL.registerNewElementsForDynamicRules = function(){
function cssQuery(selector, callback){
var hit = cssQuery.cache[selector]
if (hit){
return callback(hit)
}else{
SL.cssQuery(selector, function(elms){
cssQuery.cache[selector] = elms
callback(elms)
})
}
}
cssQuery.cache = {}
SL.each(SL.dynamicRules, function(rule){
cssQuery(rule.selector, function(elms){
SL.each(elms, function(elm){
var event = rule.event === 'custom' ? rule.customEvent : rule.event;
if (SL.$data(elm, 'dynamicRules.seen.' + event)) return
SL.$data(elm, 'dynamicRules.seen.' + event, true)
if (SL.propertiesMatch(rule.property, elm)){
SL.registerEvents(elm, [event])
}
})
})
})
}
// If the browser doesn't support CSS selector queries, we have to include one.
SL.ensureCSSSelector = function(){
if (document.querySelectorAll){
SL.hasSelector = true
return
}
SL.loadingSizzle = true
SL.sizzleQueue = []
SL.loadScript(SL.basePath() + 'selector.js', function(){
if (!SL.Sizzle){
SL.logError(new Error('Failed to load selector.js'))
return
}
var pending = SL.onEvent.pendingEvents
SL.each(pending, function(evt){
SL.handleEvent(evt)
}, this)
SL.onEvent = SL.handleEvent
SL.hasSelector = true
;delete SL.loadingSizzle
SL.each(SL.sizzleQueue, function(item){
SL.cssQuery(item[0], item[1])
})
;delete SL.sizzleQueue
})
}
// Error Handling
SL.errors = []
SL.logError = function(err){
SL.errors.push(err)
SL.notify(err.name + ' - ' + err.message, 5)
}
// `pageBottom()`
// --------------
//
// The function is to be called by the web page using an script tag like so:
//
// <script>_satellite.pageBottom()</script>
//
// just before the `</body>` tag.
SL.pageBottom = function(){
if (!SL.initialized) return
SL.pageBottomFired = true
SL.firePageLoadEvent('pagebottom')
}
// This allows Rover to configure the browser to use the staging library instead.
SL.stagingLibraryOverride = function(){
/*jshint evil:true */
var libraryOverride = SL.readStoredSetting('stagingLibrary') === 'true'
if (libraryOverride){ // allow Rover to override the library to staging
var scripts = document.getElementsByTagName('script')
, regex = /^(.*)satelliteLib-([a-f0-9]{40})\.js$/
, regexStaging = /^(.*)satelliteLib-([a-f0-9]{40})-staging\.js$/
, match
, matchStaging
, src
for (var i = 0, len = scripts.length; i < len; i++){
src = scripts[i].getAttribute('src')
if (!src) continue
if (!match) match = src.match(regex)
if (!matchStaging) matchStaging = src.match(regexStaging)
if (matchStaging) break
}
if (match && !matchStaging){
var stagingURL = match[1] + 'satelliteLib-' + match[2] + '-staging.js'
if (document.write) {
document.write('<script src="' + stagingURL + '"></script>')
} else {
var s = document.createElement('script')
s.src = stagingURL
document.head.appendChild(s)
}
return true
}
}
return false
}
SL.checkAsyncInclude = function(){
if (window.satellite_asyncLoad)
SL.notify('You may be using the async installation of Satellite. In-page HTML and the "pagebottom" event will not work. Please update your Satellite installation for these features.', 5)
}
SL.hasMultipleDomains = function(){
return !!SL.settings.domainList && SL.settings.domainList.length > 1
}
SL.handleOverrides = function(){
if (Overrides){
for (var key in Overrides){
if (Overrides.hasOwnProperty(key)){
SL.data[key] = Overrides[key]
}
}
}
}
SL.privacyManagerParams = function(){
var params = {}
SL.extend(params, SL.settings.privacyManagement)
var analyticsTools = []
for (var key in SL.tools){
if (SL.tools.hasOwnProperty(key)) {
var tool = SL.tools[key]
var settings = tool.settings
if (!settings) continue
if (settings.engine === 'sc'){
analyticsTools.push(tool)
}
}
}
var analyticsTrackingServers = SL.filter(SL.map(analyticsTools, function(tool){
return tool.getTrackingServer()
}), function(s){ return s != null })
params.adobeAnalyticsTrackingServers = analyticsTrackingServers
var substitutable = [
'bannerText',
'headline',
'introductoryText',
'customCSS'
]
for (var i = 0; i < substitutable.length; i++){
var prop = substitutable[i]
var spec = params[prop]
if (!spec) continue
if (spec.type === 'text'){
params[prop] = spec.value
}else if (spec.type === 'data'){
params[prop] = SL.getVar(spec.value)
}else{
throw new Error('Invalid type: ' + spec.type)
}
}
return params
}
SL.prepareLoadPrivacyManager = function(){
SL.addEventHandler(window, 'load', function(){
loadWhenAllSCToolsLoaded(SL.loadPrivacyManager)
})
function loadWhenAllSCToolsLoaded(callback){
var scTools = SL.filter(SL.values(SL.tools), function(tool){
return tool.settings && tool.settings.engine === 'sc'
})
if (scTools.length === 0){
return callback()
}
var numLoaded = 0
SL.each(scTools, function(tool){
SL.bindEvent(tool.id + '.load', onLoad)
})
var tid = setTimeout(onTimeout, 5000)
function onLoad(){
numLoaded++
if (numLoaded === scTools.length){
cleanUp()
clearTimeout(tid)
callback()
}
}
function cleanUp(){
SL.each(scTools, function(tool){
SL.unbindEvent(tool.id + '.load', onLoad)
})
}
function onTimeout(){
cleanUp()
callback()
}
}
}
// `loadPrivacyManager()`
// ----------------------
//
// Initialize privacy manager
SL.loadPrivacyManager = function(){
var scriptUrl = SL.basePath() + 'privacy_manager.js'
SL.loadScript(scriptUrl, function(){
var pm = SL.privacyManager
pm.configure(SL.privacyManagerParams())
pm.openIfRequired()
})
}
// `init()`
// --------
//
// Initialize Satellite.
//
// - `settings` - all the settings that comprising a library.
SL.init = function(settings) {
if (SL.stagingLibraryOverride())
return
SL.configurationSettings = settings
var tools = settings.tools
;delete settings.tools
for (var key in settings){
if (settings.hasOwnProperty(key)){
SL[key] = settings[key]
}
}
if(SL.data.customVars === undefined)
SL.data.customVars = {}
SL.data.queryParams = SL.QueryParams.normal
SL.handleOverrides()
SL.detectBrowserInfo()
if (SL.trackVisitorInfo)
SL.trackVisitorInfo()
SL.loadStoredSettings()
SL.Logger.setOutputState(SL.settings.notifications)
SL.checkAsyncInclude()
SL.ensureCSSSelector()
SL.filterRules()
SL.dynamicRules = SL.filter(SL.rules, function(rule){
return rule.eventHandlerOnElement
})
SL.tools = SL.initTools(tools)
SL.initEventEmitters()
SL.firePageLoadEvent('aftertoolinit')
if (SL.settings.privacyManagement){
SL.prepareLoadPrivacyManager()
}
if (SL.hasSelector)
SL.domReady(SL.eventEmitterBackgroundTasks)
SL.setListeners()
// Setup background tasks
SL.domReady(function() {
SL.poll(
function() { SL.backgroundTasks() },
SL.settings.recheckEvery || 3000
)
})
// Setup page load events
SL.domReady(function(){
SL.domReadyFired = true
if (!SL.pageBottomFired)
SL.pageBottom()
SL.firePageLoadEvent('domready')
})
SL.addEventHandler(window, 'load', function(){
SL.firePageLoadEvent('windowload')
})
SL.firePageLoadEvent('pagetop')
SL.initialized = true
}
SL.pageLoadPhases = ['aftertoolinit', 'pagetop', 'pagebottom', 'domready', 'windowload']
SL.loadEventBefore = function(one, other){
return SL.indexOf(SL.pageLoadPhases, one) <= SL.indexOf(SL.pageLoadPhases, other)
}
SL.flushPendingCalls = function(tool){
if (tool.pending){
SL.each(tool.pending, function(call){
var cmd = call[0]
, elm = call[1]
, evt = call[2]
, args = call[3]
if (cmd in tool)
tool[cmd].apply(tool, [elm, evt].concat(args))
else if (tool.emit)
tool.emit(cmd, elm, evt, args)
else
SL.notify('Failed to trigger ' + cmd +
' for tool ' + tool.id, 1)
})
;delete tool.pending
}
}
// setDebug(debug)
// --------------
//
// Activate or deactivate debug mode - within which
// log statements will be printed to the JS console.
//
// - `debug` - a boolean indicating whether debug mode
// should be turned on.
SL.setDebug = function(debug){
// When local storage is disabled on Safari, the mere act of referencing window.localStorage
// throws an error. For this reason, referencing window.localStorage without being inside
// a try-catch should be avoided.
try {
window.localStorage.setItem('sdsat_debug', debug)
} catch (e) {
SL.notify('Cannot set debug mode: ' + e.message, 2)
};
}
SL.getUserAgent = function() {
return navigator.userAgent;
};
SL.detectBrowserInfo = function(){
// Based on <http://jsbin.com/inubez/3/>
function matcher(regexs){
return function(userAgent){
for (var key in regexs){
if (regexs.hasOwnProperty(key)) {
var regex = regexs[key];
var match = regex.test(userAgent);
if (match) return key;
}
}
return "Unknown";
};
}
// The order in which these regular expressions are evaluated is important.
var getBrowser = matcher({
"IE Edge Mobile": /Windows Phone.*Edge/,
"IE Edge": /Edge/,
OmniWeb: /OmniWeb/,
"Opera Mini": /Opera Mini/,
"Opera Mobile": /Opera Mobi/,
Opera: /Opera/,
Chrome: /Chrome|CriOS|CrMo/,
Firefox: /Firefox|FxiOS/,
"IE Mobile": /IEMobile/,
IE: /MSIE|Trident/,
"Mobile Safari": /Mobile(\/[0-9A-z]+)? Safari/,
Safari: /Safari/
});
var getOS = matcher({
Blackberry: /BlackBerry|BB10/,
"Symbian OS": /Symbian|SymbOS/,
Maemo: /Maemo/,
Android: /Android/,
Linux: / Linux /,
Unix: /FreeBSD|OpenBSD|CrOS/,
Windows: /[\( ]Windows /,
iOS: /iPhone|iPad|iPod/,
MacOS: /Macintosh;/
});
var getDeviceType = matcher({
// This is not entirely accurate. A few old Samsung, Motorola, and Sony Ericsson phones
// will match but the majority and best guess is Nokia. Also, Nokia makes Windows phones and
// for those we will make it match Windows Phone and not Nokia.
Nokia: /Symbian|SymbOS|Maemo/,
"Windows Phone": /Windows Phone/,
Blackberry: /BlackBerry|BB10/,
Android: /Android/,
iPad: /iPad/,
iPod: /iPod/,
iPhone: /iPhone/,
Desktop: /.*/
});
var userAgent = SL.getUserAgent();
SL.browserInfo = {
browser: getBrowser(userAgent)
, os: getOS(userAgent)
, deviceType: getDeviceType(userAgent)
}
}
SL.isHttps = function(){
return 'https:' == document.location.protocol
}
SL.BaseTool = function(settings){
this.settings = settings || {}
this.forceLowerCase = SL.settings.forceLowerCase
if ('forceLowerCase' in this.settings){
this.forceLowerCase = this.settings.forceLowerCase
}
}
SL.BaseTool.prototype = {
triggerCommand: function(trig, elm, evt){
var settings = this.settings || {}
if (this.initialize && this.isQueueAvailable()){
if (this.isQueueable(trig) && evt && SL.loadEventBefore(evt.type, settings.loadOn)){
this.queueCommand(trig, elm, evt)
return
}
}
var cmd = trig.command
var method = this['$' + cmd]
var escapeHtml = method ? method.escapeHtml : false
var args = SL.preprocessArguments(
trig['arguments'],
elm,
evt,
this.forceLowerCase,
escapeHtml)
if (method){
method.apply(this, [elm, evt].concat(args))
}else if (this.$missing$){
this.$missing$(cmd, elm, evt, args)
}else
SL.notify('Failed to trigger ' + cmd +
' for tool ' + this.id, 1)
},
endPLPhase: function(pageLoadEvent){
// override to handle end initialization
},
isQueueable: function(trig){
// everything is queueable except `cancelToolInit`
return trig.command !== 'cancelToolInit'
},
isQueueAvailable: function(){
return !this.initialized && !this.initializing
},
flushQueue: function(){
if (this.pending){
SL.each(this.pending, function(args){
this.triggerCommand.apply(this, args)
}, this)
this.pending = []
}
},
queueCommand: function(trig, elm, evt){
if (!this.pending)
this.pending = []
this.pending.push([trig, elm, evt])
},
$cancelToolInit: function(){
this._cancelToolInit = true
}
}
// Set Satellite to the global variable `_satellite`.
window._satellite = SL
// ElementExistsEventEmitter
// ==================
//
// Emits the `elementexists` event. The `elementexists` event fires when an element
// of a specified selector becomes into existance - either because it's in the page
// markup or dynamically injected later on. *Each rule only fires once.*
function ElementExistsEventEmitter() {
this.rules = SL.filter(SL.rules, function(rule) {
return rule.event === 'elementexists';
});
}
ElementExistsEventEmitter.prototype.backgroundTasks = function() {
SL.each(this.rules, function(rule) {
SL.cssQuery(rule.selector, function(elms) {
if (elms.length > 0){
// This results in a bug: https://jira.corp.adobe.com/browse/DTM-6681
// The fix was reverted due to: https://jira.corp.adobe.com/browse/DTM-7377
var elm = elms[0];
if (SL.$data(elm, 'elementexists.seen')) return;
SL.$data(elm, 'elementexists.seen', true);
SL.onEvent({type: 'elementexists', target: elm});
}
})
})
}
SL.availableEventEmitters.push(ElementExistsEventEmitter);
// Leave Event Emitter
// ============================
//
// The page leave is an event that is used to detect the moment when the
// browser's tab gets closed.
//
function LeaveEventEmitter() {
if (SL.getToolsByType('nielsen').length > 0) {
SL.domReady(SL.bind(this.initialize, this));
}
}
LeaveEventEmitter.prototype = {
obue: false,
initialize: function() {
this.attachCloseListeners();
},
obuePrevUnload: function() {},
obuePrevBeforeUnload: function() {},
newObueListener: function() {
if (!this.obue) {
this.obue = true;
this.triggerBeacons();
}
},
attachCloseListeners: function() {
this.prevUnload = window.onunload;
this.prevBeforeUnload = window.onbeforeunload;
window.onunload = SL.bind(function(e) {
if (this.prevUnload) {
setTimeout(SL.bind(function() {
this.prevUnload.call(window, e);
}, this), 1);
}
this.newObueListener();
}, this);
window.onbeforeunload = SL.bind(function(e) {
if (this.prevBeforeUnload) {
setTimeout(SL.bind(function() {
this.prevBeforeUnload.call(window, e);
}, this), 1);
}
this.newObueListener();
}, this);
},
triggerBeacons: function() {
SL.fireEvent('leave', document);
}
}
SL.availableEventEmitters.push(LeaveEventEmitter);
// Orientation Change Event Emitter
// ================================
//
// The `orientationchange` event on mobile devices fire when the devices switchs between
// portrait and landscape modes. You can use `%event.orientation%` in your command arguments
// to evaluate to either `portrait` or `landscape`.
function OrientationChangeEventEmitter(){
SL.addEventHandler(window, "orientationchange", OrientationChangeEventEmitter.orientationChange)
}
OrientationChangeEventEmitter.orientationChange = function (e) {
var orientation = window.orientation === 0 ?
'portrait' :
'landscape'
e.orientation = orientation
SL.onEvent(e)
}
SL.availableEventEmitters.push(OrientationChangeEventEmitter)
// Hover Event Emitter
// =====================
//
// Emits the `hover` event in the event. This is better than `mouseover` because you can introduce a certain delay.
//
// {
// name: "Hover for 1 second"
// event: "hover(1000)",
// ...
// }
function HoverEventEmitter(){
var eventRegex = this.eventRegex = /^hover\(([0-9]+)\)$/
var rules = this.rules = []
SL.each(SL.rules, function(rule){
var m = rule.event.match(eventRegex)
if (m){
rules.push([
Number(rule.event.match(eventRegex)[1]),
rule.selector
])
}
})
}
HoverEventEmitter.prototype = {
backgroundTasks: function(){
var self = this
SL.each(this.rules, function(rule){
var selector = rule[1]
, delay = rule[0]
SL.cssQuery(selector, function(newElms){
SL.each(newElms, function(elm){
self.trackElement(elm, delay)
})
})
}, this)
},
trackElement: function(elm, delay){
var self = this
, trackDelays = SL.$data(elm, 'hover.delays')
if (!trackDelays){
SL.addEventHandler(elm, 'mouseover', function(e){
self.onMouseOver(e, elm)
})
SL.addEventHandler(elm, 'mouseout', function(e){
self.onMouseOut(e, elm)
})
SL.$data(elm, 'hover.delays', [delay])
}
else if (!SL.contains(trackDelays, delay)){
trackDelays.push(delay)
}
},
onMouseOver: function(e, elem){
var target = e.target || e.srcElement
, related = e.relatedTarget || e.fromElement
, hit = (elem === target || SL.containsElement(elem, target)) &&
!SL.containsElement(elem, related)
if (hit)
this.onMouseEnter(elem)
},
onMouseEnter: function(elm){
var delays = SL.$data(elm, 'hover.delays')
var delayTimers = SL.map(delays, function(delay){
return setTimeout(function(){
SL.onEvent({type: 'hover(' + delay + ')', target: elm})
}, delay)
})
SL.$data(elm, 'hover.delayTimers', delayTimers)
},
onMouseOut: function(e, elem){
var target = e.target || e.srcElement
, related = e.relatedTarget || e.toElement
, hit = (elem === target || SL.containsElement(elem, target)) &&
!SL.containsElement(elem, related)
if (hit)
this.onMouseLeave(elem)
},
onMouseLeave: function(elm){
var delayTimers = SL.$data(elm, 'hover.delayTimers')
if (delayTimers)
SL.each(delayTimers, function(timer){
clearTimeout(timer)
})
}
}
SL.availableEventEmitters.push(HoverEventEmitter)
// Visibility API Event Emitter
// ============================
//
// The `visibility API` is used when the browser's tab gets hidden because
// another tab now is visible. For more information see Mozilla's [Page Visibility API](https://developer.mozilla.org/en-US/docs/Web/Guide/User_experience/Using_the_Page_Visibility_API)
function VisibilityEventEmitter() {
this.defineEvents();
this.visibilityApiHasPriority = true;
if (!document.addEventListener) { // Older browers (e.g.: IE8)
this.attachDetachOlderEventListeners(true, document, 'focusout');
} else {
this.setVisibilityApiPriority(false);
}
var context = this;
SL.bindEvent('aftertoolinit', function() {
SL.fireEvent(SL.visibility.isHidden() ? 'tabblur' : 'tabfocus');
});
}
VisibilityEventEmitter.prototype = {
defineEvents: function() {
this.oldBlurClosure = function() {
SL.fireEvent('tabblur', document)
};
this.oldFocusClosure = SL.bind(function() {
if (this.visibilityApiHasPriority) {
SL.fireEvent('tabfocus', document);
} else {
if (SL.visibility.getHiddenProperty() != null) {
if(!SL.visibility.isHidden()) {
SL.fireEvent('tabfocus', document);
}
} else {
SL.fireEvent('tabfocus', document);
}
}
}, this);
},
attachDetachModernEventListeners: function(add) {
var method = (add == false ? 'removeEventHandler' : 'addEventHandler');
SL[method](document,
SL.visibility.getVisibilityEvent(),
this.handleVisibilityChange
);
},
attachDetachOlderEventListeners: function(add, blurTarget, blurEventName) {
var method = (add == false ? 'removeEventHandler' : 'addEventHandler');
SL[method](blurTarget, blurEventName, this.oldBlurClosure);
SL[method](window, 'focus', this.oldFocusClosure);
},
handleVisibilityChange: function() {
if (SL.visibility.isHidden()) {
SL.fireEvent('tabblur', document);
} else {
SL.fireEvent('tabfocus', document);
}
},
setVisibilityApiPriority: function(visibilityApiHasPriority) {
this.visibilityApiHasPriority = visibilityApiHasPriority;
this.attachDetachOlderEventListeners(false, window, 'blur');
this.attachDetachModernEventListeners(false);
if (visibilityApiHasPriority) {
if (SL.visibility.getHiddenProperty() != null) { // Modern browsers
this.attachDetachModernEventListeners(true);
} else {
this.attachDetachOlderEventListeners(true, window, 'blur');
}
} else {
this.attachDetachOlderEventListeners(true, window, 'blur');
if (SL.visibility.getHiddenProperty() != null) { // Modern browsers
this.attachDetachModernEventListeners(true);
}
}
},
oldBlurClosure: null,
oldFocusClosure: null,
visibilityApiHasPriority: true
};
SL.availableEventEmitters.push(VisibilityEventEmitter);
// Location Change Event Emitter
// =============================
//
// Will fire `locationchange` event whenever the browser location
// changes due to `hashchange`, `popstate`, `history.pushState()`,
// or `history.replaceState()`.
function LocationChangeEventEmitter(){
this.lastURL = SL.URL()
this._fireIfURIChanged = SL.bind(this.fireIfURIChanged, this)
this._onPopState = SL.bind(this.onPopState, this)
this._onHashChange = SL.bind(this.onHashChange, this)
this._pushState = SL.bind(this.pushState, this)
this._replaceState = SL.bind(this.replaceState, this)
this.initialize()
}
LocationChangeEventEmitter.prototype = {
initialize: function(){
this.setupHistoryAPI()
this.setupHashChange()
},
fireIfURIChanged: function(){
var URL = SL.URL()
if (this.lastURL !== URL){
this.fireEvent()
this.lastURL = URL
}
},
fireEvent: function(){
SL.updateQueryParams()
SL.onEvent({ type: 'locationchange', target: document })
},
setupSPASupport: function(){
this.setupHistoryAPI()
this.setupHashChange()
},
setupHistoryAPI: function(){
var history = window.history
if (history){
if (history.pushState){
this.originalPushState = history.pushState
history.pushState = this._pushState
}
if (history.replaceState){
this.originalReplaceState = history.replaceState
history.replaceState = this._replaceState
}
}
SL.addEventHandler(window, 'popstate', this._onPopState)
},
pushState: function(){
var ret = this.originalPushState.apply(history, arguments)
this.onPushState()
return ret
},
replaceState: function(){
var ret = this.originalReplaceState.apply(history, arguments)
this.onReplaceState()
return ret
},
setupHashChange: function(){
SL.addEventHandler(window, 'hashchange', this._onHashChange)
},
onReplaceState: function(){
setTimeout(this._fireIfURIChanged, 0)
},
onPushState: function(){
setTimeout(this._fireIfURIChanged, 0)
},
onPopState: function(){
setTimeout(this._fireIfURIChanged, 0)
},
onHashChange: function(){
setTimeout(this._fireIfURIChanged, 0)
},
uninitialize: function(){
this.cleanUpHistoryAPI()
this.cleanUpHashChange()
},
cleanUpHistoryAPI: function(){
if (history.pushState === this._pushState){
history.pushState = this.originalPushState
}
if (history.replaceState === this._replaceState){
history.replaceState = this.originalReplaceState
}
SL.removeEventHandler(window, 'popstate', this._onPopState)
},
cleanUpHashChange: function(){
SL.removeEventHandler(window, 'hashchange', this._onHashChange)
}
}
SL.availableEventEmitters.push(LocationChangeEventEmitter);
// VideoPlayedEventEmitter
// =======================
//
// Emits the `videoplayed` event, given a specified percentage or duration, i.e. `videoplayed`
// is a parameterized event. A rule looks like this
//
// {
// name: "Video 10% complete",
// event: "videoplayed(10%)",
// selector: "#video",
// trigger: [
// {
// tool: "ga",
// command: "trackEvent",
// arguments: [
// "video",
// "video 10% complete",
// "from: %URI%"
// ]
// }
// ]
// }
//
// `10%` is in the paranthesis which indicates this rule will only fire when the 10%
// of the total length of the video has been played.
// You can also specifiy a duration in seconds, which looks like `videoplayed(8s)` - which
// stands for 8 seconds.
function VideoPlayedEventEmitter(){
this.rules = SL.filter(SL.rules, function(rule){
return rule.event.substring(0, 11) === 'videoplayed'
})
this.eventHandler = SL.bind(this.onUpdateTime, this)
}
VideoPlayedEventEmitter.prototype = {
backgroundTasks: function(){
var eventHandler = this.eventHandler
SL.each(this.rules, function(rule){
SL.cssQuery(rule.selector || 'video', function(elms){
SL.each(elms, function(elm){
if (SL.$data(elm, 'videoplayed.tracked')) return
SL.addEventHandler(elm, 'timeupdate', SL.throttle(eventHandler, 100))
SL.$data(elm, 'videoplayed.tracked', true)
})
})
})
},
evalRule: function(elm, rule){
var eventType = rule.event
, seekable = elm.seekable
, startTime = seekable.start(0)
, endTime = seekable.end(0)
, currentTime = elm.currentTime
, m = rule.event.match(/^videoplayed\(([0-9]+)([s%])\)$/)
if (!m) return
var unit = m[2]
, amount = Number(m[1])
var func = unit === '%' ?
function(){
return amount <=
100 * (currentTime - startTime) / (endTime - startTime)
} :
function(){
return amount <= currentTime - startTime
}
if (!SL.$data(elm, eventType) && func()){
SL.$data(elm, eventType, true)
SL.onEvent({type: eventType, target: elm})
}
},
onUpdateTime: function(e){
var rules = this.rules
, elm = e.target
if (!elm.seekable || elm.seekable.length === 0) return
for (var i = 0, len = rules.length; i < len; i++)
this.evalRule(elm, rules[i])
}
}
SL.availableEventEmitters.push(VideoPlayedEventEmitter)
// Facebook Event Emitter
// ======================
//
// Will track `edge.create`, `edge.remove` and `message.send` events from the Facebook
// Javascript API and emit `facebook.like`, `facebook.unlike` and `facebook.send` events
// respectively.
function FacebookEventEmitter(FB){
this.delay = 250;
this.FB = FB;
SL.domReady(SL.bind(function () {
SL.poll(SL.bind(this.initialize, this), this.delay, 8);
}, this));
}
FacebookEventEmitter.prototype = {
initialize: function() {
this.FB = this.FB || window.FB;
if (this.FB && this.FB.Event && this.FB.Event.subscribe) {
this.bind();
return true;
}
},
bind: function(){
this.FB.Event.subscribe('edge.create', function() {
SL.notify("tracking a facebook like", 1)
SL.onEvent({type: 'facebook.like', target: document})
});
this.FB.Event.subscribe('edge.remove', function() {
SL.notify("tracking a facebook unlike", 1)
SL.onEvent({type: 'facebook.unlike', target: document})
});
this.FB.Event.subscribe('message.send', function() {
SL.notify("tracking a facebook share", 1)
SL.onEvent({type: 'facebook.send', target: document})
});
}
}
SL.availableEventEmitters.push(FacebookEventEmitter);
// Twitter Event Emitter
// =====================
//
// Emits the `twitter.tweet` event in the event a user tweets from the site.
function TwitterEventEmitter(twttr){
SL.domReady(SL.bind(function () {
this.twttr = twttr || window.twttr;
this.initialize();
}, this));
}
TwitterEventEmitter.prototype = {
initialize: function(){
var twttr = this.twttr;
if (twttr && typeof twttr.ready === 'function') {
twttr.ready(SL.bind(this.bind, this));
}
},
bind: function(){
this.twttr.events.bind('tweet', function(event) {
if (event) {
SL.notify("tracking a tweet button", 1);
SL.onEvent({type: 'twitter.tweet', target: document});
}
});
}
}
SL.availableEventEmitters.push(TwitterEventEmitter)
// InviewEventEmitter
// ==================
//
// Emits the `inview` event. The `inview` event fires on an element when the element
// first comes into the view of the user. If the element is in view immediately upon page
// load, it will be fired right away, if it only comes in view after some scrolling, it
// will fire then. An optional delay interval `inviewDelay` can be specified in the rule
// which determine how long the element has to be in view for before the event fires,
// of which the default value is 1 second.
function InViewEventEmitter(rules){
rules = rules || SL.rules
this.rules = SL.filter(rules, function(rule){
return rule.event === 'inview'
})
this.elements = []
this.eventHandler = SL.bind(this.track, this)
SL.addEventHandler(window, 'scroll', this.eventHandler)
SL.addEventHandler(window, 'load', this.eventHandler)
}
// Util functions needed by `InViewEventEmitter`
InViewEventEmitter.offset = function(elem) {
var top = null, left = null;
try {
var box = elem.getBoundingClientRect(),
doc = document,
docElem = doc.documentElement,
body = doc.body,
win = window,
clientTop = docElem.clientTop || body.clientTop || 0,
clientLeft = docElem.clientLeft || body.clientLeft || 0,
scrollTop = win.pageYOffset || docElem.scrollTop || body.scrollTop,
scrollLeft = win.pageXOffset || docElem.scrollLeft || body.scrollLeft;
top = box.top + scrollTop - clientTop;
left = box.left + scrollLeft - clientLeft;
} catch(e) {
}
return { top: top, left: left }
}
InViewEventEmitter.getViewportHeight = function() {
var height = window.innerHeight // Safari, Opera
var mode = document.compatMode
if (mode) { // IE, Gecko
height = (mode == 'CSS1Compat') ?
document.documentElement.clientHeight : // Standards
document.body.clientHeight // Quirks
}
return height
}
InViewEventEmitter.getScrollTop = function(){
return (document.documentElement.scrollTop ?
document.documentElement.scrollTop :
document.body.scrollTop)
}
InViewEventEmitter.isElementInDocument = function(el) {
return document.body.contains(el);
}
InViewEventEmitter.isElementInView = function(el) {
if (!InViewEventEmitter.isElementInDocument(el)) {
return false;
}
var vpH = InViewEventEmitter.getViewportHeight()
, scrolltop = InViewEventEmitter.getScrollTop()
, top = InViewEventEmitter.offset(el).top
, height = el.offsetHeight;
if (top !== null) {
return !(scrolltop > (top + height) || scrolltop + vpH < top)
}
return false;
}
InViewEventEmitter.prototype = {
backgroundTasks: function(){
var elements = this.elements
SL.each(this.rules, function(rule){
SL.cssQuery(rule.selector, function(elms){
var addCount = 0
SL.each(elms, function(elm){
if (!SL.contains(elements, elm)){
elements.push(elm)
addCount++
}
})
if (addCount){
SL.notify(rule.selector + ' added ' + addCount + ' elements.', 1)
}
})
})
this.track()
},
checkInView: function(el, recheck, delay){
var inview = SL.$data(el, 'inview');
if (InViewEventEmitter.isElementInView(el)) {
// it is in view now
if (!inview)
SL.$data(el, 'inview', true)
var self = this
this.processRules(el, function(rule, viewedProp, timeoutIdProp){
if (recheck || !rule.inviewDelay){
SL.$data(el, viewedProp, true)
SL.onEvent({type: 'inview', target: el, inviewDelay: rule.inviewDelay})
}else if(rule.inviewDelay){
var timeout = SL.$data(el, timeoutIdProp)
if (!timeout) {
timeout = setTimeout(function(){
self.checkInView(el, true, rule.inviewDelay)
}, rule.inviewDelay)
SL.$data(el, timeoutIdProp, timeout)
}
}
}, delay)
} else {
if (!InViewEventEmitter.isElementInDocument(el)) {
var idx = SL.indexOf(this.elements, el);
this.elements.splice(idx, 1)
}
// it is not in view now
if (inview)
SL.$data(el, 'inview', false)
this.processRules(el, function(rule, viewedProp, timeoutIdProp){
var timeout = SL.$data(el, timeoutIdProp)
if (timeout){
clearTimeout(timeout)
}
}, delay)
}
},
track: function(){
// We are not using SL.each here because we might do a splice inisde
// `checkInView` method.
for (var i = this.elements.length - 1; i >=0; i--) {
this.checkInView(this.elements[i]);
}
},
processRules: function(elm, callback, delay){
var filteredRules = this.rules;
if (delay) {
filteredRules = SL.filter(this.rules, function(e){
return e.inviewDelay == delay;
});
}
SL.each(filteredRules, function(rule, i){
// viewedProp: for rules that has a timeout, the definition for
// "viewed" is rule dependent. But for all rules that do not have
// a timeout, it is independent.
var viewedProp = rule.inviewDelay ? 'viewed_' + rule.inviewDelay : 'viewed'
var timeoutIdProp = 'inview_timeout_id_' + i
if (SL.$data(elm, viewedProp)) return
if (SL.matchesCss(rule.selector, elm)){
callback(rule, viewedProp, timeoutIdProp)
}
})
}
}
SL.availableEventEmitters.push(InViewEventEmitter)
function DataElementChangeEmitter() {
var rules = SL.filter(SL.rules, function(rule) {
return rule.event.indexOf('dataelementchange') === 0;
});
this.dataElementsNames = SL.map(rules, function(rule) {
var matchedSubstrings = rule.event.match(/dataelementchange\((.*)\)/i);
return matchedSubstrings[1];
}, this);
this.initPolling();
}
// SL.stringify is not 100% compatible with JSON.stringify (for example JSON.stringify breaks
// whenever it encounters a cyclic reference). Since this check might become intensive,
// only for this case we would prefer using JSON.stringify whenever that's available.
DataElementChangeEmitter.prototype.getStringifiedValue =
(window.JSON && window.JSON.stringify) || SL.stringify;
DataElementChangeEmitter.prototype.initPolling = function() {
if (this.dataElementsNames.length === 0) {
return;
}
this.dataElementsStore = this.getDataElementsValues();
SL.poll(SL.bind(this.checkDataElementValues, this), 1000);
};
DataElementChangeEmitter.prototype.getDataElementsValues = function() {
var values = {};
SL.each(this.dataElementsNames, function(dataElementName) {
var value = SL.getVar(dataElementName);
values[dataElementName] = this.getStringifiedValue(value);
}, this);
return values;
};
DataElementChangeEmitter.prototype.checkDataElementValues = function() {
SL.each(this.dataElementsNames, SL.bind(function(dataElementName) {
var currentStringifiedValue = this.getStringifiedValue(SL.getVar(dataElementName));
var previousStringifiedValue = this.dataElementsStore[dataElementName];
if (currentStringifiedValue !== previousStringifiedValue) {
this.dataElementsStore[dataElementName] = currentStringifiedValue;
SL.onEvent({
type: 'dataelementchange(' + dataElementName + ')',
target: document
});
}
}, this));
};
SL.availableEventEmitters.push(DataElementChangeEmitter);
// Visibility API Event Emitter
// ============================
//
// The `visibility API` is used when the browser's tab gets hidden because
// another tab now is visible. For more information see Mozilla's [Page Visibility API](https://developer.mozilla.org/en-US/docs/Web/Guide/User_experience/Using_the_Page_Visibility_API)
SL.visibility = {
// Public
// ------------------------------------------------
// `isHidden()`
//
// The method returns true if the tab is hidden, otherwise false.
isHidden: function() {
var prop = this.getHiddenProperty();
if (!prop) return false;
return document[prop];
},
// `isVisible()`
//
// The method is an alias for the `!isHidden`.
isVisible: function() {
return !this.isHidden();
},
// Private
// ------------------------------------------------
getHiddenProperty: function() {
var prefixes = ['webkit', 'moz', 'ms', 'o'];
if ('hidden' in document) return 'hidden';
// otherwise loop over all the known prefixes until we find one
for (var i = 0; i < prefixes.length; i++) {
if ((prefixes[i] + 'Hidden') in document)
return prefixes[i] + 'Hidden';
}
// otherwise it's not supported
return null;
},
getVisibilityEvent: function() {
var ve = this.getHiddenProperty();
if (!ve) return null;
return ve.replace(/[H|h]idden/,'') + 'visibilitychange';
}
};
// E-Commerce APIs
// ---------------
//
// The ecommerce API allows web admins to integrate e-commerce tracking with Satellite.
// More details on the [GA E-Commerce API's](http://code.google.com/apis/analytics/docs/gaJS/gaJSApiEcommerce.html).
// Upon any of the methods on the API being called, they will fire an event, which
// in turn can be handled by a rule in the library.
SL.ecommerce = {
// `addItem(orderId, sku, name, category, price, quantity)`
// -------------------------------------
//
// Add an item to the transaction.
addItem: function(){
var args = [].slice.call(arguments)
SL.onEvent({type: 'ecommerce.additem', target: args})
},
// `addTrans(orderId, affiliation, total, tax, shipping, city, state, country)`
// ----------------------------------------------------------------------------
//
// Add a new transaction.
addTrans: function(){
var args = [].slice.call(arguments)
SL.data.saleData.sale = {
orderId: args[0],
revenue: args[2]
}
SL.onEvent({type: 'ecommerce.addtrans', target: args})
},
// `trackTrans()`
// --------------
//
// Send the transaction data that's been set up using `addItem()` and `addTrans()`
// to GA to be tracked.
trackTrans: function(){
SL.onEvent({type: 'ecommerce.tracktrans', target: []})
}
}
// The Marketing Cloud Visitor ID Service Tool
// ================
//
// This tool interacts with the [Visitor ID library](https://git.corp.adobe.com/mc-visitor/VisitorAPI/tree/master/js/src).
// The tool initilizes the Visitor ID library as soon as the tool itself is
// created, by calling the `initialize` method. Find out more info about the
// initializing sequence by clicking [here](#-initialize-).
//
// The tool accepts the following settings:
//
// - `mcOrgId` - The Adobe Marketing Cloud Organization ID (Required)
// - `initVars` - Map containing properties that can be set on the Visitor ID
// instance. The following keys can be set here:
// * `trackingServer`,
// * `trackingServerSecure`,
// * `marketingCloudServer`
// * `marketingCloudServerSecure`
// - `customerIDs` - Map containing Customer IDs values that will be set on the
// instance
// - `autoRequest` - Flag that will read the Marketing Cloud Visitor ID by
// calling `getMarketingCloudVisitorID` method
function VisitorIdTool(settings) {
SL.BaseTool.call(this, settings);
this.name = settings.name || 'VisitorID';
this.initialize();
}
SL.extend(VisitorIdTool.prototype, {
// Public
// ------------------------------------------------
//
// `getInstance()`
// ------------------------------------------------
//
// Returns the Visitor ID instance that was created when the tool was
// initialized.
getInstance: function() {
return this.instance;
},
// Private
// ------------------------------------------------
//
// `initialize()`
// ------------------------------------------------
//
// The method creates a Visitor ID instance if all the data provided is valid.
// The instance will contain all the keys defined in the `initVar` setting.
// Any `dataElement` present as a value in the initVars map will be replaced
// with the correct value.
//
// It applies then a the map of Customer IDs by calling the `setCustomerIDs`
// method from the newly created instance. Any `dataElement` present as a
// value in the Customer IDs map will be replaced with the correct value.
//
// After that, the `getMarketingCloudVisitorID` method from the newly created
// instance is called, provided that the `autoRequest` settings is set to true.
initialize: function() {
var settings = this.settings, visitor;
SL.notify('Visitor ID: Initializing tool', 1);
visitor = this.createInstance(
settings.mcOrgId,
settings.initVars
);
if (visitor === null) {
return;
}
if (settings.customerIDs) {
this.applyCustomerIDs(visitor, settings.customerIDs);
}
if (settings.autoRequest) {
visitor.getMarketingCloudVisitorID();
}
this.instance = visitor;
},
createInstance: function(mcOrgId, initVars) {
if(!SL.isString(mcOrgId)) {
SL.notify(
'Visitor ID: Cannot create instance using mcOrgId: "' + mcOrgId + '"', 4);
return null;
}
mcOrgId = SL.replace(mcOrgId);
SL.notify(
'Visitor ID: Create instance using mcOrgId: "' + mcOrgId + '"', 1);
initVars = this.parseValues(initVars);
var instance = Visitor.getInstance(mcOrgId, initVars);
SL.notify('Visitor ID: Set variables: ' + SL.stringify(initVars), 1);
return instance;
},
applyCustomerIDs: function(instance, ids) {
var parsedIds = this.parseIds(ids);
instance.setCustomerIDs(parsedIds);
SL.notify('Visitor ID: Set Customer IDs: ' + SL.stringify(parsedIds), 1);
},
parseValues: function(hash) {
if (SL.isObject(hash) === false) {
return {};
}
var obj = {};
for (var v in hash) {
if (hash.hasOwnProperty(v)) {
obj[v] = SL.replace(hash[v]);
}
}
return obj;
},
parseIds: function(hash) {
var parsedIds = {};
if (SL.isObject(hash) === false) {
return {};
}
for (var v in hash) {
if (hash.hasOwnProperty(v)) {
var id = SL.replace(hash[v]['id']);
// All IDs should be data elements. If no replacement has taken place,
// then we can conclude that the data element doesn't exists.
// Also we should ignore existing data elements that are empty.
if (id !== hash[v]['id'] && id) {
parsedIds[v] = {};
parsedIds[v]['id'] = id;
parsedIds[v]['authState'] = Visitor.AuthState[hash[v]['authState']];
}
}
}
return parsedIds;
}
});
SL.availableTools.visitor_id = VisitorIdTool;
// Basic Tool
// ------------
//
// This is a generic tool that allows integrating with
// various simple tools.
//
function BasicTool(settings){
SL.BaseTool.call(this, settings)
this.name = settings.name || 'Basic'
}
SL.inherit(BasicTool, SL.BaseTool)
SL.extend(BasicTool.prototype, {
initialize: function(){
var settings = this.settings
if (this.settings.initTool !== false){
var url = settings.url
if (typeof url === 'string'){
url = SL.basePath() + url
}else{
url = SL.isHttps() ? url.https : url.http
}
SL.loadScript(url, SL.bind(this.onLoad, this))
this.initializing = true
}else{
this.initialized = true
}
},
isQueueAvailable: function(){
return !this.initialized
},
onLoad: function(){
this.initialized = true
this.initializing = false
if (this.settings.initialBeacon){
this.settings.initialBeacon()
}
this.flushQueue()
},
endPLPhase: function(pageLoadEvent){
var loadOn = this.settings.loadOn
if (pageLoadEvent === loadOn){
SL.notify(this.name + ': Initializing at ' + pageLoadEvent, 1)
this.initialize()
}
},
$fire: function(elm, evt, fun){
if (this.initializing){
this.queueCommand({
command: 'fire',
arguments: [fun]
}, elm, evt)
return
}
fun.call(this.settings, elm, evt)
}
})
SL.availableTools.am = BasicTool
SL.availableTools.adlens = BasicTool
SL.availableTools.aem = BasicTool
SL.availableTools.__basic = BasicTool
// The Adobe Target Tool
// ==================
//
// This tool interacts with [Adobe Target library](https://git.corp.adobe.com/mc-visitor/VisitorAPI).
//
// The tool accepts the following settings:
//
// - `engine` - The engine identifier (tnt)
// - `mboxURL` - The URL where the mbox can be found
// - `loadSync` - Specifies how the mbox should be loaded. A true value means
// that it should be loaded in a synchronous mode.
// - `pageParams` - Object containing key/value pairs used in the mbox retrieval
// call. The pairs are merged onto the `targetPageParams` property of
// Target Javascript library. For more information click
// [here](https://marketing.adobe.com/resources/help/en_US/target/target/c_pass_parameters_to_global_mbox.html).
function Tnt(settings){
SL.BaseTool.call(this, settings)
this.styleElements = {}
this.targetPageParamsStore = {}
}
SL.inherit(Tnt, SL.BaseTool)
SL.extend(Tnt.prototype, {
// Public
// ------------------------------------------------
name: 'tnt',
// `endPLPhase()`
// ------------------------------------------------
//
// Method that starts the tool initialization when the page load phase is
// matched and only if the tool initialization has not been previously
// cancelled.
//
// When the tool is initialized the global `targetPageParams` are updated with
// the parameters provided in the settings.
//
// It is important to know that the `targetPageParams` property is not
// overwritten instead a merging process is taking place. If a key is already
// present then its value is updated.
//
// The last step is the loading of the mbox where the `mboxURL` is used.
endPLPhase: function(pageLoadEvent) {
if (pageLoadEvent === 'aftertoolinit') {
this.initialize();
}
},
// Private
// ------------------------------------------------
initialize: function() {
SL.notify('Test & Target: Initializing', 1)
this.initializeTargetPageParams()
this.load()
},
initializeTargetPageParams: function() {
if (window.targetPageParams) {
this.updateTargetPageParams(
this.parseTargetPageParamsResult(
window.targetPageParams()
)
)
}
this.updateTargetPageParams(this.settings.pageParams)
this.setTargetPageParamsFunction()
},
load: function(){
var url = this.getMboxURL(this.settings.mboxURL)
if (this.settings.initTool !== false){
if (this.settings.loadSync) {
SL.loadScriptSync(url)
this.onScriptLoaded()
} else {
SL.loadScript(url, SL.bind(this.onScriptLoaded, this))
this.initializing = true
}
} else {
this.initialized = true
}
},
getMboxURL: function(urlData) {
var url = urlData
if (SL.isObject(urlData)) {
if (window.location.protocol === 'https:')
url = urlData.https
else
url = urlData.http
}
if (!url.match(/^https?:/))
return SL.basePath() + url
else
return url
},
onScriptLoaded: function(){
SL.notify('Test & Target: loaded.', 1)
this.flushQueue()
this.initialized = true
this.initializing = false
},
$addMbox: function(elm, evt, settings){
var mboxGoesAround = settings.mboxGoesAround
var styleText = mboxGoesAround + '{visibility: hidden;}'
var styleElm = this.appendStyle(styleText)
if (!(mboxGoesAround in this.styleElements)){
this.styleElements[mboxGoesAround] = styleElm
}
if (this.initialized){
this.$addMBoxStep2(null, null, settings)
}else if (this.initializing){
this.queueCommand({
command: 'addMBoxStep2'
, "arguments": [settings]
}, elm, evt)
}
},
$addMBoxStep2: function(elm, evt, settings){
var mboxID = this.generateID()
var self = this
SL.addEventHandler(window, 'load', SL.bind(function(){
SL.cssQuery(settings.mboxGoesAround, function(elms){
var elem = elms[0]
if (!elem) return
var newDiv = document.createElement("div")
newDiv.id = mboxID
elem.parentNode.replaceChild(newDiv, elem)
newDiv.appendChild(elem)
window.mboxDefine(mboxID, settings.mboxName)
var args = [settings.mboxName]
if (settings.arguments){
args = args.concat(settings.arguments)
}
window.mboxUpdate.apply(null, args)
self.reappearWhenCallComesBack(elem, mboxID, settings.timeout, settings)
});
}, this))
this.lastMboxID = mboxID // leave this here for easier testing
},
$addTargetPageParams: function(elm, evt, pageParams) {
this.updateTargetPageParams(pageParams)
},
generateID: function(){
var id = '_sdsat_mbox_' + String(Math.random()).substring(2) + '_'
return id
},
appendStyle: function(css){
var head = document.getElementsByTagName('head')[0],
style = document.createElement('style');
style.type = 'text/css';
if(style.styleSheet){
style.styleSheet.cssText = css;
} else {
style.appendChild(document.createTextNode(css));
}
head.appendChild(style);
return style;
},
reappearWhenCallComesBack: function(elmGoesAround, mboxID, timeout, settings){
var self = this
function reappear(){
var styleElm = self.styleElements[settings.mboxGoesAround]
if (styleElm){
styleElm.parentNode.removeChild(styleElm)
;delete self.styleElements[settings.mboxGoesAround]
}
}
SL.cssQuery('script[src*="omtrdc.net"]', function(results){
var script = results[0]
if (script){
SL.scriptOnLoad(script.src, script, function(){
SL.notify('Test & Target: request complete', 1)
reappear()
clearTimeout(timeoutID)
})
var timeoutID = setTimeout(function(){
SL.notify('Test & Target: bailing after ' + timeout + 'ms', 1)
reappear()
}, timeout)
}else{
SL.notify('Test & Target: failed to find T&T ajax call, bailing', 1)
reappear()
}
})
},
updateTargetPageParams: function(obj) {
var o = {}
for (var key in obj) {
if (obj.hasOwnProperty(key)) {
o[SL.replace(key)] = SL.replace(obj[key])
}
}
SL.extend(
this.targetPageParamsStore,
o
)
},
getTargetPageParams: function() {
return this.targetPageParamsStore
},
setTargetPageParamsFunction: function() {
window.targetPageParams = SL.bind(this.getTargetPageParams, this)
},
parseTargetPageParamsResult: function(data) {
var result = data
if(SL.isArray(data)) {
data = data.join('&')
}
if (SL.isString(data)) {
result = SL.parseQueryParams(data)
}
return result
}
})
SL.availableTools.tnt = Tnt
var GAUtils = {
allowLinker: function() {
return SL.hasMultipleDomains();
},
cookieDomain: function() {
var domainList = SL.settings.domainList;
var domainName = SL.find(domainList, function(domain) {
var hostname = window.location.hostname;
return SL.equalsIgnoreCase(
hostname.slice(hostname.length - domain.length),
domain);
});
var cookieDomain = domainName ? ('.' + domainName) : 'auto';
return cookieDomain;
}
};
// The Google Analytics Universal Tool
// ================
//
// This tool interacts with the [GAU library](https://developers.google.com/analytics/devguides/collection/analyticsjs/).
//
// From a high end perspective the following steps will happen. A `ga` dummy
// object will be initialized. Until the `analytics.js` file will be loaded in
// the browser, any triggered command will be queued in the `ga` object. Once
// the `analytics.js` will finish to load, all the queued commands will be
// executed.
//
// The tool is initialized during one of the following page load phases:
// top, bottom. Find out more info about the initializing sequence by clicking
// [here](#-endplphase-).
//
// Data elements are replaced when the tracker is created and on the commands
// from `initCommands` array. For the other situations, the data elements are
// replaced in the `triggerCommand` method from BaseTool.
//
// Beside the settings that are processed by the BaseTool code, this tool uses
// the following extra settings:
//
// - `engine` - The engine identifier (ga_universal)
// - `loadOn` - The PL phase when this tool will be initialized (top | bottom)
// - `url` - Custom URL of the `analytics.js` URL location. If none is provided
// the Google default URL will be used.
// - `initTool` - Boolean flag that can suppress the tool initialization phase.
// When set to `false` no JS library will be loaded and no initial command
// will be executed. All the later commands triggered by this tool will
// piggy back on any availble `ga` function from the page.
// - `trackerSettings` - Object containing properties that will be added on the
// command that will create the GAU tracker. For a list of all supported
// properties please click [here](https://developers.google.com/analytics/devguides/collection/analyticsjs/field-reference#create)
// - `initCommands` - It's an array containing commands. A command example:
// `["set", "anonymizeIp", true]`. For a list of all supported commands
// please click [here](https://developers.google.com/analytics/devguides/collection/analyticsjs/method-reference#tracker)
// The commands defined here will be executed after the tracker is created.
// - `allowLinker` - Flag that will make the GAU library load the cross domain
// linking plugin.
// - `customInit` - JS code that will be executed immediately after the tool is
// initialized. The boolean result from `customInit` will affect the
// initial page view call.
function GAUniversalTool(settings) {
SL.BaseTool.call(this, settings)
}
SL.inherit(GAUniversalTool, SL.BaseTool);
SL.extend(GAUniversalTool.prototype, {
// Public
// ------------------------------------------------
name: 'GAUniversal',
// `endPLPhase()`
// ------------------------------------------------
//
// Method that starts the tool initialization when the page load phase is
// matched and only if the tool initialization has not been previously
// cancelled. Find out more info about the initializing sequence by clicking
// [here](#-initialize-).
//
// After the tool is initialized a page view call is triggered if
// `suppressInitialPageView` flag is not set to `true`.
endPLPhase: function(pageLoadEvent) {
var settings = this.settings;
var loadOn = settings.loadOn;
if (pageLoadEvent === loadOn) {
SL.notify('GAU: Initializing at ' + pageLoadEvent, 1);
this.initialize();
this.flushQueue();
this.trackInitialPageView();
}
},
// `getTrackerName()`
// ------------------------------------------------
//
// Returns the name of the GA tracker initialized by this tool.
getTrackerName: function () {
return this.settings.trackerSettings.name || '';
},
// Private
// ------------------------------------------------
isPageCodeLoadSuppressed: function() {
return this.settings.initTool === false || this._cancelToolInit === true;
},
// `initialize()`
// ------------------------------------------------
//
// The method first creates the GA scaffolding objects (the `ga` object and
// the `GoogleAnalyticsObject` object.
//
// Then it loads the `analytics.js` library and append the command that will
// create the GAU tracker object to the `ga` object.
//
// Next, the commands from the `initCommands` array will be appended to
// the `ga` object. Finally the JS code defined in the `customInit` setting
// variable will be called.
initialize: function() {
if (this.isPageCodeLoadSuppressed()) {
this.initialized = true;
SL.notify('GAU: Page code not loaded (suppressed).', 1);
return;
}
var gaName = 'ga';
window[gaName] = window[gaName] || this.createGAObject();
window.GoogleAnalyticsObject = gaName;
SL.notify('GAU: Page code loaded.', 1);
SL.loadScriptOnce(this.getToolUrl());
var settings = this.settings;
if (GAUtils.allowLinker() && settings.allowLinker !== false) {
this.createAccountForLinker();
} else {
this.createAccount();
}
this.executeInitCommands();
if (settings.customInit){
var customInit = settings.customInit
var result = customInit(window[gaName], this.getTrackerName())
if (result === false){
this.suppressInitialPageView = true;
}
}
this.initialized = true;
},
createGAObject: function() {
var ga = function() {
ga.q.push(arguments);
};
ga.q = [];
ga.l = 1 * new Date();
return ga;
},
createAccount: function() {
this.create();
},
createAccountForLinker: function() {
var options = {};
if (GAUtils.allowLinker())
options.allowLinker = true;
this.create(options);
this.call('require', 'linker');
this.call('linker:autoLink', this.autoLinkDomains(), false, true);
},
create: function(extra){
var options = this.settings.trackerSettings;
options =
SL.preprocessArguments([options], location, null, this.forceLowerCase)[0];
options.trackingId =
SL.replace(this.settings.trackerSettings.trackingId, location);
if (!options.cookieDomain) {
options.cookieDomain = GAUtils.cookieDomain();
}
SL.extend(options, extra || {});
this.call('create', options);
},
autoLinkDomains: function() {
var ourDomain = location.hostname;
return SL.filter(SL.settings.domainList, function(domain) {
return domain !== ourDomain;
});
},
executeInitCommands: function() {
var settings = this.settings;
if (settings.initCommands) {
SL.each(settings.initCommands, function(command) {
var args = command.splice(2, command.length - 2);
command = command.concat(
SL.preprocessArguments(args, location, null, this.forceLowerCase)
);
this.call.apply(this, command);
}, this);
}
},
trackInitialPageView: function(){
if (this.suppressInitialPageView || this.isPageCodeLoadSuppressed()) {
return;
}
this.call('send', 'pageview');
},
call: function() {
if (typeof ga !== 'function') {
SL.notify('GA Universal function not found!', 4);
return;
}
if (this.isCallSuppressed()) {
return;
}
arguments[0] = this.cmd(arguments[0]);
this.log(SL.toArray(arguments));
ga.apply(window, arguments);
},
isCallSuppressed: function() {
return this._cancelToolInit === true;
},
$missing$: function(command, elm, evt, args) {
args = args || [];
args = [command].concat(args);
this.call.apply(this, args);
},
getToolUrl: function() {
var settings = this.settings;
var isHttps = SL.isHttps();
if (settings.url) {
return isHttps ? settings.url.https : settings.url.http;
}
return (isHttps ? 'https://ssl' : 'http://www') + '.google-analytics.com/analytics.js';
},
cmd: function(command) {
var trackerCommands = ['send', 'set', 'get'];
var trackerName = this.getTrackerName();
if (!trackerName || SL.indexOf(trackerCommands, command) === -1) {
return command;
}
return trackerName + '.' + command;
},
log: function(args) {
var cmd = args[0];
var tracker = this.getTrackerName() || 'default';
var msg = 'GA Universal: sent command ' + cmd + ' to tracker ' + tracker;
if (args.length > 1) {
var parameters = SL.stringify(args.slice(1));
msg += ' with parameters ' + SL.stringify(args.slice(1));
}
msg += '.';
SL.notify(msg, 1);
}
});
SL.availableTools.ga_universal = GAUniversalTool;
// Google Analytics Tool
// ---------------------
//
// The GATool allows you to use any Google Analytics command.
// Example:
//
// trigger: [
// {
// tool: "ga",
// command: "trackEvent",
// arguments: [
// "video",
// "video 10% complete"
// ]
// }
// ]
//
// This trigger will call the `trackEvent` method, which is equivalent to
//
// _gaq.push(['_trackEvent', 'video', 'video 10% complete'])
function GATool(settings){
SL.BaseTool.call(this, settings)
}
SL.inherit(GATool, SL.BaseTool)
SL.extend(GATool.prototype, {
name: 'GA',
initialize: function(){
var settings = this.settings
var before = window._gaq
, initCommands = settings.initCommands || []
, customInit = settings.customInit
if (!before){
// And yes, I *do* mean to set a global variable
// of `_gaq` here
_gaq = []
}
if (!this.isSuppressed()){
if (!before && !GATool.scriptLoaded){
var https = SL.isHttps()
var url =
(https ? 'https://ssl' : 'http://www') +
'.google-analytics.com/ga.js'
if (settings.url){
url = https ? settings.url.https : settings.url.http
}
SL.loadScript(url)
GATool.scriptLoaded = true
SL.notify('GA: page code loaded.', 1)
}
var domain = settings.domain
, trackerName = settings.trackerName
, allowLinker = GAUtils.allowLinker()
, account = SL.replace(settings.account, location)
, domainList = SL.settings.domainList || []
_gaq.push([this.cmd('setAccount'), account])
if (allowLinker)
_gaq.push([this.cmd('setAllowLinker'), allowLinker])
_gaq.push([this.cmd('setDomainName'), GAUtils.cookieDomain()])
SL.each(initCommands, function(cmd){
var arr = [this.cmd(cmd[0])].concat(SL.preprocessArguments(cmd.slice(1), location, null, this.forceLowerCase))
_gaq.push(arr)
}, this)
if (customInit)
this.suppressInitialPageView = false === customInit(_gaq, trackerName)
if (settings.pageName)
this.$overrideInitialPageView(null, null, settings.pageName)
}else{
SL.notify('GA: page code not loaded(suppressed).', 1)
}
this.initialized = true
SL.fireEvent(this.id + '.configure', _gaq, trackerName)
},
isSuppressed: function(){
return this._cancelToolInit || this.settings.initTool === false
},
tracker: function(){
return this.settings.trackerName
},
cmd: function(cmd){
var tracker = this.tracker()
return tracker ? tracker + '._' + cmd : '_' + cmd
},
$overrideInitialPageView: function(elm, evt, url){
this.urlOverride = url
},
trackInitialPageView: function(){
if (this.isSuppressed()) return
if (this.suppressInitialPageView) return
if (this.urlOverride){
var args = SL.preprocessArguments([this.urlOverride], location, null, this.forceLowerCase)
this.$missing$('trackPageview', null, null, args)
}else{
this.$missing$('trackPageview')
}
},
endPLPhase: function(pageLoadEvent){
var loadOn = this.settings.loadOn
if (pageLoadEvent === loadOn){
SL.notify('GA: Initializing at ' + pageLoadEvent, 1)
this.initialize()
this.flushQueue()
this.trackInitialPageView()
}
},
call: function(cmd, elm, evt, args){
if (this._cancelToolInit) return
var settings = this.settings
, tracker = this.tracker()
, fullCmd = this.cmd(cmd)
, args = args ? [fullCmd].concat(args) : [fullCmd]
_gaq.push(args)
if (tracker)
SL.notify("GA: sent command " + cmd + " to tracker " + tracker +
(args.length > 1 ?
" with parameters [" + args.slice(1).join(', ') + "]" :
'') + ".", 1)
else
SL.notify("GA: sent command " + cmd +
(args.length > 1 ?
" with parameters [" + args.slice(1).join(', ') + "]":
'') + ".", 1)
},
$missing$: function(cmd, elm, evt, args){
this.call(cmd, elm, evt, args)
},
// individual command methods
$postTransaction: function(elm, evt, varname){
var trans = SL.data.customVars.transaction = window[varname]
this.call('addTrans', elm, evt, [
trans.orderID,
trans.affiliation,
trans.total,
trans.tax,
trans.shipping,
trans.city,
trans.state,
trans.country
])
SL.each(trans.items, function(item){
this.call('addItem', elm, evt, [
item.orderID,
item.sku,
item.product,
item.category,
item.unitPrice,
item.quantity
])
}, this)
this.call('trackTrans', elm, evt)
},
delayLink: function(elm, evt){
var ga = this
if (!GAUtils.allowLinker()) return
if (!elm.hostname.match(this.settings.linkerDomains)) return
if (SL.isSubdomainOf(elm.hostname, location.hostname)) return
SL.preventDefault(evt)
var linkDelay = SL.settings.linkDelay || 100
setTimeout(function(){
ga.call('link', elm, evt, [elm.href])
}, linkDelay)
},
popupLink: function(elm, evt){
if (!window._gat) return
SL.preventDefault(evt)
var account = this.settings.account
var tracker = window._gat._createTracker(account)
var url = tracker._getLinkerUrl(elm.href)
window.open(url)
},
$link: function(elm, evt){
if (elm.getAttribute('target') === '_blank'){
this.popupLink(elm, evt)
}else{
this.delayLink(elm, evt)
}
},
$trackEvent: function(elm, evt){
var args = Array.prototype.slice.call(arguments, 2)
if (args.length >= 4 && args[3] != null){
// acertain that the 4th element is a number, falling back to 1
var value = parseInt(args[3], 10)
if (SL.isNaN(value)){
value = 1
}
args[3] = value
}
this.call('trackEvent', elm, evt, args)
}
})
SL.availableTools.ga = GATool
// Adobe Analytics Tool
// ================
//
// This tool interacts with the [AppMeasurement library](http://microsite.omniture.com/t2/help/en_US/sc/appmeasurement/release/c_release_notes_mjs.html)
//
// Beside the settings that are processed by the BaseTool code, this tool uses
// the following extra settings:
//
// - `engine` - The engine identifier (sc)
// - `initVars` - It's an array containing key/value pair of AppMeasurement's
// properties that are used in tracking and for settings. An example of
// such pair would be: `{ eVar6: "6", server: "tracking.server"}`. For a
// list of all supported properties please consult the [AppMeasurement's
// documentation](http://microsite.omniture.com/t2/help/en_US/sc/implement/sc_variables.html).
// - `initTool` - Boolean flag that can suppress the tool initialization phase.
// When set to `false` no JS library will be loaded and no initial command
// will be executed. All the later commands triggered by this tool will
// piggy back on any availble `ga` function from the page.
// - `sCodeURL` - Custom URL of the AppMeasurement Javascript library URL
// location.
// - `loadOn` - The PL phase when this tool will be initialized (top | bottom)
// - `account` - String containing the report suite ID to track to.
// - `skipSetAccount` - Boolean value that when true disables setting
// of the `account` with the value provided in settings. Default value
// is no being set.
// - `euCookie' - Please see the description on SL (core.js) code
// - `renameS` - String specifying the name of the global AppMeasurement
// instance. If no provided `s` is implied.
// - `executeCustomPageCodeFirst` - Boolean flag that lets the custom
// initialization code be executed before or after the `initVars` method
// call. Default value is not set which means false.
// - `customInit` - JS code that will be executed immediately after the tool is
// initialized. The boolean result from `customInit` will affect the
// initial page view call. A false value results in disabling the initial
// page view tracking call.
//
// The SiteCatalystTool allows to set variables, add events, track link, etc.
// Example:
//
// trigger: [
// {
// tool: "sc",
// command: "trackLink"
// }
// ]
//
function SiteCatalystTool(settings){
SL.BaseTool.call(this, settings)
this.varBindings = {}
this.events = []
this.products = []
this.customSetupFuns = []
}
SL.inherit(SiteCatalystTool, SL.BaseTool)
SL.extend(SiteCatalystTool.prototype, {
// Public
// ------------------------------------------------
name: 'SC',
// `endPLPhase()`
// ------------------------------------------------
//
// Method that starts the tool initialization when the page load phase is
// matched and only if the tool initialization has not been previously
// cancelled. Find out more info about the initializing sequence by clicking
// [here](#-initialize-).
//
// After the tool is initialized a page view call is triggered if
// `suppressInitialPageView` flag is not set to `true`.
endPLPhase: function(pageLoadEvent){
var loadOn = this.settings.loadOn
if (pageLoadEvent === loadOn){
this.initialize(pageLoadEvent)
}
},
// Private
// ------------------------------------------------
// `initialize()`
// ------------------------------------------------
//
// The method first check to see if the default initialization is specifically
// canceled.
//
// Then it sets an event listener on `pageLoadeEvent` to update the tracking
// variables with the ones provided in `initVars` setting object.
//
// In case that the user chosen to provide the Javascript code for
// AppMeasurement by himself instead of using the automatic management
// then we wait for the library to load.
//
// Otherwise we load the AppMeasurement from the storage and then set the
// setup variables on the tracker object.
initialize: function(pageLoadEvent){
if (this._cancelToolInit) return
this.settings.initVars = this.substituteVariables(
this.settings.initVars, { type: pageLoadEvent }
)
if (this.settings.initTool !== false){
var url = this.settings.sCodeURL || SL.basePath() + 's_code.js'
if (typeof url === 'object'){
if (window.location.protocol === 'https:')
url = url.https
else
url = url.http
}
if (!url.match(/^https?:/))
url = SL.basePath() + url
if (this.settings.initVars){
this.$setVars(null, null, this.settings.initVars)
}
SL.loadScript(url, SL.bind(this.onSCodeLoaded, this))
this.initializing = true
}else{
// Set to initializing because we are
// waiting on the AppMeasurement/s_code library to be loaded by
// the site and we'll detect the completion of the load
// in a background task.
this.initializing = true
this.pollForSC()
}
},
// `getS(s, options)`
// ------------------------------------------------
//
// The method initializes the `s` object.
//
// A notificaiton is given and `null` is returned in case of not finding
// the account/RSID.
//
// If Marketing Cloud Visitor ID Service is used that instance is linked
// with the instatiated `s` object.
getS: function(s, options){
var hostname = options && options.hostname || window.location.hostname
var varBindings = this.concatWithToolVarBindings(
options && options.setVars || this.varBindings
)
var events = options && options.addEvent || this.events
var acct = this.getAccount(hostname)
var s_gi = window.s_gi
if (!s_gi) return null
if (!this.isValidSCInstance(s)) s = null
if (!acct && !s) {
SL.notify('Adobe Analytics: tracker not initialized because account was not found', 1)
return null
}
var s = s || s_gi(acct)
var DTMversion = 'D' + SL.appVersion;
if(typeof s.tagContainerMarker !== 'undefined') {
s.tagContainerMarker = DTMversion
} else {
if (typeof s.version === 'string' &&
s.version.substring(s.version.length - 5) !==
('-' + DTMversion)){
s.version += '-' + DTMversion
}
}
if (s.sa && this.settings.skipSetAccount !== true && this.settings.initTool !== false) s.sa(this.settings.account)
this.applyVarBindingsOnTracker(s, varBindings)
if (events.length > 0)
s.events = events.join(',')
var visitorIdInstance = SL.getVisitorId()
if (visitorIdInstance) {
s.visitor = SL.getVisitorId()
}
return s
},
// `onSCodeLoaded()`
// ------------------------------------------------
//
// The method triggers load event on Analytics tool so all subsequent and
// listening methods would be properly triggered.
//
// Before cleaning up the queue the tracking beacon call is made.
onSCodeLoaded: function(loaded_manually){
this.initialized = true
this.initializing = false
var msg = [
'Adobe Analytics: loaded',
loaded_manually ? ' (manual)' : '',
'.'
]
SL.notify(msg.join(''), 1)
SL.fireEvent(this.id + '.load', this.getS())
if (!loaded_manually) {
this.flushQueueExceptTrackLink()
this.sendBeacon()
}
this.flushQueue()
},
// `getAccount(hostname)`
// ------------------------------------------------
//
// The returns the `s_account` for a specified `hostname`
//
// TODO: need to be refactored because `accountByHost` is no longer used.
getAccount: function(hostname){
if (window.s_account){
return window.s_account
}
if (hostname && this.settings.accountByHost){
return this.settings.accountByHost[hostname] || this.settings.account
}else{
return this.settings.account
}
},
// `getTrackingServer()`
// ------------------------------------------------
//
// The method tries to retrieve the tracking server from the `s` object
// otherwise falls back on generating one based on the `account`.
//
// If neither `account` or `trackingServer` are availalble, `null` is
// returned.
//
// TODO: need to be refactored to remove the tracking server generate method
// as Analytics now offers a central point to shoot to.
getTrackingServer: function(){
var tool = this
var s = tool.getS()
if (s) {
if (s.ssl && s.trackingServerSecure) {
return s.trackingServerSecure
}
else if (s.trackingServer) {
return s.trackingServer
}
}
var account = tool.getAccount(window.location.hostname)
if (!account) return null
// Based on code in app measurement.
var w
var c = ''
var d = s && s.dc
var e
var f
w = account
e = w.indexOf(",")
e >= 0 && (w = w.gb(0, e))
w = w.replace(/[^A-Za-z0-9]/g, "")
c || (c = "2o7.net")
d = d ? ("" + d).toLowerCase() : "d1"
c == "2o7.net" && (d == "d1" ? d = "112" : d == "d2" && (d = "122"), f = "")
e = w + "." + d + "." + f + c
return e
},
// `sendBeacon()`
// ------------------------------------------------
//
// The method triggers the tracking call.
//
// If custom initialization is used the beacon is supressed. Also, if custom
// code is provided and specifically stated that it should be executed first
// (`executeCustomPageCodeFirst`) the tracker get updated with the result of
// the code.
sendBeacon: function(){
var s = this.getS(window[this.settings.renameS || 's'])
if (!s){
SL.notify('Adobe Analytics: page code not loaded', 1)
return
}
if (this.settings.customInit){
if (this.settings.customInit(s) === false){
SL.notify("Adobe Analytics: custom init suppressed beacon", 1)
return
}
}
if (this.settings.executeCustomPageCodeFirst) {
this.applyVarBindingsOnTracker(s, this.varBindings)
}
this.executeCustomSetupFuns(s)
s.t()
this.clearVarBindings()
this.clearCustomSetup()
SL.notify("Adobe Analytics: tracked page view", 1)
},
pollForSC: function(){
SL.poll(SL.bind(function(){
if (typeof window.s_gi === 'function'){
this.onSCodeLoaded(true)
return true
}
}, this))
},
flushQueueExceptTrackLink: function(){
// Because we always s.tl() after the first s.t()
// that way the variables set by s.tl() will not
// contaminate the s.t() call.
if (!this.pending) return
var left = []
for (var i = 0; i < this.pending.length; i++){
var args = this.pending[i]
var trig = args[0]
if (trig.command === 'trackLink'){
left.push(args)
}else{
this.triggerCommand.apply(this, args)
}
}
this.pending = left
},
isQueueAvailable: function(){
return !this.initialized
},
substituteVariables: function(obj, evt){
var ret = {}
for (var key in obj){
if (obj.hasOwnProperty(key)) {
var value = obj[key]
ret[key] = SL.replace(value, location, evt)
}
}
return ret
},
$setVars: function(elm, evt, vars){
for (var v in vars){
if (vars.hasOwnProperty(v)) {
var val = vars[v]
if (typeof val === 'function')
val = val()
this.varBindings[v] = val
}
}
SL.notify('Adobe Analytics: set variables.', 2)
},
$customSetup: function(elm, evt, setup){
this.customSetupFuns.push(function(s){
setup.call(elm, evt, s)
})
},
isValidSCInstance: function(s) {
return !!s && typeof s.t === 'function' && typeof s.tl === 'function'
},
concatWithToolVarBindings: function(varBindings){
var settingsInitVars = this.settings.initVars || {}
SL.map(['trackingServer', 'trackingServerSecure'], function (item) {
if (settingsInitVars[item] && !varBindings[item]) {
varBindings[item] = settingsInitVars[item]
}
});
return varBindings
},
applyVarBindingsOnTracker: function (s, varBindings) {
for (var v in varBindings){
if (varBindings.hasOwnProperty(v)) {
s[v] = varBindings[v]
}
}
},
clearVarBindings: function(){
this.varBindings = {}
},
clearCustomSetup: function(){
this.customSetupFuns = []
},
executeCustomSetupFuns: function(s){
SL.each(this.customSetupFuns, function(fun){
fun.call(window, s)
})
},
$trackLink: function(elm, evt, params){
params = params || {}
var type = params.type
var linkName = params.linkName
if (!linkName &&
elm &&
elm.nodeName &&
elm.nodeName.toLowerCase() === 'a'){
linkName = elm.innerHTML
}
if (!linkName){
linkName = 'link clicked'
}
var vars = params && params.setVars
var events = (params && params.addEvent) || []
var s = this.getS(null, {
setVars: vars,
addEvent: events
})
if (!s){
SL.notify('Adobe Analytics: page code not loaded', 1)
return
}
var orgLinkTrackVars = s.linkTrackVars
var orgLinkTrackEvents = s.linkTrackEvents
var definedVarNames = this.definedVarNames(vars)
if (params && params.customSetup){
params.customSetup.call(elm, evt, s)
}
if (events.length > 0)
definedVarNames.push('events')
if (s.products)
definedVarNames.push('products')
// add back the vars from s
definedVarNames = this.mergeTrackLinkVars(s.linkTrackVars, definedVarNames)
// add back events from s
events = this.mergeTrackLinkVars(s.linkTrackEvents, events)
s.linkTrackVars = this.getCustomLinkVarsList(definedVarNames)
var eventsKeys = SL.map(events, function(item) {
return item.split(':')[0]
});
s.linkTrackEvents = this.getCustomLinkVarsList(eventsKeys)
s.tl(true, type || 'o', linkName)
SL.notify([
'Adobe Analytics: tracked link ',
'using: linkTrackVars=',
SL.stringify(s.linkTrackVars),
'; linkTrackEvents=',
SL.stringify(s.linkTrackEvents)
].join(''), 1)
s.linkTrackVars = orgLinkTrackVars
s.linkTrackEvents = orgLinkTrackEvents
},
mergeTrackLinkVars: function(newVarsStr, varsArr){
if (newVarsStr) {
varsArr = newVarsStr.split(',').concat(varsArr)
}
return varsArr
},
getCustomLinkVarsList: function (keysArr) {
var noneIndex = SL.indexOf(keysArr, 'None');
if (noneIndex > -1 && keysArr.length > 1) {
keysArr.splice(noneIndex, 1)
}
return keysArr.join(',');
},
definedVarNames: function(vars){
vars = vars || this.varBindings
var ret = []
for (var varname in vars){
if (vars.hasOwnProperty(varname) && /^(eVar[0-9]+)|(prop[0-9]+)|(hier[0-9]+)|campaign|purchaseID|channel|server|state|zip|pageType$/.test(varname))
ret.push(varname)
}
return ret
},
$trackPageView: function(elm, evt, params){
var vars = params && params.setVars
var events = (params && params.addEvent) || []
var s = this.getS(null, {
setVars: vars,
addEvent: events
})
if (!s){
SL.notify('Adobe Analytics: page code not loaded', 1)
return
}
s.linkTrackVars = ''
s.linkTrackEvents = ''
this.executeCustomSetupFuns(s)
if (params && params.customSetup){
params.customSetup.call(elm, evt, s)
}
s.t()
this.clearVarBindings()
this.clearCustomSetup()
SL.notify("Adobe Analytics: tracked page view", 1)
},
$postTransaction: function(elm, evt, varname){
var trans = SL.data.transaction = window[varname]
, s = this.varBindings
, mapping = this.settings.fieldVarMapping
SL.each(trans.items, function(item){
this.products.push(item)
}, this)
s.products = SL.map(this.products, function(item){
var vars = []
if (mapping && mapping.item){
for (var field in mapping.item){
if (mapping.item.hasOwnProperty(field)) {
var varname = mapping.item[field]
vars.push(varname + '=' + item[field])
if (varname.substring(0, 5) === 'event')
this.events.push(varname)
}
}
}
var arr = ['', item.product, item.quantity, item.unitPrice * item.quantity]
if (vars.length > 0)
arr.push(vars.join('|'))
return arr.join(';')
}, this).join(',')
if (mapping && mapping.transaction){
// Add top-level events/eVars to products string.
var topLevelVars = []
for (var field in mapping.transaction){
if (mapping.transaction.hasOwnProperty(field)) {
var varname = mapping.transaction[field]
topLevelVars.push(varname + '=' + trans[field])
if (varname.substring(0, 5) === 'event')
this.events.push(varname)
}
}
if (s.products.length > 0)
s.products += ','
s.products += ';;;;' + topLevelVars.join('|')
}
},
$addEvent: function(elm, evt){
for (var i = 2, len = arguments.length; i < len; i++){
this.events.push(arguments[i])
}
},
$addProduct: function(elm, evt){
for (var i = 2, len = arguments.length; i < len; i++){
this.products.push(arguments[i])
}
}
})
SL.availableTools.sc = SiteCatalystTool
// The Default Tool
// ================
//
// The default tool comes with several handy utilities.
function DefaultTool(){
SL.BaseTool.call(this)
this.asyncScriptCallbackQueue = []
this.argsForBlockingScripts = []
}
SL.inherit(DefaultTool, SL.BaseTool)
SL.extend(DefaultTool.prototype, {
name: 'Default',
// `loadIframe(src, variables)`
// ----------------------------
//
// Dynamically create an iframe to load a URL.
//
// - src - the URL to load
// - variables - an object literal of which the key/value pairs will be used
// to create the query string to use in the src URL
$loadIframe: function(elm, evt, options){
var pages = options.pages
, loadOn = options.loadOn
var doit = SL.bind(function(){
SL.each(pages, function(page){
this.loadIframe(elm, evt, page)
}, this)
}, this)
if (!loadOn) doit()
if (loadOn === 'domready') SL.domReady(doit)
if (loadOn === 'load') SL.addEventHandler(window, 'load', doit)
},
loadIframe: function(elm, evt, page){
var iframe = document.createElement('iframe')
iframe.style.display = 'none'
var host = SL.data.host
, data = page.data
, src = this.scriptURL(page.src)
, search = SL.searchVariables(data, elm, evt)
if (host)
src = SL.basePath() + src
src += search
iframe.src = src
var body = document.getElementsByTagName('body')[0]
if (body)
body.appendChild(iframe)
else
SL.domReady(function(){
document.getElementsByTagName('body')[0].appendChild(iframe)
})
},
scriptURL: function(url){
var scriptDir = SL.settings.scriptDir || ''
return scriptDir + url
},
// `loadScript(options)
// ------------------------------
//
// Load any number of Javascript files using dynamically generated script tags.
// If you provide multiple file URLs, they will be loaded sequentially.
$loadScript: function(elm, evt, options){
var scripts = options.scripts
, sequential = options.sequential
, loadOn = options.loadOn
var doit = SL.bind(function(){
if (sequential){
this.loadScripts(elm, evt, scripts)
}else{
SL.each(scripts, function(script){
this.loadScripts(elm, evt, [script])
}, this)
}
}, this)
if (!loadOn) doit()
else if (loadOn === 'domready') SL.domReady(doit)
else if (loadOn === 'load') SL.addEventHandler(window, 'load', doit)
},
loadScripts: function(elm, evt, scripts) {
try{
var scripts = scripts.slice(0)
, q = this.asyncScriptCallbackQueue
, lastScript
, target = evt.target || evt.srcElement
, self = this
}catch(e){
console.error('scripts is', SL.stringify(scripts))
}
function loadNext(){
if (q.length > 0 && lastScript){
var callback = q.shift()
callback.call(elm, evt, target)
}
var script = scripts.shift()
if (script){
var host = SL.data.host
, src = self.scriptURL(script.src)
if (host)
src = SL.basePath() + src
lastScript = script
SL.loadScript(src, loadNext)
}
}
loadNext()
},
$loadBlockingScript: function(elm, evt, options){
var scripts = options.scripts
, loadOn = options.loadOn
var doit = SL.bind(function(){
SL.each(scripts, function(script){
this.loadBlockingScript(elm, evt, script)
}, this)
}, this)
//if (!loadOn || loadOn === evt.type) doit()
doit()
},
loadBlockingScript: function(elm, evt, script){
/*jshint evil:true */
var src = this.scriptURL(script.src)
, host = SL.data.host
, target = evt.target || evt.srcElement
if (host)
src = SL.basePath() + src
this.argsForBlockingScripts.push([elm, evt, target])
SL.loadScriptSync(src)
},
pushAsyncScript: function(callback){
this.asyncScriptCallbackQueue.push(callback)
},
pushBlockingScript: function(callback){
var args = this.argsForBlockingScripts.shift()
var element = args[0]
callback.apply(element, args.slice(1))
},
// `writeHTML(html)`
// -----------------
//
// Write an HTML fragment onto the page using `document.write()`.
//
// - `html` - the HTML fragment
$writeHTML: SL.escapeHtmlParams(function(elm, evt){
/*jshint evil:true */
if (SL.domReadyFired || !document.write){
SL.notify('Command writeHTML failed. You should try appending HTML using the async option.', 1)
return
}
if (evt.type !== 'pagebottom' && evt.type !== 'pagetop'){
SL.notify('You can only use writeHTML on the `pagetop` and `pagebottom` events.', 1)
return
}
for (var i = 2, len = arguments.length; i < len; i++){
var html = arguments[i].html
html = SL.replace(html, elm, evt)
document.write(html)
}
}),
linkNeedsDelayActivate: function(a, win){
win = win || window
var tagName = a.tagName
, target = a.getAttribute('target')
, location = a.getAttribute('href')
if (tagName && tagName.toLowerCase() !== 'a')
return false
if (!location)
return false
else if (!target)
return true
else if (target === '_blank')
return false
else if (target === '_top')
return win.top === win
else if (target === '_parent')
return false
else if (target === '_self')
return true
else if (win.name)
return target === win.name
else
return true
},
// `delayActivateLink()`
// ---------------------
//
// Delay the activation of an anchor link by first using `evt.preventDefault()` on
// the click event, and then setting the window location to the destination after
// a small delay. The default delay is 100 milliseconds, which can be configured in
// `_satellite.settings.linkDelay`
$delayActivateLink: function(elm, evt){
if (!this.linkNeedsDelayActivate(elm)) return
SL.preventDefault(evt)
var linkDelay = SL.settings.linkDelay || 100
setTimeout(function(){
SL.setLocation(elm.href)
}, linkDelay)
},
isQueueable: function(trig){
return trig.command !== 'writeHTML'
}
})
SL.availableTools['default'] = DefaultTool
// The Nielsen Tool
// ================
//
// This tool provides the means to make Nielsen tracking possible.
//
// The tool accepts the following settings:
//
// - `collectionServer` - The collection server to be used. The variable
// specifies the nearest collection server.
// - `clientId` - The client identifier. A unique Nielsen supplied ID that
// should be alphanumeric and lowercase. A dash (-) character is allowed.
// - `contentGroup` - The content group. A historical variable used for
// grouping/aggregating content into channels. Currently the
// default value is "0".
function NielsenTool(settings) {
SL.BaseTool.call(this, settings);
this.defineListeners();
this.beaconMethod = 'plainBeacon';
this.adapt = new NielsenTool.DataAdapters();
this.dataProvider = new NielsenTool.DataProvider.Aggregate();
}
SL.inherit(NielsenTool, SL.BaseTool);
SL.extend(NielsenTool.prototype, {
// Public
// ------------------------------------------------
name: 'Nielsen',
// Private
// ------------------------------------------------
// `endPLPhase()`
// ------------------------------------------------
//
// Method that starts the tool initialization when the page load phase is
// matched and only if the tool initialization has not been previously
// cancelled.
//
// This is needed in order to be able to properly hook the needed events.
endPLPhase: function(pageLoadEvent) {
switch (pageLoadEvent) {
case 'pagetop':
this.initialize();
break;
case 'pagebottom':
if (this.enableTracking) {
this.queueCommand({ command: 'sendFirstBeacon', "arguments": [] });
this.flushQueueWhenReady();
}
break;
}
},
defineListeners: function() {
this.onTabFocus = SL.bind(function() {
this.notify('Tab visible, sending view beacon when ready', 1);
this.tabEverVisible = true;
this.flushQueueWhenReady();
}, this);
this.onPageLeave = SL.bind(function() {
this.notify('isHuman? : '+ this.isHuman(), 1);
if (this.isHuman()) {
this.sendDurationBeacon(); // track page leave
}
}, this);
this.onHumanDetectionChange = SL.bind(function(e) {
if (this == e.target.target) this.human = e.target.isHuman;
}, this);
},
initialize: function() {
this.initializeTracking();
this.initializeDataProviders();
this.initializeNonHumanDetection();
this.tabEverVisible = SL.visibility.isVisible();
if (!this.tabEverVisible) {
SL.bindEventOnce('tabfocus', this.onTabFocus);
}
else {
this.notify('Tab visible, sending view beacon when ready', 1);
}
this.initialized = true;
},
// `initializeTracking()`
// ------------------------------------------------
//
// The method starts the time tracking and hooks on the leave event.
initializeTracking: function() {
if (this.initialized) return;
this.notify('Initializing tracking', 1);
this.addRemovePageLeaveEvent(this.enableTracking);
this.addRemoveHumanDetectionChangeEvent(this.enableTracking);
this.initialized = true;
},
// `initializeDataProviders()`
// ------------------------------------------------
//
// The method initializes default data providers for:
// - Analytics Report Suite ID, if Analytics account is linked
// - Marketing Cloud Visitor ID, with fallback to auto-generated UUID
initializeDataProviders: function() {
var analytics = this.getAnalyticsTool(), rsid;
this.dataProvider.register(
new NielsenTool.DataProvider.VisitorID(
SL.getVisitorId()
)
);
if (analytics) {
rsid = new NielsenTool.DataProvider.Generic('rsid', function() {
return analytics.settings.account;
});
this.dataProvider.register(rsid);
}
else {
this.notify('Missing integration with Analytics: rsid will not be sent.');
}
},
initializeNonHumanDetection: function() {
if (SL.nonhumandetection) {
SL.nonhumandetection.init();
this.setEnableNonHumanDetection(
this.settings.enableNonHumanDetection == false ? false : true);
if (this.settings.nonHumanDetectionDelay > 0) {
this.setNonHumanDetectionDelay(
parseInt(this.settings.nonHumanDetectionDelay) * 1000);
}
} else {
this.notify('NHDM is not available.');
}
},
// `getAnalyticsTool()`
// ------------------------------------------------
//
// If integration is defined, this method returns the tool instance of
// the linked Analytics account
getAnalyticsTool: function() {
if (this.settings.integratesWith) {
return SL.tools[this.settings.integratesWith];
}
},
flushQueueWhenReady: function() {
if (!this.enableTracking || !this.tabEverVisible) return;
SL.poll(SL.bind(function() {
if (this.isReadyToTrack()) {
this.flushQueue();
return true;
}
}, this), 100, 20);
},
isReadyToTrack: function() {
return this.tabEverVisible && this.dataProvider.isReady();
},
// `setVars(vars)`
// ------------------------------------------------
//
// The method is used to set variables on the tool
$setVars: function(elm, evt, vars) {
for (var v in vars) {
var val = vars[v];
if (typeof val === 'function')
val = val();
this.settings[v] = val;
}
this.notify('Set variables done', 2);
this.prepareContextData();
},
// `setEnableTracking()`
// ------------------------------------------------
//
// The method triggers the view tracking call.
$setEnableTracking: function(elm, evt, bool) {
this.notify('Will' + (!bool ? ' not' : '') + ' track time on page', 1);
if (this.enableTracking != bool) {
this.addRemovePageLeaveEvent(bool);
this.addRemoveHumanDetectionChangeEvent(bool);
this.enableTracking = bool;
}
},
// `sendFirstBeacon()`
// ------------------------------------------------
//
// The method is called as soon as everything is in place.
$sendFirstBeacon: function(elm, evt, settings) {
this.sendViewBeacon();
},
// `setEnableNonHumanDetection()`
// ------------------------------------------------
//
// The method enables/disables the human detection mechanism.
setEnableNonHumanDetection: function(bool) {
if (bool) {
SL.nonhumandetection.register(this);
} else {
SL.nonhumandetection.unregister(this);
}
},
// `setNonHumanDetectionDelay()`
// ------------------------------------------------
//
// The method set the timeout for entering in non human state.
setNonHumanDetectionDelay: function(delay) {
SL.nonhumandetection.register(this, delay);
},
addRemovePageLeaveEvent: function(add) {
this.notify((add ? 'Attach onto' : 'Detach from') + ' page leave event', 1);
var method = (add == false ? 'unbindEvent' : 'bindEvent');
SL[method]('leave', this.onPageLeave);
},
addRemoveHumanDetectionChangeEvent: function(add) {
this.notify((add ? 'Attach onto' : 'Detach from') + ' human detection change event', 1);
var method = (add == false ? 'unbindEvent' : 'bindEvent');
SL[method]('humandetection.change', this.onHumanDetectionChange);
},
// `sendViewBeacon()`
// ------------------------------------------------
//
// The method triggers the view tracking call.
sendViewBeacon: function() {
this.notify('Tracked page view.', 1);
this.sendBeaconWith();
},
// `sendDurationBeacon()`
// ------------------------------------------------
//
// The method triggers the duration tracking call. This adds the time
// spent on the page to the call and is triggered when the user leaves
// the current web page.
sendDurationBeacon: function() {
if (
!SL.timetracking ||
typeof SL.timetracking.timeOnPage != 'function' ||
SL.timetracking.timeOnPage() == null
) {
this.notify('Could not track close due missing time on page', 5);
return;
}
this.notify('Tracked close', 1);
this.sendBeaconWith({
timeOnPage: Math.round(SL.timetracking.timeOnPage() / 1000),
duration: 'D',
timer: 'timer'
});
// a bit of delay to let the network thread finish sending data
var i,s='';for(i=0;i<this.magicConst;i++){s+='0'};
},
// `sendBeaconWith(obj)`
// ------------------------------------------------
//
// The method builds the tracking call based on provided settings and
// parameters.
sendBeaconWith: function(params) {
if (this.enableTracking) {
this[this.beaconMethod].call(this, this.prepareUrl(params));
}
},
plainBeacon: function(url) {
var img = new Image();
img.src = url;
img.width = 1;
img.height = 1;
img.alt = '';
},
navigatorSendBeacon: function(url) {
navigator.sendBeacon(url);
},
prepareUrl: function(params) {
var obj = this.settings;
SL.extend(obj, this.dataProvider.provide());
SL.extend(obj, params);
return this.preparePrefix(this.settings.collectionServer) +
this.adapt.convertToURI(
this.adapt.toNielsen(
this.substituteVariables(obj)));
},
preparePrefix: function(server) {
return '//' + encodeURIComponent(server) + '.imrworldwide.com/cgi-bin/gn?';
},
substituteVariables: function(hash){
var obj = {};
for (var v in hash) {
if (hash.hasOwnProperty(v)) {
obj[v] = SL.replace(hash[v]);
}
}
return obj;
},
prepareContextData: function() {
if (!this.getAnalyticsTool()) {
this.notify('Adobe Analytics missing.');
return;
}
var obj = this.settings;
obj.sdkVersion =_satellite.publishDate;
this.getAnalyticsTool().$setVars(null, null, {
contextData: this.adapt.toAnalytics(
this.substituteVariables(obj))
});
},
isHuman: function() {
return this.human;
},
onTabFocus: function() {},
onPageLeave: function() {},
onHumanDetectionChange: function() {},
notify: function(msg, lvl) {
SL.notify(this.logPrefix + msg, lvl);
},
beaconMethod: 'plainBeacon',
adapt: null,
enableTracking: false,
logPrefix: "Nielsen: ",
tabEverVisible: false,
human: true,
magicConst: 0x1e8480
});
// `NielsenTool.DataProvider`
// ==========================
//
// The following components handle the task of providing extra information
// for the Nielsen beacon, with support for asynchronous data
//
NielsenTool.DataProvider = {};
NielsenTool.DataProvider.Generic = function(key, valueFn) {
this.key = key;
this.valueFn = valueFn;
};
SL.extend(NielsenTool.DataProvider.Generic.prototype, {
isReady: function() {
return true;
},
getValue: function() {
return this.valueFn();
},
provide: function() {
if (!this.isReady()) {
NielsenTool.prototype.notify('Not yet ready to provide value for: ' + this.key, 5)
}
var data = {};
data[this.key] = this.getValue();
return data;
}
});
// `NielsenTool.DataProvider.VisitorID`
// ====================================
//
// Gets and optionally waits for Marketing Cloud ID to be loaded.
// If no visitor instance is provided, then it falls-back to generated UUID.
//
NielsenTool.DataProvider.VisitorID = function(visitorInstance, key, fallbackProvider) {
this.key = key || 'uuid';
this.visitorInstance = visitorInstance;
if (this.visitorInstance) {
this.visitorId = visitorInstance.getMarketingCloudVisitorID([this, this._visitorIdCallback]);
}
this.fallbackProvider = fallbackProvider || new NielsenTool.UUID();
};
SL.inherit(NielsenTool.DataProvider.VisitorID, NielsenTool.DataProvider.Generic);
SL.extend(NielsenTool.DataProvider.VisitorID.prototype, {
isReady: function() {
if (this.visitorInstance === null) {
return true;
}
return !!this.visitorId;
},
getValue: function() {
return this.visitorId || this.fallbackProvider.get();
},
_visitorIdCallback: function(id) {
this.visitorId = id;
}
});
// `NielsenTool.DataProvider.Aggregate`
// ====================================
//
// Aggregates data from multiple providers, being aware of their ready-state.
//
NielsenTool.DataProvider.Aggregate = function() {
this.providers = [];
for (var i=0; i<arguments.length; i++) {
this.register(arguments[i]);
}
};
SL.extend(NielsenTool.DataProvider.Aggregate.prototype, {
register: function(provider) {
this.providers.push(provider);
},
isReady: function() {
return SL.every(this.providers, function(provider) {
return provider.isReady();
});
},
provide: function() {
var data = {};
SL.each(this.providers, function(provider) {
SL.extend(data, provider.provide());
});
return data;
}
});
// `UUID`
// ===============
//
// The follwing generates an [RFC 4122 version 4](https://www.ietf.org/rfc/rfc4122.txt)
// uinique ID and stores it in a cookie.
NielsenTool.UUID = function() {};
SL.extend(NielsenTool.UUID.prototype, {
// `generate()`
// ------------------------------------------------
//
// Method that generates an [RFC 4122 version 4](https://www.ietf.org/rfc/rfc4122.txt)
// compliant unique ID.
//
// This is needed in for Nielsen tracking w/o Analytics integration.
generate: function() {
return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function(c) {
var r = Math.random() * 16 | 0,
v = c == 'x' ? r : (r & 0x3 | 0x8);
return v.toString(16);
});
},
get: function() {
var cookieUUID = SL.readCookie(this.key('uuid'));
if (cookieUUID) return cookieUUID;
cookieUUID = this.generate();
SL.setCookie(this.key('uuid'), cookieUUID);
return cookieUUID;
},
key: function(name) {
return '_dtm_nielsen_' + name;
}
});
// `Data Adapters`
// ===============
//
// The follwing adapters are used to adapt the settings to the proper format
// for both Nielsen tracking call and AA tracking calls
NielsenTool.DataAdapters = function() {};
SL.extend(NielsenTool.DataAdapters.prototype, {
toNielsen: function(settings) {
var cdate = new Date().getTime(),
nielsenPrefixes = {
c6: 'vc,',
c13: 'asid,',
c15: 'apn,',
c27: 'cln,',
c32: 'segA,',
c33: 'segB,',
c34: 'segC,',
c35: 'adrsid,',
c29: 'plid,',
c30: 'bldv,',
c40: 'adbid,'
},
nielsenObj = {
ci: settings.clientId,
c6: settings.vcid,
c13: settings.appId,
c15: settings.appName,
prv: 1,
forward: 0,
ad: 0,
cr: settings.duration || 'V', // [V|D], default V
rt: 'text',
st: 'dcr',
prd: 'dcr',
r: cdate,
at: settings.timer || 'view', // [view|timer], default view
c16: settings.sdkVersion,
c27: settings.timeOnPage || 0,
c40: settings.uuid,
c35: settings.rsid,
ti: cdate,
sup: 0,
c32: settings.segmentA,
c33: settings.segmentB,
c34: settings.segmentC,
asn: settings.assetName,
c29: settings.playerID,
c30: settings.buildVersion
};
for (key in nielsenObj) {
if (nielsenObj[key] !== undefined && nielsenObj[key] != null) {
if (nielsenObj[key] !== undefined && nielsenObj != null && nielsenObj != '') {
var val = encodeURIComponent(nielsenObj[key]);
if (nielsenPrefixes.hasOwnProperty(key) && val) {
val = nielsenPrefixes[key] + val;
}
nielsenObj[key] = val;
}
}
}
return this.filterObject(nielsenObj);
},
toAnalytics: function(settings) {
return this.filterObject({
'a.nielsen.clientid': settings.clientId,
'a.nielsen.vcid': settings.vcid,
'a.nielsen.appid': settings.appId,
'a.nielsen.appname': settings.appName,
'a.nielsen.accmethod': "0",
'a.nielsen.ctype': "text",
'a.nielsen.sega': settings.segmentA,
'a.nielsen.segb': settings.segmentB,
'a.nielsen.segc': settings.segmentC,
'a.nielsen.asset': settings.assetName
});
},
convertToURI: function(obj) {
if (SL.isObject(obj) === false) return '';
var uri = []
for (var key in obj) {
if (obj.hasOwnProperty(key)) uri.push(key + '=' + obj[key]);
}
return uri.join('&')
},
filterObject: function(obj) {
for (var k in obj) {
if (obj.hasOwnProperty(k) &&
(obj[k] == null || obj[k] === undefined)) {
delete obj[k];
}
}
return obj;
}
});
SL.availableTools.nielsen = NielsenTool;
_satellite.init({
"tools": {
"21d4da84002970ac77af10cdabc32f20": {
"engine": "sc",
"loadOn": "pagebottom",
"account": "clgbcollegeboardcomprod",
"euCookie": false,
"sCodeURL": "7a8a98de0363fbed05b98da851d6b23866ffa7cc/s-code-contents-55dc9cec4faa6cdfed0976f767868b7bcd08c911.js",
"initVars": {
"charSet": "UTF-8",
"currencyCode": "USD",
"trackingServer": "track.collegeboard.org",
"trackingServerSecure": "strack.collegeboard.org",
"trackInlineStats": true,
"trackDownloadLinks": false,
"trackExternalLinks": false,
"linkLeaveQueryString": false,
"dynamicVariablePrefix": "D="
},
"customInit": function(s){
/* global Visitor, SatReg */
/**
* Configured by jbeach on 2016-07-20
* Updated by jbeach on 2020-07-08
*/
kiwi = window.kiwi || {};
kiwi.util = kiwi.util || _satellite.getVar('Kiwi Utility Functions') || {};
var ruleName='KIWI: Tool > Analytics > Custom JS';
/********************* Global Vars Init SECTION *********************/
//_satellite.notify(ruleName+' > Global Vars Section');
// DDL
digitalData = window.digitalData || {};
digitalData.page = digitalData.page || {};
digitalData.page.pageInfo = digitalData.page.pageInfo || {};
digitalData.page.category = digitalData.page.category || {};
digitalData.page.attributes = digitalData.page.attributes || {};
digitalData.page.attributes.targetModsComplete = digitalData.page.attributes.targetModsComplete || 0;
digitalData.user = digitalData.user || [ {profile: {} } ];
// CB Track Data
cbTrackData = window.cbTrackData || {};
/************************** CONFIGURATIONS SECTION ***************/
//_satellite.notify('KIWI: Tool > Analytics > Custom JS > CONFIGURATIONS SECTION');
s.usePlugins=true;
s.visitor = Visitor.getInstance('5E1B123F5245B29B0A490D45@AdobeOrg');
s.linkDownloadFileTypes='.arf,.avi,.css,.csv,.dmg,.doc,.docx,.dotx,.eps,.exe,.ics,.js,.m4v,.mov,.mp3,.mp4,.mpg,.pages,.pdf,.ppt,.pptx,.rar,.rm,.rtf,.swf,.tab,.txt,.vsd,.vxd,.wav,.wma,.wmv,.xls,.xlsx,.xml,.zip';
s.linkInternalFilters='javascript:,acquia-sites.com,apscore.org,cbapis.org,collegeboard.com,collegeboard.org,springboardonline.com,springboardonline.org';
s.ActionDepthTest=true; // Depth1: Landing Page and Depth2: Second Page Events
/* Time Parting Config */
//time parting configuration
//US
s._tpDST = {
2012:'3/11,11/4',
2013:'3/10,11/3',
2014:'3/9,11/2',
2015:'3/8,11/1',
2016:'3/13,11/6',
2017:'3/12,11/5',
2018:'3/11,11/4',
2019:'3/10,11/3',
2020:'3/8,11/1',
2021:'3/14,11/7',
2022:'3/13,11/6',
2023:'3/12,11/5'};
/* end Time Parting Config */
/** end Configurations Section **/
/*********Media Module Calls**************/
/***** MEDIA MODULE CONFIGURATION FOR MILESTONE TRACKING START*****/
s.loadModule('Media');
s.Media.onLoad = function(s) {
s.Media.autoTrack= false;
/*Track Milestone 10%, 25%, 50%, 75%, 95%
* Delete unwanted milestone if necessary
*/
s.Media.trackMilestones='25,50,75,100'; //10,25,50,75,95
s.Media.playerName='default-video-player-name'; //_satellite.getVar('Video Player Name') || ;
s.Media.segmentByMilestones = true;
s.Media.trackUsingContextData = true;
/* Add reserved context data variables as needed to populate default metrics
* a.media.progress10, a.media.progress25, a.media.progress50 ,a.media.progress75, a.media.progress95
* a.media.friendlyname --> to populate Video Name report
*/
s.Media.trackVars='contextData.a.media.progress10,contextData.a.media.progress25,contextData.a.media.progress50,contextData.a.media.progress75,contextData.a.media.progress95,contextData.a.media.friendlyname';
};
/*
* USE MEDIA MONITOR TO SEND THE ADDITIONAL a.media.progressXX variables: needed as no processing rules are created by default to handle media.milestone
*/
s.Media.monitor = function (s,media) {
//Reset Variables
s.contextData['a.media.progress10'] = s.contextData['a.media.progress25'] = s.contextData['a.media.progress50'] = s.contextData['a.media.progress75'] = s.contextData['a.media.progress95'] = s.contextData['a.media.friendlyname'] = '';
s.contextData['a.media.friendlyname'] = _satellite.getVar('Video Media Name'); //assign custom friendly name if needed
//if no custom friendly name
if(!s.contextData['a.media.friendlyname']){
//default to media.name
s.contextData['a.media.friendlyname'] = media.name;
}
//If MILESTONE EVENT
if(media.event=='MILESTONE') {
//Check which milestone has been reached: media.milestone
switch (media.milestone) {
case 10:
//When the 10% milestone is reached add a.media.progress10 to the Adobe Analytics request
s.contextData['a.media.progress10'] = true;
s.Media.track(media.name);
break;
case 25:
//When the 25% milestone is reached add a.media.progress25 to the Adobe Analytics request
s.contextData['a.media.progress25'] = true;
s.Media.track(media.name);
break;
case 50:
//When the 50% milestone is reached add a.media.progress50 to the Adobe Analytics request
s.contextData['a.media.progress50'] = true;
s.Media.track(media.name);
break;
case 75:
//When the 75% milestone is reached add a.media.progress75 to the Adobe Analytics request
s.contextData['a.media.progress75'] = true;
s.Media.track(media.name);
break;
case 95:
//When the 95% milestone is reached add a.media.progress95 to the Adobe Analytics request
s.contextData['a.media.progress95'] = true;
s.Media.track(media.name);
break;
default:
//When any other % milestone is reached do nothing
break;
}
}
};
/***** MEDIA MODULE CONFIGURATION FOR MILESTONE TRACKING END*****/
/*********end Media Module Calls**************/
/************************** DO PLUGINS SECTION ***********************/
s.doPlugins=function(s) {
//_satellite.notify('KIWI: Tool > Analytics > Custom JS > DO PLUGINS SECTION (begin)');
//track times through do plugins
if (typeof kiwi._timesThruDoPlugins != 'undefined') kiwi._timesThruDoPlugins++;
else kiwi._timesThruDoPlugins = 0;
_satellite.notify('KIWI: Tool > Analytics > Custom JS > kiwi._timesThruDoPlugins = '+ kiwi._timesThruDoPlugins.toString());
//start fresh
s.clearVars();
s.linkTrackVars = 'channel,server,prop1,prop5,prop6,prop7,prop9,prop11,prop12,prop13,prop14,prop17,prop18,prop19,prop20,prop21,' +
'prop25,prop32,prop57,prop59,eVar5,eVar8,eVar17,eVar21,eVar22,eVar23,eVar24,eVar25,eVar67'; //send with all link tracking TODO: prop50,prop51
s.linkTrackEvents = '';
/* Legacy Analytics Overrides */
var ruleName='KIWI: Tool > Analytics > Custom JS > Legacy Analytics Overrides > NSAT';
if (kiwi._thisPage.siteCode == 'nsat') {
_satellite.notify(ruleName);
/* NSAT analytics overrides */
if ((!cbTrackData.flowCode && !cbTrackData.pageCode) ||
(cbTrackData.pageCode.match(/(satprofile:coursework[1-6]|:confirmationpopup|:printadmissionticket)/i))) {
var s_pageName = _satellite.getVar('SCode Page Name');
if(s_pageName) {
if (s_pageName.match(/:/i)) {
//parse it
var arr_s_pageName = s_pageName.split(':');
cbTrackData.flowCode = arr_s_pageName[0];
cbTrackData.pageCode = arr_s_pageName[1];
}
}
}
// NSAT Page Name fixing HACKERY :(, 8/21/2017
var my_pageName = s_pageName || cbTrackData.flowCode + ':' +cbTrackData.pageCode,
hack_pageName = '',
my_prevPage = decodeURIComponent(_satellite.readCookie('gpv_pn'));
if (my_pageName == 'satregistration:photo-flash' && document.location.href.match(/\/managereg\//i)) {
hack_pageName = 'changesat:photo-flash';
}
if (my_pageName == 'satregistration:confirmationpopup') {
if (my_prevPage == 'satregistration:reviewpurchase') hack_pageName = 'satregistration:purchaseconfirmpopup';
else if (my_prevPage == 'scorechoice:satregrevieworderpage') hack_pageName = 'scorechoice:confirmpopup';
} else if (my_pageName == 'changesat:confirmationpopup' && my_prevPage == 'changesat:reviewpurchase') hack_pageName = 'changesat:purchaseconfirmpopup';
if (hack_pageName) {
_satellite.setVar('Page Name Override', hack_pageName);
my_pageName = hack_pageName;
}
//map pagenames to steps, set current flowsteps
var pageToStepsArray = [
['satregistration:getstarted', ['begin']],
['satregistration:getstarted-orf1', ['begin']],
['satregistration:reviewpersonalprofile', ['profile-pi']],
['satregistration:demographics', ['profile-dg']],
['satregistration:contractoptinpage', ['contract-optin']],
['satprofile:cbprograms', ['sdq-cbprograms']],
['satprofile:gparank', ['sdq-gparank']],
['satprofile:coursework1', ['sdq-cw-math']],
['satprofile:coursework2', ['sdq-cw-english']],
['satprofile:coursework3', ['sdq-cw-science']],
['satprofile:coursework4', ['sdq-cw-socialstudies']],
['satprofile:coursework5', ['sdq-cw-languages']],
['satprofile:coursework6', ['sdq-cw-artsmusic']],
['satprofile:hsactivities', ['sdq-hsactivities']],
['satprofile:collegeplans', ['sdq-collegeplans']],
['satregistration:termsandconditions', ['terms']],
['satregistration:choosetestanddate', ['choose-test']],
['satregistration:choosetestcenter', ['choose-center']],
['satregistration:photo-flash', ['photo']],
['satregistration:facebookphotopage', ['photo-facebook']],
['satregistration:crosssell', ['crosssell']],
['satregistration:reviewpurchase', ['purchase-review']],
['satregistration:purchaseconfirmpopup', ['purchase-accept']],
['satregistration:purchaseconfirmation', ['purchase-complete']],
['satregistration:revieworder', ['reg-review']],
['satregistration:confirmationpopup', ['reg-accept']],
['satregistration:confirmation', ['reg-complete']],
['satregistration:printadmissionticket', ['ticket']],
['changesat:changeregistration', ['change-begin']],
['changesat:reviewpersonalprofile', ['change-profile-pi']],
['changesat:choosetestanddate', ['change-test']],
['changesat:choosetestcenter', ['change-center']],
['changesat:photo-flash', ['change-photo']],
['changesat:crosssell', ['change-crosssell']],
['changesat:revieworder', ['change-review']],
['changesat:confirmationpopup', ['change-accept']],
['changesat:confirmationpage', ['change-complete']],
['changesat:printadmissionticket', ['change-ticket']]
];
//NOT ENOUGH BROWSER SUPPORT YET for "Map"
//var pageToStepsMap = new Map(pageToStepsArray);
//cbTrackData.flowSteps = pageToStepsMap.get(cbTrackData.pageCode);
for (var i = 0; i < pageToStepsArray.length; i++) {
var pageKey = pageToStepsArray[i][0],
arrSteps = pageToStepsArray[i][1];
if (pageKey == my_pageName) cbTrackData.flowSteps = arrSteps;
}
//get at SAT regNo
if (_satellite.getVar('SCode Events Data')) {
var arrSEvents = _satellite.getVar('SCode Events Data').split(',');
(function(){
for (var i = 0; i < arrSEvents.length; i++) {
if (arrSEvents[i].match(/event(2|71|72|73|74|75):/i)) {
cbTrackData.satRegNo = arrSEvents[i].split(':')[1];
if (cbTrackData.satRegNo == 'regNo' &&
typeof SatReg != 'undefined' &&
typeof SatReg.FtlVars != 'undefined' &&
typeof SatReg.FtlVars.regNo != 'undefined') cbTrackData.satRegNo = window.SatReg.FtlVars.regNo; //fixes bug in Print Ticket event tracking on Next Steps button
}
}
})();
}
//get at Test Type
if (cbTrackData.pageCode == 'choosetestcenter' && _satellite.getVar('DOM nsat TestTypeId')) {
// sat subject tests open info box ... OR sat open info box ... OR sat with essay open info box...
if (_satellite.getVar('DOM nsat TestTypeId').match(/sat subject tests/i)) {s.eVar26 = 'SAT Subject';}
else s.eVar26 = 'SAT';
}
/* end NSAT analytics overrides */
}
/* end Legacy Analytics Overrides */
/* Basic Var settings */
s.events = s.apl(s.events, 'event7', ',', 2); //Page View
s.hier1 = 'D=g';
s.prop58 = _satellite.getVar('protocol');
s.server = _satellite.getVar('Domain');
s.prop20 = _satellite.getVar('Subdomain');
s.prop32 = _satellite.getVar('Site Code');
cbTrackData.flowCode = _satellite.getVar('AppData Flow Code');
s.prop1 = 'D=pageName';
//s.pageName = _satellite.getVar('Page Name'); //Page
//Page Track Object
(function(oData){
s.prop8 = oData.source || 'undefined'; //Page Track Source
s.pageName = oData.pageName || _satellite.getVar('Page Name'); //Page
})(_satellite.getVar('Data - Page Track'));
s.prop1 = 'PAGE|'+s.pageName;
/*s.eVar87 = _satellite.getVar('Page Property - AP Classroom - Application ID'); //AP Classroom Page Application ID
s.eVar88 = _satellite.getVar('Page Property - AP Classroom - Student ID'); //AP Classroom Page Student ID
s.eVar89 = _satellite.getVar('Page Property - AP Classroom - Unit ID'); //AP Classroom Page Unit ID */
s.prop7 = _satellite.readCookie('gpv_c32') || ''; //Previous Site Code
s.prop52 = _satellite.readCookie('gpv_pn') || ''; //Previous Page
s.prop18 = s.getTimeParting('n', '-5'); //Hour of Day, Day of Week, Weekend/Weekday
s.eVar20 = s.getDaysSinceLastVisit('s_lastvisit'); //Days Since Last Visit
if (kiwi._pageLoadTime) {
s.events = s.apl(s.events, 'event86=' + kiwi._pageLoadTime, ',', 2); //Page Load Time
s.prop61 = kiwi._pageLoadTime; //Page Load Time
}
if (s.ActionDepthTest) {
s.pdvalue = s.getActionDepth('s_depth');
if (s.pdvalue == 1) {s.events = s.apl(s.events, 'event38', ',', 2);} // Depth1: Landing Page
if (s.pdvalue == 2) {s.events = s.apl(s.events, 'event39', ',', 2);} // Depth2: Second Page
}
s.ActionDepthTest = false;
//s.prop50 = _satellite.getVar('Kiwi MCIDS Present'); //MCIDS Present
//s.prop51 = _satellite.getVar('Kiwi MC Visitor ID'); //Marketing Cloud Visitor ID
s.prop6 = _satellite.getVar('Kiwi Version'); //Kiwi Version
s.prop35 = _satellite.getVar('Enterprise Widgets Version'); //Enterprise Widgets Version
s.prop36 = _satellite.getVar('Apricot Version'); //Apricot Version
s.prop57 = _satellite.getVar('DOM Browser Width'); //Browser Width
s.prop74 = _satellite.getVar('Report Load Speed'); //BI Report Load Speed
s.prop5 = _satellite.getVar('Derived Education Period Code'); //Education Period Code
s.eVar7 = _satellite.getVar('DDL - User - LIFW Status'); //LIFW Status
s.eVar8 = _satellite.getVar('AppData App User Org ID'); //App User Org ID (e.g. app-specific AI Code, DI Code)
s.prop19 = _satellite.getVar('DDL - User Role'); //App User Role
s.prop21 = _satellite.getVar('AppData App Pilot'); //'channels-20180103-01'; //App Pilot
s.prop14 = _satellite.getVar('AppData AP Student Grade Level'); //AP Student Grade Level
s.prop33 = _satellite.getVar('AppData AP Course ID'); //AP Course ID
s.prop39 = _satellite.getVar('AA - App Data Custom 1'); //App Data Custom 1
s.prop40 = _satellite.getVar('AA - App Data Custom 2'); //App Data Custom 2
s.prop41 = _satellite.getVar('AA - App Data Custom 3'); //App Data Custom 3
s.prop42 = _satellite.getVar('AA - App Data Custom 4'); //App Data Custom 4
//clear the App Data Custom vars
_satellite.setVar('AA - App Data Custom 1', '');
_satellite.setVar('AA - App Data Custom 2', '');
_satellite.setVar('AA - App Data Custom 3', '');
_satellite.setVar('AA - App Data Custom 4', '');
s.prop31 = _satellite.getVar('SKU');
s.prop70 = _satellite.getVar('AppData DI Code'); //DI Code
s.eVar67 = _satellite.getVar('Apricot - User Input Method'); //User Input Method
if (kiwi._thisPage.siteCode === 'hedr') {
s.prop70 = s.eVar8; //DI Code
s.prop71 = s.prop19; //HED Reporting App Role TODO: switch reports to use prop19 and disable prop71
}
if (kiwi._thisPage.siteCode === 'springboarddigital') {
s.prop62 = s.prop19; //Springboard Digital Audience TODO: switch reports to use prop19 and disable prop62
s.prop63 = _satellite.getVar('AppData User District'); //TODO: switch to "AppData App User Org ID"
}
if((_satellite.getVar('AppData User Type')=='a2o')) s.prop72 = 'a2o'; //A2O Segment //TODO: deprecate switch this to "AppData App User Role"
/* end Basic Var settings */
/* CB Web (IAM) */
kiwi.userIsLoggedIn = (_satellite.readCookie('cb_login')) || false;
/* CB Web Login Tracking */
(function(oData, sPageName) {
if (oData && oData.hasData) {
_satellite.notify('KIWI: Data - CB Web Data found: ' + JSON.stringify(oData));
if (oData.events) {
if (oData.events.match(/event(9|14|21)/i)) {
s.eVar19 = oData.appId || ''; // CB Application ID
}
if (oData.events.match(/event9/i) && !s.prop52.match(/(securitycheck-)/i)) {
if (oData.interim) {
s.events = s.apl(s.events, 'event198', ',', 2); //CB Web AP Interim Logins
//accommodate for when page after interim account create is reminder message, WAP-2908
if (sPageName.match(/^iam:/i)) {
s.events = s.apl(s.events, 'event197:' + oData.id, ',', 2); //CB Web AP Interim Registrations
}
} else {
s.events = s.apl(s.events, 'event9', ',', 2); //CB Web Logins
}
}
if (oData.events.match(/event14/i)) {
if (oData.interim) {
s.events = s.apl(s.events, 'event197:' + oData.id, ',', 2); //CB Web AP Interim Registrations
} else {
s.events = s.apl(s.events, 'event14:' + oData.id, ',', 2); //CB Web ECL Registrations
}
}
if (oData.events.match(/event21/i)) {
s.events = s.apl(s.events, 'event21:' + oData.id, ',', 2); //CB Web EPL Registrations
}
}
//accommodate for when WEP doesn't include event14/event197 but new account is created!
if (sPageName.match(/^(iam:registrationconfirmationpage|iam:interimaccount:create:success)-/i)) {
if (oData.interim) {
s.events = s.apl(s.events, 'event197:' + oData.id, ',', 2); //CB Web AP Interim Registrations
} else {
s.events = s.apl(s.events, 'event14:' + oData.id, ',', 2); //CB Web ECL Registrations
}
kiwi.util.fireCustomEvent('ECL Account Created');
}
//new prof account creation doesn't currently get event21 in WEP cookie! so we test for scode event21 next
var sEvents = _satellite.getVar('SCode Events Data');
if (sEvents.match(/event21/i)) {
s.events = s.apl(s.events, 'event21:' + oData.id, ',', 2); //CB Web EPL Registrations
}
//derive Interim Account Merge scenario (page name not currently working for this)
var iamPageClasses = _satellite.getVar('DOM - iam-page Node');
if (iamPageClasses.match(/(^| )iam-merged($| )/i)) {
s.events = s.apl(s.events, 'event199', ',', 2); //CB Web AP Interim Account Merges
}
s.linkTrackVars=s.apl(s.linkTrackVars, 'events', ',', 2);
//stop interim account events from firing on random Custom Links, e.g. on Big Future, WAP-2908, WAP2916
s.linkTrackEvents=s.apl(s.linkTrackEvents, 'event9,event14,event21', ',', 2);
//s.linkTrackEvents=s.apl(s.linkTrackEvents, 'event9,event14,event21,event197,event198,event199', ',', 2);
//Expire WAP_EXTERNAL_PROPERTIES cookie after track
_satellite.notify('WAP_EXTERNAL_PROPERTIES='+ _satellite.getVar('IAM Cookie - WAP_EXTERNAL_PROPERTIES'))
document.cookie = 'WAP_EXTERNAL_PROPERTIES=;expires=-1;path=/ ;domain=collegeboard.org';
//update kiwi.user vals
kiwi.user = {
interim: oData.interim,
type: oData.type,
cbId: oData.id,
orgId: oData.orgId,
gender: oData.gender,
gradeLevel: oData.gradeLevel,
gradYear: oData.gradYear,
jobTitle: oData.jobTitle
};
//signal kiwi.cookie.user updates
kiwi._sessCookieMod = true;
kiwi.cookie.sess.user = kiwi.user;
}
})(_satellite.getVar('Data - CB Web Login'), _satellite.getVar('SCode Page Name'));
/* end CB Web Login Tracking */
/* CB Web Account Creation Custom Events */
//if (s.pageName.match(/^iam:registrationpage2-/i)) {}
/* end CB Web Account Creation Custom Events */
s.prop9 = _satellite.getVar('CB Web - Logged In State'); //CB Web Logged In State
s.eVar22 = _satellite.getVar('CB Web - Account Type'); //CB Web Account Type
s.eVar17 = _satellite.getVar('CB Web - Account ID'); //CB Web Account ID
s.eVar5 = _satellite.getVar('CB Web - Org ID'); //CB Web Org ID
s.eVar24 = _satellite.getVar('CB Web - Gender'); //CB Web Gender
s.eVar23 = _satellite.getVar('CB Web - Grad Year'); //CB Web Grad Year
s.eVar21 = _satellite.getVar('CB Web - Grade Level'); //CB Web Grade Level
s.eVar25 = _satellite.getVar('CB Web - Job Title Code'); //CB Web Job Title Code
//_satellite.notify('KIWI: CB Web Data tracked: ' + JSON.stringify(kiwi.user));
/* end CB Web (IAM) */
/* Special IAM Page Name */
var arrMatchCurr = s.pageName.match(/^iam:default:lockedout-(.*)$/i),
arrMatchPrev = s.prop52.match(/(login|securitycheck)/i);
if (arrMatchCurr !== null && arrMatchPrev !== null) {
s.pageName = 'iam:'+arrMatchPrev[1]+':lockedout-' + arrMatchCurr[1];
}
var arrMatchCurr = s.pageName.match(/^iam:login:error:password-(.*)$/i),
lockoutWarnModal = document.getElementById('lockout'),
pageModalOpen = document.querySelector('[iam-spa].modal-open');
if (arrMatchCurr !== null && lockoutWarnModal && pageModalOpen) {
s.pageName = 'iam:login:lockoutwarning-' + arrMatchCurr[1];
}
/* end Special IAM Page Name */
/* Error Page Tracking */
var result = s.pageName.match(/:(404errorpage|500errorpage|downpage|highvolume|403forbidden)/i);
if (result !== null) {
//s.pageName='';
//s.pageType='errorPage';
s.prop11 = 'server';
s.prop12 = result[1];
s.prop13 = 'D=g'; //URL Attempted
}
if (s.linkType === 'o') {
if (s.linkName == 'ajax error tracking') {
var oData = _satellite.getVar('Ajax Error Data');
if (oData) {
s.prop11 = oData.type;
s.prop12 = oData.code;
s.prop13 = 'D=pageName';
}
//reset data
_satellite.setVar('Ajax Error Data', '');
}
}
/* end Error Page Tracking */
/* App Error on Page */
(function(){
var warningAlertText = _satellite.getVar('DOM - Alert Text - Warning'),
dangerAlertText = _satellite.getVar('DOM - Alert Text - Danger');
if (dangerAlertText || warningAlertText) {
s.prop11 = 'on-page-alert';
s.prop12 = dangerAlertText?'on-page-alert (danger): '+dangerAlertText:'on-page-alert (warning): '+warningAlertText;
s.prop13 = 'D=pageName';
}
})();
/* end App Error on Page */
/* Legacy Internal Campaign Clicks */
//TODO: Deprecate after Target Late coming links tracking is fixed
var sIntCmp = _satellite.getVar('Legacy Internal Campaign Clicked');
if (sIntCmp) {
s.eVar2 = sIntCmp; //Internal Campaign Clicks (legacy)
s.eVar2 = s.getValOnce(s.eVar2, 's_v2', 30); //Internal Campaign Clicks (legacy), deduped
if (s.eVar2.length) {
//_satellite.notify('KIWI: Legacy Internal Campaign Tracked: ' + sIntCmp);
s.events = s.apl(s.events, 'event13', ',', 2); //Internal Campaign Clicks (legacy)
//reset appdata, cookie after track
//_satellite.setVar('Legacy Internal Campaign Clicked', '');
document.cookie = 'cb_intcmp=; expires=-1; path=/; domain=.collegeboard.org';
}
}
/* end Legacy Internal Campaign Clicks */
/* Promo/Nav Track Goals Setup */
kiwi._promoTrackGoals = kiwi._promoTrackGoals || '';
kiwi._navTrackGoals = kiwi._navTrackGoals || '';
//page load or click track via JS
if (s.linkType) {
//click track via JS - check link type
if (s.linkType === 'o' && (s.linkName === 'Widget Display Change')) {
//widget state change - collect promo views on widget
kiwi._promoTrackGoals = 'views';
kiwi._navTrackGoals = 'both';
_satellite.notify('KIWI: Promo/Nav Track Goals //widget state change - collect promo views on widget');
} else {
//check for nav/promo clicks
if (s.linkType === 'e' ||
s.linkType === 'd' ||
(s.linkType === 'o' && (s.linkName === 'Dynamic Download Link' ||
s.linkName.match(/Promo Link/i) ||
s.linkName === 'Nav Link' ||
s.linkName === 'Site Search Link'))) {
kiwi._promoTrackGoals = 'clicks';
kiwi._navTrackGoals = 'clicks';
if (s.linkName.match(/Promo Link/i)) kiwi._navTrackGoals = 'none';
if (s.linkName === 'Nav Link') kiwi._promoTrackGoals = 'none';
_satellite.notify('KIWI: Promo/Nav Track Goals //click track - link type: '+ s.linkType + ', '+ s.linkName);
}
}
} else {
//page load track - collect promo views on page (e.g. SSR but also BF First Level Tabs, also Modals as pages)
kiwi.util.fireCustomEvent('Page View');
kiwi._promoTrackGoals = 'views';
kiwi._navTrackGoals = 'both';
_satellite.notify('KIWI: Promo/Nav Track Goals //page load track - collect promo views on page');
}
if (s.linkName && (s.linkName === 'Widgets Ready' ||
s.linkName.match(/Feature Clicks - /i) ||
s.linkName.match(/Feature Used - /i))) {
//widget state change or feature click
kiwi._promoTrackGoals = '';
kiwi._navTrackGoals = '';
//_satellite.notify('KIWI: Promo/Nav Track Goals = NONE//atlas widget or feature clicks - track in a new way');
}
/* end Promo/Nav Track Goals Setup */
/* Promo Views/Clicks */
if (kiwi._promoTrackGoals === 'clicks') {
//_satellite.notify('KIWI: Promo Track Goals = clicks');
/* Promo Clicks */
var sPromoClicked2017 = _satellite.getVar('Promo - Clicked'),
sPromoClicked2019 = _satellite.getVar('Promo - Clicked 2019');
if (sPromoClicked2017 || sPromoClicked2019) {
//merge promos clicked
//sPromoClicked = kiwi.util.mergeLists(sPromoClicked2017, sPromoClicked2019);
//track 2017 promos
if (sPromoClicked2017 && kiwi._thisPage.siteSettings.use2017promos) {
s.list1 = sPromoClicked2017; //Promos (CTR)
s.linkTrackVars = s.apl(s.linkTrackVars, 'list1', ',', 2);
s.list2 = sPromoClicked2017; //Promos (Conv)
s.linkTrackVars = s.apl(s.linkTrackVars, 'list2', ',', 2);
s.events = s.apl(s.events, 'event99', ',', 2); //Promo Clicks
s.linkTrackEvents=s.apl(s.linkTrackEvents, 'event99', ',', 2);
s.linkTrackVars = s.apl(s.linkTrackVars, 'events', ',', 2);
}
//track 2019 promos
if (sPromoClicked2019) {
s.list3 = sPromoClicked2019; //Promos (CTR) 2019
s.linkTrackVars = s.apl(s.linkTrackVars, 'list3', ',', 2);
s.eVar18 = sPromoClicked2019; //Promos (Conv) 2019
s.linkTrackVars = s.apl(s.linkTrackVars, 'eVar18', ',', 2);
s.events = s.apl(s.events, 'event57', ',', 2); //Promo Clicks 2019
s.linkTrackEvents=s.apl(s.linkTrackEvents, 'event57', ',', 2);
s.linkTrackVars = s.apl(s.linkTrackVars, 'events', ',', 2);
}
}
_satellite.notify('KIWI: Promo 2017 Tracked: ' + sPromoClicked2017);
_satellite.notify('KIWI: Promo 2019 Tracked: ' + sPromoClicked2019);
var sPromoClickedTnT = _satellite.getVar('Promo - Clicked TnT');
if (sPromoClickedTnT) {
//track tnt promos
s.list3 = sPromoClickedTnT; //Promos (CTR) 2019
s.linkTrackVars = s.apl(s.linkTrackVars, 'list3', ',', 2);
s.eVar18 = sPromoClickedTnT; //Promos (Conv) 2019
s.linkTrackVars = s.apl(s.linkTrackVars, 'eVar18', ',', 2);
s.events = s.apl(s.events, 'event57', ',', 2); //Promo Clicks 2019
s.linkTrackEvents=s.apl(s.linkTrackEvents, 'event57', ',', 2);
s.linkTrackVars = s.apl(s.linkTrackVars, 'events', ',', 2);
}
_satellite.notify('KIWI: Promo TnT Tracked: ' + sPromoClickedTnT);
/* SSS Opt-Ins/re-Opt-Ins */
var promoWasOptin = sPromoClicked2017.match(/widget-sssoptin:optin\|yes/i) || false,
sEvent = '',
sEventDedupeString = '',
sEventFriendlyName = '';
if (promoWasOptin) {
sEvent = 'event59';
sEventFriendlyName = 'SSS Opt Ins';
} else {
promoWasOptin = sPromoClicked2017.match(/widget-sssoptin:reoptin\|yes/i) || false;
if (promoWasOptin) {
sEvent = 'event196';
sEventFriendlyName = 'SSS re-Opt Ins';
}
}
if (promoWasOptin) {
sEventDedupeString = sEvent + ':' + kiwi.cookie.sess.user.cbId;
s.linkTrackEvents=s.apl(s.linkTrackEvents, sEvent, ',', 2);
s.events = s.apl(s.events, sEventDedupeString, ',', 2); //SSS Opt-Ins, SSS re-Opt-Ins
_satellite.notify('KIWI: Custom Event Tracked: ' + sEventFriendlyName + ': ' + sEventDedupeString);
}
/* endSSS Opt-Ins/re-Opt-Ins */
/* end Promo Clicks */
} else if (kiwi._promoTrackGoals === 'views') {
_satellite.notify('KIWI: Promo Track Goals = views');
/* Promo Views */
var sPromoViews2017 = _satellite.getVar('Promo - Views'),
sPromoViews2019 = _satellite.getVar('Promo - Views 2019'),
sTntPromoViews = _satellite.getVar('Promo - Views TnT');
if (sPromoViews2017 || sPromoViews2019) {
s.linkTrackVars = s.apl(s.linkTrackVars, 'events,list1,list3', ',', 2);
s.linkTrackEvents = s.apl(s.linkTrackEvents, 'event98,event12,event56', ',', 2);
//merge promo views lists
//sPromoViews = kiwi.util.mergeLists(sPromoViews2017, sPromoViews2019);
//track 2017 promos
if (sPromoViews2017 && kiwi._thisPage.siteSettings.use2017promos) {
var arrPromoViews2017 = sPromoViews2017.split(',');
for (var iPv17 = 0; iPv17 < arrPromoViews2017.length; iPv17++) {
s.list1 = s.apl(s.list1, arrPromoViews2017[iPv17], ',', 2); //Promos (CTR)
}
s.events = s.apl(s.events, 'event98', ',', 2); //Promo Views
s.events = s.apl(s.events, 'event12', ',', 2); //Internal Campaign Views (legacy)
}
//track 2019 promos
if (sPromoViews2019) {
var arrPromoViews2019 = sPromoViews2019.split(',');
for (var iPv19 = 0; iPv19 < arrPromoViews2019.length; iPv19++) {
s.list3 = s.apl(s.list3, arrPromoViews2019[iPv19], ',', 2); //Promos (CTR) 2019
}
s.events = s.apl(s.events, 'event56', ',', 2); //Promo Views 2019
}
}
if (sTntPromoViews) {
s.linkTrackVars = s.apl(s.linkTrackVars, 'events,list3', ',', 2);
s.linkTrackEvents = s.apl(s.linkTrackEvents, 'event56', ',', 2);
//track tnt promos
if (sTntPromoViews) {
var arrTnTPromoViews = sTntPromoViews.split(',');
for (var iPvTnt = 0; iPvTnt < arrTnTPromoViews.length; iPvTnt++) {
s.list3 = s.apl(s.list3, arrTnTPromoViews[iPvTnt], ',', 2); //Promos (CTR) 2019
}
s.events = s.apl(s.events, 'event56', ',', 2); //Promo Views 2019
}
}
/* end Promo Views */
}
/* end Promo Views/Clicks */
/* Nav Views/Clicks */
/* Global Nav Clicks - legacy method */
s.prop49 = _satellite.getVar('Global Nav ID');
s.prop49 = s.getValOnce(s.prop49, 'gvo_c49', 0); //Global Nav ID
if (s.prop49) {
s.events = s.apl(s.events, 'event70', ',', 2); //Global Nav Clicks
}
/* end Global Nav Clicks */
if (kiwi._navTrackGoals === 'both' || kiwi._navTrackGoals === 'views') {
_satellite.notify('KIWI: Nav Track Goals = both/views');
/* Nav Views */
var sNavViewEvents = _satellite.getVar('Nav - Views');
if (sNavViewEvents) {
//for CTR Tracking:
s.linkTrackVars = s.apl(s.linkTrackVars, 'events', ',', 2);
s.linkTrackEvents=s.apl(s.linkTrackEvents, sNavViewEvents, ',', 2);
s.events = s.apl(s.events, sNavViewEvents, ',', 2); //[xyz] Nav Views
}
/* end Nav Views */
}
if (kiwi._navTrackGoals === 'both' || kiwi._navTrackGoals === 'clicks') {
_satellite.notify('KIWI: Nav Track Goals = both/clicks');
/* Nav Clicks */
if (kiwi._skipTrackNav) kiwi._skipTrackNav = false;
else {
var sNavClicked = _satellite.getVar('Nav - Clicked');
if (sNavClicked) {
var sArrNavClicked = sNavClicked.split('|'),
oNav = { //e.g. event221|global|gh|Skip to content|#main-content, event229|local|program-band|Major & Career Search
clickEvent: sArrNavClicked[0] || '',
type: sArrNavClicked[1],
key: sArrNavClicked[2],
subNav: sArrNavClicked[3] || '',
text: sArrNavClicked[4] || '',
hash: sArrNavClicked[5] || ''
},
sNavTracked = oNav.key + ':' + oNav.subNav+ ':' + oNav.text;
sNavTracked = oNav.hash?'nav-toggle:' + sNavTracked:'nav-click:' + sNavTracked;
if (oNav.hash) {
'nav-toggle:' + sNavTracked;
}
s.prop43 = sNavTracked;
s.linkTrackVars=s.apl(s.linkTrackVars, 'prop43,', ',', 2);
if (oNav.clickEvent) {
s.events = s.apl(s.events, oNav.clickEvent, ',', 2); //[xyz] Nav Clicks
s.linkTrackVars = s.apl(s.linkTrackVars, 'events', ',', 2);
s.linkTrackEvents=s.apl(s.linkTrackEvents, oNav.clickEvent, ',', 2);
switch (oNav.type) {
case 'global':
s.events = s.apl(s.events, 'event70', ',', 2); //Global Nav Clicks
s.linkTrackVars = s.apl(s.linkTrackVars, 'events', ',', 2);
s.linkTrackEvents=s.apl(s.linkTrackEvents, 'event70', ',', 2);
break;
case 'local':
s.events = s.apl(s.events, 'event95', ',', 2); //Local Nav Clicks
s.linkTrackVars = s.apl(s.linkTrackVars, 'events', ',', 2);
s.linkTrackEvents=s.apl(s.linkTrackEvents, 'event95', ',', 2);
break;
default:
break;
}
}
//Reset Vars after track
document.cookie = 'cbtrack_nav=; expires=-1; path=/; domain=.collegeboard.org';
if (cbTrackData.localNavItemClicked) {//from SSR
_satellite.notify('KIWI: cbTrackData.localNavItemClicked = ' + cbTrackData.localNavItemClicked);
cbTrackData.localNavItemClicked = '';
}
_satellite.notify('KIWI: Nav Tracked: ' + sNavClicked);
}
}
/* end Nav Clicks */
}
/* end Nav Views/Clicks */
/* College Lists */
// College List Starts/Saves
(function(oData, deduper){
if (oData && oData.hasData) {
// - Set on Page Track in BF React
_satellite.notify('KIWI: College List Data found!: ' + JSON.stringify(oData));
s.events = s.apl(s.events, 'event190:' + deduper, ',', 2); //College List Saves, Deduped
if (oData.rmsListStarted) {
s.events = s.apl(s.events, 'event202:' + deduper, ',', 2); //RMS College List Started, Deduped
}
if (oData.rmsListFulfilled) {
s.events = s.apl(s.events, 'event203:' + deduper, ',', 2); //RMS College List Fullfilled, Deduped
}
}
})(_satellite.getVar('Data - College List'), kiwi.user.cbId); //oData, deduper
//College List Adds
(function(oData, deduper){
// - Set on Link Track (DCR) in BF React
if (oData && oData.hasData) {
_satellite.notify('KIWI: College Added!: ' + JSON.stringify(oData));
//first derive legacy isFirstCollege
if (oData.addSource.match(/^(BF GWT|BF Mobile)$/i)) {
var sCollegeListCreated='true';
sCollegeListCreated=s.getValOnce(sCollegeListCreated,'s_collegeListCreated', 99999);
if(sCollegeListCreated) {
oData.isFirstCollege = true;
}
}
s.events = s.apl(s.events, 'event66', ',', 2); //College List Adds
s.linkTrackEvents=s.apl(s.linkTrackEvents, 'event66', ',', 2);
s.eVar60 = oData.addMethod;
s.eVar11 = oData.collegeAdded;
s.linkTrackVars=s.apl(s.linkTrackVars, 'eVar60', ',', 2);
s.linkTrackVars=s.apl(s.linkTrackVars, 'eVar11', ',', 2);
s.linkTrackVars=s.apl(s.linkTrackVars, 'events', ',', 2);
if (oData.isFirstCollege) {
_satellite.notify('KIWI: New College List!: ' + JSON.stringify(oData));
s.events = s.apl(s.events, 'event67', ',', 2); //College Lists Created (legacy metric, not deduped)
s.linkTrackEvents=s.apl(s.linkTrackEvents, 'event67', ',', 2);
if (deduper) {
s.events = s.apl(s.events, 'event190:' + deduper, ',', 2); //College List Saves, Deduped
s.linkTrackEvents=s.apl(s.linkTrackEvents, 'event190', ',', 2);
kiwi.util.fireCustomEvent('College List Saved');
if (oData.isRmsCollege) {
s.events = s.apl(s.events, 'event202:' + deduper, ',', 2); //RMS College List Started, Deduped
s.linkTrackEvents=s.apl(s.linkTrackEvents, 'event202', ',', 2);
}
}
}
} else {
//Abort Link Track if no Data to Capture
if (s.linkType === 'o' && s.linkName === 'College Add') {
_satellite.notify('College Add Link Track: No data to capture, aborting tracking call.')
s.abort = true;
}
}
})(_satellite.getVar('Data - College List Add'), kiwi.user.cbId); //oData, deduper
//RMS Score Changes
(function(oData){
// - Set on Link Track (DCR) in BF React
if (oData && oData.hasData) {
_satellite.notify('KIWI: RMS Score Changed!: ' + JSON.stringify(oData));
s.events = s.apl(s.events, 'event204', ',', 2); //RMS Score Changes
s.linkTrackVars=s.apl(s.linkTrackVars, 'events', ',', 2);
s.linkTrackEvents=s.apl(s.linkTrackEvents, 'event204', ',', 2);
s.eVar6 = oData.scoreType;
s.linkTrackVars=s.apl(s.linkTrackVars, 'eVar6', ',', 2);
} else {
if (s.linkType === 'o' && s.linkName === 'RMS Score Change') {
s.abort = true;
}
}
})(_satellite.getVar('Data - RMS Score Change')); //oData
/* end College Lists */
/* CB Opportunity Scholarships Events */
//many of these are also set on Link Track (DCR) but deduped through serialization
(function(oData){
if (oData && oData.hasData) {
_satellite.notify('KIWI: CBOS Events Data Found: ' + JSON.stringify(oData));
var serializeVal = kiwi.user.cbId+'-'+kiwi.user.gradYear;
//"Build"
if (oData.build) s.events = s.apl(s.events, 'event136:'+serializeVal, ',', 2); //CBOS Students - Build College List
//"Practice"
if (oData.practice) s.events = s.apl(s.events, 'event137:'+serializeVal, ',', 2); //CBOS Students - Practice SAT
//"Improve"
if (oData.improve) s.events = s.apl(s.events, 'event138:'+serializeVal, ',', 2); //CBOS Students - Improve Score
//"Strengthen"
if (oData.strengthen) s.events = s.apl(s.events, 'event139:'+serializeVal, ',', 2); //CBOS Students - Strengthen List
//"Complete"
if (oData.complete) s.events = s.apl(s.events, 'event132:'+serializeVal, ',', 2); //CBOS Students - Complete FAFSA
//"Apply"
if (oData.apply) s.events = s.apl(s.events, 'event133:'+serializeVal, ',', 2); //CBOS Students - Apply to Colleges
//"Complete Your Journey"
if (oData.cyj) s.events = s.apl(s.events, 'event135:'+serializeVal, ',', 2); //CBOS Students - Complete Journey
}
})(_satellite.getVar('Data - CBOS')); //oData
/* end CB Opportunity Scholarships Events */
/* Score View Tracking */
(function(oData){
if (oData && oData.hasData) {
_satellite.notify('KIWI: Data - Score View found: ' + JSON.stringify(oData));
if (oData.sat.adminCode) {
s.eVar51 = oData.sat.adminType + '-' + oData.sat.adminCode; //SAT Score View Admin
s.eVar51 = s.eVar51.toLowerCase();
var satSVEventDedupeKey = oData.sat.adminRegId;
satSVEventDedupeKey = satSVEventDedupeKey.toUpperCase(); //set it this way to match NSAT
var satSVEvent = 'event24:' + satSVEventDedupeKey;
s.events = s.apl(s.events, satSVEvent, ',', 2); //SAT Score Views
var satSVEventDedupeKey2 = kiwi.user.cbId + '-' + s.eVar51;
satSVEventDedupeKey2 = satSVEventDedupeKey2.toLowerCase();
s.events = s.apl(s.events, 'event116:'+satSVEventDedupeKey2, ',', 2); //SAT Multiple Choice Score Views
if (s.pageName.match(/^ssr:score-(report|overview):/i)) { //score report page only
s.events = s.apl(s.events, 'event118:' + satSVEventDedupeKey2, ',', 2); //SAT Score Report Views
}
s.linkTrackVars=s.apl(s.linkTrackVars, 'eVar51', ',', 2);
s.linkTrackVars=s.apl(s.linkTrackVars, 'events', ',', 2);
s.linkTrackEvents=s.apl(s.linkTrackEvents, 'event24', ',', 2);
s.linkTrackEvents=s.apl(s.linkTrackEvents, 'event116', ',', 2);
s.linkTrackEvents=s.apl(s.linkTrackEvents, 'event118', ',', 2);
if (kiwi._thisPage.siteCode === 'ssr' && kiwi._thisPage.pageCode.match(/^dashboard/i)) { //dashboard page only
kiwi.util.fireCustomEvent(
'SAT Score Viewed', {
adminType: oData.sat.adminType,
adminDate: oData.sat.adminCode,
registrantType: oData.sat.registrantType,
fwStatus: oData.sat.fwStatus,
scoreBand: oData.sat.scoreBand
});
}
}
if (oData.psat.adminCode) {
s.eVar72 = oData.psat.adminType + '-' + oData.psat.adminCode; //PSAT Score View Admin
s.eVar72 = s.eVar72.toLowerCase();
var psatSVEventDedupeKey = kiwi.user.cbId + '-' + s.eVar72;
var psatSVEvent = 'event88:' + psatSVEventDedupeKey;
s.events = s.apl(s.events, psatSVEvent, ',', 2); //PSAT Score Views
if (s.pageName.match(/^ssr:score-(report|overview):/i)) { //score report page only
s.events = s.apl(s.events, 'event119:'+psatSVEventDedupeKey, ',', 2); //PSAT Score Report Views
}
s.linkTrackVars=s.apl(s.linkTrackVars, 'eVar72', ',', 2);
s.linkTrackVars=s.apl(s.linkTrackVars, 'events', ',', 2);
s.linkTrackEvents=s.apl(s.linkTrackEvents, 'event88', ',', 2);
s.linkTrackEvents=s.apl(s.linkTrackEvents, 'event119', ',', 2);
if (kiwi._thisPage.siteCode === 'ssr' && kiwi._thisPage.pageCode.match(/^dashboard/i)) { //dashboard page only
kiwi.util.fireCustomEvent(
'PSAT Score Viewed', {
adminType: oData.psat.adminType,
adminDate: oData.psat.adminCode,
registrantType: oData.psat.registrantType,
fwStatus: oData.psat.fwStatus,
scoreBand: oData.psat.scoreBand
});
}
}
if (kiwi._thisPage.siteCode === 'ssr' && kiwi._thisPage.pageCode.match(/dashboard/i)) { //dashboard pages only
s.eVar64 = _satellite.getVar('AppData Score Status');
}
} else {
if (s.prop32 === 'ssr' && cbTrackData.pageCode && cbTrackData.pageCode.match(/sat-essays:/i)) {//TODO: get SAT Essay score view reporing working via DDL instead of in this brittle way
if (!s.prop12 || (s.prop12 && !(s.prop12.match(/on-page-alert (warning): Your SAT Essay scores/i)))) {
var arrPageCode = cbTrackData.pageCode.split(':');
s.eVar51 = arrPageCode[1] + '-' + arrPageCode[2]; //SAT Score View Admin
s.eVar51 = s.eVar51.toLowerCase();
var satSVEventDedupeKey3 = kiwi.user.cbId + '-' + s.eVar51;
satSVEventDedupeKey3 = satSVEventDedupeKey3.toLowerCase();
s.events = s.apl(s.events, 'event58:'+satSVEventDedupeKey3, ',', 2); //SAT Essay Score Views
s.linkTrackVars=s.apl(s.linkTrackVars, 'eVar51,events', ',', 2);
s.linkTrackEvents=s.apl(s.linkTrackEvents, 'event58', ',', 2);
}
}
}
//Mark DDL as tracked!
kiwi.ddl.aaTracked.scoreView = true;
})(_satellite.getVar('Data - Score View'));
/* end Score View Tracking */
/* Features Used - Legacy Method */
(function(sFeatureUsed){
_satellite.notify('KIWI: Feature Used found: ' + sFeatureUsed);
if (sFeatureUsed) {
s.linkTrackVars=s.apl(s.linkTrackVars, 'prop43', ',', 2);
s.prop43 = s.apl(s.prop43, sFeatureUsed, '^', 2); //Features Used
if (kiwi._timesThruDoPlugins) {
//clear out page-tracked feature used...
if (cbTrackData.featureUsed) cbTrackData.featureUsed = '';
if (cbTrackData.user && cbTrackData.user.featureUsed) cbTrackData.user.featureUsed = ''; //legacy DDL settings by BF Mobile
var ddlEvents = _satellite.getVar('DDL Events');
if (ddlEvents && ddlEvents.length) {
var deleteIdx = 0;
for (var i = 1; i < ddlEvents.length + 1; i++) {
var e = ddlEvents[i-1];
if (
typeof e.eventInfo !== 'undefined'
&& typeof e.eventInfo.eventName !== 'undefined'
&& e.eventInfo.eventName == 'Feature Used'
) {
deleteIdx = i-1;
break;
}
}
ddlEvents[deleteIdx] = {};
}
}
}
})(_satellite.getVar('Feature Used'));
/* end Features Used - Legacy Method */
/* Feature Views */
kiwi.trackFeatureViews = function(featData, featId) {
ruleName = 'KIWI: kiwi.trackFeatureViews';
//var featData = _satellite.getVar(featDataName);
if (featData && featData.hasData) {
_satellite.notify(ruleName + ': ' + featId + ' found: ' + JSON.stringify(featData));
kiwi.cookie.sess.features[featId] = kiwi.cookie.sess.features[featId] || {};
for (var i = 0; i < featData.featureNames.length; i++) {
var featureName = featData.featureNames[i],
bAlreadyInSess = (kiwi.cookie.sess.features[featId][kiwi._thisPage.siteCode] &&
kiwi.cookie.sess.features[featId][kiwi._thisPage.siteCode].hasOwnProperty(featureName));
//report these things only once per session cookie + featureName instance
if(!bAlreadyInSess && !featData.wireUpOnly) {
s.linkTrackVars=s.apl(s.linkTrackVars, 'eVar34', ',', 2);
s.linkTrackVars=s.apl(s.linkTrackVars, 'prop43', ',', 2);
s.linkTrackVars=s.apl(s.linkTrackVars, 'events', ',', 2);
s.linkTrackEvents=s.apl(s.linkTrackEvents, 'event242', ',', 2);
s.eVar34 = 'D=pageName'; //Feature Page
s.prop43 = s.apl(s.prop43, featData.featureType + ':' + featureName, '^', 2); //Features Used
s.events = s.apl(s.events, 'event242', ',', 2); //Feature Views
switch (featId) {
case 'filters':
s.linkTrackEvents=s.apl(s.linkTrackEvents, 'event240', ',', 2);
s.events = s.apl(s.events, 'event240', ',', 2); //Filter Views
break;
default:
break;
}
kiwi._sessCookieMod = true;
kiwi.cookie.sess.features[featId][kiwi._thisPage.siteCode] = kiwi.cookie.sess.features[featId][kiwi._thisPage.siteCode] || {};
kiwi.cookie.sess.features[featId][kiwi._thisPage.siteCode][featureName] = 0;
}
//report these things regardless of featureName instance
switch (featId) {
/*case 'lnavtop':
//s.linkTrackVars=s.apl(s.linkTrackEvents, 'event220', ',', 2);
//s.events = s.apl(s.events, 'event220', ',', 2); //Global Header Nav Views
break;*/
case 'widget':
switch (featureName) {
case 'header':
s.linkTrackEvents=s.apl(s.linkTrackEvents, 'event220', ',', 2);
s.events = s.apl(s.events, 'event220', ',', 2); //Global Header Nav Views
break;
case 'footer':
s.linkTrackEvents=s.apl(s.linkTrackEvents, 'event222', ',', 2);
s.events = s.apl(s.events, 'event222', ',', 2); //Global Footer Nav Views
break;
case 'identity':
if (kiwi.userIsLoggedIn) {
s.linkTrackEvents=s.apl(s.linkTrackEvents, 'event232', ',', 2);
s.events = s.apl(s.events, 'event232', ',', 2); //Global Login Nav Views
} else {
s.linkTrackEvents=s.apl(s.linkTrackEvents, 'event230', ',', 2);
s.events = s.apl(s.events, 'event230', ',', 2); //Global Student/Prof Nav Views
}
break;
case 'bfcl':
s.linkTrackVars = s.apl(s.linkTrackVars, 'prop34', ',', 2);
s.prop34 = 'bfcl:bar'; //Widget Screen
break;
default:
break;
}
break;
default:
break;
}
//indicate auto-sugg term results in DOM
if (kiwi.cookie.sess.prev['isQuick']) {
var elSS = document.querySelector('[data-cbtrack-widget="sitesearch"], .lv-search-widget');
if (elSS) {elSS.setAttribute('data-cbtrack-autosuggtermused','');}
}
//check for site search promo views
var ssBannerViews = [],
bannerAreas = document.querySelectorAll('[data-cbtrack-searchbanner], #sitesearch .lv-banner, #sitesearch .lv-no-results');
for (var m = 0; m < bannerAreas.length; m++) {
var oPromoPrefixMap = {'trustee_search':'feat','related_search':'rel','noresults':'noresults'},
myBanner = bannerAreas[m],
myBannerType = myBanner.getAttribute('data-cbtrack-searchbanner') || '',
myBannerArea = myBannerType?oPromoPrefixMap[myBannerType]:'';
if (!myBannerArea) {//legacy site search widget banner elements
myBannerArea = myBanner.classList.contains('lv-banner-type-related_search')?'rel':myBannerArea;
myBannerArea = myBanner.classList.contains('lv-banner-type-trustee_search')?'feat':myBannerArea;
myBannerArea = myBanner.classList.contains('lv-no-results')?'noresults':myBannerArea;
}
var myBannerEls = myBanner.querySelectorAll('a');
for (var n = 0; n < myBannerEls.length; n++) {
var bannerPromoView = 'ss:'+myBannerArea+':',
myBannerEl = myBannerEls[n],
myBannerViewAlreadyTracked = (!!myBannerEl.hasAttribute('data-kiwi-promo-view')),
myBannerLinkAlreadyTracked = (!!myBannerEl.hasAttribute('data-kiwi-promo-link'));
//track view
if (!myBannerViewAlreadyTracked) {
bannerPromoView += myBannerEl.getAttribute('data-cbtrack-label') || kiwi.util.getFeatureText(myBannerEl);
ssBannerViews.push(bannerPromoView);
myBannerEl.setAttribute('data-kiwi-promo-view', '');
}
//track link
if (!myBannerLinkAlreadyTracked) {
_satellite.notify(ruleName+': wiring up site search promo/banner links');
var alreadyWired = false;
if ((myBannerEl.hasAttribute('data-kiwi-sspromo-link'))) {alreadyWired = true;}
if (!alreadyWired) {myBannerEl.setAttribute('data-kiwi-sspromo-link', bannerPromoView);}
//prevent tracking by legacy promo 2019 code
myBannerEl.setAttribute('data-kiwi-promo-link', '');
myBannerEl.removeAttribute('data-cb-adcode', '');
myBannerEl.removeAttribute('trackclickvalue', '');
}
}
}
if (ssBannerViews.length) {
s.linkTrackEvents=s.apl(s.linkTrackEvents, 'event56', ',', 2);
s.events = s.apl(s.events, 'event56', ',', 2);
s.linkTrackVars = s.apl(s.linkTrackVars, 'events', ',', 2);
s.linkTrackVars = s.apl(s.linkTrackVars, 'list3', ',', 2);
for (var ssb = 0; ssb < ssBannerViews.length; ssb++) {
s.list3 = s.apl(s.list3, ssBannerViews[ssb], ',', 2); //Promos (CTR) 2019
}
}
//check for other promo views
var promoViews = [],
els = {},
promoViewPrefix = '';
//Widget Screen Els vs. Other Feature Els
if (featData.widgetName) {
promoViewPrefix = 'widget:'+ featData.widgetName + ':' + featureName + ':';
els = document.querySelectorAll('[data-cbtrack-widget="'+featData.widgetName+'"] [data-cbtrack-linkgroup="'+featureName+'"]');
} else {
promoViewPrefix = kiwi._thisPage.siteCode + ':' + featData.featureType + ':' + featureName + ':';
els = document.querySelectorAll('[data-cbtrack-'+ featId +'="'+featureName+'"]');
}
for (var j = 0; j < els.length; j++) {
var promoEls = els[j].querySelectorAll('[data-cbtrack-promo], [data-cbtrack-linktype*="promo"]');
for (var k = 0; k < promoEls.length; k++) {
function isHidden(el) {
var isHidden = false,
style = window.getComputedStyle(el);
isHidden = ((style.display === 'none') || (style.visibility === 'hidden'));
if (!isHidden && kiwi.util.getClosest) {
isHidden = !!(kiwi.util.getClosest(el, '[aria-hidden="true"]'));
}
return isHidden;
}
if (!isHidden(promoEls[k])) {
var promoView = promoViewPrefix;
promoView += kiwi.util.getFeatureText(promoEls[k]);
promoViews.push(promoView);
//prevent tracking by promo 2019 code
promoEls[k].setAttribute('data-kiwi-promo-link', '');
if (featData.widgetScreenName) {promoEls[k].setAttribute('data-kiwi-widgetscreenname', featData.widgetScreenName);}
}
}
}
if (promoViews.length) {
s.linkTrackEvents=s.apl(s.linkTrackEvents, 'event56', ',', 2);
if (kiwi._thisPage.siteSettings.use2017promos) {
s.linkTrackEvents=s.apl(s.linkTrackEvents, 'event98', ',', 2);
s.linkTrackEvents=s.apl(s.linkTrackEvents, 'event12', ',', 2);
s.events = s.apl(s.events, 'event98', ',', 2);
s.events = s.apl(s.events, 'event12', ',', 2);
s.linkTrackVars = s.apl(s.linkTrackVars, 'list1', ',', 2);
}
s.events = s.apl(s.events, 'event56', ',', 2);
s.linkTrackVars = s.apl(s.linkTrackVars, 'events', ',', 2);
s.linkTrackVars = s.apl(s.linkTrackVars, 'list3', ',', 2);
for (var iPv = 0; iPv < promoViews.length; iPv++) {
if (kiwi._thisPage.siteSettings.use2017promos) {
s.list1 = s.apl(s.list1, promoViews[iPv], ',', 2); //Promos (CTR)
}
s.list3 = s.apl(s.list3, promoViews[iPv], ',', 2); //Promos (CTR) 2019
}
}
}
}
};
if (!cbTrackData || !cbTrackData.siteCode || cbTrackData.siteCode !== 'bfm') {
kiwi.trackFeatureViews(_satellite.getVar('Feature Views - Accordions'), 'accordion');
kiwi.trackFeatureViews(_satellite.getVar('Feature Views - Crosslinks'), 'crosslink');
kiwi.trackFeatureViews(_satellite.getVar('Feature Views - CTA Cards'), 'ctacard');
kiwi.trackFeatureViews(_satellite.getVar('Feature Views - Event Cards'), 'ec');
kiwi.trackFeatureViews(_satellite.getVar('Feature Views - Filters'), 'filter');
kiwi.trackFeatureViews(_satellite.getVar('Feature Views - Jump Links'), 'jumplinks');
kiwi.trackFeatureViews(_satellite.getVar('Feature Views - Key Benefits'), 'keybenefits');
kiwi.trackFeatureViews(_satellite.getVar('Feature Views - Layout Panels'), 'layp');
//kiwi.trackFeatureViews(_satellite.getVar('Feature Views - Local Nav Top'), 'lnavtop');
kiwi.trackFeatureViews(_satellite.getVar('Feature Views - Custom'), 'custom');
kiwi.trackFeatureViews(_satellite.getVar('Feature Views - Features'), 'feature');
}
if (kiwi.widgetTrack) kiwi.trackFeatureViews(_satellite.getVar('Feature Views - Widgets'), 'widget');
/* end Feature Views */
/* Feature Clicks */
kiwi.trackFeatureClicks = function(featData, featId) {
ruleName = 'KIWI: kiwi.trackFeatureClicks';
//var featData = _satellite.getVar(featDataName);
if (featData && featData.hasData) {
_satellite.notify(ruleName + ': ' + featId + ' found: ' + JSON.stringify(featData));
s.eVar34 = 'D=c25'; //Feature Page
s.prop43 = featData.featureType + ':' + featData.featureName; //Features Used
s.prop29 = featData.featureOptions; //Feature Options Used
var usageCount = 0;
try {usageCount = kiwi.cookie.sess.features[featId][kiwi._thisPage.siteCode][featData.featureName];}
catch(e) {_satellite.notify('Kiwi: ' + featId + ' cookie issue for Usage Count');}
if (parseInt(usageCount, 10)) {
//track additional usage as additional views, to keep CTR in good shape
s.events = s.apl(s.events, 'event242', ',', 2); //Feature Views
switch (featId) {
case 'filter':
s.linkTrackEvents=s.apl(s.linkTrackEvents, 'event240', ',', 2);
s.events = s.apl(s.events, 'event240', ',', 2); //Filter Views
break;
default:
break;
}
}
usageCount += 1;
s.events = s.apl(s.events, 'event243', ',', 2); //Feature Clicks
s.prop30 = usageCount; //Feature Used Count
s.linkTrackVars=s.apl(s.linkTrackVars, 'eVar34', ',', 2);
s.linkTrackVars=s.apl(s.linkTrackVars, 'prop43', ',', 2);
s.linkTrackVars=s.apl(s.linkTrackVars, 'events', ',', 2);
s.linkTrackVars=s.apl(s.linkTrackVars, 'prop29', ',', 2);
s.linkTrackVars=s.apl(s.linkTrackVars, 'prop30', ',', 2);
s.linkTrackEvents=s.apl(s.linkTrackEvents, 'event242', ',', 2);
s.linkTrackEvents=s.apl(s.linkTrackEvents, 'event243', ',', 2);
kiwi._sessCookieMod = true;
kiwi.cookie.sess.features[featId][kiwi._thisPage.siteCode] = kiwi.cookie.sess.features[featId][kiwi._thisPage.siteCode] || {};
kiwi.cookie.sess.features[featId][kiwi._thisPage.siteCode][featData.featureName] = usageCount;
//track additional things by feature type
switch (featId) {
case 'filter':
s.linkTrackEvents=s.apl(s.linkTrackEvents, 'event241', ',', 2);
s.events = s.apl(s.events, 'event241', ',', 2); //Filter Applies
break;
case 'widget':
//check for widgetScreen
if (featData.widgetScreenName) {
s.linkTrackVars = s.apl(s.linkTrackVars, 'prop34', ',', 2);
s.prop34 = featData.widgetScreenName; //Widget Screen
}
break;
default:
break;
}
//check for nav clicks
if (featData.linkTypes.match(/(^|,)nav(,|$)/i)) {
switch (featData.featureName) {
case 'header':
s.linkTrackEvents=s.apl(s.linkTrackEvents, 'event221', ',', 2);
s.events = s.apl(s.events, 'event221', ',', 2); //Global Header Nav Clicks
s.eVar61 = kiwi._thisPage.siteCode + ':' + featData.featureOptions;
s.eVar61 = s.getValOnce(s.eVar61, 'gvo_v61', 0); //Global Nav ID 2019
if (s.eVar61) {
s.linkTrackVars=s.apl(s.linkTrackVars, 'eVar61', ',', 2);
s.linkTrackEvents=s.apl(s.linkTrackEvents, 'event70', ',', 2);
s.events = s.apl(s.events, 'event70', ',', 2); //Global Nav Clicks
}
break;
case 'footer':
s.linkTrackEvents=s.apl(s.linkTrackEvents, 'event223', ',', 2);
s.events = s.apl(s.events, 'event223', ',', 2); //Global Footer Nav Clicks
s.eVar61 = kiwi._thisPage.siteCode + ':' + featData.featureOptions;
s.eVar61 = s.getValOnce(s.eVar61, 'gvo_v61', 0); //Global Nav ID 2019
if (s.eVar61) {
s.linkTrackVars=s.apl(s.linkTrackVars, 'eVar61', ',', 2);
s.linkTrackEvents=s.apl(s.linkTrackEvents, 'event70', ',', 2);
s.events = s.apl(s.events, 'event70', ',', 2); //Global Nav Clicks
}
break;
case 'identity':
if (kiwi.userIsLoggedIn) {
s.linkTrackEvents=s.apl(s.linkTrackEvents, 'event233', ',', 2);
s.events = s.apl(s.events, 'event233', ',', 2); //Student/Prof Nav Clicks
s.eVar61 = kiwi._thisPage.siteCode + ':' + featData.featureOptions;
s.eVar61 = s.getValOnce(s.eVar61, 'gvo_v61', 0); //Global Nav ID 2019
if (s.eVar61) {
s.linkTrackVars=s.apl(s.linkTrackVars, 'eVar61', ',', 2);
s.linkTrackEvents=s.apl(s.linkTrackEvents, 'event70', ',', 2);
s.events = s.apl(s.events, 'event70', ',', 2); //Global Nav Clicks
}
} else {
s.linkTrackEvents=s.apl(s.linkTrackEvents, 'event231', ',', 2);
s.events = s.apl(s.events, 'event231', ',', 2); //Identity Pre-Auth Clicks
s.eVar61 = kiwi._thisPage.siteCode + ':' + featData.featureOptions;
s.eVar61 = s.getValOnce(s.eVar61, 'gvo_v61', 0); //Global Nav ID 2019
if (s.eVar61) {
s.linkTrackVars=s.apl(s.linkTrackVars, 'eVar61', ',', 2);
s.linkTrackEvents=s.apl(s.linkTrackEvents, 'event70', ',', 2);
s.events = s.apl(s.events, 'event70', ',', 2); //Global Nav Clicks
}
}
break;
default:
break;
}
}
var promoName = '',
blnTrack2017 = blnTrack2019 = true;
//check for sspromo clicks
if (featData.ssPromoName) {
promoName = featData.ssPromoName;
blnTrack2017 = false;
} else if (featData.linkTypes.match(/(^|,)promo(,|$)/i)) {
//check for other promo clicks
if (featId==='widget') {
promoName = featData.featureType + ':' + featData.featureName + ':' + featData.featureOptions;
} else {
promoName = kiwi._thisPage.siteCode + ':' + featData.featureType + ':' + featData.featureName + ':' + featData.featureOptions;
}
}
//track promo clicks
if (promoName) {
s.linkTrackVars = s.apl(s.linkTrackVars, 'events', ',', 2);
if (blnTrack2017 && kiwi._thisPage.siteSettings.use2017promos) {
s.events=s.apl(s.events, 'event99', ',', 2); //Promo Clicks
s.list1 = promoName; //Promos (CTR)
s.list2 = promoName; //Promos (Conv)
s.linkTrackEvents=s.apl(s.linkTrackEvents, 'event99', ',', 2);
s.linkTrackVars = s.apl(s.linkTrackVars, 'list1', ',', 2);
s.linkTrackVars = s.apl(s.linkTrackVars, 'list2', ',', 2);
_satellite.notify('KIWI: Promo 2017 Tracked: ' + promoName);
}
if (blnTrack2019) {
s.events=s.apl(s.events, 'event57', ',', 2); //Promo Clicks 2019
s.list3 = promoName; //Promos (CTR) 2019
s.eVar18 = promoName; //Promos (Conv) 2019
s.linkTrackEvents=s.apl(s.linkTrackEvents, 'event57', ',', 2);
s.linkTrackVars = s.apl(s.linkTrackVars, 'list3', ',', 2);
s.linkTrackVars = s.apl(s.linkTrackVars, 'eVar18', ',', 2);
_satellite.notify('KIWI: Promo 2019 Tracked: ' + promoName);
}
}
}
};
if (s.linkType === 'o') {
if (s.linkName === 'Feature Used - Accordion') kiwi.trackFeatureClicks(_satellite.getVar('Feature Clicks - Accordion'), 'accordion');
if (s.linkName === 'Feature Used - Crosslink') kiwi.trackFeatureClicks(_satellite.getVar('Feature Clicks - Crosslink'), 'crosslink');
if (s.linkName === 'Feature Used - CTA Card') kiwi.trackFeatureClicks(_satellite.getVar('Feature Clicks - CTA Card'), 'ctacard');
if (s.linkName === 'Feature Used - Event Card') kiwi.trackFeatureClicks(_satellite.getVar('Feature Clicks - Event Card'), 'ec');
if (s.linkName === 'Feature Used - Filter') kiwi.trackFeatureClicks(_satellite.getVar('Feature Clicks - Filter'), 'filter');
if (s.linkName === 'Feature Used - Jump Link') kiwi.trackFeatureClicks(_satellite.getVar('Feature Clicks - Jump Link'), 'jumplinks');
if (s.linkName === 'Feature Used - Key Benefit') kiwi.trackFeatureClicks(_satellite.getVar('Feature Clicks - Key Benefits'), 'keybenefits');
if (s.linkName === 'Feature Used - Layout Panel') kiwi.trackFeatureClicks(_satellite.getVar('Feature Clicks - Layout Panel'), 'layp');
//if (s.linkName === 'Feature Used - Local Nav Top') kiwi.trackFeatureClicks(_satellite.getVar('Feature Clicks - Local Nav Top'), 'lnavtop');
if (s.linkName === 'Feature Used - Widget') kiwi.trackFeatureClicks(_satellite.getVar('Feature Clicks - Widget'), 'widget');
if (s.linkName === 'Feature Used - Custom') kiwi.trackFeatureClicks(_satellite.getVar('Feature Clicks - Custom'), 'custom');
if (s.linkName === 'Feature Used - Feature') kiwi.trackFeatureClicks(_satellite.getVar('Feature Clicks - Feature'), 'feature');
}
/* end Feature Clicks */
/* Atlas Widgets */
kiwi.trackWidgetScreenView = function(widgetName, widgetScreenName, blnTrackFeatureViews) {
ruleName = 'kiwi.trackWidgetScreenView';
widgetName = widgetName || '';
widgetScreenName = widgetScreenName || '';
blnTrackFeatureViews = blnTrackFeatureViews || true;
var widgetScreen = widgetScreenName?widgetScreenName:'no-screen-found';
widgetScreen = widgetName+':'+widgetScreen;
if (kiwi._autoshown) {widgetScreen += ':autoshown';}
s.linkTrackVars = s.apl(s.linkTrackVars, 'prop34', ',', 2);
s.prop34 = widgetScreen; //Widget Screen
_satellite.notify(ruleName+ ': ' + widgetScreen);
//Feature Clicks, if not page track
if (s.linkType) {
kiwi.trackFeatureClicks({
hasData: true,
featureType: 'widget',
featureName: widgetName,
featureOptions: [widgetScreenName],
linkTypes: '',
widgetScreen: widgetScreen
}, 'widget');
}
if (blnTrackFeatureViews) {
//Feature Views (and Promos)
kiwi.trackFeatureViews({
hasData: true,
featureType: 'widget:'+widgetName,
featureNames: [widgetScreenName],
widgetName: widgetName,
widgetScreen: widgetScreen,
wireUpOnly: true
}, 'widget:'+widgetName);
}
//reset
kiwi._autoshown = false;
};
if (kiwi.widgetTrack) {//ensure only reporting on widgets ready call
(function(oData) {
if (oData && oData.hasData) {
_satellite.notify('KIWI: Atlas Widgets Data processed: ' + 'JSON.stringify(oData)');
var linkTrackVars = 'events,prop26',
linkTrackEvents = 'event194';
linkTrackVars += oData.widgetLoads?',prop27':'';
linkTrackVars += oData.widgetFails?',prop28':'';
linkTrackVars += oData.widgetServices?',prop23':'';
linkTrackVars += oData.loadSpeed?',eVar91':'';
linkTrackVars += oData.errorType?',prop11,prop12,prop13':'';
linkTrackEvents += oData.widgetServices?',event195':'';
s.linkTrackVars=s.apl(s.linkTrackVars, linkTrackVars, ',', 2);
s.linkTrackEvents=s.apl(s.linkTrackEvents, linkTrackEvents, ',', 2);
s.events = s.apl(s.events, linkTrackEvents, ',', 2); //Atlas Widget Ready Calls, Atlas Widget with Service Ready Calls
s.prop26 = oData.widgets; //Atlas Widgets Attempted
s.prop27 = oData.widgetLoads; //Atlas Widgets Loaded
s.prop28 = oData.widgetFails; //Atlas Widgets Failed
s.prop23 = oData.widgetServices; //Atlas Widget Services Requested
if (oData.loadSpeed) s.eVar91 = oData.loadSpeed; //Service Backed Element Load Speed
if (oData.errorType) {
s.prop11 = oData.errorType; //Error Type
s.prop12 = oData.errorCode; //Error Code
s.prop13 = 'D=pageName'; //Page with Error
}
if (oData.widgets.match(/(^|\^)bfcl($|\^)/i)) {
kiwi.trackWidgetScreenView('bfcl','bar', false);
}
}
})(_satellite.getVar('Feature Views - Widgets'));
//update ddl reported flags
Object.keys(kiwi.ddl.atlas).forEach(function (widget) {
this[widget].isNew = false;
if (this[widget].components && typeof this[widget].components === 'object') {
Object.keys(this[widget].components).forEach(function (component) {
this[component].isNew = false;
this[component].serviceStartIndex += this[component].totalNewServices;
this[component].totalNewServices = 0;
//this[component].services = {}; //remove prior reported services so repeat calls get reported
if(this[component].services && typeof this[component].services === 'object') {
Object.keys(this[component].services).forEach(function (service) {
this[service].isNew = false;
}, this[component].services);
}
}, this[widget].components);
}
}, kiwi.ddl.atlas);
}
/* end Atlas Widgets */
/* Internal Searches */
(function(oData){
if (oData && oData.hasData) {
//de-dupe page refreshes
kiwi.util = kiwi.util || {};
var searchDataPersist = {term: oData.term, type: oData.type, facet: oData.facet},
cv = JSON.stringify(searchDataPersist),
pv = kiwi.util.previousValue(cv, 'searchData') || '';
if (cv !== pv) {
s.events = s.apl(s.events, 'event1', ',', 2); //Internal Searches
s.eVar1 = oData.term; //Internal Search Term
s.eVar3 = oData.type; //Internal Search Type
s.prop2 = oData.count; //Total Search Results
s.prop73 = oData.speed; //Search Results Speed
s.eVar52 = oData.facet; //Search Results Facet
if (oData.isQuick) {
s.events = s.apl(s.events, 'event117', ',', 2); //Auto-Suggested Term Searches
s.eVar9 = oData.term; //Auto-Suggested Search Term
}
var oSearchTypes = _satellite.getVar('Kiwi Config - Search Types'),
mySearchTypeEvent = oSearchTypes[oData.type] || oSearchTypes['generic-site'];
if (mySearchTypeEvent) {
s.events = s.apl(s.events, mySearchTypeEvent, ',', 2); //...Various Search Types...
} else if (mySearchTypeEvent.match(/site/i)) {
//generic "site" search
s.events = s.apl(s.events, 'event3', ',', 2); //Site Searches
}
if (s.events.match(/(,|^)event3(,|$)/i)) {
s.eVar35 = 'D=c52'; //Site Search Origin Page
}
}
//Feature Views (and Promos)
kiwi.trackFeatureViews({
hasData: true,
featureType: 'srch',
featureNames: [oData.term]
}, 'srch');
}
//reset Quick search
kiwi.cookie.sess.prev['isQuick'] = false;
kiwi._sessCookieMod = true; //signal sess cookie updates
})(_satellite.getVar('Search Data'));
/* end Internal Searches */
/* Get Site Control Modals */
if (s.pageName.match(/getsitecontrol-/i)) {
s.prop25 = _satellite.getVar('Derived Page Name'); //Page Sending Custom Link
s.list1 = 'D=pageName'; // Promos (CTR)
s.events = s.apl(s.events, 'event98', ',', 2); //Promo Views
}
/* end Get Site Control Modals */
/* CBOS Optins */
if (kiwi._thisPage.siteCode === 'opportunity' &&
kiwi._thisPage.pageCode === 'my-action-plan' &&
kiwi.user.cbId &&
kiwi.user.gradYear.match(/[0-9]{4}/i)) {
s.events = s.apl(s.events, 'event34:'+kiwi.user.cbId+'-'+kiwi.user.gradYear, ',', 2); //CBOS Opt Ins
}
/* end CBOS Optins */
/* Custom Links */
kiwi._elementToTest = kiwi._elementToTest || false;
if (s.linkType) {
s.prop25 = s.pageName; //Page Sending Custom Link
/* URL Processing */
var elem = kiwi._elementToTest,
url = '';
if (elem && elem.href) {
url = elem.href.toLowerCase();
//remove affiliateId/bannerId params
var urlParts = url.split('?');
if (urlParts[1]) {
urlParts[1] = urlParts[1].replace(/&affiliateId(=[^&]*)?|^affiliateId(=[^&]*)?&?/i, '');
urlParts[1] = urlParts[1].replace(/&bannerId(=[^&]*)?|^bannerId(=[^&]*)?&?/i, '');
if (urlParts[1]) url = urlParts.join('?');
else url = urlParts[0];
}
}
/* end URL Processing */
/* Exit Links */
if (s.linkType === 'e' && url) {
s.linkName = url;
s.linkTrackVars = s.apl(s.linkTrackVars, 'prop24', ',', 2);
s.prop24 = url; //Exit Link
s.prop1 = 'EXTLINK|'+s.prop24;
s.linkTrackVars=s.apl(s.linkTrackVars, 'prop24', ',', 2);
}
/* end Exit Links */
/* Download/Dynamic/Triggered Download Links */
if (s.linkType === 'd' && s.linkName === 'Triggered Download Link') {
url = _satellite.getVar('DDL - Download');
}
if ((s.linkType === 'd' && url) ||
(s.linkType === 'o' && s.linkName === 'Dynamic Download Link')) {
if (s.linkType === 'd') {
s.linkName = url;
} else {
url = s.prop32 + '/dynamic-asset/';
if (elem.attributes['data-cbtrack-download']) {
url += elem.attributes['data-cbtrack-download'].value.replace(/:/gi, '-');
} else if (elem.attributes['download']) {
url += elem.attributes['download'].value.replace(/:/gi, '-');
} else if (elem.attributes['dynamic-asset-link-track']) {
url += elem.attributes['dynamic-asset-link-track'].value.replace(/:/gi, '-');
}
s.linkName += ': ' + url;
}
s.linkTrackVars = s.apl(s.linkTrackVars, 'prop10', ',', 2);
s.hier1 = 'D=c10';
s.eVar4 = 'D=c10';
kiwi._urlToParse = url;
kiwi._parsingDownloadLink = true;
s.prop10 = _satellite.getVar('Page Name'); //Download PageName
s.prop1 = 'DOWNLOAD|'+s.prop10;
s.linkTrackVars=s.apl(s.linkTrackVars, 'prop1', ',', 2);
//reset urlToParse after parsed
kiwi._urlToParse = '';
kiwi._parsingDownloadLink = false;
}
/* end Download/Dynamic Download Links */
if (s.linkType === 'o') {
s.linkTrackVars = s.apl(s.linkTrackVars, 'prop1', ',', 2);
s.prop1 = 'CUSTOM|'+s.linkName;
var customLinkActions = {
/* Application Error Link Tracking */
// see DDL > error.json.js for examples of how this feature is used
'Application Error': function() {
var oData = _satellite.getVar('AA - Application Error');
if (oData) {
s.events = s.apl(s.events, 'event193', ',', 2); //Application Errors
s.linkTrackVars=s.apl(s.linkTrackVars, 'events', ',', 2);
s.linkTrackEvents=s.apl(s.linkTrackEvents, 'event193', ',', 2);
s.prop4 = oData; //Application Error Code/Message
s.prop11 = 'application-error'; //Error Type
s.prop12 = oData.split(':')[0]; //Error Code
s.prop13 = 'D=25'; //Page with Error
s.linkTrackVars=s.apl(s.linkTrackVars, 'prop4', ',', 2);
s.linkTrackVars=s.apl(s.linkTrackVars, 'prop11', ',', 2);
s.linkTrackVars=s.apl(s.linkTrackVars, 'prop12', ',', 2);
s.linkTrackVars=s.apl(s.linkTrackVars, 'prop13', ',', 2);
//TODO: remove promo tracking events and evars
}
//reset data
kiwi.ddl.appError = {};
},
'Cookie Consent Banner': function() {
s.linkTrackVars = s.apl(s.linkTrackVars, 'prop43', ',', 2);
s.prop43 = 'one trust:cookie consent banner';
},
'Promo Click getsitecontrol': function() {
s.events = s.apl(s.events, 'event99', ',', 2); //Promo Clicks
s.list1 = 'D=pageName'; // Promos (CTR)
s.list2 = 'D=pageName'; // Promos (Conv)
s.linkTrackVars = s.apl(s.linkTrackVars, 'events', ',', 2);
s.linkTrackVars = s.apl(s.linkTrackVars, 'list1', ',', 2);
s.linkTrackVars = s.apl(s.linkTrackVars, 'list2', ',', 2);
s.linkTrackEvents = s.apl(s.linkTrackEvents, 'event99', ',', 2);
//modify page name
s.prop25 = _satellite.getVar('Derived Page Name'); //Page Sending Custom Link
},
/* Widget Display Changes (Old Style Widgets) */
'Widget Display Change': function() {
var oData = _satellite.getVar('Data - Widget Display');
s.list1 = ''; //Promos (CTR)
if (oData && oData.screen) {
_satellite.notify('KIWI: Widget Display Data found!');
s.linkTrackVars = s.apl(s.linkTrackVars, 'prop34', ',', 2);
s.prop34 = oData.screen; //Widget Screen
kiwi.lotag = oData.screen; //Lucky Orange Behavior Tag
/* Begin Lucky Orange */
if (kiwi.lotag &&
kiwi.lotag.match(/^(dop-generic|dop-scores-ot|dop-scores-aot)$/i)) {
window._loq = window._loq || []; // ensure queue available
window._loq.push(['tag', kiwi.lotag]); // this will tag, won't star, and will append the tag
}
/* End Lucky Orange */
if (oData.promos) {
s.events = s.apl(s.events, 'event98', ',', 2); //Promo Views
s.events = s.apl(s.events, 'event12', ',', 2); //Internal Campaign Views (legacy)
s.list1 = oData.promos; //Promos (CTR)
s.linkTrackVars = s.apl(s.linkTrackVars, 'events', ',', 2);
s.linkTrackVars = s.apl(s.linkTrackVars, 'list1', ',', 2);
s.linkTrackEvents = s.apl(s.linkTrackEvents, 'event98', ',', 2);
s.linkTrackEvents = s.apl(s.linkTrackEvents, 'event12', ',', 2);
}
if (oData.navs) {
s.linkTrackVars = s.apl(s.linkTrackVars, 'events', ',', 2);
s.linkTrackEvents=s.apl(s.linkTrackEvents, oData.navs, ',', 2);
s.events = s.apl(s.events, oData.navs, ',', 2); //[xyz] Nav Views
}
}
},
'AP Exam Intent Form Submit': function() {
var oData = _satellite.getVar('Data - AP Exam Intent');
if (oData && oData.hasData) {
_satellite.notify('KIWI: Data - AP Exam Intent found: ' + JSON.stringify(oData));
/**
* pattern: [Poll ID]:[Submitted Date];[AP Exam]:[count each yes/uns/no];[AP YouTube]:[y/n];[AP Prac]:[y/n]
* eg: ap1:20200413;ex:y00|u01|n02;yt:ys;pr:no
*/
s.eVar92 = oData.pollResponse; //SFMC Poll Responses
s.events = s.apl(s.events, 'event192', ',', 2); //SFMC Poll Submissions
s.linkTrackVars=s.apl(s.linkTrackVars, 'events', ',', 2);
s.linkTrackVars=s.apl(s.linkTrackVars, 'eVar92', ',', 2);
s.linkTrackEvents=s.apl(s.linkTrackEvents, 'event192', ',', 2);
}
},
'Parent Opt In Form Submit': function() {
var oData = _satellite.getVar('Data - Parent Opt In');
if (oData && oData.hasData) {
_satellite.notify('KIWI: Data - Parent Opt In found: ' + JSON.stringify(oData));
s.eVar84 = oData.gradYears; //Parent Opted Grad Years
if (oData.serializeEmail) s.events = s.apl(s.events, 'event114:'+oData.serializeEmail, ',', 2); //Parent Email Opt-Ins
if (oData.serializeText) s.events = s.apl(s.events, 'event115:'+oData.serializeText, ',', 2); //Parent Text Opt-Ins
s.linkTrackVars=s.apl(s.linkTrackVars, 'events,eVar84', ',', 2);
s.linkTrackEvents=s.apl(s.linkTrackEvents, 'event114,event115', ',', 2);
}
},
'Iframe Report Link': function() {
kiwi.pageCodeOverride = 'reports:' + _satellite.getVar('Data - IFrame Report Name');
s.eVar74 = kiwi._thisPage.siteCode + ':' + kiwi.pageCodeOverride; //BI Report Name
s.events = s.apl(s.events, 'event89', ',', 2); //BI Report Requested
s.linkTrackVars=s.apl(s.linkTrackVars, 'events,eVar74', ',', 2);
s.linkTrackEvents=s.apl(s.linkTrackEvents, 'event89', ',', 2);
},
'CBOS Terms Accept': function() {
kiwi.util.fireCustomEvent('CBOS Terms Accept');
s.abort = true;
},
'Confirm ECL Account Create': function() {
kiwi.util.fireCustomEvent('Confirm ECL Account Create');
s.abort = true;
},
/* Low Income/Fee Waivers Form Opt Ins/Outs */
'LIFW Opt In Form Submit': function() {
var oData = _satellite.getVar('Data - LIFW Form');
if (oData && oData.hasData) {
var serializeVal = kiwi.user.cbId+'-'+kiwi.user.gradYear;
_satellite.notify('KIWI: Data - LIFW Form found: ' + JSON.stringify(oData));
if (oData.liQualOption) s.events = s.apl(s.events, 'event35:'+serializeVal, ',', 2); //LIFW Opt Ins
else s.events = s.apl(s.events, 'event36:'+serializeVal, ',', 2); //LIFW Opt Outs
s.linkTrackVars=s.apl(s.linkTrackVars, 'events', ',', 2);
s.linkTrackEvents=s.apl(s.linkTrackEvents, 'event35,event36', ',', 2);
}
},
/* Low Income/Fee Waivers Link Opt Ins */
'LIFW Opt In': function() {
var serializeVal = kiwi.user.cbId+'-'+kiwi.user.gradYear;
s.events = s.apl(s.events, 'event35:'+serializeVal, ',', 2); //LIFW Opt Ins
s.linkTrackVars=s.apl(s.linkTrackVars, 'events', ',', 2);
s.linkTrackEvents=s.apl(s.linkTrackEvents, 'event35', ',', 2);
},
/* Low Income/Fee Waivers Link Opt Outs */
'LIFW Opt Out': function() {
var serializeVal = kiwi.user.cbId+'-'+kiwi.user.gradYear;
s.events = s.apl(s.events, 'event36:'+serializeVal, ',', 2); //LIFW Opt Outs
s.linkTrackVars=s.apl(s.linkTrackVars, 'events', ',', 2);
s.linkTrackEvents=s.apl(s.linkTrackEvents, 'event36', ',', 2);
},
/* CBOS DCR Link Track Events */
// see DDL > CBOS > my-action-plan.json.js for details
'CBOS - FAFSA Confirm': function() {
var serializeVal = kiwi.user.cbId+'-'+kiwi.user.gradYear;
s.events = s.apl(s.events, 'event132:'+serializeVal, ',', 2); //CBOS Students - Complete FAFSA
s.linkTrackVars=s.apl(s.linkTrackVars, 'events', ',', 2);
s.linkTrackEvents=s.apl(s.linkTrackEvents, 'event132', ',', 2);
//Reset Event DDL!
kiwi.ddl.event.cbosFafsaConfirm = null;
},
'CBOS - Colleges Apply': function() {
var oData = _satellite.getVar('Data - CBOS - Colleges Apply');
//expecting: oData = {hasData, isNowFulfilled, collegesCount, collegeNames (pipe-sep)}
if (oData && oData.hasData) {
if (oData.isNowFulfilled) {
var serializeVal = kiwi.user.cbId+'-'+kiwi.user.gradYear;
s.events = s.apl(s.events, 'event133:'+serializeVal, ',', 2); //CBOS Students - Apply to Colleges
s.linkTrackEvents=s.apl(s.linkTrackEvents, 'event133', ',', 2);
}
s.events = s.apl(s.events, 'event134='+oData.collegesCount, ',', 2); //CBOS College Applications
s.linkTrackEvents=s.apl(s.linkTrackEvents, 'event134', ',', 2);
s.linkTrackVars=s.apl(s.linkTrackVars, 'events', ',', 2);
s.prop22 = oData.collegeNames; //CBOS College Application Added
s.linkTrackVars=s.apl(s.linkTrackVars, 'prop22', ',', 2);
}
},
'CBOS - Low Income Opt In': function() {
var serializeVal = kiwi.user.cbId+'-'+kiwi.user.gradYear;
s.events = s.apl(s.events, 'event35:'+serializeVal, ',', 2); //LIFW Opt Ins
s.linkTrackVars=s.apl(s.linkTrackVars, 'events', ',', 2);
s.linkTrackEvents=s.apl(s.linkTrackEvents, 'event35', ',', 2);
//Reset Event DDL!
kiwi.ddl.event.cbosLowIncomeOptIn = null
},
'CBOS - Low Income Opt Out': function() {
var serializeVal = kiwi.user.cbId+'-'+kiwi.user.gradYear;
s.events = s.apl(s.events, 'event36:'+serializeVal, ',', 2); //LIFW Opt Outs
s.linkTrackVars=s.apl(s.linkTrackVars, 'events', ',', 2);
s.linkTrackEvents=s.apl(s.linkTrackEvents, 'event36', ',', 2);
//Reset Event DDL!
kiwi.ddl.event.cbosLowIncomeOptIn = null
},
/* Site Search Links */
'Site Search Link': function() {
s.events = s.apl(s.events, 'event10', ',', 2); //Search Results Clicks
s.linkTrackVars = s.apl(s.linkTrackVars, 'events', ',', 2);
s.linkTrackEvents=s.apl(s.linkTrackEvents, 'event10', ',', 2);
kiwi._urlToParse = url;
s.eVar55 = _satellite.getVar('Page Name'); //Search Results Link
//reset urlToParse after parsed
kiwi._urlToParse = '';
s.linkTrackVars = s.apl(s.linkTrackVars, 'eVar55', ',', 2);
s.linkName += ': ' + url;
if (elem.attributes['data-cb-adcode']) var featureUsed = elem.attributes['data-cb-adcode'].value;
else if (elem.attributes['trackclickvalue']) var featureUsed = elem.attributes['trackclickvalue'].value;
if(featureUsed) {
s.linkTrackVars = s.apl(s.linkTrackVars, 'prop43', ',', 2);
s.prop43 = 'sitesearch-banner:' + featureUsed;
}
},
/* Search Results Clicks */
'Search Result Click': function() {
var searchDataPersist = JSON.parse(kiwi.cookie.sess.prev.searchData);
var term = decodeURIComponent(searchDataPersist.term),
type = decodeURIComponent(searchDataPersist.type),
facet = decodeURIComponent(searchDataPersist.facet);
if (term) {
s.events = s.apl(s.events, 'event10', ',', 2); //Search Results Clicks
s.linkTrackVars = s.apl(s.linkTrackVars, 'events', ',', 2);
s.linkTrackEvents=s.apl(s.linkTrackEvents, 'event10', ',', 2);
kiwi._urlToParse = url;
s.eVar55 = _satellite.getVar('Page Name'); //Search Results Link
//reset urlToParse after parsed
kiwi._urlToParse = '';
s.linkTrackVars = s.apl(s.linkTrackVars, 'eVar55', ',', 2);
s.eVar1 = term; //Internal Search Term
s.linkTrackVars = s.apl(s.linkTrackVars, 'eVar1', ',', 2);
if (document.querySelector('[data-cbtrack-autosuggtermused]')) {
s.eVar9 = term; //Auto-Suggested Search Term
s.linkTrackVars = s.apl(s.linkTrackVars, 'eVar9', ',', 2);
}
s.eVar3 = type; //Internal Search Type
s.linkTrackVars = s.apl(s.linkTrackVars, 'eVar3', ',', 2);
s.eVar52 = facet; //Search Results Facet
s.linkTrackVars = s.apl(s.linkTrackVars, 'eVar52', ',', 2);
//Feature & Promo Clicks
var ssPromoVal = '';
if (kiwi._elementToTest && kiwi._elementToTest.getAttribute('data-kiwi-sspromo-link')) {
ssPromoVal = kiwi._elementToTest.getAttribute('data-kiwi-sspromo-link');
}
kiwi.trackFeatureClicks({
hasData: true,
featureType: 'srch',
featureName: term,
featureOptions: '',
linkTypes: '',
ssPromoName: ssPromoVal
}, 'srch');
}
},
/* Auto-Suggested Term Search Links */
'Auto-Suggested Term Search Link': function() {
kiwi.cookie.sess.prev['isQuick'] = true;
kiwi._sessCookieMod = true; //signal sess cookie updates
s.abort = true;
},
/**
* Feature Actions
* Configured by jbeach on 2019-05-03
* https://jira.collegeboard.org/browse/WAP-2509
*/
'Feature Action - Storyline': function() {
s.prop43 = 'storyline:' + _satellite.getVar('AppData Action Code');
s.linkTrackVars = s.apl(s.linkTrackVars, 'prop43', ',', 2);
},
/* Feature Clicks */
'Feature': function() {
var elem = kiwi._elementToTest;
s.prop43 = s.prop7 + '|' + kiwi.util.makeLinkName(elem);
s.linkTrackVars = s.apl(s.linkTrackVars, 'prop43', ',', 2);
},
/* Video Play Events*/
/*'': function() {
/**
* Orig provided by Wilder Freed (Adobe consultant) in 2019-01
* Configured by jbeach on 2019-03-11
*/
/* example data passed in
kiwi.videoData = {
mediaName: mediaName,
player: 'YouTube',
linkName: 'Video 25%'
};
var oVidData = kiwi.videoData;
kiwi.videoData = {};
var oEventMapping = {
'Video Start': 'event52',
'Video 25%': 'event60',
'Video 50%': 'event61',
'Video 75%': 'event62',
'Video Complete': 'event53'
};
s.linkTrackEvents=s.apl(s.linkTrackEvents, oEventMapping[oVidData.linkName], ',', 2);
s.events = s.apl(s.events, oEventMapping[oVidData.linkName], ',', 2);
s.linkTrackVars = s.apl(s.linkTrackVars, 'events, eVar56, eVar58', ',', 2);
s.eVar56 = oVidData.mediaName;
s.eVar58 = oVidData.player;
},*/
/* Target Link Clicks */
'Target Link Click': function() {
s.linkTrackVars = s.apl(s.linkTrackVars, 'prop43', ',', 2);
},
/* Generic Custom Event Tracking */
'Custom Event Name': function() {
s.linkTrackVars=s.apl(s.linkTrackVars, 'events', ',', 2);
s.linkTrackEvents=s.apl(s.linkTrackEvents, _satellite.getVar('Custom Event Code'), ',', 2);
s.events = s.apl(s.events, s.linkTrackEvents, ',', 2);
//reset data
_satellite.setVar('Custom Event Name', '');
_satellite.setVar('Custom Event Code', '');
},
/* Fake Conversions */
'Fake Conversion': function() {
s.linkTrackEvents=s.apl(s.linkTrackEvents, 'event27,event28,event29', ',', 2);
s.events = s.apl(s.events, 'event27,event28=1,event29=1', ',', 2); //Fake Conversions
},
/* IAM Account Link Approvals */
'Approve Account Link': function() {
s.linkTrackVars=s.apl(s.linkTrackVars, 'events', ',', 2);
if (s.pageName.match(/khan_academy/i)) {
s.linkTrackEvents=s.apl(s.linkTrackEvents, 'event87', ',', 2);
s.events = s.apl(s.events, 'event87', ',', 2); //Khan Account Links
s.linkTrackEvents=s.apl(s.linkTrackEvents, 'event87', ',', 2);
kiwi.util.fireCustomEvent('Khan Account Linked');
}
if (s.pageName.match(/academic_merit/i)) {
s.linkTrackEvents=s.apl(s.linkTrackEvents, 'event105', ',', 2);
s.events = s.apl(s.events, 'event105', ',', 2); //Academic Merit Links
s.linkTrackEvents=s.apl(s.linkTrackEvents, 'event105', ',', 2);
}
if (s.pageName.match(/rtnation/i)) {
s.linkTrackEvents=s.apl(s.linkTrackEvents, 'event106', ',', 2);
s.events = s.apl(s.events, 'event106', ',', 2); //Road Trip Nation Links
s.linkTrackEvents=s.apl(s.linkTrackEvents, 'event106', ',', 2);
}
if (s.pageName.match(/collegenet/i)) {
s.linkTrackEvents=s.apl(s.linkTrackEvents, 'event131', ',', 2);
s.events = s.apl(s.events, 'event131', ',', 2); //College Net/Coalition Links
s.linkTrackEvents=s.apl(s.linkTrackEvents, 'event131', ',', 2);
}
},
'Accuplacer Practice - Test Registration': function() {
if (cbTrackData.accupracRegType) {
s.linkTrackVars=s.apl(s.linkTrackVars, 'events,eVar33', ',', 2);
s.linkTrackEvents=s.apl(s.linkTrackEvents, 'event94', ',', 2);
s.eVar33 = cbTrackData.accupracRegType;
s.events = s.apl(s.events, 'event94:' + (cbTrackData.accupracUserId || ''), ',', 2); //Accuplacer Practice Test Registrations
}
},
'SpringBoard Digital - Assignment Made': function() {
s.linkTrackVars=s.apl(s.linkTrackVars, 'events,eVar71', ',', 2);
s.linkTrackEvents=s.apl(s.linkTrackEvents, 'event84', ',', 2);
s.eVar71 = _satellite.getVar('AppData Assignment Type'); //SpringBoard Digital Assignment Types
s.events = s.apl(s.events, 'event84', ',', 2); //SpringBoard Digital Assignments
},
'SpringBoard Digital - Lesson Plan Made': function() {
s.linkTrackEvents=s.apl(s.linkTrackEvents, 'event85', ',', 2);
s.events = s.apl(s.events, 'event85', ',', 2); //SpringBoard Digital Lesson Plans
},
/* Legacy Big Future */
'BF: Action Plan Grade Select': function() {
var oData = _satellite.getVar('BF Action Plan Grade Select Data');
if (oData) {
s.linkTrackVars=s.apl(s.linkTrackVars, 'events,eVar59', ',', 2);
s.linkTrackEvents=s.apl(s.linkTrackEvents, 'event65', ',', 2);
s.eVar59 = oData.grade; //Action Plan Grad Year
s.events = s.apl(s.events, 'event65', ',', 2); //Action Plans Started
}
//reset data
_satellite.setVar('BF Action Plan Grade Select Data', '');
},
'Scholarship Search Results Click': function() {
s.linkTrackVars=s.apl(s.linkTrackVars, 'events', ',', 2);
s.linkTrackEvents=s.apl(s.linkTrackEvents, 'event26', ',', 2);
s.events = s.apl(s.events, 'event26', ',', 2); //Scholarship Searches
},
//locally scoped IIFE function - can't access :(
'bf-mobi:link': function() {
s.abort = true;
},
/* end Legacy Big Future */
'Widget Screen - BFCL Widget': function() {
var elBfcl = document.querySelector('[data-cbtrack-widget="bfcl"]'),
elMsg = '', strName = '';
if (elBfcl) {elMsg = elBfcl.querySelector('.college-list-popover-container[data-cbtrack-linkgroup]');}
if (elMsg) {strName = elMsg.getAttribute('data-cbtrack-linkgroup');}
kiwi.trackWidgetScreenView('bfcl',strName, true);
},
'BFCL Widget - Popover Dismissed': function() {
kiwi.trackWidgetScreenView('bfcl','popover-dismissed', false);
},
'BFCL Widget - Login Modal': function() {
kiwi.trackWidgetScreenView('bfcl','login-modal', false);
},
'cbTrack.sssOptin': function() {
s.linkTrackVars=s.apl(s.linkTrackVars, 'events', ',', 2);
s.linkTrackEvents=s.apl(s.linkTrackEvents, 'event59', ',', 2);
s.events = s.apl(s.events, 'event59:' + kiwi.cookie.sess.user.cbId, ',', 2); //SSS Opt-Ins
_satellite.notify('KIWI: Custom Event Tracked: SSS Opt Ins: event59:' + kiwi.cookie.sess.user.cbId);
},
'cbTrack.sssReOptin': function() {
s.linkTrackVars=s.apl(s.linkTrackVars, 'events', ',', 2);
s.linkTrackEvents=s.apl(s.linkTrackEvents, 'event196', ',', 2);
s.events = s.apl(s.events, 'event196:' + kiwi.cookie.sess.user.cbId, ',', 2); //SSS re-Opt-Ins
_satellite.notify('KIWI: Custom Event Tracked: SSS re-Opt Ins: event196:' + kiwi.cookie.sess.user.cbId);
},
'cbTrack.sssOptOut': function() {
s.linkTrackVars=s.apl(s.linkTrackVars, 'events', ',', 2);
s.linkTrackEvents=s.apl(s.linkTrackEvents, 'event140', ',', 2);
s.events = s.apl(s.events, 'event140:' + kiwi.cookie.sess.user.cbId, ',', 2); //SSS Opt-Outs
_satellite.notify('KIWI: Custom Event Tracked: SSS Opt Outs: event140:' + kiwi.cookie.sess.user.cbId);
},
'cbTrack.sssOptout': function() {
s.linkTrackVars=s.apl(s.linkTrackVars, 'events', ',', 2);
s.linkTrackEvents=s.apl(s.linkTrackEvents, 'event140', ',', 2);
s.events = s.apl(s.events, 'event140:' + kiwi.cookie.sess.user.cbId, ',', 2); //SSS Opt-Outs
_satellite.notify('KIWI: Custom Event Tracked: SSS Opt Outs: event140:' + kiwi.cookie.sess.user.cbId);
},
'HEDR - FAS - Download': function() {
if (kiwi._hedr_fas_download.eventCode) {
s.events = s.apl(s.events, kiwi._hedr_fas_download.eventCode+'='+kiwi._hedr_fas_download.total, ',', 2); //HEDR FAS Downloads
s.linkTrackVars=s.apl(s.linkTrackVars, 'events', ',', 2);
s.linkTrackEvents=s.apl(s.linkTrackEvents, kiwi._hedr_fas_download.eventCode, ',', 2);
_satellite.notify('KIWI: Custom Event Tracked: HEDR - FAS - Download: ' + kiwi._hedr_fas_download.eventCode+'='+kiwi._hedr_fas_download.total);
}
},
'HEDR - Report View': function() {
if (kiwi._hedr_report_view.eventCode) {
s.events = s.apl(s.events, kiwi._hedr_report_view.eventCode, ',', 2); //HEDR Report Views
s.prop39 = kiwi._hedr_report_view.report; //App Data Custom 1: HEDR Report
s.prop40 = kiwi._hedr_report_view.sy; //App Data Custom 2: HEDR Report Year
s.prop41 = kiwi._hedr_report_view.type; //App Data Custom 3: HEDR Report Type
s.prop42 = kiwi._hedr_report_view.source; //App Data Custom 4: HEDR Report View Source
s.linkTrackVars=s.apl(s.linkTrackVars, 'events', ',', 2);
s.linkTrackEvents=s.apl(s.linkTrackEvents, kiwi._hedr_report_view.eventCode, ',', 2);
s.linkTrackVars=s.apl(s.linkTrackVars, 'prop39', ',', 2);
s.linkTrackVars=s.apl(s.linkTrackVars, 'prop40', ',', 2);
s.linkTrackVars=s.apl(s.linkTrackVars, 'prop41', ',', 2);
s.linkTrackVars=s.apl(s.linkTrackVars, 'prop42', ',', 2);
_satellite.notify('KIWI: Custom Event Tracked: HEDR - Report View: ' + JSON.stringify(kiwi._hedr_report_view));
}
},
'HEDR - Data File - Download': function() {
if (kiwi._hedr_files_download.eventCodeA) {
s.events = s.apl(s.events, kiwi._hedr_files_download.eventCodeA, ',', 2); //HEDR Data Files Downloads
s.events = s.apl(s.events, kiwi._hedr_files_download.eventCodeB+'='+kiwi._hedr_files_download.count, ',', 2); //HEDR Data Files Downloads
s.prop40 = kiwi._hedr_files_download.type; //App Data Custom 2: HEDR Data Files Type
s.prop41 = kiwi._hedr_files_download.delivMethod; //App Data Custom 3: HEDR Data Files Delivery Method
s.prop42 = kiwi._hedr_files_download.auditCount; //App Data Custom 4: HEDR Data Files Audit Count
s.linkTrackVars=s.apl(s.linkTrackVars, 'events', ',', 2);
s.linkTrackEvents=s.apl(s.linkTrackEvents, kiwi._hedr_files_download.eventCodeA, ',', 2);
s.linkTrackEvents=s.apl(s.linkTrackEvents, kiwi._hedr_files_download.eventCodeB, ',', 2);
s.linkTrackVars=s.apl(s.linkTrackVars, 'prop40', ',', 2);
s.linkTrackVars=s.apl(s.linkTrackVars, 'prop41', ',', 2);
s.linkTrackVars=s.apl(s.linkTrackVars, 'prop42', ',', 2);
_satellite.notify('KIWI: Custom Event Tracked: HEDR - Data File - Download: ' + JSON.stringify(kiwi._hedr_files_download));
}
},
'cbTrack.modalView': function() {
kiwi = window.kiwi || {};
var modals = document.querySelectorAll('[data-cbtrack-modal]');
for (var i = 0; i < modals.length; i++) {
var modal = modals[i],
modalName = 'unknown-modal-name',
modalContent = modal.querySelector('.modal-content');
if (kiwi.util.elementIsVisible(modal) ||
(modalContent && kiwi.util.elementIsVisible(modalContent))) {
modalName = modal.getAttribute('data-cbtrack-modal');
break;
}
}
_satellite.notify('KIWI: cbTrack.modalView: ' + modalName);
if (modalName) {
s.prop34 = 'modal:'+modalName; //Widget/Modal Screen
s.linkTrackVars = s.apl(s.linkTrackVars, 'prop34', ',', 2);
s.linkTrackVars = s.apl(s.linkTrackVars, 'prop1', ',', 2);
s.prop1 = 'MODAL|' +modalName;
modalName = false;
}
}
};
if (customLinkActions[s.linkName]) customLinkActions[s.linkName]();
/* Search */
if (s.linkName.match(/^Search - /i)) {
s.linkTrackVars=s.apl(s.linkTrackVars, 'prop2,eVar1,eVar3,events', ',', 2);
s.linkTrackEvents=s.apl(s.linkTrackEvents, 'event1,event3,event4,event26,event49,event63,event64', ',', 2);
}
/* end Search */
}
}
/* end Custom Links */
/* College Profile Views */
var oData = _satellite.getVar('College Profile View Data');
if (oData && oData.event22) {
_satellite.notify('KIWI: College Profile View Data found! Events: ' + oData.event22);
s.events = s.apl(s.events, 'event22', ',', 2); //College Profile Views
//reset data
window.s.events = '';
}
/* end College Profile Views */
/* CAFW Printed */
var oData = _satellite.getVar('Data - CAFW Printed');
if (oData && oData.hasData) {
_satellite.notify('KIWI: Data - CAFW Printed found: ' + JSON.stringify(oData));
s.events = s.apl(s.events, oData.events, ',', 2); //CAFW Printed
}
/* end CAFW Printed */
/* BI Report Events */
if (s.linkType === 'o' && (_satellite.getVar('Report Load Start') || _satellite.getVar('Report Load Partial'))) {
s.linkTrackVars=s.apl(s.linkTrackVars, 'events,eVar74', ',', 2);
s.eVar74 = 'D=c25'; //Report Name
if (_satellite.getVar('Report Load Start')) {
s.linkTrackEvents=s.apl(s.linkTrackEvents, 'event89', ',', 2);
s.events = s.apl(s.events, 'event89', ',', 2); //BI Report Requested
s.pageName = decodeURIComponent(s.prop52); // this ensures previous page pathing works on final page load
_satellite.setVar('Report Loading Page Name', s.pageName);
}
if (_satellite.getVar('Report Load Partial')) {
s.linkTrackEvents=s.apl(s.linkTrackEvents, 'event100', ',', 2);
s.events = s.apl(s.events, 'event100', ',', 2); //BI Report Partially Loaded
s.pageName = _satellite.getVar('Report Loading Page Name'); // this ensures previous page pathing works on final page load
_satellite.setVar('Report Loading Page Name', '');
}
//reset de after track
_satellite.setVar('Report Load Start', false);
_satellite.setVar('Report Load Partial', false);
}
if (_satellite.getVar('Report Load Complete')) {
s.eVar74 = 'D=pageName'; //Report Name
s.events = s.apl(s.events, 'event101', ',', 2); //BI Report Completed
if (s.prop74) s.events = s.apl(s.events, 'event112=' + s.prop74, ',', 2); //BI Report Load Speed
//reset de after track
_satellite.setVar('Report Load Complete', false);
_satellite.setVar('Report Load Speed', '');
}
/* end BI Report Events */
/* SpringBoard Digital */
if (_satellite.textMatch(_satellite.getVar('AppData Site Code'), 'springboarddigital')) {
if (s.pageName == 'springboarddigital:landingpage') {
//var visitor = Visitor.getInstance('5E1B123F5245B29B0A490D45@AdobeOrg');
//var mcvid = visitor.getMarketingCloudVisitorID();
var sbDigLoginEvent = 'event83'; //records once per visit in configuration
s.events = s.apl(s.events, sbDigLoginEvent, ',', 2); //SpringBoard Digital Logins
}
}
/* end SpringBoard Digital */
/* eCommerce Purchases */
(function(){
var oData = _satellite.getVar('DDL - ECommerce - Purchase');
if (oData) {
_satellite.notify('KIWI: eCommerce Purchase Data found! :: Data Found: ' + JSON.stringify(oData));
s.events = s.apl(s.events, 'purchase', ',', 2); //Orders
s.purchaseID = oData.transaction.id; //Purchase ID
s.eVar16 = oData.transaction.type; //Order Type (e.g. Event Registration)
s.eVar37 = oData.transaction.type; //Product View Source (e.g. Event Registration)
for(var i = 0; i < oData.products.length; i++) {
var oProduct = oData.products[i];
product = oProduct.category + ';' + oProduct.id + ';' + oProduct.quantity + ';' + oProduct.price;
s.products = s.apl(s.products, product, ',', 2); //Products
}
s.linkTrackVars = s.apl(s.linkTrackVars, 'events', ',', 2);
s.linkTrackVars = s.apl(s.linkTrackVars, 'eVar16', ',', 2);
s.linkTrackVars = s.apl(s.linkTrackVars, 'eVar37', ',', 2);
s.linkTrackVars = s.apl(s.linkTrackVars, 'purchaseID', ',', 2);
s.linkTrackVars = s.apl(s.linkTrackVars, 'products', ',', 2);
_satellite.notify('KIWI: '+oData.transaction.type+'!');
var deduper = oData.transaction.id,
count = 0;
switch (oData.transaction.type) {
case 'Event Registration':
s.events = s.apl(s.events, 'event23:'+deduper, ',', 2); //Event Registrations
s.eVar62 = oData.products[0].name; //Event Name
s.eVar68 = oData.products[0].category; //Event Type
s.linkTrackEvents = s.apl(s.linkTrackEvents, 'event23', ',', 2);
s.linkTrackVars = s.apl(s.linkTrackVars, 'eVar62', ',', 2);
s.linkTrackVars = s.apl(s.linkTrackVars, 'eVar68', ',', 2);
break;
case 'SAT Score Sends':
deduper = 'nsat'+deduper;
s.purchaseID = deduper; //Purchase ID
s.events = s.apl(s.events, 'event205:'+deduper, ',', 2); //SAT Score Sends - All
s.linkTrackEvents = s.apl(s.linkTrackEvents, 'event205', ',', 2);
if (oData.transaction.shipping) {
s.events = s.apl(s.events, 'event209:'+deduper, ',', 2); //SAT Score Sends - Rush
s.linkTrackEvents = s.apl(s.linkTrackEvents, 'event209', ',', 2);
}
var oData2 = _satellite.getVar('DDL - SAT Score Sends');
if (oData2 && oData2.flow) {
s.prop70 = Object.keys(oData2.schoolsSelected).join(',');
s.linkTrackVars = s.apl(s.linkTrackVars, 'prop70', ',', 2);
count = Object.keys(oData2.schoolsSelected).length;
s.events = s.apl(s.events, 'event210:'+deduper+'='+count, ',', 2); //SAT Score Recipients - Orgs
s.linkTrackEvents = s.apl(s.linkTrackEvents, 'event210', ',', 2);
if (oData2.flow === 'reg') {
s.events = s.apl(s.events, 'event206:'+deduper, ',', 2); //SAT Score Sends - Reg
s.linkTrackEvents = s.apl(s.linkTrackEvents, 'event206', ',', 2);
}
if (oData2.flow === 'asr') {
s.events = s.apl(s.events, 'event207:'+deduper, ',', 2); //SAT Score Sends - ASR
s.linkTrackEvents = s.apl(s.linkTrackEvents, 'event207', ',', 2);
}
if (oData2.fyType && oData2.fyType !== 'none') {
s.events = s.apl(s.events, 'event208:'+deduper, ',', 2); //SAT Score Sends - FW Used
s.linkTrackEvents = s.apl(s.linkTrackEvents, 'event208', ',', 2);
}
}
if (kiwi.ddl.satScoreSends) {kiwi.ddl.satScoreSends = '';}
break;
default:
break;
}
if (kiwi.ddl.eCommerce.purchase) {kiwi.ddl.eCommerce.purchase = '';}
}
})();
/* end eCommerce Purchases */
/* CSS/PROFILE Registrations */
var oCSSPReg = _satellite.getVar('SCode CSS/Profile Registration Event Data');
if (oCSSPReg && oCSSPReg.event11) {
_satellite.notify('KIWI: CSS/Profile Registration Event Data found!');
s.events = s.apl(s.events, oCSSPReg.event11, ',', 2); //CSS/PROFILE Registrations
s.eVar66 = oCSSPReg.cssProfileYear; //CSS/PROFILE Year
}
/* end CSS/PROFILE Registrations */
/* CSS/PROFILE Application Submissions */
var oCSSPSub = _satellite.getVar('SCode CSS/Profile Application Submission Event Data');
if (oCSSPSub && oCSSPSub.event81) {
_satellite.notify('KIWI: CSS/Profile Application Submission Event Data found!');
s.events = s.apl(s.events, oCSSPSub.event81, ',', 2); //CSS/PROFILE Application Submissions
s.eVar66 = oCSSPSub.cssProfileYear; //CSS/PROFILE Year
s.events = s.apl(s.events, 'purchase', ',', 2); //Orders
s.eVar16 = oCSSPSub.orderType; //Order Type
s.purchaseID = oCSSPSub.purchaseId; //Purchase ID
s.products = oCSSPSub.products; //Products
}
/* end CSS/PROFILE Application Submissions */
/* CLEP Registrations */
var oCLEPReg = _satellite.getVar('SCode CLEP Registration Event Data');
if (oCLEPReg && oCLEPReg.event16) {
_satellite.notify('KIWI: CLEP Registration Event Data found!');
s.events = s.apl(s.events, oCLEPReg.event16, ',', 2); //CLEP Registrations
s.events = s.apl(s.events, 'purchase', ',', 2); //Orders
s.eVar16 = oCLEPReg.orderType; //Order Type
s.purchaseID = oCLEPReg.purchaseId; //Purchase ID
s.products = oCLEPReg.products; //Products
kiwi.util.fireCustomEvent('CLEP Registration');
}
/* end CLEP Registrations */
/* SAT Reg Flow Tracking */
var arrStepEvent = '';
(function(oData) {
if (oData && oData.hasData) {
_satellite.notify('KIWI: SAT Reg Step Data found: ' + JSON.stringify(oData));
for (var i = 0; i < oData.stepEvents.length; i++) {
s.events = s.apl(s.events, oData.stepEvents[i], ',', 2); // SAT Reg Flow Milestones (unique by Reg), (unique by SY+User)
arrStepEvent = oData.stepEvents[i].split(':');
var stepEvent;
if (arrStepEvent.length) {
stepEvent = arrStepEvent[0];
kiwi.util.fireCustomEvent('SAT Reg Step', {stepEvent: stepEvent});
}
}
}
})(_satellite.getVar('Data - SAT Reg Step'));
/* end SAT Reg Flow Tracking */
/* SAT Cross-Sell Prod View Tracking */
(function(oData) {
if (oData && oData.hasData) {
_satellite.notify('KIWI: Data - SAT Reg Cross-Sell found: ' + JSON.stringify(oData));
s.events = s.apl(s.events, 'prodView', ',', 2); // Product Views
s.eVar37=oData.prodViewSource;
s.products=oData.products;
}
})(_satellite.getVar('Data - SAT Reg Cross-Sell'));
/* end SAT Cross-Sell Prod View Tracking */
/* Test Order Tracking */
(function(oData) {
if (oData && oData.hasData &&
s.pageName.match(/ordering\/testordering\/submitorder/i)) {
_satellite.notify('KIWI: Data - Test Order found: ' + JSON.stringify(oData));
s.eVar8 = oData.aiCode; //App User Org ID
s.eVar53 = oData.adminCode; //Test Order Admin
s.events = s.apl(s.events, 'event48:'+oData.serializeCode, ',', 2); // Test Orders
}
})(_satellite.getVar('Data - Test Order'));
/* end Test Order Tracking */
/* SAT Reg Tracking */
(function(oData) {
if (oData && oData.hasData) {
_satellite.notify('KIWI: Data - SAT Reg found: ' + JSON.stringify(oData));
s.eVar16 = oData.orderType; //Order Type
s.purchaseID = oData.purchaseId; //Purchase ID
s.products = oData.products; //Products
s.eVar26 = oData.testType; //SAT Test Type
s.eVar40 = oData.registrantType; //SAT Registrant Type
s.eVar49 = oData.adminCode; //SAT Reg Admin
s.eVar86 = _satellite.getVar('AA - SAT Fee Waiver Type');
s.events = s.apl(s.events, oData.events.join(','), ',', 2); // Purchase, SAT Regs by Type
if (arrStepEvent.length) {
var isSubjTest = (oData.testType === 'SAT Subject'),
isRepeat = (oData.registrantType === 'Repeat'),
usedFeeWaiver = (s.events.match(/event50(,|:|$)/i));
kiwi.util.fireCustomEvent('SAT Reg', {adminType: oData.adminType, isSubjTest: isSubjTest, isRepeat: isRepeat, usedFeeWaiver: usedFeeWaiver, satRegAdminDate: oData.adminCode, purchaseId: oData.purchaseId});
}
}
})(_satellite.getVar('Data - SAT Reg'));
/* end SAT Reg Tracking */
/* Other NSAT Purchase Tracking */
(function(oData) {
if (oData && oData.hasData) {
_satellite.notify('KIWI: Data - NSAT Purchase found: ' + JSON.stringify(oData));
s.eVar16 = oData.orderType; //Order Type
s.purchaseID = oData.purchaseId; //Purchase ID
s.products = oData.products; //Products
s.eVar26 = oData.testType; //SAT Test Type
s.eVar40 = oData.registrantType; //SAT Registrant Type
s.eVar49 = oData.adminCode; //SAT Reg Admin
s.events = s.apl(s.events, oData.events, ',', 2); // Purchase, Score Sends, QAS/SAS
}
})(_satellite.getVar('Data - NSAT Purchase'));
/* end Other NSAT Purchase Tracking */
/* AP FYM Event Tracking */
/* DDL SCHEMA
{
hasData: true,
apReg: {
hasData: false,
studentId: apReg.studentId || '',
studentOrgId: apReg.studentOrgId || '',
studentGradeLevel: apReg.studentGradeLevel || ''
},
apCourse: {
hasData: false,
apCourseIds: apCourse.apCourseIds || '',
educationPeriod: apCourse.educationPeriod || '',
studentIds: apCourse.studentIds || '',
courseOrgId: apCourse.courseOrgId || ''
},
apExam: {
hasData: false,
apCourseIds: apExam.apCourseIds || '',
educationPeriod: apExam.educationPeriod || '',
studentIds: apExam.studentIds || '',
courseOrgId: apExam.courseOrgId || ''
}
} */
var oData = _satellite.getVar('Data - AP FYM Event');
if (oData && oData.hasData) {
_satellite.notify('KIWI: Data - AP FYM Event found: ' + JSON.stringify(oData));
if (oData.apReg.hasData) {
var sApEventDedupeKey = oData.apReg.studentId;
s.eVar77 = oData.apReg.studentGradeLevel; //AP Student Grade Level
s.events = s.apl(s.events, 'event31:'+sApEventDedupeKey, ',', 2); //AP Student Registrants
}
if (oData.apCourse.hasData) {
//loop courses first
for (var i = 0; i <= oData.apCourse.apCourseIds.length-1; i++) {
var sApCourseInst = oData.apCourse.apCourseIds[i] + '-' + oData.apCourse.educationPeriod;
s.eVar79 = sApCourseInst + '-' + oData.apCourse.courseOrgId; //AP Course Offering
//loop students
for (var j = 0; j <= oData.apCourse.studentIds.length-1; j++) {
var sApEventDedupeKey = oData.apCourse.studentIds[j] + '-' + sApCourseInst;
s.events = s.apl(s.events, 'event32:'+sApEventDedupeKey, ',', 2); //AP Course Enrollees
}
}
}
if (oData.apExam.hasData) {
//loop courses first
for (var i = 0; i <= oData.apExam.apCourseIds.length-1; i++) {
var sApCourseInst = oData.apExam.apCourseIds[i] + '-' + oData.apExam.educationPeriod;
s.eVar79 = sApCourseInst + '-' + oData.apExam.courseOrgId; //AP Course Offering
//loop students
for (var j = 0; j <= oData.apExam.studentIds.length-1; j++) {
var sApEventDedupeKey = oData.apExam.studentIds[j] + '-' + sApCourseInst;
s.events = s.apl(s.events, 'event33:'+sApEventDedupeKey, ',', 2); //AP Exam Registrants
}
}
}
s.linkTrackVars=s.apl(s.linkTrackVars, 'events,eVar77,eVar79', ',', 2);
s.linkTrackEvents=s.apl(s.linkTrackEvents, 'event31,event32,event33', ',', 2);
}
/* end AP FYM Event Tracking */
/* AP Score View Tracking */
var oData = _satellite.getVar('Data - AP Score View');
if (oData && oData.hasData) {
_satellite.notify('KIWI: Data - AP Score View found: ' + JSON.stringify(oData));
s.events = s.apl(s.events, oData.event78, ',', 2); //AP Score Views
s.eVar65 = oData.eVar65; //AP Score View Year
}
/* end AP Score View Tracking */
/* AP Score Send Tracking */
var oData = _satellite.getVar('Data - AP Score Send');
if (oData && oData.hasData) {
_satellite.notify('KIWI: Data - AP Score Send found: ' + JSON.stringify(oData));
s.events = s.apl(s.events, oData.event79, ',', 2); //AP Score Sends
s.eVar16 = oData.orderType; //Order Type
s.purchaseID = oData.purchaseId; //Purchase ID
s.products = oData.products; //Products
}
/* end AP Score Send Tracking */
/* AP Score Match Tracking */
var oData = _satellite.getVar('Data - AP Score Match');
if (oData && oData.hasData) {
_satellite.notify('KIWI: Data - AP Score Match found: ' + JSON.stringify(oData));
s.events = s.apl(s.events, oData.event77, ',', 2); //AP Score Matches
}
/* end AP Score Match Tracking */
/* IAM Score Match Tracking */
var oData = _satellite.getVar('Data - IAM Score Match');
if (oData && oData.hasData) {
_satellite.notify('KIWI: Data - IAM Score Match found: ' + JSON.stringify(oData));
s.events = s.apl(s.events, oData.events, ',', 2); //IAM Score Matches
s.eVar69 = oData.matchAttempts; //IAM Score Match Attempts
s.eVar70 = oData.matchMethod; //IAM Score Match Method
s.eVar73 = oData.matchTestType; //IAM Score Match Test Type
}
/* end IAM Score Match Tracking *
/* Store Tracking */
//Store Item Views
if (!s.products && s.prop31) {
s.products = ';' + s.prop31; //Products
s.events = s.apl(s.events, 'prodView', ',', 2); //Product Views
}
//Store Purchases
var oSTOPurch = _satellite.getVar('SCode Store Purchase Event Data');
if (oSTOPurch && oSTOPurch.event47) {
_satellite.notify('KIWI: SCode Store Purchase Event Data found!');
s.events = s.apl(s.events, oSTOPurch.event47, ',', 2); //Store Orders
s.events = s.apl(s.events, 'purchase', ',', 2); //Orders
s.eVar16 = oSTOPurch.orderType; //Order Type
s.purchaseID = oSTOPurch.purchaseId; //Purchase ID
s.products = oSTOPurch.products; //Products
}
/* end Store Tracking */
/* Marketing Channels/Campaigns */
kiwi._thisPage.mktg = {
channel: '',
campaign: '',
mid: '', //Message ID
rid: '', //Recipient ID
sid: '' //Segment ID
};
//s.channelManager('excmpid,ep_mid,s_kwcid,ef_id', '', 'cmgvo', '', 's_tbm', 60);
//derive this page channel/campaign
s.channelManager('excmpid,sfmc_cid,ep_mid,s_kwcid,ef_id', '', '0', '', 's_tbm', 60);
switch (s._channel) {
case 'Typed/Bookmarked':
s._channel = 'Direct';
break;
case 'Unknown Paid Channel':
s._channel = 'All Other Campaigns';
break;
case 'Natural Search':
s._channel = 'Organic Search';
break;
case 'Other Natural Referrers':
s._channel = 'Other Sites';
break;
default:
break;
}
/*_satellite.notify('KIWI: Channel settings: _channel: '+ s._channel +'; _campaignID: '+ s._campaignID +
'; _campaign: '+ s._campaign +'; _referrer: '+ s._referrer +
'; _referringDomain: '+ s._referringDomain +'; _partner: '+ s._partner +
'; _keywords: '+ s._keywords);*/
//set values for this page
if (s._channel) kiwi._thisPage.mktg.channel = s._channel;
if (s._campaignID && s._campaignID != 'n/a') kiwi._thisPage.mktg.campaign = s._campaignID.toLowerCase();
/* SFMC Campaigns */
/* SFMC Links pattern (email): ?SFMC_cid=EM%%JobId%%-%%=StringToHex(__AdditionalEmailAttribute1)=%%&rid=%%SubscriberID%% */
/* SFMC Links pattern (text): ?SFMC_cid=TX%%JobId%%-%%=StringToHex(__AdditionalEmailAttribute1)=%%&rid=%%SubscriberID%% */
kiwi._thisPage.mktg.mid = _satellite.getVar('QP sfmc_cid');
kiwi._thisPage.mktg.rid = _satellite.getVar('QP rid');
if (kiwi._thisPage.mktg.mid.match(/-/)) {
//parse out segment val
var tmp = kiwi._thisPage.mktg.mid.split('-');
kiwi._thisPage.mktg.mid = tmp[0];
kiwi._thisPage.mktg.sid = decodeURIComponent(kiwi.util.hex2a(tmp[1]));
}
/* Epsilon DREAM Campaigns */
if (!kiwi._thisPage.mktg.mid) {
kiwi._thisPage.mktg.mid = _satellite.getVar('QP ep_mid');
kiwi._thisPage.mktg.rid = _satellite.getVar('QP ep_rid');
kiwi._thisPage.mktg.sid = _satellite.getVar('QP etId');
}
//set values for life cookie
if (kiwi._thisPage.mktg.channel) {
kiwi._lifeCookieMod = true;
//check if within 60 days
var todayDate = new Date(),
setDate = new Date(kiwi.cookie.life.mktg.dateSet),
expDate = setDate.setDate(setDate.getDate() + 60);
if (expDate < todayDate) {
//start over
//kiwi.cookie.life.mktg.channels = kiwi._thisPage.mktg.channel;
if (kiwi._thisPage.mktg.campaign) kiwi.cookie.life.mktg.campaigns = kiwi._thisPage.mktg.campaign;
} else {
//add them to the list && pop off first in list if urlencoded new ones are longer than 100 chars
//kiwi.cookie.life.mktg.channels = (kiwi.cookie.life.mktg.channels == '')?kiwi._thisPage.mktg.channel:kiwi.util.appendToList(kiwi.cookie.life.mktg.channels, kiwi._thisPage.mktg.channel, ',', 3);
//kiwi.cookie.life.mktg.channels = kiwi.util.chopToLength( kiwi.cookie.life.mktg.channels, 100, true );
if (kiwi._thisPage.mktg.campaign) {
kiwi.cookie.life.mktg.campaigns = (kiwi.cookie.life.mktg.campaigns == '')?kiwi._thisPage.mktg.campaign:kiwi.util.appendToList(kiwi.cookie.life.mktg.campaigns, kiwi._thisPage.mktg.campaign, '>', 3);
kiwi.cookie.life.mktg.campaigns = kiwi.util.chopToLength( kiwi.cookie.life.mktg.campaigns, 100, true );
if (kiwi.cookie.life.mktg.latest) {
kiwi.cookie.life.mktg.latest.channel = kiwi._thisPage.mktg.channel;
kiwi.cookie.life.mktg.latest.campaign = kiwi._thisPage.mktg.campaign;
}
}
}
if (kiwi._thisPage.mktg.mid) {
var tmp = kiwi._thisPage.mktg.mid+kiwi._thisPage.mktg.rid,
regexp = new RegExp('(^|,)'+tmp+'(,|$)', 'i');
if (!kiwi.cookie.life.mktg.midrids.match(regexp)) s.events = s.apl(s.events, 'event40', ',', 2); //Email Unique Clicked
kiwi.cookie.life.mktg.midrids = kiwi.util.appendToList(kiwi.cookie.life.mktg.midrids, tmp, ',', 3);
}
}
//pass data to analytics
//campaigns
s.prop17 = kiwi.cookie.life.mktg.campaigns; //Marketing Campaign Participation
if (kiwi._thisPage.mktg.campaign) {
s.campaign = s.getValOnce(kiwi._thisPage.mktg.campaign, 's_v0', 30); //Marketing Campaign Last
s.events = s.apl(s.events, 'event30', ',', 2); //Non-Deduped Campaign Clicks
s.prop59 = kiwi._thisPage.mktg.campaign; //Non-Deduped Campaign
}
//other
s.eVar39 = kiwi._thisPage.mktg.sid; //Email Segment ID
s.eVar42 = kiwi._thisPage.mktg.rid; //Email Recipient ID
/* end Marketing Channels/Campaigns */
/* Referral Promo ID */
s.eVar12 = _satellite.getVar('QP refid');
/* Patches/Hacks */
/*//prevent myap double-page tracking after login, due to way IAM login + SPA application works
if (s.prop32 === 'myap' && s.pageName === s.prop52 && !s.r && !s.linkName) {
s.abort = true;
_satellite.notify('KIWI: Tool > Analytics > Custom JS > DO PLUGINS SECTION > Duplicate APFYM Call aborted.');
}*/
//Hacks required after AppMeas upgrade due to APOSR legacy S object tracking and modal popup behavior
if (s.pageName === 'apscore:contactus-thanks' && s.prop52 == 'apscore:contactus-thanks')
s.abort = true;
if (s.pageName === 'apscore:sendscores-disclaimer' && s.prop52 == 'apscore:sendscores-disclaimer')
s.pageName = 'apscore:sendscores-selectcolleges';
// Purchase, set by NSAT, patch 6/13/2011
if (s.pageName.toLowerCase().indexOf('step4:orderconfirmation') != -1)
s.events = s.apl(s.events, 'purchase', ',', 2);
/* end Patches/Hacks */
/* Sync duplicate vars */
if (s.pageName && !s.eVar4) s.eVar4 = 'D=pageName'; //PageName
if (s.prop18) s.eVar78 = 'D=c18'; //Hour of Day, Day of Week, Weekend/Weekday
/* end Sync duplicate vars */
//bake in cookied vals
s.prop7 = s.getPreviousValue(s.prop32, 'gpv_c32'); //Previous Site Code
s.prop52 = s.getPreviousValue(s.pageName, 'gpv_pn'); //Previous Page
/* Update Kiwi Cookies */
if (kiwi._lifeCookieMod) {
var cookieDays = 60,
newExpireOn = new Date().getTime() + (86400000*cookieDays),
expDate = new Date(newExpireOn);
document.cookie = 'kiwi_life=' + JSON.stringify(kiwi.cookie.life) + ';expires=' + expDate.toGMTString() +
';path=/ ;domain=collegeboard.org';
}
if (kiwi._sessCookieMod) {
document.cookie = 'kiwi_sess=' + JSON.stringify(kiwi.cookie.sess) +
';path=/ ;domain=collegeboard.org';
}
/* end Update Kiwi Cookies */
//reset stuff
if (cbTrackData.promosViewed) cbTrackData.promosViewed = '';
if (cbTrackData.promoClicked) cbTrackData.promoClicked = '';
if (cbTrackData.apRegistration) cbTrackData.apRegistration = '';
if (cbTrackData.apCourseEnrollment) cbTrackData.apCourseEnrollment = '';
if (cbTrackData.apExamRegistration) cbTrackData.apExamRegistration = '';
if (cbTrackData.flowCode) cbTrackData.flowCode = '';
if (cbTrackData.flowSteps) cbTrackData.flowSteps = '';
//protect against bad SPA repeat calls
kiwi._thisPage = kiwi._thisPage || {};
kiwi._thisPage.siteSettings = kiwi._thisPage.siteSettings || {};
kiwi.appPageTrackCalls = kiwi.appPageTrackCalls || {};
/*if (typeof kiwi._thisPage.siteSettings.appType !== 'undefined' && kiwi._thisPage.siteSettings.appType === 'spa-noroutes') {// this is handled on pushstate for apps that use meaningful urls
ruleName = 'KIWI: Tool > Analytics > Custom JS > DO PLUGINS SECTION';
if (typeof kiwi.appPageTrackCalls !== 'undefined' &&
typeof kiwi.appPageTrackCalls.totalSinceLastTrack !== 'undefined' &&
typeof kiwi.appPageTrackCalls.currentIncrement !== 'undefined' &&
kiwi.appPageTrackCalls.totalSinceLastTrack !== kiwi.appPageTrackCalls.currentIncrement) {
s.abort = true;
_satellite.notify(ruleName + ' > appPageTrackCalls.currentIncrement: ' + kiwi.appPageTrackCalls.currentIncrement + ' aborted.');
} else {
_satellite.notify(ruleName + ' > appPageTrackCalls.currentIncrement: ' + kiwi.appPageTrackCalls.currentIncrement + ' allowed.');
kiwi.appPageTrackCalls = {totalSinceLastTrack: 0, currentIncrement: 0};
}
}*/
//_satellite.notify('KIWI: Tool > Analytics > Custom JS > DO PLUGINS SECTION (end)');
};
/** end Do Plugins Section **/
/************************** PLUGINS SECTION *************************/
//expire legacy cookies
if (document.cookie.match(/dtm_cbAcctData=/)) document.cookie = 'dtm_cbAcctData=;expires=Thu, 01 Jan 1970 00:00:00 GMT;path=/ ;domain=collegeboard.org';
if (document.cookie.match(/kiwi_cookie=/)) document.cookie = 'kiwi_cookie=;expires=Thu, 01 Jan 1970 00:00:00 GMT;path=/ ;domain=collegeboard.org';
//if (document.cookie.match(/cbtrack_nav=/)) document.cookie = 'cbtrack_nav=;expires=Thu, 01 Jan 1970 00:00:00 GMT;path=/ ;domain=collegeboard.org';
// Kiwi Cookies
kiwi._lifeCookieMod = kiwi._sessCookieMod = false;
kiwi.cookie = {
life: {
mktg: {
dateSet: new Date(),
channels: '',
campaigns: '',
midrids: ''
}
},
sess: {
user: {},
prev: {
siteCode: '',
pageName: '',
channel: '',
campaign: ''
},
mboxEvents: {
track_sat_sv: false,
track_psat_sv: false
},
features: {}
}
};
//get cookie data
kiwi._cookielife = _satellite.getVar('Cookie - Kiwi Lifetime');
if (kiwi._cookielife) {
kiwi.cookie.life = JSON.parse(kiwi._cookielife);
}
kiwi._cookiesess = _satellite.getVar('Cookie - Kiwi Session');
if (kiwi._cookiesess) {
kiwi.cookie.sess = JSON.parse(kiwi._cookiesess);
}
// general config
kiwi.config = {
subdomainsRegex: {
legacyWAP: /^(account|scores)$/i
}
};
//Initialize kiwi._thisPage values
kiwi._thisPage = kiwi.util.getThisPageSettings();
/*
// Utilities
Syntax: s.Util.getQueryParam(key, [url], [delim])
Parameters:
key (required) The name of the query string parameter that you want to get. This parameter is case sensitive.
url (optional) Default url is s.pageURL or window.location. Specifying a value for this parameter overrides the URL from which the query parameter is retrieved to the one specified.
delim (optional) Parameter delimiter in the URL. Default delimiter is "&". This lets you to specify an alternate query-string delimiter, such as ";".
*/
/* Legacy H27.4 Utility Hacks by jbeach 6/29/2016 */
s.wd = s.w || window;
s.epa = function (e) {
var t, n, o = this;
return e ? (e = o.rep('' + e, '+', ' '),
3 == o.em ? (n = new Function('x', 'var y,e;try{y=decodeURIComponent(x)}catch(e){y=unescape(x)}return y'),
n(e)) : unescape(e)) : t;
};
s.rep = function (e, t, n) {
var o, i = new Array, r = 0;
if (e)
if (e.split)
i = e.split(t);
else if (t)
for (; r >= 0;)
o = e.indexOf(t, r),
i[i.length] = e.substring(r, 0 > o ? e.length : o),
r = o,
r >= 0 && (r += t.length);
else
for (r = 0; r < e.length; r++)
i[i.length] = e.substring(r, r + 1);
if (e = '',
o = i.length,
i && o > 0 && (e = i[0],
o > 1))
if (i.join)
e = i.join(n);
else
for (r = 1; o > r; r++)
e += n + i[r];
return e;
};
s.fl=function(x,l){return x?(''+x).substring(0,l):x;};
/* end Legacy H27.4 Utility Hacks by jbeach 6/29/2016 */
/* eslint-disable */
// Utility Plugins
/*
* Plugin Utility Function: join
*/
s.join = new Function("v","p",""
+"var s = this;var f,b,d,w;if(p){f=p.front?p.front:'';b=p.back?p.back"
+":'';d=p.delim?p.delim:'';w=p.wrap?p.wrap:'';}var str='';for(var x=0"
+";x<v.length;x++){if(typeof(v[x])=='object' )str+=s.join( v[x],p);el"
+"se str+=w+v[x]+w;if(x<v.length-1)str+=d;}return f+str+b;");
/*
* Plugin Utility Function: split v1.5 - split a string (JS 1.0 compatible)
*/
s.split=new Function("l","d",""
+"var i,x=0,a=new Array;while(l){i=l.indexOf(d);i=i>-1?i:l.length;a[x"
+"++]=l.substring(0,i);l=l.substring(i+d.length);}return a");
/*
* Plugin Utility: apl v1.1
*/
s.apl=new Function("l","v","d","u",""
+"var s=this,m=0;if(!l)l='';if(u){var i,n,a=s.split(l,d);for(i=0;i<a."
+"length;i++){n=a[i];m=m||(u==1?(n==v):(n.toLowerCase()==v.toLowerCas"
+"e()));}}if(!m)l=l?l+d+v:v;return l");
/*
* Utility Function: p_gn
*/
s.p_gn=new Function("t","h",""
+"var i=t?t.indexOf('~'):-1,n,x;if(t&&h){n=i<0?'':t.substring(0,i);x="
+"t.substring(i+1);if(h.indexOf(x.toLowerCase())>-1)return n?n:'[[';}"
+"return 0;");
/*
* Utility Function: p_c
*/
s.p_c=new Function("v","c",""
+"var x=v.indexOf('=');return c.toLowerCase()==v.substring(0,x<0?v.le"
+"ngth:x).toLowerCase()?v:0");
/*
* Utility Function: p_gh
*/
s.p_gh=new Function(""
+"var s=this;if(!s.eo&&!s.lnk)return '';var o=s.eo?s.eo:s.lnk,y=s.ot("
+"o),n=s.oid(o),x=o.s_oidt;if(s.eo&&o==s.eo){while(o&&!n&&y!='BODY'){"
+"o=o.parentElement?o.parentElement:o.parentNode;if(!o)return '';y=s."
+"ot(o);n=s.oid(o);x=o.s_oidt}}return o.href?o.href:'';");
/*
* Utility Function: p_fo
*/
s.p_fo=new Function("n",""
+"var s=this;if(!s.__fo){s.__fo=new Object;}if(!s.__fo[n]){s.__fo[n]="
+"new Object;return 1;}else {return 0;}");
/*
* pt - utility function
*/
s.pt=function(x,d,f,a){var s=this,t=x,z=0,y,r;while(t){y=t.indexOf(d);y=y<0?t.length:y;t=t.substring(0,y);r=s[f](t,a);if(r)return r;z+=y+d.length;t=x.substring(z,x.length);t=z<x.length?t:""}return""};
/*
* Plugin Utility: Replace v1.0
*/
s.repl=new Function("x","o","n",""
+"var i=x.indexOf(o),l=n.length;while(x&&i>=0){x=x.substring(0,i)+n+x."
+"substring(i+o.length);i=x.indexOf(o,i+l)}return x");
/*
* Plugin: searchValue : 1.0 - searches string and returns value
*/
s.searchValue=new Function("p","d","u","vu",""
+"var s=this,i,t,k,dl,mv,mm,rv,x;while(p){i=p.indexOf(',');i=i<0?p.le"
+"ngth:i;k=p.substring(0,i);dl=k.indexOf(d);mv=k.substring(0,dl);mm=k"
+".substring(dl+1);u=u+'';rv=vu?vu:mv;if(mm=='e'){x=u.indexOf(mv);if("
+"x>-1) return rv;}else{x=u.substring(mm,mv.length);if(mv==x) return "
+"rv;}p=p.substring(i==p.length?i:i+1)}return ''");
/*
* Plugin: getVisitStart v2.0 - returns 1 on 1st page of visit, else 0
*/
s.getVisitStart=new Function("c",""
+"var s=this,v=1,t=new Date;t.setTime(t.getTime()+1800000);if(s.c_r(c"
+")){v=0}if(!s.c_w(c,1,t)){s.c_w(c,1,0)}if(!s.c_r(c)){v=0}return v;");
/*
* getQueryParam v2.5 - H-code and AppMeasurement Compatible
*/
s.getQueryParam=function(p,d,u,h){var s=this,v="",i,j,t;d=d?d:"";u=u?u:s.pageURL?s.pageURL:s.wd?s.wd.location:window.location;while(p){i=p.indexOf(",");i=i<0?p.length:i;t=s.p_gpv(p.substring(0,i),u+"",h);if(t)t=t.indexOf("#")>-1?t.substring(0,t.indexOf("#")):t;if(t)v+=v?d+t:t;p=p.substring(i==p.length?i:i+1)}return v};
s.p_gpv=function(k,u,h){var s=this,v="",q;j=h==1?"#":"?";i=u.indexOf(j);if(k&&i>-1){q=u.substring(i+1);v=s.pt(q,"&","p_gvf",k)}return v};
s.p_gvf=function(t,k){if(t){var s=this,i=t.indexOf("="),p=i<0?t:t.substring(0,i),v=i<0?true:t.substring(i+1);if(p.toLowerCase()==k.toLowerCase())return s.epa?s.epa(v):s.unescape(v)}return""};
/*
* Plugin: getPreviousValue_v1.0 - return previous value of designated
* variable (requires split utility)
*/
s.getPreviousValue=new Function("v","c","el",""
+"var s=this,t=new Date,i,j,r='';t.setTime(t.getTime()+1800000);if(el"
+"){if(s.events){i=s.split(el,',');j=s.split(s.events,',');for(x in i"
+"){for(y in j){if(i[x]==j[y]){if(s.c_r(c)) r=s.c_r(c);v?s.c_w(c,v,t)"
+":s.c_w(c,'no value',t);return r}}}}}else{if(s.c_r(c)) r=s.c_r(c);v?"
+"s.c_w(c,v,t):s.c_w(c,'no value',t);return r}");
// Plugins
/*
* Plugin: getTimeParting 3.4
*/
s.getTimeParting=new Function("h","z",""
+"var s=this,od;od=new Date('1/1/2000');if(od.getDay()!=6||od.getMont"
+"h()!=0){return'Data Not Available';}else{var H,M,D,U,ds,de,tm,da=['"
+"Sunday','Monday','Tuesday','Wednesday','Thursday','Friday','Saturda"
+"y'],d=new Date();z=z?z:0;z=parseFloat(z);if(s._tpDST){var dso=s._tp"
+"DST[d.getFullYear()].split(/,/);ds=new Date(dso[0]+'/'+d.getFullYea"
+"r());de=new Date(dso[1]+'/'+d.getFullYear());if(h=='n'&&d>ds&&d<de)"
+"{z=z+1;}else if(h=='s'&&(d>de||d<ds)){z=z+1;}}d=d.getTime()+(d.getT"
+"imezoneOffset()*60000);d=new Date(d+(3600000*z));H=d.getHours();M=d"
+".getMinutes();M=(M<10)?'0'+M:M;D=d.getDay();U=' AM';if(H>=12){U=' P"
+"M';H=H-12;}if(H==0){H=12;}D=da[D];tm=H+':'+M+U;return(tm+'|'+D);}");
/*
* Plugin: Days since last Visit 1.1 - capture time from last visit
*/
s.getDaysSinceLastVisit=new Function("c",""
+"var s=this,e=new Date(),es=new Date(),cval,cval_s,cval_ss,ct=e.getT"
+"ime(),day=24*60*60*1000,f1,f2,f3,f4,f5;e.setTime(ct+3*365*day);es.s"
+"etTime(ct+30*60*1000);f0='Cookies Not Supported';f1='First Visit';f"
+"2='More than 30 days';f3='More than 7 days';f4='Less than 7 days';f"
+"5='Less than 1 day';cval=s.c_r(c);if(cval.length==0){s.c_w(c,ct,e);"
+"s.c_w(c+'_s',f1,es);}else{var d=ct-cval;if(d>30*60*1000){if(d>30*da"
+"y){s.c_w(c,ct,e);s.c_w(c+'_s',f2,es);}else if(d<30*day+1 && d>7*day"
+"){s.c_w(c,ct,e);s.c_w(c+'_s',f3,es);}else if(d<7*day+1 && d>day){s."
+"c_w(c,ct,e);s.c_w(c+'_s',f4,es);}else if(d<day+1){s.c_w(c,ct,e);s.c"
+"_w(c+'_s',f5,es);}}else{s.c_w(c,ct,e);cval_ss=s.c_r(c+'_s');s.c_w(c"
+"+'_s',cval_ss,es);}}cval_s=s.c_r(c+'_s');if(cval_s.length==0) retur"
+"n f0;else if(cval_s!=f1&&cval_s!=f2&&cval_s!=f3&&cval_s!=f4&&cval_s"
+"!=f5) return '';else return cval_s;");
/*
* Plugin: getNewRepeat 1.2 - Returns whether user is new or repeat
*/
s.getNewRepeat=new Function("d","cn",""
+"var s=this,e=new Date(),cval,sval,ct=e.getTime();d=d?d:30;cn=cn?cn:"
+"'s_nr';e.setTime(ct+d*24*60*60*1000);cval=s.c_r(cn);if(cval.length="
+"=0){s.c_w(cn,ct+'-New',e);return'New';}sval=s.split(cval,'-');if(ct"
+"-sval[0]<30*60*1000&&sval[1]=='New'){s.c_w(cn,ct+'-New',e);return'N"
+"ew';}else{s.c_w(cn,ct+'-Repeat',e);return'Repeat';}");
/*
* Plugin: getActionDepth v1.0
*/
s.getActionDepth=new Function("c",""
+ "var s=this,v=1,t=new Date;t.setTime(t.getTime()+1800000);"
+ "if(!s.c_r(c)){v=1}if(s.c_r(c)){v=s.c_r(c);v++}"
+ "if(!s.c_w(c,v,t)){s.c_w(c,v,0)}return v;");
/*
* Plugin: getValOnce_v1.11
*/
s.getValOnce=new Function("v","c","e","t",""
+"var s=this,a=new Date,v=v?v:'',c=c?c:'s_gvo',e=e?e:0,i=t=='m'?6000"
+"0:86400000,k=s.c_r(c);if(v){a.setTime(a.getTime()+e*i);s.c_w(c,v,e"
+"==0?0:a);}return v==k?'':v");
/*
* Plugin: getPercentPageViewed v1.71
*/
s.getPercentPageViewed=new Function("n",""
+"var s=this,W=window,EL=W.addEventListener,AE=W.attachEvent,E=['load"
+"','unload','scroll','resize','zoom','keyup','mouseup','touchend','o"
+"rientationchange','pan'];W.s_Obj=s;s_PPVid=(n=='-'?s.pageName:n)||s"
+".pageName||location.href;if(!W.s_PPVevent){s.s_PPVg=function(n,r){v"
+"ar k='s_ppv',p=k+'l',c=s.c_r(n||r?k:p),a=c.indexOf(',')>-1?c.split("
+"',',10):[''],l=a.length,i;a[0]=unescape(a[0]);r=r||(n&&n!=a[0])||0;"
+"a.length=10;if(typeof a[0]!='string')a[0]='';for(i=1;i<10;i++)a[i]="
+"!r&&i<l?parseInt(a[i])||0:0;if(l<10||typeof a[9]!='string')a[9]='';"
+"if(r){s.c_w(p,c);s.c_w(k,'?')}return a};W.s_PPVevent=function(e){va"
+"r W=window,D=document,B=D.body,E=D.documentElement,S=window.screen|"
+"|0,Ho='offsetHeight',Hs='scrollHeight',Ts='scrollTop',Wc='clientWid"
+"th',Hc='clientHeight',C=100,M=Math,J='object',N='number',s=W.s_Obj|"
+"|W.s||0;e=e&&typeof e==J?e.type||'':'';if(!e.indexOf('on'))e=e.subs"
+"tring(2);s_PPVi=W.s_PPVi||0;if(W.s_PPVt&&!e){clearTimeout(s_PPVt);s"
+"_PPVt=0;if(s_PPVi<2)s_PPVi++}if(typeof s==J){var h=M.max(B[Hs]||E[H"
+"s],B[Ho]||E[Ho],B[Hc]||E[Hc]),X=W.innerWidth||E[Wc]||B[Wc]||0,Y=W.i"
+"nnerHeight||E[Hc]||B[Hc]||0,x=S?S.width:0,y=S?S.height:0,r=M.round("
+"C*(W.devicePixelRatio||1))/C,b=(D.pageYOffset||E[Ts]||B[Ts]||0)+Y,p"
+"=h>0&&b>0?M.round(C*b/h):0,O=W.orientation,o=!isNaN(O)?M.abs(o)%180"
+":Y>X?0:90,L=e=='load'||s_PPVi<1,a=s.s_PPVg(s_PPVid,L),V=function(i,"
+"v,f,n){i=parseInt(typeof a==J&&a.length>i?a[i]:'0')||0;v=typeof v!="
+"N?i:v;v=f||v>i?v:i;return n?v:v>C?C:v<0?0:v};if(new RegExp('(iPod|i"
+"Pad|iPhone)').exec(navigator.userAgent||'')&&o){o=x;x=y;y=o}o=o?'P'"
+":'L';a[9]=L?'':a[9].substring(0,1);s.c_w('s_ppv',escape(W.s_PPVid)+"
+"','+V(1,p,L)+','+(L||!V(2)?p:V(2))+','+V(3,b,L,1)+','+X+','+Y+','+x"
+"+','+y+','+r+','+a[9]+(a[9]==o?'':o))}if(!W.s_PPVt&&e!='unload')W.s"
+"_PPVt=setTimeout(W.s_PPVevent,333)};for(var f=W.s_PPVevent,i=0;i<E."
+"length;i++)if(EL)EL(E[i],f,false);else if(AE)AE('on'+E[i],f);f()};v"
+"ar a=s.s_PPVg();return!n||n=='-'?a[1]:a");
/*
* Plugin: Performance Timing Tracking - 0.1 BETA
*/
s.performanceTiming=new Function("v",""
+"var s=this;if(v)s.ptv=v;if(typeof performance!='undefined'){if(perf"
+"ormance.timing.loadEventEnd==0){s.pi=setInterval(function(){s.perfo"
+"rmanceWrite()},250);}if(!s.ptc||s.linkType=='e'){s.performanceRead("
+");}else{s.rfe();s[s.ptv]='';}}");
s.performanceWrite=new Function("",""
+"var s=this;if(performance.timing.loadEventEnd>0)clearInterval(s.pi)"
+";try{if(s.c_r('s_ptc')==''&&performance.timing.loadEventEnd>0){try{"
+"var pt=performance.timing;var pta='';pta=s.performanceCheck(pt.fetc"
+"hStart,pt.navigationStart);pta+='^^'+s.performanceCheck(pt.domainLo"
+"okupStart,pt.fetchStart);pta+='^^'+s.performanceCheck(pt.domainLook"
+"upEnd,pt.domainLookupStart);pta+='^^'+s.performanceCheck(pt.connect"
+"End,pt.connectStart);pta+='^^'+s.performanceCheck(pt.responseStart,"
+"pt.connectEnd);pta+='^^'+s.performanceCheck(pt.responseEnd,pt.respo"
+"nseStart);pta+='^^'+s.performanceCheck(pt.loadEventStart,pt.domLoad"
+"ing);pta+='^^'+s.performanceCheck(pt.loadEventEnd,pt.loadEventStart"
+");pta+='^^'+s.performanceCheck(pt.loadEventEnd,pt.navigationStart);"
+"s.c_w('s_ptc',pta);if(sessionStorage&&navigator.cookieEnabled&&s.pt"
+"v!='undefined'){var pe=performance.getEntries();var tempPe='';for(v"
+"ar i=0;i<pe.length;i++){tempPe+='!';tempPe+=pe[i].name.indexOf('?')"
+">-1?pe[i].name.split('?')[0]:pe[i].name;tempPe+='|'+(Math.round(pe["
+"i].startTime)/1000).toFixed(1)+'|'+(Math.round(pe[i].duration)/1000"
+").toFixed(1)+'|'+pe[i].initiatorType;}sessionStorage.setItem('s_pec"
+"',tempPe);}}catch(err){return;}}}catch(err){return;}");
s.performanceCheck=new Function("a","b",""
+"if(a>=0&&b>=0){if((a-b)<60000&&((a-b)>=0)){return((a-b)/1000).toFix"
+"ed(2);}else{return 600;}}");
s.performanceRead=new Function("",""
+"var s=this;if(performance.timing.loadEventEnd>0)clearInterval(s.pi)"
+";var cv=s.c_r('s_ptc');if(s.pte){var ela=s.pte.split(',');}if(cv!='"
+"'){var cva=s.split(cv,'^^');if(cva[1]!=''){for(var x=0;x<(ela.lengt"
+"h-1);x++){s.events=s.apl(s.events,ela[x]+'='+cva[x],',',2);}}s.even"
+"ts=s.apl(s.events,ela[ela.length-1],',',2);}s.linkTrackEvents=s.apl"
+"(s.linkTrackEvents,s.pte,',',2);s.c_w('s_ptc','',0);if(sessionStora"
+"ge&&navigator.cookieEnabled&&s.ptv!='undefined'){s[s.ptv]=sessionSt"
+"orage.getItem('s_pec');sessionStorage.setItem('s_pec','',0);}else{s"
+"[s.ptv]='sessionStorage Unavailable';}s.ptc=true;");
s.rfe=new Function("",""
+"var s=this;var ea=s.split(s.events,',');var pta=s.split(s.pte,',');"
+"try{for(x in pta){var ptr=new RegExp(pta[x]+'[^\,][0-9]*\.[0-9](.*)"
+"');s.events=s.events.match(ptr)[1];s.contextData['events']=s.events"
+";}}catch(e){return;}");
/* Plugin: channelManager v3.06 */
/* channelManager seList (Top 40 Search Engines) */
s.seList="google.,googlesyndication.com,.googleadservices.com|q,as_q|Google>bing.com|q|Bing>yahoo.com,yahoo.co.jp|p,va|Yahoo!>ask.jp,ask.co|q,ask|Ask>search.aol.,suche.aolsvc.de|q,query|AOL>altavista.co,altavista.de|q,r|AltaVista>.mywebsearch.com|searchfor|MyWebSearch>webcrawler.com|q|WebCrawler>wow.com|q|Wow>infospace.com|q|InfoSpace>blekko.com|q|Blekko>dogpile.com|q|DogPile>alhea.com|q|Alhea>duckduckgo.com|q|DuckDuckGo>info.com|qkw|Info.com>contenko.com|q|Contenko>baidu.com|word,wd|Baidu>daum.net,search.daum.net|q|Daum>icqit.com|q|icq>myway.com|searchfor|MyWay.com>naver.com,search.naver.com|query|Naver>netscape.com|query,search|Netscape Search>reference.com|q|Reference.com>seznam|w|Seznam.cz>abcsok.no|q|Startsiden>tiscali.it,www.tiscali.co.uk|key,query|Tiscali>virgilio.it|qs|Virgilio>yandex|text|Yandex.ru>optimum.net|q|Optimum Search>search.earthlink.net|q|Earthlink>search.comcast.net|q|Comcast>libero.it|query|libero.it>excite.co|search|Excite>mail.ru|q|Mail.ru>isearch.avg.com|q|AVG>msn.com|q|MSN>seznam.cz|q|seznam.cz>so.com|q|so.com>ixquick.com|query|ixquick.com>sogou.com|query|sogou.com>360.cn|q|360.cn";
s._channelDomain="Partner Sites|khanacademy.org,roadtripnation.com,epiconline.org,accuplacer.org";
s._channelParameter="Email|ep_mid";
s._channelPattern="Email|em>Triggered|tr>External Email|ex>SMS|tx>Offline Marketing|mtg,cb,dm>Online Media|oc>Social Media|sm,fb>Outbound Callers|ob>Push Notifications|ph>Affiliates|af>Vanity URLs|vt>Partner Sites|pt";
s.channelManager=function(a,b,c,d,e,f,g){var s=this,h=new Date,i=0,j,k,l,m,n,o,p,q,r,t,u,v,w,x,y,z,A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V;U=s.getQueryParam?1:0;V=s.repl?1:0;if(e){i=1;if(s.c_r(e))i=0;h.setTime(h.getTime()+18E5);s.c_w(e,1,h);if(f&&s.c_r("s_tbm"+e+f.toString()))i=0}j=s.referrer?s.referrer:document.referrer;if(j=="Typed/Bookmarked")j="";j=decodeURIComponent(j.toLowerCase());if(!j)k=1;else{l=j.indexOf("?")>-1?j.indexOf("?"):j.length;m=j.substring(0,l);n=j.split("/");n=n[2].split("?");
o=n[0].toLowerCase();p=s.linkInternalFilters.toLowerCase();p=p.split(",");for(q=0;q<p.length;q++){r=o.indexOf(p[q])==-1?"":j;if(r)break}}if(!r&&!k){t=j;u=o;w="Other Natural Referrers";v=w+": "+o;x=s.seList+">"+s._extraSearchEngines;if(d==1){m=V?s.repl(m,"oogle","%"):s.replace(m,"oogle","%");m=V?s.repl(m,"ahoo","^"):s.replace(m,"ahoo","^");j=V?s.repl(j,"as_q","*"):s.replace(j,"as_q","*")}y=x.split(">");for(z=0;z<y.length;z++){A=y[z];A=A.split("|");B=A[0].split(",");for(C=0;C<B.length;C++){D=m.indexOf(B[C]);
if(D>-1){if(A[2])E=v=A[2];else E=o;if(d==1){E=V?s.repl(E,"#"," - "):s.replace(E,"#"," - ");j=V?s.repl(j,"*","as_q"):s.replace(j,"*","as_q");E=V?s.repl(E,"^","ahoo"):s.replace(E,"^","ahoo");E=V?s.repl(E,"%","oogle"):s.replace(E,"%","oogle")}F=A[1].split(",");for(G=0;G<F.length;G++){if(j.indexOf(F[G]+"=")>-1||j.indexOf("duckduckgo")>-1||j.indexOf("googlequicksearchbox")>-1||j.indexOf("http://www.google.")==0||j.indexOf("https://www.google.")==0||j.indexOf("https://search.yahoo.com/")==0||j.indexOf("http://r.search.yahoo.com")==
0||j.indexOf("https://www.bing.com")==0)H=1;I=U?s.getQueryParam(F[G],"",j).toLowerCase():s.Util.getQueryParam(F[G],j).toLowerCase();if(H||I)break}}if(H||I)break}if(H||I)break}}if(!r||g!="1"){J=a.split(",");for(var q in J)if(J.hasOwnProperty(q))if(U?s.getQueryParam(J[q]):s.Util.getQueryParam(J[q]))if(b)T=T?T+b+(U?s.getQueryParam(J[q]):s.Util.getQueryParam(J[q])):U?s.getQueryParam(J[q]):s.Util.getQueryParam(J[q]);else{T=U?s.getQueryParam(J[q]):s.Util.getQueryParam(J[q]);if(T)break}if(T){v=T;if(E)w=
"Paid Search";else w="Unknown Paid Channel"}if(!T&&E&&H){w="Natural Search";v=w+": "+E}}if(i&&k&&!T)t=u=v=w="Typed/Bookmarked";J=s._channelDomain;if(J&&o&&!r){K=J.split(">");for(L=0;L<K.length;L++){M=K[L]?K[L].split("|"):"";N=M[1]?M[1].split(","):"";O=N.length;for(P=0;P<O;P++){Q=N[P].toLowerCase();R=("/"+o).indexOf(Q);if(R>-1){w=M[0];v=T?v:w+": "+o;break}}if(R>-1)break}}J=s._channelParameter;if(J&&g!="1"){K=J.split(">");for(L=0;L<K.length;L++){M=K[L]?K[L].split("|"):"";N=M[1]?M[1].split(","):"";O=
N.length;for(P=0;P<O;P++){R=U?s.getQueryParam(N[P]):s.Util.getQueryParam(N[P]);if(R){w=M[0];v=T?v:w+": "+o;break}}if(R)break}}J=s._channelPattern;if(J&&g!="1"&&T){K=J.split(">");for(L=0;L<K.length;L++){M=K[L]?K[L].split("|"):"";N=M[1]?M[1].split(","):"";O=N.length;for(P=0;P<O;P++){Q=N[P].toLowerCase();R=T?T.toLowerCase():"";S=R.indexOf(Q);if(S==0){w=M[0];break}}if(S==0)break}}S=w?T+u+w+I:"";c=c?c:"c_m";if(c!="0")S=s.getValOnce(S,c,0);if(S){s._campaignID=T?T:"n/a";s._referrer=t?t:"n/a";s._referringDomain=
u?u:"n/a";s._campaign=v?v:"n/a";s._channel=w?w:"n/a";s._partner=E?E:"n/a";s._keywords=H?I?I:"Keyword Unavailable":"n/a";if(f&&w!="Typed/Bookmarked"){h.setTime(h.getTime()+f*864E5);s.c_w("s_tbm"+e+f.toString(),1,h)}}else s._campaignID=s._referrer=s._referringDomain=s._campaign=s._channel=s._partner=s._keywords=""};
/*
* Plugin: setupLinkTrack v3.02AM
*/
s.setupLinkTrack=new Function("vl","c","e",""
+"var cv=s.c_r(c);if(vl){var vla=vl.split(',');}if(cv!=''){var cva=s."
+"split(cv,'^^');if(cva[1]!=''){for(x in vla){s[vla[x]]=cva[x];if(e){"
+"s.events=s.apl(s.events,e,',',2);}}}}s.c_w(c,'',0);if(typeof s.link"
+"Object!='undefined'&&s.hbx_lt!='manual'){s.lta=[];if(typeof s.pageN"
+"ame!='undefined')s.lta[0]=s.pageName;if(typeof s.linkObject!=null){"
+"slo=s.linkObject;if(s.linkObject!=0){if(s.linkObject.getAttribute('"
+"name')!=null){var b=s.linkObject.getAttribute('name');if(b.indexOf("
+"'&lpos=')>-1){s.lta[3]=b.match('\&lpos\=([^\&]*)')[1];}if(b.indexOf"
+"('&lid=')>-1){s.lta[1]=b.match('\&lid\=([^\&]*)')[1];}}}if(typeof s"
+".lta[1]=='undefined'){if(s.linkName!=0){s.lta[1]=s.linkName;}else i"
+"f(s.linkObject!=0){if(s.linkObject.innerHTML.indexOf('<img')>-1){s."
+"lta[1]=s.linkObject.innerHTML.match('src=\"([^\"]*)')[1]}else{s.lta[1"
+"]=s.linkObject.innerHTML;}}}s.lta[2]=s.pageName+' | '+s.lta[1];}if("
+"s.linkType!=0){for(var x=0;x<vla.length;x++){s[vla[x]]=s.cleanStr(s"
+".lta[x]);if(e){s.events=s.apl(s.events,e,',',2);s.linkTrackVars=s.a"
+"pl(s.linkTrackVars,'events',',',2);}}s.linkTrackVars=s.apl(s.linkTr"
+"ackVars,vl,',',2);}else{if(s.lta[1]){var tcv='';for(var x=0;x<s.lta"
+".length;x++){tcv+=s.cleanStr(s.lta[x])+'^^'}s.c_w(c,tcv)}}s.lta=nul"
+"l;}");
s.cleanStr = function(a){
if(typeof a != 'undefined'){
a = a.replace(/<\/?span[^>]*>/g, '');
return a;
}
};
/* eslint-enable */
/************************** DELAY TRACKING SECTION ***************/
ruleName='KIWI: Tool > Analytics > Custom JS > DELAY TRACKING SECTION';
//suppress default page load track
kiwi._suppressTrack = true;
// send an event that aa page is ready to track
document.dispatchEvent(new CustomEvent('kiwi.ready.aa', {'bubbles': true}));
if(kiwi._suppressTrack) return false;
}
},
"e653cea501cb1b08dbc50ef2f1550ad79f81a499": {
"engine": "tnt",
"mboxURL": "7a8a98de0363fbed05b98da851d6b23866ffa7cc/mbox-contents-e653cea501cb1b08dbc50ef2f1550ad79f81a499.js",
"loadSync": true,
"pageParams": {
}
},
"8c94c038e1dbec941007f34bc69cd4bc3e4b08bc": {
"engine": "visitor_id",
"loadOn": "pagetop",
"name": "VisitorID",
"mcOrgId": "5E1B123F5245B29B0A490D45@AdobeOrg",
"autoRequest": true,
"initVars": {
},
"customerIDs": {
"crm_id": {
"id": "%Kiwi - CRM ID%",
"authState": "AUTHENTICATED"
}
}
}
},
"pageLoadRules": [
{"name":"00 Master - Page Bottom","trigger":[{"command":"loadScript","arguments":[{"sequential":false,"scripts":[{"src":"satellite-57bf401064746d361f0064e4.js"}]}]}],"event":"pagebottom"},
{"name":"00 Master - Page Top","trigger":[{"command":"loadBlockingScript","arguments":[{"sequential":true,"scripts":[{"src":"satellite-5a81e11664746d5ff700072d.js"},{"src":"satellite-578e6f6764746d29b90028de.js"},{"src":"satellite-5d8a7a5864746d1e5c001919.js"},{"src":"satellite-5d70120c64746d7144003d1b.js"},{"src":"satellite-5d84ef3264746d48820000fe.js"},{"src":"satellite-5dc5a5ef64746d437e000137.js"}]}]}],"event":"pagetop"},
{"name":"APRO - DOM Ready","trigger":[{"command":"loadScript","arguments":[{"sequential":false,"scripts":[{"src":"satellite-5d8cf59664746d2d8e000439.js"}]}]}],"scope":{"URI":{"include":[/^\/($|\?)/i]},"subdomains":{"include":[/^apstudents\.collegeboard\.org$/i]}},"event":"domready"},
{"name":"Big Future - Page Top - Video Tracking","trigger":[{"command":"loadBlockingScript","arguments":[{"sequential":true,"scripts":[{"src":"satellite-58cae8d364746d0bb40060af.js"},{"src":"satellite-58caea1264746d2cd0007976.js"}]}]}],"scope":{"subdomains":{"include":["^bigfuture\\."]}},"event":"pagetop"},
{"name":"DOM Ready - bfm","trigger":[{"command":"loadScript","arguments":[{"sequential":true,"scripts":[{"src":"satellite-5d45a25764746d56f6000ec3.js"}]}]}],"scope":{"subdomains":{"include":[/^bigfuture\.collegeboard\.org$/i]}},"event":"domready"},
{"name":"MBOX nsat-orf-button-continue","trigger":[{"engine":"tnt","command":"addMbox","arguments":[{"mboxGoesAround":"#authenticatePage","mboxName":"nsat-orf-button-continue","arguments":[],"timeout":"1500"}]}],"scope":{"URI":{"include":["satweb/registration/viewAuthenticateStudentAction.action"]},"subdomains":{"include":["nsat.collegeboard.org"]}},"event":"pagebottom"},
{"name":"MBOX nsat-orf-pst-mainContainer","trigger":[{"engine":"tnt","command":"addMbox","arguments":[{"mboxGoesAround":".pst-mainContainer","mboxName":"nsat-orf-pst-mainContainer","arguments":[],"timeout":"1500"}]}],"scope":{"URI":{"include":["satweb/registration/viewAuthenticateStudentAction.action"]},"subdomains":{"include":["nsat.collegeboard.org"]}},"event":"pagetop"},
{"name":"MBOX nsat-orf-s2-horizontal-step","trigger":[{"engine":"tnt","command":"addMbox","arguments":[{"mboxGoesAround":".row.s2-horizontal-step","mboxName":"nsat-orf-s2-horizontal-step","arguments":[],"timeout":"1500"}]}],"scope":{"URI":{"include":["satweb/registration/viewAuthenticateStudentAction.action"]},"subdomains":{"include":["nsat.collegeboard.org"]}},"event":"pagebottom"},
{"name":"NSAT - MySAT - COVID-19 Alert","trigger":[{"command":"loadScript","arguments":[{"sequential":true,"scripts":[{"src":"satellite-5e6f910964746d2d2e00046d.js"}]}]}],"scope":{"URI":{"include":["satweb/satHomeAction.action"]},"subdomains":{"include":[/^nsat\.collegeboard\.org$/i]}},"event":"domready"},
{"name":"NSAT - MySAT - DOM Ready","trigger":[{"command":"loadScript","arguments":[{"sequential":false,"scripts":[{"src":"satellite-5ae75b3164746d59980008bb.js"}]}]}],"scope":{"URI":{"include":["satweb/satHomeAction.action"]},"subdomains":{"include":[/^nsat\.collegeboard\.org$/i]}},"event":"domready"},
{"name":"NSAT - ST Listening Avail (PLR)","trigger":[{"command":"loadScript","arguments":[{"sequential":true,"scripts":[{"src":"satellite-5ed6966a64746d47ca000d77.js"}]}]}],"scope":{"subdomains":{"include":[/^nsat\.collegeboard\.org$/i]}},"event":"domready"},
{"name":"NSAT - Test Center Avail","trigger":[{"command":"loadScript","arguments":[{"sequential":true,"scripts":[{"src":"satellite-5ed5798964746d511f0000f3.js"}]}]}],"scope":{"subdomains":{"include":[/^nsat\.collegeboard\.org$/i]}},"event":"domready"},
{"name":"Page Top - aps","trigger":[{"command":"loadBlockingScript","arguments":[{"sequential":true,"scripts":[{"src":"satellite-5a1dcffe64746d671f008065.js"}]}]}],"scope":{"subdomains":{"include":[/^apstudent.*\./i]}},"event":"pagebottom"},
{"name":"Page Top - bf","trigger":[{"command":"loadBlockingScript","arguments":[{"sequential":true,"scripts":[{"src":"satellite-58c01a0964746d0bba00152a.js"}]}]}],"scope":{"subdomains":{"include":[/^bigfuture\.collegeboard\.org$/i]}},"event":"pagetop"},
{"name":"Pages - Download - DOM Ready","trigger":[{"command":"loadScript","arguments":[{"sequential":false,"scripts":[{"src":"satellite-5c795b2c64746d226c002a8d.js"}]}]}],"scope":{"URI":{"include":[/^\/download(\/?|$)/i]},"subdomains":{"include":[/^pages\.collegeboard\.org$/i]},"domains":[/collegeboard\.org$/i]},"event":"domready"},
{"name":"Pixel - Alorica - Live Agent - APC","trigger":[{"command":"loadScript","arguments":[{"sequential":false,"scripts":[{"src":"satellite-5c75a3ca64746d6c4400069c.js"}]}]}],"scope":{"subdomains":{"include":[/^apcentral(-stg)?\.collegeboard\.org$/i]},"domains":[/collegeboard\.org$/i]},"conditions":[function(event,target){
/**
* Logic Provided by Dianna Choi in 2019-02
* https://jira.collegeboard.org/browse/WAP-2266
* Configured by jbeach on 2019-02-28
**/
//include all of apcentral
var bInclude = true,
bMatchFound = false;
//but exclude these paths...
if (document.location.pathname.match(/^\/(about-ap|content|courses|professional-development|score-reports-data\/awards|series|start-grow-ap\/international)/) !== null) {
bInclude = false;
//but include these again...
bInclude = bMatchFound = (document.location.pathname.match(/^\/courses$/) !== null);
if (!bMatchFound) bInclude = bMatchFound = (document.location.pathname.match(/^\/about-ap$/) !== null);
if (!bMatchFound) bInclude = bMatchFound = (document.location.pathname.match(/^\/courses\/exam-dates-and-fees/) !== null);
if (!bMatchFound) bInclude = bMatchFound = (document.location.pathname.match(/^\/courses\/.*\/(course|exam|portfolio|application-timeline)$/) !== null);
if (!bMatchFound) bInclude = bMatchFound = (document.location.pathname.match(/^\/series\/(ap-coordinator-tutorial|studio-art-submission-demo-ap-coordinators|studio-art-submission-demo-ap-teachers)/) !== null);
if (!bMatchFound && document.location.pathname.match(/^\/about-ap\//) !== null) {
bInclude = true;
bMatchFound = (
(document.location.pathname.match(/^\/about-ap\/how-ap-develops-courses-and-exams/) !== null) ||
(document.location.pathname.match(/^\/about-ap\/news-changes\/(ap-2019\/frequently-asked-questions|ap-2019\/support-students-new-online-tools|collaborations-with-ap)/) !== null) ||
(document.location.pathname.match(/^\/about-ap\/start-grow-ap\/(access-initiatives|ap-advocates-program|grow-ap\/spotlight-on-success|outreach-support-resources)/) !== null)
);
if(bMatchFound) bInclude = false;
bMatchFound = true;
}
if (!bMatchFound && document.location.pathname.match(/^\/courses\//) !== null) {
if (document.location.pathname.match(/^\/courses\/(2019-20-course-exam-description-pre-order-form|ap-course-audit|collaborations-with-ap|resources)/) !== null) {
bInclude = false;
bMatchFound = true;
}
if (!bMatchFound && document.location.pathname.match(/^\/courses\/.*/) !== null) {
bInclude = bMatchFound = (document.location.pathname.match(/^\/courses\/[^\/]*$/) !== null);
}
}
}
return bInclude;
/*
For the courses, URLs that end in the following should fire the chat, but any child pages under those directories should not:
รขโ‚ฌยข courses/_/course
รขโ‚ฌยข courses/_/exam
รขโ‚ฌยข courses/_/portfolio
Additionally, any course page URLs that end in the following or the child pages under them should not fire the chat:
รขโ‚ฌยข courses/_/course-audit
รขโ‚ฌยข courses/_/classroom-resources
รขโ‚ฌยข courses/_/professional-development
*/
/*
NOT HERE:
about-ap/news-changes/ap-2019/frequently-asked-questions
about-ap/how-ap-develops-courses-and-exams
about-ap/news-changes/collaborations-with-ap
about-ap/news-changes/ap-2019/support-students-new-online-tools
about-ap/start-grow-ap/access-initiatives
about-ap/start-grow-ap/ap-advocates-program
about-ap/start-grow-ap/grow-ap/spotlight-on-success
about-ap/start-grow-ap/outreach-support-resources
content
courses/2019-20-course-exam-description-pre-order-form
courses/ap-course-audit
courses/collaborations-with-ap
courses/resources
courses/_/[any not listed below], e.g.
courses/_/course-audit
courses/_/classroom-resources
courses/_/professional-development
courses/_/course/_
courses/_/exam/_
courses/_/portfolio/_
professional-development
score-reports-data/awards
series/[not listed below]
start-grow-ap/international
YES HERE:
(_ = any value) [any not listed above]
courses
/courses/exam-dates-and-fees
/courses/exam-dates-and-fees/_
courses/_
courses/_/course
courses/_/exam
courses/_/portfolio
courses/_/application-timeline
courses/_/exam-dates-2020
courses/_/late-testing-dates
courses/_/late-testing-dates-2020
series/ap-coordinator-tutorial
series/studio-art-submission-demo-ap-coordinators
series/studio-art-submission-demo-ap-teachers
*/
}],"event":"pagebottom"},
{"name":"Pixel - Alorica - Live Agent - CLEP","trigger":[{"command":"loadScript","arguments":[{"sequential":false,"scripts":[{"src":"satellite-5e7dfd8264746d122b0022a6.js"}]}]}],"scope":{"URI":{"include":[/^\/help-for-students(\/|$)/i]},"subdomains":{"include":[/^clep(-stg)?\.collegeboard\.org$/i]}},"event":"pagebottom"},
{"name":"Pixel - Aimtell","trigger":[{"command":"loadBlockingScript","arguments":[{"sequential":true,"scripts":[{"src":"satellite-5a5f68c664746d43530021ff.js"}]}]}],"scope":{"subdomains":{"include":[/^(advancesinap|apcentral|apcentral-stg|blog)\.collegeboard\.org/i,/^(collegereadiness|counselors|sat-stage)\.collegeboard\.org/i,/^(pages|pages-stg|parents)\.collegeboard\.org/i,/^(dreamdeferred|forum|nasai|preparate|regionalforums|newenglandforum|middlestatesforum|southernforum|midwesternforum|westernforum|southwesternforum)(-stg)?\.collegeboard\.org/i,/^(apac|apac-stg)\.collegeboard\.org/i,/^(opportunity|opportunity-stg)\.collegeboard\.org/i,/^(apstudents|apstudents-stg)\.collegeboard\.org/i]}},"event":"pagebottom"},
{"name":"Pixel - Aimtell - Page Views","trigger":[{"command":"loadScript","arguments":[{"sequential":false,"scripts":[{"src":"satellite-5e559fac64746d0821001c05.js"}]}]}],"scope":{"subdomains":{"include":[/^(apstudents|go|signup|pages)\.collegeboard\.org/i]}},"event":"windowload"},
{"name":"Pixel - DM - AdMedia","trigger":[{"command":"loadScript","arguments":[{"sequential":false,"scripts":[{"src":"satellite-5d6fb1c664746d5140000012.js"}]}]}],"scope":{"subdomains":{"include":[/^collegereadiness\.collegeboard\.org$/i]},"domains":[/collegeboard\.org$/i]},"conditions":[function(event,target){
var cmet = true;
if (_satellite.getVar('QP userName') || document.referrer.match(/userName=[^\&]+/)) {
cmet = false;
}
return cmet;
}],"event":"windowload"},
{"name":"Pixel - DM - Bing Ads","trigger":[{"command":"loadScript","arguments":[{"sequential":false,"scripts":[{"src":"satellite-5b4524fd64746d1adb00923e.js"}]}]}],"scope":{"domains":[/collegeboard\.org$/i]},"conditions":[function(event,target){
var cmet = true;
if (_satellite.getVar('QP userName') || document.referrer.match(/userName=[^\&]+/)) {
cmet = false;
}
return cmet;
}],"event":"pagebottom"},
{"name":"Pixel - DM - Division D - TTD","trigger":[{"command":"loadScript","arguments":[{"sequential":false,"scripts":[{"src":"satellite-5d1a7e7364746d2e8b0012e8.js"}]}]}],"scope":{"URI":{"include":["cbos-pledge"]},"subdomains":{"include":[/^signup\.collegeboard\.org$/i]},"domains":[/collegeboard\.org$/i]},"conditions":[function(event,target){
var cmet = true;
if (_satellite.getVar('QP userName') || document.referrer.match(/userName=[^\&]+/)) {
cmet = false;
}
return cmet;
}],"event":"pagebottom"},
{"name":"Pixel - DM - Division D - Yahoo","trigger":[{"command":"loadScript","arguments":[{"sequential":false,"scripts":[{"src":"satellite-5b9931d464746d6dc000024d.js"}]}]}],"scope":{"subdomains":{"include":[/^(bigfuture|collegereadiness|go|signup|studentscores)\.collegeboard\.org$/i]},"domains":[/collegeboard\.org$/i]},"conditions":[function(event,target){
var cmet = true;
if (_satellite.getVar('QP userName') || document.referrer.match(/userName=[^\&]+/)) {
cmet = false;
}
if (cmet) {
kiwi = window.kiwi || {};
kiwi.pixels = kiwi.pixels || {};
kiwi.pixels.divisiond = kiwi.pixels.divisiond || {};
kiwi.pixels.divisiond.yahoo = kiwi.pixels.divisiond.yahoo || {};
var host = document.location.host,
path = document.location.pathname,
hash = document.location.hash;
kiwi.pixels.divisiond.yahoo.projectId = '10000';
kiwi.pixels.divisiond.yahoo.pixelId = '10063589';
switch (host) {
case 'bigfuture.collegeboard.org':
//display on specific pages
if (path.match(/^\/(scholarship-search|pay-for-college\/grants-scholarships|college-search)$/i)) {
cmet = true;
}
break;
case 'collegereadiness.collegeboard.org':
//display on specific pages
if (path.match(/^\/sat\/register\/find-test-centers$/i)) {
cmet = true;
}
break;
case 'go.collegeboard.org':
//display on specific pages
if (path.match(/^\/(your-)?best-test$/i)) { //Students + Parents Lead Form + Conversion
cmet = true;
}
break;
case 'signup.collegeboard.org':
//display on specific pages
if (path.match(/^\/next-step-sat\/$/i)) {
cmet = true;
}
break;
case 'studentscores.collegeboard.org':
//display on specific pages
if (path.match(/^\/viewscore$/i)) {
cmet = true;
}
break;
default:
break;
}
}
return cmet;
}],"event":"pagebottom"},
{"name":"Pixel - DM - Facebook","trigger":[{"command":"loadScript","arguments":[{"sequential":false,"scripts":[{"src":"satellite-5b3fbc7264746d6050009413.js"}]}]}],"scope":{"subdomains":{"include":[/^(account|bigfuture|cbaccount|clep|clepportal|collegereadiness|go|nsat|opportunity|pages|parents|signup|studentscores)\.collegeboard\.org$/i]}},"conditions":[function(event,target){
var cmet = true;
if (_satellite.getVar('QP userName') || document.referrer.match(/userName=[^\&]+/)) {
cmet = false;
}
if (cmet) {
kiwi = window.kiwi || {};
kiwi.pixelTriggers = kiwi.pixelTriggers || {};
kiwi.pixelTriggers.fb = kiwi.pixelTriggers.fb || {};
kiwi.pixelTriggers.fb.cbMain = kiwi.pixelTriggers.fb.cbMain || {};
kiwi.pixelTriggers.fb.cbIndia = kiwi.pixelTriggers.fb.cbIndia || {};
var ruleName='KIWI: PLR > Pixel - Facebook > Condition';
_satellite.notify(ruleName);
var cmet = true,
host = document.location.host,
path = document.location.pathname,
hash = document.location.hash,
params = document.location.search;
switch (host) {
case 'bigfuture.collegeboard.org':
case 'clep.collegeboard.org':
case 'clepportal.collegeboard.org':
case 'collegereadiness.collegeboard.org':
case 'opportunity.collegeboard.org':
case 'parents.collegeboard.org':
case 'studentscores.collegeboard.org':
cmet = kiwi.pixelTriggers.fb.cbMain.init = true;
kiwi.pixelTriggers.fb.cbMain.view = true;
break;
case 'go.collegeboard.org':
cmet = kiwi.pixelTriggers.fb.cbMain.init = true;
kiwi.pixelTriggers.fb.cbMain.view = true;
//conversion event
if (path.match(/^\/(your-best-test|best-test)$/i) &&
hash.match(/^#thank-you/i)) {
kiwi.pixelTriggers.fb.cbMain.lead = true;
}
break;
case 'pages.collegeboard.org':
if (path.match(/^\/sat\/school-day/i)) {
cmet = kiwi.pixelTriggers.fb.cbMain.init = true;
kiwi.pixelTriggers.fb.cbMain.view = true;
}
break;
case 'nsat.collegeboard.org':
cmet = kiwi.pixelTriggers.fb.cbMain.init = true;
cmet = kiwi.pixelTriggers.fb.cbIndia.init = true;
//conversion events on specific pages - see DE > Kiwi > Custom Events
break;
case 'signup.collegeboard.org':
//view event
if (path.match(/^\/international-sat($|\/)/i)) {
cmet = kiwi.pixelTriggers.fb.cbIndia.init = true;
kiwi.pixelTriggers.fb.cbIndia.view = true;
}
break;
case 'account.collegeboard.org':
//weed out appId=229 (SSD MP3 App)
if (!(params.match(/appId=229/i)) && path.match(/^\/(login\/(login|signUp))$/i)) {
cmet = kiwi.pixelTriggers.fb.cbIndia.init = true;
kiwi.pixelTriggers.fb.cbIndia.view = true;
}
break;
case 'cbaccount.collegeboard.org':
cmet = kiwi.pixelTriggers.fb.cbIndia.init = true; //capture account creation on subdomain confirmation page
if (path.match(/^\/(iamweb\/(smartRegister|registerAccount))$/i)) {
kiwi.pixelTriggers.fb.cbIndia.view = true;
}
break;
default:
break;
}
}
return cmet;
}],"event":"pagebottom"},
{"name":"Pixel - DM - JunGroup - Find Test Centers","trigger":[{"command":"loadScript","arguments":[{"sequential":false,"scripts":[{"src":"satellite-5e67d7aa64746d1ac400038d.js"}]}]}],"scope":{"URI":{"include":[/\/sat\/register\/find-test-centers/i]},"subdomains":{"include":[/^collegereadiness\.collegeboard\.org$/i]},"domains":[/collegeboard\.org$/i]},"conditions":[function(event,target){
var cmet = true;
if (_satellite.getVar('QP userName') || document.referrer.match(/userName=[^\&]+/)) {
cmet = false;
}
return cmet;
}],"event":"windowload"},
{"name":"Pixel - DM - Pinterest","trigger":[{"command":"loadScript","arguments":[{"sequential":false,"scripts":[{"src":"satellite-5ca38b0464746d2d09009456.js"}]}]}],"scope":{"URI":{"include":["about-ap/news-changes/ap-2019"]},"subdomains":{"include":[/^apcentral\.collegeboard\.org$/i]},"domains":[/collegeboard\.org$/i]},"conditions":[function(event,target){
var cmet = true;
if (_satellite.getVar('QP userName') || document.referrer.match(/userName=[^\&]+/)) {
cmet = false;
}
return cmet;
}],"event":"pagebottom"},
{"name":"Pixel - DM - SnapChat","trigger":[{"command":"loadScript","arguments":[{"sequential":false,"scripts":[{"src":"satellite-5c705b1964746d101a0008bf.js"}]}]}],"scope":{"subdomains":{"include":[/^(?:opportunity|eyf)(?:(?:-.*)?\.collegeplanning-(?:non)?prod)?\.collegeboard\.org$/i,/^(account|cbaccount|nsat|signup)\.collegeboard\.org$/i]}},"conditions":[function(event,target){
var cmet = true;
if (_satellite.getVar('QP userName') || document.referrer.match(/userName=[^\&]+/)) {
cmet = false;
}
return cmet;
}],"event":"pagebottom"},
{"name":"Pixel - Google Tag - CB India","trigger":[{"command":"loadScript","arguments":[{"sequential":false,"scripts":[{"src":"satellite-5db0501264746d34d4000071.js"}]}]}],"scope":{"subdomains":{"include":[/^(account|cbaccount|nsat|signup)\.collegeboard\.org$/i]},"domains":[/collegeboard\.org$/i]},"conditions":[function(event,target){
var cmet = true;
if (_satellite.getVar('QP userName') || document.referrer.match(/userName=[^\&]+/)) {
cmet = false;
}
return cmet;
}],"event":"pagebottom"},
{"name":"Pixel - Google Tag - CB India 2","trigger":[{"command":"loadScript","arguments":[{"sequential":false,"scripts":[{"src":"satellite-5e34689464746d0c4e0009d8.js"}]}]}],"scope":{"subdomains":{"include":[/^(account|cbaccount|nsat|signup)\.collegeboard\.org$/i]},"domains":[/collegeboard\.org$/i]},"conditions":[function(event,target){
var cmet = true;
if (_satellite.getVar('QP userName') || document.referrer.match(/userName=[^\&]+/)) {
cmet = false;
}
return cmet;
}],"event":"pagebottom"},
{"name":"Pixel - Google Tag - CB LP","trigger":[{"command":"loadScript","arguments":[{"sequential":false,"scripts":[{"src":"satellite-5d6eaff964746d0c4f0006ab.js"}]}]}],"scope":{"subdomains":{"include":[/^(account|bigfuture|cbaccount|clep|collegereadiness|go|nsat|signup)\.collegeboard\.org$/i]},"domains":[/collegeboard\.org$/i]},"conditions":[function(event,target){
var cmet = true;
if (_satellite.getVar('QP userName') || document.referrer.match(/userName=[^\&]+/)) {
cmet = false;
}
return cmet;
}],"event":"pagebottom"},
{"name":"Pixel - Google Tag - CB Main","trigger":[{"command":"loadScript","arguments":[{"sequential":false,"scripts":[{"src":"satellite-5b44fdc364746d17900089e9.js"}]}]}],"scope":{"subdomains":{"include":[/^(account|apstudents|bigfuture|cbaccount|clep|clepportal|collegereadiness|go|nsat|pages|parents|signup|studentscores|www)\.collegeboard\.org$/i]}},"conditions":[function(event,target){
var cmet = true;
if (_satellite.getVar('QP userName') || document.referrer.match(/userName=[^\&]+/)) {
cmet = false;
}
return cmet;
}],"event":"pagebottom"},
{"name":"Pixel - OneTrust - v1 PROD","trigger":[{"command":"writeHTML","arguments":[{"html":"\u003c!-- OneTrust Cookies Consent Notice (Production CDN, collegeboard.org, en-GB) start --\u003e\n\u003cscript src=\"https://cdn.cookielaw.org/consent/3700e0a7-263f-4b29-87c0-e1c5fcf7ed80.js\" type=\"text/javascript\" charset=\"UTF-8\"\u003e\u003c/script\u003e\n\u003cscript type=\"text/javascript\"\u003e\n function OptanonWrapper() { }\n\u003c/script\u003e\n\u003c!-- OneTrust Cookies Consent Notice (Production CDN, collegeboard.org, en-GB) end --\u003e\n"}]}],"scope":{"subdomains":{"exclude":[/\.overturecorp\.com$/i,/\.springboardonline\.org$/i,/^profile\.collegeboard\.org$/i,/^idoc\.collegeboard\.org$/i]}},"event":"pagebottom"},
{"name":"Pixel - UX - Lucky Orange","trigger":[{"command":"loadScript","arguments":[{"sequential":false,"scripts":[{"src":"satellite-57d84a9d64746d4d4100dc5e.js"}]}]}],"scope":{"domains":[/apscore\.org$/i,/collegeboard\.com$/i,/collegeboard\.org$/i]},"event":"pagebottom"},
{"name":"Pixel - UX - Mouseflow (Regular) ","trigger":[{"command":"loadScript","arguments":[{"sequential":false,"scripts":[{"src":"satellite-5d6045a964746d4afa000f8a.js"}]}]}],"scope":{"subdomains":{"include":[/^apscore\.collegeboard\.org$/i]}},"event":"pagetop"},
{"name":"Set Cookie - viewed_college_plan","trigger":[{"command":"loadScript","arguments":[{"sequential":false,"scripts":[{"src":"satellite-5d8a5d8364746d424a000dcc.js"}]}]}],"scope":{"URI":{"include":[/\/fp-your-college-plan-11$/i]},"subdomains":{"include":[/^pages\.collegeboard\.org$/i]},"domains":[/collegeboard\.org$/i]},"event":"pagebottom"},
{"name":"Survey - GetSiteControl - 1 Recording Intro","trigger":[{"command":"loadScript","arguments":[{"sequential":false,"scripts":[{"src":"satellite-57e582c264746d0608008af2.js"}]}]}],"scope":{"subdomains":{"include":[/^international\.collegeboard\.org$/i]}},"conditions":[function(event,target){
/**
* Created by jbeach on 2019-04-10
* Updated by jbeach on 2019-04-15
*/
var cmet = false;
if(!_satellite.readCookie('gsc1_fired')) {
document.cookie = 'gsc1_fired=1;path=/;domain=collegeboard.org';
cmet = true;
}
return cmet;
}],"event":"pagebottom"},
{"name":"Survey - GetSiteControl - 2 APS Intercept","trigger":[{"command":"loadScript","arguments":[{"sequential":false,"scripts":[{"src":"satellite-580fa55364746d38fe0099bd.js"}]}]}],"scope":{"subdomains":{"include":[/^(apstudents)\.collegeboard\.org$/i]}},"event":"pagebottom"},
{"name":"Survey - GetSiteControl - 3 Dynamic Intercept","trigger":[{"command":"loadScript","arguments":[{"sequential":false,"scripts":[{"src":"satellite-5cc06f4964746d5d38000664.js"}]}]}],"scope":{"subdomains":{"include":[/^apcentral\.collegeboard\.org$/i]}},"event":"pagebottom"},
{"name":"Survey - GetSiteControl - 4 Dynamic Intercept 2","trigger":[{"command":"loadScript","arguments":[{"sequential":false,"scripts":[{"src":"satellite-5d80ec1964746d4b5e0000ed.js"}]}]}],"scope":{"subdomains":{"include":[/^opportunity\.collegeboard\.org$/i]}},"event":"pagebottom"},
{"name":"Survey - GetSiteControl - 5 Dynamic Intercept","trigger":[{"command":"loadScript","arguments":[{"sequential":false,"scripts":[{"src":"satellite-5db0a6ee64746d728900014b.js"}]}]}],"scope":{"subdomains":{"include":[/^(collegereadiness|nsat|studentscores|k12reports)\.collegeboard\.org$/i]}},"conditions":[function(event,target){
var cmet = false,
h = document.location.host,
p = document.location.pathname,
isLowerEnv = false,
isProdEnv = true;
if (typeof window.cbEnvLower) {
isLowerEnv = (typeof window.cbEnvLower === 'boolean')
?window.cbEnvLower
:(window.cbEnvLower === 'true');
isProdEnv = !isLowerEnv;
}
if (typeof window.cbEnv) {
isProdEnv = (window.cbEnv === 'prod');
isLowerEnv = !isProdEnv;
}
switch (h) {
case 'nsat.collegeboard.org':
//display only on non-lower/prod environments
cmet = isProdEnv;
break;
default:
//display everywhere
cmet = true;
break;
}
return cmet;
}],"event":"pagebottom"},
{"name":"Survey - GetSiteControl - Apricot Form Fix","trigger":[{"command":"loadScript","arguments":[{"sequential":false,"scripts":[{"src":"satellite-57d8406964746d192c00efc1.js"}]}]}],"scope":{"domains":[/apscore\.org$/i,/collegeboard\.com$/i,/collegeboard\.org$/i]},"event":"pagebottom"},
{"name":"Survey - GetSiteControl - BigFuture","trigger":[{"command":"loadScript","arguments":[{"sequential":false,"scripts":[{"src":"satellite-5b85639364746d7f9d002c8d.js"}]}]}],"scope":{"subdomains":{"include":[/^bigfuture\.collegeboard\.org$/i]},"domains":[/collegeboard\.org$/i]},"event":"pagebottom"},
{"name":"Survey - GetSiteControl - Usability","trigger":[{"command":"loadScript","arguments":[{"sequential":false,"scripts":[{"src":"satellite-57d8472b64746d57f400639c.js"}]}]}],"scope":{"URI":{"exclude":[/^\/fp-/i]},"subdomains":{"exclude":[/^(accommodations|go|ssd|signup)\.collegeboard\.org$/i,/^(testday|(dev|qa|uat)-tdtk\.fed-nonprod)\.collegeboard\.org$/i,/^(finaidportalbeta|finaidportal|idoc|idocbeta|cssprofile|profilebeta|profile)\.collegeboard\.org$/i,/^latam\.collegeboard\.org$/i,/^collegeboardsearch\.collegeboard\.org$/i,/^ap2020studentresponses\.collegeboard\.org$/i]},"domains":[/apscore\.org$/i,/collegeboard\.com$/i,/collegeboard\.org$/i]},"conditions":[function(event,target){
/**
* Created by jbeach on 2020-04-14
* Updated by jbeach on 2020-04-14
*/
var cmet = false,
h = document.location.host,
p = document.location.pathname,
cbEnvLower = 'false';
if (typeof window.cbEnvLower) {
cbEnvLower = window.cbEnvLower;
}
switch (h) {
case 'nsat.collegeboard.org':
case 'satscoresends.collegeboard.org':
//display only on non-lower/prod environments
cmet = !cbEnvLower;
break;
default:
//display everywhere
cmet = true;
break;
}
return cmet;
}],"event":"pagebottom"},
{"name":"Survey - Helpflns (SG) - AP Sites","trigger":[{"command":"loadScript","arguments":[{"sequential":false,"scripts":[{"src":"satellite-5e67a15c64746d600b0007a8.js"}]}]}],"scope":{"subdomains":{"include":[/^apstudents(-(origin|stg|dev))?\.collegeboard\.org$/i,/^apcentral(-(origin|stg|dev))?\.collegeboard\.org$/i,/^apcoronavirusupdates(-(origin|stg|dev))?\.collegeboard\.org$/i,/^aphighered(-(origin|stg|dev))?\.collegeboard\.org$/i]}},"conditions":[function(event,target){
/**
* Created by jbeach on 2018-10-29
* Updated by jbeach on 2020-04-03
*/
var cmet = false,
h = document.location.host,
p = document.location.pathname;
switch (h) {
case 'apstudents-dev.collegeboard.org':
case 'apstudents-stg.collegeboard.org':
case 'apstudents-origin.collegeboard.org':
case 'apstudents.collegeboard.org':
case 'apcentral-dev.collegeboard.org':
case 'apcentral-stg.collegeboard.org':
case 'apcentral-origin.collegeboard.org':
case 'apcentral.collegeboard.org':
//display everywhere except root/home page
if (!(p.match(/^\/$/i))) {
cmet = true;
}
break;
default:
//display everywhere
cmet = true;
break;
}
return cmet;
}],"event":"pagebottom"},
{"name":"Survey - Helpflns (SG) - International","trigger":[{"command":"loadScript","arguments":[{"sequential":false,"scripts":[{"src":"satellite-5ef3c09c64746d7f6b001fd9.js"}]}]}],"scope":{"subdomains":{"include":[/^international(-(origin|stg|dev))?\.collegeboard\.org$/i]}},"event":"pagebottom"},
{"name":"Survey - Helpflns (SG) - Membership","trigger":[{"command":"loadScript","arguments":[{"sequential":false,"scripts":[{"src":"satellite-5ee966e264746d6fc400122d.js"}]}]}],"scope":{"subdomains":{"include":[/^membership(-(origin|stg|dev))?\.collegeboard\.org$/i]}},"event":"pagebottom"},
{"name":"Survey - Helpflns (SG) - My","trigger":[{"command":"loadScript","arguments":[{"sequential":false,"scripts":[{"src":"satellite-5f18433864746d3fed000e0e.js"}]}]}],"scope":{"subdomains":{"include":[/^my(-(origin|stg|dev))?\.collegeboard\.org$/i,/^mycb-prod\.mycollegeboard-prod\.collegeboard\.org$/i,/^mycb-(dev|qa|staging|oat|perf)\.mycollegeboard-nonprod\.collegeboard\.org$/i]}},"event":"pagebottom"}
],
"rules": [
{"name":"BFCL Widget - Login Modal Shown","trigger":[{"engine":"sc","command":"trackLink","arguments":[{"type":"o","linkName":"BFCL Widget - Login Modal"}]}],"selector":"html","eventHandlerOnElement":true,"event":"custom","bubbleFireIfParent":true,"bubbleFireIfChildFired":true,"bubbleStop":false,"customEvent":"kiwi.widgetScreenTrack.bfclLoginModal"},
{"name":"BFCL Widget - Popover Dismissed","trigger":[{"engine":"sc","command":"trackLink","arguments":[{"type":"o","linkName":"BFCL Widget - Popover Dismissed"}]}],"selector":"html","eventHandlerOnElement":true,"event":"custom","bubbleFireIfParent":true,"bubbleFireIfChildFired":true,"bubbleStop":false,"customEvent":"kiwi.widgetScreenTrack.bfclHide"},
{"name":"BFCL Widget - Popover Shown","trigger":[{"engine":"sc","command":"trackLink","arguments":[{"type":"o","linkName":"Widget Screen - BFCL Widget"}]}],"selector":"html","eventHandlerOnElement":true,"event":"custom","bubbleFireIfParent":true,"bubbleFireIfChildFired":true,"bubbleStop":false,"customEvent":"kiwi.widgetScreenTrack.bfclShow"},
{"name":"Click - Accordion Expand","trigger":[{"engine":"sc","command":"trackLink","arguments":[{"type":"o","linkName":"Feature Used - Accordion","customSetup":function(event,s){
/**
* Created by jbeach on 2019-01-23
* Updated by jbeach on 2019-01-23
*/
kiwi = window.kiwi || {};
var ruleName='KIWI: EBR > Click - Accordion Expand > Analytics JS';
_satellite.notify(ruleName);
kiwi._elementToTest = this;
}}]}],"selector":"[data-cbtrack-accordion] a, [data-cbtrack-accordion] button","eventHandlerOnElement":true,"event":"click","bubbleFireIfParent":true,"bubbleFireIfChildFired":true,"bubbleStop":false},
{"name":"Click - Auto-Suggested Term Search Link","trigger":[{"engine":"sc","command":"trackLink","arguments":[{"type":"o","linkName":"Auto-Suggested Term Search Link"}]}],"selector":"[data-cbtrack-linkgroup=\"search-sugg\"] [data-cbtrack-linktype=\"nav\"], .lv-search-widget .lv-suggestions li a","eventHandlerOnElement":true,"event":"click","bubbleFireIfParent":true,"bubbleFireIfChildFired":true,"bubbleStop":false},
{"name":"Click - CBOS Opt Out","trigger":[{"command":"loadScript","arguments":[{"sequential":false,"scripts":[{"src":"satellite-5ca63d0c64746d78ba00342f.js"}]}]}],"selector":".cbos-main #optOutModal #opt-out-yes","event":"click","bubbleFireIfParent":true,"bubbleFireIfChildFired":true,"bubbleStop":false},
{"name":"Click - CBOS Terms Accept","trigger":[{"engine":"sc","command":"trackLink","arguments":[{"type":"o","linkName":"CBOS Terms Accept"}]}],"selector":"[data-cbtrack-cbos-optin]:not([disabled])","event":"click","bubbleFireIfParent":true,"bubbleFireIfChildFired":true,"bubbleStop":false},
{"name":"Click - CTA Card","trigger":[{"engine":"sc","command":"trackLink","arguments":[{"type":"o","linkName":"Feature Used - CTA Card","customSetup":function(event,s){
/**
* Created by jbeach on 2019-05-02
* Updated by jbeach on 2019-05-02
*/
kiwi = window.kiwi || {};
var ruleName='KIWI: EBR > Click - CTA Card > Analytics JS';
_satellite.notify(ruleName);
kiwi._elementToTest = this;
}}]}],"selector":"[data-cbtrack-ctacard] a, [data-cbtrack-ctacard] button","eventHandlerOnElement":true,"event":"click","bubbleFireIfParent":true,"bubbleFireIfChildFired":true,"bubbleStop":false},
{"name":"Click - Confirm ECL Account Create","trigger":[{"engine":"sc","command":"trackLink","arguments":[{"type":"o","linkName":"Confirm ECL Account Create"}]}],"scope":{"URI":{"include":[/^\/iamweb\/registerAccount/i]},"subdomains":{"include":[/^cbaccount\.collegeboard\.org$/i]},"domains":[/collegeboard\.org$/i]},"conditions":[function(event,target){
/**
* Created by jbeach on 2019-10-31
* Updated by jbeach on 2019-10-31
*/
var cmet = false,
strAriaDisabledVal = this.getAttribute('aria-disabled');
if (strAriaDisabledVal && strAriaDisabledVal.match(/^false$/i)) {
cmet = true;
}
return cmet;
}],"selector":"button#registerAccount","event":"click","bubbleFireIfParent":true,"bubbleFireIfChildFired":true,"bubbleStop":false},
{"name":"Click - Crosslink","trigger":[{"engine":"sc","command":"trackLink","arguments":[{"type":"o","linkName":"Feature Used - Crosslink","customSetup":function(event,s){
/**
* Created by jbeach on 2019-04-12
* Updated by jbeach on 2019-04-12
*/
kiwi = window.kiwi || {};
var ruleName='KIWI: EBR > Click - Crosslink > Analytics JS';
_satellite.notify(ruleName);
kiwi._elementToTest = this;
}}]}],"selector":"[data-cbtrack-crosslink]","eventHandlerOnElement":true,"event":"click","bubbleFireIfParent":true,"bubbleFireIfChildFired":true,"bubbleStop":false},
{"name":"Click - Download Link","trigger":[{"engine":"sc","command":"trackLink","arguments":[{"type":"d","linkName":"Download Link","customSetup":function(event,s){
/**
* Created by jbeach on 2016-12-02
* Updated by jbeach on 2018-01-19
*/
kiwi = window.kiwi || {};
var ruleName='KIWI: EBR > Click - Download Link > Analytics JS';
_satellite.notify(ruleName);
kiwi._elementToTest = this;
}}]},{"command":"delayActivateLink"}],"selector":"a","property":{"href":/\.(?:arf|avi|css|csv|dmg|doc|docx|dotx|eps|exe|ics|js|m4v|mov|mp3|mp4|mpg|pages|pdf|ppt|pptx|rar|rm|rtf|swf|tab|txt|vsd|vxd|wav|wma|wmv|xls|xlsx|xml|zip)($|\&|\?)/i},"event":"click","bubbleFireIfParent":true,"bubbleFireIfChildFired":true,"bubbleStop":false},
{"name":"Click - Dynamic Download Link","trigger":[{"engine":"sc","command":"trackLink","arguments":[{"type":"o","linkName":"Dynamic Download Link","customSetup":function(event,s){
/**
* Created by jbeach on 2016-12-02
* Updated by jbeach on 2018-01-19
*/
kiwi = window.kiwi || {};
var ruleName='KIWI: EBR > Click > Dynamic Download Link > Analytics JS';
_satellite.notify(ruleName);
kiwi._elementToTest = this;
}}]}],"selector":"[dynamic-asset-link-track],[data-cbtrack-download],[download]","event":"click","bubbleFireIfParent":true,"bubbleFireIfChildFired":true,"bubbleStop":false},
{"name":"Click - Event Card","trigger":[{"engine":"sc","command":"trackLink","arguments":[{"type":"o","linkName":"Feature Used - Event Card","customSetup":function(event,s){
/**
* Created by jbeach on 2019-05-17
* Updated by jbeach on 2019-05-17
*/
kiwi = window.kiwi || {};
var ruleName='KIWI: EBR > Click - Event Card > Analytics JS';
_satellite.notify(ruleName);
kiwi._elementToTest = this;
}}]}],"selector":"[data-cbtrack-ec] a, [data-cbtrack-ec] button","eventHandlerOnElement":true,"event":"click","bubbleFireIfParent":true,"bubbleFireIfChildFired":true,"bubbleStop":false},
{"name":"Click - Exit Link - New Tab","trigger":[{"engine":"sc","command":"trackLink","arguments":[{"type":"e","linkName":"Exit Link","customSetup":function(event,s){
/**
* Created by jbeach on 2016-12-02
* Updated by jbeach on 2018-01-19
*/
kiwi = window.kiwi || {};
var ruleName='KIWI: EBR > Click - Exit Link - New Tab > Analytics JS';
_satellite.notify(ruleName);
kiwi._elementToTest = this;
//if (_satellite.getVar('Async Promo Link Fired')) s.abort;
}}]}],"conditions":[function(event,target){
/**
* Created by jbeach on 2017-02-16
* Updated by jbeach on 2017-03-21
*/
//NEW TAB LOGIC
//check if outbound link
var cmet = false,
outBoundLink = _satellite.isOutboundLink(this),
newTab = false;
if (outBoundLink) {
//check if link opens in a new tab and if not so, set false
var myTarget = this.getAttribute('target'),
myDataTarget = this.getAttribute('data-target'),
myClass = this.getAttribute('class');
if (myTarget && myTarget.match(/^(_blank|_new)$/i)) {
newTab = true;
} else if (myDataTarget && myDataTarget.match(/^new-window$/i)) {
newTab = true;
} else if (myClass && myClass.match(/(?: |^)nav-item(?: |$)/i)) {//temp logic for SSR + RTN pop tools links until they can use data-target attribute
newTab = true;
}
}
cmet = outBoundLink && newTab;
return cmet;
}],"selector":"a","event":"click","bubbleFireIfParent":true,"bubbleFireIfChildFired":true,"bubbleStop":false},
{"name":"Click - Exit Link - Same Tab","trigger":[{"engine":"sc","command":"trackLink","arguments":[{"type":"e","linkName":"Exit Link","customSetup":function(event,s){
/**
* Created by jbeach on 2016-12-02
* Updated by jbeach on 2018-01-19
*/
kiwi = window.kiwi || {};
var ruleName='KIWI: EBR > Click - Exit Link - Same Tab > Analytics JS';
_satellite.notify(ruleName);
kiwi._elementToTest = this;
}}]},{"command":"delayActivateLink"}],"conditions":[function(event,target){
/**
* Created by jbeach on 2017-02-16
* Updated by jbeach on 2017-03-14
*/
//SAME TAB LOGIC
//check if outbound link
var cmet = _satellite.isOutboundLink(this);
if (cmet) {
//check if link opens in a new tab and if so, set false
var myTarget = this.getAttribute('target'),
myDataTarget = this.getAttribute('data-target'),
myClass = this.getAttribute('class');
if (myTarget && myTarget.match(/^(_blank|_new)$/i)) {
cmet = false;
} else if (myDataTarget && myDataTarget.match(/^new-window$/i)) {
cmet = false;
} else if (myClass && myClass.match(/(?: |^)nav-item(?: |$)/i)) {//temp logic for SSR + RTN pop tools links until they can use data-target attribute
cmet = false;
}
}
return cmet;
}],"selector":"a","event":"click","bubbleFireIfParent":true,"bubbleFireIfChildFired":true,"bubbleStop":false},
{"name":"Click - FW Eligibility","trigger":[{"engine":"sc","command":"trackLink","arguments":[{"type":"o","linkName":"Feature Used - Custom","customSetup":function(event,s){
/**
* Created by jbeach on 2019-03-25
* Updated by jbeach on 2019-03-25
*/
kiwi = window.kiwi || {};
var ruleName='KIWI: EBR > Click - FW Eligibility > Analytics JS';
_satellite.notify(ruleName);
kiwi._elementToTest = this;
}}]}],"scope":{"subdomains":{"include":[/^nsat\.collegeboard\.org$/i]}},"selector":"#s2-fwEligibilitymodal-continueButton","event":"click","bubbleFireIfParent":true,"bubbleFireIfChildFired":true,"bubbleStop":false},
{"name":"Click - Feature","trigger":[{"engine":"sc","command":"trackLink","arguments":[{"type":"o","linkName":"Feature Used - Feature","customSetup":function(event,s){
kiwi = window.kiwi || {};
var ruleName='KIWI: EBR > Click - Feature > Analytics JS';
_satellite.notify(ruleName);
kiwi._elementToTest = this;
}}]}],"selector":"[data-kiwi-featureclick]","event":"click","bubbleFireIfParent":true,"bubbleFireIfChildFired":true,"bubbleStop":false},
{"name":"Click - Feature (Legacy)","trigger":[{"engine":"sc","command":"trackLink","arguments":[{"type":"o","linkName":"Feature","customSetup":function(event,s){
/**
* Created by jbeach on 2018-04-19
*/
kiwi = window.kiwi || {};
var ruleName='KIWI: EBR > Click - Feature > Analytics JS';
_satellite.notify(ruleName);
kiwi._elementToTest = this;
}}]},{"command":"delayActivateLink"}],"selector":"[data-cbtrack]","event":"click","bubbleFireIfParent":true,"bubbleFireIfChildFired":true,"bubbleStop":false},
{"name":"Click - Filter Apply","trigger":[{"engine":"sc","command":"trackLink","arguments":[{"type":"o","linkName":"Feature Used - Filter","customSetup":function(event,s){
/**
* Created by jbeach on 2019-01-16
* Updated by jbeach on 2019-01-16
*/
kiwi = window.kiwi || {};
var ruleName='KIWI: EBR > Click - Filter Applied > Analytics JS';
_satellite.notify(ruleName);
kiwi._elementToTest = this.closest('[data-cbtrack-filter]');
}}]},{"command":"delayActivateLink"}],"selector":"[data-cbtrack-filter] .cb-filter-apply, [data-cbtrack-filter] form [type=\"submit\"], [data-cbtrack-filter] [name=\"lv-form-college-search-submit\"]","eventHandlerOnElement":true,"event":"click","bubbleFireIfParent":true,"bubbleFireIfChildFired":true,"bubbleStop":false},
{"name":"Click - Iframe Report Link","trigger":[{"engine":"sc","command":"trackLink","arguments":[{"type":"o","linkName":"Iframe Report Link","customSetup":function(event,s){
/**
* Created by jbeach on 2019-05-06
* Updated by jbeach on 2019-05-06
*/
kiwi = window.kiwi || {};
var ruleName='KIWI: EBR > Click > Iframe Report Link > Analytics JS';
_satellite.notify(ruleName);
kiwi._elementToTest = this;
}}]}],"selector":"[data-cbtrack-iframereport]","event":"click","bubbleFireIfParent":true,"bubbleFireIfChildFired":true,"bubbleStop":false},
{"name":"Click - Jump Link Jump","trigger":[{"engine":"sc","command":"trackLink","arguments":[{"type":"o","linkName":"Feature Used - Jump Link","customSetup":function(event,s){
/**
* Created by jbeach on 2019-02-05
* Updated by jbeach on 2019-02-05
*/
kiwi = window.kiwi || {};
var ruleName='KIWI: EBR > Click - Jump Link Jump > Analytics JS';
_satellite.notify(ruleName);
kiwi._elementToTest = this;
}}]}],"selector":".cb-jumplinks-menu a, .cb-jumplinks-container .cb-jumplinks-back, #help-topics + ul li a, a[href=\"#help-topics\"]","eventHandlerOnElement":true,"event":"click","bubbleFireIfParent":true,"bubbleFireIfChildFired":true,"bubbleStop":false},
{"name":"Click - Key Benefit","trigger":[{"engine":"sc","command":"trackLink","arguments":[{"type":"o","linkName":"Feature Used - Key Benefit","customSetup":function(event,s){
/**
* Created by jbeach on 2019-11-19
* Updated by jbeach on 2019-11-19
*/
kiwi = window.kiwi || {};
var ruleName='KIWI: EBR > Click - Key Benefit > Analytics JS';
_satellite.notify(ruleName);
kiwi._elementToTest = this;
}}]}],"selector":"[data-cbtrack-keybenefits] a, [data-cbtrack-keybenefits] button","eventHandlerOnElement":true,"event":"click","bubbleFireIfParent":true,"bubbleFireIfChildFired":true,"bubbleStop":false},
{"name":"Click - LIFW Opt In Form","trigger":[{"engine":"sc","command":"trackLink","arguments":[{"type":"o","linkName":"LIFW Opt In Form Submit"}]}],"conditions":[function(event,target){
/**