{"version":3,"sources":["webpack:///./node_modules/@financial-times/n-tracking/dist/browser.js","webpack:///./node_modules/@financial-times/n-tracking/node_modules/@financial-times/o-grid/browser.js","webpack:///./node_modules/@financial-times/n-tracking/node_modules/@financial-times/o-viewport/browser.js","webpack:///./node_modules/@financial-times/n-tracking/node_modules/@financial-times/o-viewport/dist/utils.js","webpack:///./node_modules/@financial-times/n-tracking/node_modules/@financial-times/o-utils/browser.js","webpack:///./node_modules/ready-state/dist/ready-state.es.js","webpack:///./node_modules/@financial-times/o-tracking/src/javascript/events/custom.js","webpack:///./node_modules/@financial-times/o-tracking/src/javascript/events/page-view.js","webpack:///./node_modules/ftdomdelegate/main.js","webpack:///./node_modules/@financial-times/o-tracking/src/libs/get-trace.js","webpack:///./node_modules/@financial-times/o-tracking/src/javascript/events/click.js","webpack:///./node_modules/@financial-times/o-tracking/src/javascript/events/component-view.js","webpack:///./node_modules/@financial-times/o-tracking/src/javascript/tracking.js","webpack:///./node_modules/@financial-times/o-tracking/main.js"],"names":["getCookie","name","regex","RegExp","match","document","cookie","getUserData","networkInfo","navigator","connection","mozConnection","webkitConnection","layout","getCurrentLayout","orientation","getOrientation","connectionType","type","undefined","ft_session_publib","dataPropertyMap","appName","contentId","contentType","conceptId","conceptType","segmentid","cpccampaign","abTestState","transformContextData","contextData","result","Object","keys","forEach","key","value","list","split","map","flag","transformListToObject","content","uuid","asset_type","broadcast","data","bubbles","rootEl","Element","prototype","isPrototypeOf","this","body","event","CustomEvent","cancelable","detail","dispatchEvent","n","t","i","o","window","e","console","r","performance","u","deviceMemory","c","hardwareConcurrency","a","getEntriesByType","now","mark","f","s","l","m","v","d","hidden","p","parseFloat","toFixed","g","Math","pow","b","h","T","k","ttfb","fp","fcp","lcp","lcpFinal","fid","cls","clsFinal","tbt","ntbt","y","w","indexOf","analyticsTracker","metricName","eventProperties","navigatorInformation","serviceWorkerStatus","serviceWorker","controller","isLowEndDevice","isLowEndExperience","vitalsScore","requestIdleCallback","timeout","_","F","E","x","D","I","P","beacon","css","fetch","img","other","script","total","xmlhttprequest","j","q","C","pop","L","O","PerformanceObserver","getEntries","observe","buffered","warn","S","disconnect","W","processingStart","startTime","performanceEntry","takeRecords","setTimeout","B","duration","M","z","renderTime","loadTime","H","identifier","N","decodedBodySize","initiatorType","R","A","usageDetails","quota","usage","caches","indexedDB","serviceWorkerRegistrations","G","J","resourceTiming","elementTiming","maxMeasureTime","addEventListener","bind","responseStart","responseEnd","fetchTime","fetchStart","workerTime","workerStart","totalTime","requestStart","downloadTime","timeToFirstByte","headerSize","transferSize","encodedBodySize","dnsLookupTime","domainLookupEnd","domainLookupStart","redirectTime","redirectEnd","redirectStart","effectiveType","saveData","downlink","rtt","storage","estimate","then","start","end","measure","getEntriesByName","entryType","endPaint","clear","clearMarks","markNTBT","clearTimeout","commonjsGlobal","globalThis","global","self","seedRandom","fn","module","exports","createCommonjsModule","pool","GLOBAL","startdenom","significance","overflow","oldRandom","random","ARC4","keylen","length","me","width","count","flatten","obj","depth","prop","typ","push","mixkey","seed","smear","stringseed","charCodeAt","tostring","autoseed","crypto","getRandomValues","Uint8Array","Date","plugins","screen","String","fromCharCode","apply","options","use_entropy","entropy","arc4","arguments","resetGlobal","requiredMetrics","DEPTH_MARKERS","defaultOptions","onScroll","target","debug","ScrollDepth","init","querySelector","observer","IntersectionObserver","handleIntersection","style","position","percentage","marker","createElement","className","top","bottom","zIndex","setAttribute","appendChild","changes","change","isIntersecting","intersectionRatio","scrollDepth","getAttribute","log","parentNode","removeChild","unobserve","ATTENTION_EVENTS","ATTENTION_LOST_EVENTS","PAGE_EXIT_EVENTS","defaultOptions$1","onExit","AttentionTime","totalAttentionTime","hasExited","startAttention","endAttention","handleExit","handleVisibilityChange","querySelectorAll","element","startConstantAttention","endConstantAttention","attentionTimeout","startAttentionTime","getAttentionTime","time","constantAttentionInterval","setInterval","clearInterval","currentAttentionTime","round","visibilityState","index","freeze","__proto__","realUserMonitoringForPerformance","sampleRate","percent","pseudoRandomNumber","randomNumberGenerator","seedIsInSample","Number","isFinite","navigation","context","complete","domInteractive","domComplete","hasAlreadyBroadcast","firstInputDelay","largestContentfulPaint","firstPaint","firstContentfulPaint","cumulativeLayoutShift","totalBlockingTime","url","location","href","every","metric","isContextComplete","performanceMetrics","action","category","logging","pageAttention","attention","attentionTime","meta","percentagesViewed","textCopying","nodeName","toLowerCase","getSelection","selection","toString","trim","characters","words","text","newLength","left","floor","right","ceil","substr","getTextExcerpt","SPOOR_API_INGEST_URL","appContext","extraContext","pageViewContext","queryParams","queryString","search","searchParams","URLSearchParams","property","get","getQueryParams","server","user","useSendBeacon","hostname","errorPageParams","errorStatus","errorReason","parent","referrer","getErrorPageParams","page","click","defineProperty","getCurrentGutter","getGridBreakpoints","enableLayoutChangeEvents","default","missingDataMessage","getGridProperties","properties","getGridFromDoc","breakpoints","gridProperties","getComputedStyle","documentElement","getPropertyValue","replace","JSON","parse","gutter","gridLayouts","hasOwnProperty","layouts","entries","sort","setupQuery","query","size","handleMQChange","mql","matches","matchMedia","addListener","layoutName","layoutWidth","concat","nextLayoutWidth","error","_default","_utils","__esModule","throttle","debounce","listeners","intervals","resize","visibility","scroll","listenTo","eventType","handler","ev","viewport","getSize","originalEvent","listenToResize","scrollPos","getScrollPosition","scrollHeight","height","scrollLeft","scrollTop","scrollWidth","listenToScroll","listenToOrientation","getVisibility","listenToVisibility","stopListeningTo","removeEventListener","setThrottleInterval","interval","_debug","Utils","cache","_getRequireWildcardCache","has","newObj","hasPropertyDescriptor","getOwnPropertyDescriptor","call","desc","set","_interopRequireWildcard","WeakMap","getHeight","ignoreScrollbars","clientHeight","max","innerHeight","getWidth","clientWidth","innerWidth","pageXOffset","scrollX","pageYOffset","scrollY","func","wait","args","later","capture","once","passive","readyState","Promise","defineProperties","state","loading","interactive","load","domready","dom","ready","trackingEvent","callback","noCategoryActionVals","info","config","origamiElement","srcElement","getOrigamiEventTarget","component_name","component_id","path","parentElement","_getElementPath","siblingIndex","srcParent","childNodes","str","_generateHash","reduceRight","builder","el","constructor","id","getComponentId","core","track","URL","setRootID","configWithoutContextIDs","stringify","root_id","previousPageConfigWithoutContextIDs","pageViewEventHasAlreadyBeenSentBefore","test","listener","Delegate","root","listenerMap","handle","_removedListeners","matchesTag","tagName","matchesRoot","selector","rootElement","matchesId","captureForType","on","useCapture","matcher","matcherParam","TypeError","slice","off","listenerList","singleEventType","splice","phase","returned","nodeType","correspondingUseElement","eventPhase","currentTarget","ret","toFire","hasAttribute","HTMLDocument","fire","preventDefault","destroy","getSiblingsAndPosition","originalEl","siblings","Array","from","findIndex","item","elementPropertiesToCollect","getAllElementProperties","getAttributeValue","rawValue","isJSON","parsedValue","parseRawValue","getDomPathProps","attrs","props","filter","attribute","getContextProps","isOriginalEl","customProps","getTrace","trace","customContext","attributes","domPathProps","assign","contextProps","delegate","eventPropertiesToCollect","handleClickEvent","eventData","clickEvent","clickElement","getEventProperties","domPathTokens","source_id","getRootID","elementsToTrack","sendAllEventsFromQueue","queue","nextLink","shift","TRACKING_ATTRIBUTES","view","opts","viewedEl","getContextData","Error","decorateEventData","threshold","initEvent","initPage","updateConfig","newConfig","user_id","getDeclarativeConfigElement","tracking","initialised","version","source","Boolean","configEl","declarativeConfigString","textContent","innerText","innerHTML","declarativeOptions","configError","message","getDeclarativeConfig","cookieDomain","session","initialise"],"mappings":"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","file":"1.763224f2.js","sourcesContent":["import oTracking from '@financial-times/o-tracking';\nimport oGrid from '@financial-times/o-grid';\nimport oViewport from '@financial-times/o-viewport';\nimport readyState from 'ready-state';\n\nfunction getCookie (name) {\n\tconst regex = new RegExp(`(?:^| )${name}=([^;]+)`);\n\tconst match = document.cookie && document.cookie.match(regex);\n\treturn match ? match[1] : null;\n}\n\nconst getLibrarySession = () => getCookie('FTSession_PubLib');\n\nfunction getUserData () {\n\t// https://developer.mozilla.org/en-US/docs/Web/API/NetworkInformation\n\tconst networkInfo =\n\t\tnavigator.connection ||\n\t\tnavigator.mozConnection ||\n\t\tnavigator.webkitConnection;\n\n\treturn {\n\t\tlayout: oGrid.getCurrentLayout(),\n\t\torientation: oViewport.getOrientation(),\n\t\tconnectionType: networkInfo ? networkInfo.type : undefined,\n\t\tft_session_publib: getLibrarySession()\n\t};\n}\n\nfunction getQueryParams (queryString = window.location.search) {\n\tconst result = {};\n\tconst properties = ['segmentid', 'cpccampaign'];\n\tconst searchParams = new URLSearchParams(queryString);\n\n\t// NOTE: undefined parameters will return null values so fallback to undefined\n\tproperties.forEach((property) => {\n\t\tconst value = searchParams.get(property);\n\n\t\tif (value) {\n\t\t\tresult[property] = value;\n\t\t}\n\t});\n\n\treturn result;\n}\n\nfunction getErrorPageParams (queryString = window.location.search) {\n\tconst searchParams = new URLSearchParams(queryString);\n\n\tconst errorStatus = searchParams.get('nextErrorStatus');\n\tconst errorReason = searchParams.get('nextErrorReason');\n\n\tif (errorStatus || errorReason) {\n\t\treturn {\n\t\t\terrorStatus,\n\t\t\terrorReason,\n\t\t\turl: window.parent.location.toString(),\n\t\t\treferrer: window.parent.document.referrer,\n\t\t};\n\t}\n}\n\nfunction transformListToObject (list) {\n\tconst result = {};\n\n\tlist.split(',').map(flag => {\n\t\tconst [name, value] = flag.split(':');\n\n\t\tif (name && value) {\n\t\t\tresult[name] = value;\n\t\t}\n\t});\n\n\treturn result;\n}\n\n// Map of property names received to property names specified by the data team\n// <https://sites.google.com/ft.com/ftproductanalytics/tracking-documents>\nconst dataPropertyMap = {\n\tappName: 'app',\n\tcontentId: 'rootContentId',\n\tcontentType: 'rootContentType',\n\tconceptId: 'rootConceptId',\n\tconceptType: 'rootConceptType',\n\tsegmentid: 'marketing_segment_id',\n\tcpccampaign: 'cpc_campaign',\n\tabTestState: 'active_ammit_flags'\n};\n\nfunction transformContextData (contextData) {\n\tconst result = {};\n\n\tObject.keys(contextData).forEach((key) => {\n\t\tlet value = contextData[key];\n\n\t\tif (key === 'abTestState') {\n\t\t\tvalue = transformListToObject(value);\n\t\t}\n\n\t\t// HACK: ensure content UUID and type match the audio tracking spec\n\t\t// <https://docs.google.com/spreadsheets/d/1YjXO0_3Xojact4sU24tIo_Nnv7e38zbRHWjwmOfHkb0/edit?usp=sharing>\n\t\tif (key === 'contentId') {\n\t\t\tresult.content = { ...result.content, uuid: value };\n\t\t}\n\n\t\tif (key === 'contentType') {\n\t\t\tresult.content = { ...result.content, asset_type: value };\n\t\t}\n\n\t\tresult[dataPropertyMap[key] || key] = value;\n\t});\n\n\treturn result;\n}\n\nfunction broadcast (name, data, bubbles = true) {\n\tconst rootEl = Element.prototype.isPrototypeOf(this) ? this : document.body;\n\n\t// This requires a polyfill for IE\n\t// <https://caniuse.com/#feat=customevent>\n\tconst event = new CustomEvent(name, {\n\t\tbubbles: bubbles,\n\t\tcancelable: true,\n\t\tdetail: data\n\t});\n\n\trootEl.dispatchEvent(event);\n}\n\nvar n={t:!1,i:!1,o:3e4},t=window,e=t.console,i=document,r=t.navigator,o=t.performance,u=function(){return r.deviceMemory},c=function(){return r.hardwareConcurrency},a=function(){return o&&!!o.getEntriesByType&&!!o.now&&!!o.mark},f=\"4g\",s=!1,l=function(){return !!(c()&&c()<=4)||!!(u()&&u()<=4)},m=function(n,t){switch(n){case\"slow-2g\":case\"2g\":case\"3g\":return !0;default:return l()||t}},v={u:!1},d=function(n){i.hidden&&(n(),v.u=i.hidden);},p=function(n){return parseFloat(n.toFixed(4))},g=function(n){return \"number\"!=typeof n?null:p(n/Math.pow(1024,2))},b=[2e3,4e3],h=[2500,4e3],T=[.1,.25],k={ttfb:[200,500],fp:b,fcp:b,lcp:h,lcpFinal:h,fid:[100,300],cls:T,clsFinal:T,tbt:[300,600],ntbt:[400,600]},y=function(n,t){return k[n]?t<=k[n][0]?\"good\":t<=k[n][1]?\"needsImprovement\":\"poor\":null},w=function(e,i,o){var a;a=function(){v.u&&e.indexOf(\"Final\")<0||!n.analyticsTracker||n.analyticsTracker({metricName:e,data:i,eventProperties:o||{},navigatorInformation:r?{deviceMemory:u()||0,hardwareConcurrency:c()||0,serviceWorkerStatus:\"serviceWorker\"in r?r.serviceWorker.controller?\"controlled\":\"supported\":\"unsupported\",isLowEndDevice:l(),isLowEndExperience:m(f,s)}:{},vitalsScore:y(e,i)});},\"requestIdleCallback\"in t?t.requestIdleCallback(a,{timeout:3e3}):a();},_=function(n,t,e){Object.keys(t).forEach((function(n){\"number\"==typeof t[n]&&(t[n]=p(t[n]));})),w(n,t,e);},F=function(t,e,i){var r=p(t);r<=n.o&&r>=0&&w(e,r,i);},E={},x={value:0},D={value:0},I={value:0},P={value:{beacon:0,css:0,fetch:0,img:0,other:0,script:0,total:0,xmlhttprequest:0}},j={value:0},q={value:0},C=function(n){var t=n.pop();t&&!t.s&&t.value&&(x.value+=t.value);},L={},O=function(n,t){try{var i=new PerformanceObserver((function(n){t(n.getEntries());}));return i.observe({type:n,buffered:!0}),i}catch(n){e.warn(\"Perfume.js:\",n);}return null},S=function(n){L[n]&&L[n].disconnect(),delete L[n];},W=function(n){var t=n.pop();t&&F(t.processingStart-t.startTime,\"fid\",{performanceEntry:t}),S(1),F(I.value,\"lcp\"),L[3]&&\"function\"==typeof L[3].takeRecords&&L[3].takeRecords(),F(x.value,\"cls\"),setTimeout((function(){F(j.value,\"tbt\"),_(\"dataConsumption\",P.value);}),1e4);},B=function(n){n.forEach((function(n){if(!(\"self\"!==n.name||n.startTime<D.value)){var t=n.duration-50;t>0&&(j.value+=t,q.value+=t);}}));},M=function(n){n.forEach((function(n){\"first-paint\"===n.name?F(n.startTime,\"fp\"):\"first-contentful-paint\"===n.name&&(D.value=n.startTime,F(D.value,\"fcp\"),L[4]=O(\"longtask\",B),S(0));}));},z=function(n){var t=n.pop();t&&(I.value=t.renderTime||t.loadTime);},H=function(n){n.forEach((function(n){n.identifier&&F(n.startTime,n.identifier);}));},N=function(t){t.forEach((function(t){if(n.t&&_(\"resourceTiming\",t),t.decodedBodySize&&t.initiatorType){var e=t.decodedBodySize/1e3;P.value[t.initiatorType]+=e,P.value.total+=e;}}));},R=function(){L[2]&&(F(I.value,\"lcpFinal\"),S(2)),L[3]&&(\"function\"==typeof L[3].takeRecords&&L[3].takeRecords(),F(x.value,\"clsFinal\"),S(3));},A=function(n){var t=\"usageDetails\"in n?n.usageDetails:{};_(\"storageEstimate\",{quota:g(n.quota),usage:g(n.usage),caches:g(t.caches),indexedDB:g(t.indexedDB),serviceWorker:g(t.serviceWorkerRegistrations)});},G=0,J=function(){function e(e){if(void 0===e&&(e={}),this.l=\"6.4.0\",n.analyticsTracker=e.analyticsTracker,n.t=!!e.resourceTiming,n.i=!!e.elementTiming,n.o=e.maxMeasureTime||n.o,a()){\"PerformanceObserver\"in t&&(L[0]=O(\"paint\",M),L[1]=O(\"first-input\",W),L[2]=O(\"largest-contentful-paint\",z),n.t&&O(\"resource\",N),L[3]=O(\"layout-shift\",C),n.i&&O(\"element\",H)),void 0!==i.hidden&&i.addEventListener(\"visibilitychange\",d.bind(this,R));var u=function(){if(!a())return {};var n=o.getEntriesByType(\"navigation\")[0];if(!n)return {};var t=n.responseStart,e=n.responseEnd;return {fetchTime:e-n.fetchStart,workerTime:n.workerStart>0?e-n.workerStart:0,totalTime:e-n.requestStart,downloadTime:e-t,timeToFirstByte:t-n.requestStart,headerSize:n.transferSize-n.encodedBodySize||0,dnsLookupTime:n.domainLookupEnd-n.domainLookupStart,redirectTime:n.redirectEnd-n.redirectStart}}();_(\"navigationTiming\",u),u.timeToFirstByte&&F(u.timeToFirstByte,\"ttfb\"),_(\"networkInformation\",function(){if(\"connection\"in r){var n=r.connection;return \"object\"!=typeof n?{}:(f=n.effectiveType,s=!!n.saveData,{downlink:n.downlink,effectiveType:n.effectiveType,rtt:n.rtt,saveData:!!n.saveData})}return {}}()),r&&r.storage&&\"function\"==typeof r.storage.estimate&&r.storage.estimate().then(A);}}return e.prototype.start=function(n){a()&&!E[n]&&(E[n]=!0,o.mark(\"mark_\"+n+\"_start\"),v.u=!1);},e.prototype.end=function(n,t,e){if(void 0===t&&(t={}),void 0===e&&(e=!0),a()&&E[n]){o.mark(\"mark_\"+n+\"_end\"),delete E[n];var i=function(n){o.measure(n,\"mark_\"+n+\"_start\",\"mark_\"+n+\"_end\");var t=o.getEntriesByName(n).pop();return t&&\"measure\"===t.entryType?t.duration:-1}(n);e&&_(n,p(i),t);}},e.prototype.endPaint=function(n,t){var e=this;setTimeout((function(){e.end(n,t);}));},e.prototype.clear=function(n){delete E[n],o.clearMarks&&(o.clearMarks(\"mark_\"+n+\"_start\"),o.clearMarks(\"mark_\"+n+\"_end\"));},e.prototype.markNTBT=function(){var n=this;this.start(\"ntbt\"),q.value=0,clearTimeout(G),G=setTimeout((function(){n.end(\"ntbt\",{},!1),F(q.value,\"ntbt\"),q.value=0;}),2e3);},e}();\n\nvar commonjsGlobal = typeof globalThis !== 'undefined' ? globalThis : typeof window !== 'undefined' ? window : typeof global !== 'undefined' ? global : typeof self !== 'undefined' ? self : {};\n\nfunction createCommonjsModule(fn, module) {\n\treturn module = { exports: {} }, fn(module, module.exports), module.exports;\n}\n\nvar seedRandom = createCommonjsModule(function (module) {\n\r\nvar width = 256;// each RC4 output is 0 <= x < 256\r\nvar chunks = 6;// at least six RC4 outputs for each double\r\nvar digits = 52;// there are 52 significant digits in a double\r\nvar pool = [];// pool: entropy pool starts empty\r\nvar GLOBAL = typeof commonjsGlobal === 'undefined' ? window : commonjsGlobal;\r\n\r\n//\r\n// The following constants are related to IEEE 754 limits.\r\n//\r\nvar startdenom = Math.pow(width, chunks),\r\n    significance = Math.pow(2, digits),\r\n    overflow = significance * 2,\r\n    mask = width - 1;\r\n\r\n\r\nvar oldRandom = Math.random;\r\n\r\n//\r\n// seedrandom()\r\n// This is the seedrandom function described above.\r\n//\r\nmodule.exports = function(seed, options) {\r\n  if (options && options.global === true) {\r\n    options.global = false;\r\n    Math.random = module.exports(seed, options);\r\n    options.global = true;\r\n    return Math.random;\r\n  }\r\n  var use_entropy = (options && options.entropy) || false;\r\n  var key = [];\r\n\r\n  // Flatten the seed string or build one from local entropy if needed.\r\n  var shortseed = mixkey(flatten(\r\n    use_entropy ? [seed, tostring(pool)] :\r\n    0 in arguments ? seed : autoseed(), 3), key);\r\n\r\n  // Use the seed to initialize an ARC4 generator.\r\n  var arc4 = new ARC4(key);\r\n\r\n  // Mix the randomness into accumulated entropy.\r\n  mixkey(tostring(arc4.S), pool);\r\n\r\n  // Override Math.random\r\n\r\n  // This function returns a random double in [0, 1) that contains\r\n  // randomness in every bit of the mantissa of the IEEE 754 value.\r\n\r\n  return function() {         // Closure to return a random double:\r\n    var n = arc4.g(chunks),             // Start with a numerator n < 2 ^ 48\r\n        d = startdenom,                 //   and denominator d = 2 ^ 48.\r\n        x = 0;                          //   and no 'extra last byte'.\r\n    while (n < significance) {          // Fill up all significant digits by\r\n      n = (n + x) * width;              //   shifting numerator and\r\n      d *= width;                       //   denominator and generating a\r\n      x = arc4.g(1);                    //   new least-significant-byte.\r\n    }\r\n    while (n >= overflow) {             // To avoid rounding up, before adding\r\n      n /= 2;                           //   last byte, shift everything\r\n      d /= 2;                           //   right using integer Math until\r\n      x >>>= 1;                         //   we have exactly the desired bits.\r\n    }\r\n    return (n + x) / d;                 // Form the number within [0, 1).\r\n  };\r\n};\r\n\r\nmodule.exports.resetGlobal = function () {\r\n  Math.random = oldRandom;\r\n};\r\n\r\n//\r\n// ARC4\r\n//\r\n// An ARC4 implementation.  The constructor takes a key in the form of\r\n// an array of at most (width) integers that should be 0 <= x < (width).\r\n//\r\n// The g(count) method returns a pseudorandom integer that concatenates\r\n// the next (count) outputs from ARC4.  Its return value is a number x\r\n// that is in the range 0 <= x < (width ^ count).\r\n//\r\n/** @constructor */\r\nfunction ARC4(key) {\r\n  var t, keylen = key.length,\r\n      me = this, i = 0, j = me.i = me.j = 0, s = me.S = [];\r\n\r\n  // The empty key [] is treated as [0].\r\n  if (!keylen) { key = [keylen++]; }\r\n\r\n  // Set up S using the standard key scheduling algorithm.\r\n  while (i < width) {\r\n    s[i] = i++;\r\n  }\r\n  for (i = 0; i < width; i++) {\r\n    s[i] = s[j = mask & (j + key[i % keylen] + (t = s[i]))];\r\n    s[j] = t;\r\n  }\r\n\r\n  // The \"g\" method returns the next (count) outputs as one number.\r\n  (me.g = function(count) {\r\n    // Using instance members instead of closure state nearly doubles speed.\r\n    var t, r = 0,\r\n        i = me.i, j = me.j, s = me.S;\r\n    while (count--) {\r\n      t = s[i = mask & (i + 1)];\r\n      r = r * width + s[mask & ((s[i] = s[j = mask & (j + t)]) + (s[j] = t))];\r\n    }\r\n    me.i = i; me.j = j;\r\n    return r;\r\n    // For robust unpredictability discard an initial batch of values.\r\n    // See http://www.rsa.com/rsalabs/node.asp?id=2009\r\n  })(width);\r\n}\r\n\r\n//\r\n// flatten()\r\n// Converts an object tree to nested arrays of strings.\r\n//\r\nfunction flatten(obj, depth) {\r\n  var result = [], typ = (typeof obj)[0], prop;\r\n  if (depth && typ == 'o') {\r\n    for (prop in obj) {\r\n      try { result.push(flatten(obj[prop], depth - 1)); } catch (e) {}\r\n    }\r\n  }\r\n  return (result.length ? result : typ == 's' ? obj : obj + '\\0');\r\n}\r\n\r\n//\r\n// mixkey()\r\n// Mixes a string seed into a key that is an array of integers, and\r\n// returns a shortened string seed that is equivalent to the result key.\r\n//\r\nfunction mixkey(seed, key) {\r\n  var stringseed = seed + '', smear, j = 0;\r\n  while (j < stringseed.length) {\r\n    key[mask & j] =\r\n      mask & ((smear ^= key[mask & j] * 19) + stringseed.charCodeAt(j++));\r\n  }\r\n  return tostring(key);\r\n}\r\n\r\n//\r\n// autoseed()\r\n// Returns an object for autoseeding, using window.crypto if available.\r\n//\r\n/** @param {Uint8Array=} seed */\r\nfunction autoseed(seed) {\r\n  try {\r\n    GLOBAL.crypto.getRandomValues(seed = new Uint8Array(width));\r\n    return tostring(seed);\r\n  } catch (e) {\r\n    return [+new Date, GLOBAL, GLOBAL.navigator && GLOBAL.navigator.plugins,\r\n            GLOBAL.screen, tostring(pool)];\r\n  }\r\n}\r\n\r\n//\r\n// tostring()\r\n// Converts an array of charcodes to a string\r\n//\r\nfunction tostring(a) {\r\n  return String.fromCharCode.apply(0, a);\r\n}\r\n\r\n//\r\n// When seedrandom.js is loaded, we immediately mix a few bits\r\n// from the built-in RNG into the entropy pool.  Because we do\r\n// not want to intefere with determinstic PRNG state later,\r\n// seedrandom will not call Math.random on its own again after\r\n// initialization.\r\n//\r\nmixkey(Math.random(), pool);\n});\nvar seedRandom_1 = seedRandom.resetGlobal;\n\nfunction seedIsInSample (seed, percent) {\n\tconst randomNumberGenerator = seedRandom(seed);\n\tconst pseudoRandomNumber = randomNumberGenerator();\n\n\treturn Math.round(pseudoRandomNumber * 100) <= percent;\n}\n\nconst getSpoorId = () => getCookie('spoor-id');\n\n// @see \"Important metrics to measure\" https://web.dev/metrics\nconst requiredMetrics = [\n\t'domInteractive',\n\t'domComplete',\n\t'timeToFirstByte',\n\t'firstPaint',\n\t'largestContentfulPaint',\n\t'firstInputDelay',\n\t'cumulativeLayoutShift',\n\t'firstContentfulPaint',\n\t'totalBlockingTime'\n];\n\nconst defaultSampleRate = 10;\n\nconst isContextComplete = (context) => {\n\treturn requiredMetrics.every((metric) => typeof context[metric] === 'number');\n};\n\nconst realUserMonitoringForPerformance = ({ sampleRate } = {}) => {\n\n\t// Check browser support.\n\t// @see https://developer.mozilla.org/en-US/docs/Web/API/PerformanceLongTaskTiming\n\tif (!'PerformanceLongTaskTiming' in window) return;\n\n\tconst spoorId = getSpoorId();\n\n\tsampleRate = Number.isFinite(sampleRate) && sampleRate <= 100 && sampleRate >= 0 ? sampleRate : defaultSampleRate;\n\n\t// Gather metrics for only a cohort of users.\n\tif (!seedIsInSample(spoorId, sampleRate)) return;\n\n\t// Proceed only if the page load event is a \"navigate\".\n\t// @see: https://developer.mozilla.org/en-US/docs/Web/API/PerformanceNavigationTiming/type\n\t// When testing, you will need to open a new browser window and paste the URL in i.e. simply reloading the page will not work.\n\tconst navigation = performance.getEntriesByType('navigation') && performance.getEntriesByType('navigation')[0];\n\tif (!navigation || navigation.type !== 'navigate') return;\n\n\tconst context = {};\n\n\treadyState.complete.then(() => {\n\t\t// <https://developer.mozilla.org/en-US/docs/Web/API/PerformanceNavigationTiming/domInteractive>\n\t\tcontext.domInteractive = Math.round(navigation.domInteractive);\n\t\t// <https://developer.mozilla.org/en-US/docs/Web/API/PerformanceNavigationTiming/domComplete>\n\t\tcontext.domComplete = Math.round(navigation.domComplete);\n\t});\n\n\t/**\n\t * analyticsTracker()\n\t *\n\t * This function is called every time one of the performance events occurs.\n\t * The \"final\" event should be `firstInputDelay`, which is triggered by any \"input\" event (most likely to be a click.)\n\t * Once all the metrics are present, it fires a broadcast() to the Spoor API.\n\t */\n\tlet hasAlreadyBroadcast = false;\n\n\tconst analyticsTracker = (({ metricName, data}) => {\n\t\tif (hasAlreadyBroadcast) return;\n\n\t\tif (metricName === 'fid') {\n\t\t\tcontext.firstInputDelay = Math.round(data);\n\t\t} else if (metricName === 'lcp') {\n\t\t\t//This fires twice, we are collecting the 'first firing' - see PR notes for more context https://github.com/Financial-Times/n-tracking/pull/86\n\t\t\tcontext.largestContentfulPaint = Math.round(data);\n\t\t} else if (metricName === 'ttfb') {\n\t\t\tcontext.timeToFirstByte = Math.round(data);\n\t\t} else if (metricName === 'fp') {\n\t\t\tcontext.firstPaint = Math.round(data);\n\t\t} else if (metricName === 'fcp'){\n\t\t\tcontext.firstContentfulPaint = Math.round(data);\n\t\t} else if (metricName === 'cls') {\n\t\t\tcontext.cumulativeLayoutShift = data;\n\t\t} else if (metricName === 'tbt') {\n\t\t\tcontext.totalBlockingTime = Math.round(data);\n\t\t}\n\n\t\tcontext.url = window.document.location.href || null;\n\n\t\tif (isContextComplete(context)) {\n\t\t\tconsole.log({ performanceMetrics: context }); // eslint-disable-line no-console\n\n\t\t\tbroadcast('oTracking.event', {\n\t\t\t\taction: 'performance',\n\t\t\t\tcategory: 'page',\n\t\t\t\t...context\n\t\t\t});\n\n\t\t\thasAlreadyBroadcast = true;\n\t\t}\n\t});\n\n\tnew J({\n\t\tanalyticsTracker,\n\t\tlogging: false\n\t});\n};\n\n// Create markers at each of these percentage points\nconst DEPTH_MARKERS = [25, 50, 75, 100];\n\nconst defaultOptions = {\n\tonScroll: () => {},\n\ttarget: 'body',\n\tdebug: false\n};\n\nclass ScrollDepth {\n\tconstructor (options) {\n\t\tthis.options = { ...defaultOptions, ...options };\n\n\t\tthis.init();\n\t}\n\n\tinit () {\n\t\tconst target = document.querySelector(this.options.target);\n\n\t\tif (target && 'IntersectionObserver' in window) {\n\t\t\tthis.observer = new IntersectionObserver(this.handleIntersection.bind(this));\n\n\t\t\ttarget.style.position = 'relative';\n\n\t\t\tDEPTH_MARKERS.forEach((percentage) => {\n\t\t\t\tconst marker = document.createElement('div');\n\t\t\t\tmarker.className = 'n-tracking-scroll-depth-marker';\n\t\t\t\tmarker.style.position = 'absolute';\n\t\t\t\tmarker.style.top = `${percentage}%`;\n\t\t\t\tmarker.style.bottom = '0';\n\t\t\t\tmarker.style.width = '100%';\n\t\t\t\tmarker.style.zIndex = '-1';\n\t\t\t\tmarker.setAttribute('data-scroll-depth', percentage);\n\n\t\t\t\ttarget.appendChild(marker);\n\n\t\t\t\tthis.observer.observe(marker);\n\t\t\t});\n\t\t}\n\t}\n\n\thandleIntersection (changes) {\n\t\tchanges.forEach((change) => {\n\t\t\tif (change.isIntersecting || change.intersectionRatio > 0) {\n\t\t\t\tconst marker = change.target;\n\t\t\t\tconst scrollDepth = marker.getAttribute('data-scroll-depth');\n\n\t\t\t\tthis.options.onScroll(scrollDepth);\n\n\t\t\t\tif (this.options.debug) {\n\t\t\t\t\tconsole.log('ScrollDepth', { marker: scrollDepth }); // eslint-disable-line no-console\n\t\t\t\t}\n\n\t\t\t\tif (marker.parentNode) {\n\t\t\t\t\tmarker.parentNode.removeChild(marker);\n\t\t\t\t}\n\n\t\t\t\tthis.observer.unobserve(marker);\n\t\t\t}\n\t\t});\n\t};\n}\n\n// Automatically stop the attention timer after this time\nconst ATTENTION_INTERVAL = 15000;\n\n// These events re/start the attention timer\nconst ATTENTION_EVENTS = [\n\t'load',\n\t'click',\n\t'focus',\n\t'scroll',\n\t'mousemove',\n\t'touchstart',\n\t'touchend',\n\t'touchcancel',\n\t'touchleave'\n];\n\n// These events pause the attention timer\nconst ATTENTION_LOST_EVENTS = ['blur'];\n\n// These events will trigger the exit callback\nconst PAGE_EXIT_EVENTS = ['beforeunload', 'unload', 'pagehide'];\n\nconst defaultOptions$1 = {\n\tonExit: () => {},\n\tdebug: false\n};\n\nclass AttentionTime {\n\tconstructor (options) {\n\t\tthis.options = { ...defaultOptions$1, ...options };\n\n\t\tthis.totalAttentionTime = 0;\n\t\tthis.hasExited = false;\n\n\t\tthis.init();\n\t}\n\n\tinit () {\n\t\tATTENTION_EVENTS.forEach((event) => {\n\t\t\twindow.addEventListener(event, this.startAttention.bind(this));\n\t\t});\n\n\t\tATTENTION_LOST_EVENTS.forEach((event) => {\n\t\t\twindow.addEventListener(event, this.endAttention.bind(this));\n\t\t});\n\n\t\tPAGE_EXIT_EVENTS.forEach((event) => {\n\t\t\twindow.addEventListener(event, this.handleExit.bind(this));\n\t\t});\n\n\t\tdocument.addEventListener('visibilitychange', this.handleVisibilityChange.bind(this));\n\n\t\tconst videoPlayers = document.querySelectorAll('video');\n\n\t\tvideoPlayers.forEach((element) => {\n\t\t\telement.addEventListener('playing', this.startConstantAttention.bind(this));\n\n\t\t\telement.addEventListener('pause', this.endConstantAttention.bind(this));\n\n\t\t\telement.addEventListener('ended', this.endConstantAttention.bind(this));\n\t\t});\n\t}\n\n\tstartAttention (event) {\n\t\tclearTimeout(this.attentionTimeout);\n\n\t\tif (!this.startAttentionTime) {\n\t\t\tthis.startAttentionTime = Date.now();\n\t\t}\n\n\t\tthis.attentionTimeout = setTimeout(\n\t\t\tthis.endAttention.bind(this, { type: 'timeout' }),\n\t\t\tATTENTION_INTERVAL\n\t\t);\n\n\t\tif (this.options.debug) {\n\t\t\tconsole.log('AttentionTime start', { event: event.type }); // eslint-disable-line no-console\n\t\t}\n\t}\n\n\tendAttention (event) {\n\t\tif (this.startAttentionTime) {\n\t\t\tclearTimeout(this.attentionTimeout);\n\n\t\t\tthis.totalAttentionTime = this.getAttentionTime();\n\t\t\tthis.startAttentionTime = null;\n\t\t}\n\n\t\tif (this.options.debug) {\n\t\t\tconsole.log('AttentionTime end', { event: event.type, time: this.totalAttentionTime }); // eslint-disable-line no-console\n\t\t}\n\t}\n\n\tstartConstantAttention () {\n\t\tthis.constantAttentionInterval = setInterval(\n\t\t\tthis.startAttention.bind(this),\n\t\t\tATTENTION_INTERVAL\n\t\t);\n\t}\n\n\tendConstantAttention (event) {\n\t\tthis.endAttention(event);\n\t\tclearInterval(this.constantAttentionInterval);\n\t}\n\n\tgetAttentionTime () {\n\t\tlet currentAttentionTime = 0;\n\n\t\tif (this.startAttentionTime) {\n\t\t\tcurrentAttentionTime = Math.round(\n\t\t\t\t(Date.now() - this.startAttentionTime) / 1000\n\t\t\t);\n\t\t}\n\n\t\treturn this.totalAttentionTime + currentAttentionTime;\n\t}\n\n\thandleVisibilityChange (event) {\n\t\tif (document.visibilityState === 'hidden') {\n\t\t\tthis.endAttention(event);\n\t\t} else {\n\t\t\tthis.startAttention(event);\n\t\t}\n\t}\n\n\thandleExit (event) {\n\t\tif (this.hasExited) {\n\t\t\treturn;\n\t\t}\n\n\t\tthis.endAttention(event);\n\n\t\tif (this.options.debug) {\n\t\t\tconsole.log('AttentionTime', { event: event.type, time: this.totalAttentionTime }); // eslint-disable-line no-console\n\t\t}\n\n\t\tthis.options.onExit(this.totalAttentionTime);\n\n\t\tthis.hasExited = true;\n\t}\n}\n\n// TODO: The tracking event data for the `page:interaction` and `page:scrolldepth`\n// events is needlessly different. We should work with the data team to align it.\nconst pageAttention = (options = {}) => {\n\tconst onExit = (attentionTime) => {\n\t\tbroadcast('oTracking.event', {\n\t\t\tcategory: 'page',\n\t\t\taction: 'interaction',\n\t\t\tcontext: {\n\t\t\t\tattention: {\n\t\t\t\t\ttotal: attentionTime\n\t\t\t\t}\n\t\t\t}\n\t\t});\n\t};\n\n\tconst attention = new AttentionTime({ ...options, onExit });\n\n\tconst onScroll = (scrollDepth) => {\n\t\tbroadcast('oTracking.event', {\n\t\t\tcategory: 'page',\n\t\t\taction: 'scrolldepth',\n\t\t\tmeta: {\n\t\t\t\tpercentagesViewed: scrollDepth,\n\t\t\t\tattention: attention.getAttentionTime()\n\t\t\t}\n\t\t});\n\t};\n\n\tnew ScrollDepth({ ...options, onScroll });\n};\n\nconst MAX_LENGTH = 100;\n\nconst TRUNCATED_TEXT = ' … ';\n\nvar getTextExcerpt = (text) => {\n\tif (text.length > MAX_LENGTH) {\n\t\tconst newLength = MAX_LENGTH - TRUNCATED_TEXT.length;\n\t\tconst left = Math.floor(newLength / 2);\n\t\tconst right = Math.ceil(newLength / 2);\n\n\t\treturn text.substr(0, left) + TRUNCATED_TEXT + text.substr(right * -1);\n\t} else {\n\t\treturn text;\n\t}\n};\n\nconst textCopying = () => {\n\tdocument.addEventListener('copy', (event) => {\n\t\tconst context = {\n\t\t\tnodeName: event.target.nodeName.toLowerCase()\n\t\t};\n\n\t\tif (window.getSelection) {\n\t\t\tconst selection = window.getSelection().toString().trim();\n\n\t\t\tcontext.characters = selection.length;\n\t\t\tcontext.words = selection.split(/\\s+/).length;\n\t\t\tcontext.selection = getTextExcerpt(selection);\n\t\t}\n\n\t\tbroadcast('oTracking.event', {\n\t\t\taction: 'copy',\n\t\t\tcategory: 'text',\n\t\t\tcontext\n\t\t});\n\t});\n};\n\n\n\nvar index = /*#__PURE__*/Object.freeze({\n\t__proto__: null,\n\trealUserMonitoringForPerformance: realUserMonitoringForPerformance,\n\tpageAttention: pageAttention,\n\ttextCopying: textCopying\n});\n\nconst SPOOR_API_INGEST_URL = 'https://spoor-api.ft.com/ingest';\n\nfunction init ({ appContext, extraContext, pageViewContext }) {\n\tconst queryParams = getQueryParams();\n\n\tconst options = {\n\t\tserver: SPOOR_API_INGEST_URL,\n\t\t// This data will be appended to _all_ events captured by o-tracking\n\t\tcontext: transformContextData({\n\t\t\t...queryParams,\n\t\t\t...appContext,\n\t\t\t...extraContext\n\t\t}),\n\t\tuser: getUserData(),\n\t\t// Using the Beacon API ensures that no tracking event data is lost\n\t\t// when the document is being unloaded, which happens when navigating\n\t\t// to a different page.\n\t\tuseSendBeacon: true\n\t};\n\n\toTracking.init(options);\n\n\t// Automatically trigger the page view event unless we're in an iframe\n\tif (window === window.top || window.location.hostname === 'errors-next.ft.com') {\n\t\tconst errorPageParams = getErrorPageParams();\n\n\t\toTracking.page({\n\t\t\t...errorPageParams,\n\t\t\t...pageViewContext,\n\t\t});\n\t}\n\n\t//  Initialise click event tracking for interactive elements\n\toTracking.click.init('cta');\n\n\treturn oTracking;\n}\n\nexport { SPOOR_API_INGEST_URL, broadcast, init, index as trackers };\n","\"use strict\";\n\nObject.defineProperty(exports, \"__esModule\", {\n  value: true\n});\nexports.getCurrentLayout = getCurrentLayout;\nexports.getCurrentGutter = getCurrentGutter;\nexports.getGridBreakpoints = getGridBreakpoints;\nexports.enableLayoutChangeEvents = enableLayoutChangeEvents;\nexports.default = void 0;\nvar missingDataMessage = 'Could not find layout information. ' + 'You may need to include o-grid css. See the README (https://registry.origami.ft.com/components/o-grid/readme) ' + 'for more information.';\n/**\n * Grab grid properties\n * @return {Object} layout names and gutter widths\n */\n\nfunction getGridProperties() {\n  var properties = getGridFromDoc('after');\n\n  if (Object.keys(properties).length === 0) {\n    console.warn(missingDataMessage);\n  }\n\n  return properties;\n}\n/**\n * Get all layout sizes.\n * CSS must be included so JavaScript can retrieve layout information.\n * See the README for more information.\n * @return {Object} layout names and sizes\n */\n\n\nfunction getGridBreakpoints() {\n  var breakpoints = getGridFromDoc('before');\n\n  if (Object.keys(breakpoints).length === 0) {\n    console.warn(missingDataMessage);\n  }\n\n  return breakpoints;\n}\n/**\n * Grab grid properties surfaced in html:after and html:before's content\n * @param {String} position Whether to get all properties in :before, or current properties in :after\n * @return {Object} layout names and gutter widths\n */\n\n\nfunction getGridFromDoc(position) {\n  // Contained in a try/catch as it should not error if o-grid styles are not (deliberately or accidentally) loaded\n  // e.g. o-tracking will always try to read this property, but the page is not obliged to use o-grid for layout\n  try {\n    var gridProperties = window.getComputedStyle(document.documentElement, ':' + position).getPropertyValue('content'); // Firefox computes: \"{\\\"foo\\\": \\\"bar\\\"}\"\n    // We want readable JSON: {\"foo\": \"bar\"}\n\n    gridProperties = gridProperties.replace(/'/g, '').replace(/\\\\/g, '').replace(/^\"/, '').replace(/\"$/, '');\n    return JSON.parse(gridProperties);\n  } catch (e) {\n    return {};\n  }\n}\n/**\n * Grab the current layout.\n * CSS must be included so JavaScript can retrieve layout information.\n * See the README for more information.\n * @return {String} Layout name\n */\n\n\nfunction getCurrentLayout() {\n  return getGridProperties().layout;\n}\n/**\n * Grab the current space between columns.\n * CSS must be included so JavaScript can retrieve layout information.\n * See the README for more information.\n * @return {String} Gutter width in pixels\n */\n\n\nfunction getCurrentGutter() {\n  return getGridProperties().gutter;\n}\n/**\n * This sets MediaQueryListeners on all the o-grid breakpoints\n * and fires a `o-grid.layoutChange` event on layout change.\n * CSS must be included so JavaScript can retrieve layout information.\n * See the README for more information.\n */\n\n\nfunction enableLayoutChangeEvents() {\n  // Create a map containing all breakpoints exposed via html:before\n  var gridLayouts = getGridBreakpoints();\n\n  if (gridLayouts.hasOwnProperty('layouts')) {\n    var layouts = gridLayouts.layouts;\n    var breakpoints = [...Object.entries(layouts), ['default', '240px']].sort((a, b) => parseFloat(a[1]) - parseFloat(b[1]));\n\n    var setupQuery = (query, size) => {\n      // matchMedia listener handler: Dispatch `o-grid.layoutChange` event if a match\n      var handleMQChange = mql => {\n        if (mql.matches) {\n          window.dispatchEvent(new CustomEvent('o-grid.layoutChange', {\n            detail: {\n              layout: size\n            }\n          }));\n        }\n      };\n\n      var mql = window.matchMedia(query);\n      mql.addListener(handleMQChange);\n      handleMQChange(mql);\n    }; // Generate media queries for each\n\n\n    var decr1 = val => \"\".concat(Number(val.replace('px', '') - 1), \"px\");\n\n    for (var index = 0; index < breakpoints.length; index++) {\n      var [layoutName, layoutWidth] = breakpoints[index];\n      var isLast = index === breakpoints.length - 1;\n\n      if (isLast) {\n        setupQuery(\"(min-width: \".concat(layoutWidth, \")\"), layoutName);\n        continue;\n      }\n\n      var [, nextLayoutWidth] = breakpoints[index + 1];\n      setupQuery(\"(min-width: \".concat(layoutWidth, \") and (max-width: \").concat(decr1(nextLayoutWidth), \")\"), layoutName);\n    }\n  } else {\n    console.error('Could not enable grid layout change events. Include o-grid css. See the README (https://registry.origami.ft.com/components/o-grid/readme) for more details.');\n  }\n}\n\nvar _default = {\n  getCurrentLayout,\n  getCurrentGutter,\n  getGridBreakpoints,\n  enableLayoutChangeEvents\n};\nexports.default = _default;","\"use strict\";\n\nObject.defineProperty(exports, \"__esModule\", {\n  value: true\n});\nexports.default = void 0;\n\nvar _utils = _interopRequireDefault(require(\"./dist/utils.js\"));\n\nfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }\n\nvar throttle = _utils.default.throttle;\nvar debounce = _utils.default.debounce;\nvar listeners = {};\nvar intervals = {\n  resize: 100,\n  orientation: 100,\n  visibility: 100,\n  scroll: 100\n};\n/**\n *\n * @param {string} eventType - The type of event to throttle for this duration.\n * @param {number} interval - The duration to throttle in ms.\n * @example\n * \t   // throttle for different events at different durations\n *     setThrottleInterval('scroll', 100)\n *     setThrottleInterval('resize', 300)\n *     setThrottleInterval('orientation', 30)\n *     setThrottleInterval('visibility', 30)\n * \t\t// throttle all events at 30ms\n *     setThrottleInterval(30);\n */\n\nfunction setThrottleInterval(eventType, interval) {\n  if (typeof arguments[0] === 'number') {\n    setThrottleInterval('scroll', arguments[0]);\n    setThrottleInterval('resize', arguments[1]);\n    setThrottleInterval('orientation', arguments[2]);\n    setThrottleInterval('visibility', arguments[3]);\n  } else if (interval) {\n    intervals[eventType] = interval;\n  }\n}\n/**\n * @access private\n */\n\n\nfunction listenToResize() {\n  if (listeners.resize) {\n    return;\n  }\n\n  var eventType = 'resize';\n  var handler = debounce(function (ev) {\n    _utils.default.broadcast('resize', {\n      viewport: _utils.default.getSize(),\n      originalEvent: ev\n    });\n  }, intervals.resize);\n  window.addEventListener(eventType, handler);\n  listeners.resize = {\n    eventType: eventType,\n    handler: handler\n  };\n}\n/**\n * @access private\n */\n\n\nfunction listenToOrientation() {\n  if (listeners.orientation) {\n    return;\n  }\n\n  var eventType = 'orientationchange';\n  var handler = debounce(function (ev) {\n    _utils.default.broadcast('orientation', {\n      viewport: _utils.default.getSize(),\n      orientation: _utils.default.getOrientation(),\n      originalEvent: ev\n    });\n  }, intervals.orientation);\n  window.addEventListener(eventType, handler);\n  listeners.orientation = {\n    eventType: eventType,\n    handler: handler\n  };\n}\n/**\n * @access private\n */\n\n\nfunction listenToVisibility() {\n  if (listeners.visibility) {\n    return;\n  }\n\n  var eventType = 'visibilitychange';\n  var handler = debounce(function (ev) {\n    _utils.default.broadcast('visibility', {\n      hidden: _utils.default.getVisibility(),\n      originalEvent: ev\n    });\n  }, intervals.visibility);\n  window.addEventListener(eventType, handler);\n  listeners.visibility = {\n    eventType: eventType,\n    handler: handler\n  };\n}\n/**\n * @access private\n */\n\n\nfunction listenToScroll() {\n  if (listeners.scroll) {\n    return;\n  }\n\n  var eventType = 'scroll';\n  var handler = throttle(function (ev) {\n    var scrollPos = _utils.default.getScrollPosition();\n\n    _utils.default.broadcast('scroll', {\n      viewport: _utils.default.getSize(),\n      scrollHeight: scrollPos.height,\n      scrollLeft: scrollPos.left,\n      scrollTop: scrollPos.top,\n      scrollWidth: scrollPos.width,\n      originalEvent: ev\n    });\n  }, intervals.scroll);\n  window.addEventListener(eventType, handler);\n  listeners.scroll = {\n    eventType: eventType,\n    handler: handler\n  };\n}\n/**\n * Start listening for an event(s).\n * @param {string} eventType - The event to start listening for. One of `resize`, `scroll`, `orientation`, `visibility` or `all`.\n * @example\n * \t\t// Start listening for all events.\n * \t\toViewport.listenTo('all');\n *\n * \t\t// It is now possible to listen for debounce o-viewport events such as `oViewport.orientation`.\n *      document.body.addEventListener('oViewport.orientation', function(event) {\n *      \tconsole.log(event.type); // oViewport.orientation\n *      });\n */\n\n\nfunction listenTo(eventType) {\n  if (eventType === 'resize' || eventType === 'all') {\n    listenToResize();\n  }\n\n  if (eventType === 'scroll' || eventType === 'all') {\n    listenToScroll();\n  }\n\n  if (eventType === 'orientation' || eventType === 'all') {\n    listenToOrientation();\n  }\n\n  if (eventType === 'visibility' || eventType === 'all') {\n    listenToVisibility();\n  }\n}\n/**\n * Stop listening for an event(s).\n * @param {string} eventType - The event to stop listening for. One of `resize`, `scroll`, `orientation`, `visibility` or `all`.\n * @example\n * \t\t// Start listening for all events.\n * \t\toViewport.listenTo('all');\n * \t\t// We're done. Stop listening for all events.\n * \t\toViewport.stopListeningTo('all');\n */\n\n\nfunction stopListeningTo(eventType) {\n  if (eventType === 'all') {\n    Object.keys(listeners).forEach(stopListeningTo);\n  } else if (listeners[eventType]) {\n    window.removeEventListener(listeners[eventType].eventType, listeners[eventType].handler);\n    delete listeners[eventType];\n  }\n}\n\nvar _default = {\n  debug: function debug() {\n    _utils.default.debug();\n  },\n  listenTo,\n  stopListeningTo,\n  setThrottleInterval,\n  getOrientation: _utils.default.getOrientation,\n  getSize: _utils.default.getSize,\n  getScrollPosition: _utils.default.getScrollPosition,\n  getVisibility: _utils.default.getVisibility\n};\nexports.default = _default;\nmodule.exports = exports.default;","\"use strict\";\n\nObject.defineProperty(exports, \"__esModule\", {\n  value: true\n});\nexports.default = void 0;\n\nvar Utils = _interopRequireWildcard(require(\"@financial-times/o-utils\"));\n\nfunction _getRequireWildcardCache() { if (typeof WeakMap !== \"function\") return null; var cache = new WeakMap(); _getRequireWildcardCache = function _getRequireWildcardCache() { return cache; }; return cache; }\n\nfunction _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== \"object\" && typeof obj !== \"function\") { return { default: obj }; } var cache = _getRequireWildcardCache(); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; }\n\nvar _debug;\n/**\n *\n * @param {string} eventType\n * @param {object} data\n * @param {EventTarget} target\n */\n\n\nfunction broadcast(eventType, data, target) {\n  target = target || document.body;\n\n  if (_debug) {\n    console.log('o-viewport', eventType, data);\n  }\n\n  target.dispatchEvent(new CustomEvent('oViewport.' + eventType, {\n    detail: data,\n    bubbles: true\n  }));\n}\n/**\n* Get the viewport height.\n* @param {boolean} ignoreScrollbars [false] - set to true to discount scrollbar height.\n* @return {number}\n*/\n\n\nfunction getHeight(ignoreScrollbars) {\n  return ignoreScrollbars ? document.documentElement.clientHeight : Math.max(document.documentElement.clientHeight, window.innerHeight || 0);\n}\n/**\n* Get the viewport width.\n* @param {boolean} ignoreScrollbars [false] - set to true to discount scrollbar width\n* @return {number}\n*/\n\n\nfunction getWidth(ignoreScrollbars) {\n  return ignoreScrollbars ? document.documentElement.clientWidth : Math.max(document.documentElement.clientWidth, window.innerWidth || 0);\n}\n/**\n * Viewport size.\n * @typedef {Object} Size\n * @property {number} height\n * @property {number} width\n */\n\n/**\n* Get the viewport width and height.\n* @param {boolean} ignoreScrollbars [false] - set to true to discount scrollbar width/height.\n* @return {Size}\n*/\n\n\nfunction getSize(ignoreScrollbars) {\n  return {\n    height: getHeight(ignoreScrollbars),\n    width: getWidth(ignoreScrollbars)\n  };\n}\n/**\n * Scroll position.\n * @typedef {Object} ScrollPosition\n * @property {number} height - `document.body.scrollHeight`\n * @property {number} width - `document.body.scrollWidth`\n * @property {number} left - `window.pageXOffset || window.scrollX`\n * @property {number} top - `window.pageYOffset || window.scrollY`\n */\n\n/**\n * @return {ScrollPosition}\n */\n\n\nfunction getScrollPosition() {\n  return {\n    height: document.body.scrollHeight,\n    width: document.body.scrollWidth,\n    left: window.pageXOffset || window.scrollX,\n    top: window.pageYOffset || window.scrollY\n  };\n}\n/**\n * @return {string} - 'portrait' or 'landscape'\n */\n\n\nfunction getOrientation() {\n  var orientation = window.screen.orientation;\n\n  if (orientation) {\n    return typeof orientation === 'string' ? orientation.split('-')[0] : orientation.type.split('-')[0];\n  } else if (window.matchMedia) {\n    return window.matchMedia('(orientation: portrait)').matches ? 'portrait' : 'landscape';\n  } else {\n    return getHeight() >= getWidth() ? 'portrait' : 'landscape';\n  }\n}\n/**\n * @return {boolean} - true if the viewport is visible\n */\n\n\nfunction getVisibility() {\n  return document.hidden;\n}\n\nvar _default = {\n  debug: function debug() {\n    _debug = true;\n  },\n  broadcast,\n  getWidth,\n  getHeight,\n  getSize,\n  getScrollPosition,\n  getVisibility,\n  getOrientation,\n  debounce: Utils.debounce,\n  throttle: Utils.throttle\n};\nexports.default = _default;\nmodule.exports = exports.default;","\"use strict\";\n\nObject.defineProperty(exports, \"__esModule\", {\n  value: true\n});\nexports.debounce = debounce;\nexports.throttle = throttle;\n\n/**\n*\n* Debounces function so it is only called after n milliseconds\n* without it not being called\n*\n* @example\n* Utils.debounce(myFunction() {}, 100);\n*\n* @param {Function} func - Function to be debounced\n* @param {number} wait - Time in miliseconds\n*\n* @returns {Function} - Debounced function\n*/\nfunction debounce(func, wait) {\n  var timeout;\n  return function () {\n    var args = arguments;\n\n    var later = () => {\n      timeout = null;\n      func.apply(this, args);\n    };\n\n    clearTimeout(timeout);\n    timeout = setTimeout(later, wait);\n  };\n}\n/**\n*\n* Throttle function so it is only called once every n milliseconds\n*\n* @example\n* Utils.throttle(myFunction() {}, 100);\n*\n* @param {Function} func - Function to be throttled\n* @param {number} wait - Time in miliseconds\n*\n* @returns {Function} - Throttled function\n*/\n\n\nfunction throttle(func, wait) {\n  var timeout;\n  return function () {\n    if (timeout) {\n      return;\n    }\n\n    var args = arguments;\n\n    var later = () => {\n      timeout = null;\n      func.apply(this, args);\n    };\n\n    timeout = setTimeout(later, wait);\n  };\n}","var e={capture:!0,once:!0,passive:!0},t=function(){return\"interactive\"===document.readyState||\"complete\"===document.readyState},n=function(e,n){return!(!function(e){return document.readyState===e}(e)&&!t())&&(n(e),!0)},r=function(){return new Promise(function(t){n(\"loading\",t)||document.addEventListener(\"readystatechange\",function(){\"loading\"===document.readyState&&t(\"loading\")},e)})},o=function(){return new Promise(function(t){n(\"interactive\",t)||document.addEventListener(\"readystatechange\",function(){\"interactive\"===document.readyState&&t(\"interactive\")},e)})},u=function(){return new Promise(function(t){n(\"complete\",t)||document.addEventListener(\"readystatechange\",function(){\"complete\"===document.readyState&&t(\"complete\")},e)})},i=function(){return new Promise(function(t){n(\"domready\",t)||document.addEventListener(\"DOMContentLoaded\",function(){t(\"domready\")},e)})},c=function(){return new Promise(function(t){n(\"load\",t)||window.addEventListener(\"load\",function(){t(\"load\")},e)})},d={};Object.defineProperties(d,{state:{get:function(){return document.readyState}},loading:{get:function(){return r()}},interactive:{get:function(){return o()}},complete:{get:function(){return u()}},window:{get:function(){return c()}},load:{get:function(){return c()}},domready:{get:function(){return i()}},dom:{get:function(){return i()}},ready:{get:function(){return t()}}});export default d;export{r as loading,o as interactive,u as complete,i as domready,c as load};\n//# sourceMappingURL=ready-state.es.js.map\n","import core from '../core.js';\nimport {\n\tis,\n\tbroadcast,\n\tmerge,\n\taddEvent} from '../utils.js';\n\n/**\n * Default properties for events.\n *\n * @type {object}\n * @returns {object} - Default configuration for events\n */\nconst defaultEventConfig = function () {\n\treturn {\n\t\tcategory: 'event',\n\t\taction: 'generic',\n\t\tcontext: {}\n\t};\n};\n\n/**\n * Track an event.\n *\n * @param {object} trackingEvent - The event, which could the following properties in its 'detail' key:\n * @param {object} [trackingEvent.detail] - Custom properties to add to the event.\n * @param {string} [trackingEvent.detail.category] - Category for this event e.g. page\n * @param {string} [trackingEvent.detail.action] - Action for this event e.g. view\n * @param {string} [trackingEvent.detail.component_id] - The ID for the component instance.\n * @param {object} [trackingEvent.detail.context] - Extra context to add to the event\n *\n * @param {Function} [callback] - Optional, Callback function. Called when request completed.\n * @returns {void}\n */\nfunction event(trackingEvent, callback) {\n\tif (is(trackingEvent.detail.category) || is(trackingEvent.detail.action)) {\n\t\tconst noCategoryActionVals = 'Missing category or action values';\n\t\tbroadcast('oErrors', 'log', {\n\t\t\terror: noCategoryActionVals,\n\t\t\tinfo: { module: 'o-tracking' }\n\t\t});\n\t\tthrow noCategoryActionVals;\n\t}\n\n\tconst config = merge(defaultEventConfig(), {\n\t\tcategory: trackingEvent.detail.category,\n\t\taction: trackingEvent.detail.action,\n\t\tcontext: trackingEvent.detail\n\t});\n\n\tdelete config.context.category;\n\tdelete config.context.action;\n\n\tconst origamiElement = getOrigamiEventTarget(trackingEvent);\n\tif (origamiElement) {\n\t\tconfig.context.component_name = origamiElement.getAttribute('data-o-component');\n\t\tconfig.context.component_id = config.context.component_id || getComponentId(origamiElement);\n\t}\n\n\tcore.track(config, callback);\n}\n\n/**\n * Helper function that gets the target of an event if it's an Origami component\n *\n * @param  {Event} event - The event triggered.\n * @returns {HTMLElement|undefined} - Returns the HTML element if an Origami component, else undefined.\n */\nfunction getOrigamiEventTarget(event) {\n\t// IE backwards compatibility (get the actual target). If not IE, uses\n\t// `event.target`\n\tconst element = event.target || event.srcElement;\n\n\tif (element && element.getAttribute('data-o-component')) {\n\t\treturn element;\n\t}\n}\n\n/**\n * Helper function that generates a component id based on its xpath\n *\n * @param {HTMLElement} element - The HTML Element to gen an ID for.\n *\n * @returns {number} hash\n */\nfunction getComponentId(element) {\n\tconst path = _getElementPath(element);\n\n\tif (typeof path === 'undefined') {\n\t\treturn;\n\t}\n\n\t// Select the source element (first item in the ordered sequence `path`)\n\tconst srcElement = path[0];\n\n\t// Because, you could have two identical elements in the DOM as siblings,\n\t// we need to determine the 'sibling index': the order they're sitting within a DOM node.\n\t// Although in reality this is unlikely to always be the same, it's just a\n\t// best guess - unless child elements are always appended to an element rather than added as the first child.\n\tconst siblingIndex = (function getSiblingIndex(element) {\n\t\tconst srcParent = element.parentElement;\n\t\tif (srcParent) {\n\t\t\tfor (let i = 0; i < srcParent.childNodes.length; i++) {\n\t\t\t\tif (srcParent.childNodes[i] === srcElement) {\n\t\t\t\t\treturn i;\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn -1;\n\t\t} else {\n\t\t\treturn 0;\n\t\t}\n\t}(srcElement));\n\n\t// Generate a normalised string (normalising browser quirks) from the sequence of elements\n\tconst normalisedStringPath = path.reduceRight(function(builder, el) {\n\t\tif (!el.nodeName) {\n\t\t\treturn builder + ' - ' + el.constructor.name + '\\n';\n\t\t}\n\n\t\tconst nodeName = el.nodeName.toLowerCase();\n\n\t\t// In some browsers, document is prepended with a '#'\n\t\tif (nodeName.indexOf('#') === 0) {\n\t\t\treturn builder + '<' + nodeName + '>';\n\t\t}\n\n\t\t// Replace this stuff with stuff that makes each node unique - without including styling detail (as this may change depending on animation state etc, position)\n\t\treturn builder + '<' + nodeName +' id=\"' + (el.id || '') + '\">';\n\t}, '');\n\n\n\t// Append a sibling index to the string and use some simple, off the shelf string hashing algorithm.\n\treturn _generateHash(normalisedStringPath + '_siblingIndex=' + siblingIndex);\n}\n\n/**\n * Gets the xpath for an element\n *\n * @param  {HTMLElement} element - The element to get a path for.\n *\n * @private\n *\n * @returns {Array} The xpath\n */\nfunction _getElementPath(element) {\n\tconst path = [];\n\n\twhile (element) {\n\t\tpath.push(element);\n\t\telement = element.parentElement;\n\t}\n\n\treturn path;\n}\n\n/**\n * JS Implementation of MurmurHash2\n *\n * @author <a href=\"mailto:gary.court@gmail.com\">Gary Court</a>\n * @see http://github.com/garycourt/murmurhash-js\n * @author <a href=\"mailto:aappleby@gmail.com\">Austin Appleby</a>\n * @see http://sites.google.com/site/murmurhash/\n * Copyright (c) 2011 Gary Court\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the \"Software\"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n *\n * @param {string} str  - The string to hash, ASCII only.\n *\n * @returns {number} 32-bit positive integer hash\n *\n * @private\n */\nfunction _generateHash(str) {\n\tlet l = str.length;\n\tlet h = 1 ^ l;\n\tlet i = 0;\n\tlet k;\n\n\twhile (l >= 4) {\n\t\tk = str.charCodeAt(i) & 0xff |\n\t\t\t(str.charCodeAt(++i) & 0xff) << 8 |\n\t\t\t(str.charCodeAt(++i) & 0xff) << 16 |\n\t\t\t(str.charCodeAt(++i) & 0xff) << 24;\n\n\t\tk = (k & 0xffff) * 0x5bd1e995 + (((k >>> 16) * 0x5bd1e995 & 0xffff) << 16);\n\t\tk ^= k >>> 24;\n\t\tk = (k & 0xffff) * 0x5bd1e995 + (((k >>> 16) * 0x5bd1e995 & 0xffff) << 16);\n\n\t\th = (h & 0xffff) * 0x5bd1e995 + (((h >>> 16) * 0x5bd1e995 & 0xffff) << 16) ^ k;\n\n\t\tl -= 4;\n\t\t++i;\n\t}\n\n\tswitch (l) {\n\t\tcase 3:\n\t\t\th ^= (str.charCodeAt(i + 2) & 0xff) << 16;\n\t\t\tbreak;\n\t\tcase 2:\n\t\t\th ^= (str.charCodeAt(i + 1) & 0xff) << 8;\n\t\t\tbreak;\n\t\tcase 1:\n\t\t\th ^= str.charCodeAt(i) & 0xff;\n\t\t\th = (h & 0xffff) * 0x5bd1e995 + (((h >>> 16) * 0x5bd1e995 & 0xffff) << 16);\n\t\t\tbreak;\n\t\tdefault:\n\t\t\tbreak;\n\t}\n\n\th ^= h >>> 13;\n\th = (h & 0xffff) * 0x5bd1e995 + (((h >>> 16) * 0x5bd1e995 & 0xffff) << 16);\n\th ^= h >>> 15;\n\n\treturn h >>> 0;\n}\n\nconst init = function init() {\n\taddEvent(window, 'oTracking.event', event);\n};\nevent.init = init;\n\nexport { event };\n","import core from '../core.js';\nimport {merge, triggerPage, addEvent, isDeepEqual} from '../utils.js';\nimport {set as setSetting, get as getSetting} from '../core/settings.js';\n\nsetSetting('page_has_already_been_viewed', false);\n\n/**\n * Default properties for page tracking requests.\n *\n * @returns {object} - The default properties for pages.\n */\nconst defaultPageConfig = function () {\n\treturn {\n\t\tcategory: 'page',\n\t\taction: 'view',\n\t\tcontext: {\n\t\t\turl: document.URL,\n\t\t\treferrer: document.referrer\n\t\t}\n\t};\n};\n\n/**\n * Make the page tracking request.\n *\n * @param {object} config - Configuration object. If omitted, will use the defaults.\n * @param {Function=} callback - Callback function. Called when request completed.\n * @returns {void}\n */\nfunction page(config, callback) {\n\tconfig = merge(defaultPageConfig(), {\n\t\tcontext: config\n\t});\n\n\t// Set a new root ID only if the page function has already been called once before.\n\t// This is because o-tracking assumes each page function call is for a different page being viewed\n\t// And o-tracking wants all other events on the page to share the same root_id so that Spoor can\n\t// relate those other events with the page view they were from.\n\t// If o-tracking events were fired before this `page` function was ever called, then the first\n\t// of those events would have created a `root_id` and we want the first page view event to reuse\n\t// that `root_id` so those earlier events can be related to the page view they were from.\n\tif (getSetting('page_has_already_been_viewed')) {\n\t\tcore.setRootID();\n\t}\n\tsetSetting('page_has_already_been_viewed', true);\n\n\t// Some applications which use o-tracking have a bug where they send thousands of page-view events\n\t// Instead of forwarding these errorneous events to Spoor, we ignore them.\n\t// GitHub Issue: https://github.com/Financial-Times/o-tracking/issues/296\n\tif (pageViewEventHasAlreadyBeenSentBefore(config)) {\n\t\tif (getSetting('config').test) {\n\t\t\t// eslint-disable-next-line no-console\n\t\t\tconsole.warn('A page event has already been sent for this page, refusing to send a duplicate page event.');\n\t\t}\n\t} else {\n\t\tcore.track(config, callback);\n\t\t// Alert internally that a new page has been tracked - for single page apps for example.\n\t\ttriggerPage();\n\t}\n}\n\nlet previousPageConfigWithoutContextIDs = {};\n\n/**\n * Detect whether the previously sent page-view event is the\n * same as the page-view event which is about to be sent.\n *\n * @param {object} config - The page configuration object\n * @returns {boolean} - Whether the event has been sent before\n */\nfunction pageViewEventHasAlreadyBeenSentBefore(config) {\n\tconst configWithoutContextIDs = JSON.parse(JSON.stringify(config));\n\tdelete configWithoutContextIDs.context.id;\n\tdelete configWithoutContextIDs.context.root_id;\n\n\tif (isDeepEqual(previousPageConfigWithoutContextIDs, configWithoutContextIDs)) {\n\t\treturn true;\n\t} else {\n\t\tpreviousPageConfigWithoutContextIDs = configWithoutContextIDs;\n\t\treturn false;\n\t}\n}\n\n/**\n * Listener for pages.\n *\n * @param {CustomEvent} e - The CustomEvent\n * @private\n * @returns {void}\n */\nfunction listener(e) {\n\tpage(e.detail);\n}\n\nconst init = function init() {\n\taddEvent(window, 'oTracking.page', listener);\n};\npage.init = init;\n\nexport { page };\n","/**\n * DOM event delegator\n *\n * The delegator will listen\n * for events that bubble up\n * to the root node.\n *\n * @constructor\n * @param {Node|string} [root] The root node or a selector string matching the root node\n */\nfunction Delegate(root) {\n\n\t/**\n\t * Maintain a map of listener\n\t * lists, keyed by event name.\n\t *\n\t * @type Object\n\t */\n\tthis.listenerMap = [{}, {}];\n\tif (root) {\n\t\tthis.root(root);\n\t}\n\n\t/** @type function() */\n\tthis.handle = Delegate.prototype.handle.bind(this);\n\n\t// Cache of event listeners removed during an event cycle\n\tthis._removedListeners = [];\n}\n\n/**\n * Start listening for events\n * on the provided DOM element\n *\n * @param  {Node|string} [root] The root node or a selector string matching the root node\n * @returns {Delegate} This method is chainable\n */\nDelegate.prototype.root = function (root) {\n\tconst listenerMap = this.listenerMap;\n\tlet eventType;\n\n\t// Remove master event listeners\n\tif (this.rootElement) {\n\t\tfor (eventType in listenerMap[1]) {\n\t\t\tif (listenerMap[1].hasOwnProperty(eventType)) {\n\t\t\t\tthis.rootElement.removeEventListener(eventType, this.handle, true);\n\t\t\t}\n\t\t}\n\t\tfor (eventType in listenerMap[0]) {\n\t\t\tif (listenerMap[0].hasOwnProperty(eventType)) {\n\t\t\t\tthis.rootElement.removeEventListener(eventType, this.handle, false);\n\t\t\t}\n\t\t}\n\t}\n\n\t// If no root or root is not\n\t// a dom node, then remove internal\n\t// root reference and exit here\n\tif (!root || !root.addEventListener) {\n\t\tif (this.rootElement) {\n\t\t\tdelete this.rootElement;\n\t\t}\n\t\treturn this;\n\t}\n\n\t/**\n\t * The root node at which\n\t * listeners are attached.\n\t *\n\t * @type Node\n\t */\n\tthis.rootElement = root;\n\n\t// Set up master event listeners\n\tfor (eventType in listenerMap[1]) {\n\t\tif (listenerMap[1].hasOwnProperty(eventType)) {\n\t\t\tthis.rootElement.addEventListener(eventType, this.handle, true);\n\t\t}\n\t}\n\tfor (eventType in listenerMap[0]) {\n\t\tif (listenerMap[0].hasOwnProperty(eventType)) {\n\t\t\tthis.rootElement.addEventListener(eventType, this.handle, false);\n\t\t}\n\t}\n\n\treturn this;\n};\n\n/**\n * @param {string} eventType\n * @returns boolean\n */\nDelegate.prototype.captureForType = function (eventType) {\n\treturn ['blur', 'error', 'focus', 'load', 'resize', 'scroll'].indexOf(eventType) !== -1;\n};\n\n/**\n * Attach a handler to one\n * event for all elements\n * that match the selector,\n * now or in the future\n *\n * The handler function receives\n * three arguments: the DOM event\n * object, the node that matched\n * the selector while the event\n * was bubbling and a reference\n * to itself. Within the handler,\n * 'this' is equal to the second\n * argument.\n *\n * The node that actually received\n * the event can be accessed via\n * 'event.target'.\n *\n * @param {string} eventType Listen for these events\n * @param {string|undefined} selector Only handle events on elements matching this selector, if undefined match root element\n * @param {function()} handler Handler function - event data passed here will be in event.data\n * @param {boolean} [useCapture] see 'useCapture' in <https://developer.mozilla.org/en-US/docs/Web/API/EventTarget/addEventListener>\n * @returns {Delegate} This method is chainable\n */\nDelegate.prototype.on = function (eventType, selector, handler, useCapture) {\n\tlet root;\n\tlet listenerMap;\n\tlet matcher;\n\tlet matcherParam;\n\n\tif (!eventType) {\n\t\tthrow new TypeError('Invalid event type: ' + eventType);\n\t}\n\n\t// handler can be passed as\n\t// the second or third argument\n\tif (typeof selector === 'function') {\n\t\tuseCapture = handler;\n\t\thandler = selector;\n\t\tselector = null;\n\t}\n\n\t// Fallback to sensible defaults\n\t// if useCapture not set\n\tif (useCapture === undefined) {\n\t\tuseCapture = this.captureForType(eventType);\n\t}\n\n\tif (typeof handler !== 'function') {\n\t\tthrow new TypeError('Handler must be a type of Function');\n\t}\n\n\troot = this.rootElement;\n\tlistenerMap = this.listenerMap[useCapture ? 1 : 0];\n\n\t// Add master handler for type if not created yet\n\tif (!listenerMap[eventType]) {\n\t\tif (root) {\n\t\t\troot.addEventListener(eventType, this.handle, useCapture);\n\t\t}\n\t\tlistenerMap[eventType] = [];\n\t}\n\n\tif (!selector) {\n\t\tmatcherParam = null;\n\n\t\t// COMPLEX - matchesRoot needs to have access to\n\t\t// this.rootElement, so bind the function to this.\n\t\tmatcher = matchesRoot.bind(this);\n\n\t\t// Compile a matcher for the given selector\n\t} else if (/^[a-z]+$/i.test(selector)) {\n\t\tmatcherParam = selector;\n\t\tmatcher = matchesTag;\n\t} else if (/^#[a-z0-9\\-_]+$/i.test(selector)) {\n\t\tmatcherParam = selector.slice(1);\n\t\tmatcher = matchesId;\n\t} else {\n\t\tmatcherParam = selector;\n\t\tmatcher = Element.prototype.matches;\n\t}\n\n\t// Add to the list of listeners\n\tlistenerMap[eventType].push({\n\t\tselector: selector,\n\t\thandler: handler,\n\t\tmatcher: matcher,\n\t\tmatcherParam: matcherParam\n\t});\n\n\treturn this;\n};\n\n/**\n * Remove an event handler\n * for elements that match\n * the selector, forever\n *\n * @param {string} [eventType] Remove handlers for events matching this type, considering the other parameters\n * @param {string} [selector] If this parameter is omitted, only handlers which match the other two will be removed\n * @param {function()} [handler] If this parameter is omitted, only handlers which match the previous two will be removed\n * @returns {Delegate} This method is chainable\n */\nDelegate.prototype.off = function (eventType, selector, handler, useCapture) {\n\tlet i;\n\tlet listener;\n\tlet listenerMap;\n\tlet listenerList;\n\tlet singleEventType;\n\n\t// Handler can be passed as\n\t// the second or third argument\n\tif (typeof selector === 'function') {\n\t\tuseCapture = handler;\n\t\thandler = selector;\n\t\tselector = null;\n\t}\n\n\t// If useCapture not set, remove\n\t// all event listeners\n\tif (useCapture === undefined) {\n\t\tthis.off(eventType, selector, handler, true);\n\t\tthis.off(eventType, selector, handler, false);\n\t\treturn this;\n\t}\n\n\tlistenerMap = this.listenerMap[useCapture ? 1 : 0];\n\tif (!eventType) {\n\t\tfor (singleEventType in listenerMap) {\n\t\t\tif (listenerMap.hasOwnProperty(singleEventType)) {\n\t\t\t\tthis.off(singleEventType, selector, handler);\n\t\t\t}\n\t\t}\n\n\t\treturn this;\n\t}\n\n\tlistenerList = listenerMap[eventType];\n\tif (!listenerList || !listenerList.length) {\n\t\treturn this;\n\t}\n\n\t// Remove only parameter matches\n\t// if specified\n\tfor (i = listenerList.length - 1; i >= 0; i--) {\n\t\tlistener = listenerList[i];\n\n\t\tif ((!selector || selector === listener.selector) && (!handler || handler === listener.handler)) {\n\t\t\tthis._removedListeners.push(listener);\n\t\t\tlistenerList.splice(i, 1);\n\t\t}\n\t}\n\n\t// All listeners removed\n\tif (!listenerList.length) {\n\t\tdelete listenerMap[eventType];\n\n\t\t// Remove the main handler\n\t\tif (this.rootElement) {\n\t\t\tthis.rootElement.removeEventListener(eventType, this.handle, useCapture);\n\t\t}\n\t}\n\n\treturn this;\n};\n\n\n/**\n * Handle an arbitrary event.\n *\n * @param {Event} event\n */\nDelegate.prototype.handle = function (event) {\n\tlet i;\n\tlet l;\n\tconst type = event.type;\n\tlet root;\n\tlet phase;\n\tlet listener;\n\tlet returned;\n\tlet listenerList = [];\n\tlet target;\n\tconst eventIgnore = 'ftLabsDelegateIgnore';\n\n\tif (event[eventIgnore] === true) {\n\t\treturn;\n\t}\n\n\ttarget = event.target;\n\n\t// Hardcode value of Node.TEXT_NODE\n\t// as not defined in IE8\n\tif (target.nodeType === 3) {\n\t\ttarget = target.parentNode;\n\t}\n\n\t// Handle SVG <use> elements in IE\n\tif (target.correspondingUseElement) {\n\t\ttarget = target.correspondingUseElement;\n\t}\n\n\troot = this.rootElement;\n\n\tphase = event.eventPhase || (event.target !== event.currentTarget ? 3 : 2);\n\n\t// eslint-disable-next-line default-case\n\tswitch (phase) {\n\t\tcase 1: //Event.CAPTURING_PHASE:\n\t\t\tlistenerList = this.listenerMap[1][type];\n\t\t\tbreak;\n\t\tcase 2: //Event.AT_TARGET:\n\t\t\tif (this.listenerMap[0] && this.listenerMap[0][type]) {\n\t\t\t\tlistenerList = listenerList.concat(this.listenerMap[0][type]);\n\t\t\t}\n\t\t\tif (this.listenerMap[1] && this.listenerMap[1][type]) {\n\t\t\t\tlistenerList = listenerList.concat(this.listenerMap[1][type]);\n\t\t\t}\n\t\t\tbreak;\n\t\tcase 3: //Event.BUBBLING_PHASE:\n\t\t\tlistenerList = this.listenerMap[0][type];\n\t\t\tbreak;\n\t}\n\n\tlet toFire = [];\n\n\t// Need to continuously check\n\t// that the specific list is\n\t// still populated in case one\n\t// of the callbacks actually\n\t// causes the list to be destroyed.\n\tl = listenerList.length;\n\twhile (target && l) {\n\t\tfor (i = 0; i < l; i++) {\n\t\t\tlistener = listenerList[i];\n\n\t\t\t// Bail from this loop if\n\t\t\t// the length changed and\n\t\t\t// no more listeners are\n\t\t\t// defined between i and l.\n\t\t\tif (!listener) {\n\t\t\t\tbreak;\n\t\t\t}\n\n\t\t\tif (\n\t\t\t\ttarget.tagName &&\n\t\t\t\t[\"button\", \"input\", \"select\", \"textarea\"].indexOf(target.tagName.toLowerCase()) > -1 &&\n\t\t\t\ttarget.hasAttribute(\"disabled\")\n\t\t\t) {\n\t\t\t\t// Remove things that have previously fired\n\t\t\t\ttoFire = [];\n\t\t\t}\n\t\t\t// Check for match and fire\n\t\t\t// the event if there's one\n\t\t\t//\n\t\t\t// TODO:MCG:20120117: Need a way\n\t\t\t// to check if event#stopImmediatePropagation\n\t\t\t// was called. If so, break both loops.\n\t\t\telse if (listener.matcher.call(target, listener.matcherParam, target)) {\n\t\t\t\ttoFire.push([event, target, listener]);\n\t\t\t}\n\t\t}\n\n\t\t// TODO:MCG:20120117: Need a way to\n\t\t// check if event#stopPropagation\n\t\t// was called. If so, break looping\n\t\t// through the DOM. Stop if the\n\t\t// delegation root has been reached\n\t\tif (target === root) {\n\t\t\tbreak;\n\t\t}\n\n\t\tl = listenerList.length;\n\n\t\t// Fall back to parentNode since SVG children have no parentElement in IE\n\t\ttarget = target.parentElement || target.parentNode;\n\n\t\t// Do not traverse up to document root when using parentNode, though\n\t\tif (target instanceof HTMLDocument) {\n\t\t\tbreak;\n\t\t}\n\t}\n\n\tlet ret;\n\n\tfor (i = 0; i < toFire.length; i++) {\n\t\t// Has it been removed during while the event function was fired\n\t\tif (this._removedListeners.indexOf(toFire[i][2]) > -1) {\n\t\t\tcontinue;\n\t\t}\n\t\treturned = this.fire.apply(this, toFire[i]);\n\n\t\t// Stop propagation to subsequent\n\t\t// callbacks if the callback returned\n\t\t// false\n\t\tif (returned === false) {\n\t\t\ttoFire[i][0][eventIgnore] = true;\n\t\t\ttoFire[i][0].preventDefault();\n\t\t\tret = false;\n\t\t\tbreak;\n\t\t}\n\t}\n\n\treturn ret;\n};\n\n/**\n * Fire a listener on a target.\n *\n * @param {Event} event\n * @param {Node} target\n * @param {Object} listener\n * @returns {boolean}\n */\nDelegate.prototype.fire = function (event, target, listener) {\n\treturn listener.handler.call(target, event, target);\n};\n\n/**\n * Check whether an element\n * matches a tag selector.\n *\n * Tags are NOT case-sensitive,\n * except in XML (and XML-based\n * languages such as XHTML).\n *\n * @param {string} tagName The tag name to test against\n * @param {Element} element The element to test with\n * @returns boolean\n */\nfunction matchesTag(tagName, element) {\n\treturn tagName.toLowerCase() === element.tagName.toLowerCase();\n}\n\n/**\n * Check whether an element\n * matches the root.\n *\n * @param {?String} selector In this case this is always passed through as null and not used\n * @param {Element} element The element to test with\n * @returns boolean\n */\nfunction matchesRoot(selector, element) {\n\tif (this.rootElement === window) {\n\t\treturn (\n\t\t\t// Match the outer document (dispatched from document)\n\t\t\telement === document ||\n\t\t\t// The <html> element (dispatched from document.body or document.documentElement)\n\t\t\telement === document.documentElement ||\n\t\t\t// Or the window itself (dispatched from window)\n\t\t\telement === window\n\t\t);\n\t}\n\treturn this.rootElement === element;\n}\n\n/**\n * Check whether the ID of\n * the element in 'this'\n * matches the given ID.\n *\n * IDs are case-sensitive.\n *\n * @param {string} id The ID to test against\n * @param {Element} element The element to test with\n * @returns boolean\n */\nfunction matchesId(id, element) {\n\treturn id === element.id;\n}\n\n/**\n * Short hand for off()\n * and root(), ie both\n * with no parameters\n *\n * @return void\n */\nDelegate.prototype.destroy = function () {\n\tthis.off();\n\tthis.root();\n};\n\nexport default Delegate;\n","// Trace the element and all of its parents, collecting properties as we go\nimport {sanitise, assignIfUndefined} from '../javascript/utils.js';\n\n// For a given container element, get the number of elements that match the\n// original element (siblings); and the index of the original element (position).\nconst getSiblingsAndPosition = (el, originalEl, selector) => {\n\tconst siblings = Array.from(el.querySelectorAll(selector));\n\tconst position = siblings.findIndex(item => item === originalEl);\n\tif(position === -1) {return;}\n\treturn {\n\t\tsiblings: siblings.length,\n\t\tposition,\n\t};\n};\n\n\nconst elementPropertiesToCollect = [\n\t\"nodeName\",\n\t\"className\",\n\t\"id\",\n\t\"href\",\n\t\"text\",\n\t\"role\",\n];\n// Get all (sanitised) properties of a given element.\nconst getAllElementProperties = element => {\n\n\tconst properties = {};\n\tfor (const property of elementPropertiesToCollect) {\n\t\tconst value = element[property] || element.getAttribute(property) || element.hasAttribute(property);\n\t\tif (value !== undefined) {\n\t\t\tif (typeof value === 'boolean') {\n\t\t\t\tproperties[property] = value;\n\t\t\t} else {\n\t\t\t\tproperties[property] = sanitise(value);\n\t\t\t}\n\t\t}\n\t}\n\n\treturn properties;\n};\n\nconst parseRawValue = (rawValue) => {\n\ttry {\n\t\tconst parsedValue = JSON.parse(rawValue);\n\t\tconst type = Object.prototype.toString.call(parsedValue);\n\t\tconst isJSON = type === '[object Object]' || type === '[object Array]';\n\n\t\treturn [isJSON, parsedValue];\n\t} catch (error) {\n\t\treturn [false, null];\n\t}\n}\n\nconst getAttributeValue = (rawValue) => {\n\tconst [isJSON, value] = parseRawValue(rawValue);\n\n\treturn isJSON ? value : rawValue;\n}\n\n// Get some properties of a given element.\nconst getDomPathProps = (attrs, props) => {\n\n\t// Collect any attribute that matches given strings.\n\tattrs\n\t\t.filter(attribute => attribute.name.match(/^data-trackable|^data-o-|^aria-/i))\n\t\t.forEach(attribute => {\n\t\t\tprops[attribute.name] = attribute.value;\n\t\t});\n\n\treturn props;\n};\n\n// Get only the custom data-trackable-context-? properties of a given element\nconst getContextProps = (attrs, props, isOriginalEl) => {\n\n\tconst customProps = {};\n\n\t// for the original element collect properties like className, nodeName\n\tif (isOriginalEl) {\n\t\telementPropertiesToCollect.forEach(name => {\n\t\t\tif (typeof props[name] !== 'undefined' && name !== 'id') {\n\t\t\t\tcustomProps[name] = props[name];\n\t\t\t}\n\t\t});\n\t}\n\n\t// Collect any attribute that matches given strings.\n\tattrs\n\t\t.filter(attribute => attribute.name.match(/^data-trackable-context-/i))\n\t\t.forEach(attribute => {\n\t\t\tcustomProps[attribute.name.replace('data-trackable-context-', '')] = getAttributeValue(attribute.value);\n\t\t});\n\n\treturn customProps;\n};\n\nexport function getTrace (el) {\n\tconst rootEl = document;\n\tconst originalEl = el;\n\tconst selector = originalEl.getAttribute('data-trackable') ? `[data-trackable=\"${originalEl.getAttribute('data-trackable')}\"]` : originalEl.nodeName;\n\tconst trace = [];\n\tconst customContext = {};\n\twhile (el && el !== rootEl) {\n\t\tconst props = getAllElementProperties(el);\n\t\tconst attrs = Array.from(el.attributes);\n\t\tlet domPathProps = getDomPathProps(attrs, props);\n\n\t\t// If the element happens to have a data-trackable attribute, get the siblings\n\t\t// and position of the element (relative to the current element).\n\t\tif (domPathProps[\"data-trackable\"]) {\n\t\t\tdomPathProps = Object.assign(\n\t\t\t\tdomPathProps,\n\t\t\t\tgetSiblingsAndPosition(el, originalEl, selector)\n\t\t\t);\n\t\t}\n\n\t\ttrace.push(domPathProps);\n\n\t\tconst contextProps = getContextProps(attrs, props, el === originalEl);\n\n\t\tassignIfUndefined(contextProps, customContext);\n\n\t\tel = el.parentNode;\n\t}\n\treturn { trace, customContext };\n}\n","import Delegate from 'ftdomdelegate';\nimport core from '../core.js';\nimport {sanitise, assignIfUndefined, merge } from '../utils.js';\nimport {get as getSetting} from '../core/settings.js';\nimport {getTrace} from '../../libs/get-trace.js';\nimport { Queue } from '../core/queue.js';\n\nlet delegate;\n\nconst eventPropertiesToCollect = [\n\t\"ctrlKey\",\n\t\"altKey\",\n\t\"shiftKey\",\n\t\"metaKey\",\n];\n\n// Get properties for the event (as opposed to properties of the clicked element)\n// Available properties include mouse x- and y co-ordinates, for example.\nconst getEventProperties = event => {\n\tconst eventProperties = {};\n\tfor (const property of eventPropertiesToCollect) {\n\t\tif (event[property]) {\n\t\t\ttry {\n\t\t\t\teventProperties[property] = sanitise(event[property]);\n\t\t\t} catch (e) {\n\t\t\t\t// eslint-disable-next-line no-console\n\t\t\t\tconsole.log(e);\n\t\t\t}\n\t\t}\n\t}\n\n\treturn eventProperties;\n};\n\n// Controller for handling click events\nconst handleClickEvent = eventData => (clickEvent, clickElement) => {\n\t//we don't want to track clicks to anonymous services like securedrop\n\tif (clickElement.getAttribute(\"data-o-tracking-do-not-track\") === \"true\") {return;}\n\tconst context = getEventProperties(clickEvent);\n\tconst { trace, customContext} = getTrace(clickElement);\n\tcontext.domPathTokens = trace;\n\tcontext.url = window.document.location.href || null;\n\t// source_id is a field that is currently being used in some data analytics\n\t// before removing this field - check with the data analytics team first to see if it is still being used\n\tcontext.source_id = core.getRootID();\n\n\tassignIfUndefined(customContext, context);\n\n\teventData.context = context;\n\n\t// Merge the event data into the \"parent\" config data\n\tconst config = merge(getSetting('config'), eventData);\n\tcore.track(config);\n};\n\n/**\n * Listen for click events.\n *\n * @alias click#init\n * @param {string} category - The event category for clicks.\n * @param {string} elementsToTrack - A query selector string to select elements to track links on {@link https://github.com/ftlabs/ftdomdelegate#selector-string}.\n * @returns {void}\n */\nconst init = (category, elementsToTrack) => {\n\telementsToTrack = elementsToTrack || 'a, button, input, [role=\"button\"]'; // See https://github.com/ftlabs/ftdomdelegate#selector-string\n\n\t// Note: `context` is the term o-tracking uses for the data that is sent to spoor\n\tconst eventData = {\n\t\taction: 'click',\n\t\tcategory: category || 'o-tracking'\n\t};\n\n\t// Activate the click event listener\n\tdelegate = delegate || new Delegate(document.body);\n\tdelegate.on('click', elementsToTrack, handleClickEvent(eventData), true);\n\n\t// Fire all click events that were stored in the old queue used by o-tracking v2\n\tconst clickQueue = new Queue('clicks');\n\tsendAllEventsFromQueue(clickQueue);\n};\n\nfunction sendAllEventsFromQueue(queue) {\n\tconst nextLink = queue.shift();\n\tif (nextLink) {\n\t\tcore.track(nextLink, () => sendAllEventsFromQueue(queue));\n\t}\n}\n\nconst click = {\n\tinit\n};\n\nexport { click };\n","import core from '../core.js';\nimport {getTrace} from '../../libs/get-trace.js';\nimport {assignIfUndefined, filterProperties} from '../utils.js';\n\nconst TRACKING_ATTRIBUTES = [\n\t'componentContentId',\n\t'type',\n\t'subtype',\n\t'component',\n];\n\nconst decorateEventData = (eventData, viewedEl, opts) => {\n\n\tconst { trace, customContext } = getTrace(viewedEl);\n\tlet context;\n\n\tif (opts.getContextData) {\n\t\tif (typeof opts.getContextData !== 'function') {\n\t\t\tthrow new Error('opts.getContextData is not a function');\n\t\t}\n\n\t\tconst contextData = opts.getContextData(viewedEl);\n\n\t\tif (typeof contextData !== 'object') {\n\t\t\tthrow new Error('opts.getContextData function should return {object}');\n\t\t}\n\n\t\tcontext = filterProperties(contextData, TRACKING_ATTRIBUTES);\n\t} else {\n\t\tcontext = {};\n\t}\n\n\tcontext.domPathTokens = trace;\n\tcontext.url = window.document.location.href || null;\n\n\tassignIfUndefined(customContext, context);\n\n\teventData.context = context;\n};\n\n/**\n * Listen for view events.\n *\n * @alias view#init\n * @param {object} opts - To set custom category[String], selector[String], getContextData[Function]\n * @returns {undefined}\n */\nconst init = (opts = {}) => {\n\tif(!window.IntersectionObserver) {\n\t\t// eslint-disable-next-line no-console\n\t\tconsole.warn('o-tracking: Unable to track component view events as \"window.IntersectionObserver\" is not supported.');\n\t\treturn;\n\t}\n\n\tconst selector = opts.selector || '[data-o-tracking-view]';\n\tconst elementsToTrack = [...document.querySelectorAll(selector)];\n\n\tif (!elementsToTrack.length) {\n\t\treturn;\n\t}\n\n\tfunction onChange (changes) {\n\t\tchanges.forEach(change => {\n\t\t\tif(change.isIntersecting || change.intersectionRatio > 0) {\n\t\t\t\tconst eventData = {\n\t\t\t\t\taction: opts.action || 'view',\n\t\t\t\t\tcategory: opts.category || 'component'\n\t\t\t\t};\n\t\t\t\tconst viewedEl = change.target;\n\n\t\t\t\tdecorateEventData(eventData, viewedEl, opts);\n\t\t\t\tcore.track(eventData);\n\t\t\t\tobserver.unobserve(viewedEl);\n\t\t\t}\n\t\t});\n\t}\n\n\tconst observer = new IntersectionObserver(onChange, { threshold: [ 1.0 ] });\n\n\telementsToTrack.forEach(el => observer.observe(el));\n};\n\nconst view = {\n\tinit\n};\n\nexport { view };\n\n\n","import {set, get, destroy as destroySetting} from './core/settings.js';\nimport {setUser, init as initUser} from './core/user.js';\nimport {init as initSession} from './core/session.js';\nimport {init as initSend} from './core/send.js';\nimport {event} from './events/custom.js';\nimport {page} from './events/page-view.js';\nimport {click} from './events/click.js';\nimport core from './core.js';\nimport { merge, broadcast } from './utils.js';\nimport {view} from './events/component-view.js';\n\nconst initEvent = event.init;\nconst initPage = page.init;\n\n/**\n * The version of the tracking module.\n *\n * @type {string}\n */\nconst version = '4.5.0';\n\n/**\n * The source of this event.\n *\n * @type {string}\n */\nconst source = 'o-tracking';\n\n/**\n * Update the tracking configuration with any state changes. The supplied\n * config is merged with any existing config; to unset a value, set it as\n * null or undefined.\n *\n * @param {object} newConfig The configuration object to merge in - see init()\n * @returns {void}\n */\nfunction updateConfig(newConfig) {\n\tlet config = get('config') || {};\n\n\tconfig = merge(config, newConfig);\n\tset('config', config);\n\n\tif (config.user && config.user.user_id) {\n\t\tsetUser(config.user.user_id);\n\t}\n}\n\n/**\n * Clean up the tracking module.\n *\n * @returns {void}\n */\nfunction destroy() {\n\ttracking.initialised = false;\n\n\tdestroySetting('config');\n\tdestroySetting('page_sent');\n}\n/**\n * Overload toString method to show the version.\n *\n * @returns {string} The module's version.\n */\nfunction toString() {\n\treturn 'oTracking version ' + version;\n}\n\n/**\n * Initialises the Tracking object.\n *\n * All options are optional, if a configuration option is missing, the module\n * will try to initialise using any configuration found in the DOM using the\n * script config tag.\n *\n * @example\n * <!-- DOM configuration settings -->\n * <script type='application/json' data-o-tracking-config>\n * page: {\n * \t product: 'desktop'\n * },\n * user: {\n *   user_id: '023ur9jfokwenvcklwnfiwhfoi324'\n * }\n * </script>\n *\n * @param {object} config \t\t\t\t\t- See {@link Tracking} for the configuration options.\n * @param {boolean=} config.test             - Optional, if `true`, the data sent to Spoor will be marked as test data.\n * @param {string=} config.configId          - Optional\n * @param {string=} config.session           - Optional\n * @param {string=} config.cookieDomain      - Optional\n * @param {object=} config.context           - Optional\n * @param {object=} config.user              - Optional\n * @param {object=} config.system            - Optional\n * @param {object=} config.device            - Optional\n *\n * @returns {tracking|null} - The initialised tracking object or null if no configuration has been given.\n */\nfunction init(config = {}) {\n\tif (tracking.initialised) {\n\t\treturn tracking;\n\t}\n\n\tconst hasDeclarativeConfig = Boolean(\n\t\tgetDeclarativeConfigElement()\n\t);\n\n\tif (hasDeclarativeConfig) {\n\t\tconfig = getDeclarativeConfig(config);\n\t}\n\n\t// If there's no config, there is no point initialising!\n\t// http://stackoverflow.com/a/32108184\n\tif (Object.keys(config).length === 0 && config.constructor === Object) {\n\t\treturn null;\n\t}\n\n\tset('version', version);\n\tset('source', source);\n\n\tset('page_sent', false);\n\n\tconst cookieDomain = config ? config.cookieDomain : '';\n\n\t// Set up the user from stored - may later be updated by config\n\tinitUser('', cookieDomain);\n\tupdateConfig(config);\n\n\t// Session\n\tinitSession(config.session);\n\n\t// Initialize the sending queue.\n\tinitSend();\n\n\tinitEvent();\n\tinitPage();\n\ttracking.initialised = true;\n\treturn tracking;\n}\n\n/**\n * Retrieves the <script type='application/json' data-o-tracking-config> element that is in the DOM, otherwise returns null.\n *\n * @private\n * @returns {HTMLElement|null} - Returns the <script> element if found otherwise returns null.\n */\nfunction getDeclarativeConfigElement() {\n\treturn document.querySelector('script[data-o-tracking-config]');\n}\n\n/**\n * Initialises additional data using the <script type='application/json' data-o-tracking-config> element in the DOM.\n *\n * @private\n * @param {object} options - A partially, or fully filled options object.  If\n *                           an option is missing, this method will attempt to\n *                           initialise it from the DOM.\n * @returns {object|boolean} - The options modified to include the options gathered from the DOM\n */\nfunction getDeclarativeConfig(options) {\n\tconst configEl = getDeclarativeConfigElement();\n\tlet declarativeConfigString;\n\tif (configEl) {\n\t\tdeclarativeConfigString = configEl.textContent || configEl.innerText || configEl.innerHTML;\n\t} else {\n\t\treturn false;\n\t}\n\n\ttry {\n\t\tconst declarativeOptions = JSON.parse(declarativeConfigString);\n\t\tObject.assign(options, declarativeOptions);\n\t} catch(e) {\n\t\tconst configError = new Error('Invalid JSON configuration syntax, check validity for o-tracking configuration: \"' + e.message + '\"');\n\t\tbroadcast('oErrors', 'log', {\n\t\t\terror: configError.message,\n\t\t\tinfo: { module: 'o-tracking' }\n\t\t});\n\t\tthrow configError;\n\t}\n\n\treturn options;\n}\n\nconst tracking = {\n\t/**\n\t * The initialised state of the object.\n\t *\n\t * @type {boolean}\n\t */\n\tinitialised: false,\n\tversion,\n\tupdateConfig,\n\tsource,\n\tdestroy,\n\ttoString,\n\tinit,\n\tclick,\n\tevent,\n\tpage,\n\tview,\n\tgetRootID: core.getRootID\n};\n\nexport default tracking;\n","import tracking from './src/javascript/tracking.js';\n\n/**\n * Automatically initilise o-tracking\n *\n * @returns {void}\n */\nfunction initialise() {\n\ttracking.init();\n\tdocument.removeEventListener('o.DOMContentLoaded', initialise);\n}\n\n// Try and initialise on o.DOMContentLoaded. If it fails, defer to the\n// consumer of the library.\nif (typeof document !== 'undefined') {\n\tdocument.addEventListener('o.DOMContentLoaded', initialise);\n}\n\n/**\n * A constructed object, this module is a Singleton as we only want one\n * instance sending events. See {@link Tracking} for the publicly available\n * interface.\n *\n * @type {tracking}\n */\nexport default tracking;\n"],"sourceRoot":""}