{"version":3,"sources":["webpack://nrvideo/webpack/universalModuleDefinition","webpack://nrvideo/webpack/bootstrap","webpack://nrvideo/./node_modules/newrelic-video-core/src/log.js","webpack://nrvideo/./node_modules/newrelic-video-core/src/backend.js","webpack://nrvideo/./node_modules/newrelic-video-core/src/chrono.js","webpack://nrvideo/./node_modules/newrelic-video-core/src/index.js","webpack://nrvideo/./node_modules/newrelic-video-core/src/emitter.js","webpack://nrvideo/./node_modules/newrelic-video-core/src/tracker.js","webpack://nrvideo/./node_modules/newrelic-video-core/src/videotrackerstate.js","webpack://nrvideo/./src/index.js","webpack://nrvideo/./node_modules/newrelic-video-core/src/plugins/nrinsightsbackend.js","webpack://nrvideo/./node_modules/newrelic-video-core/src/core.js","webpack://nrvideo/./node_modules/newrelic-video-core/src/constants.js","webpack://nrvideo/./node_modules/newrelic-video-core/src/videotracker.js","webpack://nrvideo/./src/tracker.js"],"names":["root","factory","exports","module","define","amd","window","installedModules","__webpack_require__","moduleId","i","l","modules","call","m","c","d","name","getter","o","Object","defineProperty","enumerable","get","r","Symbol","toStringTag","value","t","mode","__esModule","ns","create","key","bind","n","object","property","prototype","hasOwnProperty","p","s","Log","msg","_report","Levels","ERROR","WARNING","slice","arguments","NOTICE","DEBUG","extraEvents","report","level","e","debug","type","playerEvents","shift","concat","length","on","addEventListener","addEventHandler","warn","err","color","hh","mm","ss","mmm","logMethod","prefix","includeTime","Date","getDate","getMinutes","getSeconds","getMilliseconds","_getCurrentTime","_letters","_level2letter","SILENT","colorful","document","documentMode","_plainReport","Array","console","log","error","undefined","cast","splice","apply","ALL","4","3","2","1","location","search","exec","_loadLevelFromUrl","Backend","this","_attributes","event","data","assign","attr","append","Chrono","reset","startTime","stopTime","offset","getTime","getDeltaTime","chrono","Constants","Emitter","Tracker","VideoTracker","VideoTrackerState","Core","NRInsightsBackend","version","callback","_listeners","push","index","indexOf","isArray","forEach","target","pkg","options","customData","heartbeat","parentTracker","_trackerReadyChrono","start","setOptions","unregisterListeners","_heartbeatInterval","setInterval","sendHeartbeat","Math","max","getHeartbeat","clearInterval","att","send","Events","HEARTBEAT","trackerName","getTrackerName","trackerVersion","getTrackerVersion","coreVersion","timeSinceTrackerReady","hidden","isBackgroundEvent","emit","getAttributes","_createdAt","now","_viewSession","_viewCount","_isAd","numberOfErrors","numberOfAds","numberOfVideos","totalPlaytime","totalAdPlaytime","isAdBreak","initialBufferingHappened","resetFlags","resetChronos","isPlayerReady","isRequested","isStarted","isPaused","isSeeking","isBuffering","isPlaying","timeSinceRequested","timeSinceStarted","timeSincePaused","timeSinceSeekBegin","timeSinceBufferBegin","timeSinceAdBreakStart","timeSinceLastDownload","timeSinceLastHeartbeat","timeSinceLastRenditionChange","timeSinceLastAdQuartile","timeSinceLastAd","timeSinceResumed","timeSinceSeekEnd","playtimeSinceLastEvent","customTimeSinceAttributes","isAd","time","random","toString","substring","getViewSession","timeSinceAdRequested","timeSinceLastAdHeartbeat","timeSinceAdStarted","timeSinceAdPaused","timeSinceAdBufferBegin","timeSinceAdSeekBegin","timeSinceAdBreakBegin","entries","isInitialBuffering","bufferType","stop","nrvideo","Html5Tracker","accountId","apiKey","eventType","_accountId","_apiKey","_eventType","_eventBuffer","_harvestLocked","_lastTimestamp","harvestHandler","Source","TIMER","generateAttributes","timestamp","href","origin","pathname","referrer","OSName","navigator","userAgent","match","agentName","deviceType","source","pushEventToInsights","pop","ev","requestOptions","method","headers","body","JSON","stringify","url","fetch","then","response","json","insightsRequestResponse","catch","FETCH","tracker","trackers","eventHandler","trackerInit","off","dispose","backend","backendInstance","getBackend","newrelic","addPageAction","isErrorShown","ret","cleanData","notice","AdPositions","PRE","MID","POST","player","state","TrackerState","adsTracker","_lastBufferType","setPlayer","tag","setAdsTracker","setIsAd","getElementById","registerListeners","disposeAdsTracker","funnelAdEvents","stopHeartbeat","getViewId","webkitVideoDecodedByteCount","bitrate","_lastWebkitBitrate","delta","seconds","round","saveNewRendition","current","getRenditionBitrate","last","_lastAdRendition","_lastRendition","videoHeight","videoWidth","duration","currentTime","currentSrc","playbackRate","muted","autoplay","preload","viewSession","viewId","playerName","getPlayerName","playerVersion","getPlayerVersion","pageUrl","adId","getVideoId","adTitle","getTitle","adBitrate","getBitrate","getWebkitBitrate","adRenditionName","getRenditionName","adRenditionBitrate","adRenditionHeight","getRenditionHeight","adRenditionWidth","getRenditionWidth","adDuration","getDuration","adPlayhead","getPlayhead","adLanguage","getLanguage","adSrc","getSrc","adCdn","getCdn","adIsMuted","isMuted","adFps","getFps","adQuartile","getAdQuartile","adPosition","getAdPosition","adCreativeId","getAdCreativeId","adPartner","getAdPartner","contentId","contentTitle","contentIsLive","isLive","contentBitrate","contentRenditionName","contentRenditionBitrate","contentRenditionHeight","contentRenditionWidth","contentDuration","contentPlayhead","contentLanguage","contentSrc","contentPlayrate","getPlayrate","contentIsFullscreen","isFullscreen","contentIsMuted","contentCdn","contentIsAutoplayed","isAutoplayed","contentPreload","getPreload","contentFps","getStateAttributes","actionName","timeSinceAttName","setTimeSinceAttribute","goPlayerReady","PLAYER_READY","goRequest","goViewCountUp","AD_REQUEST","CONTENT_REQUEST","startHeartbeat","goHeartbeat","goStart","AD_START","CONTENT_START","goEnd","AD_END","CONTENT_END","goLastAd","goPause","AD_PAUSE","CONTENT_PAUSE","goResume","AD_RESUME","CONTENT_RESUME","goBufferStart","AD_BUFFER_START","CONTENT_BUFFER_START","buildBufferAttributes","goBufferEnd","AD_BUFFER_END","CONTENT_BUFFER_END","calculateBufferType","goSeekStart","AD_SEEK_START","CONTENT_SEEK_START","goSeekEnd","AD_SEEK_END","CONTENT_SEEK_END","DOWNLOAD","goDownload","goError","AD_ERROR","CONTENT_ERROR","getRenditionShift","AD_RENDITION_CHANGE","CONTENT_RENDITION_CHANGE","goRenditionChange","AD_HEARTBEAT","CONTENT_HEARTBEAT","goAdBreakStart","AD_BREAK_START","goAdBreakEnd","AD_BREAK_END","quartile","AD_QUARTILE","goAdQuartile","AD_CLICK","debugCommonVideoEvents","onDownload","onPlay","onPlaying","onPause","onSeeking","onSeeked","onError","onEnded","onWaiting","removeEventListener","sendDownload","sendRequest","sendBufferEnd","sendResume","sendStart","sendPause","sendSeekStart","sendSeekEnd","sendError","sendEnd","networkState","NETWORK_LOADING","readyState","HAVE_FUTURE_DATA","sendBufferStart"],"mappings":";;;;;;CAAA,SAA2CA,EAAMC,GAC1B,iBAAZC,SAA0C,iBAAXC,OACxCA,OAAOD,QAAUD,IACQ,mBAAXG,QAAyBA,OAAOC,IAC9CD,OAAO,GAAIH,GACe,iBAAZC,QACdA,QAAiB,QAAID,IAErBD,EAAc,QAAIC,IARpB,CASGK,QAAQ,WACX,O,YCTE,IAAIC,EAAmB,GAGvB,SAASC,EAAoBC,GAG5B,GAAGF,EAAiBE,GACnB,OAAOF,EAAiBE,GAAUP,QAGnC,IAAIC,EAASI,EAAiBE,GAAY,CACzCC,EAAGD,EACHE,GAAG,EACHT,QAAS,IAUV,OANAU,EAAQH,GAAUI,KAAKV,EAAOD,QAASC,EAAQA,EAAOD,QAASM,GAG/DL,EAAOQ,GAAI,EAGJR,EAAOD,QA0Df,OArDAM,EAAoBM,EAAIF,EAGxBJ,EAAoBO,EAAIR,EAGxBC,EAAoBQ,EAAI,SAASd,EAASe,EAAMC,GAC3CV,EAAoBW,EAAEjB,EAASe,IAClCG,OAAOC,eAAenB,EAASe,EAAM,CAAEK,YAAY,EAAMC,IAAKL,KAKhEV,EAAoBgB,EAAI,SAAStB,GACX,oBAAXuB,QAA0BA,OAAOC,aAC1CN,OAAOC,eAAenB,EAASuB,OAAOC,YAAa,CAAEC,MAAO,WAE7DP,OAAOC,eAAenB,EAAS,aAAc,CAAEyB,OAAO,KAQvDnB,EAAoBoB,EAAI,SAASD,EAAOE,GAEvC,GADU,EAAPA,IAAUF,EAAQnB,EAAoBmB,IAC/B,EAAPE,EAAU,OAAOF,EACpB,GAAW,EAAPE,GAA8B,iBAAVF,GAAsBA,GAASA,EAAMG,WAAY,OAAOH,EAChF,IAAII,EAAKX,OAAOY,OAAO,MAGvB,GAFAxB,EAAoBgB,EAAEO,GACtBX,OAAOC,eAAeU,EAAI,UAAW,CAAET,YAAY,EAAMK,MAAOA,IACtD,EAAPE,GAA4B,iBAATF,EAAmB,IAAI,IAAIM,KAAON,EAAOnB,EAAoBQ,EAAEe,EAAIE,EAAK,SAASA,GAAO,OAAON,EAAMM,IAAQC,KAAK,KAAMD,IAC9I,OAAOF,GAIRvB,EAAoB2B,EAAI,SAAShC,GAChC,IAAIe,EAASf,GAAUA,EAAO2B,WAC7B,WAAwB,OAAO3B,EAAgB,SAC/C,WAA8B,OAAOA,GAEtC,OADAK,EAAoBQ,EAAEE,EAAQ,IAAKA,GAC5BA,GAIRV,EAAoBW,EAAI,SAASiB,EAAQC,GAAY,OAAOjB,OAAOkB,UAAUC,eAAe1B,KAAKuB,EAAQC,IAGzG7B,EAAoBgC,EAAI,GAIjBhC,EAAoBA,EAAoBiC,EAAI,G,6UC5E/CC,E,6KAMkB,2BAALC,EAAK,qBAALA,EAAK,gBACpBC,EAAQD,EAAKD,EAAIG,OAAOC,MAAO,a,6BASZ,2BAALH,EAAK,qBAALA,EAAK,gBACnBC,EAAQD,EAAKD,EAAIG,OAAOE,QAAS,gB,+BASZ,2BAALJ,EAAK,qBAALA,EAAK,gBACrBC,EAAQ,GAAGI,MAAMnC,KAAKoC,WAAYP,EAAIG,OAAOK,OAAQ,c,8BASjC,2BAALP,EAAK,qBAALA,EAAK,gBACpBC,EAAQD,EAAKD,EAAIG,OAAOM,MAAO,Y,6CAsBFhC,EAAGiC,EAAaC,GAC7C,IACE,GAAIX,EAAIY,OAASZ,EAAIG,OAAOM,MAAO,CACjCE,EAASA,GAAU,SAAUE,GAC3Bb,EAAIc,MAAM,UAAYD,EAAEE,OAG1B,IAAIC,EAAe,CACjB,UAAW,YAAa,UAAW,QAAS,OAAQ,UACpD,QAAS,SAAU,QAAS,QAAS,OAAQ,UAAW,SACxD,UAAW,UAAW,aAAc,YAAa,kBAE/CN,IACqB,OAAnBA,EAAY,IACdA,EAAYO,QACZD,EAAeN,GAEfM,EAAeA,EAAaE,OAAOR,IAIvC,IAAK,IAAI1C,EAAI,EAAGA,EAAIgD,EAAaG,OAAQnD,IACtB,mBAANS,EACTA,EAAEN,KAAKP,OAAQoD,EAAahD,GAAI2C,GACvBlC,EAAE2C,GACX3C,EAAE2C,GAAGJ,EAAahD,GAAI2C,GACblC,EAAE4C,iBACX5C,EAAE4C,iBAAiBL,EAAahD,GAAI2C,GAC3BlC,EAAE6C,gBACX7C,EAAE6C,gBAAgBN,EAAahD,GAAI2C,GAEnCX,EAAIuB,KAAK,iEAAkE9C,IAIjF,MAAO+C,GACPxB,EAAIuB,KAAKC,Q,KAmEf,SAAStB,EAASD,EAAKW,EAAOa,GAC5Bb,EAAQA,GAASZ,EAAIG,OAAOK,OAC5BiB,EAAQA,GAAS,WAEjB,IAyCInD,EACAoD,EACAC,EACAC,EACAC,EAlCIC,EAXJC,EAAS/B,EAAI+B,QACb/B,EAAIgC,cAAaD,IAwCjBzD,EAAI,IAAI2D,KACRP,GAAM,IAAMpD,EAAE4D,WAAW5B,OAAO,GAChCqB,GAAM,IAAMrD,EAAE6D,cAAc7B,OAAO,GACnCsB,GAAM,IAAMtD,EAAE8D,cAAc9B,OAAO,GACnCuB,GAAO,KAAOvD,EAAE+D,mBAAmB/B,OAAO,GACvC,IAAMoB,EAAK,IAAMC,EAAK,IAAMC,EAAK,IAAMC,EA7CfS,OAC/BP,GAkFF,SAAwBnB,GACtB,OAAO2B,EAAS3B,GAnFN4B,CAAc5B,GAAS,IAG7BZ,EAAIY,OAASA,GAASA,IAAUZ,EAAIG,OAAOsC,WACxCzC,EAAI0C,UAAiC,oBAAbC,UAA4BA,SAASC,aAkDtE,SAASC,EAAc5C,EAAK8B,GAC1B,GAAI9B,aAAe6C,MACjB,IAAK,IAAI1E,KAAK6B,EACZ4C,EAAa5C,EAAI7B,GAAI2D,OAGJ,iBAAR9B,EACT8C,QAAQC,IAAIjB,EAAS,IAAM9B,IAE3B8C,QAAQC,IAAIjB,EAAS,KACrBgB,QAAQC,IAAI/C,IA1DZ4C,CAAa5C,EAAK8B,IAKhBD,EADElB,IAAUZ,EAAIG,OAAOC,OAAS2C,QAAQE,MAC5BF,QAAQE,MACXrC,IAAUZ,EAAIG,OAAOE,SAAW0C,QAAQxB,KACrCwB,QAAQxB,KACXX,IAAUZ,EAAIG,OAAOM,OAASsC,QAAQjC,OAE5BoC,MAAftF,OAAOuF,KACGJ,QAAQjC,MAKViC,QAAQC,IAItBjB,EAAS,KAAOA,EAChB9B,EAAImD,OAAO,EAAG,EAAGrB,EAAQ,UAAYN,GACrCK,EAAUuB,MAAMN,QAAS9C,KA1F/BD,EAAIG,OAAS,CAEXsC,OAAQ,EAERrC,MAAO,EAEPC,QAAS,EAETG,OAAQ,EAERC,MAAO,EAEP6C,IAAK,GASPtD,EAAIY,MAAQZ,EAAIG,OAAOC,MAOvBJ,EAAI0C,UAAW,EAOf1C,EAAIgC,aAAc,EAOlBhC,EAAI+B,OAAS,YAyFb,IAAMQ,EAAW,CACfgB,EAAG,IACHC,EAAG,IACHC,EAAG,IACHC,EAAG,MA2BL,WACE,GAAsB,oBAAX9F,QAA0BA,OAAO+F,UAAY/F,OAAO+F,SAASC,OAAQ,CAC9E,IAAIxF,EAAI,4BAA4ByF,KAAKjG,OAAO+F,SAASC,QAC/C,OAANxF,IACW,SAATA,EAAE,GACJ4B,EAAIY,MAAQZ,EAAIG,OAAOmD,IAEvBtD,EAAIY,MAAQxC,EAAE,IAKP,OADF,8BAA8ByF,KAAKjG,OAAO+F,SAASC,UAE1D5D,EAAI0C,UAAW,IAMrBoB,G,UAEe9D,G,2UCjST+D,E,WAEF,c,4FAAc,SAKVC,KAAKC,YAAc,G,uCAQlBC,EAAOC,GACRA,EAAOzF,OAAO0F,OAAOD,GAAQ,GAAIH,KAAKC,e,mCAQ7B1E,EAAKN,GACd+E,KAAKC,YAAY1E,GAAON,I,oCAOdoF,GACVL,KAAKC,YAAYK,OAAOD,O,eAIjBN,G,2UCxCTQ,E,WAIJ,c,4FAAe,SACbP,KAAKQ,Q,0CAMLR,KAAKS,UAAY,EAGjBT,KAAKU,SAAW,EAchBV,KAAKW,OAAS,I,qCASd,OAAIX,KAAKS,UACAT,KAAKW,SAAU,IAAI1C,MAAO2C,UAAYZ,KAAKS,WAE3C,O,8BAQTT,KAAKS,WAAY,IAAIxC,MAAO2C,UAC5BZ,KAAKU,SAAW,I,6BAShB,OADAV,KAAKU,UAAW,IAAIzC,MAAO2C,UACpBZ,KAAKa,iB,8BAQZ,IAAIC,EAAS,IAAIP,EAIjB,OAHAO,EAAOL,UAAYT,KAAKS,UACxBK,EAAOJ,SAAWV,KAAKU,SACvBI,EAAOH,OAASX,KAAKW,OACdG,M,eAIIP,G,sNC7Ef,I,IAAA,M,IACA,M,IACA,O,IACA,O,IACA,M,IACA,M,IACA,M,IACA,M,IACA,O,IACA,MACA,O,qDAGEQ,oB,EACAR,iB,EACAvE,c,EACAgF,kB,EACAC,kB,EACAC,uB,EACAC,4B,EACAC,e,EACArB,kB,EACAsB,4B,EACAC,mB,2UCjBIN,E,mKASAd,EAAOqB,GAET,GADAvB,KAAKwB,WAAaxB,KAAKwB,YAAc,GACb,mBAAbD,EAGT,OAFAvB,KAAKwB,WAAWtB,GAASF,KAAKwB,WAAWtB,IAAU,GACnDF,KAAKwB,WAAWtB,GAAOuB,KAAKF,GACrBvB,O,0BAWNE,EAAOqB,GAGV,GAFAvB,KAAKwB,WAAaxB,KAAKwB,YAAc,GAEjCxB,KAAKwB,WAAWtB,GAAQ,CAC1B,IAAIwB,EAAQ1B,KAAKwB,WAAWtB,GAAOyB,QAAQJ,IAC5B,IAAXG,GACF1B,KAAKwB,WAAWtB,GAAOd,OAAOsC,EAAO,GAGzC,OAAO1B,O,2BAUHE,EAAOC,GAAM,WAgBjB,OAfAH,KAAKwB,WAAaxB,KAAKwB,YAAc,GACrCrB,EAAOA,GAAQ,GAEXrB,MAAM8C,QAAQ5B,KAAKwB,WAAWtB,KAChCF,KAAKwB,WAAWtB,GAAO2B,SAAQ,SAACN,GAC9BA,EAASpH,KAAK,EAAM,CAAE4C,KAAMmD,EAAOC,KAAMA,EAAM2B,OAAQ,OAIvDhD,MAAM8C,QAAQ5B,KAAKwB,WAAW,OAChCxB,KAAKwB,WAAW,KAAKK,SAAQ,SAACN,GAC5BA,EAASpH,KAAK,EAAM,CAAE4C,KAAMmD,EAAOC,KAAMA,EAAM2B,OAAQ,OAIpD9B,S,eAIIgB,G,uUCtEHe,E,wJAAZ,M,IACA,M,IACA,M,uDAcMd,E,YAMJ,WAAae,I,4FAAS,e,iKAAA,iEAWpB,EAAKC,WAAa,GAKlB,EAAKC,UAAY,KAMjB,EAAKC,cAAgB,KAMrB,EAAKC,oBAAsB,IAAI7B,UAC/B,EAAK6B,oBAAoBC,QAEzBL,EAAUA,GAAW,GACrB,EAAKM,WAAWN,GAhCI,E,4WA2CVA,GACNA,IACEA,EAAQG,gBAAenC,KAAKmC,cAAgBH,EAAQG,eACpDH,EAAQC,aAAYjC,KAAKiC,WAAaD,EAAQC,YAC9CD,EAAQE,YAAWlC,KAAKkC,UAAYF,EAAQE,c,gCAQlDlC,KAAKuC,wB,iIA8CL,OAAIvC,KAAKkC,UACAlC,KAAKkC,UACHlC,KAAKmC,eAAiBnC,KAAKmC,cAAcD,UAC3ClC,KAAKmC,cAAcD,UAEnB,M,uCASTlC,KAAKwC,mBAAqBC,YACxBzC,KAAK0C,cAAclH,KAAKwE,MACxB2C,KAAKC,IAAI5C,KAAK6C,eAAgB,Q,sCAQ5B7C,KAAKwC,oBACPM,cAAc9C,KAAKwC,sB,oCAsBRO,GACb/C,KAAKgD,KAAK/B,EAAQgC,OAAOC,UAAWH,K,oCAmBvBA,GAOb,IAAK,IAAIxH,KANTwH,EAAMA,GAAO,IACTI,YAAcnD,KAAKoD,iBACvBL,EAAIM,eAAiBrD,KAAKsD,oBAC1BP,EAAIQ,YAAcxB,EAAIT,QACtByB,EAAIS,sBAAwBxD,KAAKoC,oBAAoBvB,eAErCb,KAAKiC,WACnBc,EAAIxH,GAAOyE,KAAKiC,WAAW1G,GAO7B,OAJuB2D,MAAnBP,SAAS8E,SACXV,EAAIW,kBAAoB/E,SAAS8E,QAG5BV,I,0CAKP,OAAOhB,EAAIT,U,uCAKX,MAAO,iB,2BAaHpB,EAAO6C,GACX/C,KAAK2D,KAAKzD,EAAOF,KAAK4D,cAAcb,Q,GArNlB/B,WAgOtBC,EAAQgC,OAAS,CAEfC,UAAW,a,UAGEjC,G,kpDCrPf,M,IACA,M,uDAKME,E,WAEJ,c,4FAAe,SACbnB,KAAKQ,QAMLR,KAAK6D,WAAa5F,KAAK6F,M,0CASvB9D,KAAK+D,aAAe,KAMpB/D,KAAKgE,WAAa,EAMlBhE,KAAKiE,OAAQ,EAKbjE,KAAKkE,eAAiB,EAKtBlE,KAAKmE,YAAc,EAKnBnE,KAAKoE,eAAiB,EAKtBpE,KAAKqE,cAAgB,EAKpBrE,KAAKsE,gBAAkB,EAGxBtE,KAAKuE,WAAY,EAGjBvE,KAAKwE,0BAA2B,EAEhCxE,KAAKyE,aACLzE,KAAK0E,iB,mCAML1E,KAAK2E,eAAgB,EAGrB3E,KAAK4E,aAAc,EAGnB5E,KAAK6E,WAAY,EAGjB7E,KAAK8E,UAAW,EAGhB9E,KAAK+E,WAAY,EAGjB/E,KAAKgF,aAAc,EAGnBhF,KAAKiF,WAAY,I,qCAMjBjF,KAAKkF,mBAAqB,IAAI3E,UAG9BP,KAAKmF,iBAAmB,IAAI5E,UAG5BP,KAAKoF,gBAAkB,IAAI7E,UAG3BP,KAAKqF,mBAAqB,IAAI9E,UAG9BP,KAAKsF,qBAAuB,IAAI/E,UAGhCP,KAAKuF,sBAAwB,IAAIhF,UAGjCP,KAAKwF,sBAAwB,IAAIjF,UAGjCP,KAAKyF,uBAAyB,IAAIlF,UAGlCP,KAAK0F,6BAA+B,IAAInF,UAGxCP,KAAK2F,wBAA0B,IAAIpF,UAGnCP,KAAK4F,gBAAkB,IAAIrF,UAG3BP,KAAK6F,iBAAmB,IAAItF,UAG5BP,KAAK8F,iBAAmB,IAAIvF,UAG5BP,KAAK+F,uBAAyB,IAAIxF,UAGlCP,KAAKgG,0BAA4B,K,6BAKjC,OAAOhG,KAAKiE,Q,8BAILgC,GACPjG,KAAKiE,MAAQgC,I,4CAQQ1L,GACrByF,KAAKgG,0BAA0BzL,GAAQ,IAAIgG,UAC3CP,KAAKgG,0BAA0BzL,GAAM8H,U,+CAQb9H,UACjByF,KAAKgG,0BAA0BzL,K,uCAOtC,IAAKyF,KAAK+D,aAAc,CACtB,IAAImC,GAAO,IAAIjI,MAAO2C,UAClBuF,EAASxD,KAAKwD,SAASC,SAAS,IAAIC,UAAU,GAAK1D,KAAKwD,SAASC,SAAS,IAAIC,UAAU,GAE5FrG,KAAK+D,aAAemC,EAAO,IAAMC,EAGnC,OAAOnG,KAAK+D,e,kCAQZ,OAAO/D,KAAKsG,iBAAmB,IAAMtG,KAAKgE,a,yCASxBjB,GAClBA,EAAMA,GAAO,GAET/C,KAAKiG,QACHjG,KAAK4E,cACP7B,EAAIwD,qBAAuBvG,KAAKkF,mBAAmBrE,eACnDkC,EAAIyD,yBAA2BxG,KAAKyF,uBAAuB5E,gBAEzDb,KAAK6E,YAAW9B,EAAI0D,mBAAqBzG,KAAKmF,iBAAiBtE,gBAC/Db,KAAK8E,WAAU/B,EAAI2D,kBAAoB1G,KAAKoF,gBAAgBvE,gBAC5Db,KAAKgF,cAAajC,EAAI4D,uBAAyB3G,KAAKsF,qBAAqBzE,gBACzEb,KAAK+E,YAAWhC,EAAI6D,qBAAuB5G,KAAKqF,mBAAmBxE,gBACnEb,KAAKuE,YAAWxB,EAAI8D,sBAAwB7G,KAAKuF,sBAAsB1E,gBAC3EkC,EAAIoB,YAAcnE,KAAKmE,cAEnBnE,KAAK4E,cACP7B,EAAImC,mBAAqBlF,KAAKkF,mBAAmBrE,eACjDkC,EAAI0C,uBAAyBzF,KAAKyF,uBAAuB5E,gBAEvDb,KAAK6E,YAAW9B,EAAIoC,iBAAmBnF,KAAKmF,iBAAiBtE,gBAC7Db,KAAK8E,WAAU/B,EAAIqC,gBAAkBpF,KAAKoF,gBAAgBvE,gBAC1Db,KAAKgF,cAAajC,EAAIuC,qBAAuBtF,KAAKsF,qBAAqBzE,gBACvEb,KAAK+E,YAAWhC,EAAIsC,mBAAqBrF,KAAKqF,mBAAmBxE,gBACrEkC,EAAI6C,gBAAkB5F,KAAK4F,gBAAgB/E,eAC3CkC,EAAIqB,eAAiBpE,KAAKoE,gBAE5BrB,EAAImB,eAAiBlE,KAAKkE,eAGrBlE,KAAKiG,SACJjG,KAAK+F,uBAAuBtF,UAAY,EAC1CsC,EAAIgD,uBAAyB/F,KAAK+F,uBAAuBlF,eAEzDkC,EAAIgD,uBAAyB,EAE3B/F,KAAKiF,UACPjF,KAAK+F,uBAAuB1D,QAE5BrC,KAAK+F,uBAAuBvF,QAE9BR,KAAKqE,eAAiBtB,EAAIgD,uBAC1BhD,EAAIsB,cAAgBrE,KAAKqE,eAzCJ,2BA4CvB,YAA2B3J,OAAOoM,QAAQ9G,KAAKgG,2BAA/C,+CAA2E,wBAA/DzK,EAA+D,KAA1DN,EAA0D,KACzE8H,EAAIxH,GAAON,EAAM4F,gBA7CI,6EAgDvB,OAAOkC,I,0CAQWgE,GAClB,IAAIC,EAAa,GAgBjB,OAdEA,EADED,EACW,UAEN/G,KAAK+E,UACC,OAEN/E,KAAK8E,SACC,QAIA,aAEf9I,UAAIc,MAAM,iBAAmBkK,GAEtBA,I,sCAOPhH,KAAKgE,e,sCAQL,OAAKhE,KAAK2E,gBACR3E,KAAK2E,eAAgB,GACd,K,kCAWT,OAAK3E,KAAK4E,cACR5E,KAAK4E,aAAc,EACnB5E,KAAK4F,gBAAgBpF,QACrBR,KAAKkF,mBAAmB7C,SACjB,K,gCAWT,SAAIrC,KAAK4E,aAAgB5E,KAAK6E,aACxB7E,KAAKiG,OACPjG,KAAKmE,cAELnE,KAAKoE,iBAEPpE,KAAK6E,WAAY,EACjB7E,KAAKiF,WAAY,EACjBjF,KAAKmF,iBAAiB9C,QACtBrC,KAAK+F,uBAAuB1D,SACrB,K,8BAWT,QAAIrC,KAAK4E,cACP5E,KAAKkE,eAAiB,EACtBlE,KAAKyE,aACLzE,KAAKkF,mBAAmB+B,OACxBjH,KAAKmF,iBAAiB8B,OACtBjH,KAAK+F,uBAAuBkB,QACrB,K,gCAWT,SAAIjH,KAAK6E,WAAc7E,KAAK8E,YAC1B9E,KAAK8E,UAAW,EAChB9E,KAAKiF,WAAY,EACjBjF,KAAKoF,gBAAgB/C,QACrBrC,KAAK+F,uBAAuBkB,OAC5BjH,KAAK6F,iBAAiBrF,SACf,K,iCAWT,SAAIR,KAAK6E,YAAa7E,KAAK8E,YACzB9E,KAAK8E,UAAW,EAChB9E,KAAKiF,WAAY,EACjBjF,KAAKoF,gBAAgB6B,OACrBjH,KAAK6F,iBAAiBxD,SACf,K,sCAWT,SAAIrC,KAAK4E,aAAgB5E,KAAKgF,eAC5BhF,KAAKgF,aAAc,EACnBhF,KAAKiF,WAAY,EACjBjF,KAAKsF,qBAAqBjD,SACnB,K,oCAWT,SAAIrC,KAAK4E,cAAe5E,KAAKgF,eAC3BhF,KAAKgF,aAAc,EACnBhF,KAAKiF,WAAY,EACjBjF,KAAKsF,qBAAqB2B,QACnB,K,oCAWT,SAAIjH,KAAK6E,WAAc7E,KAAK+E,aAC1B/E,KAAK+E,WAAY,EACjB/E,KAAKiF,WAAY,EACjBjF,KAAKqF,mBAAmBhD,QACxBrC,KAAK8F,iBAAiBtF,SACf,K,kCAWT,SAAIR,KAAK6E,YAAa7E,KAAK+E,aACzB/E,KAAK+E,WAAY,EACjB/E,KAAKiF,WAAY,EACjBjF,KAAKqF,mBAAmB4B,OACxBjH,KAAK8F,iBAAiBzD,SACf,K,uCAWT,OAAKrC,KAAKuE,YACRvE,KAAKuE,WAAY,EACjBvE,KAAKuF,sBAAsBlD,SACpB,K,qCAWT,QAAIrC,KAAKuE,YACPvE,KAAK4E,aAAc,EACnB5E,KAAKuE,WAAY,EACjBvE,KAAKsE,gBAAkBtE,KAAKuF,sBAAsB1E,eAClDb,KAAKuF,sBAAsB0B,QACpB,K,mCAUTjH,KAAKwF,sBAAsBnD,U,oCAO3BrC,KAAKyF,uBAAuBpD,U,0CAO5BrC,KAAK0F,6BAA6BrD,U,qCAOlCrC,KAAK2F,wBAAwBtD,U,gCAO7BrC,KAAKkE,mB,iCAOLlE,KAAK4F,gBAAgBvD,Y,eAIVlB,G,6BCvgBf,I,EAAY+F,E,wJAAZ,MACA,Q,oCAEAA,EAAQC,aAAeA,UACvB1N,EAAOD,QAAU0N,G,2UCJjB,M,IACA,M,wTAYM7F,E,YAQF,WAAY+F,EAAWC,GAAoC,IAA5BC,EAA4B,uDAAhB,eAAgB,kFAOvD,EAAKC,WAAaH,EAMlB,EAAKI,QAAUH,EAMf,EAAKI,WAAaH,EAMlB,EAAKI,aAAe,GAMpB,EAAKC,gBAAiB,EAMtB,EAAKC,eAAiB,EAGtBnF,aAAY,WAAQ,EAAKoF,eAAexG,EAAkByG,OAAOC,SAAU,KAxCpB,E,sWA2CtD7H,EAAOC,GAER,G,yPADA,kFAAWD,EAAOC,GACdH,KAAK0H,aAAavK,OAAS,IAAK,EAChCgD,EAAOH,KAAKgI,mBAAmB7H,IAC/B,UAAoBH,KAAKyH,WACzBtH,EAAA,WAAqBD,EAErB,IAAI+H,EAAYhK,KAAK6F,MACjBmE,EAAYjI,KAAK4H,gBACjBzH,EAAA,UAAoB8H,EACpBjI,KAAK4H,eAAiBK,IAGtBjI,KAAK4H,iBACLzH,EAAA,UAAoBH,KAAK4H,gBAE7B5H,KAAK0H,aAAajG,KAAKtB,M,yCAIZA,GACfA,EAAA,QAAkBvG,OAAO+F,SAASuI,KAClC/H,EAAA,WAAqBvG,OAAO+F,SAASwI,OAASvO,OAAO+F,SAASyI,SAC9DjI,EAAA,YAAsBxB,SAAS0J,SAE/B,IAAIC,EAAS,WAC8B,GAAvCC,UAAUC,UAAU7G,QAAQ,OAAc2G,EAAS,WACH,GAA3CC,UAAUC,UAAU7G,QAAQ,WAAkB2G,EAAS,WAChB,GAAvCC,UAAUC,UAAU7G,QAAQ,OAAc2G,EAAS,MACnDC,UAAUC,UAAUC,MAAM,qBAAsBH,EAAS,OAChB,GAAzCC,UAAUC,UAAU7G,QAAQ,SAAgB2G,EAAS,SACd,GAAvCC,UAAUC,UAAU7G,QAAQ,SAAc2G,EAAS,QAC5DnI,EAAA,YAAsBmI,EAEtB,IAAII,EAAY,WAC8B,GAA1CH,UAAUC,UAAU7G,QAAQ,UAAkB+G,EAAY,UACV,GAA3CH,UAAUC,UAAU7G,QAAQ,WAAmB+G,EAAY,WACnB,GAAxCH,UAAUC,UAAU7G,QAAQ,QAAgB+G,EAAY,MAChB,GAAxCH,UAAUC,UAAU7G,QAAQ,QAAgB+G,EAAY,kBACd,GAA1CH,UAAUC,UAAU7G,QAAQ,UAAkB+G,EAAY,UACjB,GAAzCH,UAAUC,UAAU7G,QAAQ,WAAiB+G,EAAY,SAClEvI,EAAA,cAAwBuI,EAExB,IAAIC,EAAa,UAOjB,OAN+CA,EAA3CJ,UAAUC,UAAUC,MAAM,gBAA8B,SACnDF,UAAUC,UAAUC,MAAM,iHAA+H,SAC1IvJ,MAAftF,OAAOuF,KAAgC,OAC9B,UAClBgB,EAAA,WAAqBwI,EAEdxI,I,qCAGIyI,GACPA,GAAUvH,EAAkByG,OAAOC,OAAS/H,KAAK2H,eACjD3L,UAAIc,MAAM,gCAIdkD,KAAK2H,gBAAiB,EAElB3H,KAAK0H,aAAavK,OAAS,GAC3BnB,UAAIc,MAAM,6BAA8BkD,KAAK0H,cAC7C1H,KAAK6I,oBAAoB7I,KAAK0H,aAAaoB,QAG3C9I,KAAK2H,gBAAiB,K,0CAIVoB,GAAI,WACdC,EAAiB,CACnBC,OAAQ,OACRC,QAAS,CAAE,eAAgB,mBAAoB,eAAgBlJ,KAAKwH,SACpE2B,KAAMC,KAAKC,UAAUN,IAGnBO,EAAM,uDAAyDtJ,KAAKuH,WAAa,UACvFgC,MAAMD,EAAKN,GACNQ,MAAK,SAAAC,GAAA,OAAYA,EAASC,UAC1BF,MAAK,SAAArJ,GAAA,OAAQ,EAAKwJ,wBAAwBxJ,MAC1CyJ,OAAM,SAAC3K,GACJjD,UAAIiD,MAAM,SAAUA,EAAO8J,GAE3B,EAAKrB,aAAajG,KAAKsH,GACvB,EAAKpB,gBAAiB,O,8CAIVxH,GAEpBH,KAAK6H,eAAexG,EAAkByG,OAAO+B,W,GA9IrB9J,WAkJhCsB,EAAkByG,OAAS,CACvBC,MAAO,QACP8B,MAAO,S,UAGIxI,G,2UCpKf,M,IACA,M,uDAMMD,E,gLAMe0I,GACbA,EAAQ1M,IAAM0M,EAAQnG,MACxBoG,EAAStI,KAAKqI,GACdA,EAAQ1M,GAAG,IAAK4M,GACkB,mBAAvBF,EAAQG,aACjBH,EAAQG,eAGVjO,UAAIiD,MAAM,+BAAgC6K,K,oCASxBA,GACpBA,EAAQI,IAAI,IAAKF,GACjBF,EAAQK,UACR,IAAIzI,EAAQqI,EAASpI,QAAQmI,IACd,IAAXpI,GAAcqI,EAAS3K,OAAOsC,EAAO,K,oCASzC,OAAOqI,I,mCASP,OAAOK,I,iCAOSC,GACdD,EAAUC,I,2BAQFnK,EAAOC,GACQjB,MAArBkC,EAAKkJ,cAA+BlJ,EAAKkJ,uBAAwBvK,UAgBjEqB,EAAKkJ,aAAatH,KAAK9C,EAAOC,GAdN,oBAAboK,UAA4BA,SAASC,cAC5CD,SAASC,cAActK,EAAOC,GAEzBsK,IACDzO,UAAIiD,MACA,6CACA,yEAEJwL,GAAe,K,gCAiBX1H,GAChB3B,EAAK4B,KAAK,QAASD,O,KAInBgH,EAAW,GACXK,SACAK,GAAe,EAQnB,SAAST,EAAcnN,GACrB,IAAIsD,EAeN,SAAoBA,GAClB,IAAIuK,EAAM,GACV,IAAK,IAAI1Q,KAAKmG,EACI,OAAZA,EAAKnG,SAAkC,IAAZmG,EAAKnG,KAAoB0Q,EAAI1Q,GAAKmG,EAAKnG,IAExE,OAAO0Q,EApBIC,CAAU9N,EAAEsD,MACnBnE,UAAIY,OAASZ,UAAIG,OAAOM,MAC1BT,UAAI4O,OAAO,OAAQ/N,EAAEE,KAAMoD,GAE3BnE,UAAI4O,OAAO,OAAQ/N,EAAEE,MAEvBqE,EAAK4B,KAAKnG,EAAEE,KAAMoD,G,UAiBLiB,G,kFClITL,E,oHAONA,EAAU8J,YAAc,CAEtBC,IAAK,MAELC,IAAK,MAELC,KAAM,Q,UAGOjK,G,2UCrBf,M,IACA,M,IACA,M,uDAaMG,E,YAQJ,WAAa+J,EAAQjJ,I,4FAAS,e,iKAAA,iEAQ5B,EAAKkJ,MAAQ,IAAIC,UAMjB,EAAKC,WAAa,KAMlB,EAAKC,gBAAkB,KAEvBrJ,EAAUA,GAAW,GACrB,EAAKM,WAAWN,GACZiJ,GAAQ,EAAKK,UAAUL,EAAQjJ,EAAQuJ,KAE3CvP,UAAI4O,OAAO,WAAa,EAAKxH,iBAAmB,KAAO,EAAKE,oBAAsB,cA1BtD,E,4WAwClBtB,GACNA,IACEA,EAAQoJ,YAAYpL,KAAKwL,cAAcxJ,EAAQoJ,YACvB,kBAAjBpJ,EAAQiE,MAAoBjG,KAAKyL,QAAQzJ,EAAQiE,MAC5DhF,UAAQrF,UAAU0G,WAAWjD,MAAMW,KAAMzD,c,gCAalC0O,EAAQM,IACbvL,KAAKiL,QAAUjL,KAAKuL,MAAKvL,KAAKmK,UAEV,oBAAbxL,UAA4BA,SAAS+M,iBACxB,iBAAXT,IAAqBA,EAAStM,SAAS+M,eAAeT,IAC9C,iBAARM,IAAkBA,EAAM5M,SAAS+M,eAAeH,KAG7DA,EAAMA,GAAON,EAEbjL,KAAKiL,OAASA,EACdjL,KAAKuL,IAAMA,EACXvL,KAAK2L,sB,6BAKL,OAAO3L,KAAKkL,MAAMjF,S,8BAIXA,GACPjG,KAAKkL,MAAMO,QAAQxF,K,oCASN6D,GACb9J,KAAK4L,oBACD9B,IACF9J,KAAKoL,WAAatB,EAClB9J,KAAKoL,WAAWK,SAAQ,GACxBzL,KAAKoL,WAAWjJ,cAAgBnC,KAChCA,KAAKoL,WAAWhO,GAAG,IAAKyO,EAAerQ,KAAKwE,U,0CAQ1CA,KAAKoL,aACPpL,KAAKoL,WAAWlB,IAAI,IAAK2B,GACzB7L,KAAKoL,WAAWjB,a,gCAQlBnK,KAAK8L,gBACL9L,KAAK4L,oBACL5L,KAAKuC,sBACLvC,KAAKiL,OAAS,KACdjL,KAAKuL,IAAM,O,8HA2CX,OAAIvL,KAAKmC,cACAnC,KAAKmC,cAAc4J,YAEnB/L,KAAKkL,MAAMa,c,uCAUpB,OAAI/L,KAAKmC,cACAnC,KAAKmC,cAAcmE,iBAEnBtG,KAAKkL,MAAM5E,mB,mCAMpB,OAAO,O,iCAKP,OAAO,O,+BAKP,OAAO,O,mCAKP,OAAO,O,yCAKP,GAAItG,KAAKuL,KAAOvL,KAAKuL,IAAIS,4BAA6B,CACpD,IAAIC,SACJ,GAAIjM,KAAKkM,mBAAoB,CAE3B,IAAIC,GADJF,EAAUjM,KAAKuL,IAAIS,6BACGhM,KAAKkM,mBACvBE,EAAUpM,KAAK6C,eAAiB,IACpCoJ,EAAUtJ,KAAK0J,MAAOF,EAAQC,EAAW,GAG3C,OADApM,KAAKkM,mBAAqBlM,KAAKuL,IAAIS,4BAC5BC,GAAW,Q,yCAMpB,OAAO,O,4CAKP,OAAO,O,wCAWUK,GACjB,IAAIC,EAAUvM,KAAKwM,sBACfC,SASJ,OARIzM,KAAKiG,QACPwG,EAAOzM,KAAK0M,iBACRJ,IAAkBtM,KAAK0M,iBAAmBH,KAE9CE,EAAOzM,KAAK2M,eACRL,IAAkBtM,KAAK2M,eAAiBJ,IAGzCA,GAAYE,EAGXF,EAAUE,EACL,KACEF,EAAUE,EACZ,OAEA,KAPF,O,2CAcT,OAAOzM,KAAKuL,IAAMvL,KAAKuL,IAAIqB,YAAc,O,0CAKzC,OAAO5M,KAAKuL,IAAMvL,KAAKuL,IAAIsB,WAAa,O,oCAKxC,OAAO7M,KAAKuL,IAAMvL,KAAKuL,IAAIuB,SAAW,O,oCAKtC,OAAO9M,KAAKuL,IAAMvL,KAAKuL,IAAIwB,YAAc,O,oCAQzC,OAAO,O,+BAKP,OAAO/M,KAAKuL,IAAMvL,KAAKuL,IAAIyB,WAAa,O,oCAKxC,OAAOhN,KAAKuL,IAAMvL,KAAKuL,IAAI0B,aAAe,O,gCAK1C,OAAOjN,KAAKuL,IAAMvL,KAAKuL,IAAI2B,MAAQ,O,qCAKnC,OAAO,O,+BAKP,OAAO,O,sCAKP,OAAOlN,KAAKoD,mB,yCAKZ,OAAO,O,+BAKP,OAAO,O,qCAOP,OAAOpD,KAAKuL,IAAMvL,KAAKuL,IAAI4B,SAAW,O,mCAOtC,OAAOnN,KAAKuL,IAAMvL,KAAKuL,IAAI6B,QAAU,O,sCASrC,OAAO,O,sCAQP,OAAIpN,KAAKmC,cACAnC,KAAKmC,cAAc+I,MAAMrG,UAAY,MAAQ,MAG7C,O,qCAQT,OAAO,O,wCAOP,OAAO,O,oCAUM9B,QAGW,KAFxBA,EAAM9B,UAAQrF,UAAUgI,cAAcvE,MAAMW,KAAMzD,YAEnC0J,OAAsBlD,EAAIkD,KAAOjG,KAAKiG,QACrDlD,EAAIsK,YAAcrN,KAAKsG,iBACvBvD,EAAIuK,OAAStN,KAAK+L,YAClBhJ,EAAIwK,WAAavN,KAAKwN,gBACtBzK,EAAI0K,cAAgBzN,KAAK0N,mBAEzB,IACE3K,EAAI4K,QAAU/T,OAAO+F,SAASuI,KAC9B,MAAO1K,IAiDT,IAAK,IAAIjC,KA/CLyE,KAAKiG,QACPlD,EAAI6K,KAAO5N,KAAK6N,aAChB9K,EAAI+K,QAAU9N,KAAK+N,WACnBhL,EAAIiL,UAAYhO,KAAKiO,cAAgBjO,KAAKkO,mBAC1CnL,EAAIoL,gBAAkBnO,KAAKoO,mBAC3BrL,EAAIsL,mBAAqBrO,KAAKwM,sBAC9BzJ,EAAIuL,kBAAoBtO,KAAKuO,qBAC7BxL,EAAIyL,iBAAmBxO,KAAKyO,oBAC5B1L,EAAI2L,WAAa1O,KAAK2O,cACtB5L,EAAI6L,WAAa5O,KAAK6O,cACtB9L,EAAI+L,WAAa9O,KAAK+O,cACtBhM,EAAIiM,MAAQhP,KAAKiP,SACjBlM,EAAImM,MAAQlP,KAAKmP,SACjBpM,EAAIqM,UAAYpP,KAAKqP,UACrBtM,EAAIuM,MAAQtP,KAAKuP,SAEjBxM,EAAIyM,WAAaxP,KAAKyP,gBACtB1M,EAAI2M,WAAa1P,KAAK2P,gBACtB5M,EAAI6M,aAAe5P,KAAK6P,kBACxB9M,EAAI+M,UAAY9P,KAAK+P,iBAErBhN,EAAIiN,UAAYhQ,KAAK6N,aACrB9K,EAAIkN,aAAejQ,KAAK+N,WACxBhL,EAAImN,cAAgBlQ,KAAKmQ,SACzBpN,EAAIqN,eAAiBpQ,KAAKiO,cAAgBjO,KAAKkO,mBAC/CnL,EAAIsN,qBAAuBrQ,KAAKoO,mBAChCrL,EAAIuN,wBAA0BtQ,KAAKwM,sBACnCzJ,EAAIwN,uBAAyBvQ,KAAKuO,qBAClCxL,EAAIyN,sBAAwBxQ,KAAKyO,oBACjC1L,EAAI0N,gBAAkBzQ,KAAK2O,cAC3B5L,EAAI2N,gBAAkB1Q,KAAK6O,cAC3B9L,EAAI4N,gBAAkB3Q,KAAK+O,cAC3BhM,EAAI6N,WAAa5Q,KAAKiP,SACtBlM,EAAI8N,gBAAkB7Q,KAAK8Q,cAC3B/N,EAAIgO,oBAAsB/Q,KAAKgR,eAC/BjO,EAAIkO,eAAiBjR,KAAKqP,UAC1BtM,EAAImO,WAAalR,KAAKmP,SACtBpM,EAAIoO,oBAAsBnR,KAAKoR,eAC/BrO,EAAIsO,eAAiBrR,KAAKsR,aAC1BvO,EAAIwO,WAAavR,KAAKuP,SACC,MAAnBvP,KAAKoL,YAAsBpL,KAAKoL,WAAWF,MAAM5G,gBAAkB,IACrEvB,EAAIuB,gBAAkBtE,KAAKoL,WAAWF,MAAM5G,kBAIhDtE,KAAKkL,MAAMsG,mBAAmBzO,GAEd/C,KAAKiC,WACnBc,EAAIxH,GAAOyE,KAAKiC,WAAW1G,GAG7B,OAAOwH,I,iCASG0O,EAAYC,EAAkB3O,GACxCA,EAAMA,GAAO,GACb/C,KAAKgD,KAAKyO,EAAY1O,GACtB/C,KAAKkL,MAAMyG,sBAAsBD,K,sCAQlB3O,GACX/C,KAAKkL,MAAM0G,kBACb7O,EAAMA,GAAO,GACb/C,KAAKgD,KAAK9B,EAAa+B,OAAO4O,aAAc9O,M,kCAUnCA,GACX,GAAI/C,KAAKkL,MAAM4G,YAAa,CAC1B9R,KAAKkL,MAAM6G,gBACX,IAAIhJ,EAAK/I,KAAKiG,OAAS/E,EAAa+B,OAAO+O,WAAa9Q,EAAa+B,OAAOgP,gBAC5EjS,KAAKgD,KAAK+F,EAAIhG,GACd/C,KAAKkS,iBACLlS,KAAKkL,MAAMiH,iB,gCASJpP,GACT,GAAI/C,KAAKkL,MAAMkH,UAAW,CACxB,IAAIrJ,SACA/I,KAAKiG,QACP8C,EAAK7H,EAAa+B,OAAOoP,SACrBrS,KAAKmC,gBAAenC,KAAKmC,cAAc+I,MAAMjG,WAAY,IAE7D8D,EAAK7H,EAAa+B,OAAOqP,cAE3BtS,KAAKgD,KAAK+F,EAAIhG,M,8BAUTA,GACP,GAAI/C,KAAKkL,MAAMqH,QAAS,CACtBxP,EAAMA,GAAO,GACb,IAAIgG,SACA/I,KAAKiG,QACP8C,EAAK7H,EAAa+B,OAAOuP,OACzBzP,EAAIwD,qBAAuBvG,KAAKkL,MAAMhG,mBAAmBrE,eACzDkC,EAAI0D,mBAAqBzG,KAAKkL,MAAM/F,iBAAiBtE,eACjDb,KAAKmC,gBAAenC,KAAKmC,cAAc+I,MAAMjG,WAAY,KAE7D8D,EAAK7H,EAAa+B,OAAOwP,YACzB1P,EAAImC,mBAAqBlF,KAAKkL,MAAMhG,mBAAmBrE,eACvDkC,EAAIoC,iBAAmBnF,KAAKkL,MAAM/F,iBAAiBtE,gBAErDb,KAAK8L,gBACL9L,KAAKgD,KAAK+F,EAAIhG,GACV/C,KAAKmC,eAAiBnC,KAAKiG,QAAQjG,KAAKmC,cAAc+I,MAAMwH,WAChE1S,KAAKkL,MAAM6G,gBACX/R,KAAKkL,MAAM7G,cAAgB,K,gCASpBtB,GACT,GAAI/C,KAAKkL,MAAMyH,UAAW,CACxB,IAAI5J,EAAK/I,KAAKiG,OAAS/E,EAAa+B,OAAO2P,SAAW1R,EAAa+B,OAAO4P,cAC1E7S,KAAKgD,KAAK+F,EAAIhG,M,iCASNA,GACV,GAAI/C,KAAKkL,MAAM4H,WAAY,CACzB/P,EAAMA,GAAO,GACb,IAAIgG,SACA/I,KAAKiG,QACP8C,EAAK7H,EAAa+B,OAAO8P,UACzBhQ,EAAI2D,kBAAoB1G,KAAKkL,MAAM9F,gBAAgBvE,iBAEnDkI,EAAK7H,EAAa+B,OAAO+P,eACzBjQ,EAAIqC,gBAAkBpF,KAAKkL,MAAM9F,gBAAgBvE,gBAEnDb,KAAKgD,KAAK+F,EAAIhG,M,sCASDA,GACf,GAAI/C,KAAKkL,MAAM+H,gBAAiB,CAC9BlQ,EAAMA,GAAO,GACb,IAAIgG,SAEFA,EADE/I,KAAKiG,OACF/E,EAAa+B,OAAOiQ,gBAEpBhS,EAAa+B,OAAOkQ,qBAG3BpQ,EAAM/C,KAAKoT,sBAAsBrQ,GACjC/C,KAAKqL,gBAAkBtI,EAAIiE,WAE3BhH,KAAKgD,KAAK+F,EAAIhG,M,oCASHA,GACb,GAAI/C,KAAKkL,MAAMmI,cAAe,CAC5BtQ,EAAMA,GAAO,GACb,IAAIgG,SACA/I,KAAKiG,QACP8C,EAAK7H,EAAa+B,OAAOqQ,cACzBvQ,EAAI4D,uBAAyB3G,KAAKkL,MAAM5F,qBAAqBzE,iBAE7DkI,EAAK7H,EAAa+B,OAAOsQ,mBACzBxQ,EAAIuC,qBAAuBtF,KAAKkL,MAAM5F,qBAAqBzE,gBAG7DkC,EAAM/C,KAAKoT,sBAAsBrQ,GAEL,MAAxB/C,KAAKqL,kBACPtI,EAAIiE,WAAahH,KAAKqL,iBAGxBrL,KAAKgD,KAAK+F,EAAIhG,GACd/C,KAAKkL,MAAM1G,0BAA2B,K,4CAIpBzB,GAapB,OAZ4B7D,MAAxB6D,EAAIoC,kBAAiCpC,EAAIoC,iBAAmB,IAC9DpC,EAAIgE,oBAAsB/G,KAAKkL,MAAM1G,yBAGrCzB,EAAIgE,oBAAqB,EAG3BhE,EAAIiE,WAAahH,KAAKkL,MAAMsI,oBAAoBzQ,EAAIgE,oBAEpDhE,EAAI8C,iBAAmB7F,KAAKkL,MAAMrF,iBAAiBhF,eACnDkC,EAAI+C,iBAAmB9F,KAAKkL,MAAMpF,iBAAiBjF,eAE5CkC,I,oCAQMA,GACb,GAAI/C,KAAKkL,MAAMuI,cAAe,CAC5B,IAAI1K,SAEFA,EADE/I,KAAKiG,OACF/E,EAAa+B,OAAOyQ,cAEpBxS,EAAa+B,OAAO0Q,mBAE3B3T,KAAKgD,KAAK+F,EAAIhG,M,kCASLA,GACX,GAAI/C,KAAKkL,MAAM0I,YAAa,CAC1B7Q,EAAMA,GAAO,GACb,IAAIgG,SACA/I,KAAKiG,QACP8C,EAAK7H,EAAa+B,OAAO4Q,YACzB9Q,EAAI6D,qBAAuB5G,KAAKkL,MAAM7F,mBAAmBxE,iBAEzDkI,EAAK7H,EAAa+B,OAAO6Q,iBACzB/Q,EAAIsC,mBAAqBrF,KAAKkL,MAAM7F,mBAAmBxE,gBAEzDb,KAAKgD,KAAK+F,EAAIhG,M,mCAUJA,IACZA,EAAMA,GAAO,IACJmI,OAAOlP,UAAIuB,KAAK,iDACzByC,KAAKgD,KAAK9B,EAAa+B,OAAO8Q,SAAUhR,GACxC/C,KAAKkL,MAAM8I,e,gCAQFjR,IACTA,EAAMA,GAAO,IACTkD,MAAO,EACXjG,KAAKkL,MAAM+I,UACX,IAAIlL,EAAK/I,KAAKiG,OAAS/E,EAAa+B,OAAOiR,SAAWhT,EAAa+B,OAAOkR,cAC1EnU,KAAKgD,KAAK+F,EAAIhG,K,2CAQMA,IACpBA,EAAMA,GAAO,IACT2C,6BAA+B1F,KAAKkL,MAAMxF,6BAA6B7E,eAC3EkC,EAAI9F,MAAQ+C,KAAKoU,mBAAkB,GACnC,IAAIrL,SAEFA,EADE/I,KAAKiG,OACF/E,EAAa+B,OAAOoR,oBAEpBnT,EAAa+B,OAAOqR,yBAE3BtU,KAAKgD,KAAK+F,EAAIhG,GACd/C,KAAKkL,MAAMqJ,sB,oCAUExR,GACb,GAAI/C,KAAKkL,MAAMtG,YAAa,CAC1B,IAAImE,SAEFA,EADE/I,KAAKiG,OACF/E,EAAa+B,OAAOuR,aAEpBtT,EAAa+B,OAAOwR,kBAE3BzU,KAAKgD,KAAK+F,EAAIhG,GACd/C,KAAKkL,MAAMiH,iB,uCAUGpP,GACZ/C,KAAKiG,QAAUjG,KAAKkL,MAAMwJ,mBAC5B1U,KAAKkL,MAAM5G,gBAAkB,EACzBtE,KAAKmC,gBAAenC,KAAKmC,cAAc+I,MAAMjG,WAAY,GAC7DjF,KAAKgD,KAAK9B,EAAa+B,OAAO0R,eAAgB5R,M,qCASlCA,GACV/C,KAAKiG,QAAUjG,KAAKkL,MAAM0J,kBAC5B7R,EAAMA,GAAO,IACT8D,sBAAwB7G,KAAKkL,MAAM3F,sBAAsB1E,eAC7Db,KAAKgD,KAAK9B,EAAa+B,OAAO4R,aAAc9R,GAExC/C,KAAKmC,gBAAenC,KAAKmC,cAAc+I,MAAMjG,WAAY,GAC7DjF,KAAK8L,gBACD9L,KAAKmC,eAAiBnC,KAAKiG,QAAQjG,KAAKmC,cAAc+I,MAAMwH,c,qCAUpD3P,GACV/C,KAAKiG,UACPlD,EAAMA,GAAO,IACJ+R,UAAU9Y,UAAIuB,KAAK,sDAC5BwF,EAAI4C,wBAA0B3F,KAAKkL,MAAMvF,wBAAwB9E,eACjEb,KAAKgD,KAAK9B,EAAa+B,OAAO8R,YAAahS,GAC3C/C,KAAKkL,MAAM8J,kB,kCAUFjS,GACP/C,KAAKiG,UACPlD,EAAMA,GAAO,IACJuG,KAAKtN,UAAIuB,KAAK,8CACvByC,KAAKgD,KAAK9B,EAAa+B,OAAOgS,SAAUlS,Q,GA/xBnB9B,WAk3B3B,SAAS4K,EAAgBhP,GACvBmD,KAAKgD,KAAKnG,EAAEE,KAAMF,EAAEsD,MAxEtBe,EAAa+B,OAAS,CAGpB4O,aAAc,eAEdkC,SAAU,WAEV3X,MAAO,QAIP6V,gBAAiB,kBAEjBK,cAAe,gBAEfG,YAAa,cAEbI,cAAe,gBAEfG,eAAgB,iBAEhBW,mBAAoB,qBAEpBG,iBAAkB,mBAElBX,qBAAsB,uBAEtBI,mBAAoB,qBAEpBkB,kBAAmB,oBAEnBH,yBAA0B,2BAE1BH,cAAe,gBAIfnC,WAAY,aAEZK,SAAU,WAEVG,OAAQ,SAERI,SAAU,WAEVG,UAAW,YAEXW,cAAe,gBAEfG,YAAa,cAEbX,gBAAiB,kBAEjBI,cAAe,gBAEfkB,aAAc,eAEdH,oBAAqB,sBAErBH,SAAU,WAEVS,eAAgB,iBAEhBE,aAAc,eAEdE,YAAa,cAEbE,SAAU,Y,UAQG/T,G,uUCr4BHgG,E,wJAAZ,M,qQAEqBC,E,keAEjB,MAAO,U,oCAIP,OAAiC,IAA1BnH,KAAKiL,OAAO8B,c,oCAInB,OAA8B,IAAvB/M,KAAKiL,OAAO6B,W,+BAInB,OAAO9M,KAAKiL,OAAO+B,a,gCAInB,OAAOhN,KAAKiL,OAAOiC,Q,2CAInB,OAAOlN,KAAKiL,OAAO2B,c,0CAInB,OAAO5M,KAAKiL,OAAO4B,a,oCAInB,OAAO7M,KAAKiL,OAAOgC,e,qCAInB,OAAOjN,KAAKiL,OAAOkC,W,mCAInB,OAAOnN,KAAKiL,OAAOmC,U,0CAInBlG,EAAQlL,IAAIkZ,uBAAuBlV,KAAKiL,QAExCjL,KAAKiL,OAAO5N,iBAAiB,YAAa2C,KAAKmV,WAAW3Z,KAAKwE,OAC/DA,KAAKiL,OAAO5N,iBAAiB,iBAAkB2C,KAAKmV,WAAW3Z,KAAKwE,OACpEA,KAAKiL,OAAO5N,iBAAiB,aAAc2C,KAAKmV,WAAW3Z,KAAKwE,OAChEA,KAAKiL,OAAO5N,iBAAiB,UAAW2C,KAAKmV,WAAW3Z,KAAKwE,OAC7DA,KAAKiL,OAAO5N,iBAAiB,OAAQ2C,KAAKoV,OAAO5Z,KAAKwE,OACtDA,KAAKiL,OAAO5N,iBAAiB,UAAW2C,KAAKqV,UAAU7Z,KAAKwE,OAC5DA,KAAKiL,OAAO5N,iBAAiB,QAAS2C,KAAKsV,QAAQ9Z,KAAKwE,OACxDA,KAAKiL,OAAO5N,iBAAiB,UAAW2C,KAAKuV,UAAU/Z,KAAKwE,OAC5DA,KAAKiL,OAAO5N,iBAAiB,SAAU2C,KAAKwV,SAASha,KAAKwE,OAC1DA,KAAKiL,OAAO5N,iBAAiB,QAAS2C,KAAKyV,QAAQja,KAAKwE,OACxDA,KAAKiL,OAAO5N,iBAAiB,QAAS2C,KAAK0V,QAAQla,KAAKwE,OACxDA,KAAKiL,OAAO5N,iBAAiB,UAAW2C,KAAK2V,UAAUna,KAAKwE,S,4CAI5DA,KAAKiL,OAAO2K,oBAAoB,YAAa5V,KAAKmV,YAClDnV,KAAKiL,OAAO2K,oBAAoB,iBAAkB5V,KAAKmV,YACvDnV,KAAKiL,OAAO2K,oBAAoB,aAAc5V,KAAKmV,YACnDnV,KAAKiL,OAAO2K,oBAAoB,UAAW5V,KAAKmV,YAChDnV,KAAKiL,OAAO2K,oBAAoB,OAAQ5V,KAAKoV,QAC7CpV,KAAKiL,OAAO2K,oBAAoB,UAAW5V,KAAKqV,WAChDrV,KAAKiL,OAAO2K,oBAAoB,QAAS5V,KAAKsV,SAC9CtV,KAAKiL,OAAO2K,oBAAoB,UAAW5V,KAAKuV,WAChDvV,KAAKiL,OAAO2K,oBAAoB,SAAU5V,KAAKwV,UAC/CxV,KAAKiL,OAAO2K,oBAAoB,QAAS5V,KAAKyV,SAC9CzV,KAAKiL,OAAO2K,oBAAoB,QAAS5V,KAAK0V,SAC9C1V,KAAKiL,OAAO2K,oBAAoB,UAAW5V,KAAK2V,a,iCAGtC9Y,GACVmD,KAAK6V,aAAa,CAAE3K,MAAOrO,EAAEE,S,+BAI7BiD,KAAK8V,gB,kCAIL9V,KAAK+V,gBACL/V,KAAKgW,aACLhW,KAAKiW,c,gCAILjW,KAAKkW,c,kCAILlW,KAAKmW,kB,iCAILnW,KAAKoW,gB,gCAILpW,KAAKqW,c,gCAILrW,KAAKsW,Y,kCAKHtW,KAAKiL,OAAOsL,eAAiBvW,KAAKiL,OAAOuL,iBACzCxW,KAAKiL,OAAOwL,WAAazW,KAAKiL,OAAOyL,kBAErC1W,KAAK2W,sB,GAhH+BzP,EAAQhG,c,UAA7BiG","file":"newrelic-video-html5.min.js","sourcesContent":["(function webpackUniversalModuleDefinition(root, factory) {\n\tif(typeof exports === 'object' && typeof module === 'object')\n\t\tmodule.exports = factory();\n\telse if(typeof define === 'function' && define.amd)\n\t\tdefine([], factory);\n\telse if(typeof exports === 'object')\n\t\texports[\"nrvideo\"] = factory();\n\telse\n\t\troot[\"nrvideo\"] = factory();\n})(window, function() {\nreturn "," \t// The module cache\n \tvar installedModules = {};\n\n \t// The require function\n \tfunction __webpack_require__(moduleId) {\n\n \t\t// Check if module is in cache\n \t\tif(installedModules[moduleId]) {\n \t\t\treturn installedModules[moduleId].exports;\n \t\t}\n \t\t// Create a new module (and put it into the cache)\n \t\tvar module = installedModules[moduleId] = {\n \t\t\ti: moduleId,\n \t\t\tl: false,\n \t\t\texports: {}\n \t\t};\n\n \t\t// Execute the module function\n \t\tmodules[moduleId].call(module.exports, module, module.exports, __webpack_require__);\n\n \t\t// Flag the module as loaded\n \t\tmodule.l = true;\n\n \t\t// Return the exports of the module\n \t\treturn module.exports;\n \t}\n\n\n \t// expose the modules object (__webpack_modules__)\n \t__webpack_require__.m = modules;\n\n \t// expose the module cache\n \t__webpack_require__.c = installedModules;\n\n \t// define getter function for harmony exports\n \t__webpack_require__.d = function(exports, name, getter) {\n \t\tif(!__webpack_require__.o(exports, name)) {\n \t\t\tObject.defineProperty(exports, name, { enumerable: true, get: getter });\n \t\t}\n \t};\n\n \t// define __esModule on exports\n \t__webpack_require__.r = function(exports) {\n \t\tif(typeof Symbol !== 'undefined' && Symbol.toStringTag) {\n \t\t\tObject.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });\n \t\t}\n \t\tObject.defineProperty(exports, '__esModule', { value: true });\n \t};\n\n \t// create a fake namespace object\n \t// mode & 1: value is a module id, require it\n \t// mode & 2: merge all properties of value into the ns\n \t// mode & 4: return value when already ns object\n \t// mode & 8|1: behave like require\n \t__webpack_require__.t = function(value, mode) {\n \t\tif(mode & 1) value = __webpack_require__(value);\n \t\tif(mode & 8) return value;\n \t\tif((mode & 4) && typeof value === 'object' && value && value.__esModule) return value;\n \t\tvar ns = Object.create(null);\n \t\t__webpack_require__.r(ns);\n \t\tObject.defineProperty(ns, 'default', { enumerable: true, value: value });\n \t\tif(mode & 2 && typeof value != 'string') for(var key in value) __webpack_require__.d(ns, key, function(key) { return value[key]; }.bind(null, key));\n \t\treturn ns;\n \t};\n\n \t// getDefaultExport function for compatibility with non-harmony modules\n \t__webpack_require__.n = function(module) {\n \t\tvar getter = module && module.__esModule ?\n \t\t\tfunction getDefault() { return module['default']; } :\n \t\t\tfunction getModuleExports() { return module; };\n \t\t__webpack_require__.d(getter, 'a', getter);\n \t\treturn getter;\n \t};\n\n \t// Object.prototype.hasOwnProperty.call\n \t__webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };\n\n \t// __webpack_public_path__\n \t__webpack_require__.p = \"\";\n\n\n \t// Load entry module and return exports\n \treturn __webpack_require__(__webpack_require__.s = 8);\n","/**\n * Static Log class\n *\n * @class\n * @static\n */\nclass Log {\n /**\n * Sends an error console log.\n * @param {...any} [msg] Message to show\n * @static\n */\n static error (...msg) {\n _report(msg, Log.Levels.ERROR, 'darkred')\n }\n\n /**\n * Sends a warning console log.\n * @method Log.warn\n * @static\n * @param {...any} msg Message to show\n */\n static warn (...msg) {\n _report(msg, Log.Levels.WARNING, 'darkorange')\n }\n\n /**\n * Sends a notice console log.\n * @method Log.notice\n * @static\n * @param {...any} msg Message to show\n */\n static notice (...msg) {\n _report([].slice.call(arguments), Log.Levels.NOTICE, 'darkcyan')\n }\n\n /**\n * Sends a debug message to console.\n * @method Log.debug\n * @static\n * @param {...any} msg Message to show\n */\n static debug (...msg) {\n _report(msg, Log.Levels.DEBUG, 'indigo')\n }\n\n /**\n * This utility method will add most of the HTML5 common event listeners to the player sent.\n * Events will be reported as DEBUG level messages.\n *\n * @example\n * // Already included events:\n * ['canplay', 'buffering', 'waiting', 'ended', 'play', 'playing', 'pause', 'resume', 'error',\n * 'abort', 'seek', 'seeking', 'seeked', 'stalled', 'dispose', 'loadeddata', 'loadstart',\n * 'loadedmetadata']\n *\n * @method Log.debugCommonVideoEvents\n * @static\n * @param {object|function} o Object to attach the events.\n * @param {array} [extraEvents]\n * An array of extra events to watch. ie: ['timeupdate', 'progress'].\n * If the first item is null, no common events will be added.\n * @param {function} [report] Callback function called to report events.\n * Default calls Log.debug()\n */\n static debugCommonVideoEvents (o, extraEvents, report) {\n try {\n if (Log.level <= Log.Levels.DEBUG) {\n report = report || function (e) {\n Log.debug('Event: ' + e.type)\n }\n\n var playerEvents = [\n 'canplay', 'buffering', 'waiting', 'ended', 'play', 'playing',\n 'pause', 'resume', 'error', 'abort', 'seek', 'seeking', 'seeked',\n 'stalled', 'dispose', 'loadeddata', 'loadstart', 'loadedmetadata'\n ]\n if (extraEvents) {\n if (extraEvents[0] === null) {\n extraEvents.shift()\n playerEvents = extraEvents\n } else {\n playerEvents = playerEvents.concat(extraEvents)\n }\n }\n\n for (var i = 0; i < playerEvents.length; i++) {\n if (typeof o === 'function') {\n o.call(window, playerEvents[i], report)\n } else if (o.on) {\n o.on(playerEvents[i], report)\n } else if (o.addEventListener) {\n o.addEventListener(playerEvents[i], report)\n } else if (o.addEventHandler) {\n o.addEventHandler(playerEvents[i], report)\n } else {\n Log.warn('debugCommonVideoEvents: No common listener function found for ', o)\n }\n }\n }\n } catch (err) {\n Log.warn(err)\n }\n }\n}\n\n/**\n * Enum for log levels\n * @enum {integer}\n * @static\n * @var\n */\nLog.Levels = {\n /** No console outputs */\n SILENT: 5,\n /** Console will show errors */\n ERROR: 4,\n /** Console will show warnings */\n WARNING: 3,\n /** Console will show notices (ie: life-cyrcle logs) */\n NOTICE: 2,\n /** Console will show debug messages. */\n DEBUG: 1,\n /** Show all messages. */\n ALL: 0\n}\n\n /**\n * Only logs of this imporance or higher will be shown.\n * @example Log.level = Log.Levels.ALL\n * @default Log.Levels.ERROR\n * @static\n */\nLog.level = Log.Levels.ERROR\n\n /**\n * If true, logs will be outputed with colors.\n * @default true\n * @static\n */\nLog.colorful = true\n\n /**\n * If true, logs will include the time mark.\n * @default true\n * @static\n */\nLog.includeTime = true\n\n /**\n * Prefix included at the start of every log.\n * @default '[New Relic]'\n * @static\n */\nLog.prefix = '[nrvideo]'\n\n// PRIVATE MEMBERS\n\n/**\n * Returns a console message\n *\n * @private\n * @param {array} msg Message array, error object or array of messages.\n * @param {Log.Level} [level=Log.Levels.NOTICE] Defines the level of the error sent.\n * Only errors with higher or equal level than Log.logLevel will be displayed.\n * @param {string} [color='darkgreen'] Color of the header\n * @see {@link Log.level}\n */\nfunction _report (msg, level, color) {\n level = level || Log.Levels.NOTICE\n color = color || 'darkcyan'\n\n var prefix = Log.prefix\n if (Log.includeTime) prefix += _getCurrentTime() + ' '\n prefix += _level2letter(level) + ':'\n\n // Show messages in actual console if level is enought\n if (Log.level <= level && level !== Log.Levels.SILENT) {\n if (!Log.colorful || (typeof document !== 'undefined' && document.documentMode)) {\n // document.documentMode exits only in IE\n _plainReport(msg, prefix)\n } else {\n // choose log method\n var logMethod\n if (level === Log.Levels.ERROR && console.error) {\n logMethod = console.error\n } else if (level === Log.Levels.WARNING && console.warn) {\n logMethod = console.warn\n } else if (level === Log.Levels.DEBUG && console.debug) {\n // NOTE: for some reason console.debug doesn't work on CAF Receivers.\n if (window.cast == undefined) {\n logMethod = console.debug\n } else {\n logMethod = console.log\n }\n } else {\n logMethod = console.log\n }\n\n // print message\n prefix = '%c' + prefix\n msg.splice(0, 0, prefix, 'color: ' + color)\n logMethod.apply(console, msg)\n }\n }\n}\n\n/**\n * Returns the current time in format hh:mm:ss.mmm (with trailing 0s)\n * @private\n * @return {string} Current time.\n */\nfunction _getCurrentTime () {\n var d = new Date()\n var hh = ('0' + d.getDate()).slice(-2)\n var mm = ('0' + d.getMinutes()).slice(-2)\n var ss = ('0' + d.getSeconds()).slice(-2)\n var mmm = ('00' + d.getMilliseconds()).slice(-3)\n return '[' + hh + ':' + mm + ':' + ss + '.' + mmm + ']'\n}\n\n/**\n * Returns a console message without style\n *\n * @private\n * @param {(string|object|array)} msg Message string, object or array of messages.\n * @param {string} prefix Prefix of the message.\n */\nfunction _plainReport (msg, prefix) {\n if (msg instanceof Array) {\n for (var m in msg) {\n _plainReport(msg[m], prefix)\n }\n } else {\n if (typeof msg === 'string') {\n console.log(prefix + ' ' + msg)\n } else {\n console.log(prefix + '↵')\n console.log(msg)\n }\n }\n}\n\nconst _letters = {\n 4: 'e', // Error\n 3: 'w', // Warning\n 2: 'n', // Notice\n 1: 'd' // Debug\n}\n\n/**\n * Transforms a level to a letter to identify every message.\n *\n * @private\n * @param {sLog.Level} level Level of the message\n */\nfunction _level2letter (level) {\n return _letters[level]\n}\n\n/**\n * This function is automatically executed at load.\n * Will search inside window.location.search for attribute 'nrvideo-debug=X'.\n * X can have one of these values, that will modify Log.Levels.\n * 5: SILENT,\n * 4: ERROR,\n * 3: WARNING,\n * 2: NOTICE,\n * 1: DEBUG,\n *\n * If nrvideo-colors=false is present, Log.colorful will be set to false.\n *\n * @private\n */\nfunction _loadLevelFromUrl () {\n if (typeof window !== 'undefined' && window.location && window.location.search) {\n var m = /\\?.*&*nrvideo-debug=(.+)/i.exec(window.location.search)\n if (m !== null) {\n if (m[1] === 'true') {\n Log.level = Log.Levels.ALL\n } else {\n Log.level = m[1]\n }\n }\n\n var m2 = /\\?.*&*nrvideo-colors=false/i.exec(window.location.search)\n if (m2 !== null) {\n Log.colorful = false\n }\n }\n}\n\n// Execute load level\n_loadLevelFromUrl()\n\nexport default Log\n","/**\n * Backend class provides the basic logic to create event backends.\n * This class is intended to be subclassed, not directly used.\n * \n * @class Backend\n */\nclass Backend {\n\n constructor() {\n /**\n * Custom attributes\n * @private\n */\n this._attributes = {}\n }\n\n /**\n * Sends given event (to be overwritten by a subclass).\n * @param {String} event Event to send.\n * @param {Object} data Data associated to the event.\n */\n send(event, data) {\n data = Object.assign(data || {}, this._attributes)\n }\n\n /**\n * Store custom attribute.\n * @param {String} key Attribute name.\n * @param {Object} value Attribute value.\n */\n setAttribute(key, value) {\n this._attributes[key] = value\n }\n\n /**\n * Store custom attribute list.\n * @param {Object} attr Attributes.\n */\n setAttributes(attr) {\n this._attributes.append(attr)\n }\n}\n\nexport default Backend","/**\n * This class calculates time lapses between two points on time.\n */\nclass Chrono {\n /**\n * Constructor\n */\n constructor () {\n this.reset()\n }\n\n /** Reset chrono values. */\n reset () {\n /** Start time */\n this.startTime = 0\n\n /** Stop time */\n this.stopTime = 0\n\n /**\n * If you set an offset in a chrono, its value will be added getDeltaTime and stop.\n *\n * @example\n * let chrono = new Chrono()\n * chrono.offset = 500\n * chrono.start()\n * process.sleep(500)\n * chrono.stop() // Will return 1000\n *\n * @type {number}\n */\n this.offset = 0\n }\n\n /**\n * Returns the time between start() and the last stop() in ms. Returns null if start wasn't\n * called.\n * @return {(number|null)} Time lapse in ms.\n */\n getDeltaTime () {\n if (this.startTime) {\n return this.offset + (new Date().getTime() - this.startTime)\n } else {\n return null\n }\n }\n\n /**\n * Starts the chrono.\n */\n start () {\n this.startTime = new Date().getTime()\n this.stopTime = 0\n }\n\n /**\n * Stops the timer and returns delta time.\n * @return {(number|null)} Returns the delta time\n */\n stop () {\n this.stopTime = new Date().getTime()\n return this.getDeltaTime()\n }\n\n /**\n * Creates a copy of the chrono.\n * @returns {Chrono} Cloned chrono\n */\n clone () {\n var chrono = new Chrono()\n chrono.startTime = this.startTime\n chrono.stopTime = this.stopTime\n chrono.offset = this.offset\n return chrono\n }\n}\n\nexport default Chrono\n","import Backend from './backend'\nimport NRInsightsBackend from './plugins/nrinsightsbackend'\nimport Core from './core'\nimport Constants from './constants'\nimport Chrono from './chrono'\nimport Log from './log'\nimport Emitter from './emitter'\nimport Tracker from './tracker'\nimport VideoTracker from './videotracker'\nimport VideoTrackerState from './videotrackerstate'\nimport { version } from '../package.json'\n\nexport {\n Constants,\n Chrono,\n Log,\n Emitter,\n Tracker,\n VideoTracker,\n VideoTrackerState,\n Core,\n Backend,\n NRInsightsBackend,\n version\n}\n","/**\n * This base class implements a basic behavior of listeners and events. Extend this object to have\n * this feature built-in inside your classes.\n *\n * @class Emitter\n */\nclass Emitter {\n /**\n * Sets a listener to a given event. Use {@link emit} to trigger those events.\n * Pass '*' to listen ALL events.\n *\n * @param {string} event Name of the event.\n * @param {function} callback Callback of the event. Receives event and data.\n * @return this\n */\n on (event, callback) {\n this._listeners = this._listeners || {}\n if (typeof callback === 'function') {\n this._listeners[event] = this._listeners[event] || []\n this._listeners[event].push(callback)\n return this\n }\n }\n\n /**\n * Removes given callback from the listeners of this object.\n *\n * @param {string} event Name of the event.\n * @param {function} callback Callback of the event.\n * @return this\n */\n off (event, callback) {\n this._listeners = this._listeners || {}\n\n if (this._listeners[event]) {\n var index = this._listeners[event].indexOf(callback)\n if (index !== -1) {\n this._listeners[event].splice(index, 1)\n }\n }\n return this\n }\n\n /**\n * Emits given event, triggering all the associated callbacks.\n *\n * @param {string} event Name of the event.\n * @param {object} [data] Custom data to be sent to the callbacks.\n * @return this\n */\n emit (event, data) {\n this._listeners = this._listeners || {}\n data = data || {}\n\n if (Array.isArray(this._listeners[event])) {\n this._listeners[event].forEach((callback) => {\n callback.call(this, { type: event, data: data, target: this })\n })\n }\n\n if (Array.isArray(this._listeners['*'])) {\n this._listeners['*'].forEach((callback) => {\n callback.call(this, { type: event, data: data, target: this })\n })\n }\n\n return this\n }\n}\n\nexport default Emitter\n","import * as pkg from '../package.json'\nimport Emitter from './emitter'\nimport Chrono from './chrono'\n\n/**\n * Tracker class provides the basic logic to extend Newrelic's Browser Agent capabilities.\n * Trackers are designed to listen third party elements (like video tags, banners, etc.) and send\n * information over to Browser Agent. Extend this class to create your own tracker, override\n * registerListeners and unregisterListeners for full coverage!\n *\n * @example\n * Tracker instances should be added to Core library to start sending data:\n * nrvideo.Core.addTracker(new Tracker())\n *\n * @extends Emitter\n */\nclass Tracker extends Emitter {\n /**\n * Constructor, receives options. You should call {@see registerListeners} after this.\n *\n * @param {Object} [options] Options for the tracker. See {@link setOptions}.\n */\n constructor (options) {\n super()\n\n /**\n * If you add something to this custom dictionary it will be added to every action. If you set\n * any value, it will always override the values returned by the getters.\n *\n * @example\n * If you define tracker.customData.contentTitle = 'a' and tracker.getTitle() returns 'b'.\n * 'a' will prevail.\n */\n this.customData = {}\n\n /**\n * Set time between hearbeats, in ms.\n */\n this.heartbeat = null\n\n /**\n * Another Tracker instance. Useful to relate ad Trackers to their parent content Trackers.\n * @type Tracker\n */\n this.parentTracker = null\n\n /**\n * Chrono that counts time since this class was instantiated.\n * @private\n */\n this._trackerReadyChrono = new Chrono()\n this._trackerReadyChrono.start()\n\n options = options || {}\n this.setOptions(options)\n }\n\n /**\n * Set options for the Tracker.\n *\n * @param {Object} [options] Options for the tracker.\n * @param {number} [options.heartbeat] Set time between heartbeats. See {@link heartbeat}.\n * @param {Object} [options.customData] Set custom data. See {@link customData}.\n * @param {Tracker} [options.parentTracker] Set parent tracker. See {@link parentTracker}.\n */\n setOptions (options) {\n if (options) {\n if (options.parentTracker) this.parentTracker = options.parentTracker\n if (options.customData) this.customData = options.customData\n if (options.heartbeat) this.heartbeat = options.heartbeat\n }\n }\n\n /**\n * Prepares tracker to dispose. Calls {@see unregisterListeners} and drops references.\n */\n dispose () {\n this.unregisterListeners()\n }\n\n /**\n * Override this method to register listeners to third party elements.\n *\n * @example\n * class SpecificTracker extends Tracker {\n * registerListeners() {\n * this.player.on('play', () => this.playHandler)\n * }\n *\n * playHandler() {\n * this.emit(Tracker.Events.REQUESTED)\n * }\n * }\n */\n registerListeners () {}\n\n /**\n * Override this method to unregister listeners to third party elements created with\n * {@see registerListeners}.\n *\n * @example\n * class SpecificTracker extends Tracker {\n * registerListeners() {\n * this.player.on('play', () => this.playHandler)\n * }\n *\n * unregisterListeners() {\n * this.player.off('play', () => this.playHandler)\n * }\n *\n * playHandler() {\n * this.emit(Tracker.Events.REQUESTED)\n * }\n * }\n */\n unregisterListeners () {}\n\n /**\n * Returns heartbeat time interval. 30000 (30s) if not set. See {@link setOptions}.\n * @return {number} Heartbeat interval in ms.\n * @final\n */\n getHeartbeat () {\n if (this.heartbeat) {\n return this.heartbeat\n } else if (this.parentTracker && this.parentTracker.heartbeat) {\n return this.parentTracker.heartbeat\n } else {\n return 30000\n }\n }\n\n /**\n * Starts heartbeating. Interval period set by options.heartbeat. Min 5000 ms.\n * This method is automaticaly called by the tracker once sendRequest is called.\n */\n startHeartbeat () {\n this._heartbeatInterval = setInterval(\n this.sendHeartbeat.bind(this),\n Math.max(this.getHeartbeat(), 5000)\n )\n }\n\n /**\n * Stops heartbeating. This method is automaticaly called by the tracker.\n */\n stopHeartbeat () {\n if (this._heartbeatInterval) {\n clearInterval(this._heartbeatInterval)\n }\n }\n\n /**\n * Heartbeating allows you to call this function each X milliseconds, defined by\n * {@link getHeartbeat}. This is useful to send regular events to track changes.\n *\n * By default it will send {@link Tracker.Events.HEARTBEAT}.\n * To start heartbeating use {@link startHeartbeat} and to stop them use {@link stopHeartbeat}.\n *\n * @example\n * Override this method to define your own Heartbeat reporting.\n *\n * class TrackerChild extends Tracker {\n * sendHeartbeat (att) {\n * this.send('MY_HEARBEAT_EVENT')\n * }\n * }\n *\n * @param {Object} [att] Collection of key:value attributes to send with the request.\n */\n sendHeartbeat (att) {\n this.send(Tracker.Events.HEARTBEAT, att)\n }\n\n /**\n * Override this method to return attributes for actions.\n *\n * @example\n * class SpecificTracker extends Tracker {\n * getAttributes(att) {\n * att = att || {}\n * att.information = 'something'\n * return att\n * }\n * }\n *\n * @param {object} [att] Collection of key value attributes\n * @return {object} Filled attributes\n * @final\n */\n getAttributes (att) {\n att = att || {}\n att.trackerName = this.getTrackerName()\n att.trackerVersion = this.getTrackerVersion()\n att.coreVersion = pkg.version\n att.timeSinceTrackerReady = this._trackerReadyChrono.getDeltaTime()\n\n for (let key in this.customData) {\n att[key] = this.customData[key]\n }\n\n if (document.hidden != undefined) {\n att.isBackgroundEvent = document.hidden\n }\n\n return att\n }\n\n /** Override to change of the Version of tracker. ie: '1.0.1' */\n getTrackerVersion () {\n return pkg.version\n }\n\n /** Override to change of the Name of the tracker. ie: 'custom-html5' */\n getTrackerName () {\n return 'base-tracker'\n }\n\n /**\n * Send given event. Will automatically call {@see getAttributes} to fill information.\n * Internally, this will call {@see Emitter#emit}, so you could listen any event fired.\n *\n * @example\n * tracker.send('BANNER_CLICK', { url: 'http....' })\n *\n * @param {string} event Event name\n * @param {object} [att] Key:value dictionary filled with attributes.\n */\n send (event, att) {\n this.emit(event, this.getAttributes(att))\n }\n}\n\n/**\n * Enumeration of events fired by this class.\n *\n * @static\n * @memberof Tracker\n * @enum {string}\n */\nTracker.Events = {\n /** The heartbeat event is sent once every 30 seconds while the video is playing. */\n HEARTBEAT: 'HEARTBEAT'\n}\n\nexport default Tracker\n","import Chrono from './chrono'\nimport Log from './log'\n\n/**\n * State machine for a VideoTracker and its monitored video.\n */\nclass VideoTrackerState {\n /** Constructor */\n constructor () {\n this.reset()\n\n /**\n * Time when the VideoTrackerState was initializated.\n * @private\n */\n this._createdAt = Date.now()\n }\n\n /** Resets all flags and chronos. */\n reset () {\n /**\n * Unique identifier of the view.\n * @private\n */\n this._viewSession = null\n\n /**\n * Number of views seen.\n * @private\n */\n this._viewCount = 0\n\n /**\n * True if it is tracking ads.\n * @private\n */\n this._isAd = false\n\n /**\n * Number of errors fired. 'End' resets it.\n */\n this.numberOfErrors = 0\n\n /**\n * Number of ads shown.\n */\n this.numberOfAds = 0\n\n /**\n * Number of videos played.\n */\n this.numberOfVideos = 0\n\n /**\n * The amount of ms the user has been watching content (not paused, not buffering, not ads...)\n */\n this.totalPlaytime = 0\n\n /**\n * The amount of ms the user has been watching ads during an ad break.\n */\n this.totalAdPlaytime = 0\n\n /** True if you are in the middle of an ad break. */\n this.isAdBreak = false\n\n /** True if initial buffering event already happened. */\n this.initialBufferingHappened = false\n\n this.resetFlags()\n this.resetChronos()\n }\n\n /** Resets flags. */\n resetFlags () {\n /** True once the player has finished loading. */\n this.isPlayerReady = false\n\n /** True if the video has been user-requested to play. ie: user cicks play. */\n this.isRequested = false\n\n /** True if the video has starting playing. ie: actual images/audio showing in screen. */\n this.isStarted = false\n\n /** True if the video is paused. */\n this.isPaused = false\n\n /** True if the video is performing a seek action. */\n this.isSeeking = false\n\n /** True if the video is currently buffering. */\n this.isBuffering = false\n\n /** True if the video is currently playing (not buffering, not paused...) */\n this.isPlaying = false\n }\n\n /** Resets chronos. */\n resetChronos () {\n /** Chrono that counts time since last requested event. */\n this.timeSinceRequested = new Chrono()\n\n /** Chrono that counts time since last start event. */\n this.timeSinceStarted = new Chrono()\n\n /** Chrono that counts time since last pause event. */\n this.timeSincePaused = new Chrono()\n\n /** Chrono that counts time since last seeking start event. */\n this.timeSinceSeekBegin = new Chrono()\n\n /** Chrono that counts time since last buffering start event. */\n this.timeSinceBufferBegin = new Chrono()\n\n /** Chrono that counts time since last ad break start event. */\n this.timeSinceAdBreakStart = new Chrono()\n\n /** Chrono that counts time since last download event. */\n this.timeSinceLastDownload = new Chrono()\n\n /** Chrono that counts time since last heartbeat. */\n this.timeSinceLastHeartbeat = new Chrono()\n\n /** Chrono that counts time since last rendition change. */\n this.timeSinceLastRenditionChange = new Chrono()\n\n /** Ads only. Chrono that counts time since last ad quartile. */\n this.timeSinceLastAdQuartile = new Chrono()\n\n /** Content only. Chrono that counts time since last AD_END. */\n this.timeSinceLastAd = new Chrono()\n\n /** Chrono that counts time since last *_RESUME. Only for buffering events. */\n this.timeSinceResumed = new Chrono()\n\n /** Chrono that counts time since last *_SEEK_END. Only for buffering events. */\n this.timeSinceSeekEnd = new Chrono()\n\n /** Chrono that counts the ammount of time the video have been playing since the last event. */\n this.playtimeSinceLastEvent = new Chrono()\n\n /** A dictionary containing the custom timeSince attributes. */\n this.customTimeSinceAttributes = {}\n }\n\n /** Returns true if the tracker is currently on ads. */\n isAd () {\n return this._isAd\n }\n\n /** Sets if the tracker is currenlty tracking ads */\n setIsAd (isAd) {\n this._isAd = isAd\n }\n\n /**\n * Set the Chrono for the custom attribute\n * \n * @param {object} name Time since attribute name.\n */\n setTimeSinceAttribute (name) {\n this.customTimeSinceAttributes[name] = new Chrono()\n this.customTimeSinceAttributes[name].start()\n }\n\n /**\n * Delete a time since attribute\n * \n * @param {object} name Time since attribute name.\n */\n removeTimeSinceAttribute (name) {\n delete this.customTimeSinceAttributes[name]\n }\n\n /**\n * Returns a random-generated view Session ID, useful to sort by views.\n */\n getViewSession () {\n if (!this._viewSession) {\n let time = new Date().getTime()\n let random = Math.random().toString(36).substring(2) + Math.random().toString(36).substring(2)\n\n this._viewSession = time + '-' + random\n }\n\n return this._viewSession\n }\n\n /**\n * Returns a random-generated view Session ID, plus a view count, allowing you to distinguish\n * between two videos played in the same session.\n */\n getViewId () {\n return this.getViewSession() + '-' + this._viewCount\n }\n\n /**\n * Fills given object with state-based attributes.\n *\n * @param {object} att Collection fo key value attributes\n * @return {object} Filled attributes\n */\n getStateAttributes (att) {\n att = att || {}\n\n if (this.isAd()) { // Ads only\n if (this.isRequested) {\n att.timeSinceAdRequested = this.timeSinceRequested.getDeltaTime()\n att.timeSinceLastAdHeartbeat = this.timeSinceLastHeartbeat.getDeltaTime()\n }\n if (this.isStarted) att.timeSinceAdStarted = this.timeSinceStarted.getDeltaTime()\n if (this.isPaused) att.timeSinceAdPaused = this.timeSincePaused.getDeltaTime()\n if (this.isBuffering) att.timeSinceAdBufferBegin = this.timeSinceBufferBegin.getDeltaTime()\n if (this.isSeeking) att.timeSinceAdSeekBegin = this.timeSinceSeekBegin.getDeltaTime()\n if (this.isAdBreak) att.timeSinceAdBreakBegin = this.timeSinceAdBreakStart.getDeltaTime()\n att.numberOfAds = this.numberOfAds\n } else { // Content only\n if (this.isRequested) {\n att.timeSinceRequested = this.timeSinceRequested.getDeltaTime()\n att.timeSinceLastHeartbeat = this.timeSinceLastHeartbeat.getDeltaTime()\n }\n if (this.isStarted) att.timeSinceStarted = this.timeSinceStarted.getDeltaTime()\n if (this.isPaused) att.timeSincePaused = this.timeSincePaused.getDeltaTime()\n if (this.isBuffering) att.timeSinceBufferBegin = this.timeSinceBufferBegin.getDeltaTime()\n if (this.isSeeking) att.timeSinceSeekBegin = this.timeSinceSeekBegin.getDeltaTime()\n att.timeSinceLastAd = this.timeSinceLastAd.getDeltaTime()\n att.numberOfVideos = this.numberOfVideos\n }\n att.numberOfErrors = this.numberOfErrors\n\n // Playtime\n if (!this.isAd()) { // Content only\n if (this.playtimeSinceLastEvent.startTime > 0) {\n att.playtimeSinceLastEvent = this.playtimeSinceLastEvent.getDeltaTime()\n } else {\n att.playtimeSinceLastEvent = 0\n }\n if (this.isPlaying) {\n this.playtimeSinceLastEvent.start()\n } else {\n this.playtimeSinceLastEvent.reset()\n }\n this.totalPlaytime += att.playtimeSinceLastEvent\n att.totalPlaytime = this.totalPlaytime\n }\n\n for (const [key, value] of Object.entries(this.customTimeSinceAttributes)) {\n att[key] = value.getDeltaTime()\n }\n\n return att\n }\n\n /**\n * Calculate the bufferType attribute.\n * \n * @param {boolean} isInitialBuffering Is initial buffering event.\n */\n calculateBufferType(isInitialBuffering) {\n let bufferType = ''\n if (isInitialBuffering) {\n bufferType = \"initial\";\n }\n else if (this.isSeeking) {\n bufferType = \"seek\";\n }\n else if (this.isPaused) {\n bufferType = \"pause\";\n }\n else {\n // If none of the above is true, it is a connection buffering\n bufferType = \"connection\";\n }\n Log.debug(\"Buffer Type = \" + bufferType)\n \n return bufferType\n }\n\n /**\n * Augments view count. This will be called with each *_START and *_END.\n */\n goViewCountUp () {\n this._viewCount++\n }\n\n /**\n * Checks flags and changes state.\n * @returns {boolean} True if the state changed.\n */\n goPlayerReady () {\n if (!this.isPlayerReady) {\n this.isPlayerReady = true\n return true\n } else {\n return false\n }\n }\n\n /**\n * Checks flags and changes state\n * @returns {boolean} True if the state changed.\n */\n goRequest () {\n if (!this.isRequested) {\n this.isRequested = true\n this.timeSinceLastAd.reset()\n this.timeSinceRequested.start()\n return true\n } else {\n return false\n }\n }\n\n /**\n * Checks flags and changes state\n * @returns {boolean} True if the state changed.\n */\n goStart () {\n if (this.isRequested && !this.isStarted) {\n if (this.isAd()) {\n this.numberOfAds++\n } else {\n this.numberOfVideos++\n }\n this.isStarted = true\n this.isPlaying = true\n this.timeSinceStarted.start()\n this.playtimeSinceLastEvent.start()\n return true\n } else {\n return false\n }\n }\n\n /**\n * Checks flags and changes state\n * @returns {boolean} True if the state changed.\n */\n goEnd () {\n if (this.isRequested) {\n this.numberOfErrors = 0\n this.resetFlags()\n this.timeSinceRequested.stop()\n this.timeSinceStarted.stop()\n this.playtimeSinceLastEvent.stop()\n return true\n } else {\n return false\n }\n }\n\n /**\n * Checks flags and changes state\n * @returns {boolean} True if the state changed.\n */\n goPause () {\n if (this.isStarted && !this.isPaused) {\n this.isPaused = true\n this.isPlaying = false\n this.timeSincePaused.start()\n this.playtimeSinceLastEvent.stop()\n this.timeSinceResumed.reset()\n return true\n } else {\n return false\n }\n }\n\n /**\n * Checks flags and changes state\n * @returns {boolean} True if the state changed.\n */\n goResume () {\n if (this.isStarted && this.isPaused) {\n this.isPaused = false\n this.isPlaying = true\n this.timeSincePaused.stop()\n this.timeSinceResumed.start()\n return true\n } else {\n return false\n }\n }\n\n /**\n * Checks flags and changes state\n * @returns {boolean} True if the state changed.\n */\n goBufferStart () {\n if (this.isRequested && !this.isBuffering) {\n this.isBuffering = true\n this.isPlaying = false\n this.timeSinceBufferBegin.start()\n return true\n } else {\n return false\n }\n }\n\n /**\n * Checks flags and changes state\n * @returns {boolean} True if the state changed.\n */\n goBufferEnd () {\n if (this.isRequested && this.isBuffering) {\n this.isBuffering = false\n this.isPlaying = true\n this.timeSinceBufferBegin.stop()\n return true\n } else {\n return false\n }\n }\n\n /**\n * Checks flags and changes state\n * @returns {boolean} True if the state changed.\n */\n goSeekStart () {\n if (this.isStarted && !this.isSeeking) {\n this.isSeeking = true\n this.isPlaying = false\n this.timeSinceSeekBegin.start()\n this.timeSinceSeekEnd.reset()\n return true\n } else {\n return false\n }\n }\n\n /**\n * Checks flags and changes state\n * @returns {boolean} True if the state changed.\n */\n goSeekEnd () {\n if (this.isStarted && this.isSeeking) {\n this.isSeeking = false\n this.isPlaying = true\n this.timeSinceSeekBegin.stop()\n this.timeSinceSeekEnd.start()\n return true\n } else {\n return false\n }\n }\n\n /**\n * Checks flags and changes state\n * @returns {boolean} True if the state changed.\n */\n goAdBreakStart () {\n if (!this.isAdBreak) {\n this.isAdBreak = true\n this.timeSinceAdBreakStart.start()\n return true\n } else {\n return false\n }\n }\n\n /**\n * Checks flags and changes state\n * @returns {boolean} True if the state changed.\n */\n goAdBreakEnd () {\n if (this.isAdBreak) {\n this.isRequested = false\n this.isAdBreak = false\n this.totalAdPlaytime = this.timeSinceAdBreakStart.getDeltaTime()\n this.timeSinceAdBreakStart.stop()\n return true\n } else {\n return false\n }\n }\n\n /**\n * Restarts download chrono.\n */\n goDownload () {\n this.timeSinceLastDownload.start()\n }\n\n /**\n * Restarts heartbeat chrono.\n */\n goHeartbeat () {\n this.timeSinceLastHeartbeat.start()\n }\n\n /**\n * Restarts rendition change chrono.\n */\n goRenditionChange () {\n this.timeSinceLastRenditionChange.start()\n }\n\n /**\n * Restarts ad quartile chrono.\n */\n goAdQuartile () {\n this.timeSinceLastAdQuartile.start()\n }\n\n /**\n * Increments error counter.\n */\n goError () {\n this.numberOfErrors++\n }\n\n /**\n * Restarts last ad chrono.\n */\n goLastAd () {\n this.timeSinceLastAd.start()\n }\n}\n\nexport default VideoTrackerState\n","import * as nrvideo from 'newrelic-video-core'\nimport Html5Tracker from './tracker'\n\nnrvideo.Html5Tracker = Html5Tracker\nmodule.exports = nrvideo\n","import Backend from '../backend'\nimport Log from '../log'\n\n/**\n * Implements a New Relic Insights API backend. For a description of what is a Backend, see {@link Backend}.\n * It must be initialized using a New Relic Account ID and an Insights API insert key.\n *\n * @example\n * let backend = new nrvideo.NRInsightsBackend(\"ACCOUNT ID\", \"API KEY\")\n * nrvideo.Core.setBackend(backend)\n *\n * @extends Backend\n */\nclass NRInsightsBackend extends Backend {\n /**\n * Constructor, receives account ID, API Key and (optionally) an event type.\n *\n * @param {String} [accountId] Insights Account ID.\n * @param {String} [apiKey] Insights API Key.\n * @param {String} [eventType] Insights event type. Default 'BrowserVideo'.\n */\n constructor(accountId, apiKey, eventType = 'BrowserVideo') {\n super()\n\n /**\n * Insights account ID.\n * @private\n */\n this._accountId = accountId\n\n /**\n * Insights API Key.\n * @private\n */\n this._apiKey = apiKey\n\n /**\n * Insights event type.\n * @private\n */\n this._eventType = eventType\n\n /**\n * Buffer to store events.\n * @private\n */\n this._eventBuffer = []\n\n /**\n * Harvest timer lock.\n * @private\n */\n this._harvestLocked = false\n\n /**\n * Last timestamp.\n * @private\n */\n this._lastTimestamp = 0\n\n // Define harvest timer handler\n setInterval(() => { this.harvestHandler(NRInsightsBackend.Source.TIMER) }, 10000)\n }\n\n send(event, data) {\n super.send(event, data)\n if (this._eventBuffer.length < 500) {\n data = this.generateAttributes(data)\n data['eventType'] = this._eventType\n data['actionName'] = event\n // Mechanism to avoid having two events with the same timestamp\n let timestamp = Date.now()\n if (timestamp > this._lastTimestamp) {\n data['timestamp'] = timestamp\n this._lastTimestamp = timestamp\n }\n else {\n this._lastTimestamp ++\n data['timestamp'] = this._lastTimestamp\n }\n this._eventBuffer.push(data)\n }\n }\n\n generateAttributes(data) {\n data['pageUrl'] = window.location.href\n data['currentUrl'] = window.location.origin + window.location.pathname\n data['referrerUrl'] = document.referrer\n\n let OSName = \"Unknown\"\n if (navigator.userAgent.indexOf(\"Win\") != -1) OSName = \"Windows\"\n else if (navigator.userAgent.indexOf(\"Android\") != -1) OSName = \"Android\"\n else if (navigator.userAgent.indexOf(\"Mac\") != -1) OSName = \"Mac\"\n else if (navigator.userAgent.match(/iPhone|iPad|iPod/i)) OSName = \"iOS\"\n else if (navigator.userAgent.indexOf(\"Linux\") != -1) OSName = \"Linux\"\n else if (navigator.userAgent.indexOf(\"X11\") != -1) OSName = \"UNIX\"\n data['userAgentOS'] = OSName\n\n let agentName = \"Unknown\"\n if (navigator.userAgent.indexOf(\"Chrome\") != -1 ) agentName = \"Chrome\"\n else if (navigator.userAgent.indexOf(\"Firefox\") != -1 ) agentName = \"Firefox\"\n else if (navigator.userAgent.indexOf(\"MSIE\") != -1 ) agentName = \"IE\"\n else if (navigator.userAgent.indexOf(\"Edge\") != -1 ) agentName = \"Microsoft Edge\"\n else if (navigator.userAgent.indexOf(\"Safari\") != -1 ) agentName = \"Safari\"\n else if (navigator.userAgent.indexOf(\"Opera\") != -1 ) agentName = \"Opera\"\n data['userAgentName'] = agentName\n\n let deviceType = \"Unknown\"\n if (navigator.userAgent.match(/Tablet|iPad/i)) deviceType = \"Tablet\"\n else if (navigator.userAgent.match(/Mobile|Windows Phone|Lumia|Android|webOS|iPhone|iPod|Blackberry|PlayBook|BB10|Opera Mini|\\bCrMo\\/|Opera Mobi/i)) deviceType = \"Mobile\"\n else if (window.cast != undefined) deviceType = \"Cast\"\n else deviceType = \"Desktop\"\n data['deviceType'] = deviceType\n\n return data\n }\n\n harvestHandler(source) {\n if (source == NRInsightsBackend.Source.TIMER && this._harvestLocked) {\n Log.debug(\"Harvest still locked, abort\")\n return\n }\n\n this._harvestLocked = true\n\n if (this._eventBuffer.length > 0) {\n Log.debug(\"Push events to Insights = \", this._eventBuffer)\n this.pushEventToInsights(this._eventBuffer.pop())\n }\n else {\n this._harvestLocked = false\n }\n }\n\n pushEventToInsights(ev) {\n const requestOptions = {\n method: 'POST',\n headers: { 'Content-Type': 'application/json', 'X-Insert-Key': this._apiKey },\n body: JSON.stringify(ev)\n }\n\n const url = \"https://insights-collector.newrelic.com/v1/accounts/\" + this._accountId + \"/events\"\n fetch(url, requestOptions)\n .then(response => response.json())\n .then(data => this.insightsRequestResponse(data))\n .catch((error) => {\n Log.error('Error:', error, ev);\n // Put back the event and abort current fetch process\n this._eventBuffer.push(ev)\n this._harvestLocked = false\n });\n }\n\n insightsRequestResponse(data) {\n // Send next event\n this.harvestHandler(NRInsightsBackend.Source.FETCH)\n }\n}\n\nNRInsightsBackend.Source = {\n TIMER: \"TIMER\",\n FETCH: \"FETCH\"\n}\n\nexport default NRInsightsBackend\n","import Log from './log'\nimport Backend from './backend'\n\n/**\n * Static class that sums up core functionalities of the library.\n * @static\n */\nclass Core {\n /**\n * Add a tracker to the system. Trackers added will start reporting its events to NR's backend.\n *\n * @param {(Emitter|Tracker)} tracker Tracker instance to add.\n */\n static addTracker (tracker) {\n if (tracker.on && tracker.emit) {\n trackers.push(tracker)\n tracker.on('*', eventHandler)\n if (typeof tracker.trackerInit == 'function') { \n tracker.trackerInit(); \n }\n } else {\n Log.error('Tried to load a non-tracker.', tracker)\n }\n }\n\n /**\n * Disposes and remove given tracker. Removes its listeners.\n *\n * @param {Tracker} tracker Tracker to remove.\n */\n static removeTracker (tracker) {\n tracker.off('*', eventHandler)\n tracker.dispose()\n let index = trackers.indexOf(tracker)\n if (index !== -1) trackers.splice(index, 1)\n }\n\n /**\n * Returns the array of trackers.\n *\n * @returns {Tracker[]} Array of trackers.\n */\n static getTrackers () {\n return trackers\n }\n\n /**\n * Returns the current backend.\n *\n * @returns {Backend} The current backend.\n */\n static getBackend() {\n return backend\n }\n\n /**\n * Sets the current backend.\n * @param {Backend} backendInstance Backend instance.\n */\n static setBackend(backendInstance) {\n backend = backendInstance\n }\n\n /**\n * Sends given event using the appropriate backend.\n * @param {String} event Event to send.\n * @param {Object} data Data associated to the event.\n */\n static send(event, data) {\n if (Core.getBackend() == undefined || !(Core.getBackend() instanceof Backend)) {\n // Use the default backend (NR Agent)\n if (typeof newrelic !== 'undefined' && newrelic.addPageAction) {\n newrelic.addPageAction(event, data)\n } else {\n if (!isErrorShown) {\n Log.error(\n 'newrelic.addPageAction() is not available.',\n 'In order to use NewRelic Video you will need New Relic Browser Agent.'\n )\n isErrorShown = true\n }\n }\n }\n else {\n // Use the user-defined backend\n Core.getBackend().send(event, data)\n }\n }\n\n /**\n * Sends an error event. This may be used for external errors launched by the app, the network or\n * any external factor. Note that errors within the player are normally reported with\n * tracker.sendError, so this method should not be used to report those.\n *\n * @param {object} att attributes to be sent along the error.\n */\n static sendError (att) {\n Core.send('ERROR', att)\n }\n}\n\nlet trackers = []\nlet backend;\nlet isErrorShown = false\n\n/**\n * Logs and sends given event.\n *\n * @private\n * @param {Event} e Event\n */\nfunction eventHandler (e) {\n let data = cleanData(e.data)\n if (Log.level <= Log.Levels.DEBUG) {\n Log.notice('Sent', e.type, data)\n } else {\n Log.notice('Sent', e.type)\n }\n Core.send(e.type, data)\n}\n\n/**\n * Cleans given object, removing all items with value === null.\n * @private\n * @param {Object} data Data to clean\n * @returns {Object} Cleaned object\n */\nfunction cleanData (data) {\n let ret = {}\n for (let i in data) {\n if (data[i] !== null && typeof data[i] !== 'undefined') ret[i] = data[i]\n }\n return ret\n}\n\nexport default Core\n","/**\n * Constants for the library.\n * @class Constants\n * @static\n */\nclass Constants {}\n\n/**\n * Enum for types/positions of ads.\n * @example var type = Constants.AdPositions.PRE\n * @enum {String}\n */\nConstants.AdPositions = {\n /** For ads shown before the content. */\n PRE: 'pre',\n /** For ads shown during the content. */\n MID: 'mid',\n /** For ads shown after the content. */\n POST: 'post'\n}\n\nexport default Constants\n","import Log from './log'\nimport Tracker from './tracker'\nimport TrackerState from './videotrackerstate'\n\n/**\n * Base video tracker class provides extensible tracking over video elements. See {@link Tracker}.\n * Extend this class to create your own video tracker class. Override getter methods and\n * registerListeners/unregisterListeners to provide full integration with your video experience.\n *\n * @example\n * Tracker instances should be added to Core library to start sending data:\n * nrvideo.Core.addTracker(new Tracker())\n *\n * @extends Tracker\n */\nclass VideoTracker extends Tracker {\n /**\n * Constructor, receives player and options.\n * Lifecycle: constructor > {@link setOptions} > {@link setPlayer} > {@link registerListeners}.\n *\n * @param {Object} [player] Player to track. See {@link setPlayer}.\n * @param {Object} [options] Options for the tracker. See {@link setOptions}.\n */\n constructor (player, options) {\n super()\n\n /**\n * TrackerState instance. Stores the state of the view. Tracker will automatically update the\n * state of its instance, so there's no need to modify/interact with it manually.\n * @type TrackerState\n */\n this.state = new TrackerState()\n\n /**\n * Another Tracker instance to track ads.\n * @type Tracker\n */\n this.adsTracker = null\n\n /**\n * Last bufferType value.\n * @private\n */\n this._lastBufferType = null\n\n options = options || {}\n this.setOptions(options)\n if (player) this.setPlayer(player, options.tag)\n\n Log.notice('Tracker ' + this.getTrackerName() + ' v' + this.getTrackerVersion() + ' is ready.')\n }\n\n /**\n * Set options for the Tracker.\n *\n * @param {Object} [options] Options for the tracker.\n * @param {Boolean} [options.isAd] True if the tracker is tracking ads. See {@link setIsAd}.\n * @param {number} [options.heartbeat] Set time between heartbeats. See {@link heartbeat}.\n * @param {Object} [options.customData] Set custom data. See {@link customData}.\n * @param {Tracker} [options.parentTracker] Set parent tracker. See {@link parentTracker}.\n * @param {Tracker} [options.adsTracker] Set ads tracker. See {@link adsTracker}.\n * @param {Object} [options.tag] DOM element to track. See {@link setPlayer}.\n */\n setOptions (options) {\n if (options) {\n if (options.adsTracker) this.setAdsTracker(options.adsTracker)\n if (typeof options.isAd === 'boolean') this.setIsAd(options.isAd)\n Tracker.prototype.setOptions.apply(this, arguments)\n }\n }\n\n /**\n * Set a player and/or a tag. If there was one already defined, it will call dispose() first.\n * Will call this.registerListeners() afterwards.\n *\n * @param {Object|string} player New player to save as this.player. If a string is passed,\n * document.getElementById will be called.\n * @param {DOMObject|string} [tag] Optional DOMElement to save as this.tag. If a string is passed,\n * document.getElementById will be called.\n */\n setPlayer (player, tag) {\n if (this.player || this.tag) this.dispose()\n\n if (typeof document !== 'undefined' && document.getElementById) {\n if (typeof player === 'string') player = document.getElementById(player)\n if (typeof tag === 'string') tag = document.getElementById(tag)\n }\n\n tag = tag || player // if no tag is passed, use player as both.\n\n this.player = player\n this.tag = tag\n this.registerListeners()\n }\n\n /** Returns true if the tracker is currently on ads. */\n isAd () {\n return this.state.isAd()\n }\n\n /** Sets if the tracker is currenlty tracking ads */\n setIsAd (isAd) {\n this.state.setIsAd(isAd)\n }\n\n /**\n * Use this function to set up a child ad tracker. You will be able to access it using\n * this.adsTracker.\n *\n * @param {Tracker} tracker Ad tracker to add\n */\n setAdsTracker (tracker) {\n this.disposeAdsTracker() // dispose current one\n if (tracker) {\n this.adsTracker = tracker\n this.adsTracker.setIsAd(true)\n this.adsTracker.parentTracker = this\n this.adsTracker.on('*', funnelAdEvents.bind(this))\n }\n }\n\n /**\n * Dispose current adsTracker.\n */\n disposeAdsTracker () {\n if (this.adsTracker) {\n this.adsTracker.off('*', funnelAdEvents)\n this.adsTracker.dispose()\n }\n }\n\n /**\n * Prepares tracker to dispose. Calls unregisterListener and drops references to player and tag.\n */\n dispose () {\n this.stopHeartbeat()\n this.disposeAdsTracker()\n this.unregisterListeners()\n this.player = null\n this.tag = null\n }\n\n /**\n * Override this method to register listeners to player/tag.\n * @example\n * class SpecificTracker extends Tracker {\n * registerListeners() {\n * this.player.on('play', () => this.playHandler)\n * }\n *\n * playHandler() {\n * this.send(VideoTracker.Events.REQUESTED)\n * }\n * }\n */\n registerListeners () { }\n\n /**\n * Override this method to unregister listeners to player/tag created in registerListeners\n * @example\n * class SpecificTracker extends Tracker {\n * registerListeners() {\n * this.player.on('play', () => this.playHandler)\n * }\n *\n * unregisterListeners() {\n * this.player.off('play', () => this.playHandler)\n * }\n *\n * playHandler() {\n * this.send(VideoTracker.Events.REQUESTED)\n * }\n * }\n */\n unregisterListeners () { }\n\n /**\n * Trackers will generate unique id's for every new video iteration. If you have your own unique\n * view value, you can override this method to return it.\n * If the tracker has a parentTracker defined, parent viewId will be used.\n */\n getViewId () {\n if (this.parentTracker) {\n return this.parentTracker.getViewId()\n } else {\n return this.state.getViewId()\n }\n }\n\n /**\n * Trackers will generate unique id's for every new video session. If you have your own unique\n * view value, you can override this method to return it.\n * If the tracker has a parentTracker defined, parent viewId will be used.\n */\n getViewSession () {\n if (this.parentTracker) {\n return this.parentTracker.getViewSession()\n } else {\n return this.state.getViewSession()\n }\n }\n\n /** Override to return the Id of the video. */\n getVideoId () {\n return null\n }\n\n /** Override to return Title of the video. */\n getTitle () {\n return null\n }\n\n /** Override to return True if the video is live. */\n isLive () {\n return null\n }\n\n /** Override to return Bitrate (in bits) of the video. */\n getBitrate () {\n return null\n }\n\n /** Calculates consumed bitrate using webkitVideoDecodedByteCount. */\n getWebkitBitrate () {\n if (this.tag && this.tag.webkitVideoDecodedByteCount) {\n let bitrate\n if (this._lastWebkitBitrate) {\n bitrate = this.tag.webkitVideoDecodedByteCount\n let delta = bitrate - this._lastWebkitBitrate\n let seconds = this.getHeartbeat() / 1000\n bitrate = Math.round((delta / seconds) * 8)\n }\n this._lastWebkitBitrate = this.tag.webkitVideoDecodedByteCount\n return bitrate || null\n }\n }\n\n /** Override to return Name of the rendition (ie: 1080p). */\n getRenditionName () {\n return null\n }\n\n /** Override to return Target Bitrate of the rendition. */\n getRenditionBitrate () {\n return null\n }\n\n /**\n * This method will return 'up', 'down' or null depending on if the bitrate of the rendition\n * have changed from the last time it was called.\n *\n * @param {boolean} [saveNewRendition=false] If true, current rendition will be stored to be used\n * the next time this method is called. This allows you to call this.getRenditionShift() without\n * saving the current rendition and thus preventing interferences with RENDITION_CHANGE events.\n */\n getRenditionShift (saveNewRendition) {\n let current = this.getRenditionBitrate()\n let last\n if (this.isAd()) {\n last = this._lastAdRendition\n if (saveNewRendition) this._lastAdRendition = current\n } else {\n last = this._lastRendition\n if (saveNewRendition) this._lastRendition = current\n }\n\n if (!current || !last) {\n return null\n } else {\n if (current > last) {\n return 'up'\n } else if (current < last) {\n return 'down'\n } else {\n return null\n }\n }\n }\n\n /** Override to return renidtion actual Height (before re-scaling). */\n getRenditionHeight () {\n return this.tag ? this.tag.videoHeight : null\n }\n\n /** Override to return rendition actual Width (before re-scaling). */\n getRenditionWidth () {\n return this.tag ? this.tag.videoWidth : null\n }\n\n /** Override to return Duration of the video, in ms. */\n getDuration () {\n return this.tag ? this.tag.duration : null\n }\n\n /** Override to return Playhead (currentTime) of the video, in ms. */\n getPlayhead () {\n return this.tag ? this.tag.currentTime : null\n }\n\n /**\n * Override to return Language of the video. We recommend using locale notation, ie: en_US.\n * {@see https://gist.github.com/jacobbubu/1836273}\n */\n getLanguage () {\n return null\n }\n\n /** Override to return URL of the resource being played. */\n getSrc () {\n return this.tag ? this.tag.currentSrc : null\n }\n\n /** Override to return Playrate (speed) of the video. ie: 1.0, 0.5, 1.25... */\n getPlayrate () {\n return this.tag ? this.tag.playbackRate : null\n }\n\n /** Override to return True if the video is currently muted. */\n isMuted () {\n return this.tag ? this.tag.muted : null\n }\n\n /** Override to return True if the video is currently fullscreen. */\n isFullscreen () {\n return null\n }\n\n /** Override to return the CDN serving the content. */\n getCdn () {\n return null\n }\n\n /** Override to return the Name of the player. */\n getPlayerName () {\n return this.getTrackerName()\n }\n\n /** Override to return the Version of the player. */\n getPlayerVersion () {\n return null\n }\n\n /** Override to return current FPS (Frames per second). */\n getFps () {\n return null\n }\n\n /**\n * Override to return if the player was autoplayed. By default: this.tag.autoplay\n */\n isAutoplayed () {\n return this.tag ? this.tag.autoplay : null\n }\n\n /**\n * Override to return the player preload attribute. By default: this.tag.preload\n */\n getPreload () {\n return this.tag ? this.tag.preload : null\n }\n\n // Only for ads\n /**\n * Override to return Quartile of the ad. 0 before first, 1 after first quartile, 2 after\n * midpoint, 3 after third quartile, 4 when completed.\n */\n getAdQuartile () {\n return null\n }\n\n /**\n * Override to return the position of the ad. Use {@link Constants.AdPositions} enum\n * to fill this data.\n */\n getAdPosition () {\n if (this.parentTracker) {\n return this.parentTracker.state.isStarted ? 'mid' : 'pre'\n }\n else {\n return null\n }\n }\n\n /**\n * Override to return the ad partner. ie: ima, freewheel...\n */\n getAdPartner () {\n return null\n }\n\n /**\n * Override to return the creative id of the ad.\n */\n getAdCreativeId () {\n return null\n }\n\n /**\n * Do NOT override. This method fills all the appropiate attributes for tracked video.\n *\n * @param {object} [att] Collection of key value attributes\n * @return {object} Filled attributes\n * @final\n */\n getAttributes (att) {\n att = Tracker.prototype.getAttributes.apply(this, arguments)\n\n if (typeof att.isAd === 'undefined') att.isAd = this.isAd()\n att.viewSession = this.getViewSession()\n att.viewId = this.getViewId()\n att.playerName = this.getPlayerName()\n att.playerVersion = this.getPlayerVersion()\n\n try {\n att.pageUrl = window.location.href\n } catch (err) { /* skip */ }\n\n if (this.isAd()) { // Ads\n att.adId = this.getVideoId()\n att.adTitle = this.getTitle()\n att.adBitrate = this.getBitrate() || this.getWebkitBitrate()\n att.adRenditionName = this.getRenditionName()\n att.adRenditionBitrate = this.getRenditionBitrate()\n att.adRenditionHeight = this.getRenditionHeight()\n att.adRenditionWidth = this.getRenditionWidth()\n att.adDuration = this.getDuration()\n att.adPlayhead = this.getPlayhead()\n att.adLanguage = this.getLanguage()\n att.adSrc = this.getSrc()\n att.adCdn = this.getCdn()\n att.adIsMuted = this.isMuted()\n att.adFps = this.getFps()\n // ad exclusives\n att.adQuartile = this.getAdQuartile()\n att.adPosition = this.getAdPosition()\n att.adCreativeId = this.getAdCreativeId()\n att.adPartner = this.getAdPartner()\n } else { // no ads\n att.contentId = this.getVideoId()\n att.contentTitle = this.getTitle()\n att.contentIsLive = this.isLive()\n att.contentBitrate = this.getBitrate() || this.getWebkitBitrate()\n att.contentRenditionName = this.getRenditionName()\n att.contentRenditionBitrate = this.getRenditionBitrate()\n att.contentRenditionHeight = this.getRenditionHeight()\n att.contentRenditionWidth = this.getRenditionWidth()\n att.contentDuration = this.getDuration()\n att.contentPlayhead = this.getPlayhead()\n att.contentLanguage = this.getLanguage()\n att.contentSrc = this.getSrc()\n att.contentPlayrate = this.getPlayrate()\n att.contentIsFullscreen = this.isFullscreen()\n att.contentIsMuted = this.isMuted()\n att.contentCdn = this.getCdn()\n att.contentIsAutoplayed = this.isAutoplayed()\n att.contentPreload = this.getPreload()\n att.contentFps = this.getFps()\n if (this.adsTracker != null && this.adsTracker.state.totalAdPlaytime > 0) {\n att.totalAdPlaytime = this.adsTracker.state.totalAdPlaytime;\n }\n }\n\n this.state.getStateAttributes(att)\n\n for (let key in this.customData) {\n att[key] = this.customData[key]\n }\n\n return att\n }\n\n /**\n * Sends custom event and registers a timeSince attribute.\n * @param {Object} [actionName] Custom action name.\n * @param {Object} [timeSinceAttName] Custom timeSince attribute name.\n * @param {Object} [att] Collection of key:value attributes to send with the request.\n */\n sendCustom (actionName, timeSinceAttName, att) {\n att = att || {}\n this.send(actionName, att)\n this.state.setTimeSinceAttribute(timeSinceAttName)\n }\n\n /**\n * Sends associated event and changes view state. An internal state machine will prevent\n * duplicated events. Should be associated to an event using registerListeners.\n * @param {Object} [att] Collection of key:value attributes to send with the request.\n */\n sendPlayerReady (att) {\n if (this.state.goPlayerReady()) {\n att = att || {}\n this.send(VideoTracker.Events.PLAYER_READY, att)\n }\n }\n\n /**\n * Sends associated event and changes view state. An internal state machine will prevent\n * duplicated events. Should be associated to an event using registerListeners. Calls\n * {@link startHeartbeat}.\n * @param {Object} [att] Collection of key:value attributes to send with the request.\n */\n sendRequest (att) {\n if (this.state.goRequest()) {\n this.state.goViewCountUp()\n let ev = this.isAd() ? VideoTracker.Events.AD_REQUEST : VideoTracker.Events.CONTENT_REQUEST\n this.send(ev, att)\n this.startHeartbeat()\n this.state.goHeartbeat()\n }\n }\n\n /**\n * Sends associated event and changes view state. An internal state machine will prevent\n * duplicated events. Should be associated to an event using registerListeners.\n * @param {Object} [att] Collection of key:value attributes to send with the request.\n */\n sendStart (att) {\n if (this.state.goStart()) {\n let ev\n if (this.isAd()) {\n ev = VideoTracker.Events.AD_START\n if (this.parentTracker) this.parentTracker.state.isPlaying = false\n } else {\n ev = VideoTracker.Events.CONTENT_START\n }\n this.send(ev, att)\n }\n }\n\n /**\n * Sends associated event and changes view state. An internal state machine will prevent\n * duplicated events. Should be associated to an event using registerListeners. Calls\n * {@link stopHeartbeat}.\n * @param {Object} [att] Collection of key:value attributes to send with the request.\n */\n sendEnd (att) {\n if (this.state.goEnd()) {\n att = att || {}\n let ev\n if (this.isAd()) {\n ev = VideoTracker.Events.AD_END\n att.timeSinceAdRequested = this.state.timeSinceRequested.getDeltaTime()\n att.timeSinceAdStarted = this.state.timeSinceStarted.getDeltaTime()\n if (this.parentTracker) this.parentTracker.state.isPlaying = true\n } else {\n ev = VideoTracker.Events.CONTENT_END\n att.timeSinceRequested = this.state.timeSinceRequested.getDeltaTime()\n att.timeSinceStarted = this.state.timeSinceStarted.getDeltaTime()\n }\n this.stopHeartbeat()\n this.send(ev, att)\n if (this.parentTracker && this.isAd()) this.parentTracker.state.goLastAd()\n this.state.goViewCountUp()\n this.state.totalPlaytime = 0\n }\n }\n\n /**\n * Sends associated event and changes view state. An internal state machine will prevent\n * duplicated events. Should be associated to an event using registerListeners.\n * @param {Object} [att] Collection of key:value attributes to send with the request.\n */\n sendPause (att) {\n if (this.state.goPause()) {\n let ev = this.isAd() ? VideoTracker.Events.AD_PAUSE : VideoTracker.Events.CONTENT_PAUSE\n this.send(ev, att)\n }\n }\n\n /**\n * Sends associated event and changes view state. An internal state machine will prevent\n * duplicated events. Should be associated to an event using registerListeners.\n * @param {Object} [att] Collection of key:value attributes to send with the request.\n */\n sendResume (att) {\n if (this.state.goResume()) {\n att = att || {}\n let ev\n if (this.isAd()) {\n ev = VideoTracker.Events.AD_RESUME\n att.timeSinceAdPaused = this.state.timeSincePaused.getDeltaTime()\n } else {\n ev = VideoTracker.Events.CONTENT_RESUME\n att.timeSincePaused = this.state.timeSincePaused.getDeltaTime()\n }\n this.send(ev, att)\n }\n }\n\n /**\n * Sends associated event and changes view state. An internal state machine will prevent\n * duplicated events. Should be associated to an event using registerListeners.\n * @param {Object} [att] Collection of key:value attributes to send with the request.\n */\n sendBufferStart (att) {\n if (this.state.goBufferStart()) {\n att = att || {}\n let ev\n if (this.isAd()) {\n ev = VideoTracker.Events.AD_BUFFER_START\n } else {\n ev = VideoTracker.Events.CONTENT_BUFFER_START\n }\n\n att = this.buildBufferAttributes(att)\n this._lastBufferType = att.bufferType\n \n this.send(ev, att)\n }\n }\n\n /**\n * Sends associated event and changes view state. An internal state machine will prevent\n * duplicated events. Should be associated to an event using registerListeners.\n * @param {Object} [att] Collection of key:value attributes to send with the request.\n */\n sendBufferEnd (att) {\n if (this.state.goBufferEnd()) {\n att = att || {}\n let ev\n if (this.isAd()) {\n ev = VideoTracker.Events.AD_BUFFER_END\n att.timeSinceAdBufferBegin = this.state.timeSinceBufferBegin.getDeltaTime()\n } else {\n ev = VideoTracker.Events.CONTENT_BUFFER_END\n att.timeSinceBufferBegin = this.state.timeSinceBufferBegin.getDeltaTime()\n }\n\n att = this.buildBufferAttributes(att)\n // Set the bufferType attribute of the last BUFFER_START\n if (this._lastBufferType != null) {\n att.bufferType = this._lastBufferType\n }\n\n this.send(ev, att)\n this.state.initialBufferingHappened = true\n }\n }\n \n buildBufferAttributes(att) {\n if (att.timeSinceStarted == undefined || att.timeSinceStarted < 100) {\n att.isInitialBuffering = !this.state.initialBufferingHappened\n }\n else {\n att.isInitialBuffering = false\n }\n\n att.bufferType = this.state.calculateBufferType(att.isInitialBuffering)\n \n att.timeSinceResumed = this.state.timeSinceResumed.getDeltaTime()\n att.timeSinceSeekEnd = this.state.timeSinceSeekEnd.getDeltaTime()\n\n return att\n }\n\n /**\n * Sends associated event and changes view state. An internal state machine will prevent\n * duplicated events. Should be associated to an event using registerListeners.\n * @param {Object} [att] Collection of key:value attributes to send with the request.\n */\n sendSeekStart (att) {\n if (this.state.goSeekStart()) {\n let ev\n if (this.isAd()) {\n ev = VideoTracker.Events.AD_SEEK_START\n } else {\n ev = VideoTracker.Events.CONTENT_SEEK_START\n }\n this.send(ev, att)\n }\n }\n\n /**\n * Sends associated event and changes view state. An internal state machine will prevent\n * duplicated events. Should be associated to an event using registerListeners.\n * @param {Object} [att] Collection of key:value attributes to send with the request.\n */\n sendSeekEnd (att) {\n if (this.state.goSeekEnd()) {\n att = att || {}\n let ev\n if (this.isAd()) {\n ev = VideoTracker.Events.AD_SEEK_END\n att.timeSinceAdSeekBegin = this.state.timeSinceSeekBegin.getDeltaTime()\n } else {\n ev = VideoTracker.Events.CONTENT_SEEK_END\n att.timeSinceSeekBegin = this.state.timeSinceSeekBegin.getDeltaTime()\n }\n this.send(ev, att)\n }\n }\n\n /**\n * Sends associated event and changes view state. An internal state machine will prevent\n * duplicated events. Should be associated to an event using registerListeners.\n * @param {Object} [att] Collection of key:value attributes to send with the request.\n * @param {String} att.state Download requires a string to distinguish different states.\n */\n sendDownload (att) {\n att = att || {}\n if (!att.state) Log.warn('Called sendDownload without { state: xxxxx }.')\n this.send(VideoTracker.Events.DOWNLOAD, att)\n this.state.goDownload()\n }\n\n /**\n * Sends associated event and changes view state. An internal state machine will prevent\n * duplicated events. Should be associated to an event using registerListeners.\n * @param {Object} [att] Collection of key:value attributes to send with the request.\n */\n sendError (att) {\n att = att || {}\n att.isAd = true\n this.state.goError()\n let ev = this.isAd() ? VideoTracker.Events.AD_ERROR : VideoTracker.Events.CONTENT_ERROR\n this.send(ev, att)\n }\n\n /**\n * Sends associated event and changes view state. An internal state machine will prevent\n * duplicated events. Should be associated to an event using registerListeners.\n * @param {Object} [att] Collection of key:value attributes to send with the request.\n */\n sendRenditionChanged (att) {\n att = att || {}\n att.timeSinceLastRenditionChange = this.state.timeSinceLastRenditionChange.getDeltaTime()\n att.shift = this.getRenditionShift(true)\n let ev\n if (this.isAd()) {\n ev = VideoTracker.Events.AD_RENDITION_CHANGE\n } else {\n ev = VideoTracker.Events.CONTENT_RENDITION_CHANGE\n }\n this.send(ev, att)\n this.state.goRenditionChange()\n }\n\n /**\n * Sends associated event and changes view state. Heartbeat will automatically be sent every\n * 10 seconds. There's no need to call this manually.\n * @param {Object} [att] Collection of key:value attributes to send with the request.\n * @param {number} att.url Url of the clicked ad.\n *\n */\n sendHeartbeat (att) {\n if (this.state.isRequested) {\n let ev\n if (this.isAd()) {\n ev = VideoTracker.Events.AD_HEARTBEAT\n } else {\n ev = VideoTracker.Events.CONTENT_HEARTBEAT\n }\n this.send(ev, att)\n this.state.goHeartbeat()\n }\n }\n\n // Only ads\n /**\n * Sends associated event and changes view state. An internal state machine will prevent\n * duplicated events. Should be associated to an event using registerListeners.\n * @param {Object} [att] Collection of key:value attributes to send with the request.\n */\n sendAdBreakStart (att) {\n if (this.isAd() && this.state.goAdBreakStart()) {\n this.state.totalAdPlaytime = 0;\n if (this.parentTracker) this.parentTracker.state.isPlaying = false\n this.send(VideoTracker.Events.AD_BREAK_START, att)\n }\n }\n\n /**\n * Sends associated event and changes view state. An internal state machine will prevent\n * duplicated events. Should be associated to an event using registerListeners.\n * @param {Object} [att] Collection of key:value attributes to send with the request.\n */\n sendAdBreakEnd (att) {\n if (this.isAd() && this.state.goAdBreakEnd()) {\n att = att || {}\n att.timeSinceAdBreakBegin = this.state.timeSinceAdBreakStart.getDeltaTime()\n this.send(VideoTracker.Events.AD_BREAK_END, att)\n // Just in case AD_END not arriving, because of an AD_ERROR\n if (this.parentTracker) this.parentTracker.state.isPlaying = true\n this.stopHeartbeat()\n if (this.parentTracker && this.isAd()) this.parentTracker.state.goLastAd()\n }\n }\n\n /**\n * Sends associated event and changes view state. An internal state machine will prevent\n * duplicated events. Should be associated to an event using registerListeners.\n * @param {Object} [att] Collection of key:value attributes to send with the request.\n * @param {number} att.quartile Number of the quartile.\n */\n sendAdQuartile (att) {\n if (this.isAd()) {\n att = att || {}\n if (!att.quartile) Log.warn('Called sendAdQuartile without { quartile: xxxxx }.')\n att.timeSinceLastAdQuartile = this.state.timeSinceLastAdQuartile.getDeltaTime()\n this.send(VideoTracker.Events.AD_QUARTILE, att)\n this.state.goAdQuartile()\n }\n }\n\n /**\n * Sends associated event and changes view state. An internal state machine will prevent\n * duplicated events. Should be associated to an event using registerListeners.\n * @param {Object} [att] Collection of key:value attributes to send with the request.\n * @param {number} att.url Url of the clicked ad.\n */\n sendAdClick (att) {\n if (this.isAd()) {\n att = att || {}\n if (!att.url) Log.warn('Called sendAdClick without { url: xxxxx }.')\n this.send(VideoTracker.Events.AD_CLICK, att)\n }\n }\n}\n\n/**\n * Enumeration of events fired by this class.\n *\n * @static\n * @memberof VideoTracker\n * @enum {String}\n */\nVideoTracker.Events = {\n // Player\n /** The player is ready to start sending events. */\n PLAYER_READY: 'PLAYER_READY',\n /** Downloading data. */\n DOWNLOAD: 'DOWNLOAD',\n /** An error happened */\n ERROR: 'ERROR',\n\n // Video\n /** Content video has been requested. */\n CONTENT_REQUEST: 'CONTENT_REQUEST',\n /** Content video started (first frame shown). */\n CONTENT_START: 'CONTENT_START',\n /** Content video ended. */\n CONTENT_END: 'CONTENT_END',\n /** Content video paused. */\n CONTENT_PAUSE: 'CONTENT_PAUSE',\n /** Content video resumed. */\n CONTENT_RESUME: 'CONTENT_RESUME',\n /** Content video seek started */\n CONTENT_SEEK_START: 'CONTENT_SEEK_START',\n /** Content video seek ended. */\n CONTENT_SEEK_END: 'CONTENT_SEEK_END',\n /** Content video beffering started */\n CONTENT_BUFFER_START: 'CONTENT_BUFFER_START',\n /** Content video buffering ended */\n CONTENT_BUFFER_END: 'CONTENT_BUFFER_END',\n /** Content video heartbeat, en event that happens once every 30 seconds while the video is playing. */\n CONTENT_HEARTBEAT: 'CONTENT_HEARTBEAT',\n /** Content video stream qwuality changed. */\n CONTENT_RENDITION_CHANGE: 'CONTENT_RENDITION_CHANGE',\n /** Content video error. */\n CONTENT_ERROR: 'CONTENT_ERROR',\n\n // Ads only\n /** Ad video has been requested. */\n AD_REQUEST: 'AD_REQUEST',\n /** Ad video started (first frame shown). */\n AD_START: 'AD_START',\n /** Ad video ended. */\n AD_END: 'AD_END',\n /** Ad video paused. */\n AD_PAUSE: 'AD_PAUSE',\n /** Ad video resumed. */\n AD_RESUME: 'AD_RESUME',\n /** Ad video seek started */\n AD_SEEK_START: 'AD_SEEK_START',\n /** Ad video seek ended */\n AD_SEEK_END: 'AD_SEEK_END',\n /** Ad video beffering started */\n AD_BUFFER_START: 'AD_BUFFER_START',\n /** Ad video beffering ended */\n AD_BUFFER_END: 'AD_BUFFER_END',\n /** Ad video heartbeat, en event that happens once every 30 seconds while the video is playing. */\n AD_HEARTBEAT: 'AD_HEARTBEAT',\n /** Ad video stream qwuality changed. */\n AD_RENDITION_CHANGE: 'AD_RENDITION_CHANGE',\n /** Ad video error. */\n AD_ERROR: 'AD_ERROR',\n /** Ad break (a block of ads) started. */\n AD_BREAK_START: 'AD_BREAK_START',\n /** Ad break ended. */\n AD_BREAK_END: 'AD_BREAK_END',\n /** Ad quartile happened. */\n AD_QUARTILE: 'AD_QUARTILE',\n /** Ad has been clicked. */\n AD_CLICK: 'AD_CLICK'\n}\n\n// Private members\nfunction funnelAdEvents (e) {\n this.send(e.type, e.data)\n}\n\nexport default VideoTracker\n","import * as nrvideo from 'newrelic-video-core'\n\nexport default class Html5Tracker extends nrvideo.VideoTracker {\n getTrackerName () {\n return 'html5'\n }\n\n getPlayhead () {\n return this.player.currentTime * 1000\n }\n\n getDuration () {\n return this.player.duration * 1000\n }\n\n getSrc () {\n return this.player.currentSrc\n }\n\n isMuted () {\n return this.player.muted\n }\n\n getRenditionHeight () {\n return this.player.videoHeight\n }\n\n getRenditionWidth () {\n return this.player.videoWidth\n }\n\n getPlayrate () {\n return this.player.playbackRate\n }\n\n isAutoplayed () {\n return this.player.autoplay\n }\n\n getPreload () {\n return this.player.preload\n }\n\n registerListeners () {\n nrvideo.Log.debugCommonVideoEvents(this.player)\n\n this.player.addEventListener('loadstart', this.onDownload.bind(this))\n this.player.addEventListener('loadedmetadata', this.onDownload.bind(this))\n this.player.addEventListener('loadeddata', this.onDownload.bind(this))\n this.player.addEventListener('canplay', this.onDownload.bind(this))\n this.player.addEventListener('play', this.onPlay.bind(this))\n this.player.addEventListener('playing', this.onPlaying.bind(this))\n this.player.addEventListener('pause', this.onPause.bind(this))\n this.player.addEventListener('seeking', this.onSeeking.bind(this))\n this.player.addEventListener('seeked', this.onSeeked.bind(this))\n this.player.addEventListener('error', this.onError.bind(this))\n this.player.addEventListener('ended', this.onEnded.bind(this))\n this.player.addEventListener('waiting', this.onWaiting.bind(this))\n }\n\n unregisterListeners () {\n this.player.removeEventListener('loadstart', this.onDownload)\n this.player.removeEventListener('loadedmetadata', this.onDownload)\n this.player.removeEventListener('loadeddata', this.onDownload)\n this.player.removeEventListener('canplay', this.onDownload)\n this.player.removeEventListener('play', this.onPlay)\n this.player.removeEventListener('playing', this.onPlaying)\n this.player.removeEventListener('pause', this.onPause)\n this.player.removeEventListener('seeking', this.onSeeking)\n this.player.removeEventListener('seeked', this.onSeeked)\n this.player.removeEventListener('error', this.onError)\n this.player.removeEventListener('ended', this.onEnded)\n this.player.removeEventListener('waiting', this.onWaiting)\n }\n\n onDownload (e) {\n this.sendDownload({ state: e.type })\n }\n\n onPlay () {\n this.sendRequest()\n }\n\n onPlaying () {\n this.sendBufferEnd()\n this.sendResume()\n this.sendStart()\n }\n\n onPause () {\n this.sendPause()\n }\n\n onSeeking () {\n this.sendSeekStart()\n }\n\n onSeeked () {\n this.sendSeekEnd()\n }\n\n onError () {\n this.sendError()\n }\n\n onEnded () {\n this.sendEnd()\n }\n\n onWaiting () {\n if (\n this.player.networkState === this.player.NETWORK_LOADING &&\n this.player.readyState < this.player.HAVE_FUTURE_DATA\n ) {\n this.sendBufferStart()\n }\n }\n}\n"],"sourceRoot":""}