@newrelic/video-core 5.0.2 → 5.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +11 -0
- package/README.md +13 -0
- package/dist/cjs/browser/index.js +1 -1
- package/dist/cjs/browser/index.js.LICENSE.txt +1 -1
- package/dist/cjs/browser/index.js.map +1 -1
- package/dist/cjs/index.js +1 -1
- package/dist/cjs/index.js.LICENSE.txt +1 -1
- package/dist/cjs/index.js.map +1 -1
- package/dist/cjs/vega/index.js +1 -1
- package/dist/cjs/vega/index.js.LICENSE.txt +1 -1
- package/dist/cjs/vega/index.js.map +1 -1
- package/dist/esm/browser/index.js +1 -1
- package/dist/esm/browser/index.js.LICENSE.txt +1 -1
- package/dist/esm/browser/index.js.map +1 -1
- package/dist/esm/index.js +1 -1
- package/dist/esm/index.js.LICENSE.txt +1 -1
- package/dist/esm/index.js.map +1 -1
- package/dist/esm/vega/index.js +1 -1
- package/dist/esm/vega/index.js.LICENSE.txt +1 -1
- package/dist/esm/vega/index.js.map +1 -1
- package/dist/types/browser/agent.d.ts +46 -0
- package/dist/types/browser/harvestScheduler.d.ts +125 -0
- package/dist/types/browser/index.d.ts +34 -0
- package/dist/types/chrono.d.ts +52 -0
- package/dist/types/connectedDevice/connectedDeviceAgent.d.ts +63 -0
- package/dist/types/connectedDevice/connectedDeviceConstants.d.ts +51 -0
- package/dist/types/connectedDevice/connectedDeviceHarvester.d.ts +198 -0
- package/dist/types/connectedDevice/index.d.ts +30 -0
- package/dist/types/constants.d.ts +30 -0
- package/dist/types/core.d.ts +54 -0
- package/dist/types/emitter.d.ts +42 -0
- package/dist/types/eventAggregator.d.ts +97 -0
- package/dist/types/index.d.ts +33 -0
- package/dist/types/log.d.ts +61 -0
- package/dist/types/obfuscate.d.ts +13 -0
- package/dist/types/optimizedHttpClient.d.ts +83 -0
- package/dist/types/recordEvent.d.ts +30 -0
- package/dist/types/retryQueueHandler.d.ts +46 -0
- package/dist/types/tracker.d.ts +176 -0
- package/dist/types/utils/eventBuilder.d.ts +69 -0
- package/dist/types/utils/harvestTimer.d.ts +45 -0
- package/dist/types/utils/index.d.ts +38 -0
- package/dist/types/utils/qoeFilters.d.ts +88 -0
- package/dist/types/videoConfiguration.d.ts +90 -0
- package/dist/types/videotracker.d.ts +366 -0
- package/dist/types/videotrackerstate.d.ts +228 -0
- package/dist/umd/nrvideo.min.js +1 -1
- package/dist/umd/nrvideo.min.js.LICENSE.txt +1 -1
- package/dist/umd/nrvideo.min.js.map +1 -1
- package/package.json +14 -2
- package/src/browser/{agent.js → agent.ts} +21 -16
- package/src/browser/{harvestScheduler.js → harvestScheduler.ts} +51 -24
- package/src/{chrono.js → chrono.ts} +29 -24
- package/src/connectedDevice/{connectedDeviceAgent.js → connectedDeviceAgent.ts} +14 -10
- package/src/connectedDevice/{connectedDeviceConstants.js → connectedDeviceConstants.ts} +5 -3
- package/src/connectedDevice/{connectedDeviceHarvester.js → connectedDeviceHarvester.ts} +71 -34
- package/src/constants.ts +62 -0
- package/src/{core.js → core.ts} +31 -18
- package/src/{emitter.js → emitter.ts} +16 -5
- package/src/{eventAggregator.js → eventAggregator.ts} +33 -19
- package/src/global.d.ts +25 -0
- package/src/{log.js → log.ts} +23 -17
- package/src/{obfuscate.js → obfuscate.ts} +6 -1
- package/src/{optimizedHttpClient.js → optimizedHttpClient.ts} +37 -13
- package/src/{recordEvent.js → recordEvent.ts} +11 -9
- package/src/{retryQueueHandler.js → retryQueueHandler.ts} +17 -12
- package/src/{tracker.js → tracker.ts} +56 -23
- package/src/utils/{eventBuilder.js → eventBuilder.ts} +31 -14
- package/src/utils/{harvestTimer.js → harvestTimer.ts} +21 -4
- package/src/utils/{index.js → index.ts} +14 -14
- package/src/utils/{qoeFilters.js → qoeFilters.ts} +19 -8
- package/src/{videoConfiguration.js → videoConfiguration.ts} +44 -10
- package/src/{videotracker.js → videotracker.ts} +119 -78
- package/src/{videotrackerstate.js → videotrackerstate.ts} +113 -49
- package/src/constants.js +0 -63
- /package/src/browser/{index.js → index.ts} +0 -0
- /package/src/connectedDevice/{index.js → index.ts} +0 -0
- /package/src/{index.js → index.ts} +0 -0
package/dist/esm/index.js
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
/*! For license information please see index.js.LICENSE.txt */
|
|
2
|
-
class t{static error(...i){e(i,t.Levels.ERROR,"darkred")}static warn(...i){e(i,t.Levels.WARNING,"darkorange")}static notice(...i){e([].slice.call(arguments),t.Levels.NOTICE,"darkcyan")}static debug(...i){e(i,t.Levels.DEBUG,"indigo")}static debugCommonVideoEvents(e,i,s){try{if(t.level<=t.Levels.DEBUG){s=s||function(e){t.debug("Event: "+e.type)};var r=["canplay","buffering","waiting","ended","play","playing","pause","resume","error","abort","seek","seeking","seeked","stalled","dispose","loadeddata","loadstart","loadedmetadata"];i&&(null===i[0]?(i.shift(),r=i):r=r.concat(i));for(var a=0;a<r.length;a++)"function"==typeof e?e.call(window,r[a],s):e.on?e.on(r[a],s):e.addEventListener?e.addEventListener(r[a],s):e.addEventHandler?e.addEventHandler(r[a],s):t.warn("debugCommonVideoEvents: No common listener function found for ",e)}}catch(e){t.warn(e)}}}function e(e,r,a){r=r||t.Levels.NOTICE,a=a||"darkcyan";var n,o,h,l,d,c,u=t.prefix;(t.includeTime&&(u+=(n=new Date,o=("0"+n.getDate()).slice(-2),h=("0"+n.getMinutes()).slice(-2),l=("0"+n.getSeconds()).slice(-2),d=("00"+n.getMilliseconds()).slice(-3),"["+o+":"+h+":"+l+"."+d+"] ")),u+=function(t){return s[t]}(r)+":",t.level<=r&&r!==t.Levels.SILENT)&&(!t.colorful||"undefined"!=typeof document&&document.documentMode?i(e,u):(c=r===t.Levels.ERROR&&console.error?console.error:r===t.Levels.WARNING&&console.warn?console.warn:r===t.Levels.DEBUG&&console.debug&&null==window.cast?console.debug:console.log,u="%c"+u,e.splice(0,0,u,"color: "+a),c.apply(console,e)))}function i(t,e){if(t instanceof Array)for(var s in t)i(t[s],e);else"string"==typeof t?console.log(e+" "+t):(console.log(e+"↵"),console.log(t))}t.Levels={SILENT:5,ERROR:4,WARNING:3,NOTICE:2,DEBUG:1,ALL:0},t.level=t.Levels.ERROR,t.colorful=!0,t.includeTime=!0,t.prefix="[nrvideo]";const s={4:"e",3:"w",2:"n",1:"d"};!function(){if("undefined"!=typeof window&&window.location&&window.location.search){var e=/\?.*&*nrvideo-debug=(.+)/i.exec(window.location.search);null!==e&&("true"===e[1]?t.level=t.Levels.ALL:t.level=e[1]),null!==/\?.*&*nrvideo-colors=false/i.exec(window.location.search)&&(t.colorful=!1)}}();const r=t;class a{}a.AdPositions={PRE:"pre",MID:"mid",POST:"post"},a.COLLECTOR={US:["bam.nr-data.net","bam-cell.nr-data.net"],EU:"bam.eu01.nr-data.net",JP:"bam.jp.nr-data.net",Staging:"staging-bam-cell.nr-data.net",GOV:"gov-bam.nr-data.net"},a.VALID_EVENT_TYPES=["VideoAction","VideoAdAction","VideoErrorAction","VideoCustomAction"],a.MAX_PAYLOAD_SIZE=1048576,a.MAX_BEACON_SIZE=61440,a.MAX_EVENTS_PER_BATCH=1e3,a.INTERVAL=1e4,a.DEFAULT_QOE_INTERVAL_FACTOR=2,a.QOE_KPI_KEYS=["startupTime","peakBitrate","averageBitrate","totalPlaytime","totalRebufferingTime","rebufferingRatio","hadStartupError","hadPlaybackError","numberOfErrors"],a.QOE_AGGREGATE_KEYS=["coreVersion","instrumentation.name","instrumentation.provider","instrumentation.version","isBackgroundEvent","playerName","playerVersion","src","viewId","viewSession","contentIsAutoplayed","contentIsMuted","contentRenditionHeight","contentRenditionWidth","contentSrc","numberOfVideos","pageUrl","trackerName","trackerVersion","contentDuration","contentPlayrate","contentPlayhead","contentPreload","elapsedTime","contentTitle","contentId","contentIsLive","deviceType","deviceGroup","deviceManufacturer","deviceModel","deviceName","deviceSize","deviceUuid","contentRenditionName","contentIsFullscreen","contentCdn","contentFps","asnOrganization","asnLongitude","asnLatitude","asn","timeSinceRequested","timeSinceStarted"];const n=a,o="5.0.2";const h=class{on(t,e){if(this._listeners=this._listeners||{},"function"==typeof e)return this._listeners[t]=this._listeners[t]||[],this._listeners[t].push(e),this}off(t,e){if(this._listeners=this._listeners||{},this._listeners[t]){var i=this._listeners[t].indexOf(e);-1!==i&&this._listeners[t].splice(i,1)}return this}emit(t,e,i){return this._listeners=this._listeners||{},i=i||{},Array.isArray(this._listeners[e])&&this._listeners[e].forEach(s=>{s.call(this,{eventType:t,type:e,data:i,target:this})}),Array.isArray(this._listeners["*"])&&this._listeners["*"].forEach(s=>{s.call(this,{eventType:t,type:e,data:i,target:this})}),this}};class l{constructor(){this.reset()}reset(){this.startTime=0,this.stopTime=0,this.accumulator=0,this.offset=0}getDeltaTime(){return this.startTime?this.offset+((new Date).getTime()-this.startTime):null}start(){this.startTime=(new Date).getTime(),this.stopTime=0}stop(){return this.stopTime=(new Date).getTime(),this.startTime<this.stopTime&&(this.accumulator+=this.stopTime-this.startTime),this.getDeltaTime()}getDuration(){return this.stopTime?this.accumulator+this.offset:this.accumulator+(this.getDeltaTime()??0)}clone(){var t=new l;return t.startTime=this.startTime,t.stopTime=this.stopTime,t.offset=this.offset,t.accumulator=this.accumulator,t}}const d=l;class c extends h{constructor(t){super(),this.customData={},this.heartbeat=null,this.parentTracker=null,this._trackerReadyChrono=new d,this._trackerReadyChrono.start(),this._actionTable=n.ACTION_TABLE,this._actionAdTable=n.ACTION_AD_TABLE,t=t||{},this.setOptions(t)}setOptions(t){t&&(t.parentTracker&&(this.parentTracker=t.parentTracker),t.customData&&(this.customData=t.customData),t.heartbeat&&(this.heartbeat=t.heartbeat))}dispose(){this.unregisterListeners()}registerListeners(){}unregisterListeners(){}getHeartbeat(){return this.state._isAd?2e3:this.heartbeat?this.heartbeat:this.parentTracker&&this.parentTracker.heartbeat?this.parentTracker.heartbeat:3e4}startHeartbeat(){this._heartbeatInterval=setInterval(this.sendHeartbeat.bind(this),Math.max(this.getHeartbeat(),2e3))}stopHeartbeat(){this._heartbeatInterval&&clearInterval(this._heartbeatInterval)}sendHeartbeat(t){this.sendVideoAction(c.Events.HEARTBEAT,t)}getAttributes(t,e){(t=t||{}).trackerName=this.getTrackerName(),t.trackerVersion=this.getTrackerVersion(),t.coreVersion=o,t.timeSinceTrackerReady=this._trackerReadyChrono.getDeltaTime();for(let e in this.customData)t[e]=this.customData[e];return null!=document.hidden&&(t.isBackgroundEvent=document.hidden),t}getTrackerVersion(){return o}getTrackerName(){return"base-tracker"}sendVideoAction(t,e){this.emit("VideoAction",t,this.getAttributes(e))}sendVideoAdAction(t,e){this.emit("VideoAdAction",t,this.getAttributes(e))}sendVideoErrorAction(t,e){let i=this.isAd()?"adError":"videoError";this.emit("VideoErrorAction",t,this.getAttributes(e,i))}sendVideoCustomAction(t,e){this.emit("VideoCustomAction",t,this.getAttributes(e,"customAction"))}setHarvestInterval(t){const e=this.getHarvester?.();if(e)try{e.setHarvestInterval(t)}catch(t){return void r.error("Failed to set harvest interval:",t.message)}else r.error("Tracker has no harvester; setHarvestInterval ignored")}getHarvester(){return null}}c.Events={HEARTBEAT:"HEARTBEAT",QOE_AGGREGATE:"QOE_AGGREGATE"};const u=c;function f(t){try{return JSON.stringify(t,(()=>{const t=new WeakSet;return(e,i)=>{if("object"==typeof i&&null!==i){if(t.has(i))return;t.add(i)}return i}})())??""}catch(t){return r.error("Error stringifying value:",t.message),""}}function g(t){if("string"==typeof t&&t.length)return t.length;if("object"==typeof t){if("undefined"!=typeof ArrayBuffer&&t instanceof ArrayBuffer&&t.byteLength)return t.byteLength;if("undefined"!=typeof Blob&&t instanceof Blob&&t.size)return t.size;if(!("undefined"!=typeof FormData&&t instanceof FormData))try{return f(t).length}catch(t){return}}}function m(t,e,i,{addTimeSinceLoad:s=!1}={}){const{appName:r,applicationID:a}=i,{qoe:o,...h}=e,l=o?{...o}:{},d={...a?{}:{appName:r},timestamp:Date.now(),...s?{timeSinceLoad:"undefined"!=typeof window&&window.performance?window.performance.now()/1e3:null}:{}},c={...h,eventType:t,...d};let f=null;if("VideoAction"===t){const t=(g=n.QOE_AGGREGATE_KEYS,m=e,g&&Array.isArray(g)&&0!==g.length?m&&"object"==typeof m?g.reduce((t,e)=>(e in m&&(t[e]=m[e]),t),{}):{}:m);f={eventType:"VideoAction",actionName:u.Events.QOE_AGGREGATE,qoeAggregateVersion:"1.0.0",...l,...t,...d}}var g,m;return{eventObject:c,qoeEventObject:f}}const E=Object.create(null);function T(t,e){E[t]=e}function v(t){return E[t]}function A(t,e={}){try{if(!n.VALID_EVENT_TYPES.includes(t))return r.warn("Invalid event type provided to recordEvent",{eventType:t}),!1;const i="Vega"===e.src,s=i?"Vega":"Browser",a="undefined"!=typeof window?window:void 0,o=i?globalThis.__NRVIDEO_CD__?.info:a?.NRVIDEO?.info;if(!o)return;const h=E[s];if(!h)return r.warn("No harvester registered for routing key",{routingKey:s}),!1;return function(t,e,i,s,r,{addTimeSinceLoad:a=!1}={}){if(!s)return!1;const{eventObject:n,qoeEventObject:o}=m(t,e,i,{addTimeSinceLoad:a}),h=s.addEvent(n);return o&&r?h&&s.addEvent(o):h}(t,e,o,h,i?globalThis.__NRVIDEO_CD__?.config?.qoeAggregate:a?.NRVIDEO?.config?.qoeAggregate,{addTimeSinceLoad:!i})}catch(t){return r.error("Failed to record event:",t.message),!1}}const p={us:"https://mobile-collector.newrelic.com/mobile",eu:"https://mobile-collector.eu01.nr-data.net/mobile",staging:"https://staging-mobile-collector.newrelic.com/mobile",gov:"https://gov-mobile-collector.newrelic.com/mobile",jp:"https://mobile-collector.jp.nr-data.net/mobile"},S=[["newrelic_mobile_example","1.1","com.newrelic.newrelic_mobile_example"],["Android","14","sdk_gphone64_arm64","AndroidAgent","7.4.0-alpha01","b797aee6-aa69-4879-9ba3-1f4aed1a7777","","","Google",{size:"normal",platform:"Flutter",platformVersion:"1.0.8"}]],y=["Vega","1.0","VegaDevice","VegaAgent","1.0.0","00000000-0000-0000-0000-000000000000","","","Amazon",{size:"normal",platform:"Native",platformVersion:"1.0.0"}],_={osBuild:"1",osName:"Vega",platform:"Native",appBuild:"1",architecture:"aarch64"},{COLLECTOR:B}=n;class R{setConfiguration(t,e,i){return!!("Vega"===i?this.validateVegaFields(t):this.validateRequiredFields(t))&&(!!this.validateConfigFields(e)&&(this.initializeGlobalConfig(t,e,i),r.notice("Video analytics configuration initialized successfully"),!0))}validateVegaFields(t){return t&&"object"==typeof t?t.applicationToken?t.endpoint?.toLowerCase()in p||(r.error("Invalid endpoint (must be us, eu, staging, gov, or jp)"),!1):(r.error("applicationToken is required"),!1):(r.error("Configuration must be an object"),!1)}validateRequiredFields(t){if(!t||"object"!=typeof t)return r.error("Configuration must be an object"),!1;const{licenseKey:e,appName:i,region:s,applicationID:a,beacon:n}=t;if(!e)return r.error("licenseKey is required"),!1;if(a){if(!n)return r.error("beacon is required when applicationID is provided"),!1;if(!Object.values(B).flatMap(t=>t).includes(n))return r.error(`Invalid beacon: ${n}`),!1}else{if(!i||!s)return r.error("appName and region are required when applicationID is not provided"),!1;if(!B[s])return r.error(`Invalid region: ${s}. Valid regions are: ${Object.keys(B).join(", ")}`),!1}return!0}validateConfigFields(t){if(null==t)return!0;if("object"!=typeof t||Array.isArray(t))return r.error("config must be an object"),!1;const{qoeAggregate:e,obfuscate:i}=t;return void 0!==e&&"boolean"!=typeof e?(r.error("qoeAggregate must be a boolean"),!1):!(void 0!==i&&!Array.isArray(i))||(r.error("obfuscate must be an array"),!1)}filterObfuscateRules(t){return t?t.filter(t=>{const e=void 0!==t.regex&&("string"==typeof t.regex||t.regex instanceof RegExp),i=void 0!==t.replacement&&"string"==typeof t.replacement;return!(!e||!i)||(r.warn("obfuscate rule missing required 'regex' (string|RegExp) and/or 'replacement' (string), skipping:",t),!1)}):[]}sanitizeQoeIntervalFactor(t){return null==t?n.DEFAULT_QOE_INTERVAL_FACTOR:"number"==typeof t&&Number.isInteger(t)&&t>=1?t:(r.warn(`Invalid qoeIntervalFactor "${t}" — must be a positive integer. Defaulting to ${n.DEFAULT_QOE_INTERVAL_FACTOR}.`),n.DEFAULT_QOE_INTERVAL_FACTOR)}initializeGlobalConfig(t,e,i){if("Vega"===i)return void(globalThis.__NRVIDEO_CD__={info:{accountId:t.accountId,applicationToken:t.applicationToken,endpoint:t.endpoint?.toLowerCase(),...t.appName?{appName:t.appName}:{},...t.applicationID?{applicationID:t.applicationID}:{},...t.deviceInfo?{deviceInfo:t.deviceInfo}:{}},config:{qoeAggregate:e?.qoeAggregate??!0,qoeIntervalFactor:this.sanitizeQoeIntervalFactor(e?.qoeIntervalFactor),obfuscate:this.filterObfuscateRules(e?.obfuscate)}});let{licenseKey:s,appName:r,region:a,beacon:o,applicationID:h}=t;o="US"===a?n.COLLECTOR.US[0]:o||B[a],window.NRVIDEO={info:{...a?{region:a}:{},beacon:o,licenseKey:s,applicationID:h,...h?{}:{appName:r}},config:{qoeAggregate:e?.qoeAggregate??!0,qoeIntervalFactor:this.sanitizeQoeIntervalFactor(e?.qoeIntervalFactor),obfuscate:this.filterObfuscateRules(e?.obfuscate)}}}}const b=new R;class D{static addTracker(t,e){e?.info&&function(t,e,i){b.setConfiguration(t,e,i)}(e.info,e?.config,e?.src),t.on&&t.emit?(w.push(t),t.on("*",k),"function"==typeof t.trackerInit&&t.trackerInit()):r.error("Tried to load a non-tracker.",t)}static removeTracker(t){t.off("*",k),t.dispose();let e=w.indexOf(t);-1!==e&&w.splice(e,1)}static getTrackers(){return w}static send(t,e,i){return A(t,{actionName:e,...i})}static sendError(t){return A("VideoErrorAction",{actionName:"ERROR",...t})}}let w=[];function k(t){try{let e=function(t){let e={};for(let i in t)null!==t[i]&&void 0!==t[i]&&(e[i]=t[i]);return e}(t.data);r.level<=r.Levels.DEBUG?r.notice("Sent",t.type,e):r.notice("Sent",t.type),D.send(t.eventType,t.type,e)}catch(t){r.error("Error in event handler:",t.message)}}const N=D;const C=class{constructor(){this.reset(),this._createdAt=Date.now(),this._hb=!0,this._acc=0,this._bufferAcc=0}reset(){this._viewSession=null,this._viewCount=0,this._isAd=!1,this.numberOfErrors=0,this.numberOfAds=0,this.numberOfVideos=0,this.totalPlaytime=0,this.weightedAverageBitrate=0,this.totalAdPlaytime=0,this.isAdBreak=!1,this.initialBufferingHappened=!1,this.startupTime=null,this.peakBitrate=0,this.partialAverageBitrate=0,this._totalBitrateDuration=0,this.weightedBitrate=0,this._lastBitrate=null,this._lastBitrateChangeTimestamp=null,this._downloadBitrates=[],this._lastDownloadBitrate=null,this.totalSwitchUps=0,this.totalSwitchDowns=0,this.totalPauseTime=0,this._playedRenditions=new Set,this.hadStartupError=!1,this.hadPlaybackError=!1,this.totalRebufferingTime=0,this.resetFlags(),this.resetChronos()}resetFlags(){this.isPlayerReady=!1,this.isRequested=!1,this.isStarted=!1,this.isPaused=!1,this.isSeeking=!1,this.isBuffering=!1,this.isPlaying=!1}resetChronos(){this.timeSinceRequested=new d,this.timeSinceStarted=new d,this.timeSincePaused=new d,this.timeSinceSeekBegin=new d,this.timeSinceBufferBegin=new d,this.timeSinceAdBreakStart=new d,this.timeSinceLastDownload=new d,this.timeSinceLastHeartbeat=new d,this.timeSinceLastRenditionChange=new d,this.timeSinceLastAdQuartile=new d,this.timeSinceLastAd=new d,this.timeSinceLastError=new d,this.timeSinceLastAdError=new d,this.timeSinceResumed=new d,this.timeSinceSeekEnd=new d,this.playtimeSinceLastEvent=new d,this.customTimeSinceAttributes={},this.elapsedTime=new d,this.bufferElapsedTime=new d,this._totalAdPlaytime=new d}isAd(){return this._isAd}setIsAd(t){this._isAd=t}setTimeSinceAttribute(t){this.customTimeSinceAttributes[t]=new d,this.customTimeSinceAttributes[t].start()}removeTimeSinceAttribute(t){delete this.customTimeSinceAttributes[t]}getViewSession(){if(!this._viewSession){let t=(new Date).getTime(),e=Math.random().toString(36).substring(2)+Math.random().toString(36).substring(2);this._viewSession=t+"-"+e}return this._viewSession}getViewId(){return this.getViewSession()+"-"+this._viewCount}getStateAttributes(t){t=t||{},this.isAd()?(this.isRequested&&(t.timeSinceAdRequested=this.timeSinceRequested.getDeltaTime(),t.timeSinceLastAdHeartbeat=this.timeSinceLastHeartbeat.getDeltaTime()),this.isStarted&&(t.timeSinceAdStarted=this.timeSinceStarted.getDeltaTime()),this.isPaused&&(t.timeSinceAdPaused=this.timeSincePaused.getDeltaTime()),this.isBuffering&&(t.timeSinceAdBufferBegin=this.timeSinceBufferBegin.getDeltaTime()),this.isSeeking&&(t.timeSinceAdSeekBegin=this.timeSinceSeekBegin.getDeltaTime()),this.isAdBreak&&(t.timeSinceAdBreakBegin=this.timeSinceAdBreakStart.getDeltaTime()),this.numberOfErrors>0&&this.timeSinceLastAdError.startTime>0&&(t.timeSinceLastAdError=this.timeSinceLastAdError.getDeltaTime()),t.numberOfAds=this.numberOfAds):(this.isRequested&&(t.timeSinceRequested=this.timeSinceRequested.getDeltaTime(),t.timeSinceLastHeartbeat=this.timeSinceLastHeartbeat.getDeltaTime()),this.isStarted&&(t.timeSinceStarted=this.timeSinceStarted.getDeltaTime()),this.isPaused&&(t.timeSincePaused=this.timeSincePaused.getDeltaTime()),this.isBuffering&&(t.timeSinceBufferBegin=this.timeSinceBufferBegin.getDeltaTime()),this.isSeeking&&(t.timeSinceSeekBegin=this.timeSinceSeekBegin.getDeltaTime()),t.timeSinceLastAd=this.timeSinceLastAd.getDeltaTime(),this.numberOfErrors>0&&this.timeSinceLastError.startTime>0&&(t.timeSinceLastError=this.timeSinceLastError.getDeltaTime()),t.numberOfVideos=this.numberOfVideos),t.numberOfErrors=this.numberOfErrors,this.isAd()||(this.playtimeSinceLastEvent.startTime>0?t.playtimeSinceLastEvent=this.playtimeSinceLastEvent.getDeltaTime():t.playtimeSinceLastEvent=0,this.isPlaying?this.playtimeSinceLastEvent.start():this.playtimeSinceLastEvent.reset(),this.totalPlaytime+=t.playtimeSinceLastEvent,t.totalPlaytime=this.totalPlaytime);for(const[e,i]of Object.entries(this.customTimeSinceAttributes))t[e]=i.getDeltaTime();return t}getQoeAttributes(t){t=t||{};const e={};try{if(null!==this.startupTime&&(e.startupTime=this.startupTime),this.peakBitrate>0&&(e.peakBitrate=this.peakBitrate),e.hadStartupError=this.hadStartupError,e.hadPlaybackError=this.hadPlaybackError,e.totalRebufferingTime=this.totalRebufferingTime,e.rebufferingRatio=this.totalPlaytime>0?this.totalRebufferingTime/this.totalPlaytime*100:0,e.totalPlaytime=this.totalPlaytime,e.averageBitrate=this.weightedBitrate,e.numberOfErrors=this.numberOfErrors,this._downloadBitrates.length>0){const t=this._downloadBitrates.reduce((t,e)=>t+e,0);e.avgDownloadRate=Math.round(t/this._downloadBitrates.length),e.minDownloadRate=Math.min(...this._downloadBitrates),e.maxDownloadRate=Math.max(...this._downloadBitrates)}e.totalSwitchUps=this.totalSwitchUps,e.totalSwitchDowns=this.totalSwitchDowns,e.totalPauseTime=this.timeSincePaused.getDuration(),e.totalViewSessionTime=this.totalPlaytime,e.totalRenditions=this._playedRenditions.size,e.qoeAggregateVersion="1.1.0"}catch(t){r.error("Failed to add attributes for QOE KPIs",t.message)}return t.qoe=e,t}calculateBufferType(t){let e="";return e=t?"initial":this.isSeeking?"seek":this.isPaused?"pause":"connection",r.debug("Buffer Type = "+e),e}goViewCountUp(){this._viewCount++}goPlayerReady(){return!this.isPlayerReady&&(this.isPlayerReady=!0,!0)}goRequest(){return!this.isRequested&&(this.isRequested=!0,this.timeSinceLastAd.reset(),this.timeSinceRequested.start(),!0)}goStart(){return!(!this.isRequested||this.isStarted)&&(this.isAd()?this.numberOfAds++:this.numberOfVideos++,this.isStarted=!0,this.isPlaying=!0,this.timeSinceStarted.start(),this.playtimeSinceLastEvent.start(),!0)}goEnd(){return!!this.isRequested&&(this.numberOfErrors=0,this.resetFlags(),this.timeSinceRequested.stop(),this.timeSinceStarted.stop(),this.playtimeSinceLastEvent.stop(),this.isPlaying=!1,!0)}goPause(){return!(!this.isStarted||this.isPaused)&&(this.isPaused=!0,this.isPlaying=!1,this.timeSincePaused.start(),this.playtimeSinceLastEvent.stop(),this.timeSinceResumed.reset(),this.isBuffering&&(this._bufferAcc+=this.bufferElapsedTime.getDeltaTime()),this.elapsedTime.start(),!0)}goResume(){return!(!this.isStarted||!this.isPaused)&&(this.isPaused=!1,this.isPlaying=!0,this.timeSincePaused.stop(),this.timeSinceResumed.start(),this._hb?(this._acc=this.elapsedTime.getDeltaTime(),this._hb=!1):(this.isBuffering&&this.bufferElapsedTime.start(),this._acc+=this.elapsedTime.getDeltaTime()),!0)}goBufferStart(){return!(!this.isRequested||this.isBuffering)&&(this.isBuffering=!0,this.isPlaying=!1,this.timeSinceBufferBegin.start(),this.bufferElapsedTime.start(),!0)}goBufferEnd(){return!(!this.isRequested||!this.isBuffering)&&(this.isBuffering=!1,this.isPlaying=!0,this.timeSinceBufferBegin.stop(),this._hb?(this._bufferAcc=this.bufferElapsedTime.getDeltaTime(),this._hb=!1):this._bufferAcc+=this.bufferElapsedTime.getDeltaTime(),!this.isAd()&&this.initialBufferingHappened&&(this.totalRebufferingTime+=this.timeSinceBufferBegin.stopTime-this.timeSinceBufferBegin.startTime),!0)}goSeekStart(){return!(!this.isStarted||this.isSeeking)&&(this.isSeeking=!0,this.isPlaying=!1,this.timeSinceSeekBegin.start(),this.timeSinceSeekEnd.reset(),!0)}goSeekEnd(){return!(!this.isStarted||!this.isSeeking)&&(this.isSeeking=!1,this.isPlaying=!0,this.timeSinceSeekBegin.stop(),this.timeSinceSeekEnd.start(),!0)}goAdBreakStart(){return!this.isAdBreak&&(this.isAdBreak=!0,this.timeSinceAdBreakStart.start(),!0)}goAdBreakEnd(){return!!this.isAdBreak&&(this.isRequested=!1,this.isAdBreak=!1,this.totalAdPlaytime=this.timeSinceAdBreakStart.getDeltaTime(),this.timeSinceAdBreakStart.stop(),!0)}goDownload(){this.timeSinceLastDownload.start()}goHeartbeat(){this.timeSinceLastHeartbeat.start()}goRenditionChange(){this.timeSinceLastRenditionChange.start()}goAdQuartile(){this.timeSinceLastAdQuartile.start()}goError(){this.isError=!0,this.numberOfErrors++,this.isAd()?this.timeSinceLastAdError.start():(this.timeSinceLastError.start(),this.isStarted?this.hadPlaybackError=!0:this.hadStartupError=!0)}goLastAd(){this.timeSinceLastAd.start()}trackContentBitrateState(t){if(t&&"number"==typeof t){this.peakBitrate=Math.max(this.peakBitrate,t);const e=Date.now();if(!this.isPlaying){if(null!==this._lastBitrate&&null!==this._lastBitrateChangeTimestamp){const t=e-this._lastBitrateChangeTimestamp;t>0&&(this.partialAverageBitrate+=this._lastBitrate*t,this._totalBitrateDuration+=t),this._lastBitrateChangeTimestamp=null}return void(this._lastBitrate=t)}if(null===this._lastBitrateChangeTimestamp&&null!==this._lastBitrate&&(this._lastBitrateChangeTimestamp=e),null!==this._lastBitrate&&this._lastBitrate!==t&&null!==this._lastBitrateChangeTimestamp){const t=e-this._lastBitrateChangeTimestamp;t>0&&(this.partialAverageBitrate+=this._lastBitrate*t,this._totalBitrateDuration+=t),this._lastBitrateChangeTimestamp=e}null===this._lastBitrateChangeTimestamp&&(this._lastBitrateChangeTimestamp=e),this._lastBitrate=t;let i=this.partialAverageBitrate,s=this._totalBitrateDuration;const r=e-this._lastBitrateChangeTimestamp;r>0&&(i+=t*r,s+=r),this.weightedBitrate=s>0?Math.round(i/s):t}}trackDownloadRate(t){!t||"number"!=typeof t||t<=0||t!==this._lastDownloadBitrate&&(this._downloadBitrates.push(t),this._lastDownloadBitrate=t)}addPlayedRendition(t,e){t&&e&&this._playedRenditions.add(`${t}x${e}`)}resetViewIdTrackedState(){this.peakBitrate=0,this.startupTime=null,this.partialAverageBitrate=0,this._totalBitrateDuration=0,this.weightedBitrate=0,this._lastBitrate=null,this._lastBitrateChangeTimestamp=null,this._downloadBitrates=[],this._lastDownloadBitrate=null,this.totalSwitchUps=0,this.totalSwitchDowns=0,this.timeSincePaused.reset(),this._playedRenditions=new Set}clearTotalAdsTime(){r.debug("clear total ads time",this.totalAdTime),this._totalAdPlaytime.reset()}totalAdTime(){return this._totalAdPlaytime.getDuration()}startAdsTime(){return r.debug("startAdsTime"),this._totalAdPlaytime.start()}stopAdsTime(){return r.debug("stopAdsTime"),this._totalAdPlaytime.stop()}setStartupTime(t){null===this.startupTime&&(this.startupTime=Math.max(this.timeSinceRequested.getDeltaTime()-t,0))}};class I extends u{constructor(t,e){super(),this.state=new C,this.adsTracker=null,this._lastBufferType=null,this._userId=null,this._src=null,e=e||{},this.setOptions(e),t&&this.setPlayer(t,e.tag),r.notice("Tracker "+this.getTrackerName()+" v"+this.getTrackerVersion()+" is ready.")}setUserId(t){this._userId=t}setOptions(t){t&&(t.adsTracker&&this.setAdsTracker(t.adsTracker),"boolean"==typeof t.isAd&&this.setIsAd(t.isAd),void 0!==t.src&&(null!==this._src&&this._src!==t.src?r.warn(`setOptions: src is locked to '${this._src}'. Ignoring override '${t.src}'.`):(this._src=t.src,this.adsTracker&&null==this.adsTracker._src&&(this.adsTracker._src=this._src))),u.prototype.setOptions.apply(this,arguments))}setPlayer(t,e){(this.player||this.tag)&&this.dispose(),"undefined"!=typeof document&&document.getElementById&&("string"==typeof t&&(t=document.getElementById(t)),"string"==typeof e&&(e=document.getElementById(e))),e=e||t,this.player=t,this.tag=e,this.registerListeners()}isAd(){return this.state.isAd()}setIsAd(t){this.state.setIsAd(t)}setAdsTracker(t){this.disposeAdsTracker(),t&&(this.adsTracker=t,this.adsTracker.setIsAd(!0),this.adsTracker.parentTracker=this,null!=this._src&&null==t._src&&(t._src=this._src),this.adsTracker.on("*",O.bind(this)))}disposeAdsTracker(){this.adsTracker&&(this.adsTracker.off("*",O),this.adsTracker.dispose())}dispose(){this.stopHeartbeat(),this.disposeAdsTracker(),this.unregisterListeners(),this.player=null,this.tag=null}registerListeners(){}unregisterListeners(){}getViewId(){return this.parentTracker?this.parentTracker.getViewId():this.state.getViewId()}getViewSession(){return this.parentTracker?this.parentTracker.getViewSession():this.state.getViewSession()}getVideoId(){return null}getTitle(){return null}isLive(){return null}getBitrate(){return null}getManifestBitrate(){return null}getSegmentDownloadBitrate(){return null}getNetworkDownloadBitrate(){return null}getWebkitBitrate(){if(this.tag&&this.tag.webkitVideoDecodedByteCount){let t;if(this._lastWebkitBitrate){t=this.tag.webkitVideoDecodedByteCount;let e=t-this._lastWebkitBitrate,i=this.getHeartbeat()/1e3;t=Math.round(e/i*8)}return this._lastWebkitBitrate=this.tag.webkitVideoDecodedByteCount,t||null}}getRenditionName(){return null}getRenditionBitrate(){return null}getRenditionShift(t){let e,i=this.getManifestBitrate();return this.isAd()?(e=this._lastAdRendition,t&&(this._lastAdRendition=i)):(e=this._lastRendition,t&&(this._lastRendition=i)),i&&e?i>e?"up":i<e?"down":null:null}getRenditionHeight(){return this.tag?this.tag.videoHeight:null}getRenditionWidth(){return this.tag?this.tag.videoWidth:null}getDuration(){return this.tag?this.tag.duration:null}getPlayhead(){return this.tag?this.tag.currentTime:null}getLanguage(){return null}getSrc(){return this.tag?this.tag.currentSrc:null}getPlayrate(){return this.tag?this.tag.playbackRate:null}isMuted(){return this.tag?this.tag.muted:null}isFullscreen(){return null}getCdn(){return null}getPlayerName(){return this.getTrackerName()}getPlayerVersion(){return o}getFps(){return null}isAutoplayed(){return this.tag?this.tag.autoplay:null}getPreload(){return this.tag?this.tag.preload:null}getAdQuartile(){return null}getAdPosition(){return this.parentTracker?this.parentTracker.state.isStarted?"mid":"pre":null}getAdPartner(){return null}getAdCreativeId(){return null}getInstrumentationProvider(){return null}getInstrumentationName(){return null}getInstrumentationVersion(){return null}getAttributes(t,e){if(void 0===(t=u.prototype.getAttributes.apply(this,arguments)).isAd&&(t.isAd=this.isAd()),t.viewSession=this.getViewSession(),t.viewId=this.getViewId(),t.playerName=this.getPlayerName(),t.playerVersion=this.getPlayerVersion(),t["instrumentation.provider"]=this.getInstrumentationProvider(),t["instrumentation.name"]=this.getInstrumentationName(),t["instrumentation.version"]=this.getInstrumentationVersion(),t["enduser.id"]=this._userId,t.src=this._src||"Browser","customAction"===e)return t;try{t.pageUrl=window.location.href}catch(t){}this.isAd()?(t.adId=this.getVideoId(),t.adTitle=this.getTitle(),t.adSrc=this.getSrc(),t.adCdn=this.getCdn(),this.state.isStarted&&(t.adBitrate=this.getBitrate()||0),t.adRenditionName=this.getRenditionName(),t.adRenditionHeight=this.getRenditionHeight(),t.adRenditionWidth=this.getRenditionWidth(),t.adDuration=this.getDuration(),t.adPlayhead=this.getPlayhead(),t.adLanguage=this.getLanguage(),t.adIsMuted=this.isMuted(),t.adFps=this.getFps(),t.adPosition=this.getAdPosition(),t.adCreativeId=this.getAdCreativeId(),t.adPartner=this.getAdPartner()):(t.contentId=this.getVideoId(),t.contentTitle=this.getTitle(),t.contentSrc=this.getSrc(),t.contentCdn=this.getCdn(),t.contentPlayhead=this.getPlayhead(),t.contentIsLive=this.isLive(),this.state.isStarted&&(t.contentBitrate=this.getBitrate()||0,t.contentManifestBitrate=this.getManifestBitrate()||0,t.contentSegmentDownloadBitrate=this.getSegmentDownloadBitrate()||0,t.contentNetworkDownloadBitrate=this.getNetworkDownloadBitrate()||0),t.contentRenditionName=this.getRenditionName(),t.contentRenditionHeight=this.getRenditionHeight(),t.contentRenditionWidth=this.getRenditionWidth(),t.contentDuration=this.getDuration(),t.contentLanguage=this.getLanguage(),t.contentPlayrate=this.getPlayrate(),t.contentIsFullscreen=this.isFullscreen(),t.contentIsMuted=this.isMuted(),t.contentIsAutoplayed=this.isAutoplayed(),t.contentPreload=this.getPreload(),t.contentFps=this.getFps(),null!=this.adsTracker&&this.adsTracker.state.totalAdPlaytime>0&&(t.totalAdPlaytime=this.adsTracker.state.totalAdPlaytime)),this.state.getStateAttributes(t),this.state.isStarted&&!this.isAd()&&(this.state.trackContentBitrateState(t.contentBitrate),this.state.trackDownloadRate(t.contentNetworkDownloadBitrate),this.state.addPlayedRendition(t.contentRenditionHeight,t.contentRenditionWidth));for(let e in this.customData)t[e]=this.customData[e];if(!this.isAd()){this.state.getQoeAttributes(t);const e=t.qoe;for(let t in this.customData)e[t]=this.customData[t]}return t}sendCustom(t,e,i){i=i||{},this.sendVideoCustomAction(t,i),this.state.setTimeSinceAttribute(e)}sendPlayerReady(t){this.state.goPlayerReady()&&(t=t||{},this.sendVideoAction(I.Events.PLAYER_READY,t))}sendRequest(t){if(this.state.goRequest()){let e;this.isAd()?(e=I.Events.AD_REQUEST,this.sendVideoAdAction(e,t)):(e=I.Events.CONTENT_REQUEST,this.sendVideoAction(e,t))}}sendStart(t){if(this.state.goStart()){let e;if(this.isAd())e=I.Events.AD_START,this.parentTracker&&(this.parentTracker.state.isPlaying=!1),this.sendVideoAdAction(e,t),this.state.startAdsTime();else{e=I.Events.CONTENT_START;let i=0;this.adsTracker&&((this.adsTracker.state.isPlaying||this.adsTracker.state.isBuffering)&&(this.adsTracker.state.stopAdsTime(),this.adsTracker.state.isPlaying=!1,this.adsTracker.state.isBuffering=!1),i=this.adsTracker.state.totalAdTime()??0),this.state.setStartupTime(i),this.sendVideoAction(e,t);const s=this.getHarvester?.();s?.setBeforeDrainCallback(()=>{if(this.state){const t=this.state.getQoeAttributes({}).qoe;s.refreshQoeKpis(t,this.getViewId())}})}this.startHeartbeat(),this.state.goHeartbeat()}}sendEnd(t){if(this.state.goEnd()){let e;if(t=t||{},this.isAd()?(e=I.Events.AD_END,t.timeSinceAdRequested=this.state.timeSinceRequested.getDeltaTime(),t.timeSinceAdStarted=this.state.timeSinceStarted.getDeltaTime(),this.parentTracker&&(this.parentTracker.state.isPlaying=!0,this.parentTracker.state.timeSincePaused.reset()),this.state.stopAdsTime()):(e=I.Events.CONTENT_END,t.timeSinceRequested=this.state.timeSinceRequested.getDeltaTime(),t.timeSinceStarted=this.state.timeSinceStarted.getDeltaTime()),this.stopHeartbeat(),this.isAd()?this.sendVideoAdAction(e,t):this.sendVideoAction(e,t),this.parentTracker&&this.isAd()&&this.parentTracker.state.goLastAd(),this.state.goViewCountUp(),this.state.totalPlaytime=0,!this.isAd()){const t=this.getHarvester?.();t?.forceNextQoeCycle?.(),t?.setBeforeDrainCallback?.(null),this.adsTracker&&this.adsTracker.state.clearTotalAdsTime(),this.state.resetViewIdTrackedState()}}}sendPause(t){if(this.state.goPause()){let e=this.isAd()?I.Events.AD_PAUSE:I.Events.CONTENT_PAUSE;this.isAd()?this.sendVideoAdAction(e,t):this.sendVideoAction(e,t)}}sendResume(t){if(this.state.goResume()){let e;t=t||{},this.isAd()?(e=I.Events.AD_RESUME,t.timeSinceAdPaused=this.state.timeSincePaused.getDeltaTime()):(e=I.Events.CONTENT_RESUME,t.timeSincePaused=this.state.timeSincePaused.getDeltaTime()),this.isAd()?this.sendVideoAdAction(e,t):this.sendVideoAction(e,t)}}sendBufferStart(t){if(this.state.goBufferStart()){let e;t=t||{},e=this.isAd()?I.Events.AD_BUFFER_START:I.Events.CONTENT_BUFFER_START,t=this.buildBufferAttributes(t),this._lastBufferType=t.bufferType,this.isAd()?this.sendVideoAdAction(e,t):this.sendVideoAction(e,t)}}sendBufferEnd(t){if(this.state.goBufferEnd()){let e;t=t||{},this.isAd()?(e=I.Events.AD_BUFFER_END,t.timeSinceAdBufferBegin=this.state.timeSinceBufferBegin.getDeltaTime()):(e=I.Events.CONTENT_BUFFER_END,t.timeSinceBufferBegin=this.state.timeSinceBufferBegin.getDeltaTime()),t=this.buildBufferAttributes(t),null!=this._lastBufferType&&(t.bufferType=this._lastBufferType),this.isAd()?this.sendVideoAdAction(e,t):this.sendVideoAction(e,t),this.state.initialBufferingHappened=!0}}buildBufferAttributes(t){return null==t.timeSinceStarted||t.timeSinceStarted<100?t.isInitialBuffering=!this.state.initialBufferingHappened:t.isInitialBuffering=!1,t.bufferType=this.state.calculateBufferType(t.isInitialBuffering),t.timeSinceResumed=this.state.timeSinceResumed.getDeltaTime(),t.timeSinceSeekEnd=this.state.timeSinceSeekEnd.getDeltaTime(),t}sendSeekStart(t){if(this.state.goSeekStart()){let e;e=this.isAd()?I.Events.AD_SEEK_START:I.Events.CONTENT_SEEK_START,this.isAd()?this.sendVideoAdAction(e,t):this.sendVideoAction(e,t)}}sendSeekEnd(t){if(this.state.goSeekEnd()){let e;t=t||{},this.isAd()?(e=I.Events.AD_SEEK_END,t.timeSinceAdSeekBegin=this.state.timeSinceSeekBegin.getDeltaTime()):(e=I.Events.CONTENT_SEEK_END,t.timeSinceSeekBegin=this.state.timeSinceSeekBegin.getDeltaTime()),this.isAd()?this.sendVideoAdAction(e,t):this.sendVideoAction(e,t)}}sendDownload(t){(t=t||{}).state||r.warn("Called sendDownload without { state: xxxxx }."),this.sendVideoAction(I.Events.DOWNLOAD,t),this.state.goDownload()}sendError(t){(t=t||{}).isAd=this.isAd(),this.state.goError();let e=this.isAd()?I.Events.AD_ERROR:I.Events.CONTENT_ERROR;this.sendVideoErrorAction(e,t)}sendRenditionChanged(t){(t=t||{}).timeSinceLastRenditionChange=this.state.timeSinceLastRenditionChange.getDeltaTime();const{oldBitrate:e,newBitrate:i}=t;let s;this.isAd()||void 0===e||void 0===i||(i>e?(t.shift="up",this.state.totalSwitchUps+=1):i<e?(t.shift="down",this.state.totalSwitchDowns+=1):t.shift=null),delete t.oldBitrate,delete t.newBitrate,s=this.isAd()?I.Events.AD_RENDITION_CHANGE:I.Events.CONTENT_RENDITION_CHANGE,this.isAd()?this.sendVideoAdAction(s,t):this.sendVideoAction(s,t),this.state.goRenditionChange()}sendHeartbeat(t){if(this.state.isRequested){let e,i=this.getHeartbeat();this.state._hb=!0,i=this.adjustElapsedTimeForPause(i),this.isAd()?(e=I.Events.AD_HEARTBEAT,"bitmovin-ads"===this.getPlayerName()?this.sendVideoAdAction(e,t):this.sendVideoAdAction(e,{elapsedTime:i,...t})):(e=I.Events.CONTENT_HEARTBEAT,this.sendVideoAction(e,{elapsedTime:i,...t})),this.state.goHeartbeat()}}adjustElapsedTimeForPause(t){return this.state._acc&&(t-=this.state._acc,this.state._acc=0),this.state.isPaused&&((t-=this.state.elapsedTime.getDeltaTime())<10&&(t=0),this.state.elapsedTime.start()),this.state._bufferAcc?(t-=this.state._bufferAcc,this.state._bufferAcc=0):this.state.isBuffering&&((t-=this.state.bufferElapsedTime.getDeltaTime())<5&&(t=0),this.state.bufferElapsedTime.start()),Math.max(0,t)}sendAdBreakStart(t){this.isAd()&&this.state.goAdBreakStart()&&(this.state.totalAdPlaytime=0,this.parentTracker&&(this.parentTracker.state.isPlaying=!1),this.sendVideoAdAction(I.Events.AD_BREAK_START,t))}sendAdBreakEnd(t){this.isAd()&&this.state.goAdBreakEnd()&&((t=t||{}).timeSinceAdBreakBegin=this.state.timeSinceAdBreakStart.getDeltaTime(),this.sendVideoAdAction(I.Events.AD_BREAK_END,t),this.parentTracker&&(this.parentTracker.state.isPlaying=!0),this.stopHeartbeat(),this.parentTracker&&this.isAd()&&this.parentTracker.state.goLastAd())}sendAdQuartile(t){this.isAd()&&((t=t||{}).quartile||r.warn("Called sendAdQuartile without { quartile: xxxxx }."),t.timeSinceLastAdQuartile=this.state.timeSinceLastAdQuartile.getDeltaTime(),this.sendVideoAdAction(I.Events.AD_QUARTILE,t),this.state.goAdQuartile())}sendAdClick(t){this.isAd()&&((t=t||{}).url||r.warn("Called sendAdClick without { url: xxxxx }."),this.sendVideoAdAction(I.Events.AD_CLICK,t))}}function O(t){t.type!==I.Events.AD_ERROR?this.sendVideoAdAction(t.type,t.data):this.sendVideoErrorAction(t.type,t.data)}I.Events={PLAYER_READY:"PLAYER_READY",DOWNLOAD:"DOWNLOAD",ERROR:"ERROR",CONTENT_REQUEST:"CONTENT_REQUEST",CONTENT_START:"CONTENT_START",CONTENT_END:"CONTENT_END",CONTENT_PAUSE:"CONTENT_PAUSE",CONTENT_RESUME:"CONTENT_RESUME",CONTENT_SEEK_START:"CONTENT_SEEK_START",CONTENT_SEEK_END:"CONTENT_SEEK_END",CONTENT_BUFFER_START:"CONTENT_BUFFER_START",CONTENT_BUFFER_END:"CONTENT_BUFFER_END",CONTENT_HEARTBEAT:"CONTENT_HEARTBEAT",CONTENT_RENDITION_CHANGE:"CONTENT_RENDITION_CHANGE",CONTENT_ERROR:"CONTENT_ERROR",AD_REQUEST:"AD_REQUEST",AD_START:"AD_START",AD_END:"AD_END",AD_PAUSE:"AD_PAUSE",AD_RESUME:"AD_RESUME",AD_SEEK_START:"AD_SEEK_START",AD_SEEK_END:"AD_SEEK_END",AD_BUFFER_START:"AD_BUFFER_START",AD_BUFFER_END:"AD_BUFFER_END",AD_HEARTBEAT:"AD_HEARTBEAT",AD_RENDITION_CHANGE:"AD_RENDITION_CHANGE",AD_ERROR:"AD_ERROR",AD_BREAK_START:"AD_BREAK_START",AD_BREAK_END:"AD_BREAK_END",AD_QUARTILE:"AD_QUARTILE",AD_CLICK:"AD_CLICK"};const P=I,{MAX_PAYLOAD_SIZE:V,MAX_EVENTS_PER_BATCH:H}=n;class L{constructor(){this.buffer=[],this.maxPayloadSize=V,this.maxEventsPerBatch=H,this.currentPayloadSize=0,this.totalEvents=0,this.smartHarvestPayloadThreshold=Math.floor(.6*this.maxPayloadSize),this.overflowPayloadThreshold=Math.floor(.9*this.maxPayloadSize),this.smartHarvestEventThreshold=Math.floor(.6*this.maxEventsPerBatch),this.overflowEventThreshold=Math.floor(.9*this.maxEventsPerBatch),this.onSmartHarvestTrigger=null}addOrReplaceByActionName(t,e){const i=this.buffer.findIndex(e=>e.actionName===t);try{return-1===i?this.add(e):this.add(e,i),!0}catch(t){return r.error("Failed to set or replace the event to buffer:",t.message),!1}}addOrReplaceByActionNameAndViewId(t,e,i){const s=this.buffer.findIndex(i=>i.actionName===t&&i.viewId===e);try{return-1===s?this.add(i):this.add(i,s),!0}catch(t){return r.error("Failed to set or replace the event to buffer:",t.message),!1}}findByActionNameAndViewId(t,e){return this.buffer.find(i=>i.actionName===t&&i.viewId===e)||null}findByActionName(t){return this.buffer.find(e=>e.actionName===t)||null}add(t,e){try{const i=g(t),s=this.currentPayloadSize+i>=this.maxPayloadSize,r=this.totalEvents+1>=this.maxEventsPerBatch;if((s||r)&&this.makeRoom(i),null!=e&&e>-1){const s=g(this.buffer[e]);this.buffer[e]=t,this.currentPayloadSize+=i-s}else this.buffer.push(t),this.totalEvents++,this.currentPayloadSize+=i;return this.checkSmartHarvestTrigger(),!0}catch(t){return r.error("Failed to add event to buffer:",t.message),!1}}checkSmartHarvestTrigger(){const t=this.currentPayloadSize/this.maxPayloadSize,e=this.totalEvents/this.maxEventsPerBatch,i=this.currentPayloadSize>=this.overflowPayloadThreshold,s=this.totalEvents>=this.overflowEventThreshold;if(i||s){const s=i?`payload ${this.currentPayloadSize}/${this.maxPayloadSize} bytes (${Math.round(100*t)}%)`:`events ${this.totalEvents}/${this.maxEventsPerBatch} (${Math.round(100*e)}%)`;r.warn(`OVERFLOW PREVENTION: ${s} - Emergency harvest triggered`),this.onSmartHarvestTrigger&&"function"==typeof this.onSmartHarvestTrigger&&this.onSmartHarvestTrigger("overflow",90)}else{const t=this.currentPayloadSize>=this.smartHarvestPayloadThreshold,e=this.totalEvents>=this.smartHarvestEventThreshold;(t||e)&&this.onSmartHarvestTrigger&&"function"==typeof this.onSmartHarvestTrigger&&this.onSmartHarvestTrigger("smart",60)}}setSmartHarvestCallback(t){this.onSmartHarvestTrigger=t}drain(){try{const t=this.buffer.splice(0);return this.totalEvents=0,this.currentPayloadSize=0,t}catch(t){return r.error("Failed to drain events from buffer:",t.message),[]}}isEmpty(){return 0===this.totalEvents}size(){return this.totalEvents}clear(){this.buffer=[],this.totalEvents=0}makeRoom(t){if(t>this.maxPayloadSize)r.error("Event dropped: Event size exceeds maximum payload size.");else for(;(this.totalEvents>=this.maxEventsPerBatch||this.currentPayloadSize+t>=this.maxPayloadSize)&&this.buffer.length>0;){const t=g(this.buffer.shift());this.totalEvents--,this.currentPayloadSize-=t,r.warn("Event buffer full, oldest event removed.")}}}const{MAX_PAYLOAD_SIZE:Q,MAX_EVENTS_PER_BATCH:x}=n;class F{constructor(){this.retryQueue=[],this.maxQueueSize=x,this.maxQueueSizeBytes=Q}addFailedEvents(t){try{const e=Array.isArray(t)?t:[t];r.notice(`Adding ${e.length} failed events to retry queue`,{queueSizeBefore:this.retryQueue.length});for(const t of e){this.retryQueue.length>=this.maxQueueSize&&this.evictOldestEvent();const e=g(t);for(;g(this.retryQueue)+e>this.maxQueueSizeBytes;)this.evictOldestEvent();this.retryQueue.push({...t})}}catch(t){r.error("Failed to add events to retry queue:",t.message)}}discardEvent(t,e){r.warn("Discarded event",{reason:e,eventType:t.eventType})}evictOldestEvent(){if(this.retryQueue.length>0){const t=this.retryQueue.shift();this.discardEvent(t,"Queue full - evicted oldest")}}getRetryEventsToFit(t,e){const i=[];let s=0,r=0;for(let a=this.retryQueue.length-1;a>=0;a--){const n=this.retryQueue[a];if(r>=e)break;const o=g(n);if(s+o>t)break;i.unshift(n),s+=o,r++,this.retryQueue.splice(a,1)}return i}getQueueSize(){return this.retryQueue.length}clear(){this.retryQueue=[]}}function q(t,e){return e&&0!==e.length?e.reduce((t,e)=>{let i;try{if(e.regex instanceof RegExp){const t=e.regex.flags.includes("g")?e.regex.flags:e.regex.flags+"g";i=new RegExp(e.regex.source,t)}else i=new RegExp(e.regex,"g")}catch(i){return r.warn("applyObfuscationRules: invalid regex, skipping rule:",e.regex,i.message),t}return t.replace(i,e.replacement)},t):t}class z{async send(t,e){const{url:i,payload:s,options:a={}}=t;try{if(!i||!s)throw new Error("URL and payload are required");const t={url:i,payload:s,options:a,callback:e};await this.executeRequest(t)}catch(t){r.error("Failed to send request:",t.message),e({retry:!1,status:0,error:t.message})}}async executeRequest(t){const{url:e,payload:i,options:s,callback:r}=t,a=Date.now();try{const r=q(JSON.stringify(i.body),window.NRVIDEO?.config?.obfuscate);if(s.isFinalHarvest&&navigator.sendBeacon){const i=await this.sendWithBeacon(e,r),s={success:i,status:i?204:0};return void this.handleRequestComplete(t,s,a)}const n=await this.fetchWithTimeout(e,{method:"POST",body:r,headers:{"Content-Type":"application/json"},keepalive:s.isFinalHarvest},1e4),o={success:n.ok,status:n.status,statusText:n.statusText};this.handleRequestComplete(t,o,a)}catch(e){const i={success:!1,status:0,error:e.message};this.handleRequestComplete(t,i,a)}}handleRequestComplete(t,e){const{callback:i}=t;i({retry:!e.success&&(0===e.status||function(t){switch(t){case 408:case 429:case 500:return!0;case 401:case 403:case 404:return!1}return t>=502&&t<=504||t>=512&&t<=530}(e.status)),status:e.status,error:e.error})}async sendWithBeacon(t,e){try{return navigator.sendBeacon(t,e)}catch(t){return r.warn("sendBeacon failed, falling back to fetch:",t.message),!1}}async fetchWithTimeout(t,e,i){const s=new AbortController,r=setTimeout(()=>s.abort(),i);try{const i=await fetch(t,{...e,signal:s.signal});return clearTimeout(r),i}catch(t){if(clearTimeout(r),"AbortError"===t.name)throw new Error(`Request timeout after ${i}ms`);throw t}}}function U(t,e){return!!e&&(e.actionName===u.Events.QOE_AGGREGATE?e.viewId?t.addOrReplaceByActionNameAndViewId(u.Events.QOE_AGGREGATE,e.viewId,e):t.addOrReplaceByActionName(u.Events.QOE_AGGREGATE,e):t.add(e))}function G(t,e,i){if(!t||!e)return;const s=i?t.findByActionNameAndViewId(u.Events.QOE_AGGREGATE,i):t.findByActionName(u.Events.QOE_AGGREGATE);if(!s)return;const r={...s};for(const t of n.QOE_KPI_KEYS)t in e&&(r[t]=e[t]);i?t.addOrReplaceByActionNameAndViewId(u.Events.QOE_AGGREGATE,i,r):t.addOrReplaceByActionName(u.Events.QOE_AGGREGATE,r)}function M(t,e){const i=t[e.viewId];if(!i)return!1;for(const t of n.QOE_KPI_KEYS)if(e[t]!==i[t])return!1;return!0}function K(t,e){const i={};for(const t of n.QOE_KPI_KEYS)i[t]=e[t];t[e.viewId]=i}function $(t,e,i){if(e)return t;const s=[];for(const e of t)e.actionName===u.Events.QOE_AGGREGATE?i.add(e):s.push(e);return s}function j(t,e,i){for(let s=t.length-1;s>=0;s--){const r=t[s];r.actionName===u.Events.QOE_AGGREGATE&&(!i&&M(e,r)?t.splice(s,1):K(e,r))}}function W({interval:t,onTick:e,errorLabel:i}){let s=!1,a=null,n=t;function o(){s&&(a=setTimeout(async()=>{a=null;try{await e()}catch(t){r.error(`${i}: scheduled tick failed:`,t.message)}finally{s&&o()}},n))}return{start(){s||(s=!0,o())},stop(){s=!1,a&&(clearTimeout(a),a=null)},cancelAndReschedule(){a&&(clearTimeout(a),a=null),s&&o()},updateInterval(t){"number"!=typeof t||t<=0||(n=t,s&&a&&(clearTimeout(a),a=null,o()))},isRunning:()=>s}}class Y{constructor(t){this.eventBuffer=t,this.retryQueueHandler=new F,this.httpClient=new z,this.fallBackUrl="",this.retryCount=0,this.eventBuffer instanceof L&&this.eventBuffer.setSmartHarvestCallback((t,e)=>this.triggerSmartHarvest(t,e)),this.harvestCycle=n.INTERVAL,this.isHarvesting=!1,this.qoeCycleCount=1,this.forceNextQoeCycle=!1,this.beforeDrainCallback=null,this._lastSentQoeKpis={},this.timer=W({interval:this.harvestCycle,onTick:()=>this.onHarvestInterval(),errorLabel:"HarvestScheduler"}),this.setupPageLifecycleHandlers()}get isStarted(){return this.timer.isRunning()}startScheduler(){this.timer.isRunning()?r.warn("Harvest scheduler is already started"):(r.notice("Starting harvest scheduler",{harvestCycle:this.harvestCycle,eventBufferSize:this.eventBuffer?this.eventBuffer.size():0}),this.timer.start())}stopScheduler(){this.timer.isRunning()&&(this.timer.stop(),r.notice("Harvest scheduler stopped"))}async triggerSmartHarvest(t,e){if(r.notice(`${t} harvest triggered at ${e}% threshold`,{type:t,threshold:e}),this.eventBuffer&&!this.eventBuffer.isEmpty())try{await this.triggerHarvest({})}catch(e){r.error(`${t} harvest failed:`,e.message)}finally{this.timer.cancelAndReschedule()}}async onHarvestInterval(){const t=this.eventBuffer&&!this.eventBuffer.isEmpty(),e=this.retryQueueHandler&&this.retryQueueHandler.getQueueSize()>0;(t||e)&&await this.triggerHarvest({})}async triggerHarvest(t={}){if(this.isHarvesting)return{success:!1,reason:"harvest_in_progress"};this.isHarvesting=!0;try{let e=this.drainEvents(t);if(t.isFinalHarvest){const t=n.MAX_BEACON_SIZE;g(e)>t&&(e=this.trimEventsToFit(e,t))}const i=await this.sendChunk(e,t,!0);return{success:i.success,totalChunks:1,results:[i]}}catch(t){return r.error("Harvest cycle failed:",t.message),this.handleHarvestFailure(t),{success:!1,error:t.message}}finally{this.isHarvesting=!1}}trimEventsToFit(t,e){if(0===t.length)return t;const i=[];let s=0;for(let r=t.length-1;r>=0;r--){const a=t[r],n=g({ins:[a,...i]});n>e||(i.unshift(a),s=n)}const a=t.length-i.length;if(a>0){const n=t.slice(0,a);r.warn(`Discarded ${a} events to fit beacon size limit`,{originalCount:t.length,trimmedCount:i.length,finalSize:s,maxSize:e}),this.retryQueueHandler&&this.retryQueueHandler.addFailedEvents(n)}return i}drainEvents(t={}){const e=window.NRVIDEO?.config?.qoeIntervalFactor??1,i=!!t.isFinalHarvest||this.forceNextQoeCycle,s=(this.qoeCycleCount-1)%e==0||i;if(this.forceNextQoeCycle&&(this.forceNextQoeCycle=!1),this.beforeDrainCallback&&"function"==typeof this.beforeDrainCallback)try{this.beforeDrainCallback()}catch(t){r.error("Before drain callback failed:",t.message)}let a=$(this.eventBuffer.drain(),s,this.eventBuffer);this.qoeCycleCount++,j(a,this._lastSentQoeKpis,i);let o=[...a],h=g(a);if(this.retryQueueHandler&&this.retryQueueHandler.getQueueSize()>0){const t=n.MAX_PAYLOAD_SIZE-h,e=n.MAX_EVENTS_PER_BATCH-o.length;if(t>0&&e>0){const i=this.retryQueueHandler.getRetryEventsToFit(t,e);i.length>0&&(o=[...i,...o])}}return o}async sendChunk(t,e,i){const s={url:function(t){try{if(!window.NRVIDEO||!window.NRVIDEO.info)throw new Error("NRVIDEO info is not available.");let{beacon:e,licenseKey:i,applicationID:s}=window.NRVIDEO.info;if(!e||!i)throw new Error("Options object provided by New Relic is not correctly initialized");return s?`https://${t||e}/ins/1/${i}?a=${s}&v=${o}&ref=${window.location.href}&ca=VA`:`https://${t||e}/ins/1/${i}?&v=${o}&ref=${window.location.href}&ca=VA`}catch(t){return console.error(t.message),null}}(this.fallBackUrl),payload:{body:{ins:t}},options:{...e,isLastChunk:i}};return new Promise(e=>{this.httpClient.send(s,i=>{i.retry?this.handleRequestFailure(t):(this.retryCount=0,this.fallBackUrl=""),e({success:!i.retry,status:i.status,error:i.error,chunk:t,eventCount:t.length})})})}handleRequestFailure(t){this.retryQueueHandler.addFailedEvents(t),"US"===window.NRVIDEO?.info?.region&&(this.retryCount++,this.retryCount>5?(this.retryCount=0,this.fallBackUrl=""):this.retryCount>=2&&(this.fallBackUrl=n.COLLECTOR.US[1]))}handleHarvestFailure(t){r.warn("Harvest failure handled",{error:t.message})}updateHarvestInterval(t){"number"!=typeof t||isNaN(t)?r.warn("Invalid newInterval provided to updateHarvestInterval"):t<1e3||t>3e5?r.warn("newInterval out of bounds (1000-300000), ignoring"):this.harvestCycle!==t&&(this.harvestCycle=t,r.notice("Updated harvestCycle:",this.harvestCycle),this.timer.updateInterval(t))}setupPageLifecycleHandlers(){let t=!1;const e=()=>{t||(t=!0,this.triggerHarvest({isFinalHarvest:!0,force:!0}))};document.addEventListener("visibilitychange",()=>{document.hidden&&e()}),window.addEventListener("pagehide",()=>{e()}),window.addEventListener("beforeunload",()=>{e()})}}const X=new class{constructor(){this.isInitialized=!1,this.harvestScheduler=null,this.eventBuffer=null}initialize(){if(this.isInitialized)r.warn("Video analytics agent already initialized");else try{this.eventBuffer=new L,this.harvestScheduler=new Y(this.eventBuffer),this.harvestScheduler.startScheduler(),this.isInitialized=!0,r.notice("Video analytics agent initialized successfully")}catch(t){r.error("Failed to initialize video analytics agent:",t.message)}}addEvent(t){this.isInitialized||(r.warn("Video analytics agent not initialized, initializing now"),this.initialize());try{return U(this.eventBuffer,t)}catch(t){return r.error("Failed to add event to harvesting system:",t.message),!1}}setHarvestInterval(t){this.isInitialized||this.initialize(),this.harvestScheduler.updateHarvestInterval(t)}forceNextQoeCycle(){this.harvestScheduler&&(this.harvestScheduler.forceNextQoeCycle=!0)}setBeforeDrainCallback(t){this.harvestScheduler&&(this.harvestScheduler.beforeDrainCallback=t)}refreshQoeKpis(t,e){G(this.eventBuffer,t,e)}};T("Browser",X);const Z=X;class J{constructor({accountId:t,applicationToken:e,endpoint:i,deviceInfo:s}={}){if(!e)throw new Error("applicationToken is required");const a=i?.toLowerCase();if(!(a in p))throw new Error("Invalid endpoint");this.accountId=t,this.applicationToken=e,this.endpoint=a,this.harvestInterval=6e4,this.maxBufferSize=100,s||r.warn("ConnectedDeviceHarvester: no deviceInfo provided — using placeholder defaults. Pass info.deviceInfo for accurate device data.");const{uuid:n,osVersion:o,deviceModel:h,deviceManufacturer:l,osBuild:d,appBuild:c,architecture:u}=s??{};this.deviceInfo={uuid:n||y[5],osVersion:o||y[1],deviceModel:h||y[2],deviceManufacturer:l||y[8],osBuild:d||_.osBuild,appBuild:c||_.appBuild,architecture:u||_.architecture},this.eventBuffer=new L,this.eventBuffer.setSmartHarvestCallback((t,e)=>this.triggerSmartHarvest(t,e)),this.dataToken=null,this.isHarvesting=!1,this.isDisposed=!1,this._isFetchingToken=!1,this.timer=W({interval:this.harvestInterval,onTick:()=>this.sendBufferedEvents(),errorLabel:"ConnectedDeviceHarvester"}),this.qoeCycleCount=1,this.forceQoeNextCycle=!1,this.beforeDrainCallback=null,this._lastSentQoeKpis={},this._connectAttempt=0,this.initialise()}getEndpointBaseUrl(){return p[this.endpoint]??p.us}async initialise(){await this.fetchDataTokens(),this.isDisposed||this.dataToken&&this.startHarvestInterval()}async fetchDataTokens(){if(!this._isFetchingToken){this._isFetchingToken=!0;try{for(let t=0;t<3;t++){if(this.isDisposed)return;const e=`${this.getEndpointBaseUrl()}/v5/connect`;try{r.notice(`ConnectedDeviceHarvester: POST ${e} (attempt ${t+1}/3)`);const i=await this._fetchWithTimeout(e,{method:"POST",headers:{"Content-Type":"application/json","X-App-License-Key":this.applicationToken},body:JSON.stringify(S)},1e4);if(!i.ok){let t="";try{t=await i.text()}catch(t){}throw new Error(`HTTP ${i.status} body=${t}`)}const s=await i.json();if(!s||!s.data_token)throw new Error("Missing data_token in connect response");return this.dataToken=s.data_token,this._connectAttempt=t+1,void r.notice("ConnectedDeviceHarvester: dataToken acquired")}catch(e){if(this._connectAttempt=t+1,r.error(`ConnectedDeviceHarvester: /v5/connect failed (attempt ${this._connectAttempt}/3):`,e.message),t>=2)return void r.error("ConnectedDeviceHarvester: Max retries reached — dataToken stays null");await new Promise(t=>setTimeout(t,1e4))}}}finally{this._isFetchingToken=!1}}}startHarvestInterval(){this.isDisposed||this.timer.start()}async triggerSmartHarvest(t,e){if(r.notice(`ConnectedDeviceHarvester: smart-harvest trigger (${t} at ${e}%)`),this.eventBuffer&&!this.eventBuffer.isEmpty())try{await this.sendBufferedEvents()}catch(e){r.error(`${t} smart-harvest failed:`,e.message)}finally{this.timer.cancelAndReschedule()}}addEvent(t){try{return U(this.eventBuffer,t)}catch(t){return r.error("ConnectedDeviceHarvester.addEvent failed:",t.message),!1}}forceQoeNextHarvest(){this.forceQoeNextCycle=!0}setBeforeDrainCallback(t){"function"!=typeof t&&null!==t||(this.beforeDrainCallback=t)}refreshQoeKpis(t,e){G(this.eventBuffer,t,e)}setHarvestInterval(t){"number"!=typeof t||t<=0||(this.harvestInterval=t,this.timer.updateInterval(t))}async sendBufferedEvents(){if(this.isHarvesting)return;if(!this.dataToken)return;if(this.eventBuffer.isEmpty())return;if("function"==typeof this.beforeDrainCallback)try{this.beforeDrainCallback()}catch(t){r.error("ConnectedDeviceHarvester beforeDrainCallback failed:",t.message)}this.isHarvesting=!0;const t=this.eventBuffer.drain(),e=globalThis.__NRVIDEO_CD__?.config?.qoeIntervalFactor??1,i=this.forceQoeNextCycle,s=(this.qoeCycleCount-1)%e==0||i;this.forceQoeNextCycle&&(this.forceQoeNextCycle=!1);const a=$(t,s,this.eventBuffer);if(this.qoeCycleCount++,j(a,this._lastSentQoeKpis,i),0===a.length)return void(this.isHarvesting=!1);const n=`${this.getEndpointBaseUrl()}/v3/data`,o={"Content-Type":"application/json","X-App-License-Key":this.applicationToken},h=()=>q(JSON.stringify([this.dataToken,this._buildDeviceInfo(),0,[],[],[],[],[],this._buildMetadata(),a]),globalThis.__NRVIDEO_CD__?.config?.obfuscate);try{let t=await this._fetchWithTimeout(n,{method:"POST",headers:o,body:h()},3e4);if(401===t.status){r.notice("ConnectedDeviceHarvester: /v3/data returned 401 — re-queuing events and reconnecting"),this.dataToken=null,this._connectAttempt=0;for(const t of a)this.eventBuffer.add(t);return void this.initialise()}if(!t.ok)throw new Error(`HTTP ${t.status}`);r.notice(`ConnectedDeviceHarvester: sent ${a.length} events`)}catch(t){r.error("ConnectedDeviceHarvester: /v3/data send failed:",t.message);for(const t of a)this.eventBuffer.add(t)}finally{this.isHarvesting=!1}}_buildDeviceInfo(){const t=this.deviceInfo;return[y[0],t.osVersion,t.deviceModel,y[3],y[4],t.uuid,"","",t.deviceManufacturer,y[9]]}_buildMetadata(){const t=this.deviceInfo;return{..._,osBuild:t.osBuild,appBuild:t.appBuild,architecture:t.architecture}}_fetchWithTimeout(t,e,i){const s=new AbortController,r=setTimeout(()=>s.abort(),i);return fetch(t,{...e,signal:s.signal}).finally(()=>clearTimeout(r))}async dispose(){return this.isDisposed=!0,this.timer.stop(),this.sendBufferedEvents()}}const tt=new class{constructor(){this.isInitialized=!1,this.harvester=null}initialize(){if(this.isInitialized)return;const t=globalThis.__NRVIDEO_CD__?.info;if(t)try{this.harvester=new J(t),this.isInitialized=!0,r.notice("ConnectedDeviceAnalyticsAgent initialized")}catch(t){r.error("ConnectedDeviceAnalyticsAgent.initialize failed:",t.message)}else r.warn("ConnectedDeviceAnalyticsAgent.initialize: globalThis.__NRVIDEO_CD__.info is missing")}addEvent(t){return this.isInitialized||this.initialize(),!!this.isInitialized&&this.harvester.addEvent(t)}forceQoeNextHarvest(){this.harvester&&this.harvester.forceQoeNextHarvest()}forceNextQoeCycle(){this.forceQoeNextHarvest()}setBeforeDrainCallback(t){this.harvester&&this.harvester.setBeforeDrainCallback(t)}refreshQoeKpis(t,e){this.isInitialized||this.initialize(),this.harvester&&this.harvester.refreshQoeKpis(t,e)}setHarvestInterval(t){this.isInitialized||this.initialize(),this.harvester&&this.harvester.setHarvestInterval(t)}};T("Vega",tt);const et=tt,it={Constants:n,Chrono:d,Log:r,Emitter:h,Tracker:u,VideoTracker:P,VideoTrackerState:C,Core:N,version:o,NrVideoEventAggregator:L,RetryQueueHandler:F,OptimizedHttpClient:z,HarvestScheduler:Y,recordEvent:A};export{et as connectedDeviceAnalyticsHarvester,it as default,v as getRegisteredHarvester,Z as videoAnalyticsHarvester};
|
|
2
|
+
class e{static Levels;static level;static colorful;static includeTime;static prefix;static error(...i){t(i,e.Levels.ERROR,"darkred")}static warn(...i){t(i,e.Levels.WARNING,"darkorange")}static notice(...i){t([].slice.call(arguments),e.Levels.NOTICE,"darkcyan")}static debug(...i){t(i,e.Levels.DEBUG,"indigo")}static debugCommonVideoEvents(t,i,s){try{if(e.level<=e.Levels.DEBUG){s=s||function(t){e.debug("Event: "+t.type)};var r=["canplay","buffering","waiting","ended","play","playing","pause","resume","error","abort","seek","seeking","seeked","stalled","dispose","loadeddata","loadstart","loadedmetadata"];i&&(null===i[0]?(i.shift(),r=i):r=r.concat(i));for(var a=0;a<r.length;a++)"function"==typeof t?t.call(window,r[a],s):t.on?t.on(r[a],s):t.addEventListener?t.addEventListener(r[a],s):t.addEventHandler?t.addEventHandler(r[a],s):e.warn("debugCommonVideoEvents: No common listener function found for ",t)}}catch(t){e.warn(t)}}}function t(t,r,a){r=r||e.Levels.NOTICE,a=a||"darkcyan";var n,o,l,h,d,c,u=e.prefix;(e.includeTime&&(u+=(n=new Date,o=("0"+n.getDate()).slice(-2),l=("0"+n.getMinutes()).slice(-2),h=("0"+n.getSeconds()).slice(-2),d=("00"+n.getMilliseconds()).slice(-3),"["+o+":"+l+":"+h+"."+d+"] ")),u+=function(e){return s[e]}(r)+":",e.level<=r&&r!==e.Levels.SILENT)&&(!e.colorful||"undefined"!=typeof document&&document.documentMode?i(t,u):(c=r===e.Levels.ERROR&&console.error?console.error:r===e.Levels.WARNING&&console.warn?console.warn:r===e.Levels.DEBUG&&console.debug&&null==window.cast?console.debug:console.log,u="%c"+u,t.splice(0,0,u,"color: "+a),c.apply(console,t)))}function i(e,t){if(e instanceof Array)for(var s in e)i(e[s],t);else"string"==typeof e?console.log(t+" "+e):(console.log(t+"↵"),console.log(e))}e.Levels={SILENT:5,ERROR:4,WARNING:3,NOTICE:2,DEBUG:1,ALL:0},e.level=e.Levels.ERROR,e.colorful=!0,e.includeTime=!0,e.prefix="[nrvideo]";const s={4:"e",3:"w",2:"n",1:"d"};!function(){if("undefined"!=typeof window&&window.location&&window.location.search){var t=/\?.*&*nrvideo-debug=(.+)/i.exec(window.location.search);null!==t&&("true"===t[1]?e.level=e.Levels.ALL:e.level=t[1]),null!==/\?.*&*nrvideo-colors=false/i.exec(window.location.search)&&(e.colorful=!1)}}();const r=e;const a=class{static AdPositions={PRE:"pre",MID:"mid",POST:"post"};static COLLECTOR={US:["bam.nr-data.net","bam-cell.nr-data.net"],EU:"bam.eu01.nr-data.net",JP:"bam.jp.nr-data.net",Staging:"staging-bam-cell.nr-data.net",GOV:"gov-bam.nr-data.net"};static VALID_EVENT_TYPES=["VideoAction","VideoAdAction","VideoErrorAction","VideoCustomAction"];static MAX_PAYLOAD_SIZE=1048576;static MAX_BEACON_SIZE=61440;static MAX_EVENTS_PER_BATCH=1e3;static INTERVAL=1e4;static DEFAULT_QOE_INTERVAL_FACTOR=2;static QOE_KPI_KEYS=["startupTime","peakBitrate","averageBitrate","totalPlaytime","totalRebufferingTime","rebufferingRatio","hadStartupError","hadPlaybackError","numberOfErrors"];static QOE_AGGREGATE_KEYS=["coreVersion","instrumentation.name","instrumentation.provider","instrumentation.version","isBackgroundEvent","playerName","playerVersion","src","viewId","viewSession","contentIsAutoplayed","contentIsMuted","contentRenditionHeight","contentRenditionWidth","contentSrc","numberOfVideos","pageUrl","trackerName","trackerVersion","contentDuration","contentPlayrate","contentPlayhead","contentPreload","elapsedTime","contentTitle","contentId","contentIsLive","deviceType","deviceGroup","deviceManufacturer","deviceModel","deviceName","deviceSize","deviceUuid","contentRenditionName","contentIsFullscreen","contentCdn","contentFps","asnOrganization","asnLongitude","asnLatitude","asn","timeSinceRequested","timeSinceStarted"]},n="5.1.0";const o=class{_listeners;on(e,t){if(this._listeners=this._listeners||{},"function"==typeof t)return this._listeners[e]=this._listeners[e]||[],this._listeners[e].push(t),this}off(e,t){if(this._listeners=this._listeners||{},this._listeners[e]){var i=this._listeners[e].indexOf(t);-1!==i&&this._listeners[e].splice(i,1)}return this}emit(e,t,i){return this._listeners=this._listeners||{},i=i||{},Array.isArray(this._listeners[t])&&this._listeners[t].forEach(s=>{s.call(this,{eventType:e,type:t,data:i,target:this})}),Array.isArray(this._listeners["*"])&&this._listeners["*"].forEach(s=>{s.call(this,{eventType:e,type:t,data:i,target:this})}),this}};class l{startTime=0;stopTime=0;accumulator=0;offset=0;constructor(){this.reset()}reset(){this.startTime=0,this.stopTime=0,this.accumulator=0,this.offset=0}getDeltaTime(){return this.startTime?this.offset+((new Date).getTime()-this.startTime):null}start(){this.startTime=(new Date).getTime(),this.stopTime=0}stop(){return this.stopTime=(new Date).getTime(),this.startTime<this.stopTime&&(this.accumulator+=this.stopTime-this.startTime),this.getDeltaTime()}getDuration(){return this.stopTime?this.accumulator+this.offset:this.accumulator+(this.getDeltaTime()??0)}clone(){var e=new l;return e.startTime=this.startTime,e.stopTime=this.stopTime,e.offset=this.offset,e.accumulator=this.accumulator,e}}const h=l;class d extends o{static Events;customData;heartbeat;parentTracker;state;_trackerReadyChrono;_actionTable;_actionAdTable;_heartbeatInterval;constructor(e){super(),this.customData={},this.heartbeat=null,this.parentTracker=null,this._trackerReadyChrono=new h,this._trackerReadyChrono.start(),this._actionTable=a.ACTION_TABLE,this._actionAdTable=a.ACTION_AD_TABLE,e=e||{},this.setOptions(e)}setOptions(e){e&&(e.parentTracker&&(this.parentTracker=e.parentTracker),e.customData&&(this.customData=e.customData),e.heartbeat&&(this.heartbeat=e.heartbeat))}dispose(){this.unregisterListeners()}registerListeners(){}unregisterListeners(){}getHeartbeat(){return this.state?._isAd?2e3:this.heartbeat?this.heartbeat:this.parentTracker&&this.parentTracker.heartbeat?this.parentTracker.heartbeat:3e4}startHeartbeat(){this._heartbeatInterval=setInterval(this.sendHeartbeat.bind(this),Math.max(this.getHeartbeat(),2e3))}stopHeartbeat(){this._heartbeatInterval&&clearInterval(this._heartbeatInterval)}sendHeartbeat(e){this.sendVideoAction(d.Events.HEARTBEAT,e)}getAttributes(e,t){(e=e||{}).trackerName=this.getTrackerName(),e.trackerVersion=this.getTrackerVersion(),e.coreVersion=n,e.timeSinceTrackerReady=this._trackerReadyChrono.getDeltaTime();for(let t in this.customData)e[t]=this.customData[t];return null!=document.hidden&&(e.isBackgroundEvent=document.hidden),e}getTrackerVersion(){return n}getTrackerName(){return"base-tracker"}sendVideoAction(e,t){this.emit("VideoAction",e,this.getAttributes(t))}sendVideoAdAction(e,t){this.emit("VideoAdAction",e,this.getAttributes(t))}sendVideoErrorAction(e,t){let i=this.isAd()?"adError":"videoError";this.emit("VideoErrorAction",e,this.getAttributes(t,i))}sendVideoCustomAction(e,t){this.emit("VideoCustomAction",e,this.getAttributes(t,"customAction"))}setHarvestInterval(e){const t=this.getHarvester?.();if(t)try{t.setHarvestInterval(e)}catch(e){return void r.error("Failed to set harvest interval:",e.message)}else r.error("Tracker has no harvester; setHarvestInterval ignored")}getHarvester(){return null}}d.Events={HEARTBEAT:"HEARTBEAT",QOE_AGGREGATE:"QOE_AGGREGATE"};const c=d;function u(e){try{return JSON.stringify(e,(()=>{const e=new WeakSet;return(t,i)=>{if("object"==typeof i&&null!==i){if(e.has(i))return;e.add(i)}return i}})())??""}catch(e){return r.error("Error stringifying value:",e.message),""}}function f(e){if("string"==typeof e&&e.length)return e.length;if("object"==typeof e){if("undefined"!=typeof ArrayBuffer&&e instanceof ArrayBuffer&&e.byteLength)return e.byteLength;if("undefined"!=typeof Blob&&e instanceof Blob&&e.size)return e.size;if(!("undefined"!=typeof FormData&&e instanceof FormData))try{return u(e).length}catch(e){return}}}function g(e,t,i,{addTimeSinceLoad:s=!1}={}){const{appName:r,applicationID:n}=i,{qoe:o,...l}=t,h=o?{...o}:{},d={...n?{}:{appName:r},timestamp:Date.now(),...s?{timeSinceLoad:"undefined"!=typeof window&&window.performance?window.performance.now()/1e3:null}:{}},u={...l,eventType:e,...d};let f=null;if("VideoAction"===e){const e=(g=a.QOE_AGGREGATE_KEYS,m=t,g&&Array.isArray(g)&&0!==g.length?m&&"object"==typeof m?g.reduce((e,t)=>(t in m&&(e[t]=m[t]),e),{}):{}:m);f={eventType:"VideoAction",actionName:c.Events.QOE_AGGREGATE,qoeAggregateVersion:"1.0.0",...h,...e,...d}}var g,m;return{eventObject:u,qoeEventObject:f}}const m=Object.create(null);function v(e,t){m[e]=t}function T(e){return m[e]}function E(e,t={}){try{if(!a.VALID_EVENT_TYPES.includes(e))return r.warn("Invalid event type provided to recordEvent",{eventType:e}),!1;const i="Vega"===t.src,s=i?"Vega":"Browser",n="undefined"!=typeof window?window:void 0,o=i?globalThis.__NRVIDEO_CD__?.info:n?.NRVIDEO?.info;if(!o)return;const l=m[s];if(!l)return r.warn("No harvester registered for routing key",{routingKey:s}),!1;return function(e,t,i,s,r,{addTimeSinceLoad:a=!1}={}){if(!s)return!1;const{eventObject:n,qoeEventObject:o}=g(e,t,i,{addTimeSinceLoad:a}),l=s.addEvent(n);return o&&r?l&&s.addEvent(o):l}(e,t,o,l,!!(i?globalThis.__NRVIDEO_CD__?.config?.qoeAggregate:n?.NRVIDEO?.config?.qoeAggregate),{addTimeSinceLoad:!i})}catch(e){return r.error("Failed to record event:",e.message),!1}}const A={us:"https://mobile-collector.newrelic.com/mobile",eu:"https://mobile-collector.eu01.nr-data.net/mobile",staging:"https://staging-mobile-collector.newrelic.com/mobile",gov:"https://gov-mobile-collector.newrelic.com/mobile",jp:"https://mobile-collector.jp.nr-data.net/mobile"},p=[["newrelic_mobile_example","1.1","com.newrelic.newrelic_mobile_example"],["Android","14","sdk_gphone64_arm64","AndroidAgent","7.4.0-alpha01","b797aee6-aa69-4879-9ba3-1f4aed1a7777","","","Google",{size:"normal",platform:"Flutter",platformVersion:"1.0.8"}]],S=["Vega","1.0","VegaDevice","VegaAgent","1.0.0","00000000-0000-0000-0000-000000000000","","","Amazon",{size:"normal",platform:"Native",platformVersion:"1.0.0"}],y={osBuild:"1",osName:"Vega",platform:"Native",appBuild:"1",architecture:"aarch64"},{COLLECTOR:_}=a;class B{setConfiguration(e,t,i){return!!("Vega"===i?this.validateVegaFields(e):this.validateRequiredFields(e))&&(!!this.validateConfigFields(t)&&(this.initializeGlobalConfig(e,t,i),r.notice("Video analytics configuration initialized successfully"),!0))}validateVegaFields(e){return e&&"object"==typeof e?e.applicationToken?e.endpoint?.toLowerCase()in A||(r.error("Invalid endpoint (must be us, eu, staging, gov, or jp)"),!1):(r.error("applicationToken is required"),!1):(r.error("Configuration must be an object"),!1)}validateRequiredFields(e){if(!e||"object"!=typeof e)return r.error("Configuration must be an object"),!1;const{licenseKey:t,appName:i,region:s,applicationID:a,beacon:n}=e;if(!t)return r.error("licenseKey is required"),!1;if(a){if(!n)return r.error("beacon is required when applicationID is provided"),!1;if(!Object.values(_).flatMap(e=>e).includes(n))return r.error(`Invalid beacon: ${n}`),!1}else{if(!i||!s)return r.error("appName and region are required when applicationID is not provided"),!1;if(!_[s])return r.error(`Invalid region: ${s}. Valid regions are: ${Object.keys(_).join(", ")}`),!1}return!0}validateConfigFields(e){if(null==e)return!0;if("object"!=typeof e||Array.isArray(e))return r.error("config must be an object"),!1;const{qoeAggregate:t,obfuscate:i}=e;return void 0!==t&&"boolean"!=typeof t?(r.error("qoeAggregate must be a boolean"),!1):!(void 0!==i&&!Array.isArray(i))||(r.error("obfuscate must be an array"),!1)}filterObfuscateRules(e){return e?e.filter(e=>{const t=void 0!==e.regex&&("string"==typeof e.regex||e.regex instanceof RegExp),i=void 0!==e.replacement&&"string"==typeof e.replacement;return!(!t||!i)||(r.warn("obfuscate rule missing required 'regex' (string|RegExp) and/or 'replacement' (string), skipping:",e),!1)}):[]}sanitizeQoeIntervalFactor(e){return null==e?a.DEFAULT_QOE_INTERVAL_FACTOR:"number"==typeof e&&Number.isInteger(e)&&e>=1?e:(r.warn(`Invalid qoeIntervalFactor "${e}" — must be a positive integer. Defaulting to ${a.DEFAULT_QOE_INTERVAL_FACTOR}.`),a.DEFAULT_QOE_INTERVAL_FACTOR)}initializeGlobalConfig(e,t,i){if("Vega"===i)return void(globalThis.__NRVIDEO_CD__={info:{accountId:e.accountId,applicationToken:e.applicationToken,endpoint:e.endpoint?.toLowerCase(),...e.appName?{appName:e.appName}:{},...e.applicationID?{applicationID:e.applicationID}:{},...e.deviceInfo?{deviceInfo:e.deviceInfo}:{}},config:{qoeAggregate:t?.qoeAggregate??!0,qoeIntervalFactor:this.sanitizeQoeIntervalFactor(t?.qoeIntervalFactor),obfuscate:this.filterObfuscateRules(t?.obfuscate)}});let{licenseKey:s,appName:r,region:n,beacon:o,applicationID:l}=e;o="US"===n?a.COLLECTOR.US[0]:o||_[n],window.NRVIDEO={info:{...n?{region:n}:{},beacon:o,licenseKey:s,applicationID:l,...l?{}:{appName:r}},config:{qoeAggregate:t?.qoeAggregate??!0,qoeIntervalFactor:this.sanitizeQoeIntervalFactor(t?.qoeIntervalFactor),obfuscate:this.filterObfuscateRules(t?.obfuscate)}}}}const b=new B;class R{static addTracker(e,t){t?.info&&function(e,t,i){b.setConfiguration(e,t,i)}(t.info,t?.config,t?.src),e.on&&e.emit?(w.push(e),e.on("*",D),"function"==typeof e.trackerInit&&e.trackerInit()):r.error("Tried to load a non-tracker.",e)}static removeTracker(e){e.off("*",D),e.dispose();let t=w.indexOf(e);-1!==t&&w.splice(t,1)}static getTrackers(){return w}static send(e,t,i){return E(e,{actionName:t,...i})}static sendError(e){return E("VideoErrorAction",{actionName:"ERROR",...e})}}let w=[];function D(e){try{let t=function(e){let t={};for(let i in e)null!==e[i]&&void 0!==e[i]&&(t[i]=e[i]);return t}(e.data);r.level<=r.Levels.DEBUG?r.notice("Sent",e.type,t):r.notice("Sent",e.type),R.send(e.eventType,e.type,t)}catch(e){r.error("Error in event handler:",e.message)}}const k=R;const C=class{_viewSession=null;_viewCount=0;_isAd=!1;numberOfErrors=0;numberOfAds=0;numberOfVideos=0;totalPlaytime=0;weightedAverageBitrate=0;totalAdPlaytime=0;isAdBreak=!1;initialBufferingHappened=!1;startupTime=null;peakBitrate=0;partialAverageBitrate=0;_totalBitrateDuration=0;weightedBitrate=0;_lastBitrate=null;_lastBitrateChangeTimestamp=null;_downloadBitrates=[];_lastDownloadBitrate=null;totalSwitchUps=0;totalSwitchDowns=0;totalPauseTime=0;_playedRenditions=new Set;hadStartupError=!1;hadPlaybackError=!1;totalRebufferingTime=0;isPlayerReady=!1;isRequested=!1;isStarted=!1;isPaused=!1;isSeeking=!1;isBuffering=!1;isPlaying=!1;timeSinceRequested;timeSinceStarted;timeSincePaused;timeSinceSeekBegin;timeSinceBufferBegin;timeSinceAdBreakStart;timeSinceLastDownload;timeSinceLastHeartbeat;timeSinceLastRenditionChange;timeSinceLastAdQuartile;timeSinceLastAd;timeSinceLastError;timeSinceLastAdError;timeSinceResumed;timeSinceSeekEnd;playtimeSinceLastEvent;customTimeSinceAttributes={};elapsedTime;bufferElapsedTime;_totalAdPlaytime;_createdAt;_hb;_acc;_bufferAcc;isError;constructor(){this.reset(),this._createdAt=Date.now(),this._hb=!0,this._acc=0,this._bufferAcc=0}reset(){this._viewSession=null,this._viewCount=0,this._isAd=!1,this.numberOfErrors=0,this.numberOfAds=0,this.numberOfVideos=0,this.totalPlaytime=0,this.weightedAverageBitrate=0,this.totalAdPlaytime=0,this.isAdBreak=!1,this.initialBufferingHappened=!1,this.startupTime=null,this.peakBitrate=0,this.partialAverageBitrate=0,this._totalBitrateDuration=0,this.weightedBitrate=0,this._lastBitrate=null,this._lastBitrateChangeTimestamp=null,this._downloadBitrates=[],this._lastDownloadBitrate=null,this.totalSwitchUps=0,this.totalSwitchDowns=0,this.totalPauseTime=0,this._playedRenditions=new Set,this.hadStartupError=!1,this.hadPlaybackError=!1,this.totalRebufferingTime=0,this.resetFlags(),this.resetChronos()}resetFlags(){this.isPlayerReady=!1,this.isRequested=!1,this.isStarted=!1,this.isPaused=!1,this.isSeeking=!1,this.isBuffering=!1,this.isPlaying=!1}resetChronos(){this.timeSinceRequested=new h,this.timeSinceStarted=new h,this.timeSincePaused=new h,this.timeSinceSeekBegin=new h,this.timeSinceBufferBegin=new h,this.timeSinceAdBreakStart=new h,this.timeSinceLastDownload=new h,this.timeSinceLastHeartbeat=new h,this.timeSinceLastRenditionChange=new h,this.timeSinceLastAdQuartile=new h,this.timeSinceLastAd=new h,this.timeSinceLastError=new h,this.timeSinceLastAdError=new h,this.timeSinceResumed=new h,this.timeSinceSeekEnd=new h,this.playtimeSinceLastEvent=new h,this.customTimeSinceAttributes={},this.elapsedTime=new h,this.bufferElapsedTime=new h,this._totalAdPlaytime=new h}isAd(){return this._isAd}setIsAd(e){this._isAd=e}setTimeSinceAttribute(e){this.customTimeSinceAttributes[e]=new h,this.customTimeSinceAttributes[e].start()}removeTimeSinceAttribute(e){delete this.customTimeSinceAttributes[e]}getViewSession(){if(!this._viewSession){let e=(new Date).getTime(),t=Math.random().toString(36).substring(2)+Math.random().toString(36).substring(2);this._viewSession=e+"-"+t}return this._viewSession}getViewId(){return this.getViewSession()+"-"+this._viewCount}getStateAttributes(e){e=e||{},this.isAd()?(this.isRequested&&(e.timeSinceAdRequested=this.timeSinceRequested.getDeltaTime(),e.timeSinceLastAdHeartbeat=this.timeSinceLastHeartbeat.getDeltaTime()),this.isStarted&&(e.timeSinceAdStarted=this.timeSinceStarted.getDeltaTime()),this.isPaused&&(e.timeSinceAdPaused=this.timeSincePaused.getDeltaTime()),this.isBuffering&&(e.timeSinceAdBufferBegin=this.timeSinceBufferBegin.getDeltaTime()),this.isSeeking&&(e.timeSinceAdSeekBegin=this.timeSinceSeekBegin.getDeltaTime()),this.isAdBreak&&(e.timeSinceAdBreakBegin=this.timeSinceAdBreakStart.getDeltaTime()),this.numberOfErrors>0&&this.timeSinceLastAdError.startTime>0&&(e.timeSinceLastAdError=this.timeSinceLastAdError.getDeltaTime()),e.numberOfAds=this.numberOfAds):(this.isRequested&&(e.timeSinceRequested=this.timeSinceRequested.getDeltaTime(),e.timeSinceLastHeartbeat=this.timeSinceLastHeartbeat.getDeltaTime()),this.isStarted&&(e.timeSinceStarted=this.timeSinceStarted.getDeltaTime()),this.isPaused&&(e.timeSincePaused=this.timeSincePaused.getDeltaTime()),this.isBuffering&&(e.timeSinceBufferBegin=this.timeSinceBufferBegin.getDeltaTime()),this.isSeeking&&(e.timeSinceSeekBegin=this.timeSinceSeekBegin.getDeltaTime()),e.timeSinceLastAd=this.timeSinceLastAd.getDeltaTime(),this.numberOfErrors>0&&this.timeSinceLastError.startTime>0&&(e.timeSinceLastError=this.timeSinceLastError.getDeltaTime()),e.numberOfVideos=this.numberOfVideos),e.numberOfErrors=this.numberOfErrors,this.isAd()||(this.playtimeSinceLastEvent.startTime>0?e.playtimeSinceLastEvent=this.playtimeSinceLastEvent.getDeltaTime():e.playtimeSinceLastEvent=0,this.isPlaying?this.playtimeSinceLastEvent.start():this.playtimeSinceLastEvent.reset(),this.totalPlaytime+=e.playtimeSinceLastEvent,e.totalPlaytime=this.totalPlaytime);for(const[t,i]of Object.entries(this.customTimeSinceAttributes))e[t]=i.getDeltaTime();return e}getQoeAttributes(e){e=e||{};const t={};try{if(null!==this.startupTime&&(t.startupTime=this.startupTime),this.peakBitrate>0&&(t.peakBitrate=this.peakBitrate),t.hadStartupError=this.hadStartupError,t.hadPlaybackError=this.hadPlaybackError,t.totalRebufferingTime=this.totalRebufferingTime,t.rebufferingRatio=this.totalPlaytime>0?this.totalRebufferingTime/this.totalPlaytime*100:0,t.totalPlaytime=this.totalPlaytime,t.averageBitrate=this.weightedBitrate,t.numberOfErrors=this.numberOfErrors,this._downloadBitrates.length>0){const e=this._downloadBitrates.reduce((e,t)=>e+t,0);t.avgDownloadRate=Math.round(e/this._downloadBitrates.length),t.minDownloadRate=Math.min(...this._downloadBitrates),t.maxDownloadRate=Math.max(...this._downloadBitrates)}t.totalSwitchUps=this.totalSwitchUps,t.totalSwitchDowns=this.totalSwitchDowns,t.totalPauseTime=this.timeSincePaused.getDuration(),t.totalViewSessionTime=this.totalPlaytime,t.totalRenditions=this._playedRenditions.size,t.qoeAggregateVersion="1.1.0"}catch(e){r.error("Failed to add attributes for QOE KPIs",e.message)}return e.qoe=t,e}calculateBufferType(e){let t="";return t=e?"initial":this.isSeeking?"seek":this.isPaused?"pause":"connection",r.debug("Buffer Type = "+t),t}goViewCountUp(){this._viewCount++}goPlayerReady(){return!this.isPlayerReady&&(this.isPlayerReady=!0,!0)}goRequest(){return!this.isRequested&&(this.isRequested=!0,this.timeSinceLastAd.reset(),this.timeSinceRequested.start(),!0)}goStart(){return!(!this.isRequested||this.isStarted)&&(this.isAd()?this.numberOfAds++:this.numberOfVideos++,this.isStarted=!0,this.isPlaying=!0,this.timeSinceStarted.start(),this.playtimeSinceLastEvent.start(),!0)}goEnd(){return!!this.isRequested&&(this.numberOfErrors=0,this.resetFlags(),this.timeSinceRequested.stop(),this.timeSinceStarted.stop(),this.playtimeSinceLastEvent.stop(),this.isPlaying=!1,!0)}goPause(){return!(!this.isStarted||this.isPaused)&&(this.isPaused=!0,this.isPlaying=!1,this.timeSincePaused.start(),this.playtimeSinceLastEvent.stop(),this.timeSinceResumed.reset(),this.isBuffering&&(this._bufferAcc+=this.bufferElapsedTime.getDeltaTime()),this.elapsedTime.start(),!0)}goResume(){return!(!this.isStarted||!this.isPaused)&&(this.isPaused=!1,this.isPlaying=!0,this.timeSincePaused.stop(),this.timeSinceResumed.start(),this._hb?(this._acc=this.elapsedTime.getDeltaTime(),this._hb=!1):(this.isBuffering&&this.bufferElapsedTime.start(),this._acc+=this.elapsedTime.getDeltaTime()),!0)}goBufferStart(){return!(!this.isRequested||this.isBuffering)&&(this.isBuffering=!0,this.isPlaying=!1,this.timeSinceBufferBegin.start(),this.bufferElapsedTime.start(),!0)}goBufferEnd(){return!(!this.isRequested||!this.isBuffering)&&(this.isBuffering=!1,this.isPlaying=!0,this.timeSinceBufferBegin.stop(),this._hb?(this._bufferAcc=this.bufferElapsedTime.getDeltaTime(),this._hb=!1):this._bufferAcc+=this.bufferElapsedTime.getDeltaTime(),!this.isAd()&&this.initialBufferingHappened&&(this.totalRebufferingTime+=this.timeSinceBufferBegin.stopTime-this.timeSinceBufferBegin.startTime),!0)}goSeekStart(){return!(!this.isStarted||this.isSeeking)&&(this.isSeeking=!0,this.isPlaying=!1,this.timeSinceSeekBegin.start(),this.timeSinceSeekEnd.reset(),!0)}goSeekEnd(){return!(!this.isStarted||!this.isSeeking)&&(this.isSeeking=!1,this.isPlaying=!0,this.timeSinceSeekBegin.stop(),this.timeSinceSeekEnd.start(),!0)}goAdBreakStart(){return!this.isAdBreak&&(this.isAdBreak=!0,this.timeSinceAdBreakStart.start(),!0)}goAdBreakEnd(){return!!this.isAdBreak&&(this.isRequested=!1,this.isAdBreak=!1,this.totalAdPlaytime=this.timeSinceAdBreakStart.getDeltaTime(),this.timeSinceAdBreakStart.stop(),!0)}goDownload(){this.timeSinceLastDownload.start()}goHeartbeat(){this.timeSinceLastHeartbeat.start()}goRenditionChange(){this.timeSinceLastRenditionChange.start()}goAdQuartile(){this.timeSinceLastAdQuartile.start()}goError(){this.isError=!0,this.numberOfErrors++,this.isAd()?this.timeSinceLastAdError.start():(this.timeSinceLastError.start(),this.isStarted?this.hadPlaybackError=!0:this.hadStartupError=!0)}goLastAd(){this.timeSinceLastAd.start()}trackContentBitrateState(e){if(e&&"number"==typeof e){this.peakBitrate=Math.max(this.peakBitrate,e);const t=Date.now();if(!this.isPlaying){if(null!==this._lastBitrate&&null!==this._lastBitrateChangeTimestamp){const e=t-this._lastBitrateChangeTimestamp;e>0&&(this.partialAverageBitrate+=this._lastBitrate*e,this._totalBitrateDuration+=e),this._lastBitrateChangeTimestamp=null}return void(this._lastBitrate=e)}if(null===this._lastBitrateChangeTimestamp&&null!==this._lastBitrate&&(this._lastBitrateChangeTimestamp=t),null!==this._lastBitrate&&this._lastBitrate!==e&&null!==this._lastBitrateChangeTimestamp){const e=t-this._lastBitrateChangeTimestamp;e>0&&(this.partialAverageBitrate+=this._lastBitrate*e,this._totalBitrateDuration+=e),this._lastBitrateChangeTimestamp=t}null===this._lastBitrateChangeTimestamp&&(this._lastBitrateChangeTimestamp=t),this._lastBitrate=e;let i=this.partialAverageBitrate,s=this._totalBitrateDuration;const r=t-this._lastBitrateChangeTimestamp;r>0&&(i+=e*r,s+=r),this.weightedBitrate=s>0?Math.round(i/s):e}}trackDownloadRate(e){!e||"number"!=typeof e||e<=0||e!==this._lastDownloadBitrate&&(this._downloadBitrates.push(e),this._lastDownloadBitrate=e)}addPlayedRendition(e,t){e&&t&&this._playedRenditions.add(`${e}x${t}`)}resetViewIdTrackedState(){this.peakBitrate=0,this.startupTime=null,this.partialAverageBitrate=0,this._totalBitrateDuration=0,this.weightedBitrate=0,this._lastBitrate=null,this._lastBitrateChangeTimestamp=null,this._downloadBitrates=[],this._lastDownloadBitrate=null,this.totalSwitchUps=0,this.totalSwitchDowns=0,this.timeSincePaused.reset(),this._playedRenditions=new Set}clearTotalAdsTime(){r.debug("clear total ads time",this.totalAdTime),this._totalAdPlaytime.reset()}totalAdTime(){return this._totalAdPlaytime.getDuration()}startAdsTime(){return r.debug("startAdsTime"),this._totalAdPlaytime.start()}stopAdsTime(){return r.debug("stopAdsTime"),this._totalAdPlaytime.stop()}setStartupTime(e){null===this.startupTime&&(this.startupTime=Math.max(this.timeSinceRequested.getDeltaTime()-e,0))}};class N extends c{static Events;state;adsTracker;_lastBufferType;_userId;_src;player;tag;_lastWebkitBitrate;_lastAdRendition;_lastRendition;constructor(e,t){super(),this.state=new C,this.adsTracker=null,this._lastBufferType=null,this._userId=null,this._src=null,t=t||{},this.setOptions(t),e&&this.setPlayer(e,t.tag),r.notice("Tracker "+this.getTrackerName()+" v"+this.getTrackerVersion()+" is ready.")}setUserId(e){this._userId=e}setOptions(e){e&&(e.adsTracker&&this.setAdsTracker(e.adsTracker),"boolean"==typeof e.isAd&&this.setIsAd(e.isAd),void 0!==e.src&&(null!==this._src&&this._src!==e.src?r.warn(`setOptions: src is locked to '${this._src}'. Ignoring override '${e.src}'.`):(this._src=e.src,this.adsTracker&&null==this.adsTracker._src&&(this.adsTracker._src=this._src))),c.prototype.setOptions.apply(this,arguments))}setPlayer(e,t){(this.player||this.tag)&&this.dispose(),"undefined"!=typeof document&&document.getElementById&&("string"==typeof e&&(e=document.getElementById(e)),"string"==typeof t&&(t=document.getElementById(t))),t=t||e,this.player=e,this.tag=t,this.registerListeners()}isAd(){return this.state.isAd()}setIsAd(e){this.state.setIsAd(e)}setAdsTracker(e){this.disposeAdsTracker(),e&&(this.adsTracker=e,this.adsTracker.setIsAd(!0),this.adsTracker.parentTracker=this,null!=this._src&&null==e._src&&(e._src=this._src),this.adsTracker.on("*",I.bind(this)))}disposeAdsTracker(){this.adsTracker&&(this.adsTracker.off("*",I),this.adsTracker.dispose())}dispose(){this.stopHeartbeat(),this.disposeAdsTracker(),this.unregisterListeners(),this.player=null,this.tag=null}registerListeners(){}unregisterListeners(){}getViewId(){return this.parentTracker?this.parentTracker.getViewId():this.state.getViewId()}getViewSession(){return this.parentTracker?this.parentTracker.getViewSession():this.state.getViewSession()}getVideoId(){return null}getTitle(){return null}isLive(){return null}getBitrate(){return null}getManifestBitrate(){return null}getSegmentDownloadBitrate(){return null}getNetworkDownloadBitrate(){return null}getWebkitBitrate(){if(this.tag&&this.tag.webkitVideoDecodedByteCount){let e;if(this._lastWebkitBitrate){e=this.tag.webkitVideoDecodedByteCount;let t=e-this._lastWebkitBitrate,i=this.getHeartbeat()/1e3;e=Math.round(t/i*8)}return this._lastWebkitBitrate=this.tag.webkitVideoDecodedByteCount,e||null}}getRenditionName(){return null}getRenditionBitrate(){return null}getRenditionShift(e){let t,i=this.getManifestBitrate();return this.isAd()?(t=this._lastAdRendition,e&&(this._lastAdRendition=i)):(t=this._lastRendition,e&&(this._lastRendition=i)),i&&t?i>t?"up":i<t?"down":null:null}getRenditionHeight(){return this.tag?this.tag.videoHeight:null}getRenditionWidth(){return this.tag?this.tag.videoWidth:null}getDuration(){return this.tag?this.tag.duration:null}getPlayhead(){return this.tag?this.tag.currentTime:null}getLanguage(){return null}getSrc(){return this.tag?this.tag.currentSrc:null}getPlayrate(){return this.tag?this.tag.playbackRate:null}isMuted(){return this.tag?this.tag.muted:null}isFullscreen(){return null}getCdn(){return null}getPlayerName(){return this.getTrackerName()}getPlayerVersion(){return n}getFps(){return null}isAutoplayed(){return this.tag?this.tag.autoplay:null}getPreload(){return this.tag?this.tag.preload:null}getAdQuartile(){return null}getAdPosition(){return this.parentTracker?this.parentTracker.state.isStarted?"mid":"pre":null}getAdPartner(){return null}getAdCreativeId(){return null}getInstrumentationProvider(){return null}getInstrumentationName(){return null}getInstrumentationVersion(){return null}getAttributes(e,t){if(void 0===(e=c.prototype.getAttributes.apply(this,arguments)).isAd&&(e.isAd=this.isAd()),e.viewSession=this.getViewSession(),e.viewId=this.getViewId(),e.playerName=this.getPlayerName(),e.playerVersion=this.getPlayerVersion(),e["instrumentation.provider"]=this.getInstrumentationProvider(),e["instrumentation.name"]=this.getInstrumentationName(),e["instrumentation.version"]=this.getInstrumentationVersion(),e["enduser.id"]=this._userId,e.src=this._src||"Browser","customAction"===t)return e;try{e.pageUrl=window.location.href}catch(e){}this.isAd()?(e.adId=this.getVideoId(),e.adTitle=this.getTitle(),e.adSrc=this.getSrc(),e.adCdn=this.getCdn(),this.state.isStarted&&(e.adBitrate=this.getBitrate()||0),e.adRenditionName=this.getRenditionName(),e.adRenditionHeight=this.getRenditionHeight(),e.adRenditionWidth=this.getRenditionWidth(),e.adDuration=this.getDuration(),e.adPlayhead=this.getPlayhead(),e.adLanguage=this.getLanguage(),e.adIsMuted=this.isMuted(),e.adFps=this.getFps(),e.adPosition=this.getAdPosition(),e.adCreativeId=this.getAdCreativeId(),e.adPartner=this.getAdPartner()):(e.contentId=this.getVideoId(),e.contentTitle=this.getTitle(),e.contentSrc=this.getSrc(),e.contentCdn=this.getCdn(),e.contentPlayhead=this.getPlayhead(),e.contentIsLive=this.isLive(),this.state.isStarted&&(e.contentBitrate=this.getBitrate()||0,e.contentManifestBitrate=this.getManifestBitrate()||0,e.contentSegmentDownloadBitrate=this.getSegmentDownloadBitrate()||0,e.contentNetworkDownloadBitrate=this.getNetworkDownloadBitrate()||0),e.contentRenditionName=this.getRenditionName(),e.contentRenditionHeight=this.getRenditionHeight(),e.contentRenditionWidth=this.getRenditionWidth(),e.contentDuration=this.getDuration(),e.contentLanguage=this.getLanguage(),e.contentPlayrate=this.getPlayrate(),e.contentIsFullscreen=this.isFullscreen(),e.contentIsMuted=this.isMuted(),e.contentIsAutoplayed=this.isAutoplayed(),e.contentPreload=this.getPreload(),e.contentFps=this.getFps(),null!=this.adsTracker&&this.adsTracker.state.totalAdPlaytime>0&&(e.totalAdPlaytime=this.adsTracker.state.totalAdPlaytime)),this.state.getStateAttributes(e),this.state.isStarted&&!this.isAd()&&(this.state.trackContentBitrateState(e.contentBitrate),this.state.trackDownloadRate(e.contentNetworkDownloadBitrate),this.state.addPlayedRendition(e.contentRenditionHeight,e.contentRenditionWidth));for(let t in this.customData)e[t]=this.customData[t];if(!this.isAd()){this.state.getQoeAttributes(e);const t=e.qoe;for(let e in this.customData)t[e]=this.customData[e]}return e}sendCustom(e,t,i){i=i||{},this.sendVideoCustomAction(e,i),this.state.setTimeSinceAttribute(t)}sendPlayerReady(e){this.state.goPlayerReady()&&(e=e||{},this.sendVideoAction(N.Events.PLAYER_READY,e))}sendRequest(e){if(this.state.goRequest()){let t;this.isAd()?(t=N.Events.AD_REQUEST,this.sendVideoAdAction(t,e)):(t=N.Events.CONTENT_REQUEST,this.sendVideoAction(t,e))}}sendStart(e){if(this.state.goStart()){let t;if(this.isAd())t=N.Events.AD_START,this.parentTracker&&(this.parentTracker.state.isPlaying=!1),this.sendVideoAdAction(t,e),this.state.startAdsTime();else{t=N.Events.CONTENT_START;let i=0;this.adsTracker&&((this.adsTracker.state.isPlaying||this.adsTracker.state.isBuffering)&&(this.adsTracker.state.stopAdsTime(),this.adsTracker.state.isPlaying=!1,this.adsTracker.state.isBuffering=!1),i=this.adsTracker.state.totalAdTime()??0),this.state.setStartupTime(i),this.sendVideoAction(t,e);const s=this.getHarvester?.();s?.setBeforeDrainCallback(()=>{if(this.state){const e=this.state.getQoeAttributes({}).qoe;s.refreshQoeKpis(e,this.getViewId())}})}this.startHeartbeat(),this.state.goHeartbeat()}}sendEnd(e){if(this.state.goEnd()){let t;if(e=e||{},this.isAd()?(t=N.Events.AD_END,e.timeSinceAdRequested=this.state.timeSinceRequested.getDeltaTime(),e.timeSinceAdStarted=this.state.timeSinceStarted.getDeltaTime(),this.parentTracker&&(this.parentTracker.state.isPlaying=!0,this.parentTracker.state.timeSincePaused.reset()),this.state.stopAdsTime()):(t=N.Events.CONTENT_END,e.timeSinceRequested=this.state.timeSinceRequested.getDeltaTime(),e.timeSinceStarted=this.state.timeSinceStarted.getDeltaTime()),this.stopHeartbeat(),this.isAd()?this.sendVideoAdAction(t,e):this.sendVideoAction(t,e),this.parentTracker&&this.isAd()&&this.parentTracker.state.goLastAd(),this.state.goViewCountUp(),this.state.totalPlaytime=0,!this.isAd()){const e=this.getHarvester?.();e?.forceNextQoeCycle?.(),e?.setBeforeDrainCallback(null),this.adsTracker&&this.adsTracker.state.clearTotalAdsTime(),this.state.resetViewIdTrackedState()}}}sendPause(e){if(this.state.goPause()){let t=this.isAd()?N.Events.AD_PAUSE:N.Events.CONTENT_PAUSE;this.isAd()?this.sendVideoAdAction(t,e):this.sendVideoAction(t,e)}}sendResume(e){if(this.state.goResume()){let t;e=e||{},this.isAd()?(t=N.Events.AD_RESUME,e.timeSinceAdPaused=this.state.timeSincePaused.getDeltaTime()):(t=N.Events.CONTENT_RESUME,e.timeSincePaused=this.state.timeSincePaused.getDeltaTime()),this.isAd()?this.sendVideoAdAction(t,e):this.sendVideoAction(t,e)}}sendBufferStart(e){if(this.state.goBufferStart()){let t;e=e||{},t=this.isAd()?N.Events.AD_BUFFER_START:N.Events.CONTENT_BUFFER_START,e=this.buildBufferAttributes(e),this._lastBufferType=e.bufferType,this.isAd()?this.sendVideoAdAction(t,e):this.sendVideoAction(t,e)}}sendBufferEnd(e){if(this.state.goBufferEnd()){let t;e=e||{},this.isAd()?(t=N.Events.AD_BUFFER_END,e.timeSinceAdBufferBegin=this.state.timeSinceBufferBegin.getDeltaTime()):(t=N.Events.CONTENT_BUFFER_END,e.timeSinceBufferBegin=this.state.timeSinceBufferBegin.getDeltaTime()),e=this.buildBufferAttributes(e),null!=this._lastBufferType&&(e.bufferType=this._lastBufferType),this.isAd()?this.sendVideoAdAction(t,e):this.sendVideoAction(t,e),this.state.initialBufferingHappened=!0}}buildBufferAttributes(e){return null==e.timeSinceStarted||e.timeSinceStarted<100?e.isInitialBuffering=!this.state.initialBufferingHappened:e.isInitialBuffering=!1,e.bufferType=this.state.calculateBufferType(e.isInitialBuffering),e.timeSinceResumed=this.state.timeSinceResumed.getDeltaTime(),e.timeSinceSeekEnd=this.state.timeSinceSeekEnd.getDeltaTime(),e}sendSeekStart(e){if(this.state.goSeekStart()){let t;t=this.isAd()?N.Events.AD_SEEK_START:N.Events.CONTENT_SEEK_START,this.isAd()?this.sendVideoAdAction(t,e):this.sendVideoAction(t,e)}}sendSeekEnd(e){if(this.state.goSeekEnd()){let t;e=e||{},this.isAd()?(t=N.Events.AD_SEEK_END,e.timeSinceAdSeekBegin=this.state.timeSinceSeekBegin.getDeltaTime()):(t=N.Events.CONTENT_SEEK_END,e.timeSinceSeekBegin=this.state.timeSinceSeekBegin.getDeltaTime()),this.isAd()?this.sendVideoAdAction(t,e):this.sendVideoAction(t,e)}}sendDownload(e){(e=e||{}).state||r.warn("Called sendDownload without { state: xxxxx }."),this.sendVideoAction(N.Events.DOWNLOAD,e),this.state.goDownload()}sendError(e){(e=e||{}).isAd=this.isAd(),this.state.goError();let t=this.isAd()?N.Events.AD_ERROR:N.Events.CONTENT_ERROR;this.sendVideoErrorAction(t,e)}sendRenditionChanged(e){(e=e||{}).timeSinceLastRenditionChange=this.state.timeSinceLastRenditionChange.getDeltaTime();const{oldBitrate:t,newBitrate:i}=e;let s;this.isAd()||void 0===t||void 0===i||(i>t?(e.shift="up",this.state.totalSwitchUps+=1):i<t?(e.shift="down",this.state.totalSwitchDowns+=1):e.shift=null),delete e.oldBitrate,delete e.newBitrate,s=this.isAd()?N.Events.AD_RENDITION_CHANGE:N.Events.CONTENT_RENDITION_CHANGE,this.isAd()?this.sendVideoAdAction(s,e):this.sendVideoAction(s,e),this.state.goRenditionChange()}sendHeartbeat(e){if(this.state.isRequested){let t,i=this.getHeartbeat();this.state._hb=!0,i=this.adjustElapsedTimeForPause(i),this.isAd()?(t=N.Events.AD_HEARTBEAT,"bitmovin-ads"===this.getPlayerName()?this.sendVideoAdAction(t,e):this.sendVideoAdAction(t,{elapsedTime:i,...e})):(t=N.Events.CONTENT_HEARTBEAT,this.sendVideoAction(t,{elapsedTime:i,...e})),this.state.goHeartbeat()}}adjustElapsedTimeForPause(e){return this.state._acc&&(e-=this.state._acc,this.state._acc=0),this.state.isPaused&&((e-=this.state.elapsedTime.getDeltaTime())<10&&(e=0),this.state.elapsedTime.start()),this.state._bufferAcc?(e-=this.state._bufferAcc,this.state._bufferAcc=0):this.state.isBuffering&&((e-=this.state.bufferElapsedTime.getDeltaTime())<5&&(e=0),this.state.bufferElapsedTime.start()),Math.max(0,e)}sendAdBreakStart(e){this.isAd()&&this.state.goAdBreakStart()&&(this.state.totalAdPlaytime=0,this.parentTracker&&(this.parentTracker.state.isPlaying=!1),this.sendVideoAdAction(N.Events.AD_BREAK_START,e))}sendAdBreakEnd(e){this.isAd()&&this.state.goAdBreakEnd()&&((e=e||{}).timeSinceAdBreakBegin=this.state.timeSinceAdBreakStart.getDeltaTime(),this.sendVideoAdAction(N.Events.AD_BREAK_END,e),this.parentTracker&&(this.parentTracker.state.isPlaying=!0),this.stopHeartbeat(),this.parentTracker&&this.isAd()&&this.parentTracker.state.goLastAd())}sendAdQuartile(e){this.isAd()&&((e=e||{}).quartile||r.warn("Called sendAdQuartile without { quartile: xxxxx }."),e.timeSinceLastAdQuartile=this.state.timeSinceLastAdQuartile.getDeltaTime(),this.sendVideoAdAction(N.Events.AD_QUARTILE,e),this.state.goAdQuartile())}sendAdClick(e){this.isAd()&&((e=e||{}).url||r.warn("Called sendAdClick without { url: xxxxx }."),this.sendVideoAdAction(N.Events.AD_CLICK,e))}}function I(e){e.type!==N.Events.AD_ERROR?this.sendVideoAdAction(e.type,e.data):this.sendVideoErrorAction(e.type,e.data)}N.Events={PLAYER_READY:"PLAYER_READY",DOWNLOAD:"DOWNLOAD",ERROR:"ERROR",CONTENT_REQUEST:"CONTENT_REQUEST",CONTENT_START:"CONTENT_START",CONTENT_END:"CONTENT_END",CONTENT_PAUSE:"CONTENT_PAUSE",CONTENT_RESUME:"CONTENT_RESUME",CONTENT_SEEK_START:"CONTENT_SEEK_START",CONTENT_SEEK_END:"CONTENT_SEEK_END",CONTENT_BUFFER_START:"CONTENT_BUFFER_START",CONTENT_BUFFER_END:"CONTENT_BUFFER_END",CONTENT_HEARTBEAT:"CONTENT_HEARTBEAT",CONTENT_RENDITION_CHANGE:"CONTENT_RENDITION_CHANGE",CONTENT_ERROR:"CONTENT_ERROR",AD_REQUEST:"AD_REQUEST",AD_START:"AD_START",AD_END:"AD_END",AD_PAUSE:"AD_PAUSE",AD_RESUME:"AD_RESUME",AD_SEEK_START:"AD_SEEK_START",AD_SEEK_END:"AD_SEEK_END",AD_BUFFER_START:"AD_BUFFER_START",AD_BUFFER_END:"AD_BUFFER_END",AD_HEARTBEAT:"AD_HEARTBEAT",AD_RENDITION_CHANGE:"AD_RENDITION_CHANGE",AD_ERROR:"AD_ERROR",AD_BREAK_START:"AD_BREAK_START",AD_BREAK_END:"AD_BREAK_END",AD_QUARTILE:"AD_QUARTILE",AD_CLICK:"AD_CLICK"};const P=N,{MAX_PAYLOAD_SIZE:O,MAX_EVENTS_PER_BATCH:V}=a;class H{buffer;maxPayloadSize;maxEventsPerBatch;currentPayloadSize;totalEvents;smartHarvestPayloadThreshold;overflowPayloadThreshold;smartHarvestEventThreshold;overflowEventThreshold;onSmartHarvestTrigger;constructor(){this.buffer=[],this.maxPayloadSize=O,this.maxEventsPerBatch=V,this.currentPayloadSize=0,this.totalEvents=0,this.smartHarvestPayloadThreshold=Math.floor(.6*this.maxPayloadSize),this.overflowPayloadThreshold=Math.floor(.9*this.maxPayloadSize),this.smartHarvestEventThreshold=Math.floor(.6*this.maxEventsPerBatch),this.overflowEventThreshold=Math.floor(.9*this.maxEventsPerBatch),this.onSmartHarvestTrigger=null}addOrReplaceByActionName(e,t){const i=this.buffer.findIndex(t=>t.actionName===e);try{return-1===i?this.add(t):this.add(t,i),!0}catch(e){return r.error("Failed to set or replace the event to buffer:",e.message),!1}}addOrReplaceByActionNameAndViewId(e,t,i){const s=this.buffer.findIndex(i=>i.actionName===e&&i.viewId===t);try{return-1===s?this.add(i):this.add(i,s),!0}catch(e){return r.error("Failed to set or replace the event to buffer:",e.message),!1}}findByActionNameAndViewId(e,t){return this.buffer.find(i=>i.actionName===e&&i.viewId===t)||null}findByActionName(e){return this.buffer.find(t=>t.actionName===e)||null}add(e,t){try{const i=f(e)??0,s=this.currentPayloadSize+i>=this.maxPayloadSize,r=this.totalEvents+1>=this.maxEventsPerBatch;if((s||r)&&this.makeRoom(i),null!=t&&t>-1){const s=f(this.buffer[t])??0;this.buffer[t]=e,this.currentPayloadSize+=i-s}else this.buffer.push(e),this.totalEvents++,this.currentPayloadSize+=i;return this.checkSmartHarvestTrigger(),!0}catch(e){return r.error("Failed to add event to buffer:",e.message),!1}}checkSmartHarvestTrigger(){const e=this.currentPayloadSize/this.maxPayloadSize,t=this.totalEvents/this.maxEventsPerBatch,i=this.currentPayloadSize>=this.overflowPayloadThreshold,s=this.totalEvents>=this.overflowEventThreshold;if(i||s){const s=i?`payload ${this.currentPayloadSize}/${this.maxPayloadSize} bytes (${Math.round(100*e)}%)`:`events ${this.totalEvents}/${this.maxEventsPerBatch} (${Math.round(100*t)}%)`;r.warn(`OVERFLOW PREVENTION: ${s} - Emergency harvest triggered`),this.onSmartHarvestTrigger&&"function"==typeof this.onSmartHarvestTrigger&&this.onSmartHarvestTrigger("overflow",90)}else{const e=this.currentPayloadSize>=this.smartHarvestPayloadThreshold,t=this.totalEvents>=this.smartHarvestEventThreshold;(e||t)&&this.onSmartHarvestTrigger&&"function"==typeof this.onSmartHarvestTrigger&&this.onSmartHarvestTrigger("smart",60)}}setSmartHarvestCallback(e){this.onSmartHarvestTrigger=e}drain(){try{const e=this.buffer.splice(0);return this.totalEvents=0,this.currentPayloadSize=0,e}catch(e){return r.error("Failed to drain events from buffer:",e.message),[]}}isEmpty(){return 0===this.totalEvents}size(){return this.totalEvents}clear(){this.buffer=[],this.totalEvents=0}makeRoom(e){if(e>this.maxPayloadSize)r.error("Event dropped: Event size exceeds maximum payload size.");else for(;(this.totalEvents>=this.maxEventsPerBatch||this.currentPayloadSize+e>=this.maxPayloadSize)&&this.buffer.length>0;){const e=f(this.buffer.shift())??0;this.totalEvents--,this.currentPayloadSize-=e,r.warn("Event buffer full, oldest event removed.")}}}const{MAX_PAYLOAD_SIZE:L,MAX_EVENTS_PER_BATCH:Q}=a;class x{retryQueue;maxQueueSize;maxQueueSizeBytes;constructor(){this.retryQueue=[],this.maxQueueSize=Q,this.maxQueueSizeBytes=L}addFailedEvents(e){try{const t=Array.isArray(e)?e:[e];r.notice(`Adding ${t.length} failed events to retry queue`,{queueSizeBefore:this.retryQueue.length});for(const e of t){this.retryQueue.length>=this.maxQueueSize&&this.evictOldestEvent();const t=f(e)??0;for(;(f(this.retryQueue)??0)+t>this.maxQueueSizeBytes;)this.evictOldestEvent();this.retryQueue.push({...e})}}catch(e){r.error("Failed to add events to retry queue:",e.message)}}discardEvent(e,t){r.warn("Discarded event",{reason:t,eventType:e.eventType})}evictOldestEvent(){if(this.retryQueue.length>0){const e=this.retryQueue.shift();this.discardEvent(e,"Queue full - evicted oldest")}}getRetryEventsToFit(e,t){const i=[];let s=0,r=0;for(let a=this.retryQueue.length-1;a>=0;a--){const n=this.retryQueue[a];if(r>=t)break;const o=f(n)??0;if(s+o>e)break;i.unshift(n),s+=o,r++,this.retryQueue.splice(a,1)}return i}getQueueSize(){return this.retryQueue.length}clear(){this.retryQueue=[]}}function F(e,t){return t&&0!==t.length?t.reduce((e,t)=>{let i;try{if(t.regex instanceof RegExp){const e=t.regex.flags.includes("g")?t.regex.flags:t.regex.flags+"g";i=new RegExp(t.regex.source,e)}else i=new RegExp(t.regex,"g")}catch(i){return r.warn("applyObfuscationRules: invalid regex, skipping rule:",t.regex,i.message),e}return e.replace(i,t.replacement)},e):e}class q{async send(e,t){const{url:i,payload:s,options:a={}}=e;try{if(!i||!s)throw new Error("URL and payload are required");const e={url:i,payload:s,options:a,callback:t};await this.executeRequest(e)}catch(e){r.error("Failed to send request:",e.message),t({retry:!1,status:0,error:e.message})}}async executeRequest(e){const{url:t,payload:i,options:s,callback:r}=e,a=Date.now();try{const r=F(JSON.stringify(i.body),window.NRVIDEO?.config?.obfuscate);if(s.isFinalHarvest&&navigator.sendBeacon){const i=await this.sendWithBeacon(t,r),s={success:i,status:i?204:0};return void this.handleRequestComplete(e,s,a)}const n=await this.fetchWithTimeout(t,{method:"POST",body:r,headers:{"Content-Type":"application/json"},keepalive:s.isFinalHarvest},1e4),o={success:n.ok,status:n.status,statusText:n.statusText};this.handleRequestComplete(e,o,a)}catch(t){const i={success:!1,status:0,error:t.message};this.handleRequestComplete(e,i,a)}}handleRequestComplete(e,t,i){const{callback:s}=e;s({retry:!t.success&&(0===t.status||function(e){switch(e){case 408:case 429:case 500:return!0;case 401:case 403:case 404:return!1}return e>=502&&e<=504||e>=512&&e<=530}(t.status)),status:t.status,error:t.error})}async sendWithBeacon(e,t){try{return navigator.sendBeacon(e,t)}catch(e){return r.warn("sendBeacon failed, falling back to fetch:",e.message),!1}}async fetchWithTimeout(e,t,i){const s=new AbortController,r=setTimeout(()=>s.abort(),i);try{const i=await fetch(e,{...t,signal:s.signal});return clearTimeout(r),i}catch(e){if(clearTimeout(r),"AbortError"===e.name)throw new Error(`Request timeout after ${i}ms`);throw e}}}function z(e,t){return!!t&&(t.actionName===c.Events.QOE_AGGREGATE?t.viewId?e.addOrReplaceByActionNameAndViewId(c.Events.QOE_AGGREGATE,t.viewId,t):e.addOrReplaceByActionName(c.Events.QOE_AGGREGATE,t):e.add(t))}function U(e,t,i){if(!e||!t)return;const s=i?e.findByActionNameAndViewId(c.Events.QOE_AGGREGATE,i):e.findByActionName(c.Events.QOE_AGGREGATE);if(!s)return;const r={...s};for(const e of a.QOE_KPI_KEYS)e in t&&(r[e]=t[e]);i?e.addOrReplaceByActionNameAndViewId(c.Events.QOE_AGGREGATE,i,r):e.addOrReplaceByActionName(c.Events.QOE_AGGREGATE,r)}function G(e,t){const i=e[t.viewId];if(!i)return!1;for(const e of a.QOE_KPI_KEYS)if(t[e]!==i[e])return!1;return!0}function M(e,t){const i={};for(const e of a.QOE_KPI_KEYS)i[e]=t[e];e[t.viewId]=i}function K(e,t,i){if(t)return e;const s=[];for(const t of e)t.actionName===c.Events.QOE_AGGREGATE?i.add(t):s.push(t);return s}function $(e,t,i){for(let s=e.length-1;s>=0;s--){const r=e[s];r.actionName===c.Events.QOE_AGGREGATE&&(!i&&G(t,r)?e.splice(s,1):M(t,r))}}function j({interval:e,onTick:t,errorLabel:i}){let s=!1,a=null,n=e;function o(){s&&(a=setTimeout(async()=>{a=null;try{await t()}catch(e){r.error(`${i}: scheduled tick failed:`,e.message)}finally{s&&o()}},n))}return{start(){s||(s=!0,o())},stop(){s=!1,a&&(clearTimeout(a),a=null)},cancelAndReschedule(){a&&(clearTimeout(a),a=null),s&&o()},updateInterval(e){"number"!=typeof e||e<=0||(n=e,s&&a&&(clearTimeout(a),a=null,o()))},isRunning:()=>s}}class W{eventBuffer;retryQueueHandler;httpClient;fallBackUrl;retryCount;harvestCycle;isHarvesting;qoeCycleCount;forceNextQoeCycle;beforeDrainCallback;_lastSentQoeKpis;timer;constructor(e){this.eventBuffer=e,this.retryQueueHandler=new x,this.httpClient=new q,this.fallBackUrl="",this.retryCount=0,this.eventBuffer instanceof H&&this.eventBuffer.setSmartHarvestCallback((e,t)=>this.triggerSmartHarvest(e,t)),this.harvestCycle=a.INTERVAL,this.isHarvesting=!1,this.qoeCycleCount=1,this.forceNextQoeCycle=!1,this.beforeDrainCallback=null,this._lastSentQoeKpis={},this.timer=j({interval:this.harvestCycle,onTick:()=>this.onHarvestInterval(),errorLabel:"HarvestScheduler"}),this.setupPageLifecycleHandlers()}get isStarted(){return this.timer.isRunning()}startScheduler(){this.timer.isRunning()?r.warn("Harvest scheduler is already started"):(r.notice("Starting harvest scheduler",{harvestCycle:this.harvestCycle,eventBufferSize:this.eventBuffer?this.eventBuffer.size():0}),this.timer.start())}stopScheduler(){this.timer.isRunning()&&(this.timer.stop(),r.notice("Harvest scheduler stopped"))}async triggerSmartHarvest(e,t){if(r.notice(`${e} harvest triggered at ${t}% threshold`,{type:e,threshold:t}),this.eventBuffer&&!this.eventBuffer.isEmpty())try{await this.triggerHarvest({})}catch(t){r.error(`${e} harvest failed:`,t.message)}finally{this.timer.cancelAndReschedule()}}async onHarvestInterval(){const e=this.eventBuffer&&!this.eventBuffer.isEmpty(),t=this.retryQueueHandler&&this.retryQueueHandler.getQueueSize()>0;(e||t)&&await this.triggerHarvest({})}async triggerHarvest(e={}){if(this.isHarvesting)return{success:!1,reason:"harvest_in_progress"};this.isHarvesting=!0;try{let t=this.drainEvents(e);if(e.isFinalHarvest){const e=a.MAX_BEACON_SIZE;(f(t)??0)>e&&(t=this.trimEventsToFit(t,e))}const i=await this.sendChunk(t,e,!0);return{success:i.success,totalChunks:1,results:[i]}}catch(e){return r.error("Harvest cycle failed:",e.message),this.handleHarvestFailure(e),{success:!1,error:e.message}}finally{this.isHarvesting=!1}}trimEventsToFit(e,t){if(0===e.length)return e;const i=[];let s=0;for(let r=e.length-1;r>=0;r--){const a=e[r],n=f({ins:[a,...i]})??0;n>t||(i.unshift(a),s=n)}const a=e.length-i.length;if(a>0){const n=e.slice(0,a);r.warn(`Discarded ${a} events to fit beacon size limit`,{originalCount:e.length,trimmedCount:i.length,finalSize:s,maxSize:t}),this.retryQueueHandler&&this.retryQueueHandler.addFailedEvents(n)}return i}drainEvents(e={}){const t=window.NRVIDEO?.config?.qoeIntervalFactor??1,i=!!e.isFinalHarvest||this.forceNextQoeCycle,s=(this.qoeCycleCount-1)%t==0||i;if(this.forceNextQoeCycle&&(this.forceNextQoeCycle=!1),this.beforeDrainCallback&&"function"==typeof this.beforeDrainCallback)try{this.beforeDrainCallback()}catch(e){r.error("Before drain callback failed:",e.message)}let n=K(this.eventBuffer.drain(),s,this.eventBuffer);this.qoeCycleCount++,$(n,this._lastSentQoeKpis,i);let o=[...n],l=f(n)??0;if(this.retryQueueHandler&&this.retryQueueHandler.getQueueSize()>0){const e=a.MAX_PAYLOAD_SIZE-l,t=a.MAX_EVENTS_PER_BATCH-o.length;if(e>0&&t>0){const i=this.retryQueueHandler.getRetryEventsToFit(e,t);i.length>0&&(o=[...i,...o])}}return o}async sendChunk(e,t,i){const s={url:function(e){try{if(!window.NRVIDEO||!window.NRVIDEO.info)throw new Error("NRVIDEO info is not available.");let{beacon:t,licenseKey:i,applicationID:s}=window.NRVIDEO.info;if(!t||!i)throw new Error("Options object provided by New Relic is not correctly initialized");return s?`https://${e||t}/ins/1/${i}?a=${s}&v=${n}&ref=${window.location.href}&ca=VA`:`https://${e||t}/ins/1/${i}?&v=${n}&ref=${window.location.href}&ca=VA`}catch(e){return console.error(e.message),null}}(this.fallBackUrl),payload:{body:{ins:e}},options:{...t,isLastChunk:i}};return new Promise(t=>{this.httpClient.send(s,i=>{i.retry?this.handleRequestFailure(e):(this.retryCount=0,this.fallBackUrl=""),t({success:!i.retry,status:i.status,error:i.error,chunk:e,eventCount:e.length})})})}handleRequestFailure(e){this.retryQueueHandler.addFailedEvents(e),"US"===window.NRVIDEO?.info?.region&&(this.retryCount++,this.retryCount>5?(this.retryCount=0,this.fallBackUrl=""):this.retryCount>=2&&(this.fallBackUrl=a.COLLECTOR.US[1]))}handleHarvestFailure(e){r.warn("Harvest failure handled",{error:e.message})}updateHarvestInterval(e){"number"!=typeof e||isNaN(e)?r.warn("Invalid newInterval provided to updateHarvestInterval"):e<1e3||e>3e5?r.warn("newInterval out of bounds (1000-300000), ignoring"):this.harvestCycle!==e&&(this.harvestCycle=e,r.notice("Updated harvestCycle:",this.harvestCycle),this.timer.updateInterval(e))}setupPageLifecycleHandlers(){let e=!1;const t=()=>{e||(e=!0,this.triggerHarvest({isFinalHarvest:!0,force:!0}))};document.addEventListener("visibilitychange",()=>{document.hidden&&t()}),window.addEventListener("pagehide",()=>{t()}),window.addEventListener("beforeunload",()=>{t()})}}const Y=new class{isInitialized;harvestScheduler;eventBuffer;constructor(){this.isInitialized=!1,this.harvestScheduler=null,this.eventBuffer=null}initialize(){if(this.isInitialized)r.warn("Video analytics agent already initialized");else try{this.eventBuffer=new H,this.harvestScheduler=new W(this.eventBuffer),this.harvestScheduler.startScheduler(),this.isInitialized=!0,r.notice("Video analytics agent initialized successfully")}catch(e){r.error("Failed to initialize video analytics agent:",e.message)}}addEvent(e){this.isInitialized||(r.warn("Video analytics agent not initialized, initializing now"),this.initialize());try{return z(this.eventBuffer,e)}catch(e){return r.error("Failed to add event to harvesting system:",e.message),!1}}setHarvestInterval(e){this.isInitialized||this.initialize(),this.harvestScheduler.updateHarvestInterval(e)}forceNextQoeCycle(){this.harvestScheduler&&(this.harvestScheduler.forceNextQoeCycle=!0)}setBeforeDrainCallback(e){this.harvestScheduler&&(this.harvestScheduler.beforeDrainCallback=e)}refreshQoeKpis(e,t){U(this.eventBuffer,e,t)}};v("Browser",Y);const X=Y;class Z{accountId;applicationToken;endpoint;harvestInterval;maxBufferSize;deviceInfo;eventBuffer;dataToken;isHarvesting;isDisposed;_isFetchingToken;timer;qoeCycleCount;forceQoeNextCycle;beforeDrainCallback;_lastSentQoeKpis;_connectAttempt;constructor({accountId:e,applicationToken:t,endpoint:i,deviceInfo:s}={}){if(!t)throw new Error("applicationToken is required");const a=i?.toLowerCase();if(!(a in A))throw new Error("Invalid endpoint");this.accountId=e,this.applicationToken=t,this.endpoint=a,this.harvestInterval=6e4,this.maxBufferSize=100,s||r.warn("ConnectedDeviceHarvester: no deviceInfo provided — using placeholder defaults. Pass info.deviceInfo for accurate device data.");const{uuid:n,osVersion:o,deviceModel:l,deviceManufacturer:h,osBuild:d,appBuild:c,architecture:u}=s??{};this.deviceInfo={uuid:n||S[5],osVersion:o||S[1],deviceModel:l||S[2],deviceManufacturer:h||S[8],osBuild:d||y.osBuild,appBuild:c||y.appBuild,architecture:u||y.architecture},this.eventBuffer=new H,this.eventBuffer.setSmartHarvestCallback((e,t)=>this.triggerSmartHarvest(e,t)),this.dataToken=null,this.isHarvesting=!1,this.isDisposed=!1,this._isFetchingToken=!1,this.timer=j({interval:this.harvestInterval,onTick:()=>this.sendBufferedEvents(),errorLabel:"ConnectedDeviceHarvester"}),this.qoeCycleCount=1,this.forceQoeNextCycle=!1,this.beforeDrainCallback=null,this._lastSentQoeKpis={},this._connectAttempt=0,this.initialise()}getEndpointBaseUrl(){return A[this.endpoint]??A.us}async initialise(){await this.fetchDataTokens(),this.isDisposed||this.dataToken&&this.startHarvestInterval()}async fetchDataTokens(){if(!this._isFetchingToken){this._isFetchingToken=!0;try{for(let e=0;e<3;e++){if(this.isDisposed)return;const t=`${this.getEndpointBaseUrl()}/v5/connect`;try{r.notice(`ConnectedDeviceHarvester: POST ${t} (attempt ${e+1}/3)`);const i=await this._fetchWithTimeout(t,{method:"POST",headers:{"Content-Type":"application/json","X-App-License-Key":this.applicationToken},body:JSON.stringify(p)},1e4);if(!i.ok){let e="";try{e=await i.text()}catch(e){}throw new Error(`HTTP ${i.status} body=${e}`)}const s=await i.json();if(!s||!s.data_token)throw new Error("Missing data_token in connect response");return this.dataToken=s.data_token,this._connectAttempt=e+1,void r.notice("ConnectedDeviceHarvester: dataToken acquired")}catch(t){if(this._connectAttempt=e+1,r.error(`ConnectedDeviceHarvester: /v5/connect failed (attempt ${this._connectAttempt}/3):`,t.message),e>=2)return void r.error("ConnectedDeviceHarvester: Max retries reached — dataToken stays null");await new Promise(e=>setTimeout(e,1e4))}}}finally{this._isFetchingToken=!1}}}startHarvestInterval(){this.isDisposed||this.timer.start()}async triggerSmartHarvest(e,t){if(r.notice(`ConnectedDeviceHarvester: smart-harvest trigger (${e} at ${t}%)`),this.eventBuffer&&!this.eventBuffer.isEmpty())try{await this.sendBufferedEvents()}catch(t){r.error(`${e} smart-harvest failed:`,t.message)}finally{this.timer.cancelAndReschedule()}}addEvent(e){try{return z(this.eventBuffer,e)}catch(e){return r.error("ConnectedDeviceHarvester.addEvent failed:",e.message),!1}}forceQoeNextHarvest(){this.forceQoeNextCycle=!0}setBeforeDrainCallback(e){"function"!=typeof e&&null!==e||(this.beforeDrainCallback=e)}refreshQoeKpis(e,t){U(this.eventBuffer,e,t)}setHarvestInterval(e){"number"!=typeof e||e<=0||(this.harvestInterval=e,this.timer.updateInterval(e))}async sendBufferedEvents(){if(this.isHarvesting)return;if(!this.dataToken)return;if(this.eventBuffer.isEmpty())return;if("function"==typeof this.beforeDrainCallback)try{this.beforeDrainCallback()}catch(e){r.error("ConnectedDeviceHarvester beforeDrainCallback failed:",e.message)}this.isHarvesting=!0;const e=this.eventBuffer.drain(),t=globalThis.__NRVIDEO_CD__?.config?.qoeIntervalFactor??1,i=this.forceQoeNextCycle,s=(this.qoeCycleCount-1)%t==0||i;this.forceQoeNextCycle&&(this.forceQoeNextCycle=!1);const a=K(e,s,this.eventBuffer);if(this.qoeCycleCount++,$(a,this._lastSentQoeKpis,i),0===a.length)return void(this.isHarvesting=!1);const n=`${this.getEndpointBaseUrl()}/v3/data`,o={"Content-Type":"application/json","X-App-License-Key":this.applicationToken},l=()=>F(JSON.stringify([this.dataToken,this._buildDeviceInfo(),0,[],[],[],[],[],this._buildMetadata(),a]),globalThis.__NRVIDEO_CD__?.config?.obfuscate);try{let e=await this._fetchWithTimeout(n,{method:"POST",headers:o,body:l()},3e4);if(401===e.status){r.notice("ConnectedDeviceHarvester: /v3/data returned 401 — re-queuing events and reconnecting"),this.dataToken=null,this._connectAttempt=0;for(const e of a)this.eventBuffer.add(e);return void this.initialise()}if(!e.ok)throw new Error(`HTTP ${e.status}`);r.notice(`ConnectedDeviceHarvester: sent ${a.length} events`)}catch(e){r.error("ConnectedDeviceHarvester: /v3/data send failed:",e.message);for(const e of a)this.eventBuffer.add(e)}finally{this.isHarvesting=!1}}_buildDeviceInfo(){const e=this.deviceInfo;return[S[0],e.osVersion,e.deviceModel,S[3],S[4],e.uuid,"","",e.deviceManufacturer,S[9]]}_buildMetadata(){const e=this.deviceInfo;return{...y,osBuild:e.osBuild,appBuild:e.appBuild,architecture:e.architecture}}_fetchWithTimeout(e,t,i){const s=new AbortController,r=setTimeout(()=>s.abort(),i);return fetch(e,{...t,signal:s.signal}).finally(()=>clearTimeout(r))}async dispose(){return this.isDisposed=!0,this.timer.stop(),this.sendBufferedEvents()}}const J=new class{isInitialized;harvester;constructor(){this.isInitialized=!1,this.harvester=null}initialize(){if(this.isInitialized)return;const e=globalThis.__NRVIDEO_CD__?.info;if(e)try{this.harvester=new Z(e),this.isInitialized=!0,r.notice("ConnectedDeviceAnalyticsAgent initialized")}catch(e){r.error("ConnectedDeviceAnalyticsAgent.initialize failed:",e.message)}else r.warn("ConnectedDeviceAnalyticsAgent.initialize: globalThis.__NRVIDEO_CD__.info is missing")}addEvent(e){return this.isInitialized||this.initialize(),!!this.isInitialized&&this.harvester.addEvent(e)}forceQoeNextHarvest(){this.harvester&&this.harvester.forceQoeNextHarvest()}forceNextQoeCycle(){this.forceQoeNextHarvest()}setBeforeDrainCallback(e){this.harvester&&this.harvester.setBeforeDrainCallback(e)}refreshQoeKpis(e,t){this.isInitialized||this.initialize(),this.harvester&&this.harvester.refreshQoeKpis(e,t)}setHarvestInterval(e){this.isInitialized||this.initialize(),this.harvester&&this.harvester.setHarvestInterval(e)}};v("Vega",J);const ee=J,te={Constants:a,Chrono:h,Log:r,Emitter:o,Tracker:c,VideoTracker:P,VideoTrackerState:C,Core:k,version:n,NrVideoEventAggregator:H,RetryQueueHandler:x,OptimizedHttpClient:q,HarvestScheduler:W,recordEvent:E};export{ee as connectedDeviceAnalyticsHarvester,te as default,T as getRegisteredHarvester,X as videoAnalyticsHarvester};
|
|
3
3
|
//# sourceMappingURL=index.js.map
|