From fc13f981027c7dc0b168a3c1b57c0066c154b09b Mon Sep 17 00:00:00 2001 From: Gabe Kangas Date: Fri, 4 Jun 2021 19:47:59 -0700 Subject: [PATCH] Rebuild frontend js libs --- .../dist/videojs-http-streaming.min.js | 8 +- .../js/web_modules/common/core-d20ff47c.js | 30501 ++++++++++++++++ webroot/js/web_modules/videojs/core.js | 2 +- .../js/web_modules/videojs/video-js.min.css | 2 +- 4 files changed, 30507 insertions(+), 6 deletions(-) create mode 100644 webroot/js/web_modules/common/core-d20ff47c.js diff --git a/webroot/js/web_modules/@videojs/http-streaming/dist/videojs-http-streaming.min.js b/webroot/js/web_modules/@videojs/http-streaming/dist/videojs-http-streaming.min.js index 0820805ed..ae3509ea5 100644 --- a/webroot/js/web_modules/@videojs/http-streaming/dist/videojs-http-streaming.min.js +++ b/webroot/js/web_modules/@videojs/http-streaming/dist/videojs-http-streaming.min.js @@ -1,5 +1,5 @@ import { c as createCommonjsModule, g as getDefaultExportFromCjs, a as commonjsGlobal } from '../../../common/_commonjsHelpers-37fa8da4.js'; -import { d as document_1, w as window_1, c as core } from '../../../common/core-f87370e0.js'; +import { d as document_1, w as window_1, c as core } from '../../../common/core-d20ff47c.js'; var entityMap = { lt: '<', @@ -2421,12 +2421,12 @@ exports.__DOMHandler = DOMHandler; }); var videojsHttpStreaming_min = createCommonjsModule(function (module, exports) { -/*! @name @videojs/http-streaming @version 2.8.1 @license Apache-2.0 */ -!function(e,t){t(exports,document_1,window_1,core,domParser);}(commonjsGlobal,(function(e,t,i,n,r){function a(e){return e&&"object"==typeof e&&"default"in e?e:{default:e}}var s=a(t),o=a(i),u=a(n);function d(e,t,i){return e(i={path:t,exports:{},require:function(e,t){return function(){throw new Error("Dynamic requires are not currently supported by @rollup/plugin-commonjs")}(null==t&&i.path)}},i.exports),i.exports}var l=d((function(e){e.exports=function(e){if(void 0===e)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return e},e.exports.default=e.exports,e.exports.__esModule=!0;})),h=d((function(e){function t(i,n){return e.exports=t=Object.setPrototypeOf||function(e,t){return e.__proto__=t,e},e.exports.default=e.exports,e.exports.__esModule=!0,t(i,n)}e.exports=t,e.exports.default=e.exports,e.exports.__esModule=!0;})),c=d((function(e){e.exports=function(e,t){e.prototype=Object.create(t.prototype),e.prototype.constructor=e,h(e,t);},e.exports.default=e.exports,e.exports.__esModule=!0;})),f=d((function(e,t){var i,n,r,a,s;i=/^((?:[a-zA-Z0-9+\-.]+:)?)(\/\/[^\/?#]*)?((?:[^\/?#]*\/)*[^;?#]*)?(;[^?#]*)?(\?[^#]*)?(#.*)?$/,n=/^([^\/?#]*)(.*)$/,r=/(?:\/|^)\.(?=\/)/g,a=/(?:\/|^)\.\.\/(?!\.\.\/)[^\/]*(?=\/)/g,s={buildAbsoluteURL:function(e,t,i){if(i=i||{},e=e.trim(),!(t=t.trim())){if(!i.alwaysNormalize)return e;var r=s.parseURL(e);if(!r)throw new Error("Error trying to parse base URL.");return r.path=s.normalizePath(r.path),s.buildURLFromParts(r)}var a=s.parseURL(t);if(!a)throw new Error("Error trying to parse relative URL.");if(a.scheme)return i.alwaysNormalize?(a.path=s.normalizePath(a.path),s.buildURLFromParts(a)):t;var o=s.parseURL(e);if(!o)throw new Error("Error trying to parse base URL.");if(!o.netLoc&&o.path&&"/"!==o.path[0]){var u=n.exec(o.path);o.netLoc=u[1],o.path=u[2];}o.netLoc&&!o.path&&(o.path="/");var d={scheme:o.scheme,netLoc:a.netLoc,path:null,params:a.params,query:a.query,fragment:a.fragment};if(!a.netLoc&&(d.netLoc=o.netLoc,"/"!==a.path[0]))if(a.path){var l=o.path,h=l.substring(0,l.lastIndexOf("/")+1)+a.path;d.path=s.normalizePath(h);}else d.path=o.path,a.params||(d.params=o.params,a.query||(d.query=o.query));return null===d.path&&(d.path=i.alwaysNormalize?s.normalizePath(a.path):a.path),s.buildURLFromParts(d)},parseURL:function(e){var t=i.exec(e);return t?{scheme:t[1]||"",netLoc:t[2]||"",path:t[3]||"",params:t[4]||"",query:t[5]||"",fragment:t[6]||""}:null},normalizePath:function(e){for(e=e.split("").reverse().join("").replace(r,"");e.length!==(e=e.replace(a,"")).length;);return e.split("").reverse().join("")},buildURLFromParts:function(e){return e.scheme+e.netLoc+e.path+e.params+e.query+e.fragment}},e.exports=s;})),p="http://example.com",m=function(e,t){if(/^[a-z]+:/i.test(t))return t;var i="function"==typeof o.default.URL,n=/^\/\//.test(e),r=!o.default.location&&!/\/\//i.test(e);if(i?e=new o.default.URL(e,o.default.location||p):/\/\//i.test(e)||(e=f.buildAbsoluteURL(o.default.location&&o.default.location.href||"",e)),i){var a=new URL(t,e);return r?a.href.slice(p.length):n?a.href.slice(a.protocol.length):a.href}return f.buildAbsoluteURL(e,t)},g=m,y=function(e,t,i){return e&&i&&i.responseURL&&t!==i.responseURL?i.responseURL:t},_=function(e){return u.default.log.debug?u.default.log.debug.bind(u.default,"VHS:",e+" >"):function(){}},v=d((function(e){function t(){return e.exports=t=Object.assign||function(e){for(var t=1;t-1},t.trigger=function(e){var t=this.listeners[e];if(t)if(2===arguments.length)for(var i=t.length,n=0;n"):function(){}},v=d((function(e){function t(){return e.exports=t=Object.assign||function(e){for(var t=1;t-1},t.trigger=function(e){var t=this.listeners[e];if(t)if(2===arguments.length)for(var i=t.length,n=0;n-1;t=this.buffer.indexOf("\n"))this.trigger("data",this.buffer.substring(0,t)),this.buffer=this.buffer.substring(t+1);},t}(T),I=String.fromCharCode(9),E=function(e){var t=/([0-9.]*)?@?([0-9.]*)?/.exec(e||""),i={};return t[1]&&(i.length=parseInt(t[1],10)),t[2]&&(i.offset=parseInt(t[2],10)),i},w=function(e){for(var t,i=e.split(new RegExp('(?:^|,)((?:[^=]*)=(?:"[^"]*"|[^,]*))')),n={},r=i.length;r--;)""!==i[r]&&((t=/([^=]*)=(.*)/.exec(i[r]).slice(1))[0]=t[0].replace(/^\s+|\s+$/g,""),t[1]=t[1].replace(/^\s+|\s+$/g,""),t[1]=t[1].replace(/^['"](.*)['"]$/g,"$1"),n[t[0]]=t[1]);return n},A=function(e){function t(){var t;return (t=e.call(this)||this).customParsers=[],t.tagMappers=[],t}c(t,e);var i=t.prototype;return i.push=function(e){var t,i,n=this;0!==(e=e.trim()).length&&("#"===e[0]?this.tagMappers.reduce((function(t,i){var n=i(e);return n===e?t:t.concat([n])}),[e]).forEach((function(e){for(var r=0;r0&&(s.duration=e.duration),0===e.duration&&(s.duration=.01,this.trigger("info",{message:"updating zero segment duration to a small value"})),this.manifest.segments=a;},key:function(){if(e.attributes)if("NONE"!==e.attributes.METHOD)if(e.attributes.URI){if("com.apple.streamingkeydelivery"===e.attributes.KEYFORMAT)return this.manifest.contentProtection=this.manifest.contentProtection||{},void(this.manifest.contentProtection["com.apple.fps.1_0"]={attributes:e.attributes});if("urn:uuid:edef8ba9-79d6-4ace-a3c8-27dcd51d21ed"===e.attributes.KEYFORMAT)return -1===["SAMPLE-AES","SAMPLE-AES-CTR","SAMPLE-AES-CENC"].indexOf(e.attributes.METHOD)?void this.trigger("warn",{message:"invalid key method provided for Widevine"}):("SAMPLE-AES-CENC"===e.attributes.METHOD&&this.trigger("warn",{message:"SAMPLE-AES-CENC is deprecated, please use SAMPLE-AES-CTR instead"}),"data:text/plain;base64,"!==e.attributes.URI.substring(0,23)?void this.trigger("warn",{message:"invalid key URI provided for Widevine"}):e.attributes.KEYID&&"0x"===e.attributes.KEYID.substring(0,2)?(this.manifest.contentProtection=this.manifest.contentProtection||{},void(this.manifest.contentProtection["com.widevine.alpha"]={attributes:{schemeIdUri:e.attributes.KEYFORMAT,keyId:e.attributes.KEYID.substring(2)},pssh:b(e.attributes.URI.split(",")[1])})):void this.trigger("warn",{message:"invalid key ID provided for Widevine"}));e.attributes.METHOD||this.trigger("warn",{message:"defaulting key method to AES-128"}),n={method:e.attributes.METHOD||"AES-128",uri:e.attributes.URI},void 0!==e.attributes.IV&&(n.iv=e.attributes.IV);}else this.trigger("warn",{message:"ignoring key declaration without URI"});else n=null;else this.trigger("warn",{message:"ignoring key declaration without attribute list"});},"media-sequence":function(){isFinite(e.number)?this.manifest.mediaSequence=e.number:this.trigger("warn",{message:"ignoring invalid media sequence: "+e.number});},"discontinuity-sequence":function(){isFinite(e.number)?(this.manifest.discontinuitySequence=e.number,h=e.number):this.trigger("warn",{message:"ignoring invalid discontinuity sequence: "+e.number});},"playlist-type":function(){/VOD|EVENT/.test(e.playlistType)?this.manifest.playlistType=e.playlistType:this.trigger("warn",{message:"ignoring unknown playlist type: "+e.playlist});},map:function(){i={},e.uri&&(i.uri=e.uri),e.byterange&&(i.byterange=e.byterange),n&&(i.key=n);},"stream-inf":function(){this.manifest.playlists=a,this.manifest.mediaGroups=this.manifest.mediaGroups||d,e.attributes?(s.attributes||(s.attributes={}),v(s.attributes,e.attributes)):this.trigger("warn",{message:"ignoring empty stream-inf attributes"});},media:function(){if(this.manifest.mediaGroups=this.manifest.mediaGroups||d,e.attributes&&e.attributes.TYPE&&e.attributes["GROUP-ID"]&&e.attributes.NAME){var i=this.manifest.mediaGroups[e.attributes.TYPE];i[e.attributes["GROUP-ID"]]=i[e.attributes["GROUP-ID"]]||{},t=i[e.attributes["GROUP-ID"]],(l={default:/yes/i.test(e.attributes.DEFAULT)}).default?l.autoselect=!0:l.autoselect=/yes/i.test(e.attributes.AUTOSELECT),e.attributes.LANGUAGE&&(l.language=e.attributes.LANGUAGE),e.attributes.URI&&(l.uri=e.attributes.URI),e.attributes["INSTREAM-ID"]&&(l.instreamId=e.attributes["INSTREAM-ID"]),e.attributes.CHARACTERISTICS&&(l.characteristics=e.attributes.CHARACTERISTICS),e.attributes.FORCED&&(l.forced=/yes/i.test(e.attributes.FORCED)),t[e.attributes.NAME]=l;}else this.trigger("warn",{message:"ignoring incomplete or missing media group"});},discontinuity:function(){h+=1,s.discontinuity=!0,this.manifest.discontinuityStarts.push(a.length);},"program-date-time":function(){void 0===this.manifest.dateTimeString&&(this.manifest.dateTimeString=e.dateTimeString,this.manifest.dateTimeObject=e.dateTimeObject),s.dateTimeString=e.dateTimeString,s.dateTimeObject=e.dateTimeObject;},targetduration:function(){!isFinite(e.duration)||e.duration<0?this.trigger("warn",{message:"ignoring invalid target duration: "+e.duration}):(this.manifest.targetDuration=e.duration,P.call(this,this.manifest));},start:function(){e.attributes&&!isNaN(e.attributes["TIME-OFFSET"])?this.manifest.start={timeOffset:e.attributes["TIME-OFFSET"],precise:e.attributes.PRECISE}:this.trigger("warn",{message:"ignoring start declaration without appropriate attribute list"});},"cue-out":function(){s.cueOut=e.data;},"cue-out-cont":function(){s.cueOutCont=e.data;},"cue-in":function(){s.cueIn=e.data;},skip:function(){this.manifest.skip=L(e.attributes),this.warnOnMissingAttributes_("#EXT-X-SKIP",e.attributes,["SKIPPED-SEGMENTS"]);},part:function(){var t=this;o=!0;var i=this.manifest.segments.length,n=L(e.attributes);s.parts=s.parts||[],s.parts.push(n),n.byterange&&(n.byterange.hasOwnProperty("offset")||(n.byterange.offset=f),f=n.byterange.offset+n.byterange.length);var r=s.parts.length-1;this.warnOnMissingAttributes_("#EXT-X-PART #"+r+" for segment #"+i,e.attributes,["URI","DURATION"]),this.manifest.renditionReports&&this.manifest.renditionReports.forEach((function(e,i){e.hasOwnProperty("lastPart")||t.trigger("warn",{message:"#EXT-X-RENDITION-REPORT #"+i+" lacks required attribute(s): LAST-PART"});}));},"server-control":function(){var t=this.manifest.serverControl=L(e.attributes);t.hasOwnProperty("canBlockReload")||(t.canBlockReload=!1,this.trigger("info",{message:"#EXT-X-SERVER-CONTROL defaulting CAN-BLOCK-RELOAD to false"})),P.call(this,this.manifest),t.canSkipDateranges&&!t.hasOwnProperty("canSkipUntil")&&this.trigger("warn",{message:"#EXT-X-SERVER-CONTROL lacks required attribute CAN-SKIP-UNTIL which is required when CAN-SKIP-DATERANGES is set"});},"preload-hint":function(){var t=this.manifest.segments.length,i=L(e.attributes),n=i.type&&"PART"===i.type;s.preloadHints=s.preloadHints||[],s.preloadHints.push(i),i.byterange&&(i.byterange.hasOwnProperty("offset")||(i.byterange.offset=n?f:0,n&&(f=i.byterange.offset+i.byterange.length)));var r=s.preloadHints.length-1;if(this.warnOnMissingAttributes_("#EXT-X-PRELOAD-HINT #"+r+" for segment #"+t,e.attributes,["TYPE","URI"]),i.type)for(var a=0;a=500?4:2},this.trigger("error");},i.haveMetadata=function(e){var t=this,i=e.playlistString,n=e.playlistObject,r=e.url,a=e.id;this.request=null,this.state="HAVE_METADATA";var s=n||C({onwarn:function(e){var i=e.message;return t.logger_("m3u8-parser warn for "+a+": "+i)},oninfo:function(e){var i=e.message;return t.logger_("m3u8-parser info for "+a+": "+i)},manifestString:i,customTagParsers:this.customTagParsers,customTagMappers:this.customTagMappers,experimentalLLHLS:this.experimentalLLHLS});s.lastRequest=Date.now(),D({playlist:s,uri:r,id:a});var u=G(this.master,s);this.targetDuration=s.partTargetDuration||s.targetDuration,u?(this.master=u,this.media_=this.master.playlists[a]):this.trigger("playlistunchanged"),this.media().endList||(o.default.clearTimeout(this.mediaUpdateTimeout),this.mediaUpdateTimeout=o.default.setTimeout((function(){t.trigger("mediaupdatetimeout");}),W(this.media(),!!u))),this.trigger("loadedplaylist");},i.dispose=function(){this.trigger("dispose"),this.stopRequest(),o.default.clearTimeout(this.mediaUpdateTimeout),o.default.clearTimeout(this.finalRenditionTimeout),this.off();},i.stopRequest=function(){if(this.request){var e=this.request;this.request=null,e.onreadystatechange=null,e.abort();}},i.media=function(e,t){var i=this;if(!e)return this.media_;if("HAVE_NOTHING"===this.state)throw new Error("Cannot switch media playlist from "+this.state);if("string"==typeof e){if(!this.master.playlists[e])throw new Error("Unknown playlist URI: "+e);e=this.master.playlists[e];}if(o.default.clearTimeout(this.finalRenditionTimeout),t){var n=(e.partTargetDuration||e.targetDuration)/2*1e3||5e3;this.finalRenditionTimeout=o.default.setTimeout(this.media.bind(this,e,!1),n);}else {var r=this.state,a=!this.media_||e.id!==this.media_.id,s=this.master.playlists[e.id];if(s&&s.endList||e.endList&&e.segments.length)return this.request&&(this.request.onreadystatechange=null,this.request.abort(),this.request=null),this.state="HAVE_METADATA",this.media_=e,void(a&&(this.trigger("mediachanging"),"HAVE_MASTER"===r?this.trigger("loadedmetadata"):this.trigger("mediachange")));if(a){if(this.state="SWITCHING_MEDIA",this.request){if(e.resolvedUri===this.request.url)return;this.request.onreadystatechange=null,this.request.abort(),this.request=null;}this.media_&&this.trigger("mediachanging"),this.request=this.vhs_.xhr({uri:e.resolvedUri,withCredentials:this.withCredentials},(function(t,n){if(i.request){if(e.lastRequest=Date.now(),e.resolvedUri=y(i.handleManifestRedirects,e.resolvedUri,n),t)return i.playlistRequestError(i.request,e,r);i.haveMetadata({playlistString:n.responseText,url:e.uri,id:e.id}),"HAVE_MASTER"===r?i.trigger("loadedmetadata"):i.trigger("mediachange");}}));}}},i.pause=function(){this.stopRequest(),o.default.clearTimeout(this.mediaUpdateTimeout),"HAVE_NOTHING"===this.state&&(this.started=!1),"SWITCHING_MEDIA"===this.state?this.media_?this.state="HAVE_METADATA":this.state="HAVE_MASTER":"HAVE_CURRENT_METADATA"===this.state&&(this.state="HAVE_METADATA");},i.load=function(e){var t=this;o.default.clearTimeout(this.mediaUpdateTimeout);var i=this.media();if(e){var n=i?(i.partTargetDuration||i.targetDuration)/2*1e3:5e3;this.mediaUpdateTimeout=o.default.setTimeout((function(){return t.load()}),n);}else this.started?i&&!i.endList?this.trigger("mediaupdatetimeout"):this.trigger("loadedplaylist"):this.start();},i.start=function(){var e=this;if(this.started=!0,"object"==typeof this.src)return this.src.uri||(this.src.uri=o.default.location.href),this.src.resolvedUri=this.src.uri,void setTimeout((function(){e.setupInitialPlaylist(e.src);}),0);this.request=this.vhs_.xhr({uri:this.src,withCredentials:this.withCredentials},(function(t,i){if(e.request){if(e.request=null,t)return e.error={status:i.status,message:"HLS playlist request error at URL: "+e.src+".",responseText:i.responseText,code:2},"HAVE_NOTHING"===e.state&&(e.started=!1),e.trigger("error");e.src=y(e.handleManifestRedirects,e.src,i);var n=C({manifestString:i.responseText,customTagParsers:e.customTagParsers,customTagMappers:e.customTagMappers,experimentalLLHLS:e.experimentalLLHLS});e.setupInitialPlaylist(n);}}));},i.srcUri=function(){return "string"==typeof this.src?this.src:this.src.uri},i.setupInitialPlaylist=function(e){if(this.state="HAVE_MASTER",e.playlists)return this.master=e,R(this.master,this.srcUri()),e.playlists.forEach((function(e){e.segments=q(e),e.segments.forEach((function(t){F(t,e.resolvedUri);}));})),this.trigger("loadedplaylist"),void(this.request||this.media(this.master.playlists[0]));var t=this.srcUri()||o.default.location.href;this.master=function(e,t){var i=x(0,t),n={mediaGroups:{AUDIO:{},VIDEO:{},"CLOSED-CAPTIONS":{},SUBTITLES:{}},uri:o.default.location.href,resolvedUri:o.default.location.href,playlists:[{uri:t,id:i,resolvedUri:t,attributes:{}}]};return n.playlists[i]=n.playlists[0],n.playlists[t]=n.playlists[0],n}(0,t),this.haveMetadata({playlistObject:e,url:t,id:this.master.playlists[0].id}),this.trigger("loadedmetadata");},t}(B),j=1/30,X=.1,z=function(e,t){var i,n=[];if(e&&e.length)for(i=0;i=t}))},Y=function(e,t){return z(e,(function(e){return e-j>=t}))},K=function(e){var t=[];if(!e||!e.length)return "";for(var i=0;i "+e.end(i));return t.join(", ")},$=function(e){for(var t=[],i=0;ii){var r=[i,t];t=r[0],i=r[1];}if(t<0){for(var a=t;aDate.now()},ge=function(e){return e.excludeUntil&&e.excludeUntil===1/0},ye=function(e){var t=me(e);return !e.disabled&&!t},_e=function(e,t){return t.attributes&&t.attributes[e]},ve=function(e,t){if(1===e.playlists.length)return !0;var i=t.attributes.BANDWIDTH||Number.MAX_VALUE;return 0===e.playlists.filter((function(e){return !!ye(e)&&(e.attributes.BANDWIDTH||0)0)for(var s=i-1;s>=0;s--){var o=r[s];if((a+=o.duration+j)>0)return {mediaIndex:o.segmentIndex,startTime:n-fe(e,i,o.segmentIndex),partIndex:o.partIndex}}return {mediaIndex:r[0]&&r[0].segmentIndex||0,partIndex:r[0]&&r[0].partIndex||null,startTime:t}}if(i<0){for(var u=i;u<0;u++)if((a-=e.targetDuration)<0)return {mediaIndex:r[0].segmentIndex,startTime:t};i=0;}for(var d=i;d=32&&e<126?String.fromCharCode(e):"."},Re=function(e){var t={};return Object.keys(e).forEach((function(i){var n=e[i];ArrayBuffer.isView(n)?t[i]={bytes:n.buffer,byteOffset:n.byteOffset,byteLength:n.byteLength}:t[i]=n;})),t},Me=function(e){var t=e.byterange||{length:1/0,offset:0};return [t.length,t.offset,e.resolvedUri].join(",")},Be=function(e){return e.resolvedUri},Ne=function(e){for(var t=Array.prototype.slice.call(e),i=16,n="",r=0;rnew Date(o.getTime()+1e3*u)?null:(i>o&&(n=s),{segment:n,estimatedStart:n.videoTimingInfo?n.videoTimingInfo.transmuxedPresentationStart:Ie.duration(t,t.mediaSequence+t.segments.indexOf(n)),type:n.videoTimingInfo?"accurate":"estimate"})}(i,n);if(!h)return l({message:i+" was not found in the stream"});var c=h.segment,f=function(e,t){var i,n;try{i=new Date(e),n=new Date(t);}catch(e){}var r=i.getTime();return (n.getTime()-r)/1e3}(c.dateTimeObject,i);if("estimate"===h.type)return 0===a?l({message:i+" is not buffered yet. Try again"}):(s(h.estimatedStart+f),void d.one("seeked",(function(){e({programTime:i,playlist:n,retryCount:a-1,seekTo:s,pauseAfterSeek:u,tech:d,callback:l});})));var p=c.start+f;d.one("seeked",(function(){return l(null,d.currentTime())})),u&&d.pause(),s(p);},He=function(e){return !!e&&"object"==typeof e},Ge=function e(){for(var t=arguments.length,i=new Array(t),n=0;nm&&(m=T);var b=void 0;if(v<0){var S=g+1;b=S===t.length?"dynamic"===n&&a>0&&o.indexOf("$Number$")>0?at(e,m,_):(u*l-m)/_:(t[S].t-m)/_;}else b=v+1;for(var I=c+p.length+b,E=c+p.length;E=r?a:""+new Array(r-a.length+1).join("0")+a)}}(t))},dt=function(e,t){var i={RepresentationID:e.id,Bandwidth:e.bandwidth||0},n=e.initialization,r=void 0===n?{sourceURL:"",range:""}:n,a=je({baseUrl:e.baseUrl,source:ut(r.sourceURL,i),range:r.range});return function(e,t){return e.duration||t?e.duration?Qe(e):st(e,t):[{number:e.startNumber||1,duration:e.sourceDuration,time:0,timeline:e.periodIndex}]}(e,t).map((function(t){i.Number=t.number,i.Time=t.time;var n=ut(e.media||"",i),r={uri:n,timeline:t.timeline,duration:t.duration,resolvedUri:m(e.baseUrl||"",n),map:a,number:t.number};return e.presentationTimeOffset&&(r.presentationTimeOffset=e.presentationTimeOffset),r}))},lt=function(e,t){var i=e.duration,n=e.segmentUrls,r=void 0===n?[]:n;if(!i&&!t||i&&t)throw new Error("SEGMENT_TIME_UNSPECIFIED");var a,s=r.map((function(t){return function(e,t){var i=e.baseUrl,n=e.initialization,r=void 0===n?{}:n,a=je({baseUrl:i,source:r.sourceURL,range:r.range}),s=je({baseUrl:i,source:t.media,range:t.mediaRange});return s.map=a,s}(e,t)}));return i&&(a=Qe(e)),t&&(a=st(e,t)),a.map((function(e,t){if(s[t]){var i=s[t];return i.timeline=e.timeline,i.duration=e.duration,i.number=e.number,i}})).filter((function(e){return e}))},ht=function(e){var t,i,n=e.attributes,r=e.segmentInfo;r.template?(i=dt,t=Ge(n,r.template),r.template.presentationTimeOffset&&(t.presentationTimeOffset=r.template.presentationTimeOffset/r.template.timescale)):r.base?(i=Ye,t=Ge(n,r.base)):r.list&&(i=lt,t=Ge(n,r.list));var a={attributes:n};if(!i)return a;var s=i(t,r.timeline);if(t.duration){var o=t,u=o.duration,d=o.timescale,l=void 0===d?1:d;t.duration=u/l;}else s.length?t.duration=s.reduce((function(e,t){return Math.max(e,Math.ceil(t.duration))}),0):t.duration=0;return a.attributes=t,a.segments=s,r.base&&t.indexRange&&(a.sidx=s[0],a.segments=[]),a},ct=function(e,t){return Ve(e.childNodes).filter((function(e){return e.tagName===t}))},ft=function(e){return e.textContent.trim()},pt=function(e){var t=/P(?:(\d*)Y)?(?:(\d*)M)?(?:(\d*)D)?(?:T(?:(\d*)H)?(?:(\d*)M)?(?:([\d.]*)S)?)?/.exec(e);if(!t)return 0;var i=t.slice(1),n=i[0],r=i[1],a=i[2],s=i[3],o=i[4],u=i[5];return 31536e3*parseFloat(n||0)+2592e3*parseFloat(r||0)+86400*parseFloat(a||0)+3600*parseFloat(s||0)+60*parseFloat(o||0)+parseFloat(u||0)},mt={mediaPresentationDuration:function(e){return pt(e)},availabilityStartTime:function(e){return /^\d+-\d+-\d+T\d+:\d+:\d+(\.\d+)?$/.test(t=e)&&(t+="Z"),Date.parse(t)/1e3;var t;},minimumUpdatePeriod:function(e){return pt(e)},suggestedPresentationDelay:function(e){return pt(e)},type:function(e){return e},timeShiftBufferDepth:function(e){return pt(e)},start:function(e){return pt(e)},width:function(e){return parseInt(e,10)},height:function(e){return parseInt(e,10)},bandwidth:function(e){return parseInt(e,10)},startNumber:function(e){return parseInt(e,10)},timescale:function(e){return parseInt(e,10)},presentationTimeOffset:function(e){return parseInt(e,10)},duration:function(e){var t=parseInt(e,10);return isNaN(t)?pt(e):t},d:function(e){return parseInt(e,10)},t:function(e){return parseInt(e,10)},r:function(e){return parseInt(e,10)},DEFAULT:function(e){return e}},gt=function(e){return e&&e.attributes?Ve(e.attributes).reduce((function(e,t){var i=mt[t.name]||mt.DEFAULT;return e[t.name]=i(t.value),e}),{}):{}},yt={"urn:uuid:1077efec-c0b2-4d02-ace3-3c1e52e2fb4b":"org.w3.clearkey","urn:uuid:edef8ba9-79d6-4ace-a3c8-27dcd51d21ed":"com.widevine.alpha","urn:uuid:9a04f079-9840-4286-ab92-e65be0885f95":"com.microsoft.playready","urn:uuid:f239e769-efa3-4850-9c16-a903c6932efb":"com.adobe.primetime"},_t=function(e,t){return t.length?We(e.map((function(e){return t.map((function(t){return m(e,ft(t))}))}))):e},vt=function(e){var t=ct(e,"SegmentTemplate")[0],i=ct(e,"SegmentList")[0],n=i&&ct(i,"SegmentURL").map((function(e){return Ge({tag:"SegmentURL"},gt(e))})),r=ct(e,"SegmentBase")[0],a=i||t,s=a&&ct(a,"SegmentTimeline")[0],o=i||r||t,u=o&&ct(o,"Initialization")[0],d=t&>(t);d&&u?d.initialization=u&>(u):d&&d.initialization&&(d.initialization={sourceURL:d.initialization});var l={template:d,timeline:s&&ct(s,"S").map((function(e){return gt(e)})),list:i&&Ge(gt(i),{segmentUrls:n,initialization:gt(u)}),base:r&&Ge(gt(r),{initialization:gt(u)})};return Object.keys(l).forEach((function(e){l[e]||delete l[e];})),l},Tt=function(e,t){return function(i,n){var r=_t(t,ct(i,"BaseURL")),a=gt(i),s=parseInt(a.id,10),u=o.default.isNaN(s)?n:s,d=Ge(e,{periodIndex:u}),l=ct(i,"AdaptationSet"),h=vt(i);return We(l.map(function(e,t,i){return function(n){var r=gt(n),a=_t(t,ct(n,"BaseURL")),s=ct(n,"Role")[0],o={role:gt(s)},u=Ge(e,r,o),d=ct(n,"Label")[0];if(d&&d.childNodes.length){var l=d.childNodes[0].nodeValue.trim();u=Ge(u,{label:l});}var h=ct(n,"ContentProtection").reduce((function(e,t){var i=gt(t),n=yt[i.schemeIdUri];if(n){e[n]={attributes:i};var r=ct(t,"cenc:pssh")[0];if(r){var a=ft(r),s=a&&b(a);e[n].pssh=s;}}return e}),{});Object.keys(h).length&&(u=Ge(u,{contentProtection:h}));var c=vt(n),f=ct(n,"Representation"),p=Ge(i,c);return We(f.map(function(e,t,i){return function(n){var r=ct(n,"BaseURL"),a=_t(t,r),s=Ge(e,gt(n)),o=vt(n);return a.map((function(e){return {segmentInfo:Ge(i,o),attributes:Ge(s,{baseUrl:e})}}))}}(u,a,p)))}}(d,r,h)))}},bt=function(e){if(""===e)throw new Error("DASH_EMPTY_MANIFEST");var t,i,n=new r.DOMParser;try{i=(t=n.parseFromString(e,"application/xml"))&&"MPD"===t.documentElement.tagName?t.documentElement:null;}catch(e){}if(!i||i&&i.getElementsByTagName("parsererror").length>0)throw new Error("DASH_INVALID_XML");return i},St=function(e,t){void 0===t&&(t={});var i=function(e,t){void 0===t&&(t={});var i=t,n=i.manifestUri,r=void 0===n?"":n,a=i.NOW,s=void 0===a?Date.now():a,o=i.clientOffset,u=void 0===o?0:o,d=ct(e,"Period");if(!d.length)throw new Error("INVALID_NUMBER_OF_PERIOD");var l=ct(e,"Location"),h=gt(e),c=_t([r],ct(e,"BaseURL"));return h.sourceDuration=h.mediaPresentationDuration||0,h.NOW=s,h.clientOffset=u,l.length&&(h.locations=l.map(ft)),{locations:h.locations,representationInfo:We(d.map(Tt(h,c)))}}(bt(e),t);return function(e,t,i){var n;if(void 0===i&&(i={}),!e.length)return {};var r=e[0].attributes,a=r.sourceDuration,s=r.type,o=void 0===s?"static":s,u=r.suggestedPresentationDelay,d=r.minimumUpdatePeriod,l=Je(e.filter(it)).map(tt),h=Je(e.filter(nt)),c=e.filter(rt),f={allowCache:!0,discontinuityStarts:[],segments:[],endList:!0,mediaGroups:(n={AUDIO:{},VIDEO:{}},n["CLOSED-CAPTIONS"]={},n.SUBTITLES={},n),uri:"",duration:a,playlists:et(l,i)};d>=0&&(f.minimumUpdatePeriod=1e3*d),t&&(f.locations=t),"dynamic"===o&&(f.suggestedPresentationDelay=u);var p=0===f.playlists.length;return h.length&&(f.mediaGroups.AUDIO.audio=function(e,t,i){var n;void 0===t&&(t={}),void 0===i&&(i=!1);var r=e.reduce((function(e,r){var a=r.attributes.role&&r.attributes.role.value||"",s=r.attributes.lang||"",o=r.attributes.label||"main";if(s&&!r.attributes.label){var u=a?" ("+a+")":"";o=""+r.attributes.lang+u;}e[o]||(e[o]={language:s,autoselect:!0,default:"main"===a,playlists:[],uri:""});var d=Ze(function(e,t){var i,n=e.attributes,r=e.segments,a=e.sidx,s={attributes:(i={NAME:n.id,BANDWIDTH:n.bandwidth,CODECS:n.codecs},i["PROGRAM-ID"]=1,i),uri:"",endList:"static"===(n.type||"static"),timeline:n.periodIndex,resolvedUri:"",targetDuration:n.duration,segments:r,mediaSequence:r.length?r[0].number:1};return n.contentProtection&&(s.contentProtection=n.contentProtection),a&&(s.sidx=a),t&&(s.attributes.AUDIO="audio",s.attributes.SUBTITLES="subs"),s}(r,i),t);return e[o].playlists.push(d),void 0===n&&"main"===a&&((n=r).default=!0),e}),{});return n||(r[Object.keys(r)[0]].default=!0),r}(h,i,p)),c.length&&(f.mediaGroups.SUBTITLES.subs=function(e,t){return void 0===t&&(t={}),e.reduce((function(e,i){var n=i.attributes.lang||"text";return e[n]||(e[n]={language:n,default:!1,autoselect:!1,playlists:[],uri:""}),e[n].playlists.push(Ze(function(e){var t,i=e.attributes,n=e.segments;void 0===n&&(n=[{uri:i.baseUrl,timeline:i.periodIndex,resolvedUri:i.baseUrl||"",duration:i.sourceDuration,number:0}],i.duration=i.sourceDuration);var r=((t={NAME:i.id,BANDWIDTH:i.bandwidth})["PROGRAM-ID"]=1,t);return i.codecs&&(r.CODECS=i.codecs),{attributes:r,uri:"",endList:"static"===(i.type||"static"),timeline:i.periodIndex,resolvedUri:i.baseUrl||"",targetDuration:i.duration,segments:n,mediaSequence:n.length?n[0].number:1}}(i),t)),e}),{})}(c,i)),f}(i.representationInfo.map(ht),i.locations,t.sidxMapping)},It=Math.pow(2,32),Et=function(e){return e instanceof Uint8Array?e:(Array.isArray(e)||(t=e,ArrayBuffer.isView(t))||e instanceof ArrayBuffer||(e="number"!=typeof e||"number"==typeof e&&e!=e?0:[e]),new Uint8Array(e&&e.buffer||e,e&&e.byteOffset||0,e&&e.byteLength||0));var t;},wt=o.default.BigInt||Number,At=[wt("0x1"),wt("0x100"),wt("0x10000"),wt("0x1000000"),wt("0x100000000"),wt("0x10000000000"),wt("0x1000000000000"),wt("0x100000000000000"),wt("0x10000000000000000")],Lt=function(e,t){var i=void 0===t?{}:t,n=i.signed,r=void 0!==n&&n,a=i.le,s=void 0!==a&&a;e=Et(e);var o=s?"reduce":"reduceRight",u=(e[o]?e[o]:Array.prototype[o]).call(e,(function(t,i,n){var r=s?n:Math.abs(n+1-e.length);return t+wt(i)*At[r]}),wt(0));if(r){var d=At[e.length]/wt(2)-wt(1);(u=wt(u))>d&&(u-=d,u-=d,u-=wt(2));}return Number(u)},Pt=function(e,t){if("string"!=typeof e&&e&&"function"==typeof e.toString&&(e=e.toString()),"string"!=typeof e)return new Uint8Array;t||(e=unescape(encodeURIComponent(e)));for(var i=new Uint8Array(e.length),n=0;n=t.length&&u.call(t,(function(t,i){return t===(o[i]?o[i]&e[a+i]:e[a+i])}))},kt=Et([73,68,51]),xt=function e(t,i){return void 0===i&&(i=0),(t=Et(t)).length-i<10||!Ot(t,kt,{offset:i})?i:(i+=function(e,t){void 0===t&&(t=0);var i=(e=Et(e))[t+5],n=e[t+6]<<21|e[t+7]<<14|e[t+8]<<7|e[t+9];return (16&i)>>4?n+20:n+10}(t,i),e(t,i))},Ct=function(e){return "string"==typeof e?Pt(e):e},Ut=function e(t,i,n){void 0===n&&(n=!1),i=function(e){return Array.isArray(e)?e.map((function(e){return Ct(e)})):[Ct(e)]}(i),t=Et(t);var r=[];if(!i.length)return r;for(var a=0;a>>0,o=t.subarray(a+4,a+8);if(0===s)break;var u=a+s;if(u>t.length){if(n)break;u=t.length;}var d=t.subarray(a+8,u);Ot(o,i[0])&&(1===i.length?r.push(d):r.push.apply(r,e(d,i.slice(1),n))),a=u;}return r},Dt={EBML:Et([26,69,223,163]),DocType:Et([66,130]),Segment:Et([24,83,128,103]),SegmentInfo:Et([21,73,169,102]),Tracks:Et([22,84,174,107]),Track:Et([174]),TrackNumber:Et([215]),DefaultDuration:Et([35,227,131]),TrackEntry:Et([174]),TrackType:Et([131]),FlagDefault:Et([136]),CodecID:Et([134]),CodecPrivate:Et([99,162]),VideoTrack:Et([224]),AudioTrack:Et([225]),Cluster:Et([31,67,182,117]),Timestamp:Et([231]),TimestampScale:Et([42,215,177]),BlockGroup:Et([160]),BlockDuration:Et([155]),Block:Et([161]),SimpleBlock:Et([163])},Rt=[128,64,32,16,8,4,2,1],Mt=function(e,t,i,n){void 0===i&&(i=!0),void 0===n&&(n=!1);var r=function(e){for(var t=1,i=0;i=i.length)return i.length;var r=Mt(i,n,!1);if(Ot(t.bytes,r.bytes))return n;var a=Mt(i,n+r.length);return e(t,i,n+a.length+a.value+r.length)},Ft=function e(t,i){i=function(e){return Array.isArray(e)?e.map((function(e){return Bt(e)})):[Bt(e)]}(i),t=Et(t);var n=[];if(!i.length)return n;for(var r=0;rt.length?t.length:o+s.value,d=t.subarray(o,u);Ot(i[0],a.bytes)&&(1===i.length?n.push(d):n=n.concat(e(d,i.slice(1)))),r+=a.length+s.length+d.length;}return n},qt=Et([0,0,0,1]),Ht=Et([0,0,1]),Gt=Et([0,0,3]),Wt=function(e){for(var t=[],i=1;i>1&63),-1!==i.indexOf(u)&&(r=a+o),a+=o+("h264"===t?1:2);}else a++;}return e.subarray(0,0)},jt={webm:Et([119,101,98,109]),matroska:Et([109,97,116,114,111,115,107,97]),flac:Et([102,76,97,67]),ogg:Et([79,103,103,83]),ac3:Et([11,119]),riff:Et([82,73,70,70]),avi:Et([65,86,73]),wav:Et([87,65,86,69]),"3gp":Et([102,116,121,112,51,103]),mp4:Et([102,116,121,112]),fmp4:Et([115,116,121,112]),mov:Et([102,116,121,112,113,116])},Xt={aac:function(e){var t=xt(e);return Ot(e,[255,16],{offset:t,mask:[255,22]})},mp3:function(e){var t=xt(e);return Ot(e,[255,2],{offset:t,mask:[255,6]})},webm:function(e){var t=Ft(e,[Dt.EBML,Dt.DocType])[0];return Ot(t,jt.webm)},mkv:function(e){var t=Ft(e,[Dt.EBML,Dt.DocType])[0];return Ot(t,jt.matroska)},mp4:function(e){return !Xt["3gp"](e)&&!Xt.mov(e)&&(Ot(e,jt.mp4,{offset:4})||Ot(e,jt.fmp4,{offset:4}))},mov:function(e){return Ot(e,jt.mov,{offset:4})},"3gp":function(e){return Ot(e,jt["3gp"],{offset:4})},ac3:function(e){var t=xt(e);return Ot(e,jt.ac3,{offset:t})},ts:function(e){if(e.length<189&&e.length>=1)return 71===e[0];for(var t=0;t+1880;n+=12,r--)i.references.push({referenceType:(128&e[n])>>>7,referencedSize:2147483647&t.getUint32(n),subsegmentDuration:t.getUint32(n+4),startsWithSap:!!(128&e[n+8]),sapType:(112&e[n+8])>>>4,sapDeltaTime:268435455&t.getUint32(n+8)});return i}(Et(s.response).subarray(8));}catch(e){return void n.requestErrored_(e,s,t)}return u[r]={sidxInfo:e.sidx,sidx:o},Ke(e,o,e.sidx.resolvedUri),i(!0)}};this.request=function(e,t,i){var n,r=[],a=!1,s=function(e,t,n,r){return t.abort(),a=!0,i(e,t,n,r)},o=function(e,t){if(!a){if(e)return s(e,t,"",r);var i=t.responseText.substring(r&&r.byteLength||0,t.responseText.length);if(r=function(){for(var e=arguments.length,t=new Array(e),i=0;i=l+d)return s(t,{response:o.subarray(d,d+l),status:i.status,uri:i.uri});n.request=n.vhs_.xhr({uri:a,responseType:"arraybuffer",headers:Pe({byterange:e.sidx.byterange})},s);}));}else this.mediaRequest_=o.default.setTimeout((function(){return i(!1)}),0);},i.dispose=function(){this.trigger("dispose"),this.stopRequest(),this.loadedPlaylists_={},o.default.clearTimeout(this.minimumUpdatePeriodTimeout_),o.default.clearTimeout(this.mediaRequest_),o.default.clearTimeout(this.mediaUpdateTimeout),this.mediaUpdateTimeout=null,this.mediaRequest_=null,this.minimumUpdatePeriodTimeout_=null,this.masterPlaylistLoader_.createMupOnMedia_&&(this.off("loadedmetadata",this.masterPlaylistLoader_.createMupOnMedia_),this.masterPlaylistLoader_.createMupOnMedia_=null),this.off();},i.hasPendingRequest=function(){return this.request||this.mediaRequest_},i.stopRequest=function(){if(this.request){var e=this.request;this.request=null,e.onreadystatechange=null,e.abort();}},i.media=function(e){var t=this;if(!e)return this.media_;if("HAVE_NOTHING"===this.state)throw new Error("Cannot switch media playlist from "+this.state);var i=this.state;if("string"==typeof e){if(!this.masterPlaylistLoader_.master.playlists[e])throw new Error("Unknown playlist URI: "+e);e=this.masterPlaylistLoader_.master.playlists[e];}var n=!this.media_||e.id!==this.media_.id;if(n&&this.loadedPlaylists_[e.id]&&this.loadedPlaylists_[e.id].endList)return this.state="HAVE_METADATA",this.media_=e,void(n&&(this.trigger("mediachanging"),this.trigger("mediachange")));n&&(this.media_&&this.trigger("mediachanging"),this.addSidxSegments_(e,i,(function(n){t.haveMetadata({startingState:i,playlist:e});})));},i.haveMetadata=function(e){var t=e.startingState,i=e.playlist;this.state="HAVE_METADATA",this.loadedPlaylists_[i.id]=i,this.mediaRequest_=null,this.refreshMedia_(i.id),"HAVE_MASTER"===t?this.trigger("loadedmetadata"):this.trigger("mediachange");},i.pause=function(){this.masterPlaylistLoader_.createMupOnMedia_&&(this.off("loadedmetadata",this.masterPlaylistLoader_.createMupOnMedia_),this.masterPlaylistLoader_.createMupOnMedia_=null),this.stopRequest(),o.default.clearTimeout(this.mediaUpdateTimeout),this.mediaUpdateTimeout=null,this.isMaster_&&(o.default.clearTimeout(this.masterPlaylistLoader_.minimumUpdatePeriodTimeout_),this.masterPlaylistLoader_.minimumUpdatePeriodTimeout_=null),"HAVE_NOTHING"===this.state&&(this.started=!1);},i.load=function(e){var t=this;o.default.clearTimeout(this.mediaUpdateTimeout),this.mediaUpdateTimeout=null;var i=this.media();if(e){var n=i?i.targetDuration/2*1e3:5e3;this.mediaUpdateTimeout=o.default.setTimeout((function(){return t.load()}),n);}else this.started?i&&!i.endList?(this.isMaster_&&!this.minimumUpdatePeriodTimeout_&&(this.trigger("minimumUpdatePeriod"),this.updateMinimumUpdatePeriodTimeout_()),this.trigger("mediaupdatetimeout")):this.trigger("loadedplaylist"):this.start();},i.start=function(){var e=this;this.started=!0,this.isMaster_?this.requestMaster_((function(t,i){e.haveMaster_(),e.hasPendingRequest()||e.media_||e.media(e.masterPlaylistLoader_.master.playlists[0]);})):this.mediaRequest_=o.default.setTimeout((function(){return e.haveMaster_()}),0);},i.requestMaster_=function(e){var t=this;this.request=this.vhs_.xhr({uri:this.masterPlaylistLoader_.srcUrl,withCredentials:this.withCredentials},(function(i,n){if(!t.requestErrored_(i,n)){var r=n.responseText!==t.masterPlaylistLoader_.masterXml_;return t.masterPlaylistLoader_.masterXml_=n.responseText,n.responseHeaders&&n.responseHeaders.date?t.masterLoaded_=Date.parse(n.responseHeaders.date):t.masterLoaded_=Date.now(),t.masterPlaylistLoader_.srcUrl=y(t.handleManifestRedirects,t.masterPlaylistLoader_.srcUrl,n),r?(t.handleMaster_(),void t.syncClientServerClock_((function(){return e(n,r)}))):e(n,r)}"HAVE_NOTHING"===t.state&&(t.started=!1);}));},i.syncClientServerClock_=function(e){var t,i=this,n=(t=this.masterPlaylistLoader_.masterXml_,function(e){var t=ct(e,"UTCTiming")[0];if(!t)return null;var i=gt(t);switch(i.schemeIdUri){case"urn:mpeg:dash:utc:http-head:2014":case"urn:mpeg:dash:utc:http-head:2012":i.method="HEAD";break;case"urn:mpeg:dash:utc:http-xsdate:2014":case"urn:mpeg:dash:utc:http-iso:2014":case"urn:mpeg:dash:utc:http-xsdate:2012":case"urn:mpeg:dash:utc:http-iso:2012":i.method="GET";break;case"urn:mpeg:dash:utc:direct:2014":case"urn:mpeg:dash:utc:direct:2012":i.method="DIRECT",i.value=Date.parse(i.value);break;case"urn:mpeg:dash:utc:http-ntp:2014":case"urn:mpeg:dash:utc:ntp:2014":case"urn:mpeg:dash:utc:sntp:2014":default:throw new Error("UNSUPPORTED_UTC_TIMING_SCHEME")}return i}(bt(t)));return null===n?(this.masterPlaylistLoader_.clientOffset_=this.masterLoaded_-Date.now(),e()):"DIRECT"===n.method?(this.masterPlaylistLoader_.clientOffset_=n.value-Date.now(),e()):void(this.request=this.vhs_.xhr({uri:g(this.masterPlaylistLoader_.srcUrl,n.value),method:n.method,withCredentials:this.withCredentials},(function(t,r){if(i.request){if(t)return i.masterPlaylistLoader_.clientOffset_=i.masterLoaded_-Date.now(),e();var a;a="HEAD"===n.method?r.responseHeaders&&r.responseHeaders.date?Date.parse(r.responseHeaders.date):i.masterLoaded_:Date.parse(r.responseText),i.masterPlaylistLoader_.clientOffset_=a-Date.now(),e();}})))},i.haveMaster_=function(){this.state="HAVE_MASTER",this.isMaster_?this.trigger("loadedplaylist"):this.media_||this.media(this.childPlaylist_);},i.handleMaster_=function(){this.mediaRequest_=null;var e,t,i,n=(e={masterXml:this.masterPlaylistLoader_.masterXml_,srcUrl:this.masterPlaylistLoader_.srcUrl,clientOffset:this.masterPlaylistLoader_.clientOffset_,sidxMapping:this.masterPlaylistLoader_.sidxMapping_},i=St(e.masterXml,{manifestUri:t=e.srcUrl,clientOffset:e.clientOffset,sidxMapping:e.sidxMapping}),R(i,t),i),r=this.masterPlaylistLoader_.master;r&&(n=function(e,t,i){for(var n=!0,r=Jt(e,{duration:t.duration,minimumUpdatePeriod:t.minimumUpdatePeriod}),a=0;a-1)},this.trigger=function(t){var i,n,r,a;if(i=e[t])if(2===arguments.length)for(r=i.length,n=0;n>>1,e.samplingfrequencyindex<<7|e.channelcount<<3,6,1,2]))},m=function(e){return t(S.hdlr,P[e])},p=function(e){var i=new Uint8Array([0,0,0,0,0,0,0,2,0,0,0,3,0,1,95,144,e.duration>>>24&255,e.duration>>>16&255,e.duration>>>8&255,255&e.duration,85,196,0,0]);return e.samplerate&&(i[12]=e.samplerate>>>24&255,i[13]=e.samplerate>>>16&255,i[14]=e.samplerate>>>8&255,i[15]=255&e.samplerate),t(S.mdhd,i)},f=function(e){return t(S.mdia,p(e),m(e.type),s(e))},a=function(e){return t(S.mfhd,new Uint8Array([0,0,0,0,(4278190080&e)>>24,(16711680&e)>>16,(65280&e)>>8,255&e]))},s=function(e){return t(S.minf,"video"===e.type?t(S.vmhd,O):t(S.smhd,k),i(),y(e))},o=function(e,i){for(var n=[],r=i.length;r--;)n[r]=v(i[r]);return t.apply(null,[S.moof,a(e)].concat(n))},u=function(e){for(var i=e.length,n=[];i--;)n[i]=h(e[i]);return t.apply(null,[S.moov,l(4294967295)].concat(n).concat(d(e)))},d=function(e){for(var i=e.length,n=[];i--;)n[i]=T(e[i]);return t.apply(null,[S.mvex].concat(n))},l=function(e){var i=new Uint8Array([0,0,0,0,0,0,0,1,0,0,0,2,0,1,95,144,(4278190080&e)>>24,(16711680&e)>>16,(65280&e)>>8,255&e,0,1,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,64,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,255]);return t(S.mvhd,i)},g=function(e){var i,n,r=e.samples||[],a=new Uint8Array(4+r.length);for(n=0;n>>8),s.push(255&r[i].byteLength),s=s.concat(Array.prototype.slice.call(r[i]));for(i=0;i>>8),o.push(255&a[i].byteLength),o=o.concat(Array.prototype.slice.call(a[i]));if(n=[S.avc1,new Uint8Array([0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,(65280&e.width)>>8,255&e.width,(65280&e.height)>>8,255&e.height,0,72,0,0,0,72,0,0,0,0,0,0,0,1,19,118,105,100,101,111,106,115,45,99,111,110,116,114,105,98,45,104,108,115,0,0,0,0,0,0,0,0,0,0,0,0,0,24,17,17]),t(S.avcC,new Uint8Array([1,e.profileIdc,e.profileCompatibility,e.levelIdc,255].concat([r.length],s,[a.length],o))),t(S.btrt,new Uint8Array([0,28,156,128,0,45,198,192,0,45,198,192]))],e.sarRatio){var u=e.sarRatio[0],d=e.sarRatio[1];n.push(t(S.pasp,new Uint8Array([(4278190080&u)>>24,(16711680&u)>>16,(65280&u)>>8,255&u,(4278190080&d)>>24,(16711680&d)>>16,(65280&d)>>8,255&d])));}return t.apply(null,n)},B=function(e){return t(S.mp4a,new Uint8Array([0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,(65280&e.channelcount)>>8,255&e.channelcount,(65280&e.samplesize)>>8,255&e.samplesize,0,0,0,0,(65280&e.samplerate)>>8,255&e.samplerate,0,0]),n(e))},c=function(e){var i=new Uint8Array([0,0,0,7,0,0,0,0,0,0,0,0,(4278190080&e.id)>>24,(16711680&e.id)>>16,(65280&e.id)>>8,255&e.id,0,0,0,0,(4278190080&e.duration)>>24,(16711680&e.duration)>>16,(65280&e.duration)>>8,255&e.duration,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,64,0,0,0,(65280&e.width)>>8,255&e.width,0,0,(65280&e.height)>>8,255&e.height,0,0]);return t(S.tkhd,i)},v=function(e){var i,n,r,a,s,o;return i=t(S.tfhd,new Uint8Array([0,0,0,58,(4278190080&e.id)>>24,(16711680&e.id)>>16,(65280&e.id)>>8,255&e.id,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0])),s=Math.floor(e.baseMediaDecodeTime/(G+1)),o=Math.floor(e.baseMediaDecodeTime%(G+1)),n=t(S.tfdt,new Uint8Array([1,0,0,0,s>>>24&255,s>>>16&255,s>>>8&255,255&s,o>>>24&255,o>>>16&255,o>>>8&255,255&o])),"audio"===e.type?(r=b(e,92),t(S.traf,i,n,r)):(a=g(e),r=b(e,a.length+92),t(S.traf,i,n,r,a))},h=function(e){return e.duration=e.duration||4294967295,t(S.trak,c(e),f(e))},T=function(e){var i=new Uint8Array([0,0,0,0,(4278190080&e.id)>>24,(16711680&e.id)>>16,(65280&e.id)>>8,255&e.id,0,0,0,1,0,0,0,0,0,0,0,0,0,1,0,1]);return "video"!==e.type&&(i[i.length-1]=0),t(S.trex,i)},q=function(e,t){var i=0,n=0,r=0,a=0;return e.length&&(void 0!==e[0].duration&&(i=1),void 0!==e[0].size&&(n=2),void 0!==e[0].flags&&(r=4),void 0!==e[0].compositionTimeOffset&&(a=8)),[0,0,i|n|r|a,1,(4278190080&e.length)>>>24,(16711680&e.length)>>>16,(65280&e.length)>>>8,255&e.length,(4278190080&t)>>>24,(16711680&t)>>>16,(65280&t)>>>8,255&t]},F=function(e,i){var n,r,a,s,o,u;for(i+=20+16*(s=e.samples||[]).length,a=q(s,i),(r=new Uint8Array(a.length+16*s.length)).set(a),n=a.length,u=0;u>>24,r[n++]=(16711680&o.duration)>>>16,r[n++]=(65280&o.duration)>>>8,r[n++]=255&o.duration,r[n++]=(4278190080&o.size)>>>24,r[n++]=(16711680&o.size)>>>16,r[n++]=(65280&o.size)>>>8,r[n++]=255&o.size,r[n++]=o.flags.isLeading<<2|o.flags.dependsOn,r[n++]=o.flags.isDependedOn<<6|o.flags.hasRedundancy<<4|o.flags.paddingValue<<1|o.flags.isNonSyncSample,r[n++]=61440&o.flags.degradationPriority,r[n++]=15&o.flags.degradationPriority,r[n++]=(4278190080&o.compositionTimeOffset)>>>24,r[n++]=(16711680&o.compositionTimeOffset)>>>16,r[n++]=(65280&o.compositionTimeOffset)>>>8,r[n++]=255&o.compositionTimeOffset;return t(S.trun,r)},N=function(e,i){var n,r,a,s,o,u;for(i+=20+8*(s=e.samples||[]).length,a=q(s,i),(n=new Uint8Array(a.length+8*s.length)).set(a),r=a.length,u=0;u>>24,n[r++]=(16711680&o.duration)>>>16,n[r++]=(65280&o.duration)>>>8,n[r++]=255&o.duration,n[r++]=(4278190080&o.size)>>>24,n[r++]=(16711680&o.size)>>>16,n[r++]=(65280&o.size)>>>8,n[r++]=255&o.size;return t(S.trun,n)},b=function(e,t){return "audio"===e.type?N(e,t):F(e,t)},r=function(){return t(S.ftyp,I,E,I,w)};var W,V,j,X,z,Q,Y,K,$=function(e){return t(S.mdat,e)},J=o,Z=function(e,t){var i={size:0,flags:{isLeading:0,dependsOn:1,isDependedOn:0,hasRedundancy:0,degradationPriority:0,isNonSyncSample:1}};return i.dataOffset=t,i.compositionTimeOffset=e.pts-e.dts,i.duration=e.duration,i.size=4*e.length,i.size+=e.byteLength,e.keyFrame&&(i.flags.dependsOn=2,i.flags.isNonSyncSample=0),i},ee=[33,16,5,32,164,27],te=[33,65,108,84,1,2,4,8,168,2,4,8,17,191,252],ie=function(e){for(var t=[];e--;)t.push(0);return t},ne=9e4;Q=function(e,t){return V(z(e,t))},Y=function(e,t){return j(X(e),t)},K=function(e,t,i){return X(i?e:e-t)};var re=ne,ae=V=function(e){return e*ne},se=(j=function(e,t){return e*t},X=function(e){return e/ne}),oe=(z=function(e,t){return e/t},Q),ue=Y,de=K,le=function(e,t,i,n){var r,a,s,o,u,d=0,l=0,h=0;if(t.length&&(r=oe(e.baseMediaDecodeTime,e.samplerate),a=Math.ceil(re/(e.samplerate/1024)),i&&n&&(d=r-Math.max(i,n),h=(l=Math.floor(d/a))*a),!(l<1||h>45e3))){for((s=function(){if(!W){var e={96e3:[ee,[227,64],ie(154),[56]],88200:[ee,[231],ie(170),[56]],64e3:[ee,[248,192],ie(240),[56]],48e3:[ee,[255,192],ie(268),[55,148,128],ie(54),[112]],44100:[ee,[255,192],ie(268),[55,163,128],ie(84),[112]],32e3:[ee,[255,192],ie(268),[55,234],ie(226),[112]],24e3:[ee,[255,192],ie(268),[55,255,128],ie(268),[111,112],ie(126),[224]],16e3:[ee,[255,192],ie(268),[55,255,128],ie(268),[111,255],ie(269),[223,108],ie(195),[1,192]],12e3:[te,ie(268),[3,127,248],ie(268),[6,255,240],ie(268),[13,255,224],ie(268),[27,253,128],ie(259),[56]],11025:[te,ie(268),[3,127,248],ie(268),[6,255,240],ie(268),[13,255,224],ie(268),[27,255,192],ie(268),[55,175,128],ie(108),[112]],8e3:[te,ie(268),[3,121,16],ie(47),[7]]};t=e,W=Object.keys(t).reduce((function(e,i){return e[i]=new Uint8Array(t[i].reduce((function(e,t){return e.concat(t)}),[])),e}),{});}var t;return W}()[e.samplerate])||(s=t[0].data),o=0;o=this.virtualRowCount&&"function"==typeof this.beforeRowOverflow&&this.beforeRowOverflow(e),this.rows.length>0&&(this.rows.push(""),this.rowIdx++);this.rows.length>this.virtualRowCount;)this.rows.shift(),this.rowIdx--;},ye.prototype.isEmpty=function(){return 0===this.rows.length||1===this.rows.length&&""===this.rows[0]},ye.prototype.addText=function(e){this.rows[this.rowIdx]+=e;},ye.prototype.backspace=function(){if(!this.isEmpty()){var e=this.rows[this.rowIdx];this.rows[this.rowIdx]=e.substr(0,e.length-1);}};var _e=function(e){this.serviceNum=e,this.text="",this.currentWindow=new ye(-1),this.windows=[];};_e.prototype.init=function(e,t){this.startPts=e;for(var i=0;i<8;i++)this.windows[i]=new ye(i),"function"==typeof t&&(this.windows[i].beforeRowOverflow=t);},_e.prototype.setCurrentWindow=function(e){this.currentWindow=this.windows[e];};var ve=function e(){e.prototype.init.call(this);var t=this;this.current708Packet=null,this.services={},this.push=function(e){3===e.type?(t.new708Packet(),t.add708Bytes(e)):(null===t.current708Packet&&t.new708Packet(),t.add708Bytes(e));};};ve.prototype=new H,ve.prototype.new708Packet=function(){null!==this.current708Packet&&this.push708Packet(),this.current708Packet={data:[],ptsVals:[]};},ve.prototype.add708Bytes=function(e){var t=e.ccData,i=t>>>8,n=255&t;this.current708Packet.ptsVals.push(e.pts),this.current708Packet.data.push(i),this.current708Packet.data.push(n);},ve.prototype.push708Packet=function(){var e=this.current708Packet,t=e.data,i=null,n=null,r=0,a=t[r++];for(e.seq=a>>6,e.sizeCode=63&a;r>5)&&n>0&&(i=a=t[r++]),this.pushServiceBlock(i,r,n),n>0&&(r+=n-1);},ve.prototype.pushServiceBlock=function(e,t,i){var n,r=t,a=this.current708Packet.data,s=this.services[e];for(s||(s=this.initService(e,r));r>5,a.rowLock=(16&n)>>4,a.columnLock=(8&n)>>3,a.priority=7&n,n=i[++e],a.relativePositioning=(128&n)>>7,a.anchorVertical=127&n,n=i[++e],a.anchorHorizontal=n,n=i[++e],a.anchorPoint=(240&n)>>4,a.rowCount=15&n,n=i[++e],a.columnCount=63&n,n=i[++e],a.windowStyle=(56&n)>>3,a.penStyle=7&n,a.virtualRowCount=a.rowCount+1,e},ve.prototype.setWindowAttributes=function(e,t){var i=this.current708Packet.data,n=i[e],r=t.currentWindow.winAttr;return n=i[++e],r.fillOpacity=(192&n)>>6,r.fillRed=(48&n)>>4,r.fillGreen=(12&n)>>2,r.fillBlue=3&n,n=i[++e],r.borderType=(192&n)>>6,r.borderRed=(48&n)>>4,r.borderGreen=(12&n)>>2,r.borderBlue=3&n,n=i[++e],r.borderType+=(128&n)>>5,r.wordWrap=(64&n)>>6,r.printDirection=(48&n)>>4,r.scrollDirection=(12&n)>>2,r.justify=3&n,n=i[++e],r.effectSpeed=(240&n)>>4,r.effectDirection=(12&n)>>2,r.displayEffect=3&n,e},ve.prototype.flushDisplayed=function(e,t){for(var i=[],n=0;n<8;n++)t.windows[n].visible&&!t.windows[n].isEmpty()&&i.push(t.windows[n].getText());t.endPts=e,t.text=i.join("\n\n"),this.pushCaption(t),t.startPts=e;},ve.prototype.pushCaption=function(e){""!==e.text&&(this.trigger("data",{startPts:e.startPts,endPts:e.endPts,text:e.text,stream:"cc708_"+e.serviceNum}),e.text="",e.startPts=e.endPts);},ve.prototype.displayWindows=function(e,t){var i=this.current708Packet.data[++e],n=this.getPts(e);this.flushDisplayed(n,t);for(var r=0;r<8;r++)i&1<>4,r.offset=(12&n)>>2,r.penSize=3&n,n=i[++e],r.italics=(128&n)>>7,r.underline=(64&n)>>6,r.edgeType=(56&n)>>3,r.fontStyle=7&n,e},ve.prototype.setPenColor=function(e,t){var i=this.current708Packet.data,n=i[e],r=t.currentWindow.penColor;return n=i[++e],r.fgOpacity=(192&n)>>6,r.fgRed=(48&n)>>4,r.fgGreen=(12&n)>>2,r.fgBlue=3&n,n=i[++e],r.bgOpacity=(192&n)>>6,r.bgRed=(48&n)>>4,r.bgGreen=(12&n)>>2,r.bgBlue=3&n,n=i[++e],r.edgeRed=(48&n)>>4,r.edgeGreen=(12&n)>>2,r.edgeBlue=3&n,e},ve.prototype.setPenLocation=function(e,t){var i=this.current708Packet.data,n=i[e],r=t.currentWindow.penLoc;return t.currentWindow.pendingNewLine=!0,n=i[++e],r.row=15&n,n=i[++e],r.column=63&n,e},ve.prototype.reset=function(e,t){var i=this.getPts(e);return this.flushDisplayed(i,t),this.initService(t.serviceNum,e)};var Te={42:225,92:233,94:237,95:243,96:250,123:231,124:247,125:209,126:241,127:9608,304:174,305:176,306:189,307:191,308:8482,309:162,310:163,311:9834,312:224,313:160,314:232,315:226,316:234,317:238,318:244,319:251,544:193,545:201,546:211,547:218,548:220,549:252,550:8216,551:161,552:42,553:39,554:8212,555:169,556:8480,557:8226,558:8220,559:8221,560:192,561:194,562:199,563:200,564:202,565:203,566:235,567:206,568:207,569:239,570:212,571:217,572:249,573:219,574:171,575:187,800:195,801:227,802:205,803:204,804:236,805:210,806:242,807:213,808:245,809:123,810:125,811:92,812:94,813:95,814:124,815:126,816:196,817:228,818:214,819:246,820:223,821:165,822:164,823:9474,824:197,825:229,826:216,827:248,828:9484,829:9488,830:9492,831:9496},be=function(e){return null===e?"":(e=Te[e]||e,String.fromCharCode(e))},Se=[4352,4384,4608,4640,5376,5408,5632,5664,5888,5920,4096,4864,4896,5120,5152],Ie=function(){for(var e=[],t=15;t--;)e.push("");return e},Ee=function e(t,i){e.prototype.init.call(this),this.field_=t||0,this.dataChannel_=i||0,this.name_="CC"+(1+(this.field_<<1|this.dataChannel_)),this.setConstants(),this.reset(),this.push=function(e){var t,i,n,r,a;if((t=32639&e.ccData)!==this.lastControlCode_){if(4096==(61440&t)?this.lastControlCode_=t:t!==this.PADDING_&&(this.lastControlCode_=null),n=t>>>8,r=255&t,t!==this.PADDING_)if(t===this.RESUME_CAPTION_LOADING_)this.mode_="popOn";else if(t===this.END_OF_CAPTION_)this.mode_="popOn",this.clearFormatting(e.pts),this.flushDisplayed(e.pts),i=this.displayed_,this.displayed_=this.nonDisplayed_,this.nonDisplayed_=i,this.startPts_=e.pts;else if(t===this.ROLL_UP_2_ROWS_)this.rollUpRows_=2,this.setRollUp(e.pts);else if(t===this.ROLL_UP_3_ROWS_)this.rollUpRows_=3,this.setRollUp(e.pts);else if(t===this.ROLL_UP_4_ROWS_)this.rollUpRows_=4,this.setRollUp(e.pts);else if(t===this.CARRIAGE_RETURN_)this.clearFormatting(e.pts),this.flushDisplayed(e.pts),this.shiftRowsUp_(),this.startPts_=e.pts;else if(t===this.BACKSPACE_)"popOn"===this.mode_?this.nonDisplayed_[this.row_]=this.nonDisplayed_[this.row_].slice(0,-1):this.displayed_[this.row_]=this.displayed_[this.row_].slice(0,-1);else if(t===this.ERASE_DISPLAYED_MEMORY_)this.flushDisplayed(e.pts),this.displayed_=Ie();else if(t===this.ERASE_NON_DISPLAYED_MEMORY_)this.nonDisplayed_=Ie();else if(t===this.RESUME_DIRECT_CAPTIONING_)"paintOn"!==this.mode_&&(this.flushDisplayed(e.pts),this.displayed_=Ie()),this.mode_="paintOn",this.startPts_=e.pts;else if(this.isSpecialCharacter(n,r))a=be((n=(3&n)<<8)|r),this[this.mode_](e.pts,a),this.column_++;else if(this.isExtCharacter(n,r))"popOn"===this.mode_?this.nonDisplayed_[this.row_]=this.nonDisplayed_[this.row_].slice(0,-1):this.displayed_[this.row_]=this.displayed_[this.row_].slice(0,-1),a=be((n=(3&n)<<8)|r),this[this.mode_](e.pts,a),this.column_++;else if(this.isMidRowCode(n,r))this.clearFormatting(e.pts),this[this.mode_](e.pts," "),this.column_++,14==(14&r)&&this.addFormatting(e.pts,["i"]),1==(1&r)&&this.addFormatting(e.pts,["u"]);else if(this.isOffsetControlCode(n,r))this.column_+=3&r;else if(this.isPAC(n,r)){var s=Se.indexOf(7968&t);"rollUp"===this.mode_&&(s-this.rollUpRows_+1<0&&(s=this.rollUpRows_-1),this.setRollUp(e.pts,s)),s!==this.row_&&(this.clearFormatting(e.pts),this.row_=s),1&r&&-1===this.formatting_.indexOf("u")&&this.addFormatting(e.pts,["u"]),16==(16&t)&&(this.column_=4*((14&t)>>1)),this.isColorPAC(r)&&14==(14&r)&&this.addFormatting(e.pts,["i"]);}else this.isNormalChar(n)&&(0===r&&(r=null),a=be(n),a+=be(r),this[this.mode_](e.pts,a),this.column_+=a.length);}else this.lastControlCode_=null;};};Ee.prototype=new H,Ee.prototype.flushDisplayed=function(e){var t=this.displayed_.map((function(e){try{return e.trim()}catch(e){return console.error("Skipping malformed caption."),""}})).join("\n").replace(/^\n+|\n+$/g,"");t.length&&this.trigger("data",{startPts:this.startPts_,endPts:e,text:t,stream:this.name_});},Ee.prototype.reset=function(){this.mode_="popOn",this.topRow_=0,this.startPts_=0,this.displayed_=Ie(),this.nonDisplayed_=Ie(),this.lastControlCode_=null,this.column_=0,this.row_=14,this.rollUpRows_=2,this.formatting_=[];},Ee.prototype.setConstants=function(){0===this.dataChannel_?(this.BASE_=16,this.EXT_=17,this.CONTROL_=(20|this.field_)<<8,this.OFFSET_=23):1===this.dataChannel_&&(this.BASE_=24,this.EXT_=25,this.CONTROL_=(28|this.field_)<<8,this.OFFSET_=31),this.PADDING_=0,this.RESUME_CAPTION_LOADING_=32|this.CONTROL_,this.END_OF_CAPTION_=47|this.CONTROL_,this.ROLL_UP_2_ROWS_=37|this.CONTROL_,this.ROLL_UP_3_ROWS_=38|this.CONTROL_,this.ROLL_UP_4_ROWS_=39|this.CONTROL_,this.CARRIAGE_RETURN_=45|this.CONTROL_,this.RESUME_DIRECT_CAPTIONING_=41|this.CONTROL_,this.BACKSPACE_=33|this.CONTROL_,this.ERASE_DISPLAYED_MEMORY_=44|this.CONTROL_,this.ERASE_NON_DISPLAYED_MEMORY_=46|this.CONTROL_;},Ee.prototype.isSpecialCharacter=function(e,t){return e===this.EXT_&&t>=48&&t<=63},Ee.prototype.isExtCharacter=function(e,t){return (e===this.EXT_+1||e===this.EXT_+2)&&t>=32&&t<=63},Ee.prototype.isMidRowCode=function(e,t){return e===this.EXT_&&t>=32&&t<=47},Ee.prototype.isOffsetControlCode=function(e,t){return e===this.OFFSET_&&t>=33&&t<=35},Ee.prototype.isPAC=function(e,t){return e>=this.BASE_&&e=64&&t<=127},Ee.prototype.isColorPAC=function(e){return e>=64&&e<=79||e>=96&&e<=127},Ee.prototype.isNormalChar=function(e){return e>=32&&e<=127},Ee.prototype.setRollUp=function(e,t){if("rollUp"!==this.mode_&&(this.row_=14,this.mode_="rollUp",this.flushDisplayed(e),this.nonDisplayed_=Ie(),this.displayed_=Ie()),void 0!==t&&t!==this.row_)for(var i=0;i"}),"");this[this.mode_](e,i);},Ee.prototype.clearFormatting=function(e){if(this.formatting_.length){var t=this.formatting_.reverse().reduce((function(e,t){return e+""}),"");this.formatting_=[],this[this.mode_](e,t);}},Ee.prototype.popOn=function(e,t){var i=this.nonDisplayed_[this.row_];i+=t,this.nonDisplayed_[this.row_]=i;},Ee.prototype.rollUp=function(e,t){var i=this.displayed_[this.row_];i+=t,this.displayed_[this.row_]=i;},Ee.prototype.shiftRowsUp_=function(){var e;for(e=0;et&&(i=-1);Math.abs(t-e)>4294967296;)e+=8589934592*i;return e},Oe=function e(t){var i,n;e.prototype.init.call(this),this.type_=t||Le,this.push=function(e){this.type_!==Le&&e.type!==this.type_||(void 0===n&&(n=e.dts),e.dts=Pe(e.dts,n),e.pts=Pe(e.pts,n),i=e.dts,this.trigger("data",e));},this.flush=function(){n=i,this.trigger("done");},this.endTimeline=function(){this.flush(),this.trigger("endedtimeline");},this.discontinuity=function(){n=void 0,i=void 0;},this.reset=function(){this.discontinuity(),this.trigger("reset");};};Oe.prototype=new H;var ke,xe=Oe,Ce=Pe,Ue=function(e,t,i){var n,r="";for(n=t;n>>2;h*=4,h+=3&l[7],u.timeStamp=h,void 0===t.pts&&void 0===t.dts&&(t.pts=u.timeStamp,t.dts=u.timeStamp),this.trigger("timestamp",u);}t.frames.push(u),s+=10,s+=o;}while(s>>4>1&&(n+=t[n]+1),0===i.pid)i.type="pat",e(t.subarray(n),i),this.trigger("data",i);else if(i.pid===this.pmtPid)for(i.type="pmt",e(t.subarray(n),i),this.trigger("data",i);this.packetsWaitingForPmt.length;)this.processPes_.apply(this,this.packetsWaitingForPmt.shift());else void 0===this.programMapTable?this.packetsWaitingForPmt.push([t,n,i]):this.processPes_(t,n,i);},this.processPes_=function(e,t,i){i.pid===this.programMapTable.video?i.streamType=Ae.H264_STREAM_TYPE:i.pid===this.programMapTable.audio?i.streamType=Ae.ADTS_STREAM_TYPE:i.streamType=this.programMapTable["timed-metadata"][i.pid],i.type="pes",i.data=e.subarray(t),this.trigger("data",i);};}).prototype=new H,Ne.STREAM_TYPES={h264:27,adts:15},(Fe=function(){var e,t=this,i={data:[],size:0},n={data:[],size:0},r={data:[],size:0},a=function(e,i,n){var r,a,s=new Uint8Array(e.size),o={type:i},u=0,d=0;if(e.data.length&&!(e.size<9)){for(o.trackId=e.data[0].pid,u=0;u>>3,h.pts*=4,h.pts+=(6&l[13])>>>1,h.dts=h.pts,64&c&&(h.dts=(14&l[14])<<27|(255&l[15])<<20|(254&l[16])<<12|(255&l[17])<<5|(254&l[18])>>>3,h.dts*=4,h.dts+=(6&l[18])>>>1)),h.data=l.subarray(9+l[8])),r="video"===i||o.packetLength<=e.size,(n||r)&&(e.size=0,e.data.length=0),r&&t.trigger("data",o);}};Fe.prototype.init.call(this),this.push=function(s){({pat:function(){},pes:function(){var e,t;switch(s.streamType){case Ae.H264_STREAM_TYPE:e=i,t="video";break;case Ae.ADTS_STREAM_TYPE:e=n,t="audio";break;case Ae.METADATA_STREAM_TYPE:e=r,t="timed-metadata";break;default:return}s.payloadUnitStartIndicator&&a(e,t,!0),e.data.push(s),e.size+=s.data.byteLength;},pmt:function(){var i={type:"metadata",tracks:[]};null!==(e=s.programMapTable).video&&i.tracks.push({timelineStartInfo:{baseMediaDecodeTime:0},id:+e.video,codec:"avc",type:"video"}),null!==e.audio&&i.tracks.push({timelineStartInfo:{baseMediaDecodeTime:0},id:+e.audio,codec:"adts",type:"audio"}),t.trigger("data",i);}})[s.type]();},this.reset=function(){i.size=0,i.data.length=0,n.size=0,n.data.length=0,this.trigger("reset");},this.flushStreams_=function(){a(i,"video"),a(n,"audio"),a(r,"timed-metadata");},this.flush=function(){this.flushStreams_(),this.trigger("done");};}).prototype=new H;var We={PAT_PID:0,MP2T_PACKET_LENGTH:Ge,TransportPacketStream:Be,TransportParseStream:Ne,ElementaryStream:Fe,TimestampRolloverStream:He,CaptionStream:we.CaptionStream,Cea608Stream:we.Cea608Stream,Cea708Stream:we.Cea708Stream,MetadataStream:qe};for(var Ve in Ae)Ae.hasOwnProperty(Ve)&&(We[Ve]=Ae[Ve]);var je,Xe=We,ze=[96e3,88200,64e3,48e3,44100,32e3,24e3,22050,16e3,12e3,11025,8e3,7350];(je=function(e){var t,i=0;je.prototype.init.call(this),this.push=function(n){var r,a,s,o,u,d,l=0;if(e||(i=0),"audio"===n.type)for(t?(o=t,(t=new Uint8Array(o.byteLength+n.data.byteLength)).set(o),t.set(n.data,o.byteLength)):t=n.data;l+5>5,d=9e4*(u=1024*(1+(3&t[l+6])))/ze[(60&t[l+2])>>>2],s=l+r,t.byteLength>>6&3),channelcount:(1&t[l+2])<<2|(192&t[l+3])>>>6,samplerate:ze[(60&t[l+2])>>>2],samplingfrequencyindex:(60&t[l+2])>>>2,samplesize:16,data:t.subarray(l+7+a,s)}),i++,t.byteLength===s)return void(t=void 0);t=t.subarray(s);}else l++;},this.flush=function(){i=0,this.trigger("done");},this.reset=function(){t=void 0,this.trigger("reset");},this.endTimeline=function(){t=void 0,this.trigger("endedtimeline");};}).prototype=new H;var Qe,Ye,Ke,$e=je,Je=function(e){var t=e.byteLength,i=0,n=0;this.length=function(){return 8*t},this.bitsAvailable=function(){return 8*t+n},this.loadWord=function(){var r=e.byteLength-t,a=new Uint8Array(4),s=Math.min(4,t);if(0===s)throw new Error("no bytes available");a.set(e.subarray(r,r+s)),i=new DataView(a.buffer).getUint32(0),n=8*s,t-=s;},this.skipBits=function(e){var r;n>e?(i<<=e,n-=e):(e-=n,e-=8*(r=Math.floor(e/8)),t-=r,this.loadWord(),i<<=e,n-=e);},this.readBits=function(e){var r=Math.min(n,e),a=i>>>32-r;return (n-=r)>0?i<<=r:t>0&&this.loadWord(),(r=e-r)>0?a<>>e))return i<<=e,n-=e,e;return this.loadWord(),e+this.skipLeadingZeros()},this.skipUnsignedExpGolomb=function(){this.skipBits(1+this.skipLeadingZeros());},this.skipExpGolomb=function(){this.skipBits(1+this.skipLeadingZeros());},this.readUnsignedExpGolomb=function(){var e=this.skipLeadingZeros();return this.readBits(e+1)-1},this.readExpGolomb=function(){var e=this.readUnsignedExpGolomb();return 1&e?1+e>>>1:-1*(e>>>1)},this.readBoolean=function(){return 1===this.readBits(1)},this.readUnsignedByte=function(){return this.readBits(8)},this.loadWord();};(Ye=function(){var e,t,i=0;Ye.prototype.init.call(this),this.push=function(n){var r;t?((r=new Uint8Array(t.byteLength+n.data.byteLength)).set(t),r.set(n.data,t.byteLength),t=r):t=n.data;for(var a=t.byteLength;i3&&this.trigger("data",t.subarray(i+3)),t=null,i=0,this.trigger("done");},this.endTimeline=function(){this.flush(),this.trigger("endedtimeline");};}).prototype=new H,Ke={100:!0,110:!0,122:!0,244:!0,44:!0,83:!0,86:!0,118:!0,128:!0,138:!0,139:!0,134:!0},(Qe=function(){var e,t,i,n,r,a,s,o=new Ye;Qe.prototype.init.call(this),e=this,this.push=function(e){"video"===e.type&&(t=e.trackId,i=e.pts,n=e.dts,o.push(e));},o.on("data",(function(s){var o={trackId:t,pts:i,dts:n,data:s};switch(31&s[0]){case 5:o.nalUnitType="slice_layer_without_partitioning_rbsp_idr";break;case 6:o.nalUnitType="sei_rbsp",o.escapedRBSP=r(s.subarray(1));break;case 7:o.nalUnitType="seq_parameter_set_rbsp",o.escapedRBSP=r(s.subarray(1)),o.config=a(o.escapedRBSP);break;case 8:o.nalUnitType="pic_parameter_set_rbsp";break;case 9:o.nalUnitType="access_unit_delimiter_rbsp";}e.trigger("data",o);})),o.on("done",(function(){e.trigger("done");})),o.on("partialdone",(function(){e.trigger("partialdone");})),o.on("reset",(function(){e.trigger("reset");})),o.on("endedtimeline",(function(){e.trigger("endedtimeline");})),this.flush=function(){o.flush();},this.partialFlush=function(){o.partialFlush();},this.reset=function(){o.reset();},this.endTimeline=function(){o.endTimeline();},s=function(e,t){var i,n=8,r=8;for(i=0;i=0?i:0,(16&e[t+5])>>4?i+20:i+10},nt=function e(t,i){return t.length-i<10||t[i]!=="I".charCodeAt(0)||t[i+1]!=="D".charCodeAt(0)||t[i+2]!=="3".charCodeAt(0)?i:e(t,i+=it(t,i))},rt=function(e){return e[0]<<21|e[1]<<14|e[2]<<7|e[3]},at={isLikelyAacData:function(e){var t=nt(e,0);return e.length>=t+2&&255==(255&e[t])&&240==(240&e[t+1])&&16==(22&e[t+1])},parseId3TagSize:it,parseAdtsSize:function(e,t){var i=(224&e[t+5])>>5,n=e[t+4]<<3;return 6144&e[t+3]|n|i},parseType:function(e,t){return e[t]==="I".charCodeAt(0)&&e[t+1]==="D".charCodeAt(0)&&e[t+2]==="3".charCodeAt(0)?"timed-metadata":!0&e[t]&&240==(240&e[t+1])?"audio":null},parseSampleRate:function(e){for(var t=0;t+5>>2];t++;}return null},parseAacTimestamp:function(e){var t,i,n;t=10,64&e[5]&&(t+=4,t+=rt(e.subarray(10,14)));do{if((i=rt(e.subarray(t+4,t+8)))<1)return null;if("PRIV"===String.fromCharCode(e[t],e[t+1],e[t+2],e[t+3])){n=e.subarray(t+10,t+i+10);for(var r=0;r>>2;return (s*=4)+(3&a[7])}break}}t+=10,t+=i;}while(t=3;)if(e[u]!=="I".charCodeAt(0)||e[u+1]!=="D".charCodeAt(0)||e[u+2]!=="3".charCodeAt(0))if(255!=(255&e[u])||240!=(240&e[u+1]))u++;else {if(e.length-u<7)break;if(u+(o=at.parseAdtsSize(e,u))>e.length)break;a={type:"audio",data:e.subarray(u,u+o),pts:t,dts:t},this.trigger("data",a),u+=o;}else {if(e.length-u<10)break;if(u+(o=at.parseId3TagSize(e,u))>e.length)break;r={type:"timed-metadata",data:e.subarray(u,u+o)},this.trigger("data",r),u+=o;}n=e.length-u,e=n>0?e.subarray(u):new Uint8Array;},this.reset=function(){e=new Uint8Array,this.trigger("reset");},this.endTimeline=function(){e=new Uint8Array,this.trigger("endedtimeline");};}).prototype=new H;var st,ot,ut,dt,lt=Ze,ht=["audioobjecttype","channelcount","samplerate","samplingfrequencyindex","samplesize"],ct=["width","height","profileIdc","levelIdc","profileCompatibility","sarRatio"],ft=et.H264Stream,pt=at.isLikelyAacData,mt=function(e,t){var i;if(e.length!==t.length)return !1;for(i=0;i=i?e:(t.minSegmentDts=1/0,e.filter((function(e){return e.dts>=i&&(t.minSegmentDts=Math.min(t.minSegmentDts,e.dts),t.minSegmentPts=t.minSegmentDts,!0)})))}(i,e,r),e.baseMediaDecodeTime=ce(e,t.keepOriginalTimestamps),f=le(e,o,a,s),e.samples=function(e){var t,i,n=[];for(t=0;t1&&(t=e.shift(),e.byteLength-=t.byteLength,e.nalCount-=t.nalCount,e[0][0].dts=t.dts,e[0][0].pts=t.pts,e[0][0].duration+=t.duration),e}(n)),s.length){var f;if(!(f=t.alignGopsAtEnd?this.alignGopsAtEnd_(n):this.alignGopsAtStart_(n)))return this.gopCache_.unshift({gop:n.pop(),pps:e.pps,sps:e.sps}),this.gopCache_.length=Math.min(6,this.gopCache_.length),a=[],this.resetStream_(),void this.trigger("done","VideoSegmentStream");he(e),n=f;}fe(e,n),e.samples=function(e,t){var i,n,r,a,s,o=t||0,u=[];for(i=0;i=-1e4&&i<=45e3&&(!n||o>i)&&(n=a,o=i));return n?n.gop:null},this.alignGopsAtStart_=function(e){var t,i,n,r,a,o,u,d;for(a=e.byteLength,o=e.nalCount,u=e.duration,t=i=0;tn.pts?t++:(i++,a-=r.byteLength,o-=r.nalCount,u-=r.duration);return 0===i?e:i===e.length?null:((d=e.slice(i)).byteLength=a,d.duration=u,d.nalCount=o,d.pts=d[0].pts,d.dts=d[0].dts,d)},this.alignGopsAtEnd_=function(e){var t,i,n,r,a,o,u;for(t=s.length-1,i=e.length-1,a=null,o=!1;t>=0&&i>=0;){if(n=s[t],r=e[i],n.pts===r.pts){o=!0;break}n.pts>r.pts?t--:(t===s.length-1&&(a=i),i--);}if(!o&&null===a)return null;if(0===(u=o?i:a))return e;var d=e.slice(u),l=d.reduce((function(e,t){return e.byteLength+=t.byteLength,e.duration+=t.duration,e.nalCount+=t.nalCount,e}),{byteLength:0,duration:0,nalCount:0});return d.byteLength=l.byteLength,d.duration=l.duration,d.nalCount=l.nalCount,d.pts=d[0].pts,d.dts=d[0].dts,d},this.alignGopsWith=function(e){s=e;};}).prototype=new H,(dt=function(e,t){this.numberOfTracks=0,this.metadataStream=t,void 0!==(e=e||{}).remux?this.remuxTracks=!!e.remux:this.remuxTracks=!0,"boolean"==typeof e.keepOriginalTimestamps?this.keepOriginalTimestamps=e.keepOriginalTimestamps:this.keepOriginalTimestamps=!1,this.pendingTracks=[],this.videoTrack=null,this.pendingBoxes=[],this.pendingCaptions=[],this.pendingMetadata=[],this.pendingBytes=0,this.emittedTracks=0,dt.prototype.init.call(this),this.push=function(e){return e.text?this.pendingCaptions.push(e):e.frames?this.pendingMetadata.push(e):(this.pendingTracks.push(e.track),this.pendingBytes+=e.boxes.byteLength,"video"===e.track.type&&(this.videoTrack=e.track,this.pendingBoxes.push(e.boxes)),void("audio"===e.track.type&&(this.audioTrack=e.track,this.pendingBoxes.unshift(e.boxes))))};}).prototype=new H,dt.prototype.flush=function(e){var t,i,n,a,s,o,d,l,h=0,c={captions:[],captionStreams:{},metadata:[],info:{}},f=0;if(this.pendingTracks.length=this.numberOfTracks&&(this.trigger("done"),this.emittedTracks=0))}if(this.videoTrack?(f=this.videoTrack.timelineStartInfo.pts,ct.forEach((function(e){c.info[e]=this.videoTrack[e];}),this)):this.audioTrack&&(f=this.audioTrack.timelineStartInfo.pts,ht.forEach((function(e){c.info[e]=this.audioTrack[e];}),this)),this.videoTrack||this.audioTrack){for(1===this.pendingTracks.length?c.type=this.pendingTracks[0].type:c.type="combined",this.emittedTracks+=this.pendingTracks.length,s=this.pendingTracks,o=void 0,d=void 0,l=void 0,d=r(),l=u(s),(o=new Uint8Array(d.byteLength+l.byteLength)).set(d),o.set(l,d.byteLength),n=o,c.initSegment=new Uint8Array(n.byteLength),c.initSegment.set(n),c.data=new Uint8Array(this.pendingBytes),a=0;a=this.numberOfTracks&&(this.trigger("done"),this.emittedTracks=0);},dt.prototype.setRemux=function(e){this.remuxTracks=e;},(ut=function(e){var t,i,n=this,r=!0;ut.prototype.init.call(this),e=e||{},this.baseMediaDecodeTime=e.baseMediaDecodeTime||0,this.transmuxPipeline_={},this.setupAacPipeline=function(){var r={};this.transmuxPipeline_=r,r.type="aac",r.metadataStream=new Xe.MetadataStream,r.aacStream=new lt,r.audioTimestampRolloverStream=new Xe.TimestampRolloverStream("audio"),r.timedMetadataTimestampRolloverStream=new Xe.TimestampRolloverStream("timed-metadata"),r.adtsStream=new $e,r.coalesceStream=new dt(e,r.metadataStream),r.headOfPipeline=r.aacStream,r.aacStream.pipe(r.audioTimestampRolloverStream).pipe(r.adtsStream),r.aacStream.pipe(r.timedMetadataTimestampRolloverStream).pipe(r.metadataStream).pipe(r.coalesceStream),r.metadataStream.on("timestamp",(function(e){r.aacStream.setTimestamp(e.timeStamp);})),r.aacStream.on("data",(function(a){"timed-metadata"!==a.type&&"audio"!==a.type||r.audioSegmentStream||(i=i||{timelineStartInfo:{baseMediaDecodeTime:n.baseMediaDecodeTime},codec:"adts",type:"audio"},r.coalesceStream.numberOfTracks++,r.audioSegmentStream=new ot(i,e),r.audioSegmentStream.on("timingInfo",n.trigger.bind(n,"audioTimingInfo")),r.adtsStream.pipe(r.audioSegmentStream).pipe(r.coalesceStream),n.trigger("trackinfo",{hasAudio:!!i,hasVideo:!!t}));})),r.coalesceStream.on("data",this.trigger.bind(this,"data")),r.coalesceStream.on("done",this.trigger.bind(this,"done"));},this.setupTsPipeline=function(){var r={};this.transmuxPipeline_=r,r.type="ts",r.metadataStream=new Xe.MetadataStream,r.packetStream=new Xe.TransportPacketStream,r.parseStream=new Xe.TransportParseStream,r.elementaryStream=new Xe.ElementaryStream,r.timestampRolloverStream=new Xe.TimestampRolloverStream,r.adtsStream=new $e,r.h264Stream=new ft,r.captionStream=new Xe.CaptionStream(e),r.coalesceStream=new dt(e,r.metadataStream),r.headOfPipeline=r.packetStream,r.packetStream.pipe(r.parseStream).pipe(r.elementaryStream).pipe(r.timestampRolloverStream),r.timestampRolloverStream.pipe(r.h264Stream),r.timestampRolloverStream.pipe(r.adtsStream),r.timestampRolloverStream.pipe(r.metadataStream).pipe(r.coalesceStream),r.h264Stream.pipe(r.captionStream).pipe(r.coalesceStream),r.elementaryStream.on("data",(function(a){var s;if("metadata"===a.type){for(s=a.tracks.length;s--;)t||"video"!==a.tracks[s].type?i||"audio"!==a.tracks[s].type||((i=a.tracks[s]).timelineStartInfo.baseMediaDecodeTime=n.baseMediaDecodeTime):(t=a.tracks[s]).timelineStartInfo.baseMediaDecodeTime=n.baseMediaDecodeTime;t&&!r.videoSegmentStream&&(r.coalesceStream.numberOfTracks++,r.videoSegmentStream=new st(t,e),r.videoSegmentStream.on("timelineStartInfo",(function(t){i&&!e.keepOriginalTimestamps&&(i.timelineStartInfo=t,r.audioSegmentStream.setEarliestDts(t.dts-n.baseMediaDecodeTime));})),r.videoSegmentStream.on("processedGopsInfo",n.trigger.bind(n,"gopInfo")),r.videoSegmentStream.on("segmentTimingInfo",n.trigger.bind(n,"videoSegmentTimingInfo")),r.videoSegmentStream.on("baseMediaDecodeTime",(function(e){i&&r.audioSegmentStream.setVideoBaseMediaDecodeTime(e);})),r.videoSegmentStream.on("timingInfo",n.trigger.bind(n,"videoTimingInfo")),r.h264Stream.pipe(r.videoSegmentStream).pipe(r.coalesceStream)),i&&!r.audioSegmentStream&&(r.coalesceStream.numberOfTracks++,r.audioSegmentStream=new ot(i,e),r.audioSegmentStream.on("timingInfo",n.trigger.bind(n,"audioTimingInfo")),r.audioSegmentStream.on("segmentTimingInfo",n.trigger.bind(n,"audioSegmentTimingInfo")),r.adtsStream.pipe(r.audioSegmentStream).pipe(r.coalesceStream)),n.trigger("trackinfo",{hasAudio:!!i,hasVideo:!!t});}})),r.coalesceStream.on("data",this.trigger.bind(this,"data")),r.coalesceStream.on("id3Frame",(function(e){e.dispatchType=r.metadataStream.dispatchType,n.trigger("id3Frame",e);})),r.coalesceStream.on("caption",this.trigger.bind(this,"caption")),r.coalesceStream.on("done",this.trigger.bind(this,"done"));},this.setBaseMediaDecodeTime=function(n){var r=this.transmuxPipeline_;e.keepOriginalTimestamps||(this.baseMediaDecodeTime=n),i&&(i.timelineStartInfo.dts=void 0,i.timelineStartInfo.pts=void 0,he(i),r.audioTimestampRolloverStream&&r.audioTimestampRolloverStream.discontinuity()),t&&(r.videoSegmentStream&&(r.videoSegmentStream.gopCache_=[]),t.timelineStartInfo.dts=void 0,t.timelineStartInfo.pts=void 0,he(t),r.captionStream.reset()),r.timestampRolloverStream&&r.timestampRolloverStream.discontinuity();},this.setAudioAppendStart=function(e){i&&this.transmuxPipeline_.audioSegmentStream.setAudioAppendStart(e);},this.setRemux=function(t){var i=this.transmuxPipeline_;e.remux=t,i&&i.coalesceStream&&i.coalesceStream.setRemux(t);},this.alignGopsWith=function(e){t&&this.transmuxPipeline_.videoSegmentStream&&this.transmuxPipeline_.videoSegmentStream.alignGopsWith(e);},this.push=function(e){if(r){var t=pt(e);t&&"aac"!==this.transmuxPipeline_.type?this.setupAacPipeline():t||"ts"===this.transmuxPipeline_.type||this.setupTsPipeline(),r=!1;}this.transmuxPipeline_.headOfPipeline.push(e);},this.flush=function(){r=!0,this.transmuxPipeline_.headOfPipeline.flush();},this.endTimeline=function(){this.transmuxPipeline_.headOfPipeline.endTimeline();},this.reset=function(){this.transmuxPipeline_.headOfPipeline&&this.transmuxPipeline_.headOfPipeline.reset();},this.resetCaptions=function(){this.transmuxPipeline_.captionStream&&this.transmuxPipeline_.captionStream.reset();};}).prototype=new H;var yt,_t={Transmuxer:ut,VideoSegmentStream:st,AudioSegmentStream:ot,AUDIO_PROPERTIES:ht,VIDEO_PROPERTIES:ct,generateSegmentTimingInfo:gt},vt=function(e){return e>>>0},Tt=function(e){var t="";return t+=String.fromCharCode(e[0]),t+=String.fromCharCode(e[1]),(t+=String.fromCharCode(e[2]))+String.fromCharCode(e[3])},bt=vt,St=function e(t,i){var n,r,a,s,o,u=[];if(!i.length)return null;for(n=0;n1?n+r:t.byteLength,a===i[0]&&(1===i.length?u.push(t.subarray(n+8,s)):(o=e(t.subarray(n+8,s),i.slice(1))).length&&(u=u.concat(o))),n=s;return u},It=vt,Et=function(e){return {isLeading:(12&e[0])>>>2,dependsOn:3&e[0],isDependedOn:(192&e[1])>>>6,hasRedundancy:(48&e[1])>>>4,paddingValue:(14&e[1])>>>1,isNonSyncSample:1&e[1],degradationPriority:e[2]<<8|e[3]}},wt=function(e){for(var t,i,n=e.byteLength,r=[],a=1;a0?function(e){var t={version:e[0],flags:new Uint8Array(e.subarray(1,4)),baseMediaDecodeTime:It(e[4]<<24|e[5]<<16|e[6]<<8|e[7])};return 1===t.version&&(t.baseMediaDecodeTime*=Math.pow(2,32),t.baseMediaDecodeTime+=It(e[8]<<24|e[9]<<16|e[10]<<8|e[11])),t}(T[0]).baseMediaDecodeTime:0,S=St(g,["trun"]);t===v&&S.length>0&&(i=function(e,t,i){var n,r,a,s,o=new DataView(e.buffer,e.byteOffset,e.byteLength),u=[];for(r=0;r+40;){var u=t.shift();this.parse(u,a,s);}return null!==(o=function(e,t,i){return null===t?null:{seiNals:Pt(e,t)[t],timescale:i}}(e,i,n))&&o.seiNals?(this.pushNals(o.seiNals),this.flushStream(),r):null},this.pushNals=function(t){if(!this.isInitialized()||!t||0===t.length)return null;t.forEach((function(t){e.push(t);}));},this.flushStream=function(){if(!this.isInitialized())return null;a?e.partialFlush():e.flush();},this.clearParsedCaptions=function(){r.captions=[],r.captionStreams={};},this.resetCaptionStream=function(){if(!this.isInitialized())return null;e.reset();},this.clearAllCaptions=function(){this.clearParsedCaptions(),this.resetCaptionStream();},this.reset=function(){t=[],i=null,n=null,r?this.clearParsedCaptions():r={captions:[],captionStreams:{}},this.resetCaptionStream();},this.reset();},kt=vt,xt=function(e){return ("00"+e.toString(16)).slice(-2)},Ct=function(e,t){var i,n,r;return i=St(t,["moof","traf"]),n=[].concat.apply([],i.map((function(t){return St(t,["tfhd"]).map((function(i){var n,r,a;return n=kt(i[4]<<24|i[5]<<16|i[6]<<8|i[7]),r=e[n]||9e4,(a="number"!=typeof(a=St(t,["tfdt"]).map((function(e){var t,i;return t=e[0],i=kt(e[4]<<24|e[5]<<16|e[6]<<8|e[7]),1===t&&(i*=Math.pow(2,32),i+=kt(e[8]<<24|e[9]<<16|e[10]<<8|e[11])),i}))[0])||isNaN(a)?1/0:a)/r}))}))),r=Math.min.apply(null,n),isFinite(r)?r:0},Ut=function(e){var t=St(e,["moov","trak"]),i=[];return t.forEach((function(e){var t,n,r={},a=St(e,["tkhd"])[0];a&&(n=(t=new DataView(a.buffer,a.byteOffset,a.byteLength)).getUint8(0),r.id=0===n?t.getUint32(12):t.getUint32(20));var s=St(e,["mdia","hdlr"])[0];if(s){var o=Tt(s.subarray(8,12));r.type="vide"===o?"video":"soun"===o?"audio":o;}var u=St(e,["mdia","minf","stbl","stsd"])[0];if(u){var d=u.subarray(8);r.codec=Tt(d.subarray(4,8));var l,h=St(d,[r.codec])[0];h&&(/^[a-z]vc[1-9]$/i.test(r.codec)?(l=h.subarray(78),"avcC"===Tt(l.subarray(4,8))&&l.length>11?(r.codec+=".",r.codec+=xt(l[9]),r.codec+=xt(l[10]),r.codec+=xt(l[11])):r.codec="avc1.4d400d"):/^mp4[a,v]$/i.test(r.codec)?(l=h.subarray(28),"esds"===Tt(l.subarray(4,8))&&l.length>20&&0!==l[19]?(r.codec+="."+xt(l[19]),r.codec+="."+xt(l[20]>>>2&63).replace(/^0/,"")):r.codec="mp4a.40.2"):r.codec=r.codec.toLowerCase());}var c=St(e,["mdia","mdhd"])[0];c&&(r.timescale=yt(c)),i.push(r);})),i},Dt=(yt=function(e){var t=0===e[0]?12:20;return kt(e[t]<<24|e[t+1]<<16|e[t+2]<<8|e[t+3])},function(e){var t=31&e[1];return (t<<=8)|e[2]}),Rt=function(e){return !!(64&e[1])},Mt=function(e){var t=0;return (48&e[3])>>>4>1&&(t+=e[4]+1),t},Bt=function(e){switch(e){case 5:return "slice_layer_without_partitioning_rbsp_idr";case 6:return "sei_rbsp";case 7:return "seq_parameter_set_rbsp";case 8:return "pic_parameter_set_rbsp";case 9:return "access_unit_delimiter_rbsp";default:return null}},Nt={parseType:function(e,t){var i=Dt(e);return 0===i?"pat":i===t?"pmt":t?"pes":null},parsePat:function(e){var t=Rt(e),i=4+Mt(e);return t&&(i+=e[i]+1),(31&e[i+10])<<8|e[i+11]},parsePmt:function(e){var t={},i=Rt(e),n=4+Mt(e);if(i&&(n+=e[n]+1),1&e[n+5]){var r;r=3+((15&e[n+1])<<8|e[n+2])-4;for(var a=12+((15&e[n+10])<<8|e[n+11]);a=e.byteLength)return null;var i,n=null;return 192&(i=e[t+7])&&((n={}).pts=(14&e[t+9])<<27|(255&e[t+10])<<20|(254&e[t+11])<<12|(255&e[t+12])<<5|(254&e[t+13])>>>3,n.pts*=4,n.pts+=(6&e[t+13])>>>1,n.dts=n.pts,64&i&&(n.dts=(14&e[t+14])<<27|(255&e[t+15])<<20|(254&e[t+16])<<12|(255&e[t+17])<<5|(254&e[t+18])>>>3,n.dts*=4,n.dts+=(6&e[t+18])>>>1)),n},videoPacketContainsKeyFrame:function(e){for(var t=4+Mt(e),i=e.subarray(t),n=0,r=0,a=!1;r3&&"slice_layer_without_partitioning_rbsp_idr"===Bt(31&i[r+3])&&(a=!0),a}},Ft=Ce,qt={};qt.ts=Nt,qt.aac=at;var Ht=re,Gt=188,Wt=71,Vt=function(e,t,i){for(var n,r,a,s,o=0,u=Gt,d=!1;u<=e.byteLength;)if(e[o]!==Wt||e[u]!==Wt&&u!==e.byteLength)o++,u++;else {switch(n=e.subarray(o,u),qt.ts.parseType(n,t.pid)){case"pes":r=qt.ts.parsePesType(n,t.table),a=qt.ts.parsePayloadUnitStartIndicator(n),"audio"===r&&a&&(s=qt.ts.parsePesTime(n))&&(s.type="audio",i.audio.push(s),d=!0);}if(d)break;o+=Gt,u+=Gt;}for(o=(u=e.byteLength)-Gt,d=!1;o>=0;)if(e[o]!==Wt||e[u]!==Wt&&u!==e.byteLength)o--,u--;else {switch(n=e.subarray(o,u),qt.ts.parseType(n,t.pid)){case"pes":r=qt.ts.parsePesType(n,t.table),a=qt.ts.parsePayloadUnitStartIndicator(n),"audio"===r&&a&&(s=qt.ts.parsePesTime(n))&&(s.type="audio",i.audio.push(s),d=!0);}if(d)break;o-=Gt,u-=Gt;}},jt=function(e,t,i){for(var n,r,a,s,o,u,d,l=0,h=Gt,c=!1,f={data:[],size:0};h=0;)if(e[l]!==Wt||e[h]!==Wt)l--,h--;else {switch(n=e.subarray(l,h),qt.ts.parseType(n,t.pid)){case"pes":r=qt.ts.parsePesType(n,t.table),a=qt.ts.parsePayloadUnitStartIndicator(n),"video"===r&&a&&(s=qt.ts.parsePesTime(n))&&(s.type="video",i.video.push(s),c=!0);}if(c)break;l-=Gt,h-=Gt;}},Xt=function(e,t){var i;return (i=qt.aac.isLikelyAacData(e)?function(e){for(var t,i=!1,n=0,r=null,a=null,s=0,o=0;e.length-o>=3;){switch(qt.aac.parseType(e,o)){case"timed-metadata":if(e.length-o<10){i=!0;break}if((s=qt.aac.parseId3TagSize(e,o))>e.length){i=!0;break}null===a&&(t=e.subarray(o,o+s),a=qt.aac.parseAacTimestamp(t)),o+=s;break;case"audio":if(e.length-o<7){i=!0;break}if((s=qt.aac.parseAdtsSize(e,o))>e.length){i=!0;break}null===r&&(t=e.subarray(o,o+s),r=qt.aac.parseSampleRate(t)),n++,o+=s;break;default:o++;}if(i)return null}if(null===r||null===a)return null;var u=Ht/r;return {audio:[{type:"audio",dts:a,pts:a},{type:"audio",dts:a+1024*n*u,pts:a+1024*n*u}]}}(e):function(e){var t={pid:null,table:null},i={};for(var n in function(e,t){for(var i,n=0,r=Gt;r0}(f)){t.isFmp4=!0;var p=t.map.tracks,m={isFmp4:!0,hasVideo:!!p.video,hasAudio:!!p.audio};p.audio&&p.audio.codec&&"enca"!==p.audio.codec&&(m.audioCodec=p.audio.codec),p.video&&p.video.codec&&"encv"!==p.video.codec&&(m.videoCodec=p.video.codec),p.video&&p.audio&&(m.isMuxed=!0),n(t,m);var g=function(e){h(t,{data:f,type:m.hasAudio&&!m.isMuxed?"audio":"video"}),e&&e.length&&u(t,e),c(null,t,{});};ci({action:"probeMp4StartTime",timescales:t.map.timescales,data:f,transmuxer:t.transmuxer,callback:function(e){var n=e.data,a=e.startTime;i=n.buffer,t.bytes=f=n,m.hasAudio&&!m.isMuxed&&r(t,"audio","start",a),m.hasVideo&&r(t,"video","start",a),p.video&&n.byteLength&&t.transmuxer?ci({action:"pushMp4Captions",endAction:"mp4Captions",transmuxer:t.transmuxer,data:f,timescales:t.map.timescales,trackIds:[p.video.id],callback:function(e){i=e.data.buffer,t.bytes=f=e.data,g(e.captions);}}):g();}});}else if(t.transmuxer){if(void 0===t.container&&(t.container=Yt(f)),"ts"!==t.container&&"aac"!==t.container)return n(t,{hasAudio:!1,hasVideo:!1}),void c(null,t,{});yi({segment:t,bytes:i,trackInfoFn:n,timingInfoFn:r,videoSegmentTimingInfoFn:a,audioSegmentTimingInfoFn:s,id3Fn:o,captionsFn:u,isEndOfTimeline:d,endedTimelineFn:l,dataFn:h,doneFn:c});}else c(null,t,{});},vi=function(e){var t=e.xhr,i=e.xhrOptions,n=e.decryptionWorker,r=e.segment,a=e.abortFn,s=e.progressFn,o=e.trackInfoFn,d=e.timingInfoFn,l=e.videoSegmentTimingInfoFn,h=e.audioSegmentTimingInfoFn,c=e.id3Fn,f=e.captionsFn,p=e.isEndOfTimeline,m=e.endedTimelineFn,g=e.dataFn,y=e.doneFn,_=[],v=function(e){var t=e.activeXhrs,i=e.decryptionWorker,n=e.trackInfoFn,r=e.timingInfoFn,a=e.videoSegmentTimingInfoFn,s=e.audioSegmentTimingInfoFn,o=e.id3Fn,u=e.captionsFn,d=e.isEndOfTimeline,l=e.endedTimelineFn,h=e.dataFn,c=e.doneFn,f=0,p=!1;return function(e,m){if(!p){if(e)return p=!0,mi(t),c(e,m);if((f+=1)===t.length){if(m.endOfAllRequests=Date.now(),m.encryptedBytes)return function(e){var t,i=e.decryptionWorker,n=e.segment,r=e.trackInfoFn,a=e.timingInfoFn,s=e.videoSegmentTimingInfoFn,o=e.audioSegmentTimingInfoFn,u=e.id3Fn,d=e.captionsFn,l=e.isEndOfTimeline,h=e.endedTimelineFn,c=e.dataFn,f=e.doneFn;i.addEventListener("message",(function e(t){if(t.data.source===n.requestId){i.removeEventListener("message",e);var p=t.data.decrypted;n.bytes=new Uint8Array(p.bytes,p.byteOffset,p.byteLength),_i({segment:n,bytes:n.bytes,trackInfoFn:r,timingInfoFn:a,videoSegmentTimingInfoFn:s,audioSegmentTimingInfoFn:o,id3Fn:u,captionsFn:d,isEndOfTimeline:l,endedTimelineFn:h,dataFn:c,doneFn:f});}})),t=n.key.bytes.slice?n.key.bytes.slice():new Uint32Array(Array.prototype.slice.call(n.key.bytes)),i.postMessage(Re({source:n.requestId,encrypted:n.encryptedBytes,key:t,iv:n.key.iv}),[n.encryptedBytes.buffer,t.buffer]);}({decryptionWorker:i,segment:m,trackInfoFn:n,timingInfoFn:r,videoSegmentTimingInfoFn:a,audioSegmentTimingInfoFn:s,id3Fn:o,captionsFn:u,isEndOfTimeline:d,endedTimelineFn:l,dataFn:h,doneFn:c});_i({segment:m,bytes:m.bytes,trackInfoFn:n,timingInfoFn:r,videoSegmentTimingInfoFn:a,audioSegmentTimingInfoFn:s,id3Fn:o,captionsFn:u,isEndOfTimeline:d,endedTimelineFn:l,dataFn:h,doneFn:c});}}}}({activeXhrs:_,decryptionWorker:n,trackInfoFn:o,timingInfoFn:d,videoSegmentTimingInfoFn:l,audioSegmentTimingInfoFn:h,id3Fn:c,captionsFn:f,isEndOfTimeline:p,endedTimelineFn:m,dataFn:g,doneFn:y});if(r.key&&!r.key.bytes){var T=t(u.default.mergeOptions(i,{uri:r.key.resolvedUri,responseType:"arraybuffer"}),function(e,t){return function(i,n){var r=n.response,a=gi(i,n);if(a)return t(a,e);if(16!==r.byteLength)return t({status:n.status,message:"Invalid HLS key at URL: "+n.uri,code:2,xhr:n},e);var s=new DataView(r);return e.key.bytes=new Uint32Array([s.getUint32(0),s.getUint32(4),s.getUint32(8),s.getUint32(12)]),t(null,e)}}(r,v));_.push(T);}if(r.map&&!r.map.bytes){var b=t(u.default.mergeOptions(i,{uri:r.map.resolvedUri,responseType:"arraybuffer",headers:Pe(r.map)}),function(e){var t=e.segment,i=e.finishProcessingFn;return function(e,n){var r=n.response,a=gi(e,n);if(a)return i(a,t);if(0===r.byteLength)return i({status:n.status,message:"Empty HLS segment content at URL: "+n.uri,code:2,xhr:n},t);t.map.bytes=new Uint8Array(n.response);var s=Yt(t.map.bytes);if("mp4"!==s)return i({status:n.status,message:"Found unsupported "+(s||"unknown")+" container for initialization segment at URL: "+n.uri,code:2,internal:!0,xhr:n},t);ci({action:"probeMp4Tracks",data:t.map.bytes,transmuxer:t.transmuxer,callback:function(e){var n=e.tracks,r=e.data;return t.map.bytes=r,n.forEach((function(e){t.map.tracks=t.map.tracks||{},t.map.tracks[e.type]||(t.map.tracks[e.type]=e,"number"==typeof e.id&&e.timescale&&(t.map.timescales=t.map.timescales||{},t.map.timescales[e.id]=e.timescale));})),i(null,t)}});}}({segment:r,finishProcessingFn:v}));_.push(b);}var S=u.default.mergeOptions(i,{uri:r.part&&r.part.resolvedUri||r.resolvedUri,responseType:"arraybuffer",headers:Pe(r)}),I=t(S,function(e){var t=e.segment,i=e.finishProcessingFn,n=e.responseType;return function(e,r){var a=r.response,s=gi(e,r);if(s)return i(s,t);var o="arraybuffer"!==n&&r.responseText?function(e){for(var t=new Uint8Array(new ArrayBuffer(e.length)),i=0;i1)return Ti("multiple "+e+" codecs found as attributes: "+t[e].join(", ")+". Setting playlist codecs to null so that we wait for mux.js to probe segments for real codecs."),void(t[e]=null);t[e]=t[e][0];})),t},Ii=function(e){var t=0;return e.audio&&t++,e.video&&t++,t},Ei=function(e,t){var i=t.attributes||{},n=Si(function(e){var t=e.attributes||{};if(t.CODECS)return ne(t.CODECS)}(t)||[]);if(bi(e,t)&&!n.audio&&!function(e,t){if(!bi(e,t))return !0;var i=t.attributes||{},n=e.mediaGroups.AUDIO[i.AUDIO];for(var r in n)if(!n[r].uri&&!n[r].playlists)return !0;return !1}(e,t)){var r=Si(function(e,t){if(!e.mediaGroups.AUDIO||!t)return null;var i=e.mediaGroups.AUDIO[t];if(!i)return null;for(var n in i){var r=i[n];if(r.default&&r.playlists)return ne(r.playlists[0].attributes.CODECS)}return null}(e,i.AUDIO)||[]);r.audio&&(n.audio=r.audio);}return n},wi=_("PlaylistSelector"),Ai=function(e){if(e&&e.playlist){var t=e.playlist;return JSON.stringify({id:t.id,bandwidth:e.bandwidth,width:e.width,height:e.height,codecs:t.attributes&&t.attributes.CODECS||""})}},Li=function(e,t){if(!e)return "";var i=o.default.getComputedStyle(e);return i?i[t]:""},Pi=function(e,t){var i=e.slice();e.sort((function(e,n){var r=t(e,n);return 0===r?i.indexOf(e)-i.indexOf(n):r}));},Oi=function(e,t){var i,n;return e.attributes.BANDWIDTH&&(i=e.attributes.BANDWIDTH),i=i||o.default.Number.MAX_VALUE,t.attributes.BANDWIDTH&&(n=t.attributes.BANDWIDTH),i-(n||o.default.Number.MAX_VALUE)},ki=function(e,t,i,n,r,a){if(e){var s={bandwidth:t,width:i,height:n,limitRenditionByPlayerDimensions:r},u=e.playlists;Ie.isAudioOnly(e)&&(u=a.getAudioTrackPlaylists_(),s.audioOnly=!0);var d=u.map((function(e){var t=e.attributes&&e.attributes.RESOLUTION&&e.attributes.RESOLUTION.width,i=e.attributes&&e.attributes.RESOLUTION&&e.attributes.RESOLUTION.height;return {bandwidth:e.attributes&&e.attributes.BANDWIDTH||o.default.Number.MAX_VALUE,width:t,height:i,playlist:e}}));Pi(d,(function(e,t){return e.bandwidth-t.bandwidth}));var l=(d=d.filter((function(e){return !Ie.isIncompatible(e.playlist)}))).filter((function(e){return Ie.isEnabled(e.playlist)}));l.length||(l=d.filter((function(e){return !Ie.isDisabled(e.playlist)})));var h=l.filter((function(e){return e.bandwidth*ii.BANDWIDTH_VARIANCEi||e.height>n}))).filter((function(e){return e.width===_[0].width&&e.height===_[0].height})),c=v[v.length-1],T=v.filter((function(e){return e.bandwidth===c.bandwidth}))[0]);var S=T||b||f||l[0]||d[0];if(S&&S.playlist){var I="sortedPlaylistReps";return T?I="resolutionPlusOneRep":b?I="resolutionBestRep":f?I="bandwidthBestRep":l[0]&&(I="enabledPlaylistReps"),wi("choosing "+Ai(S)+" using "+I+" with options",s),S.playlist}return wi("could not choose a playlist with options",s),null}},xi=function(){var e=this.useDevicePixelRatio&&o.default.devicePixelRatio||1;return ki(this.playlists.master,this.systemBandwidth,parseInt(Li(this.tech_.el(),"width"),10)*e,parseInt(Li(this.tech_.el(),"height"),10)*e,this.limitRenditionByPlayerDimensions,this.masterPlaylistController_)},Ci=function(e,t,i){var n,r;if(i&&i.cues)for(n=i.cues.length;n--;)(r=i.cues[n]).startTime>=e&&r.endTime<=t&&i.removeCue(r);},Ui=9e4,Di=Ui,Ri=(function(e){return "number"==typeof e&&isFinite(e)}),Mi=1/60,Bi=function(e){var t=e.startOfSegment,i=e.duration,n=e.segment,r=n.start,a=n.end,s=n.parts,o=e.playlist,u=o.mediaSequence,d=o.id,l=o.segments,h=void 0===l?[]:l,c=e.mediaIndex,f=e.partIndex,p=e.timeline,m=h.length-1,g="mediaIndex/partIndex increment";return e.getMediaInfoForTime?g="getMediaInfoForTime ("+e.getMediaInfoForTime+")":e.isSyncRequest&&(g="getSyncSegmentCandidate (isSyncRequest)"),(e.segment.uri?"segment":"pre-segment")+" ["+c+"/"+m+"]"+(f?" part ["+f+"/"+(s.length-1)+"]":"")+" mediaSequenceNumber ["+u+"/"+(u+m)+"] start/end ["+r+" => "+a+"] startOfSegment ["+t+"] duration ["+i+"] timeline ["+p+"] selected by ["+g+"] playlist ["+d+"]"},Ni=function(e){return e+"TimingInfo"},Fi=function(e){var t=e.timelineChangeController,i=e.currentTimeline,n=e.segmentTimeline,r=e.loaderType,a=e.audioDisabled;if(i===n)return !1;if("audio"===r){var s=t.lastTimelineChange({type:"main"});return !s||s.to!==n}if("main"===r&&a){var o=t.pendingTimelineChange({type:"audio"});return !o||o.to!==n}return !1},qi=function(e){var t=e.segmentDuration,i=e.maxDuration;return !!t&&Math.round(t)>i+j},Hi=function(e){function t(t,i){var n;if(n=e.call(this)||this,!t)throw new TypeError("Initialization settings are required");if("function"!=typeof t.currentTime)throw new TypeError("No currentTime getter specified");if(!t.mediaSource)throw new TypeError("No MediaSource specified");return n.bandwidth=t.bandwidth,n.throughput={rate:0,count:0},n.roundTrip=NaN,n.resetStats_(),n.mediaIndex=null,n.partIndex=null,n.hasPlayed_=t.hasPlayed,n.currentTime_=t.currentTime,n.seekable_=t.seekable,n.seeking_=t.seeking,n.duration_=t.duration,n.mediaSource_=t.mediaSource,n.vhs_=t.vhs,n.loaderType_=t.loaderType,n.currentMediaInfo_=void 0,n.startingMediaInfo_=void 0,n.segmentMetadataTrack_=t.segmentMetadataTrack,n.goalBufferLength_=t.goalBufferLength,n.sourceType_=t.sourceType,n.sourceUpdater_=t.sourceUpdater,n.inbandTextTracks_=t.inbandTextTracks,n.state_="INIT",n.timelineChangeController_=t.timelineChangeController,n.shouldSaveSegmentTimingInfo_=!0,n.parse708captions_=t.parse708captions,n.checkBufferTimeout_=null,n.error_=void 0,n.currentTimeline_=-1,n.pendingSegment_=null,n.xhrOptions_=null,n.pendingSegments_=[],n.audioDisabled_=!1,n.isPendingTimestampOffset_=!1,n.gopBuffer_=[],n.timeMapping_=0,n.safeAppend_=u.default.browser.IE_VERSION>=11,n.appendInitSegment_={audio:!0,video:!0},n.playlistOfLastInitSegment_={audio:null,video:null},n.callQueue_=[],n.loadQueue_=[],n.metadataQueue_={id3:[],caption:[]},n.waitingOnRemove_=!1,n.quotaExceededErrorRetryTimeout_=null,n.activeInitSegmentId_=null,n.initSegments_={},n.cacheEncryptionKeys_=t.cacheEncryptionKeys,n.keyCache_={},n.decrypter_=t.decrypter,n.syncController_=t.syncController,n.syncPoint_={segmentIndex:0,time:0},n.transmuxer_=n.createTransmuxer_(),n.triggerSyncInfoUpdate_=function(){return n.trigger("syncinfoupdate")},n.syncController_.on("syncinfoupdate",n.triggerSyncInfoUpdate_),n.mediaSource_.addEventListener("sourceopen",(function(){n.isEndOfStream_()||(n.ended_=!1);})),n.fetchAtBuffer_=!1,n.logger_=_("SegmentLoader["+n.loaderType_+"]"),Object.defineProperty(l(n),"state",{get:function(){return this.state_},set:function(e){e!==this.state_&&(this.logger_(this.state_+" -> "+e),this.state_=e,this.trigger("statechange"));}}),n.sourceUpdater_.on("ready",(function(){n.hasEnoughInfoToAppend_()&&n.processCallQueue_();})),"main"===n.loaderType_&&n.timelineChangeController_.on("pendingtimelinechange",(function(){n.hasEnoughInfoToAppend_()&&n.processCallQueue_();})),"audio"===n.loaderType_&&n.timelineChangeController_.on("timelinechange",(function(){n.hasEnoughInfoToLoad_()&&n.processLoadQueue_(),n.hasEnoughInfoToAppend_()&&n.processCallQueue_();})),n}c(t,e);var i=t.prototype;return i.createTransmuxer_=function(){return function(e){var t=new oi;t.currentTransmux=null,t.transmuxQueue=[];var i=t.terminate;return t.terminate=function(){return t.currentTransmux=null,t.transmuxQueue.length=0,i.call(t)},t.postMessage({action:"init",options:e}),t}({remux:!1,alignGopsAtEnd:this.safeAppend_,keepOriginalTimestamps:!0,parse708captions:this.parse708captions_})},i.resetStats_=function(){this.mediaBytesTransferred=0,this.mediaRequests=0,this.mediaRequestsAborted=0,this.mediaRequestsTimedout=0,this.mediaRequestsErrored=0,this.mediaTransferDuration=0,this.mediaSecondsLoaded=0;},i.dispose=function(){this.trigger("dispose"),this.state="DISPOSED",this.pause(),this.abort_(),this.transmuxer_&&this.transmuxer_.terminate(),this.resetStats_(),this.checkBufferTimeout_&&o.default.clearTimeout(this.checkBufferTimeout_),this.syncController_&&this.triggerSyncInfoUpdate_&&this.syncController_.off("syncinfoupdate",this.triggerSyncInfoUpdate_),this.off();},i.setAudio=function(e){this.audioDisabled_=!e,e?this.appendInitSegment_.audio=!0:this.sourceUpdater_.removeAudio(0,this.duration_());},i.abort=function(){"WAITING"===this.state?(this.abort_(),this.state="READY",this.paused()||this.monitorBuffer_()):this.pendingSegment_&&(this.pendingSegment_=null);},i.abort_=function(){this.pendingSegment_&&this.pendingSegment_.abortRequests&&this.pendingSegment_.abortRequests(),this.pendingSegment_=null,this.callQueue_=[],this.loadQueue_=[],this.metadataQueue_.id3=[],this.metadataQueue_.caption=[],this.timelineChangeController_.clearPendingTimelineChange(this.loaderType_),this.waitingOnRemove_=!1,o.default.clearTimeout(this.quotaExceededErrorRetryTimeout_),this.quotaExceededErrorRetryTimeout_=null;},i.checkForAbort_=function(e){return "APPENDING"!==this.state||this.pendingSegment_?!this.pendingSegment_||this.pendingSegment_.requestId!==e:(this.state="READY",!0)},i.error=function(e){return void 0!==e&&(this.logger_("error occurred:",e),this.error_=e),this.pendingSegment_=null,this.error_},i.endOfStream=function(){this.ended_=!0,this.transmuxer_&&hi(this.transmuxer_),this.gopBuffer_.length=0,this.pause(),this.trigger("ended");},i.buffered_=function(){if(!this.sourceUpdater_||!this.startingMediaInfo_)return u.default.createTimeRanges();if("main"===this.loaderType_){var e=this.startingMediaInfo_,t=e.hasAudio,i=e.hasVideo,n=e.isMuxed;if(i&&t&&!this.audioDisabled_&&!n)return this.sourceUpdater_.buffered();if(i)return this.sourceUpdater_.videoBuffered()}return this.sourceUpdater_.audioBuffered()},i.initSegmentForMap=function(e,t){if(void 0===t&&(t=!1),!e)return null;var i=Me(e),n=this.initSegments_[i];return t&&!n&&e.bytes&&(this.initSegments_[i]=n={resolvedUri:e.resolvedUri,byterange:e.byterange,bytes:e.bytes,tracks:e.tracks,timescales:e.timescales}),n||e},i.segmentKey=function(e,t){if(void 0===t&&(t=!1),!e)return null;var i=Be(e),n=this.keyCache_[i];this.cacheEncryptionKeys_&&t&&!n&&e.bytes&&(this.keyCache_[i]=n={resolvedUri:e.resolvedUri,bytes:e.bytes});var r={resolvedUri:(n||e).resolvedUri};return n&&(r.bytes=n.bytes),r},i.couldBeginLoading_=function(){return this.playlist_&&!this.paused()},i.load=function(){if(this.monitorBuffer_(),this.playlist_)return "INIT"===this.state&&this.couldBeginLoading_()?this.init_():void(!this.couldBeginLoading_()||"READY"!==this.state&&"INIT"!==this.state||(this.state="READY"))},i.init_=function(){return this.state="READY",this.resetEverything(),this.monitorBuffer_()},i.playlist=function(e,t){if(void 0===t&&(t={}),e){var i=this.playlist_,n=this.pendingSegment_;this.playlist_=e,this.xhrOptions_=t,"INIT"===this.state&&(e.syncInfo={mediaSequence:e.mediaSequence,time:0},"main"===this.loaderType_&&this.syncController_.setDateTimeMappingForStart(e));var r=null;if(i&&(i.id?r=i.id:i.uri&&(r=i.uri)),this.logger_("playlist update ["+r+" => "+(e.id||e.uri)+"]"),this.trigger("syncinfoupdate"),"INIT"===this.state&&this.couldBeginLoading_())return this.init_();if(!i||i.uri!==e.uri)return null!==this.mediaIndex&&this.resyncLoader(),this.currentMediaInfo_=void 0,void this.trigger("playlistupdate");var a=e.mediaSequence-i.mediaSequence;if(this.logger_("live window shift ["+a+"]"),null!==this.mediaIndex)if(this.mediaIndex-=a,this.mediaIndex<0)this.mediaIndex=null,this.partIndex=null;else {var s=this.playlist_.segments[this.mediaIndex];if(this.partIndex&&(!s.parts||!s.parts.length||!s.parts[this.partIndex])){var o=this.mediaIndex;this.logger_("currently processing part (index "+this.partIndex+") no longer exists."),this.resetLoader(),this.mediaIndex=o;}}n&&(n.mediaIndex-=a,n.mediaIndex<0?(n.mediaIndex=null,n.partIndex=null):(n.mediaIndex>=0&&(n.segment=e.segments[n.mediaIndex]),n.partIndex>=0&&n.segment.parts&&(n.part=n.segment.parts[n.partIndex]))),this.syncController_.saveExpiredSegmentInfo(i,e);}},i.pause=function(){this.checkBufferTimeout_&&(o.default.clearTimeout(this.checkBufferTimeout_),this.checkBufferTimeout_=null);},i.paused=function(){return null===this.checkBufferTimeout_},i.resetEverything=function(e){this.ended_=!1,this.appendInitSegment_={audio:!0,video:!0},this.resetLoader(),this.remove(0,1/0,e),this.transmuxer_&&this.transmuxer_.postMessage({action:"clearAllMp4Captions"});},i.resetLoader=function(){this.fetchAtBuffer_=!1,this.resyncLoader();},i.resyncLoader=function(){this.transmuxer_&&hi(this.transmuxer_),this.mediaIndex=null,this.partIndex=null,this.syncPoint_=null,this.isPendingTimestampOffset_=!1,this.callQueue_=[],this.loadQueue_=[],this.metadataQueue_.id3=[],this.metadataQueue_.caption=[],this.abort(),this.transmuxer_&&this.transmuxer_.postMessage({action:"clearParsedMp4Captions"});},i.remove=function(e,t,i,n){if(void 0===i&&(i=function(){}),void 0===n&&(n=!1),t===1/0&&(t=this.duration_()),t<=e)this.logger_("skipping remove because end ${end} is <= start ${start}");else if(this.sourceUpdater_&&this.startingMediaInfo_){var r=1,a=function(){0==--r&&i();};for(var s in !n&&this.audioDisabled_||(r++,this.sourceUpdater_.removeAudio(e,t,a)),(n||"main"===this.loaderType_)&&(this.gopBuffer_=function(e,t,i,n){for(var r=Math.ceil((t-n)*Di),a=Math.ceil((i-n)*Di),s=e.slice(),o=e.length;o--&&!(e[o].pts<=a););if(-1===o)return s;for(var u=o+1;u--&&!(e[u].pts<=r););return u=Math.max(u,0),s.splice(u,o-u+1),s}(this.gopBuffer_,e,t,this.timeMapping_),r++,this.sourceUpdater_.removeVideo(e,t,a)),this.inbandTextTracks_)Ci(e,t,this.inbandTextTracks_[s]);Ci(e,t,this.segmentMetadataTrack_),a();}else this.logger_("skipping remove because no source updater or starting media info");},i.monitorBuffer_=function(){this.checkBufferTimeout_&&o.default.clearTimeout(this.checkBufferTimeout_),this.checkBufferTimeout_=o.default.setTimeout(this.monitorBufferTick_.bind(this),1);},i.monitorBufferTick_=function(){"READY"===this.state&&this.fillBuffer_(),this.checkBufferTimeout_&&o.default.clearTimeout(this.checkBufferTimeout_),this.checkBufferTimeout_=o.default.setTimeout(this.monitorBufferTick_.bind(this),500);},i.fillBuffer_=function(){if(!this.sourceUpdater_.updating()){var e=this.chooseNextRequest_();e&&("number"==typeof e.timestampOffset&&(this.isPendingTimestampOffset_=!1,this.timelineChangeController_.pendingTimelineChange({type:this.loaderType_,from:this.currentTimeline_,to:e.timeline})),this.loadSegment_(e));}},i.isEndOfStream_=function(e,t,i){if(void 0===e&&(e=this.mediaIndex),void 0===t&&(t=this.playlist_),void 0===i&&(i=this.partIndex),!t||!this.mediaSource_)return !1;var n="number"==typeof e&&t.segments[e],r=e+1===t.segments.length,a=!n||!n.parts||i+1===n.parts.length;return t.endList&&"open"===this.mediaSource_.readyState&&r&&a},i.chooseNextRequest_=function(){var e=J(this.buffered_())||0,t=Math.max(0,e-this.currentTime_()),i=!this.hasPlayed_()&&t>=1,n=t>=this.goalBufferLength_(),r=this.playlist_.segments;if(!r.length||i||n)return null;this.syncPoint_=this.syncPoint_||this.syncController_.getSyncPoint(this.playlist_,this.duration_(),this.currentTimeline_,this.currentTime_());var a={partIndex:null,mediaIndex:null,startOfSegment:null,playlist:this.playlist_,isSyncRequest:Boolean(!this.syncPoint_)};if(a.isSyncRequest)a.mediaIndex=function(e,t){var i=(void 0===t?{}:t).segments,n=void 0===i?[]:i;if(-1===e)return 0;var r=n.reduce((function(t,i,n){return i.timeline===e&&t.push(n),t}),[]);return r.length?r[Math.min(r.length-1,1)]:Math.max(n.length-1,0)}(this.currentTimeline_,this.playlist_);else if(null!==this.mediaIndex){var s=r[this.mediaIndex],o="number"==typeof this.partIndex?this.partIndex:-1;a.startOfSegment=s.end?s.end:e,s.parts&&s.parts[o+1]?(a.mediaIndex=this.mediaIndex,a.partIndex=o+1):a.mediaIndex=this.mediaIndex+1;}else {var u=Ie.getMediaInfoForTime(this.playlist_,this.fetchAtBuffer_?e:this.currentTime_(),this.syncPoint_.segmentIndex,this.syncPoint_.time);a.getMediaInfoForTime=this.fetchAtBuffer_?"bufferedEnd":"currentTime",a.mediaIndex=u.mediaIndex,a.startOfSegment=u.startTime,a.partIndex=u.partIndex;}var d=r[a.mediaIndex],l=d&&"number"==typeof a.partIndex&&d.parts&&d.parts[a.partIndex];if(!d||"number"==typeof a.partIndex&&!l)return null;"number"!=typeof a.partIndex&&d.parts&&(a.partIndex=0);var h=this.mediaSource_&&"ended"===this.mediaSource_.readyState;return a.mediaIndex>=r.length-1&&h&&!this.seeking_()?null:this.generateSegmentInfo_(a)},i.generateSegmentInfo_=function(e){var t=e.playlist,i=e.mediaIndex,n=e.startOfSegment,r=e.isSyncRequest,a=e.partIndex,s=e.forceTimestampOffset,o=e.getMediaInfoForTime,u=t.segments[i],d="number"==typeof a&&u.parts[a],l={requestId:"segment-loader-"+Math.random(),uri:d&&d.resolvedUri||u.resolvedUri,mediaIndex:i,partIndex:d?a:null,isSyncRequest:r,startOfSegment:n,playlist:t,bytes:null,encryptedBytes:null,timestampOffset:null,timeline:u.timeline,duration:u.duration,segment:u,part:d,byteLength:0,transmuxer:this.transmuxer_,getMediaInfoForTime:o},h=void 0!==s?s:this.isPendingTimestampOffset_;l.timestampOffset=this.timestampOffsetForSegment_({segmentTimeline:u.timeline,currentTimeline:this.currentTimeline_,startOfSegment:n,buffered:this.buffered_(),overrideCheck:h});var c=J(this.sourceUpdater_.audioBuffered());return "number"==typeof c&&(l.audioAppendStart=c-this.sourceUpdater_.audioTimestampOffset()),this.sourceUpdater_.videoBuffered().length&&(l.gopsToAlignWith=function(e,t,i){if(null==t||!e.length)return [];var n,r=Math.ceil((t-i+3)*Di);for(n=0;nr);n++);return e.slice(n)}(this.gopBuffer_,this.currentTime_()-this.sourceUpdater_.videoTimestampOffset(),this.timeMapping_)),l},i.timestampOffsetForSegment_=function(e){return i=(t=e).segmentTimeline,n=t.currentTimeline,r=t.startOfSegment,a=t.buffered,t.overrideCheck||i!==n?i "+s+" for "+e),function(e,t,i){if(!e[i]){t.trigger({type:"usage",name:"vhs-608"}),t.trigger({type:"usage",name:"hls-608"});var n=t.textTracks().getTrackById(i);e[i]=n||t.addRemoteTextTrack({kind:"captions",id:i,label:i},!1).track;}}(d,i.vhs_.tech_,e),Ci(a,s,d[e]),function(e){var t=e.inbandTextTracks,i=e.captionArray,n=e.timestampOffset;if(i){var r=o.default.WebKitDataCue||o.default.VTTCue;i.forEach((function(e){var i=e.stream;t[i].addCue(new r(e.startTime+n,e.endTime+n,e.text));}));}}({captionArray:u,inbandTextTracks:d,timestampOffset:n});})),this.transmuxer_&&this.transmuxer_.postMessage({action:"clearParsedMp4Captions"});}else this.metadataQueue_.caption.push(this.handleCaptions_.bind(this,e,t));else this.logger_("SegmentLoader received no captions from a caption event");},i.handleId3_=function(e,t,i){if(this.earlyAbortWhenNeeded_(e.stats),!this.checkForAbort_(e.requestId))if(this.pendingSegment_.hasAppendedData_){var n=null===this.sourceUpdater_.videoTimestampOffset()?this.sourceUpdater_.audioTimestampOffset():this.sourceUpdater_.videoTimestampOffset();!function(e,t,i){e.metadataTrack_||(e.metadataTrack_=i.addRemoteTextTrack({kind:"metadata",label:"Timed Metadata"},!1).track,e.metadataTrack_.inBandMetadataTrackDispatchType=t);}(this.inbandTextTracks_,i,this.vhs_.tech_),function(e){var t=e.inbandTextTracks,i=e.metadataArray,n=e.timestampOffset,r=e.videoDuration;if(i){var a=o.default.WebKitDataCue||o.default.VTTCue,s=t.metadataTrack_;if(s&&(i.forEach((function(e){var t=e.cueTime+n;!("number"!=typeof t||o.default.isNaN(t)||t<0)&&t<1/0&&e.frames.forEach((function(e){var i=new a(t,t,e.value||e.url||e.data||"");i.frame=e,i.value=e,function(e){Object.defineProperties(e.frame,{id:{get:function(){return u.default.log.warn("cue.frame.id is deprecated. Use cue.value.key instead."),e.value.key}},value:{get:function(){return u.default.log.warn("cue.frame.value is deprecated. Use cue.value.data instead."),e.value.data}},privateData:{get:function(){return u.default.log.warn("cue.frame.privateData is deprecated. Use cue.value.data instead."),e.value.data}}});}(i),s.addCue(i);}));})),s.cues&&s.cues.length)){for(var d=s.cues,l=[],h=0;h1&&this.logger_("On QUOTA_EXCEEDED_ERR, found gaps in the audio buffer: "+$(s).join(", ")),u.length>1&&this.logger_("On QUOTA_EXCEEDED_ERR, found gaps in the video buffer: "+$(u).join(", "));var d=s.length?s.start(0):0,l=s.length?s.end(s.length-1):0,h=u.length?u.start(0):0,c=u.length?u.end(u.length-1):0;if(l-d<=1&&c-h<=1)return this.logger_("On QUOTA_EXCEEDED_ERR, single segment too large to append to buffer, triggering an error. Appended byte length: "+a.byteLength+", audio buffer: "+$(s).join(", ")+", video buffer: "+$(u).join(", ")+", "),this.error({message:"Quota exceeded error with append of a single segment of content",blacklistDuration:1/0}),void this.trigger("error");this.waitingOnRemove_=!0,this.callQueue_.push(this.appendToSourceBuffer_.bind(this,{segmentInfo:n,type:r,bytes:a}));var f=this.currentTime_()-1;this.logger_("On QUOTA_EXCEEDED_ERR, removing audio/video from 0 to "+f),this.remove(0,f,(function(){i.logger_("On QUOTA_EXCEEDED_ERR, retrying append in 1s"),i.waitingOnRemove_=!1,i.quotaExceededErrorRetryTimeout_=o.default.setTimeout((function(){i.logger_("On QUOTA_EXCEEDED_ERR, re-processing call queue"),i.quotaExceededErrorRetryTimeout_=null,i.processCallQueue_();}),1e3);}),!0);},i.handleAppendError_=function(e,t){var i=e.segmentInfo,n=e.type,r=e.bytes;t&&(22!==t.code?(this.logger_("Received non QUOTA_EXCEEDED_ERR on append",t),this.error(n+" append of "+r.length+"b failed for segment #"+i.mediaIndex+" in playlist "+i.playlist.id),this.trigger("appenderror")):this.handleQuotaExceededError_({segmentInfo:i,type:n,bytes:r}));},i.appendToSourceBuffer_=function(e){var t,i,n,r=e.segmentInfo,a=e.type,s=e.initSegment,o=e.data,u=e.bytes;if(!u){var d=[o],l=o.byteLength;s&&(d.unshift(s),l+=s.byteLength),n=0,(t={bytes:l,segments:d}).bytes&&(i=new Uint8Array(t.bytes),t.segments.forEach((function(e){i.set(e,n),n+=e.byteLength;}))),u=i;}this.sourceUpdater_.appendBuffer({segmentInfo:r,type:a,bytes:u},this.handleAppendError_.bind(this,{segmentInfo:r,type:a,bytes:u}));},i.handleSegmentTimingInfo_=function(e,t,i){if(this.pendingSegment_&&t===this.pendingSegment_.requestId){var n=this.pendingSegment_.segment,r=e+"TimingInfo";n[r]||(n[r]={}),n[r].transmuxerPrependedSeconds=i.prependedContentDuration||0,n[r].transmuxedPresentationStart=i.start.presentation,n[r].transmuxedDecodeStart=i.start.decode,n[r].transmuxedPresentationEnd=i.end.presentation,n[r].transmuxedDecodeEnd=i.end.decode,n[r].baseMediaDecodeTime=i.baseMediaDecodeTime;}},i.appendData_=function(e,t){var i=t.type,n=t.data;if(n&&n.byteLength&&("audio"!==i||!this.audioDisabled_)){var r=this.getInitSegmentAndUpdateState_({type:i,initSegment:t.initSegment,playlist:e.playlist,map:e.isFmp4?e.segment.map:null});this.appendToSourceBuffer_({segmentInfo:e,type:i,initSegment:r,data:n});}},i.loadSegment_=function(e){var t=this;this.state="WAITING",this.pendingSegment_=e,this.trimBackBuffer_(e),"number"==typeof e.timestampOffset&&this.transmuxer_&&this.transmuxer_.postMessage({action:"clearAllMp4Captions"}),this.hasEnoughInfoToLoad_()?this.updateTransmuxerAndRequestSegment_(e):this.loadQueue_.push((function(){var i=v({},e,{forceTimestampOffset:!0});v(e,t.generateSegmentInfo_(i)),t.isPendingTimestampOffset_=!1,t.updateTransmuxerAndRequestSegment_(e);}));},i.updateTransmuxerAndRequestSegment_=function(e){var t=this;this.shouldUpdateTransmuxerTimestampOffset_(e.timestampOffset)&&(this.gopBuffer_.length=0,e.gopsToAlignWith=[],this.timeMapping_=0,this.transmuxer_.postMessage({action:"reset"}),this.transmuxer_.postMessage({action:"setTimestampOffset",timestampOffset:e.timestampOffset}));var i=this.createSimplifiedSegmentObj_(e),n=this.isEndOfStream_(e.mediaIndex,e.playlist,e.partIndex),r=null!==this.mediaIndex,a=e.timeline!==this.currentTimeline_&&e.timeline>0,s=n||r&&a;this.logger_("Requesting "+Bi(e)),i.map&&!i.map.bytes&&(this.logger_("going to request init segment."),this.appendInitSegment_={video:!0,audio:!0}),e.abortRequests=vi({xhr:this.vhs_.xhr,xhrOptions:this.xhrOptions_,decryptionWorker:this.decrypter_,segment:i,abortFn:this.handleAbort_.bind(this,e),progressFn:this.handleProgress_.bind(this),trackInfoFn:this.handleTrackInfo_.bind(this),timingInfoFn:this.handleTimingInfo_.bind(this),videoSegmentTimingInfoFn:this.handleSegmentTimingInfo_.bind(this,"video",e.requestId),audioSegmentTimingInfoFn:this.handleSegmentTimingInfo_.bind(this,"audio",e.requestId),captionsFn:this.handleCaptions_.bind(this),isEndOfTimeline:s,endedTimelineFn:function(){t.logger_("received endedtimeline callback");},id3Fn:this.handleId3_.bind(this),dataFn:this.handleData_.bind(this),doneFn:this.segmentRequestFinished_.bind(this)});},i.trimBackBuffer_=function(e){var t=function(e,t,i){var n=t-ii.BACK_BUFFER_LENGTH;e.length&&(n=Math.max(n,e.start(0)));var r=t-i;return Math.min(r,n)}(this.seekable_(),this.currentTime_(),this.playlist_.targetDuration||10);t>0&&this.remove(0,t);},i.createSimplifiedSegmentObj_=function(e){var t=e.segment,i=e.part,n={resolvedUri:i?i.resolvedUri:t.resolvedUri,byterange:i?i.byterange:t.byterange,requestId:e.requestId,transmuxer:e.transmuxer,audioAppendStart:e.audioAppendStart,gopsToAlignWith:e.gopsToAlignWith,part:e.part},r=e.playlist.segments[e.mediaIndex-1];if(r&&r.timeline===t.timeline&&(r.videoTimingInfo?n.baseStartTime=r.videoTimingInfo.transmuxedDecodeEnd:r.audioTimingInfo&&(n.baseStartTime=r.audioTimingInfo.transmuxedDecodeEnd)),t.key){var a=t.key.iv||new Uint32Array([0,0,0,e.mediaIndex+e.playlist.mediaSequence]);n.key=this.segmentKey(t.key),n.key.iv=a;}return t.map&&(n.map=this.initSegmentForMap(t.map)),n},i.saveTransferStats_=function(e){this.mediaRequests+=1,e&&(this.mediaBytesTransferred+=e.bytesReceived,this.mediaTransferDuration+=e.roundTripTime);},i.saveBandwidthRelatedStats_=function(e,t){this.pendingSegment_.byteLength=t.bytesReceived,e=n);r++);return e.slice(0,r).concat(t)}(this.gopBuffer_,i.gopInfo,this.safeAppend_)),this.state="APPENDING",this.trigger("appending"),this.waitForAppendsToComplete_(n);}},i.setTimeMapping_=function(e){var t=this.syncController_.mappingForTimeline(e);null!==t&&(this.timeMapping_=t);},i.updateMediaSecondsLoaded_=function(e){"number"==typeof e.start&&"number"==typeof e.end?this.mediaSecondsLoaded+=e.end-e.start:this.mediaSecondsLoaded+=e.duration;},i.shouldUpdateTransmuxerTimestampOffset_=function(e){return null!==e&&("main"===this.loaderType_&&e!==this.sourceUpdater_.videoTimestampOffset()||!this.audioDisabled_&&e!==this.sourceUpdater_.audioTimestampOffset())},i.trueSegmentStart_=function(e){var t=e.currentStart,i=e.playlist,n=e.mediaIndex,r=e.firstVideoFrameTimeForData,a=e.currentVideoTimestampOffset,s=e.useVideoTimingInfo,o=e.videoTimingInfo,u=e.audioTimingInfo;if(void 0!==t)return t;if(!s)return u.start;var d=i.segments[n-1];return 0!==n&&d&&void 0!==d.start&&d.end===r+a?o.start:r},i.waitForAppendsToComplete_=function(e){if(!this.currentMediaInfo_)return this.error({message:"No starting media returned, likely due to an unsupported media format.",blacklistDuration:1/0}),void this.trigger("error");var t=this.currentMediaInfo_,i=t.hasAudio,n=t.hasVideo,r=t.isMuxed,a="main"===this.loaderType_&&n,s=!this.audioDisabled_&&i&&!r;if(e.waitingOnAppends=0,!e.hasAppendedData_)return e.timingInfo||"number"!=typeof e.timestampOffset||(this.isPendingTimestampOffset_=!0),e.timingInfo={start:0},e.waitingOnAppends++,this.isPendingTimestampOffset_||(this.updateSourceBufferTimestampOffset_(e),this.processMetadataQueue_()),void this.checkAppendsDone_(e);a&&e.waitingOnAppends++,s&&e.waitingOnAppends++,a&&this.sourceUpdater_.videoQueueCallback(this.checkAppendsDone_.bind(this,e)),s&&this.sourceUpdater_.audioQueueCallback(this.checkAppendsDone_.bind(this,e));},i.checkAppendsDone_=function(e){this.checkForAbort_(e.requestId)||(e.waitingOnAppends--,0===e.waitingOnAppends&&this.handleAppendsDone_());},i.checkForIllegalMediaSwitch=function(e){var t=function(e,t,i){return "main"===e&&t&&i?i.hasAudio||i.hasVideo?t.hasVideo&&!i.hasVideo?"Only audio found in segment when we expected video. We can't switch to audio only from a stream that had video. To get rid of this message, please add codec information to the manifest.":!t.hasVideo&&i.hasVideo?"Video found in segment when we expected only audio. We can't switch to a stream with video from an audio only stream. To get rid of this message, please add codec information to the manifest.":null:"Neither audio nor video found in segment.":null}(this.loaderType_,this.currentMediaInfo_,e);return !!t&&(this.error({message:t,blacklistDuration:1/0}),this.trigger("error"),!0)},i.updateSourceBufferTimestampOffset_=function(e){if(null!==e.timestampOffset&&"number"==typeof e.timingInfo.start&&!e.changedTimestampOffset&&"main"===this.loaderType_){var t=!1;e.timestampOffset-=e.timingInfo.start,e.changedTimestampOffset=!0,e.timestampOffset!==this.sourceUpdater_.videoTimestampOffset()&&(this.sourceUpdater_.videoTimestampOffset(e.timestampOffset),t=!0),e.timestampOffset!==this.sourceUpdater_.audioTimestampOffset()&&(this.sourceUpdater_.audioTimestampOffset(e.timestampOffset),t=!0),t&&this.trigger("timestampoffset");}},i.updateTimingInfoEnd_=function(e){e.timingInfo=e.timingInfo||{};var t="main"===this.loaderType_&&this.currentMediaInfo_.hasVideo&&e.videoTimingInfo?e.videoTimingInfo:e.audioTimingInfo;t&&(e.timingInfo.end="number"==typeof t.end?t.end:t.start+e.duration);},i.handleAppendsDone_=function(){if(this.pendingSegment_&&this.trigger("appendsdone"),!this.pendingSegment_)return this.state="READY",void(this.paused()||this.monitorBuffer_());var e=this.pendingSegment_;this.updateTimingInfoEnd_(e),this.shouldSaveSegmentTimingInfo_&&this.syncController_.saveSegmentTimingInfo({segmentInfo:e,shouldSaveTimelineMapping:"main"===this.loaderType_}),this.logger_("Appended "+Bi(e));var t=function(e,t){if("hls"!==t)return null;var i,n,r,a,s=(i=e.audioTimingInfo,n=e.videoTimingInfo,r=i&&"number"==typeof i.start&&"number"==typeof i.end?i.end-i.start:0,a=n&&"number"==typeof n.start&&"number"==typeof n.end?n.end-n.start:0,Math.max(r,a));if(!s)return null;var o=e.playlist.targetDuration,u=qi({segmentDuration:s,maxDuration:2*o}),d=qi({segmentDuration:s,maxDuration:o}),l="Segment with index "+e.mediaIndex+" from playlist "+e.playlist.id+" has a duration of "+s+" when the reported duration is "+e.duration+" and the target duration is "+o+". For HLS content, a duration in excess of the target duration may result in playback issues. See the HLS specification section on EXT-X-TARGETDURATION for more details: https://tools.ietf.org/html/draft-pantos-http-live-streaming-23#section-4.3.3.1";return u||d?{severity:u?"warn":"info",message:l}:null}(e,this.sourceType_);if(t&&("warn"===t.severity?u.default.log.warn(t.message):this.logger_(t.message)),this.recordThroughput_(e),this.pendingSegment_=null,this.state="READY",e.isSyncRequest)this.trigger("syncinfoupdate");else {this.addSegmentMetadataCue_(e),this.fetchAtBuffer_=!0,this.currentTimeline_!==e.timeline&&(this.timelineChangeController_.lastTimelineChange({type:this.loaderType_,from:this.currentTimeline_,to:e.timeline}),"main"!==this.loaderType_||this.audioDisabled_||this.timelineChangeController_.lastTimelineChange({type:"audio",from:this.currentTimeline_,to:e.timeline})),this.currentTimeline_=e.timeline,this.trigger("syncinfoupdate");var i=e.segment;i.end&&this.currentTime_()-i.end>3*e.playlist.targetDuration?this.resetEverything():(null!==this.mediaIndex&&this.trigger("bandwidthupdate"),this.trigger("progress"),this.mediaIndex=e.mediaIndex,this.partIndex=e.partIndex,this.isEndOfStream_(e.mediaIndex,e.playlist,e.partIndex)&&this.endOfStream(),this.trigger("appended"),this.paused()||this.monitorBuffer_());}},i.recordThroughput_=function(e){if(e.duration=e.playlist.segments.length){e=null;break}e=this.generateSegmentInfo_({playlist:e.playlist,mediaIndex:e.mediaIndex+1,startOfSegment:e.startOfSegment+e.duration,isSyncRequest:e.isSyncRequest});}return e},i.stopForError=function(e){this.error(e),this.state="READY",this.pause(),this.trigger("error");},i.segmentRequestFinished_=function(e,t,i){var n=this;if(this.subtitlesTrack_){if(this.saveTransferStats_(t.stats),!this.pendingSegment_)return this.state="READY",void(this.mediaRequestsAborted+=1);if(e)return e.code===fi&&this.handleTimeout_(),e.code===pi?this.mediaRequestsAborted+=1:this.mediaRequestsErrored+=1,void this.stopForError(e);var r=this.pendingSegment_;this.saveBandwidthRelatedStats_(r.duration,t.stats),this.state="APPENDING",this.trigger("appending");var a=r.segment;if(a.map&&(a.map.bytes=t.map.bytes),r.bytes=t.bytes,"function"!=typeof o.default.WebVTT&&this.subtitlesTrack_&&this.subtitlesTrack_.tech_){var s,u=function(){n.subtitlesTrack_.tech_.off("vttjsloaded",s),n.stopForError({message:"Error loading vtt.js"});};return s=function(){n.subtitlesTrack_.tech_.off("vttjserror",u),n.segmentRequestFinished_(e,t,i);},this.state="WAITING_ON_VTTJS",this.subtitlesTrack_.tech_.one("vttjsloaded",s),void this.subtitlesTrack_.tech_.one("vttjserror",u)}a.requested=!0;try{this.parseVTTCues_(r);}catch(e){return void this.stopForError({message:e.message})}if(this.updateTimeMapping_(r,this.syncController_.timelines[r.timeline],this.playlist_),r.cues.length?r.timingInfo={start:r.cues[0].startTime,end:r.cues[r.cues.length-1].endTime}:r.timingInfo={start:r.startOfSegment,end:r.startOfSegment+r.duration},r.isSyncRequest)return this.trigger("syncinfoupdate"),this.pendingSegment_=null,void(this.state="READY");r.byteLength=r.bytes.byteLength,this.mediaSecondsLoaded+=a.duration,r.cues.forEach((function(e){n.subtitlesTrack_.addCue(n.featuresNativeTextTracks_?new o.default.VTTCue(e.startTime,e.endTime,e.text):e);})),function(e){var t=e.cues;if(t)for(var i=0;i1&&n.push(t[a]);n.length&&n.forEach((function(t){return e.removeCue(t)}));}}(this.subtitlesTrack_),this.handleAppendsDone_();}else this.state="READY";},i.handleData_=function(){},i.updateTimingInfoEnd_=function(){},i.parseVTTCues_=function(e){var t,i=!1;"function"==typeof o.default.TextDecoder?t=new o.default.TextDecoder("utf8"):(t=o.default.WebVTT.StringDecoder(),i=!0);var n=new o.default.WebVTT.Parser(o.default,o.default.vttjs,t);if(e.cues=[],e.timestampmap={MPEGTS:0,LOCAL:0},n.oncue=e.cues.push.bind(e.cues),n.ontimestampmap=function(t){e.timestampmap=t;},n.onparsingerror=function(e){u.default.log.warn("Error encountered when parsing cues: "+e.message);},e.segment.map){var r=e.segment.map.bytes;i&&(r=un(r)),n.parse(r);}var a=e.bytes;i&&(a=un(a)),n.parse(a),n.flush();},i.updateTimeMapping_=function(e,t,i){var n=e.segment;if(t)if(e.cues.length){var r=e.timestampmap,a=r.MPEGTS/Di-r.LOCAL+t.mapping;if(e.cues.forEach((function(e){e.startTime+=a,e.endTime+=a;})),!i.syncInfo){var s=e.cues[0].startTime,o=e.cues[e.cues.length-1].startTime;i.syncInfo={mediaSequence:i.mediaSequence+e.mediaIndex,time:Math.min(s,o-n.duration)};}}else n.empty=!0;},t}(Hi),hn=function(e,t){for(var i=e.cues,n=0;n=r.adStartTime&&t<=r.adEndTime)return r}return null},cn=function(e,t,i){void 0===i&&(i=0);var n=t.segments;return t.endList||0===i?e:n.length-(e+1)},fn=[{name:"VOD",run:function(e,t,i,n,r){return i!==1/0?{time:0,segmentIndex:0}:null}},{name:"ProgramDateTime",run:function(e,t,i,n,r){if(!Object.keys(e.timelineToDatetimeMappings).length)return null;var a=t.segments||[],s=null,o=null;r=r||0;for(var u=0;u=h)&&(o=h,s={time:l.start,segmentIndex:d});}}return s}},{name:"Discontinuity",run:function(e,t,i,n,r){var a=null;if(r=r||0,t.discontinuityStarts&&t.discontinuityStarts.length)for(var s=null,o=0;o=h)&&(s=h,a={time:l.time,segmentIndex:u});}}return a}},{name:"Playlist",run:function(e,t,i,n,r){return t.syncInfo?{time:t.syncInfo.time,segmentIndex:t.syncInfo.mediaSequence-t.mediaSequence}:null}}],pn=function(e){function t(t){var i;return (i=e.call(this)||this).timelines=[],i.discontinuities=[],i.timelineToDatetimeMappings={},i.logger_=_("SyncController"),i}c(t,e);var i=t.prototype;return i.getSyncPoint=function(e,t,i,n){var r=this.runStrategies_(e,t,i,n);return r.length?this.selectSyncPoint_(r,{key:"time",value:n}):null},i.getExpiredTime=function(e,t){if(!e||!e.segments)return null;var i=this.runStrategies_(e,t,e.discontinuitySequence,0);if(!i.length)return null;var n=this.selectSyncPoint_(i,{key:"segmentIndex",value:0});return n.segmentIndex>0&&(n.time*=-1),Math.abs(n.time+fe(e,n.segmentIndex,0))},i.runStrategies_=function(e,t,i,n){for(var r=[],a=0;a=0;i--){var n=e.segments[i];if(n&&void 0!==n.start){t.syncInfo={mediaSequence:e.mediaSequence+i,time:n.start},this.logger_("playlist refresh sync: [time:"+t.syncInfo.time+", mediaSequence: "+t.syncInfo.mediaSequence+"]"),this.trigger("syncinfoupdate");break}}},i.setDateTimeMappingForStart=function(e){if(this.timelineToDatetimeMappings={},e.segments&&e.segments.length&&e.segments[0].dateTimeObject){var t=e.segments[0],i=t.dateTimeObject.getTime()/1e3;this.timelineToDatetimeMappings[t.timeline]=-i;}},i.saveSegmentTimingInfo=function(e){var t=e.segmentInfo,i=e.shouldSaveTimelineMapping,n=this.calculateSegmentTimeMapping_(t,t.timingInfo,i),r=t.segment;n&&(this.saveDiscontinuitySyncInfo_(t),t.playlist.syncInfo||(t.playlist.syncInfo={mediaSequence:t.playlist.mediaSequence+t.mediaIndex,time:r.start}));var a=r.dateTimeObject;r.discontinuity&&i&&a&&(this.timelineToDatetimeMappings[r.timeline]=-a.getTime()/1e3);},i.timestampOffsetForTimeline=function(e){return void 0===this.timelines[e]?null:this.timelines[e].time},i.mappingForTimeline=function(e){return void 0===this.timelines[e]?null:this.timelines[e].mapping},i.calculateSegmentTimeMapping_=function(e,t,i){var n=e.segment,r=this.timelines[e.timeline];if("number"==typeof e.timestampOffset)r={time:e.startOfSegment,mapping:e.startOfSegment-t.start},i&&(this.timelines[e.timeline]=r,this.trigger("timestampoffset"),this.logger_("time mapping for timeline "+e.timeline+": [time: "+r.time+"] [mapping: "+r.mapping+"]")),n.start=e.startOfSegment,n.end=t.end+r.mapping;else {if(!r)return !1;n.start=t.start+r.mapping,n.end=t.end+r.mapping;}return !0},i.saveDiscontinuitySyncInfo_=function(e){var t=e.playlist,i=e.segment;if(i.discontinuity)this.discontinuities[i.timeline]={time:i.start,accuracy:0};else if(t.discontinuityStarts&&t.discontinuityStarts.length)for(var n=0;no){var u;u=s<0?i.start-fe(t,e.mediaIndex,r):i.end+fe(t,e.mediaIndex+1,r),this.discontinuities[a]={time:u,accuracy:o};}}},i.dispose=function(){this.trigger("dispose"),this.off();},t}(u.default.EventTarget),mn=function(e){function t(){var t;return (t=e.call(this)||this).pendingTimelineChanges_={},t.lastTimelineChanges_={},t}c(t,e);var i=t.prototype;return i.clearPendingTimelineChange=function(e){this.pendingTimelineChanges_[e]=null,this.trigger("pendingtimelinechange");},i.pendingTimelineChange=function(e){var t=e.type,i=e.from,n=e.to;return "number"==typeof i&&"number"==typeof n&&(this.pendingTimelineChanges_[t]={type:t,from:i,to:n},this.trigger("pendingtimelinechange")),this.pendingTimelineChanges_[t]},i.lastTimelineChange=function(e){var t=e.type,i=e.from,n=e.to;return "number"==typeof i&&"number"==typeof n&&(this.lastTimelineChanges_[t]={type:t,from:i,to:n},delete this.pendingTimelineChanges_[t],this.trigger("timelinechange")),this.lastTimelineChanges_[t]},i.dispose=function(){this.trigger("dispose"),this.pendingTimelineChanges_={},this.lastTimelineChanges_={},this.off();},t}(u.default.EventTarget),gn=ri(ai(si((function(){function e(e,t,i){return e(i={path:t,exports:{},require:function(e,t){return function(){throw new Error("Dynamic requires are not currently supported by @rollup/plugin-commonjs")}(null==t&&i.path)}},i.exports),i.exports}var t=e((function(e){function t(e,t){for(var i=0;i-1},t.trigger=function(e){var t=this.listeners[e];if(t)if(2===arguments.length)for(var i=t.length,n=0;n>7))^e]=e;for(t=i=0;!h[t];t^=n||1,i=p[i]||1)for(a=(a=i^i<<1^i<<2^i<<3^i<<4)>>8^255&a^99,h[t]=a,c[a]=t,o=16843009*f[r=f[n=f[t]]]^65537*r^257*n^16843008*t,s=257*f[a]^16843008*a,e=0;e<4;e++)d[e][t]=s=s<<24^s>>>8,l[e][a]=o=o<<24^o>>>8;for(e=0;e<5;e++)d[e]=d[e].slice(0),l[e]=l[e].slice(0);return u}()),this._tables=[[a[0][0].slice(),a[0][1].slice(),a[0][2].slice(),a[0][3].slice(),a[0][4].slice()],[a[1][0].slice(),a[1][1].slice(),a[1][2].slice(),a[1][3].slice(),a[1][4].slice()]];var r=this._tables[0][4],s=this._tables[1],o=e.length,u=1;if(4!==o&&6!==o&&8!==o)throw new Error("Invalid aes key size");var d=e.slice(0),l=[];for(this._key=[d,l],t=o;t<4*o+28;t++)n=d[t-1],(t%o==0||8===o&&t%o==4)&&(n=r[n>>>24]<<24^r[n>>16&255]<<16^r[n>>8&255]<<8^r[255&n],t%o==0&&(n=n<<8^n>>>24^u<<24,u=u<<1^283*(u>>7))),d[t]=d[t-o]^n;for(i=0;t;i++,t--)n=d[3&i?t:t-4],l[i]=t<=4||i<4?n:s[0][r[n>>>24]]^s[1][r[n>>16&255]]^s[2][r[n>>8&255]]^s[3][r[255&n]];}return e.prototype.decrypt=function(e,t,i,n,r,a){var s,o,u,d,l=this._key[1],h=e^l[0],c=n^l[1],f=i^l[2],p=t^l[3],m=l.length/4-2,g=4,y=this._tables[1],_=y[0],v=y[1],T=y[2],b=y[3],S=y[4];for(d=0;d>>24]^v[c>>16&255]^T[f>>8&255]^b[255&p]^l[g],o=_[c>>>24]^v[f>>16&255]^T[p>>8&255]^b[255&h]^l[g+1],u=_[f>>>24]^v[p>>16&255]^T[h>>8&255]^b[255&c]^l[g+2],p=_[p>>>24]^v[h>>16&255]^T[c>>8&255]^b[255&f]^l[g+3],g+=4,h=s,c=o,f=u;for(d=0;d<4;d++)r[(3&-d)+a]=S[h>>>24]<<24^S[c>>16&255]<<16^S[f>>8&255]<<8^S[255&p]^l[g++],s=h,h=c,c=f,f=p,p=s;},e}(),o=function(e){function t(){var t;return (t=e.call(this,r)||this).jobs=[],t.delay=1,t.timeout_=null,t}n(t,e);var i=t.prototype;return i.processJob_=function(){this.jobs.shift()(),this.jobs.length?this.timeout_=setTimeout(this.processJob_.bind(this),this.delay):this.timeout_=null;},i.push=function(e){this.jobs.push(e),this.timeout_||(this.timeout_=setTimeout(this.processJob_.bind(this),this.delay));},t}(r),u=function(e){return e<<24|(65280&e)<<8|(16711680&e)>>8|e>>>24},d=function(){function e(t,i,n,r){var a=e.STEP,s=new Int32Array(t.buffer),d=new Uint8Array(t.byteLength),l=0;for(this.asyncStream_=new o,this.asyncStream_.push(this.decryptChunk_(s.subarray(l,l+a),i,n,d)),l=a;l>2),m=new s(Array.prototype.slice.call(t)),g=new Uint8Array(e.byteLength),y=new Int32Array(g.buffer);for(n=i[0],r=i[1],a=i[2],o=i[3],f=0;f=0&&(t="main-desc"),t},_n=function(e,t){e.abort(),e.pause(),t&&t.activePlaylistLoader&&(t.activePlaylistLoader.pause(),t.activePlaylistLoader=null);},vn=function(e,t){t.activePlaylistLoader=e,e.load();},Tn={AUDIO:function(e,t){return function(){var i=t.segmentLoaders[e],n=t.mediaTypes[e],r=t.blacklistCurrentPlaylist;_n(i,n);var a=n.activeTrack(),s=n.activeGroup(),o=(s.filter((function(e){return e.default}))[0]||s[0]).id,d=n.tracks[o];if(a!==d){for(var l in u.default.log.warn("Problem encountered loading the alternate audio track.Switching back to default."),n.tracks)n.tracks[l].enabled=n.tracks[l]===d;n.onTrackChanged();}else r({message:"Problem encountered loading the default audio track."});}},SUBTITLES:function(e,t){return function(){var i=t.segmentLoaders[e],n=t.mediaTypes[e];u.default.log.warn("Problem encountered loading the subtitle track.Disabling subtitle track."),_n(i,n);var r=n.activeTrack();r&&(r.mode="disabled"),n.onTrackChanged();}}},bn={AUDIO:function(e,t,i){if(t){var n=i.tech,r=i.requestOptions,a=i.segmentLoaders[e];t.on("loadedmetadata",(function(){var e=t.media();a.playlist(e,r),(!n.paused()||e.endList&&"none"!==n.preload())&&a.load();})),t.on("loadedplaylist",(function(){a.playlist(t.media(),r),n.paused()||a.load();})),t.on("error",Tn[e](e,i));}},SUBTITLES:function(e,t,i){var n=i.tech,r=i.requestOptions,a=i.segmentLoaders[e],s=i.mediaTypes[e];t.on("loadedmetadata",(function(){var e=t.media();a.playlist(e,r),a.track(s.activeTrack()),(!n.paused()||e.endList&&"none"!==n.preload())&&a.load();})),t.on("loadedplaylist",(function(){a.playlist(t.media(),r),n.paused()||a.load();})),t.on("error",Tn[e](e,i));}},Sn={AUDIO:function(e,t){var i=t.vhs,n=t.sourceType,r=t.segmentLoaders[e],a=t.requestOptions,s=t.master.mediaGroups,o=t.mediaTypes[e],d=o.groups,l=o.tracks,h=o.logger_,c=t.masterPlaylistLoader,f=Se(c.master);for(var p in s[e]&&0!==Object.keys(s[e]).length||(s[e]={main:{default:{default:!0}}}),s[e])for(var m in d[p]||(d[p]=[]),s[e][p]){var g=s[e][p][m],y=void 0;if(f?(h("AUDIO group '"+p+"' label '"+m+"' is a master playlist"),g.isMasterPlaylist=!0,y=null):y="vhs-json"===n&&g.playlists?new V(g.playlists[0],i,a):g.resolvedUri?new V(g.resolvedUri,i,a):g.playlists&&"dash"===n?new ti(g.playlists[0],i,a,c):null,g=u.default.mergeOptions({id:m,playlistLoader:y},g),bn[e](e,g.playlistLoader,t),d[p].push(g),void 0===l[m]){var _=new u.default.AudioTrack({id:m,kind:yn(g),enabled:!1,language:g.language,default:g.default,label:m});l[m]=_;}}r.on("error",Tn[e](e,t));},SUBTITLES:function(e,t){var i=t.tech,n=t.vhs,r=t.sourceType,a=t.segmentLoaders[e],s=t.requestOptions,o=t.master.mediaGroups,d=t.mediaTypes[e],l=d.groups,h=d.tracks,c=t.masterPlaylistLoader;for(var f in o[e])for(var p in l[f]||(l[f]=[]),o[e][f])if(!o[e][f][p].forced){var m=o[e][f][p],g=void 0;if("hls"===r)g=new V(m.resolvedUri,n,s);else if("dash"===r){if(!m.playlists.filter((function(e){return e.excludeUntil!==1/0})).length)return;g=new ti(m.playlists[0],n,s,c);}else "vhs-json"===r&&(g=new V(m.playlists?m.playlists[0]:m.resolvedUri,n,s));if(m=u.default.mergeOptions({id:p,playlistLoader:g},m),bn[e](e,m.playlistLoader,t),l[f].push(m),void 0===h[p]){var y=i.addRemoteTextTrack({id:p,kind:"subtitles",default:m.default&&m.autoselect,language:m.language,label:p},!1).track;h[p]=y;}}a.on("error",Tn[e](e,t));},"CLOSED-CAPTIONS":function(e,t){var i=t.tech,n=t.master.mediaGroups,r=t.mediaTypes[e],a=r.groups,s=r.tracks;for(var o in n[e])for(var d in a[o]||(a[o]=[]),n[e][o]){var l=n[e][o][d];if(l.instreamId.match(/CC\d/)&&(a[o].push(u.default.mergeOptions({id:d},l)),void 0===s[d])){var h=i.addRemoteTextTrack({id:l.instreamId,kind:"captions",default:l.default&&l.autoselect,language:l.language,label:d},!1).track;s[d]=h;}}}},In=function e(t,i){for(var n=0;n "+a+" from "+t),this.tech_.trigger({type:"usage",name:"vhs-rendition-change-"+t})),this.masterPlaylistLoader_.media(e,i);},i.startABRTimer_=function(){var e=this;this.stopABRTimer_(),this.abrTimer_=o.default.setInterval((function(){return e.checkABR_()}),250);},i.stopABRTimer_=function(){this.tech_.scrubbing&&this.tech_.scrubbing()||(o.default.clearInterval(this.abrTimer_),this.abrTimer_=null);},i.getAudioTrackPlaylists_=function(){var e=this.master();if(!e||!e.mediaGroups||!e.mediaGroups.AUDIO)return e&&e.playlists||[];var t,i=e.mediaGroups.AUDIO,n=Object.keys(i);if(Object.keys(this.mediaTypes_.AUDIO.groups).length)t=this.mediaTypes_.AUDIO.activeTrack();else {var r=i.main||n.length&&i[n[0]];for(var a in r)if(r[a].default){t={label:a};break}}if(!t)return [];var s=[];for(var o in i)if(i[o][t.label]){var u=i[o][t.label];u.playlists?s.push.apply(s,u.playlists):s.push(u);}return s},i.setupMasterPlaylistLoaderListeners_=function(){var e=this;this.masterPlaylistLoader_.on("loadedmetadata",(function(){var t=e.masterPlaylistLoader_.media(),i=1.5*t.targetDuration*1e3;ve(e.masterPlaylistLoader_.master,e.masterPlaylistLoader_.media())?e.requestOptions_.timeout=0:e.requestOptions_.timeout=i,t.endList&&"none"!==e.tech_.preload()&&(e.mainSegmentLoader_.playlist(t,e.requestOptions_),e.mainSegmentLoader_.load()),function(e){["AUDIO","SUBTITLES","CLOSED-CAPTIONS"].forEach((function(t){Sn[t](t,e);}));var t=e.mediaTypes,i=e.masterPlaylistLoader,n=e.tech,r=e.vhs,a=e.segmentLoaders,s=a.AUDIO,o=a.main;["AUDIO","SUBTITLES"].forEach((function(i){t[i].activeGroup=function(e,t){return function(i){var n=t.masterPlaylistLoader,r=t.mediaTypes[e].groups,a=n.media();if(!a)return null;var s=null;a.attributes[e]&&(s=r[a.attributes[e]]);var o=Object.keys(r);if(!s)if("AUDIO"===e&&o.length>1&&Se(t.master))for(var u=0;u1&&(this.tech_.trigger({type:"usage",name:"vhs-alternate-audio"}),this.tech_.trigger({type:"usage",name:"hls-alternate-audio"})),this.useCueTags_&&(this.tech_.trigger({type:"usage",name:"vhs-playlist-cue-tags"}),this.tech_.trigger({type:"usage",name:"hls-playlist-cue-tags"}));},i.shouldSwitchToMedia_=function(e){var t=this.masterPlaylistLoader_.media(),i=this.tech_.buffered();return function(e){var t=e.currentPlaylist,i=e.nextPlaylist,n=e.forwardBuffer,r=e.bufferLowWaterLine,a=e.bufferHighWaterLine,s=e.duration,o=e.experimentalBufferBasedABR,d=e.log;if(!i)return u.default.log.warn("We received no playlist to switch to. Please check your stream."),!1;var l="allowing switch "+(t&&t.id||"null")+" -> "+i.id;if(!t||!t.endList)return d(l+" as current playlist "+(t?"is live":"is not set")),!0;if(i.id===t.id)return !1;var h=o?ii.EXPERIMENTAL_MAX_BUFFER_LOW_WATER_LINE:ii.MAX_BUFFER_LOW_WATER_LINE;if(sf)&&n>=r){var m=l+" as forwardBuffer >= bufferLowWaterLine ("+n+" >= "+r+")";return o&&(m+=" and next bandwidth > current bandwidth ("+c+" > "+f+")"),d(m),!0}return d("not "+l+" as no switching criteria met"),!1}({currentPlaylist:t,nextPlaylist:e,forwardBuffer:i.length?i.end(i.length-1)-this.tech_.currentTime():0,bufferLowWaterLine:this.bufferLowWaterLine(),bufferHighWaterLine:this.bufferHighWaterLine(),duration:this.duration(),experimentalBufferBasedABR:this.experimentalBufferBasedABR,log:this.logger_})},i.setupSegmentLoaderListeners_=function(){var e=this;this.experimentalBufferBasedABR||(this.mainSegmentLoader_.on("bandwidthupdate",(function(){var t=e.selectPlaylist();e.shouldSwitchToMedia_(t)&&e.switchMedia_(t,"bandwidthupdate"),e.tech_.trigger("bandwidthupdate");})),this.mainSegmentLoader_.on("progress",(function(){e.trigger("progress");}))),this.mainSegmentLoader_.on("error",(function(){e.blacklistCurrentPlaylist(e.mainSegmentLoader_.error());})),this.mainSegmentLoader_.on("appenderror",(function(){e.error=e.mainSegmentLoader_.error_,e.trigger("error");})),this.mainSegmentLoader_.on("syncinfoupdate",(function(){e.onSyncInfoUpdate_();})),this.mainSegmentLoader_.on("timestampoffset",(function(){e.tech_.trigger({type:"usage",name:"vhs-timestamp-offset"}),e.tech_.trigger({type:"usage",name:"hls-timestamp-offset"});})),this.audioSegmentLoader_.on("syncinfoupdate",(function(){e.onSyncInfoUpdate_();})),this.audioSegmentLoader_.on("appenderror",(function(){e.error=e.audioSegmentLoader_.error_,e.trigger("error");})),this.mainSegmentLoader_.on("ended",(function(){e.logger_("main segment loader ended"),e.onEndOfStream();})),this.mainSegmentLoader_.on("earlyabort",(function(t){e.experimentalBufferBasedABR||(e.delegateLoaders_("all",["abort"]),e.blacklistCurrentPlaylist({message:"Aborted early because there isn't enough bandwidth to complete the request without rebuffering."},120));}));var t=function(){if(!e.sourceUpdater_.hasCreatedSourceBuffers())return e.tryToCreateSourceBuffers_();var t=e.getCodecsOrExclude_();t&&e.sourceUpdater_.addOrChangeSourceBuffers(t);};this.mainSegmentLoader_.on("trackinfo",t),this.audioSegmentLoader_.on("trackinfo",t),this.mainSegmentLoader_.on("fmp4",(function(){e.triggeredFmp4Usage||(e.tech_.trigger({type:"usage",name:"vhs-fmp4"}),e.tech_.trigger({type:"usage",name:"hls-fmp4"}),e.triggeredFmp4Usage=!0);})),this.audioSegmentLoader_.on("fmp4",(function(){e.triggeredFmp4Usage||(e.tech_.trigger({type:"usage",name:"vhs-fmp4"}),e.tech_.trigger({type:"usage",name:"hls-fmp4"}),e.triggeredFmp4Usage=!0);})),this.audioSegmentLoader_.on("ended",(function(){e.logger_("audioSegmentLoader ended"),e.onEndOfStream();}));},i.mediaSecondsLoaded_=function(){return Math.max(this.audioSegmentLoader_.mediaSecondsLoaded+this.mainSegmentLoader_.mediaSecondsLoaded)},i.load=function(){this.mainSegmentLoader_.load(),this.mediaTypes_.AUDIO.activePlaylistLoader&&this.audioSegmentLoader_.load(),this.mediaTypes_.SUBTITLES.activePlaylistLoader&&this.subtitleSegmentLoader_.load();},i.smoothQualityChange_=function(e){void 0===e&&(e=this.selectPlaylist()),e!==this.masterPlaylistLoader_.media()&&(this.switchMedia_(e,"smooth-quality"),this.mainSegmentLoader_.resetLoader());},i.fastQualityChange_=function(e){var t=this;void 0===e&&(e=this.selectPlaylist()),e!==this.masterPlaylistLoader_.media()?(this.switchMedia_(e,"fast-quality"),this.mainSegmentLoader_.resetEverything((function(){u.default.browser.IE_VERSION||u.default.browser.IS_EDGE?t.tech_.setCurrentTime(t.tech_.currentTime()+.04):t.tech_.setCurrentTime(t.tech_.currentTime());}))):this.logger_("skipping fastQualityChange because new media is same as old");},i.play=function(){if(!this.setupFirstPlay()){this.tech_.ended()&&this.tech_.setCurrentTime(0),this.hasPlayed_&&this.load();var e=this.tech_.seekable();return this.tech_.duration()===1/0&&this.tech_.currentTime()r.end(0)||r.start(0)>e.end(0)?this.seekable_=r:this.seekable_=u.default.createTimeRanges([[e.start(0)>r.start(0)?e.start(0):r.start(0),e.end(0)0&&(n=Math.max(n,i.end(i.length-1))),this.mediaSource.duration!==n&&this.sourceUpdater_.setDuration(n);}},i.dispose=function(){var e=this;this.trigger("dispose"),this.decrypter_.terminate(),this.masterPlaylistLoader_.dispose(),this.mainSegmentLoader_.dispose(),this.loadOnPlay_&&this.tech_.off("play",this.loadOnPlay_),["AUDIO","SUBTITLES"].forEach((function(t){var i=e.mediaTypes_[t].groups;for(var n in i)i[n].forEach((function(e){e.playlistLoader&&e.playlistLoader.dispose();}));})),this.audioSegmentLoader_.dispose(),this.subtitleSegmentLoader_.dispose(),this.sourceUpdater_.dispose(),this.timelineChangeController_.dispose(),this.stopABRTimer_(),this.updateDuration_&&this.mediaSource.removeEventListener("sourceopen",this.updateDuration_),this.mediaSource.removeEventListener("durationchange",this.handleDurationChange_),this.mediaSource.removeEventListener("sourceopen",this.handleSourceOpen_),this.mediaSource.removeEventListener("sourceended",this.handleSourceEnded_),this.off();},i.master=function(){return this.masterPlaylistLoader_.master},i.media=function(){return this.masterPlaylistLoader_.media()||this.initialMedia_},i.areMediaTypesKnown_=function(){var e=!!this.mediaTypes_.AUDIO.activePlaylistLoader;return !(!this.mainSegmentLoader_.currentMediaInfo_||e&&!this.audioSegmentLoader_.currentMediaInfo_)},i.getCodecsOrExclude_=function(){var e=this,t={main:this.mainSegmentLoader_.currentMediaInfo_||{},audio:this.audioSegmentLoader_.currentMediaInfo_||{}};t.video=t.main;var i=Ei(this.master(),this.media()),n={},r=!!this.mediaTypes_.AUDIO.activePlaylistLoader;if(t.main.hasVideo&&(n.video=i.video||t.main.videoCodec||"avc1.4d400d"),t.main.isMuxed&&(n.video+=","+(i.audio||t.main.audioCodec||ue)),(t.main.hasAudio&&!t.main.isMuxed||t.audio.hasAudio||r)&&(n.audio=i.audio||t.main.audioCodec||t.audio.audioCodec||ue,t.audio.isFmp4=t.main.hasAudio&&!t.main.isMuxed?t.main.isFmp4:t.audio.isFmp4),n.audio||n.video){var a,s={};if(["video","audio"].forEach((function(e){if(n.hasOwnProperty(e)&&(r=t[e].isFmp4,o=n[e],!(r?se(o):oe(o)))){var i=t[e].isFmp4?"browser":"muxer";s[i]=s[i]||[],s[i].push(n[e]),"audio"===e&&(a=i);}var r,o;})),r&&a&&this.media().attributes.AUDIO){var o=this.media().attributes.AUDIO;this.master().playlists.forEach((function(t){(t.attributes&&t.attributes.AUDIO)===o&&t!==e.media()&&(t.excludeUntil=1/0);})),this.logger_("excluding audio group "+o+" as "+a+' does not support codec(s): "'+n.audio+'"');}if(!Object.keys(s).length){if(this.sourceUpdater_.hasCreatedSourceBuffers()&&!this.sourceUpdater_.canChangeType()){var u=[];if(["video","audio"].forEach((function(t){var i=(ne(e.sourceUpdater_.codecs[t]||"")[0]||{}).type,r=(ne(n[t]||"")[0]||{}).type;i&&r&&i.toLowerCase()!==r.toLowerCase()&&u.push('"'+e.sourceUpdater_.codecs[t]+'" -> "'+n[t]+'"');})),u.length)return void this.blacklistCurrentPlaylist({playlist:this.media(),message:"Codec switching not supported: "+u.join(", ")+".",blacklistDuration:1/0,internal:!0})}return n}var d=Object.keys(s).reduce((function(e,t){return e&&(e+=", "),e+(t+' does not support codec(s): "')+s[t].join(",")+'"'}),"")+".";this.blacklistCurrentPlaylist({playlist:this.media(),internal:!0,message:d,blacklistDuration:1/0});}else this.blacklistCurrentPlaylist({playlist:this.media(),message:"Could not determine codecs for playlist.",blacklistDuration:1/0});},i.tryToCreateSourceBuffers_=function(){if("open"===this.mediaSource.readyState&&!this.sourceUpdater_.hasCreatedSourceBuffers()&&this.areMediaTypesKnown_()){var e=this.getCodecsOrExclude_();if(e){this.sourceUpdater_.createSourceBuffers(e);var t=[e.video,e.audio].filter(Boolean).join(",");this.excludeIncompatibleVariants_(t);}}},i.excludeUnsupportedVariants_=function(){var e=this,t=this.master().playlists,i=[];Object.keys(t).forEach((function(n){var r=t[n];if(-1===i.indexOf(r.id)){i.push(r.id);var a=Ei(e.master,r),s=[];!a.audio||oe(a.audio)||se(a.audio)||s.push("audio codec "+a.audio),!a.video||oe(a.video)||se(a.video)||s.push("video codec "+a.video),a.text&&"stpp.ttml.im1t"===a.text&&s.push("text codec "+a.text),s.length&&(r.excludeUntil=1/0,e.logger_("excluding "+r.id+" for unsupported: "+s.join(", ")));}}));},i.excludeIncompatibleVariants_=function(e){var t=this,i=[],n=this.master().playlists,r=Si(ne(e)),a=Ii(r),s=r.video&&ne(r.video)[0]||null,o=r.audio&&ne(r.audio)[0]||null;Object.keys(n).forEach((function(e){var r=n[e];if(-1===i.indexOf(r.id)&&r.excludeUntil!==1/0){i.push(r.id);var u=[],d=Ei(t.masterPlaylistLoader_.master,r),l=Ii(d);if(d.audio||d.video){if(l!==a&&u.push('codec count "'+l+'" !== "'+a+'"'),!t.sourceUpdater_.canChangeType()){var h=d.video&&ne(d.video)[0]||null,c=d.audio&&ne(d.audio)[0]||null;h&&s&&h.type.toLowerCase()!==s.type.toLowerCase()&&u.push('video codec "'+h.type+'" !== "'+s.type+'"'),c&&o&&c.type.toLowerCase()!==o.type.toLowerCase()&&u.push('audio codec "'+c.type+'" !== "'+o.type+'"');}u.length&&(r.excludeUntil=1/0,t.logger_("blacklisting "+r.id+": "+u.join(" && ")));}}}));},i.updateAdCues_=function(e){var t=0,i=this.seekable();i.length&&(t=i.start(0)),function(e,t,i){if(void 0===i&&(i=0),e.segments)for(var n,r=i,a=0;a0&&this.logger_("resetting possible stalled download count for "+e+" loader"),this[e+"StalledDownloads_"]=0,this[e+"Buffered_"]=t.buffered_();},t.checkSegmentDownloads_=function(e){var t=this.masterPlaylistController_,i=t[e+"SegmentLoader_"],n=i.buffered_(),r=function(e,t){if(e===t)return !1;if(!e&&t||!t&&e)return !0;if(e.length!==t.length)return !0;for(var i=0;i=t.end(t.length-1)))return this.techWaiting_();this.consecutiveUpdates>=5&&e===this.lastRecordedTime?(this.consecutiveUpdates++,this.waiting_()):e===this.lastRecordedTime?this.consecutiveUpdates++:(this.consecutiveUpdates=0,this.lastRecordedTime=e);}},t.cancelTimer_=function(){this.consecutiveUpdates=0,this.timer_&&(this.logger_("cancelTimer_"),clearTimeout(this.timer_)),this.timer_=null;},t.fixesBadSeeks_=function(){if(!this.tech_.seeking())return !1;var e,t=this.seekable(),i=this.tech_.currentTime();if(this.afterSeekableWindow_(t,i,this.media(),this.allowSeeksWithinUnsafeLiveWindow)&&(e=t.end(t.length-1)),this.beforeSeekableWindow_(t,i)){var n=t.start(0);e=n+(n===t.end(0)?0:X);}if(void 0!==e)return this.logger_("Trying to seek outside of seekable at time "+i+" with seekable range "+K(t)+". Seeking to "+e+"."),this.tech_.setCurrentTime(e),!0;var r=this.tech_.buffered();return !!function(e){var t=e.buffered,i=e.targetDuration,n=e.currentTime;return !(!t.length||t.end(0)-t.start(0)<2*i||n>t.start(0)||!(t.start(0)-n "+i.end(0)+"]. Attempting to resume playback by seeking to the current time."),this.tech_.trigger({type:"usage",name:"vhs-unknown-waiting"}),void this.tech_.trigger({type:"usage",name:"hls-unknown-waiting"})):void 0}},t.techWaiting_=function(){var e=this.seekable(),t=this.tech_.currentTime();if(this.tech_.seeking()&&this.fixesBadSeeks_())return !0;if(this.tech_.seeking()||null!==this.timer_)return !0;if(this.beforeSeekableWindow_(e,t)){var i=e.end(e.length-1);return this.logger_("Fell out of live window at time "+t+". Seeking to live point (seekable end) "+i),this.cancelTimer_(),this.tech_.setCurrentTime(i),this.tech_.trigger({type:"usage",name:"vhs-live-resync"}),this.tech_.trigger({type:"usage",name:"hls-live-resync"}),!0}var n=this.tech_.vhs.masterPlaylistController_.sourceUpdater_,r=this.tech_.buffered();if(this.videoUnderflow_({audioBuffered:n.audioBuffered(),videoBuffered:n.videoBuffered(),currentTime:t}))return this.cancelTimer_(),this.tech_.setCurrentTime(t),this.tech_.trigger({type:"usage",name:"vhs-video-underflow"}),this.tech_.trigger({type:"usage",name:"hls-video-underflow"}),!0;var a=Y(r,t);if(a.length>0){var s=a.start(0)-t;return this.logger_("Stopped at "+t+", setting timer for "+s+", seeking to "+a.start(0)),this.cancelTimer_(),this.timer_=setTimeout(this.skipTheGap_.bind(this),1e3*s,t),!0}return !1},t.afterSeekableWindow_=function(e,t,i,n){if(void 0===n&&(n=!1),!e.length)return !1;var r=e.end(e.length-1)+X;return !i.endList&&n&&(r=e.end(e.length-1)+3*i.targetDuration),t>r},t.beforeSeekableWindow_=function(e,t){return !!(e.length&&e.start(0)>0&&t2)return {start:r,end:a}}return null},e}(),xn={errorInterval:30,getSource:function(e){return e(this.tech({IWillNotUseThisInPlugins:!0}).currentSource_||this.currentSource())}},Cn=function e(t,i){var n=0,r=0,a=u.default.mergeOptions(xn,i);t.ready((function(){t.trigger({type:"usage",name:"vhs-error-reload-initialized"}),t.trigger({type:"usage",name:"hls-error-reload-initialized"});}));var s=function(){r&&t.currentTime(r);},o=function(e){null!=e&&(r=t.duration()!==1/0&&t.currentTime()||0,t.one("loadedmetadata",s),t.src(e),t.trigger({type:"usage",name:"vhs-error-reload"}),t.trigger({type:"usage",name:"hls-error-reload"}),t.play());},d=function(){return Date.now()-n<1e3*a.errorInterval?(t.trigger({type:"usage",name:"vhs-error-reload-canceled"}),void t.trigger({type:"usage",name:"hls-error-reload-canceled"})):a.getSource&&"function"==typeof a.getSource?(n=Date.now(),a.getSource.call(t,o)):void u.default.log.error("ERROR: reloadSourceOnError - The option getSource must be a function!")},l=function e(){t.off("loadedmetadata",s),t.off("error",d),t.off("dispose",e);};t.on("error",d),t.on("dispose",l),t.reloadSourceOnError=function(i){l(),e(t,i);};},Un=function(e){Cn(this,e);},Dn="2.8.1",Rn={PlaylistLoader:V,Playlist:Ie,utils:Fe,STANDARD_PLAYLIST_SELECTOR:xi,INITIAL_PLAYLIST_SELECTOR:function(){var e=this,t=this.playlists.master.playlists.filter(Ie.isEnabled);return Pi(t,(function(e,t){return Oi(e,t)})),t.filter((function(t){return !!Ei(e.playlists.master,t).video}))[0]||null},lastBandwidthSelector:xi,movingAverageBandwidthSelector:function(e){var t=-1;if(e<0||e>1)throw new Error("Moving average bandwidth decay must be between 0 and 1.");return function(){var i=this.useDevicePixelRatio&&o.default.devicePixelRatio||1;return t<0&&(t=this.systemBandwidth),t=e*this.systemBandwidth+(1-e)*t,ki(this.playlists.master,t,parseInt(Li(this.tech_.el(),"width"),10)*i,parseInt(Li(this.tech_.el(),"height"),10)*i,this.limitRenditionByPlayerDimensions,this.masterPlaylistController_)}},comparePlaylistBandwidth:Oi,comparePlaylistResolution:function(e,t){var i,n;return e.attributes.RESOLUTION&&e.attributes.RESOLUTION.width&&(i=e.attributes.RESOLUTION.width),i=i||o.default.Number.MAX_VALUE,t.attributes.RESOLUTION&&t.attributes.RESOLUTION.width&&(n=t.attributes.RESOLUTION.width),i===(n=n||o.default.Number.MAX_VALUE)&&e.attributes.BANDWIDTH&&t.attributes.BANDWIDTH?e.attributes.BANDWIDTH-t.attributes.BANDWIDTH:i-n},xhr:Le()};Object.keys(ii).forEach((function(e){Object.defineProperty(Rn,e,{get:function(){return u.default.log.warn("using Vhs."+e+" is UNSAFE be sure you know what you are doing"),ii[e]},set:function(t){u.default.log.warn("using Vhs."+e+" is UNSAFE be sure you know what you are doing"),"number"!=typeof t||t<0?u.default.log.warn("value of Vhs."+e+" must be greater than or equal to 0"):ii[e]=t;}});}));var Mn="videojs-vhs",Bn=function(e,t){for(var i=t.media(),n=-1,r=0;r0?1/this.throughput:0,Math.floor(1/(t+e))},set:function(){u.default.log.error('The "systemBandwidth" property is read-only');}}}),this.options_.bandwidth&&(this.bandwidth=this.options_.bandwidth),this.options_.throughput&&(this.throughput=this.options_.throughput),Object.defineProperties(this.stats,{bandwidth:{get:function(){return i.bandwidth||0},enumerable:!0},mediaRequests:{get:function(){return i.masterPlaylistController_.mediaRequests_()||0},enumerable:!0},mediaRequestsAborted:{get:function(){return i.masterPlaylistController_.mediaRequestsAborted_()||0},enumerable:!0},mediaRequestsTimedout:{get:function(){return i.masterPlaylistController_.mediaRequestsTimedout_()||0},enumerable:!0},mediaRequestsErrored:{get:function(){return i.masterPlaylistController_.mediaRequestsErrored_()||0},enumerable:!0},mediaTransferDuration:{get:function(){return i.masterPlaylistController_.mediaTransferDuration_()||0},enumerable:!0},mediaBytesTransferred:{get:function(){return i.masterPlaylistController_.mediaBytesTransferred_()||0},enumerable:!0},mediaSecondsLoaded:{get:function(){return i.masterPlaylistController_.mediaSecondsLoaded_()||0},enumerable:!0},buffered:{get:function(){return $(i.tech_.buffered())},enumerable:!0},currentTime:{get:function(){return i.tech_.currentTime()},enumerable:!0},currentSource:{get:function(){return i.tech_.currentSource_},enumerable:!0},currentTech:{get:function(){return i.tech_.name_},enumerable:!0},duration:{get:function(){return i.tech_.duration()},enumerable:!0},master:{get:function(){return i.playlists.master},enumerable:!0},playerDimensions:{get:function(){return i.tech_.currentDimensions()},enumerable:!0},seekable:{get:function(){return $(i.tech_.seekable())},enumerable:!0},timestamp:{get:function(){return Date.now()},enumerable:!0},videoPlaybackQuality:{get:function(){return i.tech_.getVideoPlaybackQuality()},enumerable:!0}}),this.tech_.one("canplay",this.masterPlaylistController_.setupFirstPlay.bind(this.masterPlaylistController_)),this.tech_.on("bandwidthupdate",(function(){i.options_.useBandwidthFromLocalStorage&&function(e){if(!o.default.localStorage)return !1;var t=Gn();t=t?u.default.mergeOptions(t,e):e;try{o.default.localStorage.setItem(Mn,JSON.stringify(t));}catch(e){return !1}}({bandwidth:i.bandwidth,throughput:Math.round(i.throughput)});})),this.masterPlaylistController_.on("selectedinitialmedia",(function(){var e;(e=i).representations=function(){var t=e.masterPlaylistController_.master(),i=Se(t)?e.masterPlaylistController_.getAudioTrackPlaylists_():t.playlists;return i?i.filter((function(e){return !ge(e)})).map((function(t,i){return new Pn(e,t,t.id)})):[]};})),this.masterPlaylistController_.sourceUpdater_.on("createdsourcebuffers",(function(){i.setupEme_();})),this.on(this.masterPlaylistController_,"progress",(function(){this.tech_.trigger("progress");})),this.on(this.masterPlaylistController_,"firstplay",(function(){this.ignoreNextSeekingEvent_=!0;})),this.setupQualityLevels_(),this.tech_.el()&&(this.mediaSourceUrl_=o.default.URL.createObjectURL(this.masterPlaylistController_.mediaSource),this.tech_.src(this.mediaSourceUrl_));}},i.setupEme_=function(){var e=this,t=this.masterPlaylistController_.mediaTypes_.AUDIO.activePlaylistLoader,i=Hn({player:this.player_,sourceKeySystems:this.source_.keySystems,media:this.playlists.media(),audioMedia:t&&t.media()});11!==u.default.browser.IE_VERSION&&i?(this.logger_("waiting for EME key session creation"),qn({player:this.player_,sourceKeySystems:this.source_.keySystems,audioMedia:t&&t.media(),mainPlaylists:this.playlists.master.playlists}).then((function(){e.logger_("created EME key session"),e.masterPlaylistController_.sourceUpdater_.initializedEme();})).catch((function(t){e.logger_("error while creating EME key session",t),e.player_.error({message:"Failed to initialize media keys for EME",code:3});}))):this.masterPlaylistController_.sourceUpdater_.initializedEme();},i.setupQualityLevels_=function(){var e=this,t=u.default.players[this.tech_.options_.playerId];t&&t.qualityLevels&&!this.qualityLevels_&&(this.qualityLevels_=t.qualityLevels(),this.masterPlaylistController_.on("selectedinitialmedia",(function(){var t,i;t=e.qualityLevels_,(i=e).representations().forEach((function(e){t.addQualityLevel(e);})),Bn(t,i.playlists);})),this.playlists.on("mediachange",(function(){Bn(e.qualityLevels_,e.playlists);})));},t.version=function(){return {"@videojs/http-streaming":Dn,"mux.js":"5.11.0","mpd-parser":"0.16.0","m3u8-parser":"4.7.0","aes-decrypter":"3.1.2"}},i.version=function(){return this.constructor.version()},i.canChangeType=function(){return on.canChangeType()},i.play=function(){this.masterPlaylistController_.play();},i.setCurrentTime=function(e){this.masterPlaylistController_.setCurrentTime(e);},i.duration=function(){return this.masterPlaylistController_.duration()},i.seekable=function(){return this.masterPlaylistController_.seekable()},i.dispose=function(){this.playbackWatcher_&&this.playbackWatcher_.dispose(),this.masterPlaylistController_&&this.masterPlaylistController_.dispose(),this.qualityLevels_&&this.qualityLevels_.dispose(),this.player_&&(delete this.player_.vhs,delete this.player_.dash,delete this.player_.hls),this.tech_&&this.tech_.vhs&&delete this.tech_.vhs,this.tech_&&delete this.tech_.hls,this.mediaSourceUrl_&&o.default.URL.revokeObjectURL&&(o.default.URL.revokeObjectURL(this.mediaSourceUrl_),this.mediaSourceUrl_=null),e.prototype.dispose.call(this);},i.convertToProgramTime=function(e,t){return function(e){var t=e.playlist,i=e.time,n=void 0===i?void 0:i,r=e.callback;if(!r)throw new Error("getProgramTime: callback must be provided");if(!t||void 0===n)return r({message:"getProgramTime: playlist and time must be provided"});var a=function(e,t){if(!t||!t.segments||0===t.segments.length)return null;for(var i,n=0,r=0;rn){if(e>n+.25*a.duration)return null;i=a;}return {segment:i,estimatedStart:i.videoTimingInfo?i.videoTimingInfo.transmuxedPresentationStart:n-i.duration,type:i.videoTimingInfo?"accurate":"estimate"}}(n,t);if(!a)return r({message:"valid programTime was not found"});if("estimate"===a.type)return r({message:"Accurate programTime could not be determined. Please seek to e.seekTime and try again",seekTime:a.estimatedStart});var s={mediaSeconds:n},o=function(e,t){if(!t.dateTimeObject)return null;var i=t.videoTimingInfo.transmuxerPrependedSeconds,n=e-(t.videoTimingInfo.transmuxedPresentationStart+i);return new Date(t.dateTimeObject.getTime()+1e3*n)}(n,a.segment);return o&&(s.programDateTime=o.toISOString()),r(null,s)}({playlist:this.masterPlaylistController_.media(),time:e,callback:t})},i.seekToProgramTime=function(e,t,i,n){return void 0===i&&(i=!0),void 0===n&&(n=2),qe({programTime:e,playlist:this.masterPlaylistController_.media(),retryCount:n,pauseAfterSeek:i,seekTo:this.options_.seekTo,tech:this.options_.tech,callback:t})},t}(u.default.getComponent("Component")),jn={name:"videojs-http-streaming",VERSION:Dn,canHandleSource:function(e,t){void 0===t&&(t={});var i=u.default.mergeOptions(u.default.options,t);return jn.canPlayType(e.type,i)},handleSource:function(e,t,i){void 0===i&&(i={});var n=u.default.mergeOptions(u.default.options,i);return t.vhs=new Vn(e,t,n),u.default.hasOwnProperty("hls")||Object.defineProperty(t,"hls",{get:function(){return u.default.log.warn("player.tech().hls is deprecated. Use player.tech().vhs instead."),t.vhs},configurable:!0}),t.vhs.xhr=Le(),t.vhs.src(e.src,e.type),t.vhs},canPlayType:function(e,t){void 0===t&&(t={});var i=u.default.mergeOptions(u.default.options,t).vhs.overrideNative,n=void 0===i?!u.default.browser.IS_ANY_SAFARI:i,r=xe(e);return !r||Rn.supportsTypeNatively(r)&&!n?"":"maybe"}};se("avc1.4d400d,mp4a.40.2")&&u.default.getTech("Html5").registerSourceHandler(jn,0),u.default.VhsHandler=Vn,Object.defineProperty(u.default,"HlsHandler",{get:function(){return u.default.log.warn("videojs.HlsHandler is deprecated. Use videojs.VhsHandler instead."),Vn},configurable:!0}),u.default.VhsSourceHandler=jn,Object.defineProperty(u.default,"HlsSourceHandler",{get:function(){return u.default.log.warn("videojs.HlsSourceHandler is deprecated. Use videojs.VhsSourceHandler instead."),jn},configurable:!0}),u.default.Vhs=Rn,Object.defineProperty(u.default,"Hls",{get:function(){return u.default.log.warn("videojs.Hls is deprecated. Use videojs.Vhs instead."),Rn},configurable:!0}),u.default.use||(u.default.registerComponent("Hls",Rn),u.default.registerComponent("Vhs",Rn)),u.default.options.vhs=u.default.options.vhs||{},u.default.options.hls=u.default.options.hls||{},u.default.registerPlugin?u.default.registerPlugin("reloadSourceOnError",Un):u.default.plugin("reloadSourceOnError",Un),e.LOCAL_STORAGE_KEY=Mn,e.Vhs=Rn,e.VhsHandler=Vn,e.VhsSourceHandler=jn,e.emeKeySystems=Nn,e.expandDataUri=Wn,e.getAllPsshKeySystemsOptions=Fn,e.setupEmeOptions=Hn,e.simpleTypeFromSourceType=xe,e.waitForKeySessionCreation=qn,Object.defineProperty(e,"__esModule",{value:!0});})); +/*! @name aes-decrypter @version 3.1.2 @license Apache-2.0 */r(null,(e=d).subarray(0,e.byteLength-e[e.byteLength-1]));}));}return e.prototype.decryptChunk_=function(e,t,i,n){return function(){var r=function(e,t,i){var n,r,a,o,d,l,h,c,f,p=new Int32Array(e.buffer,e.byteOffset,e.byteLength>>2),m=new s(Array.prototype.slice.call(t)),g=new Uint8Array(e.byteLength),y=new Int32Array(g.buffer);for(n=i[0],r=i[1],a=i[2],o=i[3],f=0;f=0&&(t="main-desc"),t},_n=function(e,t){e.abort(),e.pause(),t&&t.activePlaylistLoader&&(t.activePlaylistLoader.pause(),t.activePlaylistLoader=null);},vn=function(e,t){t.activePlaylistLoader=e,e.load();},Tn={AUDIO:function(e,t){return function(){var i=t.segmentLoaders[e],n=t.mediaTypes[e],r=t.blacklistCurrentPlaylist;_n(i,n);var a=n.activeTrack(),s=n.activeGroup(),o=(s.filter((function(e){return e.default}))[0]||s[0]).id,d=n.tracks[o];if(a!==d){for(var l in u.default.log.warn("Problem encountered loading the alternate audio track.Switching back to default."),n.tracks)n.tracks[l].enabled=n.tracks[l]===d;n.onTrackChanged();}else r({message:"Problem encountered loading the default audio track."});}},SUBTITLES:function(e,t){return function(){var i=t.segmentLoaders[e],n=t.mediaTypes[e];u.default.log.warn("Problem encountered loading the subtitle track.Disabling subtitle track."),_n(i,n);var r=n.activeTrack();r&&(r.mode="disabled"),n.onTrackChanged();}}},bn={AUDIO:function(e,t,i){if(t){var n=i.tech,r=i.requestOptions,a=i.segmentLoaders[e];t.on("loadedmetadata",(function(){var e=t.media();a.playlist(e,r),(!n.paused()||e.endList&&"none"!==n.preload())&&a.load();})),t.on("loadedplaylist",(function(){a.playlist(t.media(),r),n.paused()||a.load();})),t.on("error",Tn[e](e,i));}},SUBTITLES:function(e,t,i){var n=i.tech,r=i.requestOptions,a=i.segmentLoaders[e],s=i.mediaTypes[e];t.on("loadedmetadata",(function(){var e=t.media();a.playlist(e,r),a.track(s.activeTrack()),(!n.paused()||e.endList&&"none"!==n.preload())&&a.load();})),t.on("loadedplaylist",(function(){a.playlist(t.media(),r),n.paused()||a.load();})),t.on("error",Tn[e](e,i));}},Sn={AUDIO:function(e,t){var i=t.vhs,n=t.sourceType,r=t.segmentLoaders[e],a=t.requestOptions,s=t.master.mediaGroups,o=t.mediaTypes[e],d=o.groups,l=o.tracks,h=o.logger_,c=t.masterPlaylistLoader,f=Se(c.master);for(var p in s[e]&&0!==Object.keys(s[e]).length||(s[e]={main:{default:{default:!0}}}),s[e])for(var m in d[p]||(d[p]=[]),s[e][p]){var g=s[e][p][m],y=void 0;if(f?(h("AUDIO group '"+p+"' label '"+m+"' is a master playlist"),g.isMasterPlaylist=!0,y=null):y="vhs-json"===n&&g.playlists?new V(g.playlists[0],i,a):g.resolvedUri?new V(g.resolvedUri,i,a):g.playlists&&"dash"===n?new ti(g.playlists[0],i,a,c):null,g=u.default.mergeOptions({id:m,playlistLoader:y},g),bn[e](e,g.playlistLoader,t),d[p].push(g),void 0===l[m]){var _=new u.default.AudioTrack({id:m,kind:yn(g),enabled:!1,language:g.language,default:g.default,label:m});l[m]=_;}}r.on("error",Tn[e](e,t));},SUBTITLES:function(e,t){var i=t.tech,n=t.vhs,r=t.sourceType,a=t.segmentLoaders[e],s=t.requestOptions,o=t.master.mediaGroups,d=t.mediaTypes[e],l=d.groups,h=d.tracks,c=t.masterPlaylistLoader;for(var f in o[e])for(var p in l[f]||(l[f]=[]),o[e][f])if(!o[e][f][p].forced){var m=o[e][f][p],g=void 0;if("hls"===r)g=new V(m.resolvedUri,n,s);else if("dash"===r){if(!m.playlists.filter((function(e){return e.excludeUntil!==1/0})).length)return;g=new ti(m.playlists[0],n,s,c);}else "vhs-json"===r&&(g=new V(m.playlists?m.playlists[0]:m.resolvedUri,n,s));if(m=u.default.mergeOptions({id:p,playlistLoader:g},m),bn[e](e,m.playlistLoader,t),l[f].push(m),void 0===h[p]){var y=i.addRemoteTextTrack({id:p,kind:"subtitles",default:m.default&&m.autoselect,language:m.language,label:p},!1).track;h[p]=y;}}a.on("error",Tn[e](e,t));},"CLOSED-CAPTIONS":function(e,t){var i=t.tech,n=t.master.mediaGroups,r=t.mediaTypes[e],a=r.groups,s=r.tracks;for(var o in n[e])for(var d in a[o]||(a[o]=[]),n[e][o]){var l=n[e][o][d];if(l.instreamId.match(/CC\d/)&&(a[o].push(u.default.mergeOptions({id:d},l)),void 0===s[d])){var h=i.addRemoteTextTrack({id:l.instreamId,kind:"captions",default:l.default&&l.autoselect,language:l.language,label:d},!1).track;s[d]=h;}}}},In=function e(t,i){for(var n=0;n "+a+" from "+t),this.tech_.trigger({type:"usage",name:"vhs-rendition-change-"+t})),this.masterPlaylistLoader_.media(e,i);},i.startABRTimer_=function(){var e=this;this.stopABRTimer_(),this.abrTimer_=o.default.setInterval((function(){return e.checkABR_()}),250);},i.stopABRTimer_=function(){this.tech_.scrubbing&&this.tech_.scrubbing()||(o.default.clearInterval(this.abrTimer_),this.abrTimer_=null);},i.getAudioTrackPlaylists_=function(){var e=this.master();if(!e||!e.mediaGroups||!e.mediaGroups.AUDIO)return e&&e.playlists||[];var t,i=e.mediaGroups.AUDIO,n=Object.keys(i);if(Object.keys(this.mediaTypes_.AUDIO.groups).length)t=this.mediaTypes_.AUDIO.activeTrack();else {var r=i.main||n.length&&i[n[0]];for(var a in r)if(r[a].default){t={label:a};break}}if(!t)return [];var s=[];for(var o in i)if(i[o][t.label]){var u=i[o][t.label];u.playlists?s.push.apply(s,u.playlists):s.push(u);}return s},i.setupMasterPlaylistLoaderListeners_=function(){var e=this;this.masterPlaylistLoader_.on("loadedmetadata",(function(){var t=e.masterPlaylistLoader_.media(),i=1.5*t.targetDuration*1e3;ve(e.masterPlaylistLoader_.master,e.masterPlaylistLoader_.media())?e.requestOptions_.timeout=0:e.requestOptions_.timeout=i,t.endList&&"none"!==e.tech_.preload()&&(e.mainSegmentLoader_.playlist(t,e.requestOptions_),e.mainSegmentLoader_.load()),function(e){["AUDIO","SUBTITLES","CLOSED-CAPTIONS"].forEach((function(t){Sn[t](t,e);}));var t=e.mediaTypes,i=e.masterPlaylistLoader,n=e.tech,r=e.vhs,a=e.segmentLoaders,s=a.AUDIO,o=a.main;["AUDIO","SUBTITLES"].forEach((function(i){t[i].activeGroup=function(e,t){return function(i){var n=t.masterPlaylistLoader,r=t.mediaTypes[e].groups,a=n.media();if(!a)return null;var s=null;a.attributes[e]&&(s=r[a.attributes[e]]);var o=Object.keys(r);if(!s)if("AUDIO"===e&&o.length>1&&Se(t.master))for(var u=0;u1&&(this.tech_.trigger({type:"usage",name:"vhs-alternate-audio"}),this.tech_.trigger({type:"usage",name:"hls-alternate-audio"})),this.useCueTags_&&(this.tech_.trigger({type:"usage",name:"vhs-playlist-cue-tags"}),this.tech_.trigger({type:"usage",name:"hls-playlist-cue-tags"}));},i.shouldSwitchToMedia_=function(e){var t=this.masterPlaylistLoader_.media(),i=this.tech_.buffered();return function(e){var t=e.currentPlaylist,i=e.nextPlaylist,n=e.forwardBuffer,r=e.bufferLowWaterLine,a=e.bufferHighWaterLine,s=e.duration,o=e.experimentalBufferBasedABR,d=e.log;if(!i)return u.default.log.warn("We received no playlist to switch to. Please check your stream."),!1;var l="allowing switch "+(t&&t.id||"null")+" -> "+i.id;if(!t||!t.endList)return d(l+" as current playlist "+(t?"is live":"is not set")),!0;if(i.id===t.id)return !1;var h=o?ii.EXPERIMENTAL_MAX_BUFFER_LOW_WATER_LINE:ii.MAX_BUFFER_LOW_WATER_LINE;if(sf)&&n>=r){var m=l+" as forwardBuffer >= bufferLowWaterLine ("+n+" >= "+r+")";return o&&(m+=" and next bandwidth > current bandwidth ("+c+" > "+f+")"),d(m),!0}return d("not "+l+" as no switching criteria met"),!1}({currentPlaylist:t,nextPlaylist:e,forwardBuffer:i.length?i.end(i.length-1)-this.tech_.currentTime():0,bufferLowWaterLine:this.bufferLowWaterLine(),bufferHighWaterLine:this.bufferHighWaterLine(),duration:this.duration(),experimentalBufferBasedABR:this.experimentalBufferBasedABR,log:this.logger_})},i.setupSegmentLoaderListeners_=function(){var e=this;this.experimentalBufferBasedABR||(this.mainSegmentLoader_.on("bandwidthupdate",(function(){var t=e.selectPlaylist();e.shouldSwitchToMedia_(t)&&e.switchMedia_(t,"bandwidthupdate"),e.tech_.trigger("bandwidthupdate");})),this.mainSegmentLoader_.on("progress",(function(){e.trigger("progress");}))),this.mainSegmentLoader_.on("error",(function(){e.blacklistCurrentPlaylist(e.mainSegmentLoader_.error());})),this.mainSegmentLoader_.on("appenderror",(function(){e.error=e.mainSegmentLoader_.error_,e.trigger("error");})),this.mainSegmentLoader_.on("syncinfoupdate",(function(){e.onSyncInfoUpdate_();})),this.mainSegmentLoader_.on("timestampoffset",(function(){e.tech_.trigger({type:"usage",name:"vhs-timestamp-offset"}),e.tech_.trigger({type:"usage",name:"hls-timestamp-offset"});})),this.audioSegmentLoader_.on("syncinfoupdate",(function(){e.onSyncInfoUpdate_();})),this.audioSegmentLoader_.on("appenderror",(function(){e.error=e.audioSegmentLoader_.error_,e.trigger("error");})),this.mainSegmentLoader_.on("ended",(function(){e.logger_("main segment loader ended"),e.onEndOfStream();})),this.mainSegmentLoader_.on("earlyabort",(function(t){e.experimentalBufferBasedABR||(e.delegateLoaders_("all",["abort"]),e.blacklistCurrentPlaylist({message:"Aborted early because there isn't enough bandwidth to complete the request without rebuffering."},120));}));var t=function(){if(!e.sourceUpdater_.hasCreatedSourceBuffers())return e.tryToCreateSourceBuffers_();var t=e.getCodecsOrExclude_();t&&e.sourceUpdater_.addOrChangeSourceBuffers(t);};this.mainSegmentLoader_.on("trackinfo",t),this.audioSegmentLoader_.on("trackinfo",t),this.mainSegmentLoader_.on("fmp4",(function(){e.triggeredFmp4Usage||(e.tech_.trigger({type:"usage",name:"vhs-fmp4"}),e.tech_.trigger({type:"usage",name:"hls-fmp4"}),e.triggeredFmp4Usage=!0);})),this.audioSegmentLoader_.on("fmp4",(function(){e.triggeredFmp4Usage||(e.tech_.trigger({type:"usage",name:"vhs-fmp4"}),e.tech_.trigger({type:"usage",name:"hls-fmp4"}),e.triggeredFmp4Usage=!0);})),this.audioSegmentLoader_.on("ended",(function(){e.logger_("audioSegmentLoader ended"),e.onEndOfStream();}));},i.mediaSecondsLoaded_=function(){return Math.max(this.audioSegmentLoader_.mediaSecondsLoaded+this.mainSegmentLoader_.mediaSecondsLoaded)},i.load=function(){this.mainSegmentLoader_.load(),this.mediaTypes_.AUDIO.activePlaylistLoader&&this.audioSegmentLoader_.load(),this.mediaTypes_.SUBTITLES.activePlaylistLoader&&this.subtitleSegmentLoader_.load();},i.smoothQualityChange_=function(e){void 0===e&&(e=this.selectPlaylist()),e!==this.masterPlaylistLoader_.media()&&(this.switchMedia_(e,"smooth-quality"),this.mainSegmentLoader_.resetLoader());},i.fastQualityChange_=function(e){var t=this;void 0===e&&(e=this.selectPlaylist()),e!==this.masterPlaylistLoader_.media()?(this.switchMedia_(e,"fast-quality"),this.mainSegmentLoader_.resetEverything((function(){u.default.browser.IE_VERSION||u.default.browser.IS_EDGE?t.tech_.setCurrentTime(t.tech_.currentTime()+.04):t.tech_.setCurrentTime(t.tech_.currentTime());}))):this.logger_("skipping fastQualityChange because new media is same as old");},i.play=function(){if(!this.setupFirstPlay()){this.tech_.ended()&&this.tech_.setCurrentTime(0),this.hasPlayed_&&this.load();var e=this.tech_.seekable();return this.tech_.duration()===1/0&&this.tech_.currentTime()r.end(0)||r.start(0)>e.end(0)?this.seekable_=r:this.seekable_=u.default.createTimeRanges([[e.start(0)>r.start(0)?e.start(0):r.start(0),e.end(0)0&&(n=Math.max(n,i.end(i.length-1))),this.mediaSource.duration!==n&&this.sourceUpdater_.setDuration(n);}},i.dispose=function(){var e=this;this.trigger("dispose"),this.decrypter_.terminate(),this.masterPlaylistLoader_.dispose(),this.mainSegmentLoader_.dispose(),this.loadOnPlay_&&this.tech_.off("play",this.loadOnPlay_),["AUDIO","SUBTITLES"].forEach((function(t){var i=e.mediaTypes_[t].groups;for(var n in i)i[n].forEach((function(e){e.playlistLoader&&e.playlistLoader.dispose();}));})),this.audioSegmentLoader_.dispose(),this.subtitleSegmentLoader_.dispose(),this.sourceUpdater_.dispose(),this.timelineChangeController_.dispose(),this.stopABRTimer_(),this.updateDuration_&&this.mediaSource.removeEventListener("sourceopen",this.updateDuration_),this.mediaSource.removeEventListener("durationchange",this.handleDurationChange_),this.mediaSource.removeEventListener("sourceopen",this.handleSourceOpen_),this.mediaSource.removeEventListener("sourceended",this.handleSourceEnded_),this.off();},i.master=function(){return this.masterPlaylistLoader_.master},i.media=function(){return this.masterPlaylistLoader_.media()||this.initialMedia_},i.areMediaTypesKnown_=function(){var e=!!this.mediaTypes_.AUDIO.activePlaylistLoader;return !(!this.mainSegmentLoader_.currentMediaInfo_||e&&!this.audioSegmentLoader_.currentMediaInfo_)},i.getCodecsOrExclude_=function(){var e=this,t={main:this.mainSegmentLoader_.currentMediaInfo_||{},audio:this.audioSegmentLoader_.currentMediaInfo_||{}};t.video=t.main;var i=Ei(this.master(),this.media()),n={},r=!!this.mediaTypes_.AUDIO.activePlaylistLoader;if(t.main.hasVideo&&(n.video=i.video||t.main.videoCodec||"avc1.4d400d"),t.main.isMuxed&&(n.video+=","+(i.audio||t.main.audioCodec||ue)),(t.main.hasAudio&&!t.main.isMuxed||t.audio.hasAudio||r)&&(n.audio=i.audio||t.main.audioCodec||t.audio.audioCodec||ue,t.audio.isFmp4=t.main.hasAudio&&!t.main.isMuxed?t.main.isFmp4:t.audio.isFmp4),n.audio||n.video){var a,s={};if(["video","audio"].forEach((function(e){if(n.hasOwnProperty(e)&&(r=t[e].isFmp4,o=n[e],!(r?se(o):oe(o)))){var i=t[e].isFmp4?"browser":"muxer";s[i]=s[i]||[],s[i].push(n[e]),"audio"===e&&(a=i);}var r,o;})),r&&a&&this.media().attributes.AUDIO){var o=this.media().attributes.AUDIO;this.master().playlists.forEach((function(t){(t.attributes&&t.attributes.AUDIO)===o&&t!==e.media()&&(t.excludeUntil=1/0);})),this.logger_("excluding audio group "+o+" as "+a+' does not support codec(s): "'+n.audio+'"');}if(!Object.keys(s).length){if(this.sourceUpdater_.hasCreatedSourceBuffers()&&!this.sourceUpdater_.canChangeType()){var u=[];if(["video","audio"].forEach((function(t){var i=(ne(e.sourceUpdater_.codecs[t]||"")[0]||{}).type,r=(ne(n[t]||"")[0]||{}).type;i&&r&&i.toLowerCase()!==r.toLowerCase()&&u.push('"'+e.sourceUpdater_.codecs[t]+'" -> "'+n[t]+'"');})),u.length)return void this.blacklistCurrentPlaylist({playlist:this.media(),message:"Codec switching not supported: "+u.join(", ")+".",blacklistDuration:1/0,internal:!0})}return n}var d=Object.keys(s).reduce((function(e,t){return e&&(e+=", "),e+(t+' does not support codec(s): "')+s[t].join(",")+'"'}),"")+".";this.blacklistCurrentPlaylist({playlist:this.media(),internal:!0,message:d,blacklistDuration:1/0});}else this.blacklistCurrentPlaylist({playlist:this.media(),message:"Could not determine codecs for playlist.",blacklistDuration:1/0});},i.tryToCreateSourceBuffers_=function(){if("open"===this.mediaSource.readyState&&!this.sourceUpdater_.hasCreatedSourceBuffers()&&this.areMediaTypesKnown_()){var e=this.getCodecsOrExclude_();if(e){this.sourceUpdater_.createSourceBuffers(e);var t=[e.video,e.audio].filter(Boolean).join(",");this.excludeIncompatibleVariants_(t);}}},i.excludeUnsupportedVariants_=function(){var e=this,t=this.master().playlists,i=[];Object.keys(t).forEach((function(n){var r=t[n];if(-1===i.indexOf(r.id)){i.push(r.id);var a=Ei(e.master,r),s=[];!a.audio||oe(a.audio)||se(a.audio)||s.push("audio codec "+a.audio),!a.video||oe(a.video)||se(a.video)||s.push("video codec "+a.video),a.text&&"stpp.ttml.im1t"===a.text&&s.push("text codec "+a.text),s.length&&(r.excludeUntil=1/0,e.logger_("excluding "+r.id+" for unsupported: "+s.join(", ")));}}));},i.excludeIncompatibleVariants_=function(e){var t=this,i=[],n=this.master().playlists,r=Si(ne(e)),a=Ii(r),s=r.video&&ne(r.video)[0]||null,o=r.audio&&ne(r.audio)[0]||null;Object.keys(n).forEach((function(e){var r=n[e];if(-1===i.indexOf(r.id)&&r.excludeUntil!==1/0){i.push(r.id);var u=[],d=Ei(t.masterPlaylistLoader_.master,r),l=Ii(d);if(d.audio||d.video){if(l!==a&&u.push('codec count "'+l+'" !== "'+a+'"'),!t.sourceUpdater_.canChangeType()){var h=d.video&&ne(d.video)[0]||null,c=d.audio&&ne(d.audio)[0]||null;h&&s&&h.type.toLowerCase()!==s.type.toLowerCase()&&u.push('video codec "'+h.type+'" !== "'+s.type+'"'),c&&o&&c.type.toLowerCase()!==o.type.toLowerCase()&&u.push('audio codec "'+c.type+'" !== "'+o.type+'"');}u.length&&(r.excludeUntil=1/0,t.logger_("blacklisting "+r.id+": "+u.join(" && ")));}}}));},i.updateAdCues_=function(e){var t=0,i=this.seekable();i.length&&(t=i.start(0)),function(e,t,i){if(void 0===i&&(i=0),e.segments)for(var n,r=i,a=0;a0&&this.logger_("resetting possible stalled download count for "+e+" loader"),this[e+"StalledDownloads_"]=0,this[e+"Buffered_"]=t.buffered_();},t.checkSegmentDownloads_=function(e){var t=this.masterPlaylistController_,i=t[e+"SegmentLoader_"],n=i.buffered_(),r=function(e,t){if(e===t)return !1;if(!e&&t||!t&&e)return !0;if(e.length!==t.length)return !0;for(var i=0;i=t.end(t.length-1)))return this.techWaiting_();this.consecutiveUpdates>=5&&e===this.lastRecordedTime?(this.consecutiveUpdates++,this.waiting_()):e===this.lastRecordedTime?this.consecutiveUpdates++:(this.consecutiveUpdates=0,this.lastRecordedTime=e);}},t.cancelTimer_=function(){this.consecutiveUpdates=0,this.timer_&&(this.logger_("cancelTimer_"),clearTimeout(this.timer_)),this.timer_=null;},t.fixesBadSeeks_=function(){if(!this.tech_.seeking())return !1;var e,t=this.seekable(),i=this.tech_.currentTime();if(this.afterSeekableWindow_(t,i,this.media(),this.allowSeeksWithinUnsafeLiveWindow)&&(e=t.end(t.length-1)),this.beforeSeekableWindow_(t,i)){var n=t.start(0);e=n+(n===t.end(0)?0:X);}if(void 0!==e)return this.logger_("Trying to seek outside of seekable at time "+i+" with seekable range "+K(t)+". Seeking to "+e+"."),this.tech_.setCurrentTime(e),!0;var r=this.tech_.buffered();return !!function(e){var t=e.buffered,i=e.targetDuration,n=e.currentTime;return !(!t.length||t.end(0)-t.start(0)<2*i||n>t.start(0)||!(t.start(0)-n "+i.end(0)+"]. Attempting to resume playback by seeking to the current time."),this.tech_.trigger({type:"usage",name:"vhs-unknown-waiting"}),void this.tech_.trigger({type:"usage",name:"hls-unknown-waiting"})):void 0}},t.techWaiting_=function(){var e=this.seekable(),t=this.tech_.currentTime();if(this.tech_.seeking()&&this.fixesBadSeeks_())return !0;if(this.tech_.seeking()||null!==this.timer_)return !0;if(this.beforeSeekableWindow_(e,t)){var i=e.end(e.length-1);return this.logger_("Fell out of live window at time "+t+". Seeking to live point (seekable end) "+i),this.cancelTimer_(),this.tech_.setCurrentTime(i),this.tech_.trigger({type:"usage",name:"vhs-live-resync"}),this.tech_.trigger({type:"usage",name:"hls-live-resync"}),!0}var n=this.tech_.vhs.masterPlaylistController_.sourceUpdater_,r=this.tech_.buffered();if(this.videoUnderflow_({audioBuffered:n.audioBuffered(),videoBuffered:n.videoBuffered(),currentTime:t}))return this.cancelTimer_(),this.tech_.setCurrentTime(t),this.tech_.trigger({type:"usage",name:"vhs-video-underflow"}),this.tech_.trigger({type:"usage",name:"hls-video-underflow"}),!0;var a=Y(r,t);if(a.length>0){var s=a.start(0)-t;return this.logger_("Stopped at "+t+", setting timer for "+s+", seeking to "+a.start(0)),this.cancelTimer_(),this.timer_=setTimeout(this.skipTheGap_.bind(this),1e3*s,t),!0}return !1},t.afterSeekableWindow_=function(e,t,i,n){if(void 0===n&&(n=!1),!e.length)return !1;var r=e.end(e.length-1)+X;return !i.endList&&n&&(r=e.end(e.length-1)+3*i.targetDuration),t>r},t.beforeSeekableWindow_=function(e,t){return !!(e.length&&e.start(0)>0&&t2)return {start:r,end:a}}return null},e}(),xn={errorInterval:30,getSource:function(e){return e(this.tech({IWillNotUseThisInPlugins:!0}).currentSource_||this.currentSource())}},Cn=function e(t,i){var n=0,r=0,a=u.default.mergeOptions(xn,i);t.ready((function(){t.trigger({type:"usage",name:"vhs-error-reload-initialized"}),t.trigger({type:"usage",name:"hls-error-reload-initialized"});}));var s=function(){r&&t.currentTime(r);},o=function(e){null!=e&&(r=t.duration()!==1/0&&t.currentTime()||0,t.one("loadedmetadata",s),t.src(e),t.trigger({type:"usage",name:"vhs-error-reload"}),t.trigger({type:"usage",name:"hls-error-reload"}),t.play());},d=function(){return Date.now()-n<1e3*a.errorInterval?(t.trigger({type:"usage",name:"vhs-error-reload-canceled"}),void t.trigger({type:"usage",name:"hls-error-reload-canceled"})):a.getSource&&"function"==typeof a.getSource?(n=Date.now(),a.getSource.call(t,o)):void u.default.log.error("ERROR: reloadSourceOnError - The option getSource must be a function!")},l=function e(){t.off("loadedmetadata",s),t.off("error",d),t.off("dispose",e);};t.on("error",d),t.on("dispose",l),t.reloadSourceOnError=function(i){l(),e(t,i);};},Un=function(e){Cn(this,e);},Dn="2.8.2",Rn={PlaylistLoader:V,Playlist:Ie,utils:Fe,STANDARD_PLAYLIST_SELECTOR:xi,INITIAL_PLAYLIST_SELECTOR:function(){var e=this,t=this.playlists.master.playlists.filter(Ie.isEnabled);return Pi(t,(function(e,t){return Oi(e,t)})),t.filter((function(t){return !!Ei(e.playlists.master,t).video}))[0]||null},lastBandwidthSelector:xi,movingAverageBandwidthSelector:function(e){var t=-1;if(e<0||e>1)throw new Error("Moving average bandwidth decay must be between 0 and 1.");return function(){var i=this.useDevicePixelRatio&&o.default.devicePixelRatio||1;return t<0&&(t=this.systemBandwidth),t=e*this.systemBandwidth+(1-e)*t,ki(this.playlists.master,t,parseInt(Li(this.tech_.el(),"width"),10)*i,parseInt(Li(this.tech_.el(),"height"),10)*i,this.limitRenditionByPlayerDimensions,this.masterPlaylistController_)}},comparePlaylistBandwidth:Oi,comparePlaylistResolution:function(e,t){var i,n;return e.attributes.RESOLUTION&&e.attributes.RESOLUTION.width&&(i=e.attributes.RESOLUTION.width),i=i||o.default.Number.MAX_VALUE,t.attributes.RESOLUTION&&t.attributes.RESOLUTION.width&&(n=t.attributes.RESOLUTION.width),i===(n=n||o.default.Number.MAX_VALUE)&&e.attributes.BANDWIDTH&&t.attributes.BANDWIDTH?e.attributes.BANDWIDTH-t.attributes.BANDWIDTH:i-n},xhr:Le()};Object.keys(ii).forEach((function(e){Object.defineProperty(Rn,e,{get:function(){return u.default.log.warn("using Vhs."+e+" is UNSAFE be sure you know what you are doing"),ii[e]},set:function(t){u.default.log.warn("using Vhs."+e+" is UNSAFE be sure you know what you are doing"),"number"!=typeof t||t<0?u.default.log.warn("value of Vhs."+e+" must be greater than or equal to 0"):ii[e]=t;}});}));var Mn="videojs-vhs",Bn=function(e,t){for(var i=t.media(),n=-1,r=0;r0?1/this.throughput:0,Math.floor(1/(t+e))},set:function(){u.default.log.error('The "systemBandwidth" property is read-only');}}}),this.options_.bandwidth&&(this.bandwidth=this.options_.bandwidth),this.options_.throughput&&(this.throughput=this.options_.throughput),Object.defineProperties(this.stats,{bandwidth:{get:function(){return i.bandwidth||0},enumerable:!0},mediaRequests:{get:function(){return i.masterPlaylistController_.mediaRequests_()||0},enumerable:!0},mediaRequestsAborted:{get:function(){return i.masterPlaylistController_.mediaRequestsAborted_()||0},enumerable:!0},mediaRequestsTimedout:{get:function(){return i.masterPlaylistController_.mediaRequestsTimedout_()||0},enumerable:!0},mediaRequestsErrored:{get:function(){return i.masterPlaylistController_.mediaRequestsErrored_()||0},enumerable:!0},mediaTransferDuration:{get:function(){return i.masterPlaylistController_.mediaTransferDuration_()||0},enumerable:!0},mediaBytesTransferred:{get:function(){return i.masterPlaylistController_.mediaBytesTransferred_()||0},enumerable:!0},mediaSecondsLoaded:{get:function(){return i.masterPlaylistController_.mediaSecondsLoaded_()||0},enumerable:!0},buffered:{get:function(){return $(i.tech_.buffered())},enumerable:!0},currentTime:{get:function(){return i.tech_.currentTime()},enumerable:!0},currentSource:{get:function(){return i.tech_.currentSource_},enumerable:!0},currentTech:{get:function(){return i.tech_.name_},enumerable:!0},duration:{get:function(){return i.tech_.duration()},enumerable:!0},master:{get:function(){return i.playlists.master},enumerable:!0},playerDimensions:{get:function(){return i.tech_.currentDimensions()},enumerable:!0},seekable:{get:function(){return $(i.tech_.seekable())},enumerable:!0},timestamp:{get:function(){return Date.now()},enumerable:!0},videoPlaybackQuality:{get:function(){return i.tech_.getVideoPlaybackQuality()},enumerable:!0}}),this.tech_.one("canplay",this.masterPlaylistController_.setupFirstPlay.bind(this.masterPlaylistController_)),this.tech_.on("bandwidthupdate",(function(){i.options_.useBandwidthFromLocalStorage&&function(e){if(!o.default.localStorage)return !1;var t=Gn();t=t?u.default.mergeOptions(t,e):e;try{o.default.localStorage.setItem(Mn,JSON.stringify(t));}catch(e){return !1}}({bandwidth:i.bandwidth,throughput:Math.round(i.throughput)});})),this.masterPlaylistController_.on("selectedinitialmedia",(function(){var e;(e=i).representations=function(){var t=e.masterPlaylistController_.master(),i=Se(t)?e.masterPlaylistController_.getAudioTrackPlaylists_():t.playlists;return i?i.filter((function(e){return !ge(e)})).map((function(t,i){return new Pn(e,t,t.id)})):[]};})),this.masterPlaylistController_.sourceUpdater_.on("createdsourcebuffers",(function(){i.setupEme_();})),this.on(this.masterPlaylistController_,"progress",(function(){this.tech_.trigger("progress");})),this.on(this.masterPlaylistController_,"firstplay",(function(){this.ignoreNextSeekingEvent_=!0;})),this.setupQualityLevels_(),this.tech_.el()&&(this.mediaSourceUrl_=o.default.URL.createObjectURL(this.masterPlaylistController_.mediaSource),this.tech_.src(this.mediaSourceUrl_));}},i.setupEme_=function(){var e=this,t=this.masterPlaylistController_.mediaTypes_.AUDIO.activePlaylistLoader,i=Hn({player:this.player_,sourceKeySystems:this.source_.keySystems,media:this.playlists.media(),audioMedia:t&&t.media()});11!==u.default.browser.IE_VERSION&&i?(this.logger_("waiting for EME key session creation"),qn({player:this.player_,sourceKeySystems:this.source_.keySystems,audioMedia:t&&t.media(),mainPlaylists:this.playlists.master.playlists}).then((function(){e.logger_("created EME key session"),e.masterPlaylistController_.sourceUpdater_.initializedEme();})).catch((function(t){e.logger_("error while creating EME key session",t),e.player_.error({message:"Failed to initialize media keys for EME",code:3});}))):this.masterPlaylistController_.sourceUpdater_.initializedEme();},i.setupQualityLevels_=function(){var e=this,t=u.default.players[this.tech_.options_.playerId];t&&t.qualityLevels&&!this.qualityLevels_&&(this.qualityLevels_=t.qualityLevels(),this.masterPlaylistController_.on("selectedinitialmedia",(function(){var t,i;t=e.qualityLevels_,(i=e).representations().forEach((function(e){t.addQualityLevel(e);})),Bn(t,i.playlists);})),this.playlists.on("mediachange",(function(){Bn(e.qualityLevels_,e.playlists);})));},t.version=function(){return {"@videojs/http-streaming":Dn,"mux.js":"5.11.0","mpd-parser":"0.16.0","m3u8-parser":"4.7.0","aes-decrypter":"3.1.2"}},i.version=function(){return this.constructor.version()},i.canChangeType=function(){return on.canChangeType()},i.play=function(){this.masterPlaylistController_.play();},i.setCurrentTime=function(e){this.masterPlaylistController_.setCurrentTime(e);},i.duration=function(){return this.masterPlaylistController_.duration()},i.seekable=function(){return this.masterPlaylistController_.seekable()},i.dispose=function(){this.playbackWatcher_&&this.playbackWatcher_.dispose(),this.masterPlaylistController_&&this.masterPlaylistController_.dispose(),this.qualityLevels_&&this.qualityLevels_.dispose(),this.player_&&(delete this.player_.vhs,delete this.player_.dash,delete this.player_.hls),this.tech_&&this.tech_.vhs&&delete this.tech_.vhs,this.tech_&&delete this.tech_.hls,this.mediaSourceUrl_&&o.default.URL.revokeObjectURL&&(o.default.URL.revokeObjectURL(this.mediaSourceUrl_),this.mediaSourceUrl_=null),e.prototype.dispose.call(this);},i.convertToProgramTime=function(e,t){return function(e){var t=e.playlist,i=e.time,n=void 0===i?void 0:i,r=e.callback;if(!r)throw new Error("getProgramTime: callback must be provided");if(!t||void 0===n)return r({message:"getProgramTime: playlist and time must be provided"});var a=function(e,t){if(!t||!t.segments||0===t.segments.length)return null;for(var i,n=0,r=0;rn){if(e>n+.25*a.duration)return null;i=a;}return {segment:i,estimatedStart:i.videoTimingInfo?i.videoTimingInfo.transmuxedPresentationStart:n-i.duration,type:i.videoTimingInfo?"accurate":"estimate"}}(n,t);if(!a)return r({message:"valid programTime was not found"});if("estimate"===a.type)return r({message:"Accurate programTime could not be determined. Please seek to e.seekTime and try again",seekTime:a.estimatedStart});var s={mediaSeconds:n},o=function(e,t){if(!t.dateTimeObject)return null;var i=t.videoTimingInfo.transmuxerPrependedSeconds,n=e-(t.videoTimingInfo.transmuxedPresentationStart+i);return new Date(t.dateTimeObject.getTime()+1e3*n)}(n,a.segment);return o&&(s.programDateTime=o.toISOString()),r(null,s)}({playlist:this.masterPlaylistController_.media(),time:e,callback:t})},i.seekToProgramTime=function(e,t,i,n){return void 0===i&&(i=!0),void 0===n&&(n=2),qe({programTime:e,playlist:this.masterPlaylistController_.media(),retryCount:n,pauseAfterSeek:i,seekTo:this.options_.seekTo,tech:this.options_.tech,callback:t})},t}(u.default.getComponent("Component")),jn={name:"videojs-http-streaming",VERSION:Dn,canHandleSource:function(e,t){void 0===t&&(t={});var i=u.default.mergeOptions(u.default.options,t);return jn.canPlayType(e.type,i)},handleSource:function(e,t,i){void 0===i&&(i={});var n=u.default.mergeOptions(u.default.options,i);return t.vhs=new Vn(e,t,n),u.default.hasOwnProperty("hls")||Object.defineProperty(t,"hls",{get:function(){return u.default.log.warn("player.tech().hls is deprecated. Use player.tech().vhs instead."),t.vhs},configurable:!0}),t.vhs.xhr=Le(),t.vhs.src(e.src,e.type),t.vhs},canPlayType:function(e,t){void 0===t&&(t={});var i=u.default.mergeOptions(u.default.options,t).vhs.overrideNative,n=void 0===i?!u.default.browser.IS_ANY_SAFARI:i,r=xe(e);return !r||Rn.supportsTypeNatively(r)&&!n?"":"maybe"}};se("avc1.4d400d,mp4a.40.2")&&u.default.getTech("Html5").registerSourceHandler(jn,0),u.default.VhsHandler=Vn,Object.defineProperty(u.default,"HlsHandler",{get:function(){return u.default.log.warn("videojs.HlsHandler is deprecated. Use videojs.VhsHandler instead."),Vn},configurable:!0}),u.default.VhsSourceHandler=jn,Object.defineProperty(u.default,"HlsSourceHandler",{get:function(){return u.default.log.warn("videojs.HlsSourceHandler is deprecated. Use videojs.VhsSourceHandler instead."),jn},configurable:!0}),u.default.Vhs=Rn,Object.defineProperty(u.default,"Hls",{get:function(){return u.default.log.warn("videojs.Hls is deprecated. Use videojs.Vhs instead."),Rn},configurable:!0}),u.default.use||(u.default.registerComponent("Hls",Rn),u.default.registerComponent("Vhs",Rn)),u.default.options.vhs=u.default.options.vhs||{},u.default.options.hls=u.default.options.hls||{},u.default.registerPlugin?u.default.registerPlugin("reloadSourceOnError",Un):u.default.plugin("reloadSourceOnError",Un),e.LOCAL_STORAGE_KEY=Mn,e.Vhs=Rn,e.VhsHandler=Vn,e.VhsSourceHandler=jn,e.emeKeySystems=Nn,e.expandDataUri=Wn,e.getAllPsshKeySystemsOptions=Fn,e.setupEmeOptions=Hn,e.simpleTypeFromSourceType=xe,e.waitForKeySessionCreation=qn,Object.defineProperty(e,"__esModule",{value:!0});})); }); var videojsHttpStreaming_min$1 = /*@__PURE__*/getDefaultExportFromCjs(videojsHttpStreaming_min); diff --git a/webroot/js/web_modules/common/core-d20ff47c.js b/webroot/js/web_modules/common/core-d20ff47c.js new file mode 100644 index 000000000..7d185c6ec --- /dev/null +++ b/webroot/js/web_modules/common/core-d20ff47c.js @@ -0,0 +1,30501 @@ +import { b as getDefaultExportFromNamespaceIfNotNamed, a as commonjsGlobal, c as createCommonjsModule } from './_commonjsHelpers-37fa8da4.js'; + +var _nodeResolve_empty = {}; + +var _nodeResolve_empty$1 = /*#__PURE__*/Object.freeze({ + __proto__: null, + 'default': _nodeResolve_empty +}); + +var minDoc = /*@__PURE__*/getDefaultExportFromNamespaceIfNotNamed(_nodeResolve_empty$1); + +var topLevel = typeof commonjsGlobal !== 'undefined' ? commonjsGlobal : + typeof window !== 'undefined' ? window : {}; + + +var doccy; + +if (typeof document !== 'undefined') { + doccy = document; +} else { + doccy = topLevel['__GLOBAL_DOCUMENT_CACHE@4']; + + if (!doccy) { + doccy = topLevel['__GLOBAL_DOCUMENT_CACHE@4'] = minDoc; + } +} + +var document_1 = doccy; + +var win; + +if (typeof window !== "undefined") { + win = window; +} else if (typeof commonjsGlobal !== "undefined") { + win = commonjsGlobal; +} else if (typeof self !== "undefined"){ + win = self; +} else { + win = {}; +} + +var window_1 = win; + +var _extends_1 = createCommonjsModule(function (module) { +function _extends() { + module.exports = _extends = Object.assign || function (target) { + for (var i = 1; i < arguments.length; i++) { + var source = arguments[i]; + + for (var key in source) { + if (Object.prototype.hasOwnProperty.call(source, key)) { + target[key] = source[key]; + } + } + } + + return target; + }; + + return _extends.apply(this, arguments); +} + +module.exports = _extends; +}); + +function _assertThisInitialized(self) { + if (self === void 0) { + throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); + } + + return self; +} + +var assertThisInitialized = _assertThisInitialized; + +function _inheritsLoose(subClass, superClass) { + subClass.prototype = Object.create(superClass.prototype); + subClass.prototype.constructor = subClass; + subClass.__proto__ = superClass; +} + +var inheritsLoose = _inheritsLoose; + +var tuple = SafeParseTuple; + +function SafeParseTuple(obj, reviver) { + var json; + var error = null; + + try { + json = JSON.parse(obj, reviver); + } catch (err) { + error = err; + } + + return [error, json] +} + +var keycode = createCommonjsModule(function (module, exports) { +// Source: http://jsfiddle.net/vWx8V/ +// http://stackoverflow.com/questions/5603195/full-list-of-javascript-keycodes + +/** + * Conenience method returns corresponding value for given keyName or keyCode. + * + * @param {Mixed} keyCode {Number} or keyName {String} + * @return {Mixed} + * @api public + */ + +function keyCode(searchInput) { + // Keyboard Events + if (searchInput && 'object' === typeof searchInput) { + var hasKeyCode = searchInput.which || searchInput.keyCode || searchInput.charCode; + if (hasKeyCode) searchInput = hasKeyCode; + } + + // Numbers + if ('number' === typeof searchInput) return names[searchInput] + + // Everything else (cast to string) + var search = String(searchInput); + + // check codes + var foundNamedKey = codes[search.toLowerCase()]; + if (foundNamedKey) return foundNamedKey + + // check aliases + var foundNamedKey = aliases[search.toLowerCase()]; + if (foundNamedKey) return foundNamedKey + + // weird character? + if (search.length === 1) return search.charCodeAt(0) + + return undefined +} + +/** + * Compares a keyboard event with a given keyCode or keyName. + * + * @param {Event} event Keyboard event that should be tested + * @param {Mixed} keyCode {Number} or keyName {String} + * @return {Boolean} + * @api public + */ +keyCode.isEventKey = function isEventKey(event, nameOrCode) { + if (event && 'object' === typeof event) { + var keyCode = event.which || event.keyCode || event.charCode; + if (keyCode === null || keyCode === undefined) { return false; } + if (typeof nameOrCode === 'string') { + // check codes + var foundNamedKey = codes[nameOrCode.toLowerCase()]; + if (foundNamedKey) { return foundNamedKey === keyCode; } + + // check aliases + var foundNamedKey = aliases[nameOrCode.toLowerCase()]; + if (foundNamedKey) { return foundNamedKey === keyCode; } + } else if (typeof nameOrCode === 'number') { + return nameOrCode === keyCode; + } + return false; + } +}; + +exports = module.exports = keyCode; + +/** + * Get by name + * + * exports.code['enter'] // => 13 + */ + +var codes = exports.code = exports.codes = { + 'backspace': 8, + 'tab': 9, + 'enter': 13, + 'shift': 16, + 'ctrl': 17, + 'alt': 18, + 'pause/break': 19, + 'caps lock': 20, + 'esc': 27, + 'space': 32, + 'page up': 33, + 'page down': 34, + 'end': 35, + 'home': 36, + 'left': 37, + 'up': 38, + 'right': 39, + 'down': 40, + 'insert': 45, + 'delete': 46, + 'command': 91, + 'left command': 91, + 'right command': 93, + 'numpad *': 106, + 'numpad +': 107, + 'numpad -': 109, + 'numpad .': 110, + 'numpad /': 111, + 'num lock': 144, + 'scroll lock': 145, + 'my computer': 182, + 'my calculator': 183, + ';': 186, + '=': 187, + ',': 188, + '-': 189, + '.': 190, + '/': 191, + '`': 192, + '[': 219, + '\\': 220, + ']': 221, + "'": 222 +}; + +// Helper aliases + +var aliases = exports.aliases = { + 'windows': 91, + '⇧': 16, + '⌥': 18, + '⌃': 17, + '⌘': 91, + 'ctl': 17, + 'control': 17, + 'option': 18, + 'pause': 19, + 'break': 19, + 'caps': 20, + 'return': 13, + 'escape': 27, + 'spc': 32, + 'spacebar': 32, + 'pgup': 33, + 'pgdn': 34, + 'ins': 45, + 'del': 46, + 'cmd': 91 +}; + +/*! + * Programatically add the following + */ + +// lower case chars +for (i = 97; i < 123; i++) codes[String.fromCharCode(i)] = i - 32; + +// numbers +for (var i = 48; i < 58; i++) codes[i - 48] = i; + +// function keys +for (i = 1; i < 13; i++) codes['f'+i] = i + 111; + +// numpad keys +for (i = 0; i < 10; i++) codes['numpad '+i] = i + 96; + +/** + * Get by code + * + * exports.name[13] // => 'Enter' + */ + +var names = exports.names = exports.title = {}; // title for backward compat + +// Create reverse mapping +for (i in codes) names[codes[i]] = i; + +// Add aliases +for (var alias in aliases) { + codes[alias] = aliases[alias]; +} +}); + +var isFunction_1 = isFunction; + +var toString$1 = Object.prototype.toString; + +function isFunction (fn) { + if (!fn) { + return false + } + var string = toString$1.call(fn); + return string === '[object Function]' || + (typeof fn === 'function' && string !== '[object RegExp]') || + (typeof window !== 'undefined' && + // IE8 and below + (fn === window.setTimeout || + fn === window.alert || + fn === window.confirm || + fn === window.prompt)) +} + +/** + * @license + * slighly modified parse-headers 2.0.2 + * Copyright (c) 2014 David Björklund + * Available under the MIT license + * + */ + +var parseHeaders = function(headers) { + var result = {}; + + if (!headers) { + return result; + } + + headers.trim().split('\n').forEach(function(row) { + var index = row.indexOf(':'); + var key = row.slice(0, index).trim().toLowerCase(); + var value = row.slice(index + 1).trim(); + + if (typeof(result[key]) === 'undefined') { + result[key] = value; + } else if (Array.isArray(result[key])) { + result[key].push(value); + } else { + result[key] = [ result[key], value ]; + } + }); + + return result; +}; + +var xhr = createXHR; +// Allow use of default import syntax in TypeScript +var _default = createXHR; +createXHR.XMLHttpRequest = window_1.XMLHttpRequest || noop; +createXHR.XDomainRequest = "withCredentials" in (new createXHR.XMLHttpRequest()) ? createXHR.XMLHttpRequest : window_1.XDomainRequest; + +forEachArray(["get", "put", "post", "patch", "head", "delete"], function(method) { + createXHR[method === "delete" ? "del" : method] = function(uri, options, callback) { + options = initParams(uri, options, callback); + options.method = method.toUpperCase(); + return _createXHR(options) + }; +}); + +function forEachArray(array, iterator) { + for (var i = 0; i < array.length; i++) { + iterator(array[i]); + } +} + +function isEmpty(obj){ + for(var i in obj){ + if(obj.hasOwnProperty(i)) return false + } + return true +} + +function initParams(uri, options, callback) { + var params = uri; + + if (isFunction_1(options)) { + callback = options; + if (typeof uri === "string") { + params = {uri:uri}; + } + } else { + params = _extends_1({}, options, {uri: uri}); + } + + params.callback = callback; + return params +} + +function createXHR(uri, options, callback) { + options = initParams(uri, options, callback); + return _createXHR(options) +} + +function _createXHR(options) { + if(typeof options.callback === "undefined"){ + throw new Error("callback argument missing") + } + + var called = false; + var callback = function cbOnce(err, response, body){ + if(!called){ + called = true; + options.callback(err, response, body); + } + }; + + function readystatechange() { + if (xhr.readyState === 4) { + setTimeout(loadFunc, 0); + } + } + + function getBody() { + // Chrome with requestType=blob throws errors arround when even testing access to responseText + var body = undefined; + + if (xhr.response) { + body = xhr.response; + } else { + body = xhr.responseText || getXml(xhr); + } + + if (isJson) { + try { + body = JSON.parse(body); + } catch (e) {} + } + + return body + } + + function errorFunc(evt) { + clearTimeout(timeoutTimer); + if(!(evt instanceof Error)){ + evt = new Error("" + (evt || "Unknown XMLHttpRequest Error") ); + } + evt.statusCode = 0; + return callback(evt, failureResponse) + } + + // will load the data & process the response in a special response object + function loadFunc() { + if (aborted) return + var status; + clearTimeout(timeoutTimer); + if(options.useXDR && xhr.status===undefined) { + //IE8 CORS GET successful response doesn't have a status field, but body is fine + status = 200; + } else { + status = (xhr.status === 1223 ? 204 : xhr.status); + } + var response = failureResponse; + var err = null; + + if (status !== 0){ + response = { + body: getBody(), + statusCode: status, + method: method, + headers: {}, + url: uri, + rawRequest: xhr + }; + if(xhr.getAllResponseHeaders){ //remember xhr can in fact be XDR for CORS in IE + response.headers = parseHeaders(xhr.getAllResponseHeaders()); + } + } else { + err = new Error("Internal XMLHttpRequest Error"); + } + return callback(err, response, response.body) + } + + var xhr = options.xhr || null; + + if (!xhr) { + if (options.cors || options.useXDR) { + xhr = new createXHR.XDomainRequest(); + }else { + xhr = new createXHR.XMLHttpRequest(); + } + } + + var key; + var aborted; + var uri = xhr.url = options.uri || options.url; + var method = xhr.method = options.method || "GET"; + var body = options.body || options.data; + var headers = xhr.headers = options.headers || {}; + var sync = !!options.sync; + var isJson = false; + var timeoutTimer; + var failureResponse = { + body: undefined, + headers: {}, + statusCode: 0, + method: method, + url: uri, + rawRequest: xhr + }; + + if ("json" in options && options.json !== false) { + isJson = true; + headers["accept"] || headers["Accept"] || (headers["Accept"] = "application/json"); //Don't override existing accept header declared by user + if (method !== "GET" && method !== "HEAD") { + headers["content-type"] || headers["Content-Type"] || (headers["Content-Type"] = "application/json"); //Don't override existing accept header declared by user + body = JSON.stringify(options.json === true ? body : options.json); + } + } + + xhr.onreadystatechange = readystatechange; + xhr.onload = loadFunc; + xhr.onerror = errorFunc; + // IE9 must have onprogress be set to a unique function. + xhr.onprogress = function () { + // IE must die + }; + xhr.onabort = function(){ + aborted = true; + }; + xhr.ontimeout = errorFunc; + xhr.open(method, uri, !sync, options.username, options.password); + //has to be after open + if(!sync) { + xhr.withCredentials = !!options.withCredentials; + } + // Cannot set timeout with sync request + // not setting timeout on the xhr object, because of old webkits etc. not handling that correctly + // both npm's request and jquery 1.x use this kind of timeout, so this is being consistent + if (!sync && options.timeout > 0 ) { + timeoutTimer = setTimeout(function(){ + if (aborted) return + aborted = true;//IE9 may still call readystatechange + xhr.abort("timeout"); + var e = new Error("XMLHttpRequest timeout"); + e.code = "ETIMEDOUT"; + errorFunc(e); + }, options.timeout ); + } + + if (xhr.setRequestHeader) { + for(key in headers){ + if(headers.hasOwnProperty(key)){ + xhr.setRequestHeader(key, headers[key]); + } + } + } else if (options.headers && !isEmpty(options.headers)) { + throw new Error("Headers cannot be set on an XDomainRequest object") + } + + if ("responseType" in options) { + xhr.responseType = options.responseType; + } + + if ("beforeSend" in options && + typeof options.beforeSend === "function" + ) { + options.beforeSend(xhr); + } + + // Microsoft Edge browser sends "undefined" when send is called with undefined value. + // XMLHttpRequest spec says to pass null as body to indicate no body + // See https://github.com/naugtur/xhr/issues/100. + xhr.send(body || null); + + return xhr + + +} + +function getXml(xhr) { + // xhr.responseXML will throw Exception "InvalidStateError" or "DOMException" + // See https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest/responseXML. + try { + if (xhr.responseType === "document") { + return xhr.responseXML + } + var firefoxBugTakenEffect = xhr.responseXML && xhr.responseXML.documentElement.nodeName === "parsererror"; + if (xhr.responseType === "" && !firefoxBugTakenEffect) { + return xhr.responseXML + } + } catch (e) {} + + return null +} + +function noop() {} +xhr.default = _default; + +/** + * Copyright 2013 vtt.js Contributors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* -*- Mode: Java; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set shiftwidth=2 tabstop=2 autoindent cindent expandtab: */ + + +var _objCreate = Object.create || (function() { + function F() {} + return function(o) { + if (arguments.length !== 1) { + throw new Error('Object.create shim only accepts one parameter.'); + } + F.prototype = o; + return new F(); + }; +})(); + +// Creates a new ParserError object from an errorData object. The errorData +// object should have default code and message properties. The default message +// property can be overriden by passing in a message parameter. +// See ParsingError.Errors below for acceptable errors. +function ParsingError(errorData, message) { + this.name = "ParsingError"; + this.code = errorData.code; + this.message = message || errorData.message; +} +ParsingError.prototype = _objCreate(Error.prototype); +ParsingError.prototype.constructor = ParsingError; + +// ParsingError metadata for acceptable ParsingErrors. +ParsingError.Errors = { + BadSignature: { + code: 0, + message: "Malformed WebVTT signature." + }, + BadTimeStamp: { + code: 1, + message: "Malformed time stamp." + } +}; + +// Try to parse input as a time stamp. +function parseTimeStamp(input) { + + function computeSeconds(h, m, s, f) { + return (h | 0) * 3600 + (m | 0) * 60 + (s | 0) + (f | 0) / 1000; + } + + var m = input.match(/^(\d+):(\d{1,2})(:\d{1,2})?\.(\d{3})/); + if (!m) { + return null; + } + + if (m[3]) { + // Timestamp takes the form of [hours]:[minutes]:[seconds].[milliseconds] + return computeSeconds(m[1], m[2], m[3].replace(":", ""), m[4]); + } else if (m[1] > 59) { + // Timestamp takes the form of [hours]:[minutes].[milliseconds] + // First position is hours as it's over 59. + return computeSeconds(m[1], m[2], 0, m[4]); + } else { + // Timestamp takes the form of [minutes]:[seconds].[milliseconds] + return computeSeconds(0, m[1], m[2], m[4]); + } +} + +// A settings object holds key/value pairs and will ignore anything but the first +// assignment to a specific key. +function Settings() { + this.values = _objCreate(null); +} + +Settings.prototype = { + // Only accept the first assignment to any key. + set: function(k, v) { + if (!this.get(k) && v !== "") { + this.values[k] = v; + } + }, + // Return the value for a key, or a default value. + // If 'defaultKey' is passed then 'dflt' is assumed to be an object with + // a number of possible default values as properties where 'defaultKey' is + // the key of the property that will be chosen; otherwise it's assumed to be + // a single value. + get: function(k, dflt, defaultKey) { + if (defaultKey) { + return this.has(k) ? this.values[k] : dflt[defaultKey]; + } + return this.has(k) ? this.values[k] : dflt; + }, + // Check whether we have a value for a key. + has: function(k) { + return k in this.values; + }, + // Accept a setting if its one of the given alternatives. + alt: function(k, v, a) { + for (var n = 0; n < a.length; ++n) { + if (v === a[n]) { + this.set(k, v); + break; + } + } + }, + // Accept a setting if its a valid (signed) integer. + integer: function(k, v) { + if (/^-?\d+$/.test(v)) { // integer + this.set(k, parseInt(v, 10)); + } + }, + // Accept a setting if its a valid percentage. + percent: function(k, v) { + if ((v.match(/^([\d]{1,3})(\.[\d]*)?%$/))) { + v = parseFloat(v); + if (v >= 0 && v <= 100) { + this.set(k, v); + return true; + } + } + return false; + } +}; + +// Helper function to parse input into groups separated by 'groupDelim', and +// interprete each group as a key/value pair separated by 'keyValueDelim'. +function parseOptions(input, callback, keyValueDelim, groupDelim) { + var groups = groupDelim ? input.split(groupDelim) : [input]; + for (var i in groups) { + if (typeof groups[i] !== "string") { + continue; + } + var kv = groups[i].split(keyValueDelim); + if (kv.length !== 2) { + continue; + } + var k = kv[0]; + var v = kv[1]; + callback(k, v); + } +} + +function parseCue(input, cue, regionList) { + // Remember the original input if we need to throw an error. + var oInput = input; + // 4.1 WebVTT timestamp + function consumeTimeStamp() { + var ts = parseTimeStamp(input); + if (ts === null) { + throw new ParsingError(ParsingError.Errors.BadTimeStamp, + "Malformed timestamp: " + oInput); + } + // Remove time stamp from input. + input = input.replace(/^[^\sa-zA-Z-]+/, ""); + return ts; + } + + // 4.4.2 WebVTT cue settings + function consumeCueSettings(input, cue) { + var settings = new Settings(); + + parseOptions(input, function (k, v) { + switch (k) { + case "region": + // Find the last region we parsed with the same region id. + for (var i = regionList.length - 1; i >= 0; i--) { + if (regionList[i].id === v) { + settings.set(k, regionList[i].region); + break; + } + } + break; + case "vertical": + settings.alt(k, v, ["rl", "lr"]); + break; + case "line": + var vals = v.split(","), + vals0 = vals[0]; + settings.integer(k, vals0); + settings.percent(k, vals0) ? settings.set("snapToLines", false) : null; + settings.alt(k, vals0, ["auto"]); + if (vals.length === 2) { + settings.alt("lineAlign", vals[1], ["start", "center", "end"]); + } + break; + case "position": + vals = v.split(","); + settings.percent(k, vals[0]); + if (vals.length === 2) { + settings.alt("positionAlign", vals[1], ["start", "center", "end"]); + } + break; + case "size": + settings.percent(k, v); + break; + case "align": + settings.alt(k, v, ["start", "center", "end", "left", "right"]); + break; + } + }, /:/, /\s/); + + // Apply default values for any missing fields. + cue.region = settings.get("region", null); + cue.vertical = settings.get("vertical", ""); + try { + cue.line = settings.get("line", "auto"); + } catch (e) {} + cue.lineAlign = settings.get("lineAlign", "start"); + cue.snapToLines = settings.get("snapToLines", true); + cue.size = settings.get("size", 100); + // Safari still uses the old middle value and won't accept center + try { + cue.align = settings.get("align", "center"); + } catch (e) { + cue.align = settings.get("align", "middle"); + } + try { + cue.position = settings.get("position", "auto"); + } catch (e) { + cue.position = settings.get("position", { + start: 0, + left: 0, + center: 50, + middle: 50, + end: 100, + right: 100 + }, cue.align); + } + + + cue.positionAlign = settings.get("positionAlign", { + start: "start", + left: "start", + center: "center", + middle: "center", + end: "end", + right: "end" + }, cue.align); + } + + function skipWhitespace() { + input = input.replace(/^\s+/, ""); + } + + // 4.1 WebVTT cue timings. + skipWhitespace(); + cue.startTime = consumeTimeStamp(); // (1) collect cue start time + skipWhitespace(); + if (input.substr(0, 3) !== "-->") { // (3) next characters must match "-->" + throw new ParsingError(ParsingError.Errors.BadTimeStamp, + "Malformed time stamp (time stamps must be separated by '-->'): " + + oInput); + } + input = input.substr(3); + skipWhitespace(); + cue.endTime = consumeTimeStamp(); // (5) collect cue end time + + // 4.1 WebVTT cue settings list. + skipWhitespace(); + consumeCueSettings(input, cue); +} + +// When evaluating this file as part of a Webpack bundle for server +// side rendering, `document` is an empty object. +var TEXTAREA_ELEMENT = document_1.createElement && document_1.createElement("textarea"); + +var TAG_NAME = { + c: "span", + i: "i", + b: "b", + u: "u", + ruby: "ruby", + rt: "rt", + v: "span", + lang: "span" +}; + +// 5.1 default text color +// 5.2 default text background color is equivalent to text color with bg_ prefix +var DEFAULT_COLOR_CLASS = { + white: 'rgba(255,255,255,1)', + lime: 'rgba(0,255,0,1)', + cyan: 'rgba(0,255,255,1)', + red: 'rgba(255,0,0,1)', + yellow: 'rgba(255,255,0,1)', + magenta: 'rgba(255,0,255,1)', + blue: 'rgba(0,0,255,1)', + black: 'rgba(0,0,0,1)' +}; + +var TAG_ANNOTATION = { + v: "title", + lang: "lang" +}; + +var NEEDS_PARENT = { + rt: "ruby" +}; + +// Parse content into a document fragment. +function parseContent(window, input) { + function nextToken() { + // Check for end-of-string. + if (!input) { + return null; + } + + // Consume 'n' characters from the input. + function consume(result) { + input = input.substr(result.length); + return result; + } + + var m = input.match(/^([^<]*)(<[^>]*>?)?/); + // If there is some text before the next tag, return it, otherwise return + // the tag. + return consume(m[1] ? m[1] : m[2]); + } + + function unescape(s) { + TEXTAREA_ELEMENT.innerHTML = s; + s = TEXTAREA_ELEMENT.textContent; + TEXTAREA_ELEMENT.textContent = ""; + return s; + } + + function shouldAdd(current, element) { + return !NEEDS_PARENT[element.localName] || + NEEDS_PARENT[element.localName] === current.localName; + } + + // Create an element for this tag. + function createElement(type, annotation) { + var tagName = TAG_NAME[type]; + if (!tagName) { + return null; + } + var element = window.document.createElement(tagName); + var name = TAG_ANNOTATION[type]; + if (name && annotation) { + element[name] = annotation.trim(); + } + return element; + } + + var rootDiv = window.document.createElement("div"), + current = rootDiv, + t, + tagStack = []; + + while ((t = nextToken()) !== null) { + if (t[0] === '<') { + if (t[1] === "/") { + // If the closing tag matches, move back up to the parent node. + if (tagStack.length && + tagStack[tagStack.length - 1] === t.substr(2).replace(">", "")) { + tagStack.pop(); + current = current.parentNode; + } + // Otherwise just ignore the end tag. + continue; + } + var ts = parseTimeStamp(t.substr(1, t.length - 2)); + var node; + if (ts) { + // Timestamps are lead nodes as well. + node = window.document.createProcessingInstruction("timestamp", ts); + current.appendChild(node); + continue; + } + var m = t.match(/^<([^.\s/0-9>]+)(\.[^\s\\>]+)?([^>\\]+)?(\\?)>?$/); + // If we can't parse the tag, skip to the next tag. + if (!m) { + continue; + } + // Try to construct an element, and ignore the tag if we couldn't. + node = createElement(m[1], m[3]); + if (!node) { + continue; + } + // Determine if the tag should be added based on the context of where it + // is placed in the cuetext. + if (!shouldAdd(current, node)) { + continue; + } + // Set the class list (as a list of classes, separated by space). + if (m[2]) { + var classes = m[2].split('.'); + + classes.forEach(function(cl) { + var bgColor = /^bg_/.test(cl); + // slice out `bg_` if it's a background color + var colorName = bgColor ? cl.slice(3) : cl; + + if (DEFAULT_COLOR_CLASS.hasOwnProperty(colorName)) { + var propName = bgColor ? 'background-color' : 'color'; + var propValue = DEFAULT_COLOR_CLASS[colorName]; + + node.style[propName] = propValue; + } + }); + + node.className = classes.join(' '); + } + // Append the node to the current node, and enter the scope of the new + // node. + tagStack.push(m[1]); + current.appendChild(node); + current = node; + continue; + } + + // Text nodes are leaf nodes. + current.appendChild(window.document.createTextNode(unescape(t))); + } + + return rootDiv; +} + +// This is a list of all the Unicode characters that have a strong +// right-to-left category. What this means is that these characters are +// written right-to-left for sure. It was generated by pulling all the strong +// right-to-left characters out of the Unicode data table. That table can +// found at: http://www.unicode.org/Public/UNIDATA/UnicodeData.txt +var strongRTLRanges = [[0x5be, 0x5be], [0x5c0, 0x5c0], [0x5c3, 0x5c3], [0x5c6, 0x5c6], + [0x5d0, 0x5ea], [0x5f0, 0x5f4], [0x608, 0x608], [0x60b, 0x60b], [0x60d, 0x60d], + [0x61b, 0x61b], [0x61e, 0x64a], [0x66d, 0x66f], [0x671, 0x6d5], [0x6e5, 0x6e6], + [0x6ee, 0x6ef], [0x6fa, 0x70d], [0x70f, 0x710], [0x712, 0x72f], [0x74d, 0x7a5], + [0x7b1, 0x7b1], [0x7c0, 0x7ea], [0x7f4, 0x7f5], [0x7fa, 0x7fa], [0x800, 0x815], + [0x81a, 0x81a], [0x824, 0x824], [0x828, 0x828], [0x830, 0x83e], [0x840, 0x858], + [0x85e, 0x85e], [0x8a0, 0x8a0], [0x8a2, 0x8ac], [0x200f, 0x200f], + [0xfb1d, 0xfb1d], [0xfb1f, 0xfb28], [0xfb2a, 0xfb36], [0xfb38, 0xfb3c], + [0xfb3e, 0xfb3e], [0xfb40, 0xfb41], [0xfb43, 0xfb44], [0xfb46, 0xfbc1], + [0xfbd3, 0xfd3d], [0xfd50, 0xfd8f], [0xfd92, 0xfdc7], [0xfdf0, 0xfdfc], + [0xfe70, 0xfe74], [0xfe76, 0xfefc], [0x10800, 0x10805], [0x10808, 0x10808], + [0x1080a, 0x10835], [0x10837, 0x10838], [0x1083c, 0x1083c], [0x1083f, 0x10855], + [0x10857, 0x1085f], [0x10900, 0x1091b], [0x10920, 0x10939], [0x1093f, 0x1093f], + [0x10980, 0x109b7], [0x109be, 0x109bf], [0x10a00, 0x10a00], [0x10a10, 0x10a13], + [0x10a15, 0x10a17], [0x10a19, 0x10a33], [0x10a40, 0x10a47], [0x10a50, 0x10a58], + [0x10a60, 0x10a7f], [0x10b00, 0x10b35], [0x10b40, 0x10b55], [0x10b58, 0x10b72], + [0x10b78, 0x10b7f], [0x10c00, 0x10c48], [0x1ee00, 0x1ee03], [0x1ee05, 0x1ee1f], + [0x1ee21, 0x1ee22], [0x1ee24, 0x1ee24], [0x1ee27, 0x1ee27], [0x1ee29, 0x1ee32], + [0x1ee34, 0x1ee37], [0x1ee39, 0x1ee39], [0x1ee3b, 0x1ee3b], [0x1ee42, 0x1ee42], + [0x1ee47, 0x1ee47], [0x1ee49, 0x1ee49], [0x1ee4b, 0x1ee4b], [0x1ee4d, 0x1ee4f], + [0x1ee51, 0x1ee52], [0x1ee54, 0x1ee54], [0x1ee57, 0x1ee57], [0x1ee59, 0x1ee59], + [0x1ee5b, 0x1ee5b], [0x1ee5d, 0x1ee5d], [0x1ee5f, 0x1ee5f], [0x1ee61, 0x1ee62], + [0x1ee64, 0x1ee64], [0x1ee67, 0x1ee6a], [0x1ee6c, 0x1ee72], [0x1ee74, 0x1ee77], + [0x1ee79, 0x1ee7c], [0x1ee7e, 0x1ee7e], [0x1ee80, 0x1ee89], [0x1ee8b, 0x1ee9b], + [0x1eea1, 0x1eea3], [0x1eea5, 0x1eea9], [0x1eeab, 0x1eebb], [0x10fffd, 0x10fffd]]; + +function isStrongRTLChar(charCode) { + for (var i = 0; i < strongRTLRanges.length; i++) { + var currentRange = strongRTLRanges[i]; + if (charCode >= currentRange[0] && charCode <= currentRange[1]) { + return true; + } + } + + return false; +} + +function determineBidi(cueDiv) { + var nodeStack = [], + text = "", + charCode; + + if (!cueDiv || !cueDiv.childNodes) { + return "ltr"; + } + + function pushNodes(nodeStack, node) { + for (var i = node.childNodes.length - 1; i >= 0; i--) { + nodeStack.push(node.childNodes[i]); + } + } + + function nextTextNode(nodeStack) { + if (!nodeStack || !nodeStack.length) { + return null; + } + + var node = nodeStack.pop(), + text = node.textContent || node.innerText; + if (text) { + // TODO: This should match all unicode type B characters (paragraph + // separator characters). See issue #115. + var m = text.match(/^.*(\n|\r)/); + if (m) { + nodeStack.length = 0; + return m[0]; + } + return text; + } + if (node.tagName === "ruby") { + return nextTextNode(nodeStack); + } + if (node.childNodes) { + pushNodes(nodeStack, node); + return nextTextNode(nodeStack); + } + } + + pushNodes(nodeStack, cueDiv); + while ((text = nextTextNode(nodeStack))) { + for (var i = 0; i < text.length; i++) { + charCode = text.charCodeAt(i); + if (isStrongRTLChar(charCode)) { + return "rtl"; + } + } + } + return "ltr"; +} + +function computeLinePos(cue) { + if (typeof cue.line === "number" && + (cue.snapToLines || (cue.line >= 0 && cue.line <= 100))) { + return cue.line; + } + if (!cue.track || !cue.track.textTrackList || + !cue.track.textTrackList.mediaElement) { + return -1; + } + var track = cue.track, + trackList = track.textTrackList, + count = 0; + for (var i = 0; i < trackList.length && trackList[i] !== track; i++) { + if (trackList[i].mode === "showing") { + count++; + } + } + return ++count * -1; +} + +function StyleBox() { +} + +// Apply styles to a div. If there is no div passed then it defaults to the +// div on 'this'. +StyleBox.prototype.applyStyles = function(styles, div) { + div = div || this.div; + for (var prop in styles) { + if (styles.hasOwnProperty(prop)) { + div.style[prop] = styles[prop]; + } + } +}; + +StyleBox.prototype.formatStyle = function(val, unit) { + return val === 0 ? 0 : val + unit; +}; + +// Constructs the computed display state of the cue (a div). Places the div +// into the overlay which should be a block level element (usually a div). +function CueStyleBox(window, cue, styleOptions) { + StyleBox.call(this); + this.cue = cue; + + // Parse our cue's text into a DOM tree rooted at 'cueDiv'. This div will + // have inline positioning and will function as the cue background box. + this.cueDiv = parseContent(window, cue.text); + var styles = { + color: "rgba(255, 255, 255, 1)", + backgroundColor: "rgba(0, 0, 0, 0.8)", + position: "relative", + left: 0, + right: 0, + top: 0, + bottom: 0, + display: "inline", + writingMode: cue.vertical === "" ? "horizontal-tb" + : cue.vertical === "lr" ? "vertical-lr" + : "vertical-rl", + unicodeBidi: "plaintext" + }; + + this.applyStyles(styles, this.cueDiv); + + // Create an absolutely positioned div that will be used to position the cue + // div. Note, all WebVTT cue-setting alignments are equivalent to the CSS + // mirrors of them except middle instead of center on Safari. + this.div = window.document.createElement("div"); + styles = { + direction: determineBidi(this.cueDiv), + writingMode: cue.vertical === "" ? "horizontal-tb" + : cue.vertical === "lr" ? "vertical-lr" + : "vertical-rl", + unicodeBidi: "plaintext", + textAlign: cue.align === "middle" ? "center" : cue.align, + font: styleOptions.font, + whiteSpace: "pre-line", + position: "absolute" + }; + + this.applyStyles(styles); + this.div.appendChild(this.cueDiv); + + // Calculate the distance from the reference edge of the viewport to the text + // position of the cue box. The reference edge will be resolved later when + // the box orientation styles are applied. + var textPos = 0; + switch (cue.positionAlign) { + case "start": + textPos = cue.position; + break; + case "center": + textPos = cue.position - (cue.size / 2); + break; + case "end": + textPos = cue.position - cue.size; + break; + } + + // Horizontal box orientation; textPos is the distance from the left edge of the + // area to the left edge of the box and cue.size is the distance extending to + // the right from there. + if (cue.vertical === "") { + this.applyStyles({ + left: this.formatStyle(textPos, "%"), + width: this.formatStyle(cue.size, "%") + }); + // Vertical box orientation; textPos is the distance from the top edge of the + // area to the top edge of the box and cue.size is the height extending + // downwards from there. + } else { + this.applyStyles({ + top: this.formatStyle(textPos, "%"), + height: this.formatStyle(cue.size, "%") + }); + } + + this.move = function(box) { + this.applyStyles({ + top: this.formatStyle(box.top, "px"), + bottom: this.formatStyle(box.bottom, "px"), + left: this.formatStyle(box.left, "px"), + right: this.formatStyle(box.right, "px"), + height: this.formatStyle(box.height, "px"), + width: this.formatStyle(box.width, "px") + }); + }; +} +CueStyleBox.prototype = _objCreate(StyleBox.prototype); +CueStyleBox.prototype.constructor = CueStyleBox; + +// Represents the co-ordinates of an Element in a way that we can easily +// compute things with such as if it overlaps or intersects with another Element. +// Can initialize it with either a StyleBox or another BoxPosition. +function BoxPosition(obj) { + // Either a BoxPosition was passed in and we need to copy it, or a StyleBox + // was passed in and we need to copy the results of 'getBoundingClientRect' + // as the object returned is readonly. All co-ordinate values are in reference + // to the viewport origin (top left). + var lh, height, width, top; + if (obj.div) { + height = obj.div.offsetHeight; + width = obj.div.offsetWidth; + top = obj.div.offsetTop; + + var rects = (rects = obj.div.childNodes) && (rects = rects[0]) && + rects.getClientRects && rects.getClientRects(); + obj = obj.div.getBoundingClientRect(); + // In certain cases the outter div will be slightly larger then the sum of + // the inner div's lines. This could be due to bold text, etc, on some platforms. + // In this case we should get the average line height and use that. This will + // result in the desired behaviour. + lh = rects ? Math.max((rects[0] && rects[0].height) || 0, obj.height / rects.length) + : 0; + + } + this.left = obj.left; + this.right = obj.right; + this.top = obj.top || top; + this.height = obj.height || height; + this.bottom = obj.bottom || (top + (obj.height || height)); + this.width = obj.width || width; + this.lineHeight = lh !== undefined ? lh : obj.lineHeight; +} + +// Move the box along a particular axis. Optionally pass in an amount to move +// the box. If no amount is passed then the default is the line height of the +// box. +BoxPosition.prototype.move = function(axis, toMove) { + toMove = toMove !== undefined ? toMove : this.lineHeight; + switch (axis) { + case "+x": + this.left += toMove; + this.right += toMove; + break; + case "-x": + this.left -= toMove; + this.right -= toMove; + break; + case "+y": + this.top += toMove; + this.bottom += toMove; + break; + case "-y": + this.top -= toMove; + this.bottom -= toMove; + break; + } +}; + +// Check if this box overlaps another box, b2. +BoxPosition.prototype.overlaps = function(b2) { + return this.left < b2.right && + this.right > b2.left && + this.top < b2.bottom && + this.bottom > b2.top; +}; + +// Check if this box overlaps any other boxes in boxes. +BoxPosition.prototype.overlapsAny = function(boxes) { + for (var i = 0; i < boxes.length; i++) { + if (this.overlaps(boxes[i])) { + return true; + } + } + return false; +}; + +// Check if this box is within another box. +BoxPosition.prototype.within = function(container) { + return this.top >= container.top && + this.bottom <= container.bottom && + this.left >= container.left && + this.right <= container.right; +}; + +// Check if this box is entirely within the container or it is overlapping +// on the edge opposite of the axis direction passed. For example, if "+x" is +// passed and the box is overlapping on the left edge of the container, then +// return true. +BoxPosition.prototype.overlapsOppositeAxis = function(container, axis) { + switch (axis) { + case "+x": + return this.left < container.left; + case "-x": + return this.right > container.right; + case "+y": + return this.top < container.top; + case "-y": + return this.bottom > container.bottom; + } +}; + +// Find the percentage of the area that this box is overlapping with another +// box. +BoxPosition.prototype.intersectPercentage = function(b2) { + var x = Math.max(0, Math.min(this.right, b2.right) - Math.max(this.left, b2.left)), + y = Math.max(0, Math.min(this.bottom, b2.bottom) - Math.max(this.top, b2.top)), + intersectArea = x * y; + return intersectArea / (this.height * this.width); +}; + +// Convert the positions from this box to CSS compatible positions using +// the reference container's positions. This has to be done because this +// box's positions are in reference to the viewport origin, whereas, CSS +// values are in referecne to their respective edges. +BoxPosition.prototype.toCSSCompatValues = function(reference) { + return { + top: this.top - reference.top, + bottom: reference.bottom - this.bottom, + left: this.left - reference.left, + right: reference.right - this.right, + height: this.height, + width: this.width + }; +}; + +// Get an object that represents the box's position without anything extra. +// Can pass a StyleBox, HTMLElement, or another BoxPositon. +BoxPosition.getSimpleBoxPosition = function(obj) { + var height = obj.div ? obj.div.offsetHeight : obj.tagName ? obj.offsetHeight : 0; + var width = obj.div ? obj.div.offsetWidth : obj.tagName ? obj.offsetWidth : 0; + var top = obj.div ? obj.div.offsetTop : obj.tagName ? obj.offsetTop : 0; + + obj = obj.div ? obj.div.getBoundingClientRect() : + obj.tagName ? obj.getBoundingClientRect() : obj; + var ret = { + left: obj.left, + right: obj.right, + top: obj.top || top, + height: obj.height || height, + bottom: obj.bottom || (top + (obj.height || height)), + width: obj.width || width + }; + return ret; +}; + +// Move a StyleBox to its specified, or next best, position. The containerBox +// is the box that contains the StyleBox, such as a div. boxPositions are +// a list of other boxes that the styleBox can't overlap with. +function moveBoxToLinePosition(window, styleBox, containerBox, boxPositions) { + + // Find the best position for a cue box, b, on the video. The axis parameter + // is a list of axis, the order of which, it will move the box along. For example: + // Passing ["+x", "-x"] will move the box first along the x axis in the positive + // direction. If it doesn't find a good position for it there it will then move + // it along the x axis in the negative direction. + function findBestPosition(b, axis) { + var bestPosition, + specifiedPosition = new BoxPosition(b), + percentage = 1; // Highest possible so the first thing we get is better. + + for (var i = 0; i < axis.length; i++) { + while (b.overlapsOppositeAxis(containerBox, axis[i]) || + (b.within(containerBox) && b.overlapsAny(boxPositions))) { + b.move(axis[i]); + } + // We found a spot where we aren't overlapping anything. This is our + // best position. + if (b.within(containerBox)) { + return b; + } + var p = b.intersectPercentage(containerBox); + // If we're outside the container box less then we were on our last try + // then remember this position as the best position. + if (percentage > p) { + bestPosition = new BoxPosition(b); + percentage = p; + } + // Reset the box position to the specified position. + b = new BoxPosition(specifiedPosition); + } + return bestPosition || specifiedPosition; + } + + var boxPosition = new BoxPosition(styleBox), + cue = styleBox.cue, + linePos = computeLinePos(cue), + axis = []; + + // If we have a line number to align the cue to. + if (cue.snapToLines) { + var size; + switch (cue.vertical) { + case "": + axis = [ "+y", "-y" ]; + size = "height"; + break; + case "rl": + axis = [ "+x", "-x" ]; + size = "width"; + break; + case "lr": + axis = [ "-x", "+x" ]; + size = "width"; + break; + } + + var step = boxPosition.lineHeight, + position = step * Math.round(linePos), + maxPosition = containerBox[size] + step, + initialAxis = axis[0]; + + // If the specified intial position is greater then the max position then + // clamp the box to the amount of steps it would take for the box to + // reach the max position. + if (Math.abs(position) > maxPosition) { + position = position < 0 ? -1 : 1; + position *= Math.ceil(maxPosition / step) * step; + } + + // If computed line position returns negative then line numbers are + // relative to the bottom of the video instead of the top. Therefore, we + // need to increase our initial position by the length or width of the + // video, depending on the writing direction, and reverse our axis directions. + if (linePos < 0) { + position += cue.vertical === "" ? containerBox.height : containerBox.width; + axis = axis.reverse(); + } + + // Move the box to the specified position. This may not be its best + // position. + boxPosition.move(initialAxis, position); + + } else { + // If we have a percentage line value for the cue. + var calculatedPercentage = (boxPosition.lineHeight / containerBox.height) * 100; + + switch (cue.lineAlign) { + case "center": + linePos -= (calculatedPercentage / 2); + break; + case "end": + linePos -= calculatedPercentage; + break; + } + + // Apply initial line position to the cue box. + switch (cue.vertical) { + case "": + styleBox.applyStyles({ + top: styleBox.formatStyle(linePos, "%") + }); + break; + case "rl": + styleBox.applyStyles({ + left: styleBox.formatStyle(linePos, "%") + }); + break; + case "lr": + styleBox.applyStyles({ + right: styleBox.formatStyle(linePos, "%") + }); + break; + } + + axis = [ "+y", "-x", "+x", "-y" ]; + + // Get the box position again after we've applied the specified positioning + // to it. + boxPosition = new BoxPosition(styleBox); + } + + var bestPosition = findBestPosition(boxPosition, axis); + styleBox.move(bestPosition.toCSSCompatValues(containerBox)); +} + +function WebVTT$1() { + // Nothing +} + +// Helper to allow strings to be decoded instead of the default binary utf8 data. +WebVTT$1.StringDecoder = function() { + return { + decode: function(data) { + if (!data) { + return ""; + } + if (typeof data !== "string") { + throw new Error("Error - expected string data."); + } + return decodeURIComponent(encodeURIComponent(data)); + } + }; +}; + +WebVTT$1.convertCueToDOMTree = function(window, cuetext) { + if (!window || !cuetext) { + return null; + } + return parseContent(window, cuetext); +}; + +var FONT_SIZE_PERCENT = 0.05; +var FONT_STYLE = "sans-serif"; +var CUE_BACKGROUND_PADDING = "1.5%"; + +// Runs the processing model over the cues and regions passed to it. +// @param overlay A block level element (usually a div) that the computed cues +// and regions will be placed into. +WebVTT$1.processCues = function(window, cues, overlay) { + if (!window || !cues || !overlay) { + return null; + } + + // Remove all previous children. + while (overlay.firstChild) { + overlay.removeChild(overlay.firstChild); + } + + var paddedOverlay = window.document.createElement("div"); + paddedOverlay.style.position = "absolute"; + paddedOverlay.style.left = "0"; + paddedOverlay.style.right = "0"; + paddedOverlay.style.top = "0"; + paddedOverlay.style.bottom = "0"; + paddedOverlay.style.margin = CUE_BACKGROUND_PADDING; + overlay.appendChild(paddedOverlay); + + // Determine if we need to compute the display states of the cues. This could + // be the case if a cue's state has been changed since the last computation or + // if it has not been computed yet. + function shouldCompute(cues) { + for (var i = 0; i < cues.length; i++) { + if (cues[i].hasBeenReset || !cues[i].displayState) { + return true; + } + } + return false; + } + + // We don't need to recompute the cues' display states. Just reuse them. + if (!shouldCompute(cues)) { + for (var i = 0; i < cues.length; i++) { + paddedOverlay.appendChild(cues[i].displayState); + } + return; + } + + var boxPositions = [], + containerBox = BoxPosition.getSimpleBoxPosition(paddedOverlay), + fontSize = Math.round(containerBox.height * FONT_SIZE_PERCENT * 100) / 100; + var styleOptions = { + font: fontSize + "px " + FONT_STYLE + }; + + (function() { + var styleBox, cue; + + for (var i = 0; i < cues.length; i++) { + cue = cues[i]; + + // Compute the intial position and styles of the cue div. + styleBox = new CueStyleBox(window, cue, styleOptions); + paddedOverlay.appendChild(styleBox.div); + + // Move the cue div to it's correct line position. + moveBoxToLinePosition(window, styleBox, containerBox, boxPositions); + + // Remember the computed div so that we don't have to recompute it later + // if we don't have too. + cue.displayState = styleBox.div; + + boxPositions.push(BoxPosition.getSimpleBoxPosition(styleBox)); + } + })(); +}; + +WebVTT$1.Parser = function(window, vttjs, decoder) { + if (!decoder) { + decoder = vttjs; + vttjs = {}; + } + if (!vttjs) { + vttjs = {}; + } + + this.window = window; + this.vttjs = vttjs; + this.state = "INITIAL"; + this.buffer = ""; + this.decoder = decoder || new TextDecoder("utf8"); + this.regionList = []; +}; + +WebVTT$1.Parser.prototype = { + // If the error is a ParsingError then report it to the consumer if + // possible. If it's not a ParsingError then throw it like normal. + reportOrThrowError: function(e) { + if (e instanceof ParsingError) { + this.onparsingerror && this.onparsingerror(e); + } else { + throw e; + } + }, + parse: function (data) { + var self = this; + + // If there is no data then we won't decode it, but will just try to parse + // whatever is in buffer already. This may occur in circumstances, for + // example when flush() is called. + if (data) { + // Try to decode the data that we received. + self.buffer += self.decoder.decode(data, {stream: true}); + } + + function collectNextLine() { + var buffer = self.buffer; + var pos = 0; + while (pos < buffer.length && buffer[pos] !== '\r' && buffer[pos] !== '\n') { + ++pos; + } + var line = buffer.substr(0, pos); + // Advance the buffer early in case we fail below. + if (buffer[pos] === '\r') { + ++pos; + } + if (buffer[pos] === '\n') { + ++pos; + } + self.buffer = buffer.substr(pos); + return line; + } + + // 3.4 WebVTT region and WebVTT region settings syntax + function parseRegion(input) { + var settings = new Settings(); + + parseOptions(input, function (k, v) { + switch (k) { + case "id": + settings.set(k, v); + break; + case "width": + settings.percent(k, v); + break; + case "lines": + settings.integer(k, v); + break; + case "regionanchor": + case "viewportanchor": + var xy = v.split(','); + if (xy.length !== 2) { + break; + } + // We have to make sure both x and y parse, so use a temporary + // settings object here. + var anchor = new Settings(); + anchor.percent("x", xy[0]); + anchor.percent("y", xy[1]); + if (!anchor.has("x") || !anchor.has("y")) { + break; + } + settings.set(k + "X", anchor.get("x")); + settings.set(k + "Y", anchor.get("y")); + break; + case "scroll": + settings.alt(k, v, ["up"]); + break; + } + }, /=/, /\s/); + + // Create the region, using default values for any values that were not + // specified. + if (settings.has("id")) { + var region = new (self.vttjs.VTTRegion || self.window.VTTRegion)(); + region.width = settings.get("width", 100); + region.lines = settings.get("lines", 3); + region.regionAnchorX = settings.get("regionanchorX", 0); + region.regionAnchorY = settings.get("regionanchorY", 100); + region.viewportAnchorX = settings.get("viewportanchorX", 0); + region.viewportAnchorY = settings.get("viewportanchorY", 100); + region.scroll = settings.get("scroll", ""); + // Register the region. + self.onregion && self.onregion(region); + // Remember the VTTRegion for later in case we parse any VTTCues that + // reference it. + self.regionList.push({ + id: settings.get("id"), + region: region + }); + } + } + + // draft-pantos-http-live-streaming-20 + // https://tools.ietf.org/html/draft-pantos-http-live-streaming-20#section-3.5 + // 3.5 WebVTT + function parseTimestampMap(input) { + var settings = new Settings(); + + parseOptions(input, function(k, v) { + switch(k) { + case "MPEGT": + settings.integer(k + 'S', v); + break; + case "LOCA": + settings.set(k + 'L', parseTimeStamp(v)); + break; + } + }, /[^\d]:/, /,/); + + self.ontimestampmap && self.ontimestampmap({ + "MPEGTS": settings.get("MPEGTS"), + "LOCAL": settings.get("LOCAL") + }); + } + + // 3.2 WebVTT metadata header syntax + function parseHeader(input) { + if (input.match(/X-TIMESTAMP-MAP/)) { + // This line contains HLS X-TIMESTAMP-MAP metadata + parseOptions(input, function(k, v) { + switch(k) { + case "X-TIMESTAMP-MAP": + parseTimestampMap(v); + break; + } + }, /=/); + } else { + parseOptions(input, function (k, v) { + switch (k) { + case "Region": + // 3.3 WebVTT region metadata header syntax + parseRegion(v); + break; + } + }, /:/); + } + + } + + // 5.1 WebVTT file parsing. + try { + var line; + if (self.state === "INITIAL") { + // We can't start parsing until we have the first line. + if (!/\r\n|\n/.test(self.buffer)) { + return this; + } + + line = collectNextLine(); + + var m = line.match(/^WEBVTT([ \t].*)?$/); + if (!m || !m[0]) { + throw new ParsingError(ParsingError.Errors.BadSignature); + } + + self.state = "HEADER"; + } + + var alreadyCollectedLine = false; + while (self.buffer) { + // We can't parse a line until we have the full line. + if (!/\r\n|\n/.test(self.buffer)) { + return this; + } + + if (!alreadyCollectedLine) { + line = collectNextLine(); + } else { + alreadyCollectedLine = false; + } + + switch (self.state) { + case "HEADER": + // 13-18 - Allow a header (metadata) under the WEBVTT line. + if (/:/.test(line)) { + parseHeader(line); + } else if (!line) { + // An empty line terminates the header and starts the body (cues). + self.state = "ID"; + } + continue; + case "NOTE": + // Ignore NOTE blocks. + if (!line) { + self.state = "ID"; + } + continue; + case "ID": + // Check for the start of NOTE blocks. + if (/^NOTE($|[ \t])/.test(line)) { + self.state = "NOTE"; + break; + } + // 19-29 - Allow any number of line terminators, then initialize new cue values. + if (!line) { + continue; + } + self.cue = new (self.vttjs.VTTCue || self.window.VTTCue)(0, 0, ""); + // Safari still uses the old middle value and won't accept center + try { + self.cue.align = "center"; + } catch (e) { + self.cue.align = "middle"; + } + self.state = "CUE"; + // 30-39 - Check if self line contains an optional identifier or timing data. + if (line.indexOf("-->") === -1) { + self.cue.id = line; + continue; + } + // Process line as start of a cue. + /*falls through*/ + case "CUE": + // 40 - Collect cue timings and settings. + try { + parseCue(line, self.cue, self.regionList); + } catch (e) { + self.reportOrThrowError(e); + // In case of an error ignore rest of the cue. + self.cue = null; + self.state = "BADCUE"; + continue; + } + self.state = "CUETEXT"; + continue; + case "CUETEXT": + var hasSubstring = line.indexOf("-->") !== -1; + // 34 - If we have an empty line then report the cue. + // 35 - If we have the special substring '-->' then report the cue, + // but do not collect the line as we need to process the current + // one as a new cue. + if (!line || hasSubstring && (alreadyCollectedLine = true)) { + // We are done parsing self cue. + self.oncue && self.oncue(self.cue); + self.cue = null; + self.state = "ID"; + continue; + } + if (self.cue.text) { + self.cue.text += "\n"; + } + self.cue.text += line.replace(/\u2028/g, '\n').replace(/u2029/g, '\n'); + continue; + case "BADCUE": // BADCUE + // 54-62 - Collect and discard the remaining cue. + if (!line) { + self.state = "ID"; + } + continue; + } + } + } catch (e) { + self.reportOrThrowError(e); + + // If we are currently parsing a cue, report what we have. + if (self.state === "CUETEXT" && self.cue && self.oncue) { + self.oncue(self.cue); + } + self.cue = null; + // Enter BADWEBVTT state if header was not parsed correctly otherwise + // another exception occurred so enter BADCUE state. + self.state = self.state === "INITIAL" ? "BADWEBVTT" : "BADCUE"; + } + return this; + }, + flush: function () { + var self = this; + try { + // Finish decoding the stream. + self.buffer += self.decoder.decode(); + // Synthesize the end of the current cue or region. + if (self.cue || self.state === "HEADER") { + self.buffer += "\n\n"; + self.parse(); + } + // If we've flushed, parsed, and we're still on the INITIAL state then + // that means we don't have enough of the stream to parse the first + // line. + if (self.state === "INITIAL") { + throw new ParsingError(ParsingError.Errors.BadSignature); + } + } catch(e) { + self.reportOrThrowError(e); + } + self.onflush && self.onflush(); + return this; + } +}; + +var vtt = WebVTT$1; + +/** + * Copyright 2013 vtt.js Contributors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +var autoKeyword = "auto"; +var directionSetting = { + "": 1, + "lr": 1, + "rl": 1 +}; +var alignSetting = { + "start": 1, + "center": 1, + "end": 1, + "left": 1, + "right": 1, + "auto": 1, + "line-left": 1, + "line-right": 1 +}; + +function findDirectionSetting(value) { + if (typeof value !== "string") { + return false; + } + var dir = directionSetting[value.toLowerCase()]; + return dir ? value.toLowerCase() : false; +} + +function findAlignSetting(value) { + if (typeof value !== "string") { + return false; + } + var align = alignSetting[value.toLowerCase()]; + return align ? value.toLowerCase() : false; +} + +function VTTCue(startTime, endTime, text) { + /** + * Shim implementation specific properties. These properties are not in + * the spec. + */ + + // Lets us know when the VTTCue's data has changed in such a way that we need + // to recompute its display state. This lets us compute its display state + // lazily. + this.hasBeenReset = false; + + /** + * VTTCue and TextTrackCue properties + * http://dev.w3.org/html5/webvtt/#vttcue-interface + */ + + var _id = ""; + var _pauseOnExit = false; + var _startTime = startTime; + var _endTime = endTime; + var _text = text; + var _region = null; + var _vertical = ""; + var _snapToLines = true; + var _line = "auto"; + var _lineAlign = "start"; + var _position = "auto"; + var _positionAlign = "auto"; + var _size = 100; + var _align = "center"; + + Object.defineProperties(this, { + "id": { + enumerable: true, + get: function() { + return _id; + }, + set: function(value) { + _id = "" + value; + } + }, + + "pauseOnExit": { + enumerable: true, + get: function() { + return _pauseOnExit; + }, + set: function(value) { + _pauseOnExit = !!value; + } + }, + + "startTime": { + enumerable: true, + get: function() { + return _startTime; + }, + set: function(value) { + if (typeof value !== "number") { + throw new TypeError("Start time must be set to a number."); + } + _startTime = value; + this.hasBeenReset = true; + } + }, + + "endTime": { + enumerable: true, + get: function() { + return _endTime; + }, + set: function(value) { + if (typeof value !== "number") { + throw new TypeError("End time must be set to a number."); + } + _endTime = value; + this.hasBeenReset = true; + } + }, + + "text": { + enumerable: true, + get: function() { + return _text; + }, + set: function(value) { + _text = "" + value; + this.hasBeenReset = true; + } + }, + + "region": { + enumerable: true, + get: function() { + return _region; + }, + set: function(value) { + _region = value; + this.hasBeenReset = true; + } + }, + + "vertical": { + enumerable: true, + get: function() { + return _vertical; + }, + set: function(value) { + var setting = findDirectionSetting(value); + // Have to check for false because the setting an be an empty string. + if (setting === false) { + throw new SyntaxError("Vertical: an invalid or illegal direction string was specified."); + } + _vertical = setting; + this.hasBeenReset = true; + } + }, + + "snapToLines": { + enumerable: true, + get: function() { + return _snapToLines; + }, + set: function(value) { + _snapToLines = !!value; + this.hasBeenReset = true; + } + }, + + "line": { + enumerable: true, + get: function() { + return _line; + }, + set: function(value) { + if (typeof value !== "number" && value !== autoKeyword) { + throw new SyntaxError("Line: an invalid number or illegal string was specified."); + } + _line = value; + this.hasBeenReset = true; + } + }, + + "lineAlign": { + enumerable: true, + get: function() { + return _lineAlign; + }, + set: function(value) { + var setting = findAlignSetting(value); + if (!setting) { + console.warn("lineAlign: an invalid or illegal string was specified."); + } else { + _lineAlign = setting; + this.hasBeenReset = true; + } + } + }, + + "position": { + enumerable: true, + get: function() { + return _position; + }, + set: function(value) { + if (value < 0 || value > 100) { + throw new Error("Position must be between 0 and 100."); + } + _position = value; + this.hasBeenReset = true; + } + }, + + "positionAlign": { + enumerable: true, + get: function() { + return _positionAlign; + }, + set: function(value) { + var setting = findAlignSetting(value); + if (!setting) { + console.warn("positionAlign: an invalid or illegal string was specified."); + } else { + _positionAlign = setting; + this.hasBeenReset = true; + } + } + }, + + "size": { + enumerable: true, + get: function() { + return _size; + }, + set: function(value) { + if (value < 0 || value > 100) { + throw new Error("Size must be between 0 and 100."); + } + _size = value; + this.hasBeenReset = true; + } + }, + + "align": { + enumerable: true, + get: function() { + return _align; + }, + set: function(value) { + var setting = findAlignSetting(value); + if (!setting) { + throw new SyntaxError("align: an invalid or illegal alignment string was specified."); + } + _align = setting; + this.hasBeenReset = true; + } + } + }); + + /** + * Other spec defined properties + */ + + // http://www.whatwg.org/specs/web-apps/current-work/multipage/the-video-element.html#text-track-cue-display-state + this.displayState = undefined; +} + +/** + * VTTCue methods + */ + +VTTCue.prototype.getCueAsHTML = function() { + // Assume WebVTT.convertCueToDOMTree is on the global. + return WebVTT.convertCueToDOMTree(window, this.text); +}; + +var vttcue = VTTCue; + +/** + * Copyright 2013 vtt.js Contributors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +var scrollSetting = { + "": true, + "up": true +}; + +function findScrollSetting(value) { + if (typeof value !== "string") { + return false; + } + var scroll = scrollSetting[value.toLowerCase()]; + return scroll ? value.toLowerCase() : false; +} + +function isValidPercentValue(value) { + return typeof value === "number" && (value >= 0 && value <= 100); +} + +// VTTRegion shim http://dev.w3.org/html5/webvtt/#vttregion-interface +function VTTRegion() { + var _width = 100; + var _lines = 3; + var _regionAnchorX = 0; + var _regionAnchorY = 100; + var _viewportAnchorX = 0; + var _viewportAnchorY = 100; + var _scroll = ""; + + Object.defineProperties(this, { + "width": { + enumerable: true, + get: function() { + return _width; + }, + set: function(value) { + if (!isValidPercentValue(value)) { + throw new Error("Width must be between 0 and 100."); + } + _width = value; + } + }, + "lines": { + enumerable: true, + get: function() { + return _lines; + }, + set: function(value) { + if (typeof value !== "number") { + throw new TypeError("Lines must be set to a number."); + } + _lines = value; + } + }, + "regionAnchorY": { + enumerable: true, + get: function() { + return _regionAnchorY; + }, + set: function(value) { + if (!isValidPercentValue(value)) { + throw new Error("RegionAnchorX must be between 0 and 100."); + } + _regionAnchorY = value; + } + }, + "regionAnchorX": { + enumerable: true, + get: function() { + return _regionAnchorX; + }, + set: function(value) { + if(!isValidPercentValue(value)) { + throw new Error("RegionAnchorY must be between 0 and 100."); + } + _regionAnchorX = value; + } + }, + "viewportAnchorY": { + enumerable: true, + get: function() { + return _viewportAnchorY; + }, + set: function(value) { + if (!isValidPercentValue(value)) { + throw new Error("ViewportAnchorY must be between 0 and 100."); + } + _viewportAnchorY = value; + } + }, + "viewportAnchorX": { + enumerable: true, + get: function() { + return _viewportAnchorX; + }, + set: function(value) { + if (!isValidPercentValue(value)) { + throw new Error("ViewportAnchorX must be between 0 and 100."); + } + _viewportAnchorX = value; + } + }, + "scroll": { + enumerable: true, + get: function() { + return _scroll; + }, + set: function(value) { + var setting = findScrollSetting(value); + // Have to check for false as an empty string is a legal value. + if (setting === false) { + console.warn("Scroll: an invalid or illegal string was specified."); + } else { + _scroll = setting; + } + } + } + }); +} + +var vttregion = VTTRegion; + +var browserIndex = createCommonjsModule(function (module) { +/** + * Copyright 2013 vtt.js Contributors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +// Default exports for Node. Export the extended versions of VTTCue and +// VTTRegion in Node since we likely want the capability to convert back and +// forth between JSON. If we don't then it's not that big of a deal since we're +// off browser. + + + +var vttjs = module.exports = { + WebVTT: vtt, + VTTCue: vttcue, + VTTRegion: vttregion +}; + +window_1.vttjs = vttjs; +window_1.WebVTT = vttjs.WebVTT; + +var cueShim = vttjs.VTTCue; +var regionShim = vttjs.VTTRegion; +var nativeVTTCue = window_1.VTTCue; +var nativeVTTRegion = window_1.VTTRegion; + +vttjs.shim = function() { + window_1.VTTCue = cueShim; + window_1.VTTRegion = regionShim; +}; + +vttjs.restore = function() { + window_1.VTTCue = nativeVTTCue; + window_1.VTTRegion = nativeVTTRegion; +}; + +if (!window_1.VTTCue) { + vttjs.shim(); +} +}); + +var setPrototypeOf = createCommonjsModule(function (module) { +function _setPrototypeOf(o, p) { + module.exports = _setPrototypeOf = Object.setPrototypeOf || function _setPrototypeOf(o, p) { + o.__proto__ = p; + return o; + }; + + return _setPrototypeOf(o, p); +} + +module.exports = _setPrototypeOf; +}); + +function _isNativeReflectConstruct() { + if (typeof Reflect === "undefined" || !Reflect.construct) return false; + if (Reflect.construct.sham) return false; + if (typeof Proxy === "function") return true; + + try { + Date.prototype.toString.call(Reflect.construct(Date, [], function () {})); + return true; + } catch (e) { + return false; + } +} + +var isNativeReflectConstruct = _isNativeReflectConstruct; + +var construct = createCommonjsModule(function (module) { +function _construct(Parent, args, Class) { + if (isNativeReflectConstruct()) { + module.exports = _construct = Reflect.construct; + } else { + module.exports = _construct = function _construct(Parent, args, Class) { + var a = [null]; + a.push.apply(a, args); + var Constructor = Function.bind.apply(Parent, a); + var instance = new Constructor(); + if (Class) setPrototypeOf(instance, Class.prototype); + return instance; + }; + } + + return _construct.apply(null, arguments); +} + +module.exports = _construct; +}); + +function _inherits(subClass, superClass) { + if (typeof superClass !== "function" && superClass !== null) { + throw new TypeError("Super expression must either be null or a function"); + } + + subClass.prototype = Object.create(superClass && superClass.prototype, { + constructor: { + value: subClass, + writable: true, + configurable: true + } + }); + if (superClass) setPrototypeOf(subClass, superClass); +} + +var inherits = _inherits; + +function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; } + +var window__default = /*#__PURE__*/_interopDefaultLegacy(window_1); +var document__default = /*#__PURE__*/_interopDefaultLegacy(document_1); +var _extends__default = /*#__PURE__*/_interopDefaultLegacy(_extends_1); +var _assertThisInitialized__default = /*#__PURE__*/_interopDefaultLegacy(assertThisInitialized); +var _inheritsLoose__default = /*#__PURE__*/_interopDefaultLegacy(inheritsLoose); +var safeParseTuple__default = /*#__PURE__*/_interopDefaultLegacy(tuple); +var keycode__default = /*#__PURE__*/_interopDefaultLegacy(keycode); +var XHR__default = /*#__PURE__*/_interopDefaultLegacy(xhr); +var vtt__default = /*#__PURE__*/_interopDefaultLegacy(browserIndex); +var _construct__default = /*#__PURE__*/_interopDefaultLegacy(construct); +var _inherits__default = /*#__PURE__*/_interopDefaultLegacy(inherits); + +var version = "7.12.3"; + +/** + * @file fullscreen-api.js + * @module fullscreen-api + * @private + */ +/** + * Store the browser-specific methods for the fullscreen API. + * + * @type {Object} + * @see [Specification]{@link https://fullscreen.spec.whatwg.org} + * @see [Map Approach From Screenfull.js]{@link https://github.com/sindresorhus/screenfull.js} + */ + +var FullscreenApi = { + prefixed: true +}; // browser API methods + +var apiMap = [['requestFullscreen', 'exitFullscreen', 'fullscreenElement', 'fullscreenEnabled', 'fullscreenchange', 'fullscreenerror', 'fullscreen'], // WebKit +['webkitRequestFullscreen', 'webkitExitFullscreen', 'webkitFullscreenElement', 'webkitFullscreenEnabled', 'webkitfullscreenchange', 'webkitfullscreenerror', '-webkit-full-screen'], // Mozilla +['mozRequestFullScreen', 'mozCancelFullScreen', 'mozFullScreenElement', 'mozFullScreenEnabled', 'mozfullscreenchange', 'mozfullscreenerror', '-moz-full-screen'], // Microsoft +['msRequestFullscreen', 'msExitFullscreen', 'msFullscreenElement', 'msFullscreenEnabled', 'MSFullscreenChange', 'MSFullscreenError', '-ms-fullscreen']]; +var specApi = apiMap[0]; +var browserApi; // determine the supported set of functions + +for (var i = 0; i < apiMap.length; i++) { + // check for exitFullscreen function + if (apiMap[i][1] in document__default['default']) { + browserApi = apiMap[i]; + break; + } +} // map the browser API names to the spec API names + + +if (browserApi) { + for (var _i = 0; _i < browserApi.length; _i++) { + FullscreenApi[specApi[_i]] = browserApi[_i]; + } + + FullscreenApi.prefixed = browserApi[0] !== specApi[0]; +} + +/** + * @file create-logger.js + * @module create-logger + */ + +var history = []; +/** + * Log messages to the console and history based on the type of message + * + * @private + * @param {string} type + * The name of the console method to use. + * + * @param {Array} args + * The arguments to be passed to the matching console method. + */ + +var LogByTypeFactory = function LogByTypeFactory(name, log) { + return function (type, level, args) { + var lvl = log.levels[level]; + var lvlRegExp = new RegExp("^(" + lvl + ")$"); + + if (type !== 'log') { + // Add the type to the front of the message when it's not "log". + args.unshift(type.toUpperCase() + ':'); + } // Add console prefix after adding to history. + + + args.unshift(name + ':'); // Add a clone of the args at this point to history. + + if (history) { + history.push([].concat(args)); // only store 1000 history entries + + var splice = history.length - 1000; + history.splice(0, splice > 0 ? splice : 0); + } // If there's no console then don't try to output messages, but they will + // still be stored in history. + + + if (!window__default['default'].console) { + return; + } // Was setting these once outside of this function, but containing them + // in the function makes it easier to test cases where console doesn't exist + // when the module is executed. + + + var fn = window__default['default'].console[type]; + + if (!fn && type === 'debug') { + // Certain browsers don't have support for console.debug. For those, we + // should default to the closest comparable log. + fn = window__default['default'].console.info || window__default['default'].console.log; + } // Bail out if there's no console or if this type is not allowed by the + // current logging level. + + + if (!fn || !lvl || !lvlRegExp.test(type)) { + return; + } + + fn[Array.isArray(args) ? 'apply' : 'call'](window__default['default'].console, args); + }; +}; + +function createLogger$1(name) { + // This is the private tracking variable for logging level. + var level = 'info'; // the curried logByType bound to the specific log and history + + var logByType; + /** + * Logs plain debug messages. Similar to `console.log`. + * + * Due to [limitations](https://github.com/jsdoc3/jsdoc/issues/955#issuecomment-313829149) + * of our JSDoc template, we cannot properly document this as both a function + * and a namespace, so its function signature is documented here. + * + * #### Arguments + * ##### *args + * Mixed[] + * + * Any combination of values that could be passed to `console.log()`. + * + * #### Return Value + * + * `undefined` + * + * @namespace + * @param {Mixed[]} args + * One or more messages or objects that should be logged. + */ + + var log = function log() { + for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) { + args[_key] = arguments[_key]; + } + + logByType('log', level, args); + }; // This is the logByType helper that the logging methods below use + + + logByType = LogByTypeFactory(name, log); + /** + * Create a new sublogger which chains the old name to the new name. + * + * For example, doing `videojs.log.createLogger('player')` and then using that logger will log the following: + * ```js + * mylogger('foo'); + * // > VIDEOJS: player: foo + * ``` + * + * @param {string} name + * The name to add call the new logger + * @return {Object} + */ + + log.createLogger = function (subname) { + return createLogger$1(name + ': ' + subname); + }; + /** + * Enumeration of available logging levels, where the keys are the level names + * and the values are `|`-separated strings containing logging methods allowed + * in that logging level. These strings are used to create a regular expression + * matching the function name being called. + * + * Levels provided by Video.js are: + * + * - `off`: Matches no calls. Any value that can be cast to `false` will have + * this effect. The most restrictive. + * - `all`: Matches only Video.js-provided functions (`debug`, `log`, + * `log.warn`, and `log.error`). + * - `debug`: Matches `log.debug`, `log`, `log.warn`, and `log.error` calls. + * - `info` (default): Matches `log`, `log.warn`, and `log.error` calls. + * - `warn`: Matches `log.warn` and `log.error` calls. + * - `error`: Matches only `log.error` calls. + * + * @type {Object} + */ + + + log.levels = { + all: 'debug|log|warn|error', + off: '', + debug: 'debug|log|warn|error', + info: 'log|warn|error', + warn: 'warn|error', + error: 'error', + DEFAULT: level + }; + /** + * Get or set the current logging level. + * + * If a string matching a key from {@link module:log.levels} is provided, acts + * as a setter. + * + * @param {string} [lvl] + * Pass a valid level to set a new logging level. + * + * @return {string} + * The current logging level. + */ + + log.level = function (lvl) { + if (typeof lvl === 'string') { + if (!log.levels.hasOwnProperty(lvl)) { + throw new Error("\"" + lvl + "\" in not a valid log level"); + } + + level = lvl; + } + + return level; + }; + /** + * Returns an array containing everything that has been logged to the history. + * + * This array is a shallow clone of the internal history record. However, its + * contents are _not_ cloned; so, mutating objects inside this array will + * mutate them in history. + * + * @return {Array} + */ + + + log.history = function () { + return history ? [].concat(history) : []; + }; + /** + * Allows you to filter the history by the given logger name + * + * @param {string} fname + * The name to filter by + * + * @return {Array} + * The filtered list to return + */ + + + log.history.filter = function (fname) { + return (history || []).filter(function (historyItem) { + // if the first item in each historyItem includes `fname`, then it's a match + return new RegExp(".*" + fname + ".*").test(historyItem[0]); + }); + }; + /** + * Clears the internal history tracking, but does not prevent further history + * tracking. + */ + + + log.history.clear = function () { + if (history) { + history.length = 0; + } + }; + /** + * Disable history tracking if it is currently enabled. + */ + + + log.history.disable = function () { + if (history !== null) { + history.length = 0; + history = null; + } + }; + /** + * Enable history tracking if it is currently disabled. + */ + + + log.history.enable = function () { + if (history === null) { + history = []; + } + }; + /** + * Logs error messages. Similar to `console.error`. + * + * @param {Mixed[]} args + * One or more messages or objects that should be logged as an error + */ + + + log.error = function () { + for (var _len2 = arguments.length, args = new Array(_len2), _key2 = 0; _key2 < _len2; _key2++) { + args[_key2] = arguments[_key2]; + } + + return logByType('error', level, args); + }; + /** + * Logs warning messages. Similar to `console.warn`. + * + * @param {Mixed[]} args + * One or more messages or objects that should be logged as a warning. + */ + + + log.warn = function () { + for (var _len3 = arguments.length, args = new Array(_len3), _key3 = 0; _key3 < _len3; _key3++) { + args[_key3] = arguments[_key3]; + } + + return logByType('warn', level, args); + }; + /** + * Logs debug messages. Similar to `console.debug`, but may also act as a comparable + * log if `console.debug` is not available + * + * @param {Mixed[]} args + * One or more messages or objects that should be logged as debug. + */ + + + log.debug = function () { + for (var _len4 = arguments.length, args = new Array(_len4), _key4 = 0; _key4 < _len4; _key4++) { + args[_key4] = arguments[_key4]; + } + + return logByType('debug', level, args); + }; + + return log; +} + +/** + * @file log.js + * @module log + */ +var log = createLogger$1('VIDEOJS'); +var createLogger = log.createLogger; + +/** + * @file obj.js + * @module obj + */ + +/** + * @callback obj:EachCallback + * + * @param {Mixed} value + * The current key for the object that is being iterated over. + * + * @param {string} key + * The current key-value for object that is being iterated over + */ + +/** + * @callback obj:ReduceCallback + * + * @param {Mixed} accum + * The value that is accumulating over the reduce loop. + * + * @param {Mixed} value + * The current key for the object that is being iterated over. + * + * @param {string} key + * The current key-value for object that is being iterated over + * + * @return {Mixed} + * The new accumulated value. + */ +var toString = Object.prototype.toString; +/** + * Get the keys of an Object + * + * @param {Object} + * The Object to get the keys from + * + * @return {string[]} + * An array of the keys from the object. Returns an empty array if the + * object passed in was invalid or had no keys. + * + * @private + */ + +var keys = function keys(object) { + return isObject(object) ? Object.keys(object) : []; +}; +/** + * Array-like iteration for objects. + * + * @param {Object} object + * The object to iterate over + * + * @param {obj:EachCallback} fn + * The callback function which is called for each key in the object. + */ + + +function each(object, fn) { + keys(object).forEach(function (key) { + return fn(object[key], key); + }); +} +/** + * Array-like reduce for objects. + * + * @param {Object} object + * The Object that you want to reduce. + * + * @param {Function} fn + * A callback function which is called for each key in the object. It + * receives the accumulated value and the per-iteration value and key + * as arguments. + * + * @param {Mixed} [initial = 0] + * Starting value + * + * @return {Mixed} + * The final accumulated value. + */ + +function reduce(object, fn, initial) { + if (initial === void 0) { + initial = 0; + } + + return keys(object).reduce(function (accum, key) { + return fn(accum, object[key], key); + }, initial); +} +/** + * Object.assign-style object shallow merge/extend. + * + * @param {Object} target + * @param {Object} ...sources + * @return {Object} + */ + +function assign(target) { + for (var _len = arguments.length, sources = new Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) { + sources[_key - 1] = arguments[_key]; + } + + if (Object.assign) { + return _extends__default['default'].apply(void 0, [target].concat(sources)); + } + + sources.forEach(function (source) { + if (!source) { + return; + } + + each(source, function (value, key) { + target[key] = value; + }); + }); + return target; +} +/** + * Returns whether a value is an object of any kind - including DOM nodes, + * arrays, regular expressions, etc. Not functions, though. + * + * This avoids the gotcha where using `typeof` on a `null` value + * results in `'object'`. + * + * @param {Object} value + * @return {boolean} + */ + +function isObject(value) { + return !!value && typeof value === 'object'; +} +/** + * Returns whether an object appears to be a "plain" object - that is, a + * direct instance of `Object`. + * + * @param {Object} value + * @return {boolean} + */ + +function isPlain(value) { + return isObject(value) && toString.call(value) === '[object Object]' && value.constructor === Object; +} + +/** + * @file computed-style.js + * @module computed-style + */ +/** + * A safe getComputedStyle. + * + * This is needed because in Firefox, if the player is loaded in an iframe with + * `display:none`, then `getComputedStyle` returns `null`, so, we do a + * null-check to make sure that the player doesn't break in these cases. + * + * @function + * @param {Element} el + * The element you want the computed style of + * + * @param {string} prop + * The property name you want + * + * @see https://bugzilla.mozilla.org/show_bug.cgi?id=548397 + */ + +function computedStyle(el, prop) { + if (!el || !prop) { + return ''; + } + + if (typeof window__default['default'].getComputedStyle === 'function') { + var computedStyleValue; + + try { + computedStyleValue = window__default['default'].getComputedStyle(el); + } catch (e) { + return ''; + } + + return computedStyleValue ? computedStyleValue.getPropertyValue(prop) || computedStyleValue[prop] : ''; + } + + return ''; +} + +/** + * @file browser.js + * @module browser + */ +var USER_AGENT = window__default['default'].navigator && window__default['default'].navigator.userAgent || ''; +var webkitVersionMap = /AppleWebKit\/([\d.]+)/i.exec(USER_AGENT); +var appleWebkitVersion = webkitVersionMap ? parseFloat(webkitVersionMap.pop()) : null; +/** + * Whether or not this device is an iPod. + * + * @static + * @const + * @type {Boolean} + */ + +var IS_IPOD = /iPod/i.test(USER_AGENT); +/** + * The detected iOS version - or `null`. + * + * @static + * @const + * @type {string|null} + */ + +var IOS_VERSION = function () { + var match = USER_AGENT.match(/OS (\d+)_/i); + + if (match && match[1]) { + return match[1]; + } + + return null; +}(); +/** + * Whether or not this is an Android device. + * + * @static + * @const + * @type {Boolean} + */ + +var IS_ANDROID = /Android/i.test(USER_AGENT); +/** + * The detected Android version - or `null`. + * + * @static + * @const + * @type {number|string|null} + */ + +var ANDROID_VERSION = function () { + // This matches Android Major.Minor.Patch versions + // ANDROID_VERSION is Major.Minor as a Number, if Minor isn't available, then only Major is returned + var match = USER_AGENT.match(/Android (\d+)(?:\.(\d+))?(?:\.(\d+))*/i); + + if (!match) { + return null; + } + + var major = match[1] && parseFloat(match[1]); + var minor = match[2] && parseFloat(match[2]); + + if (major && minor) { + return parseFloat(match[1] + '.' + match[2]); + } else if (major) { + return major; + } + + return null; +}(); +/** + * Whether or not this is a native Android browser. + * + * @static + * @const + * @type {Boolean} + */ + +var IS_NATIVE_ANDROID = IS_ANDROID && ANDROID_VERSION < 5 && appleWebkitVersion < 537; +/** + * Whether or not this is Mozilla Firefox. + * + * @static + * @const + * @type {Boolean} + */ + +var IS_FIREFOX = /Firefox/i.test(USER_AGENT); +/** + * Whether or not this is Microsoft Edge. + * + * @static + * @const + * @type {Boolean} + */ + +var IS_EDGE = /Edg/i.test(USER_AGENT); +/** + * Whether or not this is Google Chrome. + * + * This will also be `true` for Chrome on iOS, which will have different support + * as it is actually Safari under the hood. + * + * @static + * @const + * @type {Boolean} + */ + +var IS_CHROME = !IS_EDGE && (/Chrome/i.test(USER_AGENT) || /CriOS/i.test(USER_AGENT)); +/** + * The detected Google Chrome version - or `null`. + * + * @static + * @const + * @type {number|null} + */ + +var CHROME_VERSION = function () { + var match = USER_AGENT.match(/(Chrome|CriOS)\/(\d+)/); + + if (match && match[2]) { + return parseFloat(match[2]); + } + + return null; +}(); +/** + * The detected Internet Explorer version - or `null`. + * + * @static + * @const + * @type {number|null} + */ + +var IE_VERSION = function () { + var result = /MSIE\s(\d+)\.\d/.exec(USER_AGENT); + var version = result && parseFloat(result[1]); + + if (!version && /Trident\/7.0/i.test(USER_AGENT) && /rv:11.0/.test(USER_AGENT)) { + // IE 11 has a different user agent string than other IE versions + version = 11.0; + } + + return version; +}(); +/** + * Whether or not this is desktop Safari. + * + * @static + * @const + * @type {Boolean} + */ + +var IS_SAFARI = /Safari/i.test(USER_AGENT) && !IS_CHROME && !IS_ANDROID && !IS_EDGE; +/** + * Whether or not this is a Windows machine. + * + * @static + * @const + * @type {Boolean} + */ + +var IS_WINDOWS = /Windows/i.test(USER_AGENT); +/** + * Whether or not this device is touch-enabled. + * + * @static + * @const + * @type {Boolean} + */ + +var TOUCH_ENABLED = Boolean(isReal() && ('ontouchstart' in window__default['default'] || window__default['default'].navigator.maxTouchPoints || window__default['default'].DocumentTouch && window__default['default'].document instanceof window__default['default'].DocumentTouch)); +/** + * Whether or not this device is an iPad. + * + * @static + * @const + * @type {Boolean} + */ + +var IS_IPAD = /iPad/i.test(USER_AGENT) || IS_SAFARI && TOUCH_ENABLED && !/iPhone/i.test(USER_AGENT); +/** + * Whether or not this device is an iPhone. + * + * @static + * @const + * @type {Boolean} + */ +// The Facebook app's UIWebView identifies as both an iPhone and iPad, so +// to identify iPhones, we need to exclude iPads. +// http://artsy.github.io/blog/2012/10/18/the-perils-of-ios-user-agent-sniffing/ + +var IS_IPHONE = /iPhone/i.test(USER_AGENT) && !IS_IPAD; +/** + * Whether or not this is an iOS device. + * + * @static + * @const + * @type {Boolean} + */ + +var IS_IOS = IS_IPHONE || IS_IPAD || IS_IPOD; +/** + * Whether or not this is any flavor of Safari - including iOS. + * + * @static + * @const + * @type {Boolean} + */ + +var IS_ANY_SAFARI = (IS_SAFARI || IS_IOS) && !IS_CHROME; + +var browser = /*#__PURE__*/Object.freeze({ + __proto__: null, + IS_IPOD: IS_IPOD, + IOS_VERSION: IOS_VERSION, + IS_ANDROID: IS_ANDROID, + ANDROID_VERSION: ANDROID_VERSION, + IS_NATIVE_ANDROID: IS_NATIVE_ANDROID, + IS_FIREFOX: IS_FIREFOX, + IS_EDGE: IS_EDGE, + IS_CHROME: IS_CHROME, + CHROME_VERSION: CHROME_VERSION, + IE_VERSION: IE_VERSION, + IS_SAFARI: IS_SAFARI, + IS_WINDOWS: IS_WINDOWS, + TOUCH_ENABLED: TOUCH_ENABLED, + IS_IPAD: IS_IPAD, + IS_IPHONE: IS_IPHONE, + IS_IOS: IS_IOS, + IS_ANY_SAFARI: IS_ANY_SAFARI +}); + +/** + * @file dom.js + * @module dom + */ +/** + * Detect if a value is a string with any non-whitespace characters. + * + * @private + * @param {string} str + * The string to check + * + * @return {boolean} + * Will be `true` if the string is non-blank, `false` otherwise. + * + */ + +function isNonBlankString(str) { + // we use str.trim as it will trim any whitespace characters + // from the front or back of non-whitespace characters. aka + // Any string that contains non-whitespace characters will + // still contain them after `trim` but whitespace only strings + // will have a length of 0, failing this check. + return typeof str === 'string' && Boolean(str.trim()); +} +/** + * Throws an error if the passed string has whitespace. This is used by + * class methods to be relatively consistent with the classList API. + * + * @private + * @param {string} str + * The string to check for whitespace. + * + * @throws {Error} + * Throws an error if there is whitespace in the string. + */ + + +function throwIfWhitespace(str) { + // str.indexOf instead of regex because str.indexOf is faster performance wise. + if (str.indexOf(' ') >= 0) { + throw new Error('class has illegal whitespace characters'); + } +} +/** + * Produce a regular expression for matching a className within an elements className. + * + * @private + * @param {string} className + * The className to generate the RegExp for. + * + * @return {RegExp} + * The RegExp that will check for a specific `className` in an elements + * className. + */ + + +function classRegExp(className) { + return new RegExp('(^|\\s)' + className + '($|\\s)'); +} +/** + * Whether the current DOM interface appears to be real (i.e. not simulated). + * + * @return {boolean} + * Will be `true` if the DOM appears to be real, `false` otherwise. + */ + + +function isReal() { + // Both document and window will never be undefined thanks to `global`. + return document__default['default'] === window__default['default'].document; +} +/** + * Determines, via duck typing, whether or not a value is a DOM element. + * + * @param {Mixed} value + * The value to check. + * + * @return {boolean} + * Will be `true` if the value is a DOM element, `false` otherwise. + */ + +function isEl(value) { + return isObject(value) && value.nodeType === 1; +} +/** + * Determines if the current DOM is embedded in an iframe. + * + * @return {boolean} + * Will be `true` if the DOM is embedded in an iframe, `false` + * otherwise. + */ + +function isInFrame() { + // We need a try/catch here because Safari will throw errors when attempting + // to get either `parent` or `self` + try { + return window__default['default'].parent !== window__default['default'].self; + } catch (x) { + return true; + } +} +/** + * Creates functions to query the DOM using a given method. + * + * @private + * @param {string} method + * The method to create the query with. + * + * @return {Function} + * The query method + */ + +function createQuerier(method) { + return function (selector, context) { + if (!isNonBlankString(selector)) { + return document__default['default'][method](null); + } + + if (isNonBlankString(context)) { + context = document__default['default'].querySelector(context); + } + + var ctx = isEl(context) ? context : document__default['default']; + return ctx[method] && ctx[method](selector); + }; +} +/** + * Creates an element and applies properties, attributes, and inserts content. + * + * @param {string} [tagName='div'] + * Name of tag to be created. + * + * @param {Object} [properties={}] + * Element properties to be applied. + * + * @param {Object} [attributes={}] + * Element attributes to be applied. + * + * @param {module:dom~ContentDescriptor} content + * A content descriptor object. + * + * @return {Element} + * The element that was created. + */ + + +function createEl(tagName, properties, attributes, content) { + if (tagName === void 0) { + tagName = 'div'; + } + + if (properties === void 0) { + properties = {}; + } + + if (attributes === void 0) { + attributes = {}; + } + + var el = document__default['default'].createElement(tagName); + Object.getOwnPropertyNames(properties).forEach(function (propName) { + var val = properties[propName]; // See #2176 + // We originally were accepting both properties and attributes in the + // same object, but that doesn't work so well. + + if (propName.indexOf('aria-') !== -1 || propName === 'role' || propName === 'type') { + log.warn('Setting attributes in the second argument of createEl()\n' + 'has been deprecated. Use the third argument instead.\n' + ("createEl(type, properties, attributes). Attempting to set " + propName + " to " + val + ".")); + el.setAttribute(propName, val); // Handle textContent since it's not supported everywhere and we have a + // method for it. + } else if (propName === 'textContent') { + textContent(el, val); + } else if (el[propName] !== val || propName === 'tabIndex') { + el[propName] = val; + } + }); + Object.getOwnPropertyNames(attributes).forEach(function (attrName) { + el.setAttribute(attrName, attributes[attrName]); + }); + + if (content) { + appendContent(el, content); + } + + return el; +} +/** + * Injects text into an element, replacing any existing contents entirely. + * + * @param {Element} el + * The element to add text content into + * + * @param {string} text + * The text content to add. + * + * @return {Element} + * The element with added text content. + */ + +function textContent(el, text) { + if (typeof el.textContent === 'undefined') { + el.innerText = text; + } else { + el.textContent = text; + } + + return el; +} +/** + * Insert an element as the first child node of another + * + * @param {Element} child + * Element to insert + * + * @param {Element} parent + * Element to insert child into + */ + +function prependTo(child, parent) { + if (parent.firstChild) { + parent.insertBefore(child, parent.firstChild); + } else { + parent.appendChild(child); + } +} +/** + * Check if an element has a class name. + * + * @param {Element} element + * Element to check + * + * @param {string} classToCheck + * Class name to check for + * + * @return {boolean} + * Will be `true` if the element has a class, `false` otherwise. + * + * @throws {Error} + * Throws an error if `classToCheck` has white space. + */ + +function hasClass(element, classToCheck) { + throwIfWhitespace(classToCheck); + + if (element.classList) { + return element.classList.contains(classToCheck); + } + + return classRegExp(classToCheck).test(element.className); +} +/** + * Add a class name to an element. + * + * @param {Element} element + * Element to add class name to. + * + * @param {string} classToAdd + * Class name to add. + * + * @return {Element} + * The DOM element with the added class name. + */ + +function addClass(element, classToAdd) { + if (element.classList) { + element.classList.add(classToAdd); // Don't need to `throwIfWhitespace` here because `hasElClass` will do it + // in the case of classList not being supported. + } else if (!hasClass(element, classToAdd)) { + element.className = (element.className + ' ' + classToAdd).trim(); + } + + return element; +} +/** + * Remove a class name from an element. + * + * @param {Element} element + * Element to remove a class name from. + * + * @param {string} classToRemove + * Class name to remove + * + * @return {Element} + * The DOM element with class name removed. + */ + +function removeClass(element, classToRemove) { + if (element.classList) { + element.classList.remove(classToRemove); + } else { + throwIfWhitespace(classToRemove); + element.className = element.className.split(/\s+/).filter(function (c) { + return c !== classToRemove; + }).join(' '); + } + + return element; +} +/** + * The callback definition for toggleClass. + * + * @callback module:dom~PredicateCallback + * @param {Element} element + * The DOM element of the Component. + * + * @param {string} classToToggle + * The `className` that wants to be toggled + * + * @return {boolean|undefined} + * If `true` is returned, the `classToToggle` will be added to the + * `element`. If `false`, the `classToToggle` will be removed from + * the `element`. If `undefined`, the callback will be ignored. + */ + +/** + * Adds or removes a class name to/from an element depending on an optional + * condition or the presence/absence of the class name. + * + * @param {Element} element + * The element to toggle a class name on. + * + * @param {string} classToToggle + * The class that should be toggled. + * + * @param {boolean|module:dom~PredicateCallback} [predicate] + * See the return value for {@link module:dom~PredicateCallback} + * + * @return {Element} + * The element with a class that has been toggled. + */ + +function toggleClass(element, classToToggle, predicate) { + // This CANNOT use `classList` internally because IE11 does not support the + // second parameter to the `classList.toggle()` method! Which is fine because + // `classList` will be used by the add/remove functions. + var has = hasClass(element, classToToggle); + + if (typeof predicate === 'function') { + predicate = predicate(element, classToToggle); + } + + if (typeof predicate !== 'boolean') { + predicate = !has; + } // If the necessary class operation matches the current state of the + // element, no action is required. + + + if (predicate === has) { + return; + } + + if (predicate) { + addClass(element, classToToggle); + } else { + removeClass(element, classToToggle); + } + + return element; +} +/** + * Apply attributes to an HTML element. + * + * @param {Element} el + * Element to add attributes to. + * + * @param {Object} [attributes] + * Attributes to be applied. + */ + +function setAttributes(el, attributes) { + Object.getOwnPropertyNames(attributes).forEach(function (attrName) { + var attrValue = attributes[attrName]; + + if (attrValue === null || typeof attrValue === 'undefined' || attrValue === false) { + el.removeAttribute(attrName); + } else { + el.setAttribute(attrName, attrValue === true ? '' : attrValue); + } + }); +} +/** + * Get an element's attribute values, as defined on the HTML tag. + * + * Attributes are not the same as properties. They're defined on the tag + * or with setAttribute. + * + * @param {Element} tag + * Element from which to get tag attributes. + * + * @return {Object} + * All attributes of the element. Boolean attributes will be `true` or + * `false`, others will be strings. + */ + +function getAttributes(tag) { + var obj = {}; // known boolean attributes + // we can check for matching boolean properties, but not all browsers + // and not all tags know about these attributes, so, we still want to check them manually + + var knownBooleans = ',' + 'autoplay,controls,playsinline,loop,muted,default,defaultMuted' + ','; + + if (tag && tag.attributes && tag.attributes.length > 0) { + var attrs = tag.attributes; + + for (var i = attrs.length - 1; i >= 0; i--) { + var attrName = attrs[i].name; + var attrVal = attrs[i].value; // check for known booleans + // the matching element property will return a value for typeof + + if (typeof tag[attrName] === 'boolean' || knownBooleans.indexOf(',' + attrName + ',') !== -1) { + // the value of an included boolean attribute is typically an empty + // string ('') which would equal false if we just check for a false value. + // we also don't want support bad code like autoplay='false' + attrVal = attrVal !== null ? true : false; + } + + obj[attrName] = attrVal; + } + } + + return obj; +} +/** + * Get the value of an element's attribute. + * + * @param {Element} el + * A DOM element. + * + * @param {string} attribute + * Attribute to get the value of. + * + * @return {string} + * The value of the attribute. + */ + +function getAttribute(el, attribute) { + return el.getAttribute(attribute); +} +/** + * Set the value of an element's attribute. + * + * @param {Element} el + * A DOM element. + * + * @param {string} attribute + * Attribute to set. + * + * @param {string} value + * Value to set the attribute to. + */ + +function setAttribute(el, attribute, value) { + el.setAttribute(attribute, value); +} +/** + * Remove an element's attribute. + * + * @param {Element} el + * A DOM element. + * + * @param {string} attribute + * Attribute to remove. + */ + +function removeAttribute(el, attribute) { + el.removeAttribute(attribute); +} +/** + * Attempt to block the ability to select text. + */ + +function blockTextSelection() { + document__default['default'].body.focus(); + + document__default['default'].onselectstart = function () { + return false; + }; +} +/** + * Turn off text selection blocking. + */ + +function unblockTextSelection() { + document__default['default'].onselectstart = function () { + return true; + }; +} +/** + * Identical to the native `getBoundingClientRect` function, but ensures that + * the method is supported at all (it is in all browsers we claim to support) + * and that the element is in the DOM before continuing. + * + * This wrapper function also shims properties which are not provided by some + * older browsers (namely, IE8). + * + * Additionally, some browsers do not support adding properties to a + * `ClientRect`/`DOMRect` object; so, we shallow-copy it with the standard + * properties (except `x` and `y` which are not widely supported). This helps + * avoid implementations where keys are non-enumerable. + * + * @param {Element} el + * Element whose `ClientRect` we want to calculate. + * + * @return {Object|undefined} + * Always returns a plain object - or `undefined` if it cannot. + */ + +function getBoundingClientRect(el) { + if (el && el.getBoundingClientRect && el.parentNode) { + var rect = el.getBoundingClientRect(); + var result = {}; + ['bottom', 'height', 'left', 'right', 'top', 'width'].forEach(function (k) { + if (rect[k] !== undefined) { + result[k] = rect[k]; + } + }); + + if (!result.height) { + result.height = parseFloat(computedStyle(el, 'height')); + } + + if (!result.width) { + result.width = parseFloat(computedStyle(el, 'width')); + } + + return result; + } +} +/** + * Represents the position of a DOM element on the page. + * + * @typedef {Object} module:dom~Position + * + * @property {number} left + * Pixels to the left. + * + * @property {number} top + * Pixels from the top. + */ + +/** + * Get the position of an element in the DOM. + * + * Uses `getBoundingClientRect` technique from John Resig. + * + * @see http://ejohn.org/blog/getboundingclientrect-is-awesome/ + * + * @param {Element} el + * Element from which to get offset. + * + * @return {module:dom~Position} + * The position of the element that was passed in. + */ + +function findPosition(el) { + if (!el || el && !el.offsetParent) { + return { + left: 0, + top: 0, + width: 0, + height: 0 + }; + } + + var width = el.offsetWidth; + var height = el.offsetHeight; + var left = 0; + var top = 0; + + while (el.offsetParent && el !== document__default['default'][FullscreenApi.fullscreenElement]) { + left += el.offsetLeft; + top += el.offsetTop; + el = el.offsetParent; + } + + return { + left: left, + top: top, + width: width, + height: height + }; +} +/** + * Represents x and y coordinates for a DOM element or mouse pointer. + * + * @typedef {Object} module:dom~Coordinates + * + * @property {number} x + * x coordinate in pixels + * + * @property {number} y + * y coordinate in pixels + */ + +/** + * Get the pointer position within an element. + * + * The base on the coordinates are the bottom left of the element. + * + * @param {Element} el + * Element on which to get the pointer position on. + * + * @param {EventTarget~Event} event + * Event object. + * + * @return {module:dom~Coordinates} + * A coordinates object corresponding to the mouse position. + * + */ + +function getPointerPosition(el, event) { + var translated = { + x: 0, + y: 0 + }; + + if (IS_IOS) { + var item = el; + + while (item && item.nodeName.toLowerCase() !== 'html') { + var transform = computedStyle(item, 'transform'); + + if (/^matrix/.test(transform)) { + var values = transform.slice(7, -1).split(/,\s/).map(Number); + translated.x += values[4]; + translated.y += values[5]; + } else if (/^matrix3d/.test(transform)) { + var _values = transform.slice(9, -1).split(/,\s/).map(Number); + + translated.x += _values[12]; + translated.y += _values[13]; + } + + item = item.parentNode; + } + } + + var position = {}; + var boxTarget = findPosition(event.target); + var box = findPosition(el); + var boxW = box.width; + var boxH = box.height; + var offsetY = event.offsetY - (box.top - boxTarget.top); + var offsetX = event.offsetX - (box.left - boxTarget.left); + + if (event.changedTouches) { + offsetX = event.changedTouches[0].pageX - box.left; + offsetY = event.changedTouches[0].pageY + box.top; + + if (IS_IOS) { + offsetX -= translated.x; + offsetY -= translated.y; + } + } + + position.y = 1 - Math.max(0, Math.min(1, offsetY / boxH)); + position.x = Math.max(0, Math.min(1, offsetX / boxW)); + return position; +} +/** + * Determines, via duck typing, whether or not a value is a text node. + * + * @param {Mixed} value + * Check if this value is a text node. + * + * @return {boolean} + * Will be `true` if the value is a text node, `false` otherwise. + */ + +function isTextNode(value) { + return isObject(value) && value.nodeType === 3; +} +/** + * Empties the contents of an element. + * + * @param {Element} el + * The element to empty children from + * + * @return {Element} + * The element with no children + */ + +function emptyEl(el) { + while (el.firstChild) { + el.removeChild(el.firstChild); + } + + return el; +} +/** + * This is a mixed value that describes content to be injected into the DOM + * via some method. It can be of the following types: + * + * Type | Description + * -----------|------------- + * `string` | The value will be normalized into a text node. + * `Element` | The value will be accepted as-is. + * `TextNode` | The value will be accepted as-is. + * `Array` | A one-dimensional array of strings, elements, text nodes, or functions. These functions should return a string, element, or text node (any other return value, like an array, will be ignored). + * `Function` | A function, which is expected to return a string, element, text node, or array - any of the other possible values described above. This means that a content descriptor could be a function that returns an array of functions, but those second-level functions must return strings, elements, or text nodes. + * + * @typedef {string|Element|TextNode|Array|Function} module:dom~ContentDescriptor + */ + +/** + * Normalizes content for eventual insertion into the DOM. + * + * This allows a wide range of content definition methods, but helps protect + * from falling into the trap of simply writing to `innerHTML`, which could + * be an XSS concern. + * + * The content for an element can be passed in multiple types and + * combinations, whose behavior is as follows: + * + * @param {module:dom~ContentDescriptor} content + * A content descriptor value. + * + * @return {Array} + * All of the content that was passed in, normalized to an array of + * elements or text nodes. + */ + +function normalizeContent(content) { + // First, invoke content if it is a function. If it produces an array, + // that needs to happen before normalization. + if (typeof content === 'function') { + content = content(); + } // Next up, normalize to an array, so one or many items can be normalized, + // filtered, and returned. + + + return (Array.isArray(content) ? content : [content]).map(function (value) { + // First, invoke value if it is a function to produce a new value, + // which will be subsequently normalized to a Node of some kind. + if (typeof value === 'function') { + value = value(); + } + + if (isEl(value) || isTextNode(value)) { + return value; + } + + if (typeof value === 'string' && /\S/.test(value)) { + return document__default['default'].createTextNode(value); + } + }).filter(function (value) { + return value; + }); +} +/** + * Normalizes and appends content to an element. + * + * @param {Element} el + * Element to append normalized content to. + * + * @param {module:dom~ContentDescriptor} content + * A content descriptor value. + * + * @return {Element} + * The element with appended normalized content. + */ + +function appendContent(el, content) { + normalizeContent(content).forEach(function (node) { + return el.appendChild(node); + }); + return el; +} +/** + * Normalizes and inserts content into an element; this is identical to + * `appendContent()`, except it empties the element first. + * + * @param {Element} el + * Element to insert normalized content into. + * + * @param {module:dom~ContentDescriptor} content + * A content descriptor value. + * + * @return {Element} + * The element with inserted normalized content. + */ + +function insertContent(el, content) { + return appendContent(emptyEl(el), content); +} +/** + * Check if an event was a single left click. + * + * @param {EventTarget~Event} event + * Event object. + * + * @return {boolean} + * Will be `true` if a single left click, `false` otherwise. + */ + +function isSingleLeftClick(event) { + // Note: if you create something draggable, be sure to + // call it on both `mousedown` and `mousemove` event, + // otherwise `mousedown` should be enough for a button + if (event.button === undefined && event.buttons === undefined) { + // Why do we need `buttons` ? + // Because, middle mouse sometimes have this: + // e.button === 0 and e.buttons === 4 + // Furthermore, we want to prevent combination click, something like + // HOLD middlemouse then left click, that would be + // e.button === 0, e.buttons === 5 + // just `button` is not gonna work + // Alright, then what this block does ? + // this is for chrome `simulate mobile devices` + // I want to support this as well + return true; + } + + if (event.button === 0 && event.buttons === undefined) { + // Touch screen, sometimes on some specific device, `buttons` + // doesn't have anything (safari on ios, blackberry...) + return true; + } // `mouseup` event on a single left click has + // `button` and `buttons` equal to 0 + + + if (event.type === 'mouseup' && event.button === 0 && event.buttons === 0) { + return true; + } + + if (event.button !== 0 || event.buttons !== 1) { + // This is the reason we have those if else block above + // if any special case we can catch and let it slide + // we do it above, when get to here, this definitely + // is-not-left-click + return false; + } + + return true; +} +/** + * Finds a single DOM element matching `selector` within the optional + * `context` of another DOM element (defaulting to `document`). + * + * @param {string} selector + * A valid CSS selector, which will be passed to `querySelector`. + * + * @param {Element|String} [context=document] + * A DOM element within which to query. Can also be a selector + * string in which case the first matching element will be used + * as context. If missing (or no element matches selector), falls + * back to `document`. + * + * @return {Element|null} + * The element that was found or null. + */ + +var $ = createQuerier('querySelector'); +/** + * Finds a all DOM elements matching `selector` within the optional + * `context` of another DOM element (defaulting to `document`). + * + * @param {string} selector + * A valid CSS selector, which will be passed to `querySelectorAll`. + * + * @param {Element|String} [context=document] + * A DOM element within which to query. Can also be a selector + * string in which case the first matching element will be used + * as context. If missing (or no element matches selector), falls + * back to `document`. + * + * @return {NodeList} + * A element list of elements that were found. Will be empty if none + * were found. + * + */ + +var $$ = createQuerier('querySelectorAll'); + +var Dom = /*#__PURE__*/Object.freeze({ + __proto__: null, + isReal: isReal, + isEl: isEl, + isInFrame: isInFrame, + createEl: createEl, + textContent: textContent, + prependTo: prependTo, + hasClass: hasClass, + addClass: addClass, + removeClass: removeClass, + toggleClass: toggleClass, + setAttributes: setAttributes, + getAttributes: getAttributes, + getAttribute: getAttribute, + setAttribute: setAttribute, + removeAttribute: removeAttribute, + blockTextSelection: blockTextSelection, + unblockTextSelection: unblockTextSelection, + getBoundingClientRect: getBoundingClientRect, + findPosition: findPosition, + getPointerPosition: getPointerPosition, + isTextNode: isTextNode, + emptyEl: emptyEl, + normalizeContent: normalizeContent, + appendContent: appendContent, + insertContent: insertContent, + isSingleLeftClick: isSingleLeftClick, + $: $, + $$: $$ +}); + +/** + * @file setup.js - Functions for setting up a player without + * user interaction based on the data-setup `attribute` of the video tag. + * + * @module setup + */ +var _windowLoaded = false; +var videojs$1; +/** + * Set up any tags that have a data-setup `attribute` when the player is started. + */ + +var autoSetup = function autoSetup() { + // Protect against breakage in non-browser environments and check global autoSetup option. + if (!isReal() || videojs$1.options.autoSetup === false) { + return; + } + + var vids = Array.prototype.slice.call(document__default['default'].getElementsByTagName('video')); + var audios = Array.prototype.slice.call(document__default['default'].getElementsByTagName('audio')); + var divs = Array.prototype.slice.call(document__default['default'].getElementsByTagName('video-js')); + var mediaEls = vids.concat(audios, divs); // Check if any media elements exist + + if (mediaEls && mediaEls.length > 0) { + for (var i = 0, e = mediaEls.length; i < e; i++) { + var mediaEl = mediaEls[i]; // Check if element exists, has getAttribute func. + + if (mediaEl && mediaEl.getAttribute) { + // Make sure this player hasn't already been set up. + if (mediaEl.player === undefined) { + var options = mediaEl.getAttribute('data-setup'); // Check if data-setup attr exists. + // We only auto-setup if they've added the data-setup attr. + + if (options !== null) { + // Create new video.js instance. + videojs$1(mediaEl); + } + } // If getAttribute isn't defined, we need to wait for the DOM. + + } else { + autoSetupTimeout(1); + break; + } + } // No videos were found, so keep looping unless page is finished loading. + + } else if (!_windowLoaded) { + autoSetupTimeout(1); + } +}; +/** + * Wait until the page is loaded before running autoSetup. This will be called in + * autoSetup if `hasLoaded` returns false. + * + * @param {number} wait + * How long to wait in ms + * + * @param {module:videojs} [vjs] + * The videojs library function + */ + + +function autoSetupTimeout(wait, vjs) { + if (vjs) { + videojs$1 = vjs; + } + + window__default['default'].setTimeout(autoSetup, wait); +} +/** + * Used to set the internal tracking of window loaded state to true. + * + * @private + */ + + +function setWindowLoaded() { + _windowLoaded = true; + window__default['default'].removeEventListener('load', setWindowLoaded); +} + +if (isReal()) { + if (document__default['default'].readyState === 'complete') { + setWindowLoaded(); + } else { + /** + * Listen for the load event on window, and set _windowLoaded to true. + * + * We use a standard event listener here to avoid incrementing the GUID + * before any players are created. + * + * @listens load + */ + window__default['default'].addEventListener('load', setWindowLoaded); + } +} + +/** + * @file stylesheet.js + * @module stylesheet + */ +/** + * Create a DOM syle element given a className for it. + * + * @param {string} className + * The className to add to the created style element. + * + * @return {Element} + * The element that was created. + */ + +var createStyleElement = function createStyleElement(className) { + var style = document__default['default'].createElement('style'); + style.className = className; + return style; +}; +/** + * Add text to a DOM element. + * + * @param {Element} el + * The Element to add text content to. + * + * @param {string} content + * The text to add to the element. + */ + +var setTextContent = function setTextContent(el, content) { + if (el.styleSheet) { + el.styleSheet.cssText = content; + } else { + el.textContent = content; + } +}; + +/** + * @file guid.js + * @module guid + */ +// Default value for GUIDs. This allows us to reset the GUID counter in tests. +// +// The initial GUID is 3 because some users have come to rely on the first +// default player ID ending up as `vjs_video_3`. +// +// See: https://github.com/videojs/video.js/pull/6216 +var _initialGuid = 3; +/** + * Unique ID for an element or function + * + * @type {Number} + */ + +var _guid = _initialGuid; +/** + * Get a unique auto-incrementing ID by number that has not been returned before. + * + * @return {number} + * A new unique ID. + */ + +function newGUID() { + return _guid++; +} + +/** + * @file dom-data.js + * @module dom-data + */ +var FakeWeakMap; + +if (!window__default['default'].WeakMap) { + FakeWeakMap = /*#__PURE__*/function () { + function FakeWeakMap() { + this.vdata = 'vdata' + Math.floor(window__default['default'].performance && window__default['default'].performance.now() || Date.now()); + this.data = {}; + } + + var _proto = FakeWeakMap.prototype; + + _proto.set = function set(key, value) { + var access = key[this.vdata] || newGUID(); + + if (!key[this.vdata]) { + key[this.vdata] = access; + } + + this.data[access] = value; + return this; + }; + + _proto.get = function get(key) { + var access = key[this.vdata]; // we have data, return it + + if (access) { + return this.data[access]; + } // we don't have data, return nothing. + // return undefined explicitly as that's the contract for this method + + + log('We have no data for this element', key); + return undefined; + }; + + _proto.has = function has(key) { + var access = key[this.vdata]; + return access in this.data; + }; + + _proto["delete"] = function _delete(key) { + var access = key[this.vdata]; + + if (access) { + delete this.data[access]; + delete key[this.vdata]; + } + }; + + return FakeWeakMap; + }(); +} +/** + * Element Data Store. + * + * Allows for binding data to an element without putting it directly on the + * element. Ex. Event listeners are stored here. + * (also from jsninja.com, slightly modified and updated for closure compiler) + * + * @type {Object} + * @private + */ + + +var DomData = window__default['default'].WeakMap ? new WeakMap() : new FakeWeakMap(); + +/** + * @file events.js. An Event System (John Resig - Secrets of a JS Ninja http://jsninja.com/) + * (Original book version wasn't completely usable, so fixed some things and made Closure Compiler compatible) + * This should work very similarly to jQuery's events, however it's based off the book version which isn't as + * robust as jquery's, so there's probably some differences. + * + * @file events.js + * @module events + */ +/** + * Clean up the listener cache and dispatchers + * + * @param {Element|Object} elem + * Element to clean up + * + * @param {string} type + * Type of event to clean up + */ + +function _cleanUpEvents(elem, type) { + if (!DomData.has(elem)) { + return; + } + + var data = DomData.get(elem); // Remove the events of a particular type if there are none left + + if (data.handlers[type].length === 0) { + delete data.handlers[type]; // data.handlers[type] = null; + // Setting to null was causing an error with data.handlers + // Remove the meta-handler from the element + + if (elem.removeEventListener) { + elem.removeEventListener(type, data.dispatcher, false); + } else if (elem.detachEvent) { + elem.detachEvent('on' + type, data.dispatcher); + } + } // Remove the events object if there are no types left + + + if (Object.getOwnPropertyNames(data.handlers).length <= 0) { + delete data.handlers; + delete data.dispatcher; + delete data.disabled; + } // Finally remove the element data if there is no data left + + + if (Object.getOwnPropertyNames(data).length === 0) { + DomData["delete"](elem); + } +} +/** + * Loops through an array of event types and calls the requested method for each type. + * + * @param {Function} fn + * The event method we want to use. + * + * @param {Element|Object} elem + * Element or object to bind listeners to + * + * @param {string} type + * Type of event to bind to. + * + * @param {EventTarget~EventListener} callback + * Event listener. + */ + + +function _handleMultipleEvents(fn, elem, types, callback) { + types.forEach(function (type) { + // Call the event method for each one of the types + fn(elem, type, callback); + }); +} +/** + * Fix a native event to have standard property values + * + * @param {Object} event + * Event object to fix. + * + * @return {Object} + * Fixed event object. + */ + + +function fixEvent(event) { + if (event.fixed_) { + return event; + } + + function returnTrue() { + return true; + } + + function returnFalse() { + return false; + } // Test if fixing up is needed + // Used to check if !event.stopPropagation instead of isPropagationStopped + // But native events return true for stopPropagation, but don't have + // other expected methods like isPropagationStopped. Seems to be a problem + // with the Javascript Ninja code. So we're just overriding all events now. + + + if (!event || !event.isPropagationStopped) { + var old = event || window__default['default'].event; + event = {}; // Clone the old object so that we can modify the values event = {}; + // IE8 Doesn't like when you mess with native event properties + // Firefox returns false for event.hasOwnProperty('type') and other props + // which makes copying more difficult. + // TODO: Probably best to create a whitelist of event props + + for (var key in old) { + // Safari 6.0.3 warns you if you try to copy deprecated layerX/Y + // Chrome warns you if you try to copy deprecated keyboardEvent.keyLocation + // and webkitMovementX/Y + if (key !== 'layerX' && key !== 'layerY' && key !== 'keyLocation' && key !== 'webkitMovementX' && key !== 'webkitMovementY') { + // Chrome 32+ warns if you try to copy deprecated returnValue, but + // we still want to if preventDefault isn't supported (IE8). + if (!(key === 'returnValue' && old.preventDefault)) { + event[key] = old[key]; + } + } + } // The event occurred on this element + + + if (!event.target) { + event.target = event.srcElement || document__default['default']; + } // Handle which other element the event is related to + + + if (!event.relatedTarget) { + event.relatedTarget = event.fromElement === event.target ? event.toElement : event.fromElement; + } // Stop the default browser action + + + event.preventDefault = function () { + if (old.preventDefault) { + old.preventDefault(); + } + + event.returnValue = false; + old.returnValue = false; + event.defaultPrevented = true; + }; + + event.defaultPrevented = false; // Stop the event from bubbling + + event.stopPropagation = function () { + if (old.stopPropagation) { + old.stopPropagation(); + } + + event.cancelBubble = true; + old.cancelBubble = true; + event.isPropagationStopped = returnTrue; + }; + + event.isPropagationStopped = returnFalse; // Stop the event from bubbling and executing other handlers + + event.stopImmediatePropagation = function () { + if (old.stopImmediatePropagation) { + old.stopImmediatePropagation(); + } + + event.isImmediatePropagationStopped = returnTrue; + event.stopPropagation(); + }; + + event.isImmediatePropagationStopped = returnFalse; // Handle mouse position + + if (event.clientX !== null && event.clientX !== undefined) { + var doc = document__default['default'].documentElement; + var body = document__default['default'].body; + event.pageX = event.clientX + (doc && doc.scrollLeft || body && body.scrollLeft || 0) - (doc && doc.clientLeft || body && body.clientLeft || 0); + event.pageY = event.clientY + (doc && doc.scrollTop || body && body.scrollTop || 0) - (doc && doc.clientTop || body && body.clientTop || 0); + } // Handle key presses + + + event.which = event.charCode || event.keyCode; // Fix button for mouse clicks: + // 0 == left; 1 == middle; 2 == right + + if (event.button !== null && event.button !== undefined) { + // The following is disabled because it does not pass videojs-standard + // and... yikes. + + /* eslint-disable */ + event.button = event.button & 1 ? 0 : event.button & 4 ? 1 : event.button & 2 ? 2 : 0; + /* eslint-enable */ + } + } + + event.fixed_ = true; // Returns fixed-up instance + + return event; +} +/** + * Whether passive event listeners are supported + */ + +var _supportsPassive; + +var supportsPassive = function supportsPassive() { + if (typeof _supportsPassive !== 'boolean') { + _supportsPassive = false; + + try { + var opts = Object.defineProperty({}, 'passive', { + get: function get() { + _supportsPassive = true; + } + }); + window__default['default'].addEventListener('test', null, opts); + window__default['default'].removeEventListener('test', null, opts); + } catch (e) {// disregard + } + } + + return _supportsPassive; +}; +/** + * Touch events Chrome expects to be passive + */ + + +var passiveEvents = ['touchstart', 'touchmove']; +/** + * Add an event listener to element + * It stores the handler function in a separate cache object + * and adds a generic handler to the element's event, + * along with a unique id (guid) to the element. + * + * @param {Element|Object} elem + * Element or object to bind listeners to + * + * @param {string|string[]} type + * Type of event to bind to. + * + * @param {EventTarget~EventListener} fn + * Event listener. + */ + +function on(elem, type, fn) { + if (Array.isArray(type)) { + return _handleMultipleEvents(on, elem, type, fn); + } + + if (!DomData.has(elem)) { + DomData.set(elem, {}); + } + + var data = DomData.get(elem); // We need a place to store all our handler data + + if (!data.handlers) { + data.handlers = {}; + } + + if (!data.handlers[type]) { + data.handlers[type] = []; + } + + if (!fn.guid) { + fn.guid = newGUID(); + } + + data.handlers[type].push(fn); + + if (!data.dispatcher) { + data.disabled = false; + + data.dispatcher = function (event, hash) { + if (data.disabled) { + return; + } + + event = fixEvent(event); + var handlers = data.handlers[event.type]; + + if (handlers) { + // Copy handlers so if handlers are added/removed during the process it doesn't throw everything off. + var handlersCopy = handlers.slice(0); + + for (var m = 0, n = handlersCopy.length; m < n; m++) { + if (event.isImmediatePropagationStopped()) { + break; + } else { + try { + handlersCopy[m].call(elem, event, hash); + } catch (e) { + log.error(e); + } + } + } + } + }; + } + + if (data.handlers[type].length === 1) { + if (elem.addEventListener) { + var options = false; + + if (supportsPassive() && passiveEvents.indexOf(type) > -1) { + options = { + passive: true + }; + } + + elem.addEventListener(type, data.dispatcher, options); + } else if (elem.attachEvent) { + elem.attachEvent('on' + type, data.dispatcher); + } + } +} +/** + * Removes event listeners from an element + * + * @param {Element|Object} elem + * Object to remove listeners from. + * + * @param {string|string[]} [type] + * Type of listener to remove. Don't include to remove all events from element. + * + * @param {EventTarget~EventListener} [fn] + * Specific listener to remove. Don't include to remove listeners for an event + * type. + */ + +function off(elem, type, fn) { + // Don't want to add a cache object through getElData if not needed + if (!DomData.has(elem)) { + return; + } + + var data = DomData.get(elem); // If no events exist, nothing to unbind + + if (!data.handlers) { + return; + } + + if (Array.isArray(type)) { + return _handleMultipleEvents(off, elem, type, fn); + } // Utility function + + + var removeType = function removeType(el, t) { + data.handlers[t] = []; + + _cleanUpEvents(el, t); + }; // Are we removing all bound events? + + + if (type === undefined) { + for (var t in data.handlers) { + if (Object.prototype.hasOwnProperty.call(data.handlers || {}, t)) { + removeType(elem, t); + } + } + + return; + } + + var handlers = data.handlers[type]; // If no handlers exist, nothing to unbind + + if (!handlers) { + return; + } // If no listener was provided, remove all listeners for type + + + if (!fn) { + removeType(elem, type); + return; + } // We're only removing a single handler + + + if (fn.guid) { + for (var n = 0; n < handlers.length; n++) { + if (handlers[n].guid === fn.guid) { + handlers.splice(n--, 1); + } + } + } + + _cleanUpEvents(elem, type); +} +/** + * Trigger an event for an element + * + * @param {Element|Object} elem + * Element to trigger an event on + * + * @param {EventTarget~Event|string} event + * A string (the type) or an event object with a type attribute + * + * @param {Object} [hash] + * data hash to pass along with the event + * + * @return {boolean|undefined} + * Returns the opposite of `defaultPrevented` if default was + * prevented. Otherwise, returns `undefined` + */ + +function trigger(elem, event, hash) { + // Fetches element data and a reference to the parent (for bubbling). + // Don't want to add a data object to cache for every parent, + // so checking hasElData first. + var elemData = DomData.has(elem) ? DomData.get(elem) : {}; + var parent = elem.parentNode || elem.ownerDocument; // type = event.type || event, + // handler; + // If an event name was passed as a string, creates an event out of it + + if (typeof event === 'string') { + event = { + type: event, + target: elem + }; + } else if (!event.target) { + event.target = elem; + } // Normalizes the event properties. + + + event = fixEvent(event); // If the passed element has a dispatcher, executes the established handlers. + + if (elemData.dispatcher) { + elemData.dispatcher.call(elem, event, hash); + } // Unless explicitly stopped or the event does not bubble (e.g. media events) + // recursively calls this function to bubble the event up the DOM. + + + if (parent && !event.isPropagationStopped() && event.bubbles === true) { + trigger.call(null, parent, event, hash); // If at the top of the DOM, triggers the default action unless disabled. + } else if (!parent && !event.defaultPrevented && event.target && event.target[event.type]) { + if (!DomData.has(event.target)) { + DomData.set(event.target, {}); + } + + var targetData = DomData.get(event.target); // Checks if the target has a default action for this event. + + if (event.target[event.type]) { + // Temporarily disables event dispatching on the target as we have already executed the handler. + targetData.disabled = true; // Executes the default action. + + if (typeof event.target[event.type] === 'function') { + event.target[event.type](); + } // Re-enables event dispatching. + + + targetData.disabled = false; + } + } // Inform the triggerer if the default was prevented by returning false + + + return !event.defaultPrevented; +} +/** + * Trigger a listener only once for an event. + * + * @param {Element|Object} elem + * Element or object to bind to. + * + * @param {string|string[]} type + * Name/type of event + * + * @param {Event~EventListener} fn + * Event listener function + */ + +function one(elem, type, fn) { + if (Array.isArray(type)) { + return _handleMultipleEvents(one, elem, type, fn); + } + + var func = function func() { + off(elem, type, func); + fn.apply(this, arguments); + }; // copy the guid to the new function so it can removed using the original function's ID + + + func.guid = fn.guid = fn.guid || newGUID(); + on(elem, type, func); +} +/** + * Trigger a listener only once and then turn if off for all + * configured events + * + * @param {Element|Object} elem + * Element or object to bind to. + * + * @param {string|string[]} type + * Name/type of event + * + * @param {Event~EventListener} fn + * Event listener function + */ + +function any(elem, type, fn) { + var func = function func() { + off(elem, type, func); + fn.apply(this, arguments); + }; // copy the guid to the new function so it can removed using the original function's ID + + + func.guid = fn.guid = fn.guid || newGUID(); // multiple ons, but one off for everything + + on(elem, type, func); +} + +var Events = /*#__PURE__*/Object.freeze({ + __proto__: null, + fixEvent: fixEvent, + on: on, + off: off, + trigger: trigger, + one: one, + any: any +}); + +/** + * @file fn.js + * @module fn + */ +var UPDATE_REFRESH_INTERVAL = 30; +/** + * Bind (a.k.a proxy or context). A simple method for changing the context of + * a function. + * + * It also stores a unique id on the function so it can be easily removed from + * events. + * + * @function + * @param {Mixed} context + * The object to bind as scope. + * + * @param {Function} fn + * The function to be bound to a scope. + * + * @param {number} [uid] + * An optional unique ID for the function to be set + * + * @return {Function} + * The new function that will be bound into the context given + */ + +var bind = function bind(context, fn, uid) { + // Make sure the function has a unique ID + if (!fn.guid) { + fn.guid = newGUID(); + } // Create the new function that changes the context + + + var bound = fn.bind(context); // Allow for the ability to individualize this function + // Needed in the case where multiple objects might share the same prototype + // IF both items add an event listener with the same function, then you try to remove just one + // it will remove both because they both have the same guid. + // when using this, you need to use the bind method when you remove the listener as well. + // currently used in text tracks + + bound.guid = uid ? uid + '_' + fn.guid : fn.guid; + return bound; +}; +/** + * Wraps the given function, `fn`, with a new function that only invokes `fn` + * at most once per every `wait` milliseconds. + * + * @function + * @param {Function} fn + * The function to be throttled. + * + * @param {number} wait + * The number of milliseconds by which to throttle. + * + * @return {Function} + */ + +var throttle = function throttle(fn, wait) { + var last = window__default['default'].performance.now(); + + var throttled = function throttled() { + var now = window__default['default'].performance.now(); + + if (now - last >= wait) { + fn.apply(void 0, arguments); + last = now; + } + }; + + return throttled; +}; +/** + * Creates a debounced function that delays invoking `func` until after `wait` + * milliseconds have elapsed since the last time the debounced function was + * invoked. + * + * Inspired by lodash and underscore implementations. + * + * @function + * @param {Function} func + * The function to wrap with debounce behavior. + * + * @param {number} wait + * The number of milliseconds to wait after the last invocation. + * + * @param {boolean} [immediate] + * Whether or not to invoke the function immediately upon creation. + * + * @param {Object} [context=window] + * The "context" in which the debounced function should debounce. For + * example, if this function should be tied to a Video.js player, + * the player can be passed here. Alternatively, defaults to the + * global `window` object. + * + * @return {Function} + * A debounced function. + */ + +var debounce = function debounce(func, wait, immediate, context) { + if (context === void 0) { + context = window__default['default']; + } + + var timeout; + + var cancel = function cancel() { + context.clearTimeout(timeout); + timeout = null; + }; + /* eslint-disable consistent-this */ + + + var debounced = function debounced() { + var self = this; + var args = arguments; + + var _later = function later() { + timeout = null; + _later = null; + + if (!immediate) { + func.apply(self, args); + } + }; + + if (!timeout && immediate) { + func.apply(self, args); + } + + context.clearTimeout(timeout); + timeout = context.setTimeout(_later, wait); + }; + /* eslint-enable consistent-this */ + + + debounced.cancel = cancel; + return debounced; +}; + +/** + * @file src/js/event-target.js + */ +/** + * `EventTarget` is a class that can have the same API as the DOM `EventTarget`. It + * adds shorthand functions that wrap around lengthy functions. For example: + * the `on` function is a wrapper around `addEventListener`. + * + * @see [EventTarget Spec]{@link https://www.w3.org/TR/DOM-Level-2-Events/events.html#Events-EventTarget} + * @class EventTarget + */ + +var EventTarget = function EventTarget() {}; +/** + * A Custom DOM event. + * + * @typedef {Object} EventTarget~Event + * @see [Properties]{@link https://developer.mozilla.org/en-US/docs/Web/API/CustomEvent} + */ + +/** + * All event listeners should follow the following format. + * + * @callback EventTarget~EventListener + * @this {EventTarget} + * + * @param {EventTarget~Event} event + * the event that triggered this function + * + * @param {Object} [hash] + * hash of data sent during the event + */ + +/** + * An object containing event names as keys and booleans as values. + * + * > NOTE: If an event name is set to a true value here {@link EventTarget#trigger} + * will have extra functionality. See that function for more information. + * + * @property EventTarget.prototype.allowedEvents_ + * @private + */ + + +EventTarget.prototype.allowedEvents_ = {}; +/** + * Adds an `event listener` to an instance of an `EventTarget`. An `event listener` is a + * function that will get called when an event with a certain name gets triggered. + * + * @param {string|string[]} type + * An event name or an array of event names. + * + * @param {EventTarget~EventListener} fn + * The function to call with `EventTarget`s + */ + +EventTarget.prototype.on = function (type, fn) { + // Remove the addEventListener alias before calling Events.on + // so we don't get into an infinite type loop + var ael = this.addEventListener; + + this.addEventListener = function () {}; + + on(this, type, fn); + this.addEventListener = ael; +}; +/** + * An alias of {@link EventTarget#on}. Allows `EventTarget` to mimic + * the standard DOM API. + * + * @function + * @see {@link EventTarget#on} + */ + + +EventTarget.prototype.addEventListener = EventTarget.prototype.on; +/** + * Removes an `event listener` for a specific event from an instance of `EventTarget`. + * This makes it so that the `event listener` will no longer get called when the + * named event happens. + * + * @param {string|string[]} type + * An event name or an array of event names. + * + * @param {EventTarget~EventListener} fn + * The function to remove. + */ + +EventTarget.prototype.off = function (type, fn) { + off(this, type, fn); +}; +/** + * An alias of {@link EventTarget#off}. Allows `EventTarget` to mimic + * the standard DOM API. + * + * @function + * @see {@link EventTarget#off} + */ + + +EventTarget.prototype.removeEventListener = EventTarget.prototype.off; +/** + * This function will add an `event listener` that gets triggered only once. After the + * first trigger it will get removed. This is like adding an `event listener` + * with {@link EventTarget#on} that calls {@link EventTarget#off} on itself. + * + * @param {string|string[]} type + * An event name or an array of event names. + * + * @param {EventTarget~EventListener} fn + * The function to be called once for each event name. + */ + +EventTarget.prototype.one = function (type, fn) { + // Remove the addEventListener aliasing Events.on + // so we don't get into an infinite type loop + var ael = this.addEventListener; + + this.addEventListener = function () {}; + + one(this, type, fn); + this.addEventListener = ael; +}; + +EventTarget.prototype.any = function (type, fn) { + // Remove the addEventListener aliasing Events.on + // so we don't get into an infinite type loop + var ael = this.addEventListener; + + this.addEventListener = function () {}; + + any(this, type, fn); + this.addEventListener = ael; +}; +/** + * This function causes an event to happen. This will then cause any `event listeners` + * that are waiting for that event, to get called. If there are no `event listeners` + * for an event then nothing will happen. + * + * If the name of the `Event` that is being triggered is in `EventTarget.allowedEvents_`. + * Trigger will also call the `on` + `uppercaseEventName` function. + * + * Example: + * 'click' is in `EventTarget.allowedEvents_`, so, trigger will attempt to call + * `onClick` if it exists. + * + * @param {string|EventTarget~Event|Object} event + * The name of the event, an `Event`, or an object with a key of type set to + * an event name. + */ + + +EventTarget.prototype.trigger = function (event) { + var type = event.type || event; // deprecation + // In a future version we should default target to `this` + // similar to how we default the target to `elem` in + // `Events.trigger`. Right now the default `target` will be + // `document` due to the `Event.fixEvent` call. + + if (typeof event === 'string') { + event = { + type: type + }; + } + + event = fixEvent(event); + + if (this.allowedEvents_[type] && this['on' + type]) { + this['on' + type](event); + } + + trigger(this, event); +}; +/** + * An alias of {@link EventTarget#trigger}. Allows `EventTarget` to mimic + * the standard DOM API. + * + * @function + * @see {@link EventTarget#trigger} + */ + + +EventTarget.prototype.dispatchEvent = EventTarget.prototype.trigger; +var EVENT_MAP; + +EventTarget.prototype.queueTrigger = function (event) { + var _this = this; + + // only set up EVENT_MAP if it'll be used + if (!EVENT_MAP) { + EVENT_MAP = new Map(); + } + + var type = event.type || event; + var map = EVENT_MAP.get(this); + + if (!map) { + map = new Map(); + EVENT_MAP.set(this, map); + } + + var oldTimeout = map.get(type); + map["delete"](type); + window__default['default'].clearTimeout(oldTimeout); + var timeout = window__default['default'].setTimeout(function () { + // if we cleared out all timeouts for the current target, delete its map + if (map.size === 0) { + map = null; + EVENT_MAP["delete"](_this); + } + + _this.trigger(event); + }, 0); + map.set(type, timeout); +}; + +/** + * @file mixins/evented.js + * @module evented + */ + +var objName = function objName(obj) { + if (typeof obj.name === 'function') { + return obj.name(); + } + + if (typeof obj.name === 'string') { + return obj.name; + } + + if (obj.name_) { + return obj.name_; + } + + if (obj.constructor && obj.constructor.name) { + return obj.constructor.name; + } + + return typeof obj; +}; +/** + * Returns whether or not an object has had the evented mixin applied. + * + * @param {Object} object + * An object to test. + * + * @return {boolean} + * Whether or not the object appears to be evented. + */ + + +var isEvented = function isEvented(object) { + return object instanceof EventTarget || !!object.eventBusEl_ && ['on', 'one', 'off', 'trigger'].every(function (k) { + return typeof object[k] === 'function'; + }); +}; +/** + * Adds a callback to run after the evented mixin applied. + * + * @param {Object} object + * An object to Add + * @param {Function} callback + * The callback to run. + */ + + +var addEventedCallback = function addEventedCallback(target, callback) { + if (isEvented(target)) { + callback(); + } else { + if (!target.eventedCallbacks) { + target.eventedCallbacks = []; + } + + target.eventedCallbacks.push(callback); + } +}; +/** + * Whether a value is a valid event type - non-empty string or array. + * + * @private + * @param {string|Array} type + * The type value to test. + * + * @return {boolean} + * Whether or not the type is a valid event type. + */ + + +var isValidEventType = function isValidEventType(type) { + return (// The regex here verifies that the `type` contains at least one non- + // whitespace character. + typeof type === 'string' && /\S/.test(type) || Array.isArray(type) && !!type.length + ); +}; +/** + * Validates a value to determine if it is a valid event target. Throws if not. + * + * @private + * @throws {Error} + * If the target does not appear to be a valid event target. + * + * @param {Object} target + * The object to test. + * + * @param {Object} obj + * The evented object we are validating for + * + * @param {string} fnName + * The name of the evented mixin function that called this. + */ + + +var validateTarget = function validateTarget(target, obj, fnName) { + if (!target || !target.nodeName && !isEvented(target)) { + throw new Error("Invalid target for " + objName(obj) + "#" + fnName + "; must be a DOM node or evented object."); + } +}; +/** + * Validates a value to determine if it is a valid event target. Throws if not. + * + * @private + * @throws {Error} + * If the type does not appear to be a valid event type. + * + * @param {string|Array} type + * The type to test. + * + * @param {Object} obj +* The evented object we are validating for + * + * @param {string} fnName + * The name of the evented mixin function that called this. + */ + + +var validateEventType = function validateEventType(type, obj, fnName) { + if (!isValidEventType(type)) { + throw new Error("Invalid event type for " + objName(obj) + "#" + fnName + "; must be a non-empty string or array."); + } +}; +/** + * Validates a value to determine if it is a valid listener. Throws if not. + * + * @private + * @throws {Error} + * If the listener is not a function. + * + * @param {Function} listener + * The listener to test. + * + * @param {Object} obj + * The evented object we are validating for + * + * @param {string} fnName + * The name of the evented mixin function that called this. + */ + + +var validateListener = function validateListener(listener, obj, fnName) { + if (typeof listener !== 'function') { + throw new Error("Invalid listener for " + objName(obj) + "#" + fnName + "; must be a function."); + } +}; +/** + * Takes an array of arguments given to `on()` or `one()`, validates them, and + * normalizes them into an object. + * + * @private + * @param {Object} self + * The evented object on which `on()` or `one()` was called. This + * object will be bound as the `this` value for the listener. + * + * @param {Array} args + * An array of arguments passed to `on()` or `one()`. + * + * @param {string} fnName + * The name of the evented mixin function that called this. + * + * @return {Object} + * An object containing useful values for `on()` or `one()` calls. + */ + + +var normalizeListenArgs = function normalizeListenArgs(self, args, fnName) { + // If the number of arguments is less than 3, the target is always the + // evented object itself. + var isTargetingSelf = args.length < 3 || args[0] === self || args[0] === self.eventBusEl_; + var target; + var type; + var listener; + + if (isTargetingSelf) { + target = self.eventBusEl_; // Deal with cases where we got 3 arguments, but we are still listening to + // the evented object itself. + + if (args.length >= 3) { + args.shift(); + } + + type = args[0]; + listener = args[1]; + } else { + target = args[0]; + type = args[1]; + listener = args[2]; + } + + validateTarget(target, self, fnName); + validateEventType(type, self, fnName); + validateListener(listener, self, fnName); + listener = bind(self, listener); + return { + isTargetingSelf: isTargetingSelf, + target: target, + type: type, + listener: listener + }; +}; +/** + * Adds the listener to the event type(s) on the target, normalizing for + * the type of target. + * + * @private + * @param {Element|Object} target + * A DOM node or evented object. + * + * @param {string} method + * The event binding method to use ("on" or "one"). + * + * @param {string|Array} type + * One or more event type(s). + * + * @param {Function} listener + * A listener function. + */ + + +var listen = function listen(target, method, type, listener) { + validateTarget(target, target, method); + + if (target.nodeName) { + Events[method](target, type, listener); + } else { + target[method](type, listener); + } +}; +/** + * Contains methods that provide event capabilities to an object which is passed + * to {@link module:evented|evented}. + * + * @mixin EventedMixin + */ + + +var EventedMixin = { + /** + * Add a listener to an event (or events) on this object or another evented + * object. + * + * @param {string|Array|Element|Object} targetOrType + * If this is a string or array, it represents the event type(s) + * that will trigger the listener. + * + * Another evented object can be passed here instead, which will + * cause the listener to listen for events on _that_ object. + * + * In either case, the listener's `this` value will be bound to + * this object. + * + * @param {string|Array|Function} typeOrListener + * If the first argument was a string or array, this should be the + * listener function. Otherwise, this is a string or array of event + * type(s). + * + * @param {Function} [listener] + * If the first argument was another evented object, this will be + * the listener function. + */ + on: function on() { + var _this = this; + + for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) { + args[_key] = arguments[_key]; + } + + var _normalizeListenArgs = normalizeListenArgs(this, args, 'on'), + isTargetingSelf = _normalizeListenArgs.isTargetingSelf, + target = _normalizeListenArgs.target, + type = _normalizeListenArgs.type, + listener = _normalizeListenArgs.listener; + + listen(target, 'on', type, listener); // If this object is listening to another evented object. + + if (!isTargetingSelf) { + // If this object is disposed, remove the listener. + var removeListenerOnDispose = function removeListenerOnDispose() { + return _this.off(target, type, listener); + }; // Use the same function ID as the listener so we can remove it later it + // using the ID of the original listener. + + + removeListenerOnDispose.guid = listener.guid; // Add a listener to the target's dispose event as well. This ensures + // that if the target is disposed BEFORE this object, we remove the + // removal listener that was just added. Otherwise, we create a memory leak. + + var removeRemoverOnTargetDispose = function removeRemoverOnTargetDispose() { + return _this.off('dispose', removeListenerOnDispose); + }; // Use the same function ID as the listener so we can remove it later + // it using the ID of the original listener. + + + removeRemoverOnTargetDispose.guid = listener.guid; + listen(this, 'on', 'dispose', removeListenerOnDispose); + listen(target, 'on', 'dispose', removeRemoverOnTargetDispose); + } + }, + + /** + * Add a listener to an event (or events) on this object or another evented + * object. The listener will be called once per event and then removed. + * + * @param {string|Array|Element|Object} targetOrType + * If this is a string or array, it represents the event type(s) + * that will trigger the listener. + * + * Another evented object can be passed here instead, which will + * cause the listener to listen for events on _that_ object. + * + * In either case, the listener's `this` value will be bound to + * this object. + * + * @param {string|Array|Function} typeOrListener + * If the first argument was a string or array, this should be the + * listener function. Otherwise, this is a string or array of event + * type(s). + * + * @param {Function} [listener] + * If the first argument was another evented object, this will be + * the listener function. + */ + one: function one() { + var _this2 = this; + + for (var _len2 = arguments.length, args = new Array(_len2), _key2 = 0; _key2 < _len2; _key2++) { + args[_key2] = arguments[_key2]; + } + + var _normalizeListenArgs2 = normalizeListenArgs(this, args, 'one'), + isTargetingSelf = _normalizeListenArgs2.isTargetingSelf, + target = _normalizeListenArgs2.target, + type = _normalizeListenArgs2.type, + listener = _normalizeListenArgs2.listener; // Targeting this evented object. + + + if (isTargetingSelf) { + listen(target, 'one', type, listener); // Targeting another evented object. + } else { + // TODO: This wrapper is incorrect! It should only + // remove the wrapper for the event type that called it. + // Instead all listners are removed on the first trigger! + // see https://github.com/videojs/video.js/issues/5962 + var wrapper = function wrapper() { + _this2.off(target, type, wrapper); + + for (var _len3 = arguments.length, largs = new Array(_len3), _key3 = 0; _key3 < _len3; _key3++) { + largs[_key3] = arguments[_key3]; + } + + listener.apply(null, largs); + }; // Use the same function ID as the listener so we can remove it later + // it using the ID of the original listener. + + + wrapper.guid = listener.guid; + listen(target, 'one', type, wrapper); + } + }, + + /** + * Add a listener to an event (or events) on this object or another evented + * object. The listener will only be called once for the first event that is triggered + * then removed. + * + * @param {string|Array|Element|Object} targetOrType + * If this is a string or array, it represents the event type(s) + * that will trigger the listener. + * + * Another evented object can be passed here instead, which will + * cause the listener to listen for events on _that_ object. + * + * In either case, the listener's `this` value will be bound to + * this object. + * + * @param {string|Array|Function} typeOrListener + * If the first argument was a string or array, this should be the + * listener function. Otherwise, this is a string or array of event + * type(s). + * + * @param {Function} [listener] + * If the first argument was another evented object, this will be + * the listener function. + */ + any: function any() { + var _this3 = this; + + for (var _len4 = arguments.length, args = new Array(_len4), _key4 = 0; _key4 < _len4; _key4++) { + args[_key4] = arguments[_key4]; + } + + var _normalizeListenArgs3 = normalizeListenArgs(this, args, 'any'), + isTargetingSelf = _normalizeListenArgs3.isTargetingSelf, + target = _normalizeListenArgs3.target, + type = _normalizeListenArgs3.type, + listener = _normalizeListenArgs3.listener; // Targeting this evented object. + + + if (isTargetingSelf) { + listen(target, 'any', type, listener); // Targeting another evented object. + } else { + var wrapper = function wrapper() { + _this3.off(target, type, wrapper); + + for (var _len5 = arguments.length, largs = new Array(_len5), _key5 = 0; _key5 < _len5; _key5++) { + largs[_key5] = arguments[_key5]; + } + + listener.apply(null, largs); + }; // Use the same function ID as the listener so we can remove it later + // it using the ID of the original listener. + + + wrapper.guid = listener.guid; + listen(target, 'any', type, wrapper); + } + }, + + /** + * Removes listener(s) from event(s) on an evented object. + * + * @param {string|Array|Element|Object} [targetOrType] + * If this is a string or array, it represents the event type(s). + * + * Another evented object can be passed here instead, in which case + * ALL 3 arguments are _required_. + * + * @param {string|Array|Function} [typeOrListener] + * If the first argument was a string or array, this may be the + * listener function. Otherwise, this is a string or array of event + * type(s). + * + * @param {Function} [listener] + * If the first argument was another evented object, this will be + * the listener function; otherwise, _all_ listeners bound to the + * event type(s) will be removed. + */ + off: function off$1(targetOrType, typeOrListener, listener) { + // Targeting this evented object. + if (!targetOrType || isValidEventType(targetOrType)) { + off(this.eventBusEl_, targetOrType, typeOrListener); // Targeting another evented object. + } else { + var target = targetOrType; + var type = typeOrListener; // Fail fast and in a meaningful way! + + validateTarget(target, this, 'off'); + validateEventType(type, this, 'off'); + validateListener(listener, this, 'off'); // Ensure there's at least a guid, even if the function hasn't been used + + listener = bind(this, listener); // Remove the dispose listener on this evented object, which was given + // the same guid as the event listener in on(). + + this.off('dispose', listener); + + if (target.nodeName) { + off(target, type, listener); + off(target, 'dispose', listener); + } else if (isEvented(target)) { + target.off(type, listener); + target.off('dispose', listener); + } + } + }, + + /** + * Fire an event on this evented object, causing its listeners to be called. + * + * @param {string|Object} event + * An event type or an object with a type property. + * + * @param {Object} [hash] + * An additional object to pass along to listeners. + * + * @return {boolean} + * Whether or not the default behavior was prevented. + */ + trigger: function trigger$1(event, hash) { + validateTarget(this.eventBusEl_, this, 'trigger'); + var type = event && typeof event !== 'string' ? event.type : event; + + if (!isValidEventType(type)) { + var error = "Invalid event type for " + objName(this) + "#trigger; " + 'must be a non-empty string or object with a type key that has a non-empty value.'; + + if (event) { + (this.log || log).error(error); + } else { + throw new Error(error); + } + } + + return trigger(this.eventBusEl_, event, hash); + } +}; +/** + * Applies {@link module:evented~EventedMixin|EventedMixin} to a target object. + * + * @param {Object} target + * The object to which to add event methods. + * + * @param {Object} [options={}] + * Options for customizing the mixin behavior. + * + * @param {string} [options.eventBusKey] + * By default, adds a `eventBusEl_` DOM element to the target object, + * which is used as an event bus. If the target object already has a + * DOM element that should be used, pass its key here. + * + * @return {Object} + * The target object. + */ + +function evented(target, options) { + if (options === void 0) { + options = {}; + } + + var _options = options, + eventBusKey = _options.eventBusKey; // Set or create the eventBusEl_. + + if (eventBusKey) { + if (!target[eventBusKey].nodeName) { + throw new Error("The eventBusKey \"" + eventBusKey + "\" does not refer to an element."); + } + + target.eventBusEl_ = target[eventBusKey]; + } else { + target.eventBusEl_ = createEl('span', { + className: 'vjs-event-bus' + }); + } + + assign(target, EventedMixin); + + if (target.eventedCallbacks) { + target.eventedCallbacks.forEach(function (callback) { + callback(); + }); + } // When any evented object is disposed, it removes all its listeners. + + + target.on('dispose', function () { + target.off(); + window__default['default'].setTimeout(function () { + target.eventBusEl_ = null; + }, 0); + }); + return target; +} + +/** + * @file mixins/stateful.js + * @module stateful + */ +/** + * Contains methods that provide statefulness to an object which is passed + * to {@link module:stateful}. + * + * @mixin StatefulMixin + */ + +var StatefulMixin = { + /** + * A hash containing arbitrary keys and values representing the state of + * the object. + * + * @type {Object} + */ + state: {}, + + /** + * Set the state of an object by mutating its + * {@link module:stateful~StatefulMixin.state|state} object in place. + * + * @fires module:stateful~StatefulMixin#statechanged + * @param {Object|Function} stateUpdates + * A new set of properties to shallow-merge into the plugin state. + * Can be a plain object or a function returning a plain object. + * + * @return {Object|undefined} + * An object containing changes that occurred. If no changes + * occurred, returns `undefined`. + */ + setState: function setState(stateUpdates) { + var _this = this; + + // Support providing the `stateUpdates` state as a function. + if (typeof stateUpdates === 'function') { + stateUpdates = stateUpdates(); + } + + var changes; + each(stateUpdates, function (value, key) { + // Record the change if the value is different from what's in the + // current state. + if (_this.state[key] !== value) { + changes = changes || {}; + changes[key] = { + from: _this.state[key], + to: value + }; + } + + _this.state[key] = value; + }); // Only trigger "statechange" if there were changes AND we have a trigger + // function. This allows us to not require that the target object be an + // evented object. + + if (changes && isEvented(this)) { + /** + * An event triggered on an object that is both + * {@link module:stateful|stateful} and {@link module:evented|evented} + * indicating that its state has changed. + * + * @event module:stateful~StatefulMixin#statechanged + * @type {Object} + * @property {Object} changes + * A hash containing the properties that were changed and + * the values they were changed `from` and `to`. + */ + this.trigger({ + changes: changes, + type: 'statechanged' + }); + } + + return changes; + } +}; +/** + * Applies {@link module:stateful~StatefulMixin|StatefulMixin} to a target + * object. + * + * If the target object is {@link module:evented|evented} and has a + * `handleStateChanged` method, that method will be automatically bound to the + * `statechanged` event on itself. + * + * @param {Object} target + * The object to be made stateful. + * + * @param {Object} [defaultState] + * A default set of properties to populate the newly-stateful object's + * `state` property. + * + * @return {Object} + * Returns the `target`. + */ + +function stateful(target, defaultState) { + assign(target, StatefulMixin); // This happens after the mixing-in because we need to replace the `state` + // added in that step. + + target.state = assign({}, target.state, defaultState); // Auto-bind the `handleStateChanged` method of the target object if it exists. + + if (typeof target.handleStateChanged === 'function' && isEvented(target)) { + target.on('statechanged', target.handleStateChanged); + } + + return target; +} + +/** + * @file string-cases.js + * @module to-lower-case + */ + +/** + * Lowercase the first letter of a string. + * + * @param {string} string + * String to be lowercased + * + * @return {string} + * The string with a lowercased first letter + */ +var toLowerCase = function toLowerCase(string) { + if (typeof string !== 'string') { + return string; + } + + return string.replace(/./, function (w) { + return w.toLowerCase(); + }); +}; +/** + * Uppercase the first letter of a string. + * + * @param {string} string + * String to be uppercased + * + * @return {string} + * The string with an uppercased first letter + */ + +var toTitleCase = function toTitleCase(string) { + if (typeof string !== 'string') { + return string; + } + + return string.replace(/./, function (w) { + return w.toUpperCase(); + }); +}; +/** + * Compares the TitleCase versions of the two strings for equality. + * + * @param {string} str1 + * The first string to compare + * + * @param {string} str2 + * The second string to compare + * + * @return {boolean} + * Whether the TitleCase versions of the strings are equal + */ + +var titleCaseEquals = function titleCaseEquals(str1, str2) { + return toTitleCase(str1) === toTitleCase(str2); +}; + +/** + * @file merge-options.js + * @module merge-options + */ +/** + * Merge two objects recursively. + * + * Performs a deep merge like + * {@link https://lodash.com/docs/4.17.10#merge|lodash.merge}, but only merges + * plain objects (not arrays, elements, or anything else). + * + * Non-plain object values will be copied directly from the right-most + * argument. + * + * @static + * @param {Object[]} sources + * One or more objects to merge into a new object. + * + * @return {Object} + * A new object that is the merged result of all sources. + */ + +function mergeOptions() { + var result = {}; + + for (var _len = arguments.length, sources = new Array(_len), _key = 0; _key < _len; _key++) { + sources[_key] = arguments[_key]; + } + + sources.forEach(function (source) { + if (!source) { + return; + } + + each(source, function (value, key) { + if (!isPlain(value)) { + result[key] = value; + return; + } + + if (!isPlain(result[key])) { + result[key] = {}; + } + + result[key] = mergeOptions(result[key], value); + }); + }); + return result; +} + +var MapSham = /*#__PURE__*/function () { + function MapSham() { + this.map_ = {}; + } + + var _proto = MapSham.prototype; + + _proto.has = function has(key) { + return key in this.map_; + }; + + _proto["delete"] = function _delete(key) { + var has = this.has(key); + delete this.map_[key]; + return has; + }; + + _proto.set = function set(key, value) { + this.map_[key] = value; + return this; + }; + + _proto.forEach = function forEach(callback, thisArg) { + for (var key in this.map_) { + callback.call(thisArg, this.map_[key], key, this); + } + }; + + return MapSham; +}(); + +var Map$1 = window__default['default'].Map ? window__default['default'].Map : MapSham; + +var SetSham = /*#__PURE__*/function () { + function SetSham() { + this.set_ = {}; + } + + var _proto = SetSham.prototype; + + _proto.has = function has(key) { + return key in this.set_; + }; + + _proto["delete"] = function _delete(key) { + var has = this.has(key); + delete this.set_[key]; + return has; + }; + + _proto.add = function add(key) { + this.set_[key] = 1; + return this; + }; + + _proto.forEach = function forEach(callback, thisArg) { + for (var key in this.set_) { + callback.call(thisArg, key, key, this); + } + }; + + return SetSham; +}(); + +var Set = window__default['default'].Set ? window__default['default'].Set : SetSham; + +/** + * Player Component - Base class for all UI objects + * + * @file component.js + */ +/** + * Base class for all UI Components. + * Components are UI objects which represent both a javascript object and an element + * in the DOM. They can be children of other components, and can have + * children themselves. + * + * Components can also use methods from {@link EventTarget} + */ + +var Component = /*#__PURE__*/function () { + /** + * A callback that is called when a component is ready. Does not have any + * paramters and any callback value will be ignored. + * + * @callback Component~ReadyCallback + * @this Component + */ + + /** + * Creates an instance of this class. + * + * @param {Player} player + * The `Player` that this class should be attached to. + * + * @param {Object} [options] + * The key/value store of player options. + * + * @param {Object[]} [options.children] + * An array of children objects to intialize this component with. Children objects have + * a name property that will be used if more than one component of the same type needs to be + * added. + * + * @param {Component~ReadyCallback} [ready] + * Function that gets called when the `Component` is ready. + */ + function Component(player, options, ready) { + // The component might be the player itself and we can't pass `this` to super + if (!player && this.play) { + this.player_ = player = this; // eslint-disable-line + } else { + this.player_ = player; + } + + this.isDisposed_ = false; // Hold the reference to the parent component via `addChild` method + + this.parentComponent_ = null; // Make a copy of prototype.options_ to protect against overriding defaults + + this.options_ = mergeOptions({}, this.options_); // Updated options with supplied options + + options = this.options_ = mergeOptions(this.options_, options); // Get ID from options or options element if one is supplied + + this.id_ = options.id || options.el && options.el.id; // If there was no ID from the options, generate one + + if (!this.id_) { + // Don't require the player ID function in the case of mock players + var id = player && player.id && player.id() || 'no_player'; + this.id_ = id + "_component_" + newGUID(); + } + + this.name_ = options.name || null; // Create element if one wasn't provided in options + + if (options.el) { + this.el_ = options.el; + } else if (options.createEl !== false) { + this.el_ = this.createEl(); + } // if evented is anything except false, we want to mixin in evented + + + if (options.evented !== false) { + // Make this an evented object and use `el_`, if available, as its event bus + evented(this, { + eventBusKey: this.el_ ? 'el_' : null + }); + this.handleLanguagechange = this.handleLanguagechange.bind(this); + this.on(this.player_, 'languagechange', this.handleLanguagechange); + } + + stateful(this, this.constructor.defaultState); + this.children_ = []; + this.childIndex_ = {}; + this.childNameIndex_ = {}; + this.setTimeoutIds_ = new Set(); + this.setIntervalIds_ = new Set(); + this.rafIds_ = new Set(); + this.namedRafs_ = new Map$1(); + this.clearingTimersOnDispose_ = false; // Add any child components in options + + if (options.initChildren !== false) { + this.initChildren(); + } + + this.ready(ready); // Don't want to trigger ready here or it will before init is actually + // finished for all children that run this constructor + + if (options.reportTouchActivity !== false) { + this.enableTouchActivity(); + } + } + /** + * Dispose of the `Component` and all child components. + * + * @fires Component#dispose + */ + + + var _proto = Component.prototype; + + _proto.dispose = function dispose() { + // Bail out if the component has already been disposed. + if (this.isDisposed_) { + return; + } + + if (this.readyQueue_) { + this.readyQueue_.length = 0; + } + /** + * Triggered when a `Component` is disposed. + * + * @event Component#dispose + * @type {EventTarget~Event} + * + * @property {boolean} [bubbles=false] + * set to false so that the dispose event does not + * bubble up + */ + + + this.trigger({ + type: 'dispose', + bubbles: false + }); + this.isDisposed_ = true; // Dispose all children. + + if (this.children_) { + for (var i = this.children_.length - 1; i >= 0; i--) { + if (this.children_[i].dispose) { + this.children_[i].dispose(); + } + } + } // Delete child references + + + this.children_ = null; + this.childIndex_ = null; + this.childNameIndex_ = null; + this.parentComponent_ = null; + + if (this.el_) { + // Remove element from DOM + if (this.el_.parentNode) { + this.el_.parentNode.removeChild(this.el_); + } + + if (DomData.has(this.el_)) { + DomData["delete"](this.el_); + } + + this.el_ = null; + } // remove reference to the player after disposing of the element + + + this.player_ = null; + } + /** + * Determine whether or not this component has been disposed. + * + * @return {boolean} + * If the component has been disposed, will be `true`. Otherwise, `false`. + */ + ; + + _proto.isDisposed = function isDisposed() { + return Boolean(this.isDisposed_); + } + /** + * Return the {@link Player} that the `Component` has attached to. + * + * @return {Player} + * The player that this `Component` has attached to. + */ + ; + + _proto.player = function player() { + return this.player_; + } + /** + * Deep merge of options objects with new options. + * > Note: When both `obj` and `options` contain properties whose values are objects. + * The two properties get merged using {@link module:mergeOptions} + * + * @param {Object} obj + * The object that contains new options. + * + * @return {Object} + * A new object of `this.options_` and `obj` merged together. + */ + ; + + _proto.options = function options(obj) { + if (!obj) { + return this.options_; + } + + this.options_ = mergeOptions(this.options_, obj); + return this.options_; + } + /** + * Get the `Component`s DOM element + * + * @return {Element} + * The DOM element for this `Component`. + */ + ; + + _proto.el = function el() { + return this.el_; + } + /** + * Create the `Component`s DOM element. + * + * @param {string} [tagName] + * Element's DOM node type. e.g. 'div' + * + * @param {Object} [properties] + * An object of properties that should be set. + * + * @param {Object} [attributes] + * An object of attributes that should be set. + * + * @return {Element} + * The element that gets created. + */ + ; + + _proto.createEl = function createEl$1(tagName, properties, attributes) { + return createEl(tagName, properties, attributes); + } + /** + * Localize a string given the string in english. + * + * If tokens are provided, it'll try and run a simple token replacement on the provided string. + * The tokens it looks for look like `{1}` with the index being 1-indexed into the tokens array. + * + * If a `defaultValue` is provided, it'll use that over `string`, + * if a value isn't found in provided language files. + * This is useful if you want to have a descriptive key for token replacement + * but have a succinct localized string and not require `en.json` to be included. + * + * Currently, it is used for the progress bar timing. + * ```js + * { + * "progress bar timing: currentTime={1} duration={2}": "{1} of {2}" + * } + * ``` + * It is then used like so: + * ```js + * this.localize('progress bar timing: currentTime={1} duration{2}', + * [this.player_.currentTime(), this.player_.duration()], + * '{1} of {2}'); + * ``` + * + * Which outputs something like: `01:23 of 24:56`. + * + * + * @param {string} string + * The string to localize and the key to lookup in the language files. + * @param {string[]} [tokens] + * If the current item has token replacements, provide the tokens here. + * @param {string} [defaultValue] + * Defaults to `string`. Can be a default value to use for token replacement + * if the lookup key is needed to be separate. + * + * @return {string} + * The localized string or if no localization exists the english string. + */ + ; + + _proto.localize = function localize(string, tokens, defaultValue) { + if (defaultValue === void 0) { + defaultValue = string; + } + + var code = this.player_.language && this.player_.language(); + var languages = this.player_.languages && this.player_.languages(); + var language = languages && languages[code]; + var primaryCode = code && code.split('-')[0]; + var primaryLang = languages && languages[primaryCode]; + var localizedString = defaultValue; + + if (language && language[string]) { + localizedString = language[string]; + } else if (primaryLang && primaryLang[string]) { + localizedString = primaryLang[string]; + } + + if (tokens) { + localizedString = localizedString.replace(/\{(\d+)\}/g, function (match, index) { + var value = tokens[index - 1]; + var ret = value; + + if (typeof value === 'undefined') { + ret = match; + } + + return ret; + }); + } + + return localizedString; + } + /** + * Handles language change for the player in components. Should be overriden by sub-components. + * + * @abstract + */ + ; + + _proto.handleLanguagechange = function handleLanguagechange() {} + /** + * Return the `Component`s DOM element. This is where children get inserted. + * This will usually be the the same as the element returned in {@link Component#el}. + * + * @return {Element} + * The content element for this `Component`. + */ + ; + + _proto.contentEl = function contentEl() { + return this.contentEl_ || this.el_; + } + /** + * Get this `Component`s ID + * + * @return {string} + * The id of this `Component` + */ + ; + + _proto.id = function id() { + return this.id_; + } + /** + * Get the `Component`s name. The name gets used to reference the `Component` + * and is set during registration. + * + * @return {string} + * The name of this `Component`. + */ + ; + + _proto.name = function name() { + return this.name_; + } + /** + * Get an array of all child components + * + * @return {Array} + * The children + */ + ; + + _proto.children = function children() { + return this.children_; + } + /** + * Returns the child `Component` with the given `id`. + * + * @param {string} id + * The id of the child `Component` to get. + * + * @return {Component|undefined} + * The child `Component` with the given `id` or undefined. + */ + ; + + _proto.getChildById = function getChildById(id) { + return this.childIndex_[id]; + } + /** + * Returns the child `Component` with the given `name`. + * + * @param {string} name + * The name of the child `Component` to get. + * + * @return {Component|undefined} + * The child `Component` with the given `name` or undefined. + */ + ; + + _proto.getChild = function getChild(name) { + if (!name) { + return; + } + + return this.childNameIndex_[name]; + } + /** + * Returns the descendant `Component` following the givent + * descendant `names`. For instance ['foo', 'bar', 'baz'] would + * try to get 'foo' on the current component, 'bar' on the 'foo' + * component and 'baz' on the 'bar' component and return undefined + * if any of those don't exist. + * + * @param {...string[]|...string} names + * The name of the child `Component` to get. + * + * @return {Component|undefined} + * The descendant `Component` following the given descendant + * `names` or undefined. + */ + ; + + _proto.getDescendant = function getDescendant() { + for (var _len = arguments.length, names = new Array(_len), _key = 0; _key < _len; _key++) { + names[_key] = arguments[_key]; + } + + // flatten array argument into the main array + names = names.reduce(function (acc, n) { + return acc.concat(n); + }, []); + var currentChild = this; + + for (var i = 0; i < names.length; i++) { + currentChild = currentChild.getChild(names[i]); + + if (!currentChild || !currentChild.getChild) { + return; + } + } + + return currentChild; + } + /** + * Add a child `Component` inside the current `Component`. + * + * + * @param {string|Component} child + * The name or instance of a child to add. + * + * @param {Object} [options={}] + * The key/value store of options that will get passed to children of + * the child. + * + * @param {number} [index=this.children_.length] + * The index to attempt to add a child into. + * + * @return {Component} + * The `Component` that gets added as a child. When using a string the + * `Component` will get created by this process. + */ + ; + + _proto.addChild = function addChild(child, options, index) { + if (options === void 0) { + options = {}; + } + + if (index === void 0) { + index = this.children_.length; + } + + var component; + var componentName; // If child is a string, create component with options + + if (typeof child === 'string') { + componentName = toTitleCase(child); + var componentClassName = options.componentClass || componentName; // Set name through options + + options.name = componentName; // Create a new object & element for this controls set + // If there's no .player_, this is a player + + var ComponentClass = Component.getComponent(componentClassName); + + if (!ComponentClass) { + throw new Error("Component " + componentClassName + " does not exist"); + } // data stored directly on the videojs object may be + // misidentified as a component to retain + // backwards-compatibility with 4.x. check to make sure the + // component class can be instantiated. + + + if (typeof ComponentClass !== 'function') { + return null; + } + + component = new ComponentClass(this.player_ || this, options); // child is a component instance + } else { + component = child; + } + + if (component.parentComponent_) { + component.parentComponent_.removeChild(component); + } + + this.children_.splice(index, 0, component); + component.parentComponent_ = this; + + if (typeof component.id === 'function') { + this.childIndex_[component.id()] = component; + } // If a name wasn't used to create the component, check if we can use the + // name function of the component + + + componentName = componentName || component.name && toTitleCase(component.name()); + + if (componentName) { + this.childNameIndex_[componentName] = component; + this.childNameIndex_[toLowerCase(componentName)] = component; + } // Add the UI object's element to the container div (box) + // Having an element is not required + + + if (typeof component.el === 'function' && component.el()) { + // If inserting before a component, insert before that component's element + var refNode = null; + + if (this.children_[index + 1]) { + // Most children are components, but the video tech is an HTML element + if (this.children_[index + 1].el_) { + refNode = this.children_[index + 1].el_; + } else if (isEl(this.children_[index + 1])) { + refNode = this.children_[index + 1]; + } + } + + this.contentEl().insertBefore(component.el(), refNode); + } // Return so it can stored on parent object if desired. + + + return component; + } + /** + * Remove a child `Component` from this `Component`s list of children. Also removes + * the child `Component`s element from this `Component`s element. + * + * @param {Component} component + * The child `Component` to remove. + */ + ; + + _proto.removeChild = function removeChild(component) { + if (typeof component === 'string') { + component = this.getChild(component); + } + + if (!component || !this.children_) { + return; + } + + var childFound = false; + + for (var i = this.children_.length - 1; i >= 0; i--) { + if (this.children_[i] === component) { + childFound = true; + this.children_.splice(i, 1); + break; + } + } + + if (!childFound) { + return; + } + + component.parentComponent_ = null; + this.childIndex_[component.id()] = null; + this.childNameIndex_[toTitleCase(component.name())] = null; + this.childNameIndex_[toLowerCase(component.name())] = null; + var compEl = component.el(); + + if (compEl && compEl.parentNode === this.contentEl()) { + this.contentEl().removeChild(component.el()); + } + } + /** + * Add and initialize default child `Component`s based upon options. + */ + ; + + _proto.initChildren = function initChildren() { + var _this = this; + + var children = this.options_.children; + + if (children) { + // `this` is `parent` + var parentOptions = this.options_; + + var handleAdd = function handleAdd(child) { + var name = child.name; + var opts = child.opts; // Allow options for children to be set at the parent options + // e.g. videojs(id, { controlBar: false }); + // instead of videojs(id, { children: { controlBar: false }); + + if (parentOptions[name] !== undefined) { + opts = parentOptions[name]; + } // Allow for disabling default components + // e.g. options['children']['posterImage'] = false + + + if (opts === false) { + return; + } // Allow options to be passed as a simple boolean if no configuration + // is necessary. + + + if (opts === true) { + opts = {}; + } // We also want to pass the original player options + // to each component as well so they don't need to + // reach back into the player for options later. + + + opts.playerOptions = _this.options_.playerOptions; // Create and add the child component. + // Add a direct reference to the child by name on the parent instance. + // If two of the same component are used, different names should be supplied + // for each + + var newChild = _this.addChild(name, opts); + + if (newChild) { + _this[name] = newChild; + } + }; // Allow for an array of children details to passed in the options + + + var workingChildren; + var Tech = Component.getComponent('Tech'); + + if (Array.isArray(children)) { + workingChildren = children; + } else { + workingChildren = Object.keys(children); + } + + workingChildren // children that are in this.options_ but also in workingChildren would + // give us extra children we do not want. So, we want to filter them out. + .concat(Object.keys(this.options_).filter(function (child) { + return !workingChildren.some(function (wchild) { + if (typeof wchild === 'string') { + return child === wchild; + } + + return child === wchild.name; + }); + })).map(function (child) { + var name; + var opts; + + if (typeof child === 'string') { + name = child; + opts = children[name] || _this.options_[name] || {}; + } else { + name = child.name; + opts = child; + } + + return { + name: name, + opts: opts + }; + }).filter(function (child) { + // we have to make sure that child.name isn't in the techOrder since + // techs are registerd as Components but can't aren't compatible + // See https://github.com/videojs/video.js/issues/2772 + var c = Component.getComponent(child.opts.componentClass || toTitleCase(child.name)); + return c && !Tech.isTech(c); + }).forEach(handleAdd); + } + } + /** + * Builds the default DOM class name. Should be overriden by sub-components. + * + * @return {string} + * The DOM class name for this object. + * + * @abstract + */ + ; + + _proto.buildCSSClass = function buildCSSClass() { + // Child classes can include a function that does: + // return 'CLASS NAME' + this._super(); + return ''; + } + /** + * Bind a listener to the component's ready state. + * Different from event listeners in that if the ready event has already happened + * it will trigger the function immediately. + * + * @return {Component} + * Returns itself; method can be chained. + */ + ; + + _proto.ready = function ready(fn, sync) { + if (sync === void 0) { + sync = false; + } + + if (!fn) { + return; + } + + if (!this.isReady_) { + this.readyQueue_ = this.readyQueue_ || []; + this.readyQueue_.push(fn); + return; + } + + if (sync) { + fn.call(this); + } else { + // Call the function asynchronously by default for consistency + this.setTimeout(fn, 1); + } + } + /** + * Trigger all the ready listeners for this `Component`. + * + * @fires Component#ready + */ + ; + + _proto.triggerReady = function triggerReady() { + this.isReady_ = true; // Ensure ready is triggered asynchronously + + this.setTimeout(function () { + var readyQueue = this.readyQueue_; // Reset Ready Queue + + this.readyQueue_ = []; + + if (readyQueue && readyQueue.length > 0) { + readyQueue.forEach(function (fn) { + fn.call(this); + }, this); + } // Allow for using event listeners also + + /** + * Triggered when a `Component` is ready. + * + * @event Component#ready + * @type {EventTarget~Event} + */ + + + this.trigger('ready'); + }, 1); + } + /** + * Find a single DOM element matching a `selector`. This can be within the `Component`s + * `contentEl()` or another custom context. + * + * @param {string} selector + * A valid CSS selector, which will be passed to `querySelector`. + * + * @param {Element|string} [context=this.contentEl()] + * A DOM element within which to query. Can also be a selector string in + * which case the first matching element will get used as context. If + * missing `this.contentEl()` gets used. If `this.contentEl()` returns + * nothing it falls back to `document`. + * + * @return {Element|null} + * the dom element that was found, or null + * + * @see [Information on CSS Selectors](https://developer.mozilla.org/en-US/docs/Web/Guide/CSS/Getting_Started/Selectors) + */ + ; + + _proto.$ = function $$1(selector, context) { + return $(selector, context || this.contentEl()); + } + /** + * Finds all DOM element matching a `selector`. This can be within the `Component`s + * `contentEl()` or another custom context. + * + * @param {string} selector + * A valid CSS selector, which will be passed to `querySelectorAll`. + * + * @param {Element|string} [context=this.contentEl()] + * A DOM element within which to query. Can also be a selector string in + * which case the first matching element will get used as context. If + * missing `this.contentEl()` gets used. If `this.contentEl()` returns + * nothing it falls back to `document`. + * + * @return {NodeList} + * a list of dom elements that were found + * + * @see [Information on CSS Selectors](https://developer.mozilla.org/en-US/docs/Web/Guide/CSS/Getting_Started/Selectors) + */ + ; + + _proto.$$ = function $$$1(selector, context) { + return $$(selector, context || this.contentEl()); + } + /** + * Check if a component's element has a CSS class name. + * + * @param {string} classToCheck + * CSS class name to check. + * + * @return {boolean} + * - True if the `Component` has the class. + * - False if the `Component` does not have the class` + */ + ; + + _proto.hasClass = function hasClass$1(classToCheck) { + return hasClass(this.el_, classToCheck); + } + /** + * Add a CSS class name to the `Component`s element. + * + * @param {string} classToAdd + * CSS class name to add + */ + ; + + _proto.addClass = function addClass$1(classToAdd) { + addClass(this.el_, classToAdd); + } + /** + * Remove a CSS class name from the `Component`s element. + * + * @param {string} classToRemove + * CSS class name to remove + */ + ; + + _proto.removeClass = function removeClass$1(classToRemove) { + removeClass(this.el_, classToRemove); + } + /** + * Add or remove a CSS class name from the component's element. + * - `classToToggle` gets added when {@link Component#hasClass} would return false. + * - `classToToggle` gets removed when {@link Component#hasClass} would return true. + * + * @param {string} classToToggle + * The class to add or remove based on (@link Component#hasClass} + * + * @param {boolean|Dom~predicate} [predicate] + * An {@link Dom~predicate} function or a boolean + */ + ; + + _proto.toggleClass = function toggleClass$1(classToToggle, predicate) { + toggleClass(this.el_, classToToggle, predicate); + } + /** + * Show the `Component`s element if it is hidden by removing the + * 'vjs-hidden' class name from it. + */ + ; + + _proto.show = function show() { + this.removeClass('vjs-hidden'); + } + /** + * Hide the `Component`s element if it is currently showing by adding the + * 'vjs-hidden` class name to it. + */ + ; + + _proto.hide = function hide() { + this.addClass('vjs-hidden'); + } + /** + * Lock a `Component`s element in its visible state by adding the 'vjs-lock-showing' + * class name to it. Used during fadeIn/fadeOut. + * + * @private + */ + ; + + _proto.lockShowing = function lockShowing() { + this.addClass('vjs-lock-showing'); + } + /** + * Unlock a `Component`s element from its visible state by removing the 'vjs-lock-showing' + * class name from it. Used during fadeIn/fadeOut. + * + * @private + */ + ; + + _proto.unlockShowing = function unlockShowing() { + this.removeClass('vjs-lock-showing'); + } + /** + * Get the value of an attribute on the `Component`s element. + * + * @param {string} attribute + * Name of the attribute to get the value from. + * + * @return {string|null} + * - The value of the attribute that was asked for. + * - Can be an empty string on some browsers if the attribute does not exist + * or has no value + * - Most browsers will return null if the attibute does not exist or has + * no value. + * + * @see [DOM API]{@link https://developer.mozilla.org/en-US/docs/Web/API/Element/getAttribute} + */ + ; + + _proto.getAttribute = function getAttribute$1(attribute) { + return getAttribute(this.el_, attribute); + } + /** + * Set the value of an attribute on the `Component`'s element + * + * @param {string} attribute + * Name of the attribute to set. + * + * @param {string} value + * Value to set the attribute to. + * + * @see [DOM API]{@link https://developer.mozilla.org/en-US/docs/Web/API/Element/setAttribute} + */ + ; + + _proto.setAttribute = function setAttribute$1(attribute, value) { + setAttribute(this.el_, attribute, value); + } + /** + * Remove an attribute from the `Component`s element. + * + * @param {string} attribute + * Name of the attribute to remove. + * + * @see [DOM API]{@link https://developer.mozilla.org/en-US/docs/Web/API/Element/removeAttribute} + */ + ; + + _proto.removeAttribute = function removeAttribute$1(attribute) { + removeAttribute(this.el_, attribute); + } + /** + * Get or set the width of the component based upon the CSS styles. + * See {@link Component#dimension} for more detailed information. + * + * @param {number|string} [num] + * The width that you want to set postfixed with '%', 'px' or nothing. + * + * @param {boolean} [skipListeners] + * Skip the componentresize event trigger + * + * @return {number|string} + * The width when getting, zero if there is no width. Can be a string + * postpixed with '%' or 'px'. + */ + ; + + _proto.width = function width(num, skipListeners) { + return this.dimension('width', num, skipListeners); + } + /** + * Get or set the height of the component based upon the CSS styles. + * See {@link Component#dimension} for more detailed information. + * + * @param {number|string} [num] + * The height that you want to set postfixed with '%', 'px' or nothing. + * + * @param {boolean} [skipListeners] + * Skip the componentresize event trigger + * + * @return {number|string} + * The width when getting, zero if there is no width. Can be a string + * postpixed with '%' or 'px'. + */ + ; + + _proto.height = function height(num, skipListeners) { + return this.dimension('height', num, skipListeners); + } + /** + * Set both the width and height of the `Component` element at the same time. + * + * @param {number|string} width + * Width to set the `Component`s element to. + * + * @param {number|string} height + * Height to set the `Component`s element to. + */ + ; + + _proto.dimensions = function dimensions(width, height) { + // Skip componentresize listeners on width for optimization + this.width(width, true); + this.height(height); + } + /** + * Get or set width or height of the `Component` element. This is the shared code + * for the {@link Component#width} and {@link Component#height}. + * + * Things to know: + * - If the width or height in an number this will return the number postfixed with 'px'. + * - If the width/height is a percent this will return the percent postfixed with '%' + * - Hidden elements have a width of 0 with `window.getComputedStyle`. This function + * defaults to the `Component`s `style.width` and falls back to `window.getComputedStyle`. + * See [this]{@link http://www.foliotek.com/devblog/getting-the-width-of-a-hidden-element-with-jquery-using-width/} + * for more information + * - If you want the computed style of the component, use {@link Component#currentWidth} + * and {@link {Component#currentHeight} + * + * @fires Component#componentresize + * + * @param {string} widthOrHeight + 8 'width' or 'height' + * + * @param {number|string} [num] + 8 New dimension + * + * @param {boolean} [skipListeners] + * Skip componentresize event trigger + * + * @return {number} + * The dimension when getting or 0 if unset + */ + ; + + _proto.dimension = function dimension(widthOrHeight, num, skipListeners) { + if (num !== undefined) { + // Set to zero if null or literally NaN (NaN !== NaN) + if (num === null || num !== num) { + num = 0; + } // Check if using css width/height (% or px) and adjust + + + if (('' + num).indexOf('%') !== -1 || ('' + num).indexOf('px') !== -1) { + this.el_.style[widthOrHeight] = num; + } else if (num === 'auto') { + this.el_.style[widthOrHeight] = ''; + } else { + this.el_.style[widthOrHeight] = num + 'px'; + } // skipListeners allows us to avoid triggering the resize event when setting both width and height + + + if (!skipListeners) { + /** + * Triggered when a component is resized. + * + * @event Component#componentresize + * @type {EventTarget~Event} + */ + this.trigger('componentresize'); + } + + return; + } // Not setting a value, so getting it + // Make sure element exists + + + if (!this.el_) { + return 0; + } // Get dimension value from style + + + var val = this.el_.style[widthOrHeight]; + var pxIndex = val.indexOf('px'); + + if (pxIndex !== -1) { + // Return the pixel value with no 'px' + return parseInt(val.slice(0, pxIndex), 10); + } // No px so using % or no style was set, so falling back to offsetWidth/height + // If component has display:none, offset will return 0 + // TODO: handle display:none and no dimension style using px + + + return parseInt(this.el_['offset' + toTitleCase(widthOrHeight)], 10); + } + /** + * Get the computed width or the height of the component's element. + * + * Uses `window.getComputedStyle`. + * + * @param {string} widthOrHeight + * A string containing 'width' or 'height'. Whichever one you want to get. + * + * @return {number} + * The dimension that gets asked for or 0 if nothing was set + * for that dimension. + */ + ; + + _proto.currentDimension = function currentDimension(widthOrHeight) { + var computedWidthOrHeight = 0; + + if (widthOrHeight !== 'width' && widthOrHeight !== 'height') { + throw new Error('currentDimension only accepts width or height value'); + } + + computedWidthOrHeight = computedStyle(this.el_, widthOrHeight); // remove 'px' from variable and parse as integer + + computedWidthOrHeight = parseFloat(computedWidthOrHeight); // if the computed value is still 0, it's possible that the browser is lying + // and we want to check the offset values. + // This code also runs wherever getComputedStyle doesn't exist. + + if (computedWidthOrHeight === 0 || isNaN(computedWidthOrHeight)) { + var rule = "offset" + toTitleCase(widthOrHeight); + computedWidthOrHeight = this.el_[rule]; + } + + return computedWidthOrHeight; + } + /** + * An object that contains width and height values of the `Component`s + * computed style. Uses `window.getComputedStyle`. + * + * @typedef {Object} Component~DimensionObject + * + * @property {number} width + * The width of the `Component`s computed style. + * + * @property {number} height + * The height of the `Component`s computed style. + */ + + /** + * Get an object that contains computed width and height values of the + * component's element. + * + * Uses `window.getComputedStyle`. + * + * @return {Component~DimensionObject} + * The computed dimensions of the component's element. + */ + ; + + _proto.currentDimensions = function currentDimensions() { + return { + width: this.currentDimension('width'), + height: this.currentDimension('height') + }; + } + /** + * Get the computed width of the component's element. + * + * Uses `window.getComputedStyle`. + * + * @return {number} + * The computed width of the component's element. + */ + ; + + _proto.currentWidth = function currentWidth() { + return this.currentDimension('width'); + } + /** + * Get the computed height of the component's element. + * + * Uses `window.getComputedStyle`. + * + * @return {number} + * The computed height of the component's element. + */ + ; + + _proto.currentHeight = function currentHeight() { + return this.currentDimension('height'); + } + /** + * Set the focus to this component + */ + ; + + _proto.focus = function focus() { + this.el_.focus(); + } + /** + * Remove the focus from this component + */ + ; + + _proto.blur = function blur() { + this.el_.blur(); + } + /** + * When this Component receives a `keydown` event which it does not process, + * it passes the event to the Player for handling. + * + * @param {EventTarget~Event} event + * The `keydown` event that caused this function to be called. + */ + ; + + _proto.handleKeyDown = function handleKeyDown(event) { + if (this.player_) { + // We only stop propagation here because we want unhandled events to fall + // back to the browser. + event.stopPropagation(); + this.player_.handleKeyDown(event); + } + } + /** + * Many components used to have a `handleKeyPress` method, which was poorly + * named because it listened to a `keydown` event. This method name now + * delegates to `handleKeyDown`. This means anyone calling `handleKeyPress` + * will not see their method calls stop working. + * + * @param {EventTarget~Event} event + * The event that caused this function to be called. + */ + ; + + _proto.handleKeyPress = function handleKeyPress(event) { + this.handleKeyDown(event); + } + /** + * Emit a 'tap' events when touch event support gets detected. This gets used to + * support toggling the controls through a tap on the video. They get enabled + * because every sub-component would have extra overhead otherwise. + * + * @private + * @fires Component#tap + * @listens Component#touchstart + * @listens Component#touchmove + * @listens Component#touchleave + * @listens Component#touchcancel + * @listens Component#touchend + */ + ; + + _proto.emitTapEvents = function emitTapEvents() { + // Track the start time so we can determine how long the touch lasted + var touchStart = 0; + var firstTouch = null; // Maximum movement allowed during a touch event to still be considered a tap + // Other popular libs use anywhere from 2 (hammer.js) to 15, + // so 10 seems like a nice, round number. + + var tapMovementThreshold = 10; // The maximum length a touch can be while still being considered a tap + + var touchTimeThreshold = 200; + var couldBeTap; + this.on('touchstart', function (event) { + // If more than one finger, don't consider treating this as a click + if (event.touches.length === 1) { + // Copy pageX/pageY from the object + firstTouch = { + pageX: event.touches[0].pageX, + pageY: event.touches[0].pageY + }; // Record start time so we can detect a tap vs. "touch and hold" + + touchStart = window__default['default'].performance.now(); // Reset couldBeTap tracking + + couldBeTap = true; + } + }); + this.on('touchmove', function (event) { + // If more than one finger, don't consider treating this as a click + if (event.touches.length > 1) { + couldBeTap = false; + } else if (firstTouch) { + // Some devices will throw touchmoves for all but the slightest of taps. + // So, if we moved only a small distance, this could still be a tap + var xdiff = event.touches[0].pageX - firstTouch.pageX; + var ydiff = event.touches[0].pageY - firstTouch.pageY; + var touchDistance = Math.sqrt(xdiff * xdiff + ydiff * ydiff); + + if (touchDistance > tapMovementThreshold) { + couldBeTap = false; + } + } + }); + + var noTap = function noTap() { + couldBeTap = false; + }; // TODO: Listen to the original target. http://youtu.be/DujfpXOKUp8?t=13m8s + + + this.on('touchleave', noTap); + this.on('touchcancel', noTap); // When the touch ends, measure how long it took and trigger the appropriate + // event + + this.on('touchend', function (event) { + firstTouch = null; // Proceed only if the touchmove/leave/cancel event didn't happen + + if (couldBeTap === true) { + // Measure how long the touch lasted + var touchTime = window__default['default'].performance.now() - touchStart; // Make sure the touch was less than the threshold to be considered a tap + + if (touchTime < touchTimeThreshold) { + // Don't let browser turn this into a click + event.preventDefault(); + /** + * Triggered when a `Component` is tapped. + * + * @event Component#tap + * @type {EventTarget~Event} + */ + + this.trigger('tap'); // It may be good to copy the touchend event object and change the + // type to tap, if the other event properties aren't exact after + // Events.fixEvent runs (e.g. event.target) + } + } + }); + } + /** + * This function reports user activity whenever touch events happen. This can get + * turned off by any sub-components that wants touch events to act another way. + * + * Report user touch activity when touch events occur. User activity gets used to + * determine when controls should show/hide. It is simple when it comes to mouse + * events, because any mouse event should show the controls. So we capture mouse + * events that bubble up to the player and report activity when that happens. + * With touch events it isn't as easy as `touchstart` and `touchend` toggle player + * controls. So touch events can't help us at the player level either. + * + * User activity gets checked asynchronously. So what could happen is a tap event + * on the video turns the controls off. Then the `touchend` event bubbles up to + * the player. Which, if it reported user activity, would turn the controls right + * back on. We also don't want to completely block touch events from bubbling up. + * Furthermore a `touchmove` event and anything other than a tap, should not turn + * controls back on. + * + * @listens Component#touchstart + * @listens Component#touchmove + * @listens Component#touchend + * @listens Component#touchcancel + */ + ; + + _proto.enableTouchActivity = function enableTouchActivity() { + // Don't continue if the root player doesn't support reporting user activity + if (!this.player() || !this.player().reportUserActivity) { + return; + } // listener for reporting that the user is active + + + var report = bind(this.player(), this.player().reportUserActivity); + var touchHolding; + this.on('touchstart', function () { + report(); // For as long as the they are touching the device or have their mouse down, + // we consider them active even if they're not moving their finger or mouse. + // So we want to continue to update that they are active + + this.clearInterval(touchHolding); // report at the same interval as activityCheck + + touchHolding = this.setInterval(report, 250); + }); + + var touchEnd = function touchEnd(event) { + report(); // stop the interval that maintains activity if the touch is holding + + this.clearInterval(touchHolding); + }; + + this.on('touchmove', report); + this.on('touchend', touchEnd); + this.on('touchcancel', touchEnd); + } + /** + * A callback that has no parameters and is bound into `Component`s context. + * + * @callback Component~GenericCallback + * @this Component + */ + + /** + * Creates a function that runs after an `x` millisecond timeout. This function is a + * wrapper around `window.setTimeout`. There are a few reasons to use this one + * instead though: + * 1. It gets cleared via {@link Component#clearTimeout} when + * {@link Component#dispose} gets called. + * 2. The function callback will gets turned into a {@link Component~GenericCallback} + * + * > Note: You can't use `window.clearTimeout` on the id returned by this function. This + * will cause its dispose listener not to get cleaned up! Please use + * {@link Component#clearTimeout} or {@link Component#dispose} instead. + * + * @param {Component~GenericCallback} fn + * The function that will be run after `timeout`. + * + * @param {number} timeout + * Timeout in milliseconds to delay before executing the specified function. + * + * @return {number} + * Returns a timeout ID that gets used to identify the timeout. It can also + * get used in {@link Component#clearTimeout} to clear the timeout that + * was set. + * + * @listens Component#dispose + * @see [Similar to]{@link https://developer.mozilla.org/en-US/docs/Web/API/WindowTimers/setTimeout} + */ + ; + + _proto.setTimeout = function setTimeout(fn, timeout) { + var _this2 = this; + + // declare as variables so they are properly available in timeout function + // eslint-disable-next-line + var timeoutId; + fn = bind(this, fn); + this.clearTimersOnDispose_(); + timeoutId = window__default['default'].setTimeout(function () { + if (_this2.setTimeoutIds_.has(timeoutId)) { + _this2.setTimeoutIds_["delete"](timeoutId); + } + + fn(); + }, timeout); + this.setTimeoutIds_.add(timeoutId); + return timeoutId; + } + /** + * Clears a timeout that gets created via `window.setTimeout` or + * {@link Component#setTimeout}. If you set a timeout via {@link Component#setTimeout} + * use this function instead of `window.clearTimout`. If you don't your dispose + * listener will not get cleaned up until {@link Component#dispose}! + * + * @param {number} timeoutId + * The id of the timeout to clear. The return value of + * {@link Component#setTimeout} or `window.setTimeout`. + * + * @return {number} + * Returns the timeout id that was cleared. + * + * @see [Similar to]{@link https://developer.mozilla.org/en-US/docs/Web/API/WindowTimers/clearTimeout} + */ + ; + + _proto.clearTimeout = function clearTimeout(timeoutId) { + if (this.setTimeoutIds_.has(timeoutId)) { + this.setTimeoutIds_["delete"](timeoutId); + window__default['default'].clearTimeout(timeoutId); + } + + return timeoutId; + } + /** + * Creates a function that gets run every `x` milliseconds. This function is a wrapper + * around `window.setInterval`. There are a few reasons to use this one instead though. + * 1. It gets cleared via {@link Component#clearInterval} when + * {@link Component#dispose} gets called. + * 2. The function callback will be a {@link Component~GenericCallback} + * + * @param {Component~GenericCallback} fn + * The function to run every `x` seconds. + * + * @param {number} interval + * Execute the specified function every `x` milliseconds. + * + * @return {number} + * Returns an id that can be used to identify the interval. It can also be be used in + * {@link Component#clearInterval} to clear the interval. + * + * @listens Component#dispose + * @see [Similar to]{@link https://developer.mozilla.org/en-US/docs/Web/API/WindowTimers/setInterval} + */ + ; + + _proto.setInterval = function setInterval(fn, interval) { + fn = bind(this, fn); + this.clearTimersOnDispose_(); + var intervalId = window__default['default'].setInterval(fn, interval); + this.setIntervalIds_.add(intervalId); + return intervalId; + } + /** + * Clears an interval that gets created via `window.setInterval` or + * {@link Component#setInterval}. If you set an inteval via {@link Component#setInterval} + * use this function instead of `window.clearInterval`. If you don't your dispose + * listener will not get cleaned up until {@link Component#dispose}! + * + * @param {number} intervalId + * The id of the interval to clear. The return value of + * {@link Component#setInterval} or `window.setInterval`. + * + * @return {number} + * Returns the interval id that was cleared. + * + * @see [Similar to]{@link https://developer.mozilla.org/en-US/docs/Web/API/WindowTimers/clearInterval} + */ + ; + + _proto.clearInterval = function clearInterval(intervalId) { + if (this.setIntervalIds_.has(intervalId)) { + this.setIntervalIds_["delete"](intervalId); + window__default['default'].clearInterval(intervalId); + } + + return intervalId; + } + /** + * Queues up a callback to be passed to requestAnimationFrame (rAF), but + * with a few extra bonuses: + * + * - Supports browsers that do not support rAF by falling back to + * {@link Component#setTimeout}. + * + * - The callback is turned into a {@link Component~GenericCallback} (i.e. + * bound to the component). + * + * - Automatic cancellation of the rAF callback is handled if the component + * is disposed before it is called. + * + * @param {Component~GenericCallback} fn + * A function that will be bound to this component and executed just + * before the browser's next repaint. + * + * @return {number} + * Returns an rAF ID that gets used to identify the timeout. It can + * also be used in {@link Component#cancelAnimationFrame} to cancel + * the animation frame callback. + * + * @listens Component#dispose + * @see [Similar to]{@link https://developer.mozilla.org/en-US/docs/Web/API/window/requestAnimationFrame} + */ + ; + + _proto.requestAnimationFrame = function requestAnimationFrame(fn) { + var _this3 = this; + + // Fall back to using a timer. + if (!this.supportsRaf_) { + return this.setTimeout(fn, 1000 / 60); + } + + this.clearTimersOnDispose_(); // declare as variables so they are properly available in rAF function + // eslint-disable-next-line + + var id; + fn = bind(this, fn); + id = window__default['default'].requestAnimationFrame(function () { + if (_this3.rafIds_.has(id)) { + _this3.rafIds_["delete"](id); + } + + fn(); + }); + this.rafIds_.add(id); + return id; + } + /** + * Request an animation frame, but only one named animation + * frame will be queued. Another will never be added until + * the previous one finishes. + * + * @param {string} name + * The name to give this requestAnimationFrame + * + * @param {Component~GenericCallback} fn + * A function that will be bound to this component and executed just + * before the browser's next repaint. + */ + ; + + _proto.requestNamedAnimationFrame = function requestNamedAnimationFrame(name, fn) { + var _this4 = this; + + if (this.namedRafs_.has(name)) { + return; + } + + this.clearTimersOnDispose_(); + fn = bind(this, fn); + var id = this.requestAnimationFrame(function () { + fn(); + + if (_this4.namedRafs_.has(name)) { + _this4.namedRafs_["delete"](name); + } + }); + this.namedRafs_.set(name, id); + return name; + } + /** + * Cancels a current named animation frame if it exists. + * + * @param {string} name + * The name of the requestAnimationFrame to cancel. + */ + ; + + _proto.cancelNamedAnimationFrame = function cancelNamedAnimationFrame(name) { + if (!this.namedRafs_.has(name)) { + return; + } + + this.cancelAnimationFrame(this.namedRafs_.get(name)); + this.namedRafs_["delete"](name); + } + /** + * Cancels a queued callback passed to {@link Component#requestAnimationFrame} + * (rAF). + * + * If you queue an rAF callback via {@link Component#requestAnimationFrame}, + * use this function instead of `window.cancelAnimationFrame`. If you don't, + * your dispose listener will not get cleaned up until {@link Component#dispose}! + * + * @param {number} id + * The rAF ID to clear. The return value of {@link Component#requestAnimationFrame}. + * + * @return {number} + * Returns the rAF ID that was cleared. + * + * @see [Similar to]{@link https://developer.mozilla.org/en-US/docs/Web/API/window/cancelAnimationFrame} + */ + ; + + _proto.cancelAnimationFrame = function cancelAnimationFrame(id) { + // Fall back to using a timer. + if (!this.supportsRaf_) { + return this.clearTimeout(id); + } + + if (this.rafIds_.has(id)) { + this.rafIds_["delete"](id); + window__default['default'].cancelAnimationFrame(id); + } + + return id; + } + /** + * A function to setup `requestAnimationFrame`, `setTimeout`, + * and `setInterval`, clearing on dispose. + * + * > Previously each timer added and removed dispose listeners on it's own. + * For better performance it was decided to batch them all, and use `Set`s + * to track outstanding timer ids. + * + * @private + */ + ; + + _proto.clearTimersOnDispose_ = function clearTimersOnDispose_() { + var _this5 = this; + + if (this.clearingTimersOnDispose_) { + return; + } + + this.clearingTimersOnDispose_ = true; + this.one('dispose', function () { + [['namedRafs_', 'cancelNamedAnimationFrame'], ['rafIds_', 'cancelAnimationFrame'], ['setTimeoutIds_', 'clearTimeout'], ['setIntervalIds_', 'clearInterval']].forEach(function (_ref) { + var idName = _ref[0], + cancelName = _ref[1]; + + // for a `Set` key will actually be the value again + // so forEach((val, val) =>` but for maps we want to use + // the key. + _this5[idName].forEach(function (val, key) { + return _this5[cancelName](key); + }); + }); + _this5.clearingTimersOnDispose_ = false; + }); + } + /** + * Register a `Component` with `videojs` given the name and the component. + * + * > NOTE: {@link Tech}s should not be registered as a `Component`. {@link Tech}s + * should be registered using {@link Tech.registerTech} or + * {@link videojs:videojs.registerTech}. + * + * > NOTE: This function can also be seen on videojs as + * {@link videojs:videojs.registerComponent}. + * + * @param {string} name + * The name of the `Component` to register. + * + * @param {Component} ComponentToRegister + * The `Component` class to register. + * + * @return {Component} + * The `Component` that was registered. + */ + ; + + Component.registerComponent = function registerComponent(name, ComponentToRegister) { + if (typeof name !== 'string' || !name) { + throw new Error("Illegal component name, \"" + name + "\"; must be a non-empty string."); + } + + var Tech = Component.getComponent('Tech'); // We need to make sure this check is only done if Tech has been registered. + + var isTech = Tech && Tech.isTech(ComponentToRegister); + var isComp = Component === ComponentToRegister || Component.prototype.isPrototypeOf(ComponentToRegister.prototype); + + if (isTech || !isComp) { + var reason; + + if (isTech) { + reason = 'techs must be registered using Tech.registerTech()'; + } else { + reason = 'must be a Component subclass'; + } + + throw new Error("Illegal component, \"" + name + "\"; " + reason + "."); + } + + name = toTitleCase(name); + + if (!Component.components_) { + Component.components_ = {}; + } + + var Player = Component.getComponent('Player'); + + if (name === 'Player' && Player && Player.players) { + var players = Player.players; + var playerNames = Object.keys(players); // If we have players that were disposed, then their name will still be + // in Players.players. So, we must loop through and verify that the value + // for each item is not null. This allows registration of the Player component + // after all players have been disposed or before any were created. + + if (players && playerNames.length > 0 && playerNames.map(function (pname) { + return players[pname]; + }).every(Boolean)) { + throw new Error('Can not register Player component after player has been created.'); + } + } + + Component.components_[name] = ComponentToRegister; + Component.components_[toLowerCase(name)] = ComponentToRegister; + return ComponentToRegister; + } + /** + * Get a `Component` based on the name it was registered with. + * + * @param {string} name + * The Name of the component to get. + * + * @return {Component} + * The `Component` that got registered under the given name. + * + * @deprecated In `videojs` 6 this will not return `Component`s that were not + * registered using {@link Component.registerComponent}. Currently we + * check the global `videojs` object for a `Component` name and + * return that if it exists. + */ + ; + + Component.getComponent = function getComponent(name) { + if (!name || !Component.components_) { + return; + } + + return Component.components_[name]; + }; + + return Component; +}(); +/** + * Whether or not this component supports `requestAnimationFrame`. + * + * This is exposed primarily for testing purposes. + * + * @private + * @type {Boolean} + */ + + +Component.prototype.supportsRaf_ = typeof window__default['default'].requestAnimationFrame === 'function' && typeof window__default['default'].cancelAnimationFrame === 'function'; +Component.registerComponent('Component', Component); + +/** + * @file time-ranges.js + * @module time-ranges + */ + +/** + * Returns the time for the specified index at the start or end + * of a TimeRange object. + * + * @typedef {Function} TimeRangeIndex + * + * @param {number} [index=0] + * The range number to return the time for. + * + * @return {number} + * The time offset at the specified index. + * + * @deprecated The index argument must be provided. + * In the future, leaving it out will throw an error. + */ + +/** + * An object that contains ranges of time. + * + * @typedef {Object} TimeRange + * + * @property {number} length + * The number of time ranges represented by this object. + * + * @property {module:time-ranges~TimeRangeIndex} start + * Returns the time offset at which a specified time range begins. + * + * @property {module:time-ranges~TimeRangeIndex} end + * Returns the time offset at which a specified time range ends. + * + * @see https://developer.mozilla.org/en-US/docs/Web/API/TimeRanges + */ + +/** + * Check if any of the time ranges are over the maximum index. + * + * @private + * @param {string} fnName + * The function name to use for logging + * + * @param {number} index + * The index to check + * + * @param {number} maxIndex + * The maximum possible index + * + * @throws {Error} if the timeRanges provided are over the maxIndex + */ +function rangeCheck(fnName, index, maxIndex) { + if (typeof index !== 'number' || index < 0 || index > maxIndex) { + throw new Error("Failed to execute '" + fnName + "' on 'TimeRanges': The index provided (" + index + ") is non-numeric or out of bounds (0-" + maxIndex + ")."); + } +} +/** + * Get the time for the specified index at the start or end + * of a TimeRange object. + * + * @private + * @param {string} fnName + * The function name to use for logging + * + * @param {string} valueIndex + * The property that should be used to get the time. should be + * 'start' or 'end' + * + * @param {Array} ranges + * An array of time ranges + * + * @param {Array} [rangeIndex=0] + * The index to start the search at + * + * @return {number} + * The time that offset at the specified index. + * + * @deprecated rangeIndex must be set to a value, in the future this will throw an error. + * @throws {Error} if rangeIndex is more than the length of ranges + */ + + +function getRange(fnName, valueIndex, ranges, rangeIndex) { + rangeCheck(fnName, rangeIndex, ranges.length - 1); + return ranges[rangeIndex][valueIndex]; +} +/** + * Create a time range object given ranges of time. + * + * @private + * @param {Array} [ranges] + * An array of time ranges. + */ + + +function createTimeRangesObj(ranges) { + if (ranges === undefined || ranges.length === 0) { + return { + length: 0, + start: function start() { + throw new Error('This TimeRanges object is empty'); + }, + end: function end() { + throw new Error('This TimeRanges object is empty'); + } + }; + } + + return { + length: ranges.length, + start: getRange.bind(null, 'start', 0, ranges), + end: getRange.bind(null, 'end', 1, ranges) + }; +} +/** + * Create a `TimeRange` object which mimics an + * {@link https://developer.mozilla.org/en-US/docs/Web/API/TimeRanges|HTML5 TimeRanges instance}. + * + * @param {number|Array[]} start + * The start of a single range (a number) or an array of ranges (an + * array of arrays of two numbers each). + * + * @param {number} end + * The end of a single range. Cannot be used with the array form of + * the `start` argument. + */ + + +function createTimeRanges(start, end) { + if (Array.isArray(start)) { + return createTimeRangesObj(start); + } else if (start === undefined || end === undefined) { + return createTimeRangesObj(); + } + + return createTimeRangesObj([[start, end]]); +} + +/** + * @file buffer.js + * @module buffer + */ +/** + * Compute the percentage of the media that has been buffered. + * + * @param {TimeRange} buffered + * The current `TimeRange` object representing buffered time ranges + * + * @param {number} duration + * Total duration of the media + * + * @return {number} + * Percent buffered of the total duration in decimal form. + */ + +function bufferedPercent(buffered, duration) { + var bufferedDuration = 0; + var start; + var end; + + if (!duration) { + return 0; + } + + if (!buffered || !buffered.length) { + buffered = createTimeRanges(0, 0); + } + + for (var i = 0; i < buffered.length; i++) { + start = buffered.start(i); + end = buffered.end(i); // buffered end can be bigger than duration by a very small fraction + + if (end > duration) { + end = duration; + } + + bufferedDuration += end - start; + } + + return bufferedDuration / duration; +} + +/** + * @file media-error.js + */ +/** + * A Custom `MediaError` class which mimics the standard HTML5 `MediaError` class. + * + * @param {number|string|Object|MediaError} value + * This can be of multiple types: + * - number: should be a standard error code + * - string: an error message (the code will be 0) + * - Object: arbitrary properties + * - `MediaError` (native): used to populate a video.js `MediaError` object + * - `MediaError` (video.js): will return itself if it's already a + * video.js `MediaError` object. + * + * @see [MediaError Spec]{@link https://dev.w3.org/html5/spec-author-view/video.html#mediaerror} + * @see [Encrypted MediaError Spec]{@link https://www.w3.org/TR/2013/WD-encrypted-media-20130510/#error-codes} + * + * @class MediaError + */ + +function MediaError(value) { + // Allow redundant calls to this constructor to avoid having `instanceof` + // checks peppered around the code. + if (value instanceof MediaError) { + return value; + } + + if (typeof value === 'number') { + this.code = value; + } else if (typeof value === 'string') { + // default code is zero, so this is a custom error + this.message = value; + } else if (isObject(value)) { + // We assign the `code` property manually because native `MediaError` objects + // do not expose it as an own/enumerable property of the object. + if (typeof value.code === 'number') { + this.code = value.code; + } + + assign(this, value); + } + + if (!this.message) { + this.message = MediaError.defaultMessages[this.code] || ''; + } +} +/** + * The error code that refers two one of the defined `MediaError` types + * + * @type {Number} + */ + + +MediaError.prototype.code = 0; +/** + * An optional message that to show with the error. Message is not part of the HTML5 + * video spec but allows for more informative custom errors. + * + * @type {String} + */ + +MediaError.prototype.message = ''; +/** + * An optional status code that can be set by plugins to allow even more detail about + * the error. For example a plugin might provide a specific HTTP status code and an + * error message for that code. Then when the plugin gets that error this class will + * know how to display an error message for it. This allows a custom message to show + * up on the `Player` error overlay. + * + * @type {Array} + */ + +MediaError.prototype.status = null; +/** + * Errors indexed by the W3C standard. The order **CANNOT CHANGE**! See the + * specification listed under {@link MediaError} for more information. + * + * @enum {array} + * @readonly + * @property {string} 0 - MEDIA_ERR_CUSTOM + * @property {string} 1 - MEDIA_ERR_ABORTED + * @property {string} 2 - MEDIA_ERR_NETWORK + * @property {string} 3 - MEDIA_ERR_DECODE + * @property {string} 4 - MEDIA_ERR_SRC_NOT_SUPPORTED + * @property {string} 5 - MEDIA_ERR_ENCRYPTED + */ + +MediaError.errorTypes = ['MEDIA_ERR_CUSTOM', 'MEDIA_ERR_ABORTED', 'MEDIA_ERR_NETWORK', 'MEDIA_ERR_DECODE', 'MEDIA_ERR_SRC_NOT_SUPPORTED', 'MEDIA_ERR_ENCRYPTED']; +/** + * The default `MediaError` messages based on the {@link MediaError.errorTypes}. + * + * @type {Array} + * @constant + */ + +MediaError.defaultMessages = { + 1: 'You aborted the media playback', + 2: 'A network error caused the media download to fail part-way.', + 3: 'The media playback was aborted due to a corruption problem or because the media used features your browser did not support.', + 4: 'The media could not be loaded, either because the server or network failed or because the format is not supported.', + 5: 'The media is encrypted and we do not have the keys to decrypt it.' +}; // Add types as properties on MediaError +// e.g. MediaError.MEDIA_ERR_SRC_NOT_SUPPORTED = 4; + +for (var errNum = 0; errNum < MediaError.errorTypes.length; errNum++) { + MediaError[MediaError.errorTypes[errNum]] = errNum; // values should be accessible on both the class and instance + + MediaError.prototype[MediaError.errorTypes[errNum]] = errNum; +} // jsdocs for instance/static members added above + +/** + * Returns whether an object is `Promise`-like (i.e. has a `then` method). + * + * @param {Object} value + * An object that may or may not be `Promise`-like. + * + * @return {boolean} + * Whether or not the object is `Promise`-like. + */ +function isPromise(value) { + return value !== undefined && value !== null && typeof value.then === 'function'; +} +/** + * Silence a Promise-like object. + * + * This is useful for avoiding non-harmful, but potentially confusing "uncaught + * play promise" rejection error messages. + * + * @param {Object} value + * An object that may or may not be `Promise`-like. + */ + +function silencePromise(value) { + if (isPromise(value)) { + value.then(null, function (e) {}); + } +} + +/** + * @file text-track-list-converter.js Utilities for capturing text track state and + * re-creating tracks based on a capture. + * + * @module text-track-list-converter + */ + +/** + * Examine a single {@link TextTrack} and return a JSON-compatible javascript object that + * represents the {@link TextTrack}'s state. + * + * @param {TextTrack} track + * The text track to query. + * + * @return {Object} + * A serializable javascript representation of the TextTrack. + * @private + */ +var trackToJson_ = function trackToJson_(track) { + var ret = ['kind', 'label', 'language', 'id', 'inBandMetadataTrackDispatchType', 'mode', 'src'].reduce(function (acc, prop, i) { + if (track[prop]) { + acc[prop] = track[prop]; + } + + return acc; + }, { + cues: track.cues && Array.prototype.map.call(track.cues, function (cue) { + return { + startTime: cue.startTime, + endTime: cue.endTime, + text: cue.text, + id: cue.id + }; + }) + }); + return ret; +}; +/** + * Examine a {@link Tech} and return a JSON-compatible javascript array that represents the + * state of all {@link TextTrack}s currently configured. The return array is compatible with + * {@link text-track-list-converter:jsonToTextTracks}. + * + * @param {Tech} tech + * The tech object to query + * + * @return {Array} + * A serializable javascript representation of the {@link Tech}s + * {@link TextTrackList}. + */ + + +var textTracksToJson = function textTracksToJson(tech) { + var trackEls = tech.$$('track'); + var trackObjs = Array.prototype.map.call(trackEls, function (t) { + return t.track; + }); + var tracks = Array.prototype.map.call(trackEls, function (trackEl) { + var json = trackToJson_(trackEl.track); + + if (trackEl.src) { + json.src = trackEl.src; + } + + return json; + }); + return tracks.concat(Array.prototype.filter.call(tech.textTracks(), function (track) { + return trackObjs.indexOf(track) === -1; + }).map(trackToJson_)); +}; +/** + * Create a set of remote {@link TextTrack}s on a {@link Tech} based on an array of javascript + * object {@link TextTrack} representations. + * + * @param {Array} json + * An array of `TextTrack` representation objects, like those that would be + * produced by `textTracksToJson`. + * + * @param {Tech} tech + * The `Tech` to create the `TextTrack`s on. + */ + + +var jsonToTextTracks = function jsonToTextTracks(json, tech) { + json.forEach(function (track) { + var addedTrack = tech.addRemoteTextTrack(track).track; + + if (!track.src && track.cues) { + track.cues.forEach(function (cue) { + return addedTrack.addCue(cue); + }); + } + }); + return tech.textTracks(); +}; + +var textTrackConverter = { + textTracksToJson: textTracksToJson, + jsonToTextTracks: jsonToTextTracks, + trackToJson_: trackToJson_ +}; + +var MODAL_CLASS_NAME = 'vjs-modal-dialog'; +/** + * The `ModalDialog` displays over the video and its controls, which blocks + * interaction with the player until it is closed. + * + * Modal dialogs include a "Close" button and will close when that button + * is activated - or when ESC is pressed anywhere. + * + * @extends Component + */ + +var ModalDialog = /*#__PURE__*/function (_Component) { + _inheritsLoose__default['default'](ModalDialog, _Component); + + /** + * Create an instance of this class. + * + * @param {Player} player + * The `Player` that this class should be attached to. + * + * @param {Object} [options] + * The key/value store of player options. + * + * @param {Mixed} [options.content=undefined] + * Provide customized content for this modal. + * + * @param {string} [options.description] + * A text description for the modal, primarily for accessibility. + * + * @param {boolean} [options.fillAlways=false] + * Normally, modals are automatically filled only the first time + * they open. This tells the modal to refresh its content + * every time it opens. + * + * @param {string} [options.label] + * A text label for the modal, primarily for accessibility. + * + * @param {boolean} [options.pauseOnOpen=true] + * If `true`, playback will will be paused if playing when + * the modal opens, and resumed when it closes. + * + * @param {boolean} [options.temporary=true] + * If `true`, the modal can only be opened once; it will be + * disposed as soon as it's closed. + * + * @param {boolean} [options.uncloseable=false] + * If `true`, the user will not be able to close the modal + * through the UI in the normal ways. Programmatic closing is + * still possible. + */ + function ModalDialog(player, options) { + var _this; + + _this = _Component.call(this, player, options) || this; + + _this.handleKeyDown_ = function (e) { + return _this.handleKeyDown(e); + }; + + _this.close_ = function (e) { + return _this.close(e); + }; + + _this.opened_ = _this.hasBeenOpened_ = _this.hasBeenFilled_ = false; + + _this.closeable(!_this.options_.uncloseable); + + _this.content(_this.options_.content); // Make sure the contentEl is defined AFTER any children are initialized + // because we only want the contents of the modal in the contentEl + // (not the UI elements like the close button). + + + _this.contentEl_ = createEl('div', { + className: MODAL_CLASS_NAME + "-content" + }, { + role: 'document' + }); + _this.descEl_ = createEl('p', { + className: MODAL_CLASS_NAME + "-description vjs-control-text", + id: _this.el().getAttribute('aria-describedby') + }); + textContent(_this.descEl_, _this.description()); + + _this.el_.appendChild(_this.descEl_); + + _this.el_.appendChild(_this.contentEl_); + + return _this; + } + /** + * Create the `ModalDialog`'s DOM element + * + * @return {Element} + * The DOM element that gets created. + */ + + + var _proto = ModalDialog.prototype; + + _proto.createEl = function createEl() { + return _Component.prototype.createEl.call(this, 'div', { + className: this.buildCSSClass(), + tabIndex: -1 + }, { + 'aria-describedby': this.id() + "_description", + 'aria-hidden': 'true', + 'aria-label': this.label(), + 'role': 'dialog' + }); + }; + + _proto.dispose = function dispose() { + this.contentEl_ = null; + this.descEl_ = null; + this.previouslyActiveEl_ = null; + + _Component.prototype.dispose.call(this); + } + /** + * Builds the default DOM `className`. + * + * @return {string} + * The DOM `className` for this object. + */ + ; + + _proto.buildCSSClass = function buildCSSClass() { + return MODAL_CLASS_NAME + " vjs-hidden " + _Component.prototype.buildCSSClass.call(this); + } + /** + * Returns the label string for this modal. Primarily used for accessibility. + * + * @return {string} + * the localized or raw label of this modal. + */ + ; + + _proto.label = function label() { + return this.localize(this.options_.label || 'Modal Window'); + } + /** + * Returns the description string for this modal. Primarily used for + * accessibility. + * + * @return {string} + * The localized or raw description of this modal. + */ + ; + + _proto.description = function description() { + var desc = this.options_.description || this.localize('This is a modal window.'); // Append a universal closeability message if the modal is closeable. + + if (this.closeable()) { + desc += ' ' + this.localize('This modal can be closed by pressing the Escape key or activating the close button.'); + } + + return desc; + } + /** + * Opens the modal. + * + * @fires ModalDialog#beforemodalopen + * @fires ModalDialog#modalopen + */ + ; + + _proto.open = function open() { + if (!this.opened_) { + var player = this.player(); + /** + * Fired just before a `ModalDialog` is opened. + * + * @event ModalDialog#beforemodalopen + * @type {EventTarget~Event} + */ + + this.trigger('beforemodalopen'); + this.opened_ = true; // Fill content if the modal has never opened before and + // never been filled. + + if (this.options_.fillAlways || !this.hasBeenOpened_ && !this.hasBeenFilled_) { + this.fill(); + } // If the player was playing, pause it and take note of its previously + // playing state. + + + this.wasPlaying_ = !player.paused(); + + if (this.options_.pauseOnOpen && this.wasPlaying_) { + player.pause(); + } + + this.on('keydown', this.handleKeyDown_); // Hide controls and note if they were enabled. + + this.hadControls_ = player.controls(); + player.controls(false); + this.show(); + this.conditionalFocus_(); + this.el().setAttribute('aria-hidden', 'false'); + /** + * Fired just after a `ModalDialog` is opened. + * + * @event ModalDialog#modalopen + * @type {EventTarget~Event} + */ + + this.trigger('modalopen'); + this.hasBeenOpened_ = true; + } + } + /** + * If the `ModalDialog` is currently open or closed. + * + * @param {boolean} [value] + * If given, it will open (`true`) or close (`false`) the modal. + * + * @return {boolean} + * the current open state of the modaldialog + */ + ; + + _proto.opened = function opened(value) { + if (typeof value === 'boolean') { + this[value ? 'open' : 'close'](); + } + + return this.opened_; + } + /** + * Closes the modal, does nothing if the `ModalDialog` is + * not open. + * + * @fires ModalDialog#beforemodalclose + * @fires ModalDialog#modalclose + */ + ; + + _proto.close = function close() { + if (!this.opened_) { + return; + } + + var player = this.player(); + /** + * Fired just before a `ModalDialog` is closed. + * + * @event ModalDialog#beforemodalclose + * @type {EventTarget~Event} + */ + + this.trigger('beforemodalclose'); + this.opened_ = false; + + if (this.wasPlaying_ && this.options_.pauseOnOpen) { + player.play(); + } + + this.off('keydown', this.handleKeyDown_); + + if (this.hadControls_) { + player.controls(true); + } + + this.hide(); + this.el().setAttribute('aria-hidden', 'true'); + /** + * Fired just after a `ModalDialog` is closed. + * + * @event ModalDialog#modalclose + * @type {EventTarget~Event} + */ + + this.trigger('modalclose'); + this.conditionalBlur_(); + + if (this.options_.temporary) { + this.dispose(); + } + } + /** + * Check to see if the `ModalDialog` is closeable via the UI. + * + * @param {boolean} [value] + * If given as a boolean, it will set the `closeable` option. + * + * @return {boolean} + * Returns the final value of the closable option. + */ + ; + + _proto.closeable = function closeable(value) { + if (typeof value === 'boolean') { + var closeable = this.closeable_ = !!value; + var close = this.getChild('closeButton'); // If this is being made closeable and has no close button, add one. + + if (closeable && !close) { + // The close button should be a child of the modal - not its + // content element, so temporarily change the content element. + var temp = this.contentEl_; + this.contentEl_ = this.el_; + close = this.addChild('closeButton', { + controlText: 'Close Modal Dialog' + }); + this.contentEl_ = temp; + this.on(close, 'close', this.close_); + } // If this is being made uncloseable and has a close button, remove it. + + + if (!closeable && close) { + this.off(close, 'close', this.close_); + this.removeChild(close); + close.dispose(); + } + } + + return this.closeable_; + } + /** + * Fill the modal's content element with the modal's "content" option. + * The content element will be emptied before this change takes place. + */ + ; + + _proto.fill = function fill() { + this.fillWith(this.content()); + } + /** + * Fill the modal's content element with arbitrary content. + * The content element will be emptied before this change takes place. + * + * @fires ModalDialog#beforemodalfill + * @fires ModalDialog#modalfill + * + * @param {Mixed} [content] + * The same rules apply to this as apply to the `content` option. + */ + ; + + _proto.fillWith = function fillWith(content) { + var contentEl = this.contentEl(); + var parentEl = contentEl.parentNode; + var nextSiblingEl = contentEl.nextSibling; + /** + * Fired just before a `ModalDialog` is filled with content. + * + * @event ModalDialog#beforemodalfill + * @type {EventTarget~Event} + */ + + this.trigger('beforemodalfill'); + this.hasBeenFilled_ = true; // Detach the content element from the DOM before performing + // manipulation to avoid modifying the live DOM multiple times. + + parentEl.removeChild(contentEl); + this.empty(); + insertContent(contentEl, content); + /** + * Fired just after a `ModalDialog` is filled with content. + * + * @event ModalDialog#modalfill + * @type {EventTarget~Event} + */ + + this.trigger('modalfill'); // Re-inject the re-filled content element. + + if (nextSiblingEl) { + parentEl.insertBefore(contentEl, nextSiblingEl); + } else { + parentEl.appendChild(contentEl); + } // make sure that the close button is last in the dialog DOM + + + var closeButton = this.getChild('closeButton'); + + if (closeButton) { + parentEl.appendChild(closeButton.el_); + } + } + /** + * Empties the content element. This happens anytime the modal is filled. + * + * @fires ModalDialog#beforemodalempty + * @fires ModalDialog#modalempty + */ + ; + + _proto.empty = function empty() { + /** + * Fired just before a `ModalDialog` is emptied. + * + * @event ModalDialog#beforemodalempty + * @type {EventTarget~Event} + */ + this.trigger('beforemodalempty'); + emptyEl(this.contentEl()); + /** + * Fired just after a `ModalDialog` is emptied. + * + * @event ModalDialog#modalempty + * @type {EventTarget~Event} + */ + + this.trigger('modalempty'); + } + /** + * Gets or sets the modal content, which gets normalized before being + * rendered into the DOM. + * + * This does not update the DOM or fill the modal, but it is called during + * that process. + * + * @param {Mixed} [value] + * If defined, sets the internal content value to be used on the + * next call(s) to `fill`. This value is normalized before being + * inserted. To "clear" the internal content value, pass `null`. + * + * @return {Mixed} + * The current content of the modal dialog + */ + ; + + _proto.content = function content(value) { + if (typeof value !== 'undefined') { + this.content_ = value; + } + + return this.content_; + } + /** + * conditionally focus the modal dialog if focus was previously on the player. + * + * @private + */ + ; + + _proto.conditionalFocus_ = function conditionalFocus_() { + var activeEl = document__default['default'].activeElement; + var playerEl = this.player_.el_; + this.previouslyActiveEl_ = null; + + if (playerEl.contains(activeEl) || playerEl === activeEl) { + this.previouslyActiveEl_ = activeEl; + this.focus(); + } + } + /** + * conditionally blur the element and refocus the last focused element + * + * @private + */ + ; + + _proto.conditionalBlur_ = function conditionalBlur_() { + if (this.previouslyActiveEl_) { + this.previouslyActiveEl_.focus(); + this.previouslyActiveEl_ = null; + } + } + /** + * Keydown handler. Attached when modal is focused. + * + * @listens keydown + */ + ; + + _proto.handleKeyDown = function handleKeyDown(event) { + // Do not allow keydowns to reach out of the modal dialog. + event.stopPropagation(); + + if (keycode__default['default'].isEventKey(event, 'Escape') && this.closeable()) { + event.preventDefault(); + this.close(); + return; + } // exit early if it isn't a tab key + + + if (!keycode__default['default'].isEventKey(event, 'Tab')) { + return; + } + + var focusableEls = this.focusableEls_(); + var activeEl = this.el_.querySelector(':focus'); + var focusIndex; + + for (var i = 0; i < focusableEls.length; i++) { + if (activeEl === focusableEls[i]) { + focusIndex = i; + break; + } + } + + if (document__default['default'].activeElement === this.el_) { + focusIndex = 0; + } + + if (event.shiftKey && focusIndex === 0) { + focusableEls[focusableEls.length - 1].focus(); + event.preventDefault(); + } else if (!event.shiftKey && focusIndex === focusableEls.length - 1) { + focusableEls[0].focus(); + event.preventDefault(); + } + } + /** + * get all focusable elements + * + * @private + */ + ; + + _proto.focusableEls_ = function focusableEls_() { + var allChildren = this.el_.querySelectorAll('*'); + return Array.prototype.filter.call(allChildren, function (child) { + return (child instanceof window__default['default'].HTMLAnchorElement || child instanceof window__default['default'].HTMLAreaElement) && child.hasAttribute('href') || (child instanceof window__default['default'].HTMLInputElement || child instanceof window__default['default'].HTMLSelectElement || child instanceof window__default['default'].HTMLTextAreaElement || child instanceof window__default['default'].HTMLButtonElement) && !child.hasAttribute('disabled') || child instanceof window__default['default'].HTMLIFrameElement || child instanceof window__default['default'].HTMLObjectElement || child instanceof window__default['default'].HTMLEmbedElement || child.hasAttribute('tabindex') && child.getAttribute('tabindex') !== -1 || child.hasAttribute('contenteditable'); + }); + }; + + return ModalDialog; +}(Component); +/** + * Default options for `ModalDialog` default options. + * + * @type {Object} + * @private + */ + + +ModalDialog.prototype.options_ = { + pauseOnOpen: true, + temporary: true +}; +Component.registerComponent('ModalDialog', ModalDialog); + +/** + * Common functionaliy between {@link TextTrackList}, {@link AudioTrackList}, and + * {@link VideoTrackList} + * + * @extends EventTarget + */ + +var TrackList = /*#__PURE__*/function (_EventTarget) { + _inheritsLoose__default['default'](TrackList, _EventTarget); + + /** + * Create an instance of this class + * + * @param {Track[]} tracks + * A list of tracks to initialize the list with. + * + * @abstract + */ + function TrackList(tracks) { + var _this; + + if (tracks === void 0) { + tracks = []; + } + + _this = _EventTarget.call(this) || this; + _this.tracks_ = []; + /** + * @memberof TrackList + * @member {number} length + * The current number of `Track`s in the this Trackist. + * @instance + */ + + Object.defineProperty(_assertThisInitialized__default['default'](_this), 'length', { + get: function get() { + return this.tracks_.length; + } + }); + + for (var i = 0; i < tracks.length; i++) { + _this.addTrack(tracks[i]); + } + + return _this; + } + /** + * Add a {@link Track} to the `TrackList` + * + * @param {Track} track + * The audio, video, or text track to add to the list. + * + * @fires TrackList#addtrack + */ + + + var _proto = TrackList.prototype; + + _proto.addTrack = function addTrack(track) { + var _this2 = this; + + var index = this.tracks_.length; + + if (!('' + index in this)) { + Object.defineProperty(this, index, { + get: function get() { + return this.tracks_[index]; + } + }); + } // Do not add duplicate tracks + + + if (this.tracks_.indexOf(track) === -1) { + this.tracks_.push(track); + /** + * Triggered when a track is added to a track list. + * + * @event TrackList#addtrack + * @type {EventTarget~Event} + * @property {Track} track + * A reference to track that was added. + */ + + this.trigger({ + track: track, + type: 'addtrack', + target: this + }); + } + /** + * Triggered when a track label is changed. + * + * @event TrackList#addtrack + * @type {EventTarget~Event} + * @property {Track} track + * A reference to track that was added. + */ + + + track.labelchange_ = function () { + _this2.trigger({ + track: track, + type: 'labelchange', + target: _this2 + }); + }; + + if (isEvented(track)) { + track.addEventListener('labelchange', track.labelchange_); + } + } + /** + * Remove a {@link Track} from the `TrackList` + * + * @param {Track} rtrack + * The audio, video, or text track to remove from the list. + * + * @fires TrackList#removetrack + */ + ; + + _proto.removeTrack = function removeTrack(rtrack) { + var track; + + for (var i = 0, l = this.length; i < l; i++) { + if (this[i] === rtrack) { + track = this[i]; + + if (track.off) { + track.off(); + } + + this.tracks_.splice(i, 1); + break; + } + } + + if (!track) { + return; + } + /** + * Triggered when a track is removed from track list. + * + * @event TrackList#removetrack + * @type {EventTarget~Event} + * @property {Track} track + * A reference to track that was removed. + */ + + + this.trigger({ + track: track, + type: 'removetrack', + target: this + }); + } + /** + * Get a Track from the TrackList by a tracks id + * + * @param {string} id - the id of the track to get + * @method getTrackById + * @return {Track} + * @private + */ + ; + + _proto.getTrackById = function getTrackById(id) { + var result = null; + + for (var i = 0, l = this.length; i < l; i++) { + var track = this[i]; + + if (track.id === id) { + result = track; + break; + } + } + + return result; + }; + + return TrackList; +}(EventTarget); +/** + * Triggered when a different track is selected/enabled. + * + * @event TrackList#change + * @type {EventTarget~Event} + */ + +/** + * Events that can be called with on + eventName. See {@link EventHandler}. + * + * @property {Object} TrackList#allowedEvents_ + * @private + */ + + +TrackList.prototype.allowedEvents_ = { + change: 'change', + addtrack: 'addtrack', + removetrack: 'removetrack', + labelchange: 'labelchange' +}; // emulate attribute EventHandler support to allow for feature detection + +for (var event in TrackList.prototype.allowedEvents_) { + TrackList.prototype['on' + event] = null; +} + +/** + * Anywhere we call this function we diverge from the spec + * as we only support one enabled audiotrack at a time + * + * @param {AudioTrackList} list + * list to work on + * + * @param {AudioTrack} track + * The track to skip + * + * @private + */ + +var disableOthers$1 = function disableOthers(list, track) { + for (var i = 0; i < list.length; i++) { + if (!Object.keys(list[i]).length || track.id === list[i].id) { + continue; + } // another audio track is enabled, disable it + + + list[i].enabled = false; + } +}; +/** + * The current list of {@link AudioTrack} for a media file. + * + * @see [Spec]{@link https://html.spec.whatwg.org/multipage/embedded-content.html#audiotracklist} + * @extends TrackList + */ + + +var AudioTrackList = /*#__PURE__*/function (_TrackList) { + _inheritsLoose__default['default'](AudioTrackList, _TrackList); + + /** + * Create an instance of this class. + * + * @param {AudioTrack[]} [tracks=[]] + * A list of `AudioTrack` to instantiate the list with. + */ + function AudioTrackList(tracks) { + var _this; + + if (tracks === void 0) { + tracks = []; + } + + // make sure only 1 track is enabled + // sorted from last index to first index + for (var i = tracks.length - 1; i >= 0; i--) { + if (tracks[i].enabled) { + disableOthers$1(tracks, tracks[i]); + break; + } + } + + _this = _TrackList.call(this, tracks) || this; + _this.changing_ = false; + return _this; + } + /** + * Add an {@link AudioTrack} to the `AudioTrackList`. + * + * @param {AudioTrack} track + * The AudioTrack to add to the list + * + * @fires TrackList#addtrack + */ + + + var _proto = AudioTrackList.prototype; + + _proto.addTrack = function addTrack(track) { + var _this2 = this; + + if (track.enabled) { + disableOthers$1(this, track); + } + + _TrackList.prototype.addTrack.call(this, track); // native tracks don't have this + + + if (!track.addEventListener) { + return; + } + + track.enabledChange_ = function () { + // when we are disabling other tracks (since we don't support + // more than one track at a time) we will set changing_ + // to true so that we don't trigger additional change events + if (_this2.changing_) { + return; + } + + _this2.changing_ = true; + disableOthers$1(_this2, track); + _this2.changing_ = false; + + _this2.trigger('change'); + }; + /** + * @listens AudioTrack#enabledchange + * @fires TrackList#change + */ + + + track.addEventListener('enabledchange', track.enabledChange_); + }; + + _proto.removeTrack = function removeTrack(rtrack) { + _TrackList.prototype.removeTrack.call(this, rtrack); + + if (rtrack.removeEventListener && rtrack.enabledChange_) { + rtrack.removeEventListener('enabledchange', rtrack.enabledChange_); + rtrack.enabledChange_ = null; + } + }; + + return AudioTrackList; +}(TrackList); + +/** + * Un-select all other {@link VideoTrack}s that are selected. + * + * @param {VideoTrackList} list + * list to work on + * + * @param {VideoTrack} track + * The track to skip + * + * @private + */ + +var disableOthers = function disableOthers(list, track) { + for (var i = 0; i < list.length; i++) { + if (!Object.keys(list[i]).length || track.id === list[i].id) { + continue; + } // another video track is enabled, disable it + + + list[i].selected = false; + } +}; +/** + * The current list of {@link VideoTrack} for a video. + * + * @see [Spec]{@link https://html.spec.whatwg.org/multipage/embedded-content.html#videotracklist} + * @extends TrackList + */ + + +var VideoTrackList = /*#__PURE__*/function (_TrackList) { + _inheritsLoose__default['default'](VideoTrackList, _TrackList); + + /** + * Create an instance of this class. + * + * @param {VideoTrack[]} [tracks=[]] + * A list of `VideoTrack` to instantiate the list with. + */ + function VideoTrackList(tracks) { + var _this; + + if (tracks === void 0) { + tracks = []; + } + + // make sure only 1 track is enabled + // sorted from last index to first index + for (var i = tracks.length - 1; i >= 0; i--) { + if (tracks[i].selected) { + disableOthers(tracks, tracks[i]); + break; + } + } + + _this = _TrackList.call(this, tracks) || this; + _this.changing_ = false; + /** + * @member {number} VideoTrackList#selectedIndex + * The current index of the selected {@link VideoTrack`}. + */ + + Object.defineProperty(_assertThisInitialized__default['default'](_this), 'selectedIndex', { + get: function get() { + for (var _i = 0; _i < this.length; _i++) { + if (this[_i].selected) { + return _i; + } + } + + return -1; + }, + set: function set() {} + }); + return _this; + } + /** + * Add a {@link VideoTrack} to the `VideoTrackList`. + * + * @param {VideoTrack} track + * The VideoTrack to add to the list + * + * @fires TrackList#addtrack + */ + + + var _proto = VideoTrackList.prototype; + + _proto.addTrack = function addTrack(track) { + var _this2 = this; + + if (track.selected) { + disableOthers(this, track); + } + + _TrackList.prototype.addTrack.call(this, track); // native tracks don't have this + + + if (!track.addEventListener) { + return; + } + + track.selectedChange_ = function () { + if (_this2.changing_) { + return; + } + + _this2.changing_ = true; + disableOthers(_this2, track); + _this2.changing_ = false; + + _this2.trigger('change'); + }; + /** + * @listens VideoTrack#selectedchange + * @fires TrackList#change + */ + + + track.addEventListener('selectedchange', track.selectedChange_); + }; + + _proto.removeTrack = function removeTrack(rtrack) { + _TrackList.prototype.removeTrack.call(this, rtrack); + + if (rtrack.removeEventListener && rtrack.selectedChange_) { + rtrack.removeEventListener('selectedchange', rtrack.selectedChange_); + rtrack.selectedChange_ = null; + } + }; + + return VideoTrackList; +}(TrackList); + +/** + * The current list of {@link TextTrack} for a media file. + * + * @see [Spec]{@link https://html.spec.whatwg.org/multipage/embedded-content.html#texttracklist} + * @extends TrackList + */ + +var TextTrackList = /*#__PURE__*/function (_TrackList) { + _inheritsLoose__default['default'](TextTrackList, _TrackList); + + function TextTrackList() { + return _TrackList.apply(this, arguments) || this; + } + + var _proto = TextTrackList.prototype; + + /** + * Add a {@link TextTrack} to the `TextTrackList` + * + * @param {TextTrack} track + * The text track to add to the list. + * + * @fires TrackList#addtrack + */ + _proto.addTrack = function addTrack(track) { + var _this = this; + + _TrackList.prototype.addTrack.call(this, track); + + if (!this.queueChange_) { + this.queueChange_ = function () { + return _this.queueTrigger('change'); + }; + } + + if (!this.triggerSelectedlanguagechange) { + this.triggerSelectedlanguagechange_ = function () { + return _this.trigger('selectedlanguagechange'); + }; + } + /** + * @listens TextTrack#modechange + * @fires TrackList#change + */ + + + track.addEventListener('modechange', this.queueChange_); + var nonLanguageTextTrackKind = ['metadata', 'chapters']; + + if (nonLanguageTextTrackKind.indexOf(track.kind) === -1) { + track.addEventListener('modechange', this.triggerSelectedlanguagechange_); + } + }; + + _proto.removeTrack = function removeTrack(rtrack) { + _TrackList.prototype.removeTrack.call(this, rtrack); // manually remove the event handlers we added + + + if (rtrack.removeEventListener) { + if (this.queueChange_) { + rtrack.removeEventListener('modechange', this.queueChange_); + } + + if (this.selectedlanguagechange_) { + rtrack.removeEventListener('modechange', this.triggerSelectedlanguagechange_); + } + } + }; + + return TextTrackList; +}(TrackList); + +/** + * @file html-track-element-list.js + */ + +/** + * The current list of {@link HtmlTrackElement}s. + */ +var HtmlTrackElementList = /*#__PURE__*/function () { + /** + * Create an instance of this class. + * + * @param {HtmlTrackElement[]} [tracks=[]] + * A list of `HtmlTrackElement` to instantiate the list with. + */ + function HtmlTrackElementList(trackElements) { + if (trackElements === void 0) { + trackElements = []; + } + + this.trackElements_ = []; + /** + * @memberof HtmlTrackElementList + * @member {number} length + * The current number of `Track`s in the this Trackist. + * @instance + */ + + Object.defineProperty(this, 'length', { + get: function get() { + return this.trackElements_.length; + } + }); + + for (var i = 0, length = trackElements.length; i < length; i++) { + this.addTrackElement_(trackElements[i]); + } + } + /** + * Add an {@link HtmlTrackElement} to the `HtmlTrackElementList` + * + * @param {HtmlTrackElement} trackElement + * The track element to add to the list. + * + * @private + */ + + + var _proto = HtmlTrackElementList.prototype; + + _proto.addTrackElement_ = function addTrackElement_(trackElement) { + var index = this.trackElements_.length; + + if (!('' + index in this)) { + Object.defineProperty(this, index, { + get: function get() { + return this.trackElements_[index]; + } + }); + } // Do not add duplicate elements + + + if (this.trackElements_.indexOf(trackElement) === -1) { + this.trackElements_.push(trackElement); + } + } + /** + * Get an {@link HtmlTrackElement} from the `HtmlTrackElementList` given an + * {@link TextTrack}. + * + * @param {TextTrack} track + * The track associated with a track element. + * + * @return {HtmlTrackElement|undefined} + * The track element that was found or undefined. + * + * @private + */ + ; + + _proto.getTrackElementByTrack_ = function getTrackElementByTrack_(track) { + var trackElement_; + + for (var i = 0, length = this.trackElements_.length; i < length; i++) { + if (track === this.trackElements_[i].track) { + trackElement_ = this.trackElements_[i]; + break; + } + } + + return trackElement_; + } + /** + * Remove a {@link HtmlTrackElement} from the `HtmlTrackElementList` + * + * @param {HtmlTrackElement} trackElement + * The track element to remove from the list. + * + * @private + */ + ; + + _proto.removeTrackElement_ = function removeTrackElement_(trackElement) { + for (var i = 0, length = this.trackElements_.length; i < length; i++) { + if (trackElement === this.trackElements_[i]) { + if (this.trackElements_[i].track && typeof this.trackElements_[i].track.off === 'function') { + this.trackElements_[i].track.off(); + } + + if (typeof this.trackElements_[i].off === 'function') { + this.trackElements_[i].off(); + } + + this.trackElements_.splice(i, 1); + break; + } + } + }; + + return HtmlTrackElementList; +}(); + +/** + * @file text-track-cue-list.js + */ + +/** + * @typedef {Object} TextTrackCueList~TextTrackCue + * + * @property {string} id + * The unique id for this text track cue + * + * @property {number} startTime + * The start time for this text track cue + * + * @property {number} endTime + * The end time for this text track cue + * + * @property {boolean} pauseOnExit + * Pause when the end time is reached if true. + * + * @see [Spec]{@link https://html.spec.whatwg.org/multipage/embedded-content.html#texttrackcue} + */ + +/** + * A List of TextTrackCues. + * + * @see [Spec]{@link https://html.spec.whatwg.org/multipage/embedded-content.html#texttrackcuelist} + */ +var TextTrackCueList = /*#__PURE__*/function () { + /** + * Create an instance of this class.. + * + * @param {Array} cues + * A list of cues to be initialized with + */ + function TextTrackCueList(cues) { + TextTrackCueList.prototype.setCues_.call(this, cues); + /** + * @memberof TextTrackCueList + * @member {number} length + * The current number of `TextTrackCue`s in the TextTrackCueList. + * @instance + */ + + Object.defineProperty(this, 'length', { + get: function get() { + return this.length_; + } + }); + } + /** + * A setter for cues in this list. Creates getters + * an an index for the cues. + * + * @param {Array} cues + * An array of cues to set + * + * @private + */ + + + var _proto = TextTrackCueList.prototype; + + _proto.setCues_ = function setCues_(cues) { + var oldLength = this.length || 0; + var i = 0; + var l = cues.length; + this.cues_ = cues; + this.length_ = cues.length; + + var defineProp = function defineProp(index) { + if (!('' + index in this)) { + Object.defineProperty(this, '' + index, { + get: function get() { + return this.cues_[index]; + } + }); + } + }; + + if (oldLength < l) { + i = oldLength; + + for (; i < l; i++) { + defineProp.call(this, i); + } + } + } + /** + * Get a `TextTrackCue` that is currently in the `TextTrackCueList` by id. + * + * @param {string} id + * The id of the cue that should be searched for. + * + * @return {TextTrackCueList~TextTrackCue|null} + * A single cue or null if none was found. + */ + ; + + _proto.getCueById = function getCueById(id) { + var result = null; + + for (var i = 0, l = this.length; i < l; i++) { + var cue = this[i]; + + if (cue.id === id) { + result = cue; + break; + } + } + + return result; + }; + + return TextTrackCueList; +}(); + +/** + * @file track-kinds.js + */ + +/** + * All possible `VideoTrackKind`s + * + * @see https://html.spec.whatwg.org/multipage/embedded-content.html#dom-videotrack-kind + * @typedef VideoTrack~Kind + * @enum + */ +var VideoTrackKind = { + alternative: 'alternative', + captions: 'captions', + main: 'main', + sign: 'sign', + subtitles: 'subtitles', + commentary: 'commentary' +}; +/** + * All possible `AudioTrackKind`s + * + * @see https://html.spec.whatwg.org/multipage/embedded-content.html#dom-audiotrack-kind + * @typedef AudioTrack~Kind + * @enum + */ + +var AudioTrackKind = { + 'alternative': 'alternative', + 'descriptions': 'descriptions', + 'main': 'main', + 'main-desc': 'main-desc', + 'translation': 'translation', + 'commentary': 'commentary' +}; +/** + * All possible `TextTrackKind`s + * + * @see https://html.spec.whatwg.org/multipage/embedded-content.html#dom-texttrack-kind + * @typedef TextTrack~Kind + * @enum + */ + +var TextTrackKind = { + subtitles: 'subtitles', + captions: 'captions', + descriptions: 'descriptions', + chapters: 'chapters', + metadata: 'metadata' +}; +/** + * All possible `TextTrackMode`s + * + * @see https://html.spec.whatwg.org/multipage/embedded-content.html#texttrackmode + * @typedef TextTrack~Mode + * @enum + */ + +var TextTrackMode = { + disabled: 'disabled', + hidden: 'hidden', + showing: 'showing' +}; + +/** + * A Track class that contains all of the common functionality for {@link AudioTrack}, + * {@link VideoTrack}, and {@link TextTrack}. + * + * > Note: This class should not be used directly + * + * @see {@link https://html.spec.whatwg.org/multipage/embedded-content.html} + * @extends EventTarget + * @abstract + */ + +var Track = /*#__PURE__*/function (_EventTarget) { + _inheritsLoose__default['default'](Track, _EventTarget); + + /** + * Create an instance of this class. + * + * @param {Object} [options={}] + * Object of option names and values + * + * @param {string} [options.kind=''] + * A valid kind for the track type you are creating. + * + * @param {string} [options.id='vjs_track_' + Guid.newGUID()] + * A unique id for this AudioTrack. + * + * @param {string} [options.label=''] + * The menu label for this track. + * + * @param {string} [options.language=''] + * A valid two character language code. + * + * @abstract + */ + function Track(options) { + var _this; + + if (options === void 0) { + options = {}; + } + + _this = _EventTarget.call(this) || this; + var trackProps = { + id: options.id || 'vjs_track_' + newGUID(), + kind: options.kind || '', + language: options.language || '' + }; + var label = options.label || ''; + /** + * @memberof Track + * @member {string} id + * The id of this track. Cannot be changed after creation. + * @instance + * + * @readonly + */ + + /** + * @memberof Track + * @member {string} kind + * The kind of track that this is. Cannot be changed after creation. + * @instance + * + * @readonly + */ + + /** + * @memberof Track + * @member {string} language + * The two letter language code for this track. Cannot be changed after + * creation. + * @instance + * + * @readonly + */ + + var _loop = function _loop(key) { + Object.defineProperty(_assertThisInitialized__default['default'](_this), key, { + get: function get() { + return trackProps[key]; + }, + set: function set() {} + }); + }; + + for (var key in trackProps) { + _loop(key); + } + /** + * @memberof Track + * @member {string} label + * The label of this track. Cannot be changed after creation. + * @instance + * + * @fires Track#labelchange + */ + + + Object.defineProperty(_assertThisInitialized__default['default'](_this), 'label', { + get: function get() { + return label; + }, + set: function set(newLabel) { + if (newLabel !== label) { + label = newLabel; + /** + * An event that fires when label changes on this track. + * + * > Note: This is not part of the spec! + * + * @event Track#labelchange + * @type {EventTarget~Event} + */ + + this.trigger('labelchange'); + } + } + }); + return _this; + } + + return Track; +}(EventTarget); + +/** + * @file url.js + * @module url + */ +/** + * @typedef {Object} url:URLObject + * + * @property {string} protocol + * The protocol of the url that was parsed. + * + * @property {string} hostname + * The hostname of the url that was parsed. + * + * @property {string} port + * The port of the url that was parsed. + * + * @property {string} pathname + * The pathname of the url that was parsed. + * + * @property {string} search + * The search query of the url that was parsed. + * + * @property {string} hash + * The hash of the url that was parsed. + * + * @property {string} host + * The host of the url that was parsed. + */ + +/** + * Resolve and parse the elements of a URL. + * + * @function + * @param {String} url + * The url to parse + * + * @return {url:URLObject} + * An object of url details + */ + +var parseUrl = function parseUrl(url) { + var props = ['protocol', 'hostname', 'port', 'pathname', 'search', 'hash', 'host']; // add the url to an anchor and let the browser parse the URL + + var a = document__default['default'].createElement('a'); + a.href = url; // IE8 (and 9?) Fix + // ie8 doesn't parse the URL correctly until the anchor is actually + // added to the body, and an innerHTML is needed to trigger the parsing + + var addToBody = a.host === '' && a.protocol !== 'file:'; + var div; + + if (addToBody) { + div = document__default['default'].createElement('div'); + div.innerHTML = ""; + a = div.firstChild; // prevent the div from affecting layout + + div.setAttribute('style', 'display:none; position:absolute;'); + document__default['default'].body.appendChild(div); + } // Copy the specific URL properties to a new object + // This is also needed for IE8 because the anchor loses its + // properties when it's removed from the dom + + + var details = {}; + + for (var i = 0; i < props.length; i++) { + details[props[i]] = a[props[i]]; + } // IE9 adds the port to the host property unlike everyone else. If + // a port identifier is added for standard ports, strip it. + + + if (details.protocol === 'http:') { + details.host = details.host.replace(/:80$/, ''); + } + + if (details.protocol === 'https:') { + details.host = details.host.replace(/:443$/, ''); + } + + if (!details.protocol) { + details.protocol = window__default['default'].location.protocol; + } + + if (addToBody) { + document__default['default'].body.removeChild(div); + } + + return details; +}; +/** + * Get absolute version of relative URL. Used to tell Flash the correct URL. + * + * @function + * @param {string} url + * URL to make absolute + * + * @return {string} + * Absolute URL + * + * @see http://stackoverflow.com/questions/470832/getting-an-absolute-url-from-a-relative-one-ie6-issue + */ + +var getAbsoluteURL = function getAbsoluteURL(url) { + // Check if absolute URL + if (!url.match(/^https?:\/\//)) { + // Convert to absolute URL. Flash hosted off-site needs an absolute URL. + var div = document__default['default'].createElement('div'); + div.innerHTML = "x"; + url = div.firstChild.href; + } + + return url; +}; +/** + * Returns the extension of the passed file name. It will return an empty string + * if passed an invalid path. + * + * @function + * @param {string} path + * The fileName path like '/path/to/file.mp4' + * + * @return {string} + * The extension in lower case or an empty string if no + * extension could be found. + */ + +var getFileExtension = function getFileExtension(path) { + if (typeof path === 'string') { + var splitPathRe = /^(\/?)([\s\S]*?)((?:\.{1,2}|[^\/]+?)(\.([^\.\/\?]+)))(?:[\/]*|[\?].*)$/; + var pathParts = splitPathRe.exec(path); + + if (pathParts) { + return pathParts.pop().toLowerCase(); + } + } + + return ''; +}; +/** + * Returns whether the url passed is a cross domain request or not. + * + * @function + * @param {string} url + * The url to check. + * + * @param {Object} [winLoc] + * the domain to check the url against, defaults to window.location + * + * @param {string} [winLoc.protocol] + * The window location protocol defaults to window.location.protocol + * + * @param {string} [winLoc.host] + * The window location host defaults to window.location.host + * + * @return {boolean} + * Whether it is a cross domain request or not. + */ + +var isCrossOrigin = function isCrossOrigin(url, winLoc) { + if (winLoc === void 0) { + winLoc = window__default['default'].location; + } + + var urlInfo = parseUrl(url); // IE8 protocol relative urls will return ':' for protocol + + var srcProtocol = urlInfo.protocol === ':' ? winLoc.protocol : urlInfo.protocol; // Check if url is for another domain/origin + // IE8 doesn't know location.origin, so we won't rely on it here + + var crossOrigin = srcProtocol + urlInfo.host !== winLoc.protocol + winLoc.host; + return crossOrigin; +}; + +var Url = /*#__PURE__*/Object.freeze({ + __proto__: null, + parseUrl: parseUrl, + getAbsoluteURL: getAbsoluteURL, + getFileExtension: getFileExtension, + isCrossOrigin: isCrossOrigin +}); + +/** + * Takes a webvtt file contents and parses it into cues + * + * @param {string} srcContent + * webVTT file contents + * + * @param {TextTrack} track + * TextTrack to add cues to. Cues come from the srcContent. + * + * @private + */ + +var parseCues = function parseCues(srcContent, track) { + var parser = new window__default['default'].WebVTT.Parser(window__default['default'], window__default['default'].vttjs, window__default['default'].WebVTT.StringDecoder()); + var errors = []; + + parser.oncue = function (cue) { + track.addCue(cue); + }; + + parser.onparsingerror = function (error) { + errors.push(error); + }; + + parser.onflush = function () { + track.trigger({ + type: 'loadeddata', + target: track + }); + }; + + parser.parse(srcContent); + + if (errors.length > 0) { + if (window__default['default'].console && window__default['default'].console.groupCollapsed) { + window__default['default'].console.groupCollapsed("Text Track parsing errors for " + track.src); + } + + errors.forEach(function (error) { + return log.error(error); + }); + + if (window__default['default'].console && window__default['default'].console.groupEnd) { + window__default['default'].console.groupEnd(); + } + } + + parser.flush(); +}; +/** + * Load a `TextTrack` from a specified url. + * + * @param {string} src + * Url to load track from. + * + * @param {TextTrack} track + * Track to add cues to. Comes from the content at the end of `url`. + * + * @private + */ + + +var loadTrack = function loadTrack(src, track) { + var opts = { + uri: src + }; + var crossOrigin = isCrossOrigin(src); + + if (crossOrigin) { + opts.cors = crossOrigin; + } + + var withCredentials = track.tech_.crossOrigin() === 'use-credentials'; + + if (withCredentials) { + opts.withCredentials = withCredentials; + } + + XHR__default['default'](opts, bind(this, function (err, response, responseBody) { + if (err) { + return log.error(err, response); + } + + track.loaded_ = true; // Make sure that vttjs has loaded, otherwise, wait till it finished loading + // NOTE: this is only used for the alt/video.novtt.js build + + if (typeof window__default['default'].WebVTT !== 'function') { + if (track.tech_) { + // to prevent use before define eslint error, we define loadHandler + // as a let here + track.tech_.any(['vttjsloaded', 'vttjserror'], function (event) { + if (event.type === 'vttjserror') { + log.error("vttjs failed to load, stopping trying to process " + track.src); + return; + } + + return parseCues(responseBody, track); + }); + } + } else { + parseCues(responseBody, track); + } + })); +}; +/** + * A representation of a single `TextTrack`. + * + * @see [Spec]{@link https://html.spec.whatwg.org/multipage/embedded-content.html#texttrack} + * @extends Track + */ + + +var TextTrack = /*#__PURE__*/function (_Track) { + _inheritsLoose__default['default'](TextTrack, _Track); + + /** + * Create an instance of this class. + * + * @param {Object} options={} + * Object of option names and values + * + * @param {Tech} options.tech + * A reference to the tech that owns this TextTrack. + * + * @param {TextTrack~Kind} [options.kind='subtitles'] + * A valid text track kind. + * + * @param {TextTrack~Mode} [options.mode='disabled'] + * A valid text track mode. + * + * @param {string} [options.id='vjs_track_' + Guid.newGUID()] + * A unique id for this TextTrack. + * + * @param {string} [options.label=''] + * The menu label for this track. + * + * @param {string} [options.language=''] + * A valid two character language code. + * + * @param {string} [options.srclang=''] + * A valid two character language code. An alternative, but deprioritized + * version of `options.language` + * + * @param {string} [options.src] + * A url to TextTrack cues. + * + * @param {boolean} [options.default] + * If this track should default to on or off. + */ + function TextTrack(options) { + var _this; + + if (options === void 0) { + options = {}; + } + + if (!options.tech) { + throw new Error('A tech was not provided.'); + } + + var settings = mergeOptions(options, { + kind: TextTrackKind[options.kind] || 'subtitles', + language: options.language || options.srclang || '' + }); + var mode = TextTrackMode[settings.mode] || 'disabled'; + var default_ = settings["default"]; + + if (settings.kind === 'metadata' || settings.kind === 'chapters') { + mode = 'hidden'; + } + + _this = _Track.call(this, settings) || this; + _this.tech_ = settings.tech; + _this.cues_ = []; + _this.activeCues_ = []; + _this.preload_ = _this.tech_.preloadTextTracks !== false; + var cues = new TextTrackCueList(_this.cues_); + var activeCues = new TextTrackCueList(_this.activeCues_); + var changed = false; + var timeupdateHandler = bind(_assertThisInitialized__default['default'](_this), function () { + if (!this.tech_.isReady_ || this.tech_.isDisposed()) { + return; + } // Accessing this.activeCues for the side-effects of updating itself + // due to its nature as a getter function. Do not remove or cues will + // stop updating! + // Use the setter to prevent deletion from uglify (pure_getters rule) + + + this.activeCues = this.activeCues; + + if (changed) { + this.trigger('cuechange'); + changed = false; + } + }); + + var disposeHandler = function disposeHandler() { + _this.tech_.off('timeupdate', timeupdateHandler); + }; + + _this.tech_.one('dispose', disposeHandler); + + if (mode !== 'disabled') { + _this.tech_.on('timeupdate', timeupdateHandler); + } + + Object.defineProperties(_assertThisInitialized__default['default'](_this), { + /** + * @memberof TextTrack + * @member {boolean} default + * If this track was set to be on or off by default. Cannot be changed after + * creation. + * @instance + * + * @readonly + */ + "default": { + get: function get() { + return default_; + }, + set: function set() {} + }, + + /** + * @memberof TextTrack + * @member {string} mode + * Set the mode of this TextTrack to a valid {@link TextTrack~Mode}. Will + * not be set if setting to an invalid mode. + * @instance + * + * @fires TextTrack#modechange + */ + mode: { + get: function get() { + return mode; + }, + set: function set(newMode) { + if (!TextTrackMode[newMode]) { + return; + } + + if (mode === newMode) { + return; + } + + mode = newMode; + + if (!this.preload_ && mode !== 'disabled' && this.cues.length === 0) { + // On-demand load. + loadTrack(this.src, this); + } + + this.tech_.off('timeupdate', timeupdateHandler); + + if (mode !== 'disabled') { + this.tech_.on('timeupdate', timeupdateHandler); + } + /** + * An event that fires when mode changes on this track. This allows + * the TextTrackList that holds this track to act accordingly. + * + * > Note: This is not part of the spec! + * + * @event TextTrack#modechange + * @type {EventTarget~Event} + */ + + + this.trigger('modechange'); + } + }, + + /** + * @memberof TextTrack + * @member {TextTrackCueList} cues + * The text track cue list for this TextTrack. + * @instance + */ + cues: { + get: function get() { + if (!this.loaded_) { + return null; + } + + return cues; + }, + set: function set() {} + }, + + /** + * @memberof TextTrack + * @member {TextTrackCueList} activeCues + * The list text track cues that are currently active for this TextTrack. + * @instance + */ + activeCues: { + get: function get() { + if (!this.loaded_) { + return null; + } // nothing to do + + + if (this.cues.length === 0) { + return activeCues; + } + + var ct = this.tech_.currentTime(); + var active = []; + + for (var i = 0, l = this.cues.length; i < l; i++) { + var cue = this.cues[i]; + + if (cue.startTime <= ct && cue.endTime >= ct) { + active.push(cue); + } else if (cue.startTime === cue.endTime && cue.startTime <= ct && cue.startTime + 0.5 >= ct) { + active.push(cue); + } + } + + changed = false; + + if (active.length !== this.activeCues_.length) { + changed = true; + } else { + for (var _i = 0; _i < active.length; _i++) { + if (this.activeCues_.indexOf(active[_i]) === -1) { + changed = true; + } + } + } + + this.activeCues_ = active; + activeCues.setCues_(this.activeCues_); + return activeCues; + }, + // /!\ Keep this setter empty (see the timeupdate handler above) + set: function set() {} + } + }); + + if (settings.src) { + _this.src = settings.src; + + if (!_this.preload_) { + // Tracks will load on-demand. + // Act like we're loaded for other purposes. + _this.loaded_ = true; + } + + if (_this.preload_ || settings.kind !== 'subtitles' && settings.kind !== 'captions') { + loadTrack(_this.src, _assertThisInitialized__default['default'](_this)); + } + } else { + _this.loaded_ = true; + } + + return _this; + } + /** + * Add a cue to the internal list of cues. + * + * @param {TextTrack~Cue} cue + * The cue to add to our internal list + */ + + + var _proto = TextTrack.prototype; + + _proto.addCue = function addCue(originalCue) { + var cue = originalCue; + + if (window__default['default'].vttjs && !(originalCue instanceof window__default['default'].vttjs.VTTCue)) { + cue = new window__default['default'].vttjs.VTTCue(originalCue.startTime, originalCue.endTime, originalCue.text); + + for (var prop in originalCue) { + if (!(prop in cue)) { + cue[prop] = originalCue[prop]; + } + } // make sure that `id` is copied over + + + cue.id = originalCue.id; + cue.originalCue_ = originalCue; + } + + var tracks = this.tech_.textTracks(); + + for (var i = 0; i < tracks.length; i++) { + if (tracks[i] !== this) { + tracks[i].removeCue(cue); + } + } + + this.cues_.push(cue); + this.cues.setCues_(this.cues_); + } + /** + * Remove a cue from our internal list + * + * @param {TextTrack~Cue} removeCue + * The cue to remove from our internal list + */ + ; + + _proto.removeCue = function removeCue(_removeCue) { + var i = this.cues_.length; + + while (i--) { + var cue = this.cues_[i]; + + if (cue === _removeCue || cue.originalCue_ && cue.originalCue_ === _removeCue) { + this.cues_.splice(i, 1); + this.cues.setCues_(this.cues_); + break; + } + } + }; + + return TextTrack; +}(Track); +/** + * cuechange - One or more cues in the track have become active or stopped being active. + */ + + +TextTrack.prototype.allowedEvents_ = { + cuechange: 'cuechange' +}; + +/** + * A representation of a single `AudioTrack`. If it is part of an {@link AudioTrackList} + * only one `AudioTrack` in the list will be enabled at a time. + * + * @see [Spec]{@link https://html.spec.whatwg.org/multipage/embedded-content.html#audiotrack} + * @extends Track + */ + +var AudioTrack = /*#__PURE__*/function (_Track) { + _inheritsLoose__default['default'](AudioTrack, _Track); + + /** + * Create an instance of this class. + * + * @param {Object} [options={}] + * Object of option names and values + * + * @param {AudioTrack~Kind} [options.kind=''] + * A valid audio track kind + * + * @param {string} [options.id='vjs_track_' + Guid.newGUID()] + * A unique id for this AudioTrack. + * + * @param {string} [options.label=''] + * The menu label for this track. + * + * @param {string} [options.language=''] + * A valid two character language code. + * + * @param {boolean} [options.enabled] + * If this track is the one that is currently playing. If this track is part of + * an {@link AudioTrackList}, only one {@link AudioTrack} will be enabled. + */ + function AudioTrack(options) { + var _this; + + if (options === void 0) { + options = {}; + } + + var settings = mergeOptions(options, { + kind: AudioTrackKind[options.kind] || '' + }); + _this = _Track.call(this, settings) || this; + var enabled = false; + /** + * @memberof AudioTrack + * @member {boolean} enabled + * If this `AudioTrack` is enabled or not. When setting this will + * fire {@link AudioTrack#enabledchange} if the state of enabled is changed. + * @instance + * + * @fires VideoTrack#selectedchange + */ + + Object.defineProperty(_assertThisInitialized__default['default'](_this), 'enabled', { + get: function get() { + return enabled; + }, + set: function set(newEnabled) { + // an invalid or unchanged value + if (typeof newEnabled !== 'boolean' || newEnabled === enabled) { + return; + } + + enabled = newEnabled; + /** + * An event that fires when enabled changes on this track. This allows + * the AudioTrackList that holds this track to act accordingly. + * + * > Note: This is not part of the spec! Native tracks will do + * this internally without an event. + * + * @event AudioTrack#enabledchange + * @type {EventTarget~Event} + */ + + this.trigger('enabledchange'); + } + }); // if the user sets this track to selected then + // set selected to that true value otherwise + // we keep it false + + if (settings.enabled) { + _this.enabled = settings.enabled; + } + + _this.loaded_ = true; + return _this; + } + + return AudioTrack; +}(Track); + +/** + * A representation of a single `VideoTrack`. + * + * @see [Spec]{@link https://html.spec.whatwg.org/multipage/embedded-content.html#videotrack} + * @extends Track + */ + +var VideoTrack = /*#__PURE__*/function (_Track) { + _inheritsLoose__default['default'](VideoTrack, _Track); + + /** + * Create an instance of this class. + * + * @param {Object} [options={}] + * Object of option names and values + * + * @param {string} [options.kind=''] + * A valid {@link VideoTrack~Kind} + * + * @param {string} [options.id='vjs_track_' + Guid.newGUID()] + * A unique id for this AudioTrack. + * + * @param {string} [options.label=''] + * The menu label for this track. + * + * @param {string} [options.language=''] + * A valid two character language code. + * + * @param {boolean} [options.selected] + * If this track is the one that is currently playing. + */ + function VideoTrack(options) { + var _this; + + if (options === void 0) { + options = {}; + } + + var settings = mergeOptions(options, { + kind: VideoTrackKind[options.kind] || '' + }); + _this = _Track.call(this, settings) || this; + var selected = false; + /** + * @memberof VideoTrack + * @member {boolean} selected + * If this `VideoTrack` is selected or not. When setting this will + * fire {@link VideoTrack#selectedchange} if the state of selected changed. + * @instance + * + * @fires VideoTrack#selectedchange + */ + + Object.defineProperty(_assertThisInitialized__default['default'](_this), 'selected', { + get: function get() { + return selected; + }, + set: function set(newSelected) { + // an invalid or unchanged value + if (typeof newSelected !== 'boolean' || newSelected === selected) { + return; + } + + selected = newSelected; + /** + * An event that fires when selected changes on this track. This allows + * the VideoTrackList that holds this track to act accordingly. + * + * > Note: This is not part of the spec! Native tracks will do + * this internally without an event. + * + * @event VideoTrack#selectedchange + * @type {EventTarget~Event} + */ + + this.trigger('selectedchange'); + } + }); // if the user sets this track to selected then + // set selected to that true value otherwise + // we keep it false + + if (settings.selected) { + _this.selected = settings.selected; + } + + return _this; + } + + return VideoTrack; +}(Track); + +/** + * @memberof HTMLTrackElement + * @typedef {HTMLTrackElement~ReadyState} + * @enum {number} + */ + +var NONE = 0; +var LOADING = 1; +var LOADED = 2; +var ERROR = 3; +/** + * A single track represented in the DOM. + * + * @see [Spec]{@link https://html.spec.whatwg.org/multipage/embedded-content.html#htmltrackelement} + * @extends EventTarget + */ + +var HTMLTrackElement = /*#__PURE__*/function (_EventTarget) { + _inheritsLoose__default['default'](HTMLTrackElement, _EventTarget); + + /** + * Create an instance of this class. + * + * @param {Object} options={} + * Object of option names and values + * + * @param {Tech} options.tech + * A reference to the tech that owns this HTMLTrackElement. + * + * @param {TextTrack~Kind} [options.kind='subtitles'] + * A valid text track kind. + * + * @param {TextTrack~Mode} [options.mode='disabled'] + * A valid text track mode. + * + * @param {string} [options.id='vjs_track_' + Guid.newGUID()] + * A unique id for this TextTrack. + * + * @param {string} [options.label=''] + * The menu label for this track. + * + * @param {string} [options.language=''] + * A valid two character language code. + * + * @param {string} [options.srclang=''] + * A valid two character language code. An alternative, but deprioritized + * vesion of `options.language` + * + * @param {string} [options.src] + * A url to TextTrack cues. + * + * @param {boolean} [options.default] + * If this track should default to on or off. + */ + function HTMLTrackElement(options) { + var _this; + + if (options === void 0) { + options = {}; + } + + _this = _EventTarget.call(this) || this; + var readyState; + var track = new TextTrack(options); + _this.kind = track.kind; + _this.src = track.src; + _this.srclang = track.language; + _this.label = track.label; + _this["default"] = track["default"]; + Object.defineProperties(_assertThisInitialized__default['default'](_this), { + /** + * @memberof HTMLTrackElement + * @member {HTMLTrackElement~ReadyState} readyState + * The current ready state of the track element. + * @instance + */ + readyState: { + get: function get() { + return readyState; + } + }, + + /** + * @memberof HTMLTrackElement + * @member {TextTrack} track + * The underlying TextTrack object. + * @instance + * + */ + track: { + get: function get() { + return track; + } + } + }); + readyState = NONE; + /** + * @listens TextTrack#loadeddata + * @fires HTMLTrackElement#load + */ + + track.addEventListener('loadeddata', function () { + readyState = LOADED; + + _this.trigger({ + type: 'load', + target: _assertThisInitialized__default['default'](_this) + }); + }); + return _this; + } + + return HTMLTrackElement; +}(EventTarget); + +HTMLTrackElement.prototype.allowedEvents_ = { + load: 'load' +}; +HTMLTrackElement.NONE = NONE; +HTMLTrackElement.LOADING = LOADING; +HTMLTrackElement.LOADED = LOADED; +HTMLTrackElement.ERROR = ERROR; + +/* + * This file contains all track properties that are used in + * player.js, tech.js, html5.js and possibly other techs in the future. + */ + +var NORMAL = { + audio: { + ListClass: AudioTrackList, + TrackClass: AudioTrack, + capitalName: 'Audio' + }, + video: { + ListClass: VideoTrackList, + TrackClass: VideoTrack, + capitalName: 'Video' + }, + text: { + ListClass: TextTrackList, + TrackClass: TextTrack, + capitalName: 'Text' + } +}; +Object.keys(NORMAL).forEach(function (type) { + NORMAL[type].getterName = type + "Tracks"; + NORMAL[type].privateName = type + "Tracks_"; +}); +var REMOTE = { + remoteText: { + ListClass: TextTrackList, + TrackClass: TextTrack, + capitalName: 'RemoteText', + getterName: 'remoteTextTracks', + privateName: 'remoteTextTracks_' + }, + remoteTextEl: { + ListClass: HtmlTrackElementList, + TrackClass: HTMLTrackElement, + capitalName: 'RemoteTextTrackEls', + getterName: 'remoteTextTrackEls', + privateName: 'remoteTextTrackEls_' + } +}; + +var ALL = _extends__default['default']({}, NORMAL, REMOTE); + +REMOTE.names = Object.keys(REMOTE); +NORMAL.names = Object.keys(NORMAL); +ALL.names = [].concat(REMOTE.names).concat(NORMAL.names); + +/** + * An Object containing a structure like: `{src: 'url', type: 'mimetype'}` or string + * that just contains the src url alone. + * * `var SourceObject = {src: 'http://ex.com/video.mp4', type: 'video/mp4'};` + * `var SourceString = 'http://example.com/some-video.mp4';` + * + * @typedef {Object|string} Tech~SourceObject + * + * @property {string} src + * The url to the source + * + * @property {string} type + * The mime type of the source + */ + +/** + * A function used by {@link Tech} to create a new {@link TextTrack}. + * + * @private + * + * @param {Tech} self + * An instance of the Tech class. + * + * @param {string} kind + * `TextTrack` kind (subtitles, captions, descriptions, chapters, or metadata) + * + * @param {string} [label] + * Label to identify the text track + * + * @param {string} [language] + * Two letter language abbreviation + * + * @param {Object} [options={}] + * An object with additional text track options + * + * @return {TextTrack} + * The text track that was created. + */ + +function createTrackHelper(self, kind, label, language, options) { + if (options === void 0) { + options = {}; + } + + var tracks = self.textTracks(); + options.kind = kind; + + if (label) { + options.label = label; + } + + if (language) { + options.language = language; + } + + options.tech = self; + var track = new ALL.text.TrackClass(options); + tracks.addTrack(track); + return track; +} +/** + * This is the base class for media playback technology controllers, such as + * {@link HTML5} + * + * @extends Component + */ + + +var Tech = /*#__PURE__*/function (_Component) { + _inheritsLoose__default['default'](Tech, _Component); + + /** + * Create an instance of this Tech. + * + * @param {Object} [options] + * The key/value store of player options. + * + * @param {Component~ReadyCallback} ready + * Callback function to call when the `HTML5` Tech is ready. + */ + function Tech(options, ready) { + var _this; + + if (options === void 0) { + options = {}; + } + + if (ready === void 0) { + ready = function ready() {}; + } + + // we don't want the tech to report user activity automatically. + // This is done manually in addControlsListeners + options.reportTouchActivity = false; + _this = _Component.call(this, null, options, ready) || this; + + _this.onDurationChange_ = function (e) { + return _this.onDurationChange(e); + }; + + _this.trackProgress_ = function (e) { + return _this.trackProgress(e); + }; + + _this.trackCurrentTime_ = function (e) { + return _this.trackCurrentTime(e); + }; + + _this.stopTrackingCurrentTime_ = function (e) { + return _this.stopTrackingCurrentTime(e); + }; + + _this.disposeSourceHandler_ = function (e) { + return _this.disposeSourceHandler(e); + }; // keep track of whether the current source has played at all to + // implement a very limited played() + + + _this.hasStarted_ = false; + + _this.on('playing', function () { + this.hasStarted_ = true; + }); + + _this.on('loadstart', function () { + this.hasStarted_ = false; + }); + + ALL.names.forEach(function (name) { + var props = ALL[name]; + + if (options && options[props.getterName]) { + _this[props.privateName] = options[props.getterName]; + } + }); // Manually track progress in cases where the browser/tech doesn't report it. + + if (!_this.featuresProgressEvents) { + _this.manualProgressOn(); + } // Manually track timeupdates in cases where the browser/tech doesn't report it. + + + if (!_this.featuresTimeupdateEvents) { + _this.manualTimeUpdatesOn(); + } + + ['Text', 'Audio', 'Video'].forEach(function (track) { + if (options["native" + track + "Tracks"] === false) { + _this["featuresNative" + track + "Tracks"] = false; + } + }); + + if (options.nativeCaptions === false || options.nativeTextTracks === false) { + _this.featuresNativeTextTracks = false; + } else if (options.nativeCaptions === true || options.nativeTextTracks === true) { + _this.featuresNativeTextTracks = true; + } + + if (!_this.featuresNativeTextTracks) { + _this.emulateTextTracks(); + } + + _this.preloadTextTracks = options.preloadTextTracks !== false; + _this.autoRemoteTextTracks_ = new ALL.text.ListClass(); + + _this.initTrackListeners(); // Turn on component tap events only if not using native controls + + + if (!options.nativeControlsForTouch) { + _this.emitTapEvents(); + } + + if (_this.constructor) { + _this.name_ = _this.constructor.name || 'Unknown Tech'; + } + + return _this; + } + /** + * A special function to trigger source set in a way that will allow player + * to re-trigger if the player or tech are not ready yet. + * + * @fires Tech#sourceset + * @param {string} src The source string at the time of the source changing. + */ + + + var _proto = Tech.prototype; + + _proto.triggerSourceset = function triggerSourceset(src) { + var _this2 = this; + + if (!this.isReady_) { + // on initial ready we have to trigger source set + // 1ms after ready so that player can watch for it. + this.one('ready', function () { + return _this2.setTimeout(function () { + return _this2.triggerSourceset(src); + }, 1); + }); + } + /** + * Fired when the source is set on the tech causing the media element + * to reload. + * + * @see {@link Player#event:sourceset} + * @event Tech#sourceset + * @type {EventTarget~Event} + */ + + + this.trigger({ + src: src, + type: 'sourceset' + }); + } + /* Fallbacks for unsupported event types + ================================================================================ */ + + /** + * Polyfill the `progress` event for browsers that don't support it natively. + * + * @see {@link Tech#trackProgress} + */ + ; + + _proto.manualProgressOn = function manualProgressOn() { + this.on('durationchange', this.onDurationChange_); + this.manualProgress = true; // Trigger progress watching when a source begins loading + + this.one('ready', this.trackProgress_); + } + /** + * Turn off the polyfill for `progress` events that was created in + * {@link Tech#manualProgressOn} + */ + ; + + _proto.manualProgressOff = function manualProgressOff() { + this.manualProgress = false; + this.stopTrackingProgress(); + this.off('durationchange', this.onDurationChange_); + } + /** + * This is used to trigger a `progress` event when the buffered percent changes. It + * sets an interval function that will be called every 500 milliseconds to check if the + * buffer end percent has changed. + * + * > This function is called by {@link Tech#manualProgressOn} + * + * @param {EventTarget~Event} event + * The `ready` event that caused this to run. + * + * @listens Tech#ready + * @fires Tech#progress + */ + ; + + _proto.trackProgress = function trackProgress(event) { + this.stopTrackingProgress(); + this.progressInterval = this.setInterval(bind(this, function () { + // Don't trigger unless buffered amount is greater than last time + var numBufferedPercent = this.bufferedPercent(); + + if (this.bufferedPercent_ !== numBufferedPercent) { + /** + * See {@link Player#progress} + * + * @event Tech#progress + * @type {EventTarget~Event} + */ + this.trigger('progress'); + } + + this.bufferedPercent_ = numBufferedPercent; + + if (numBufferedPercent === 1) { + this.stopTrackingProgress(); + } + }), 500); + } + /** + * Update our internal duration on a `durationchange` event by calling + * {@link Tech#duration}. + * + * @param {EventTarget~Event} event + * The `durationchange` event that caused this to run. + * + * @listens Tech#durationchange + */ + ; + + _proto.onDurationChange = function onDurationChange(event) { + this.duration_ = this.duration(); + } + /** + * Get and create a `TimeRange` object for buffering. + * + * @return {TimeRange} + * The time range object that was created. + */ + ; + + _proto.buffered = function buffered() { + return createTimeRanges(0, 0); + } + /** + * Get the percentage of the current video that is currently buffered. + * + * @return {number} + * A number from 0 to 1 that represents the decimal percentage of the + * video that is buffered. + * + */ + ; + + _proto.bufferedPercent = function bufferedPercent$1() { + return bufferedPercent(this.buffered(), this.duration_); + } + /** + * Turn off the polyfill for `progress` events that was created in + * {@link Tech#manualProgressOn} + * Stop manually tracking progress events by clearing the interval that was set in + * {@link Tech#trackProgress}. + */ + ; + + _proto.stopTrackingProgress = function stopTrackingProgress() { + this.clearInterval(this.progressInterval); + } + /** + * Polyfill the `timeupdate` event for browsers that don't support it. + * + * @see {@link Tech#trackCurrentTime} + */ + ; + + _proto.manualTimeUpdatesOn = function manualTimeUpdatesOn() { + this.manualTimeUpdates = true; + this.on('play', this.trackCurrentTime_); + this.on('pause', this.stopTrackingCurrentTime_); + } + /** + * Turn off the polyfill for `timeupdate` events that was created in + * {@link Tech#manualTimeUpdatesOn} + */ + ; + + _proto.manualTimeUpdatesOff = function manualTimeUpdatesOff() { + this.manualTimeUpdates = false; + this.stopTrackingCurrentTime(); + this.off('play', this.trackCurrentTime_); + this.off('pause', this.stopTrackingCurrentTime_); + } + /** + * Sets up an interval function to track current time and trigger `timeupdate` every + * 250 milliseconds. + * + * @listens Tech#play + * @triggers Tech#timeupdate + */ + ; + + _proto.trackCurrentTime = function trackCurrentTime() { + if (this.currentTimeInterval) { + this.stopTrackingCurrentTime(); + } + + this.currentTimeInterval = this.setInterval(function () { + /** + * Triggered at an interval of 250ms to indicated that time is passing in the video. + * + * @event Tech#timeupdate + * @type {EventTarget~Event} + */ + this.trigger({ + type: 'timeupdate', + target: this, + manuallyTriggered: true + }); // 42 = 24 fps // 250 is what Webkit uses // FF uses 15 + }, 250); + } + /** + * Stop the interval function created in {@link Tech#trackCurrentTime} so that the + * `timeupdate` event is no longer triggered. + * + * @listens {Tech#pause} + */ + ; + + _proto.stopTrackingCurrentTime = function stopTrackingCurrentTime() { + this.clearInterval(this.currentTimeInterval); // #1002 - if the video ends right before the next timeupdate would happen, + // the progress bar won't make it all the way to the end + + this.trigger({ + type: 'timeupdate', + target: this, + manuallyTriggered: true + }); + } + /** + * Turn off all event polyfills, clear the `Tech`s {@link AudioTrackList}, + * {@link VideoTrackList}, and {@link TextTrackList}, and dispose of this Tech. + * + * @fires Component#dispose + */ + ; + + _proto.dispose = function dispose() { + // clear out all tracks because we can't reuse them between techs + this.clearTracks(NORMAL.names); // Turn off any manual progress or timeupdate tracking + + if (this.manualProgress) { + this.manualProgressOff(); + } + + if (this.manualTimeUpdates) { + this.manualTimeUpdatesOff(); + } + + _Component.prototype.dispose.call(this); + } + /** + * Clear out a single `TrackList` or an array of `TrackLists` given their names. + * + * > Note: Techs without source handlers should call this between sources for `video` + * & `audio` tracks. You don't want to use them between tracks! + * + * @param {string[]|string} types + * TrackList names to clear, valid names are `video`, `audio`, and + * `text`. + */ + ; + + _proto.clearTracks = function clearTracks(types) { + var _this3 = this; + + types = [].concat(types); // clear out all tracks because we can't reuse them between techs + + types.forEach(function (type) { + var list = _this3[type + "Tracks"]() || []; + var i = list.length; + + while (i--) { + var track = list[i]; + + if (type === 'text') { + _this3.removeRemoteTextTrack(track); + } + + list.removeTrack(track); + } + }); + } + /** + * Remove any TextTracks added via addRemoteTextTrack that are + * flagged for automatic garbage collection + */ + ; + + _proto.cleanupAutoTextTracks = function cleanupAutoTextTracks() { + var list = this.autoRemoteTextTracks_ || []; + var i = list.length; + + while (i--) { + var track = list[i]; + this.removeRemoteTextTrack(track); + } + } + /** + * Reset the tech, which will removes all sources and reset the internal readyState. + * + * @abstract + */ + ; + + _proto.reset = function reset() {} + /** + * Get the value of `crossOrigin` from the tech. + * + * @abstract + * + * @see {Html5#crossOrigin} + */ + ; + + _proto.crossOrigin = function crossOrigin() {} + /** + * Set the value of `crossOrigin` on the tech. + * + * @abstract + * + * @param {string} crossOrigin the crossOrigin value + * @see {Html5#setCrossOrigin} + */ + ; + + _proto.setCrossOrigin = function setCrossOrigin() {} + /** + * Get or set an error on the Tech. + * + * @param {MediaError} [err] + * Error to set on the Tech + * + * @return {MediaError|null} + * The current error object on the tech, or null if there isn't one. + */ + ; + + _proto.error = function error(err) { + if (err !== undefined) { + this.error_ = new MediaError(err); + this.trigger('error'); + } + + return this.error_; + } + /** + * Returns the `TimeRange`s that have been played through for the current source. + * + * > NOTE: This implementation is incomplete. It does not track the played `TimeRange`. + * It only checks whether the source has played at all or not. + * + * @return {TimeRange} + * - A single time range if this video has played + * - An empty set of ranges if not. + */ + ; + + _proto.played = function played() { + if (this.hasStarted_) { + return createTimeRanges(0, 0); + } + + return createTimeRanges(); + } + /** + * Start playback + * + * @abstract + * + * @see {Html5#play} + */ + ; + + _proto.play = function play() {} + /** + * Set whether we are scrubbing or not + * + * @abstract + * + * @see {Html5#setScrubbing} + */ + ; + + _proto.setScrubbing = function setScrubbing() {} + /** + * Get whether we are scrubbing or not + * + * @abstract + * + * @see {Html5#scrubbing} + */ + ; + + _proto.scrubbing = function scrubbing() {} + /** + * Causes a manual time update to occur if {@link Tech#manualTimeUpdatesOn} was + * previously called. + * + * @fires Tech#timeupdate + */ + ; + + _proto.setCurrentTime = function setCurrentTime() { + // improve the accuracy of manual timeupdates + if (this.manualTimeUpdates) { + /** + * A manual `timeupdate` event. + * + * @event Tech#timeupdate + * @type {EventTarget~Event} + */ + this.trigger({ + type: 'timeupdate', + target: this, + manuallyTriggered: true + }); + } + } + /** + * Turn on listeners for {@link VideoTrackList}, {@link {AudioTrackList}, and + * {@link TextTrackList} events. + * + * This adds {@link EventTarget~EventListeners} for `addtrack`, and `removetrack`. + * + * @fires Tech#audiotrackchange + * @fires Tech#videotrackchange + * @fires Tech#texttrackchange + */ + ; + + _proto.initTrackListeners = function initTrackListeners() { + var _this4 = this; + + /** + * Triggered when tracks are added or removed on the Tech {@link AudioTrackList} + * + * @event Tech#audiotrackchange + * @type {EventTarget~Event} + */ + + /** + * Triggered when tracks are added or removed on the Tech {@link VideoTrackList} + * + * @event Tech#videotrackchange + * @type {EventTarget~Event} + */ + + /** + * Triggered when tracks are added or removed on the Tech {@link TextTrackList} + * + * @event Tech#texttrackchange + * @type {EventTarget~Event} + */ + NORMAL.names.forEach(function (name) { + var props = NORMAL[name]; + + var trackListChanges = function trackListChanges() { + _this4.trigger(name + "trackchange"); + }; + + var tracks = _this4[props.getterName](); + + tracks.addEventListener('removetrack', trackListChanges); + tracks.addEventListener('addtrack', trackListChanges); + + _this4.on('dispose', function () { + tracks.removeEventListener('removetrack', trackListChanges); + tracks.removeEventListener('addtrack', trackListChanges); + }); + }); + } + /** + * Emulate TextTracks using vtt.js if necessary + * + * @fires Tech#vttjsloaded + * @fires Tech#vttjserror + */ + ; + + _proto.addWebVttScript_ = function addWebVttScript_() { + var _this5 = this; + + if (window__default['default'].WebVTT) { + return; + } // Initially, Tech.el_ is a child of a dummy-div wait until the Component system + // signals that the Tech is ready at which point Tech.el_ is part of the DOM + // before inserting the WebVTT script + + + if (document__default['default'].body.contains(this.el())) { + // load via require if available and vtt.js script location was not passed in + // as an option. novtt builds will turn the above require call into an empty object + // which will cause this if check to always fail. + if (!this.options_['vtt.js'] && isPlain(vtt__default['default']) && Object.keys(vtt__default['default']).length > 0) { + this.trigger('vttjsloaded'); + return; + } // load vtt.js via the script location option or the cdn of no location was + // passed in + + + var script = document__default['default'].createElement('script'); + script.src = this.options_['vtt.js'] || 'https://vjs.zencdn.net/vttjs/0.14.1/vtt.min.js'; + + script.onload = function () { + /** + * Fired when vtt.js is loaded. + * + * @event Tech#vttjsloaded + * @type {EventTarget~Event} + */ + _this5.trigger('vttjsloaded'); + }; + + script.onerror = function () { + /** + * Fired when vtt.js was not loaded due to an error + * + * @event Tech#vttjsloaded + * @type {EventTarget~Event} + */ + _this5.trigger('vttjserror'); + }; + + this.on('dispose', function () { + script.onload = null; + script.onerror = null; + }); // but have not loaded yet and we set it to true before the inject so that + // we don't overwrite the injected window.WebVTT if it loads right away + + window__default['default'].WebVTT = true; + this.el().parentNode.appendChild(script); + } else { + this.ready(this.addWebVttScript_); + } + } + /** + * Emulate texttracks + * + */ + ; + + _proto.emulateTextTracks = function emulateTextTracks() { + var _this6 = this; + + var tracks = this.textTracks(); + var remoteTracks = this.remoteTextTracks(); + + var handleAddTrack = function handleAddTrack(e) { + return tracks.addTrack(e.track); + }; + + var handleRemoveTrack = function handleRemoveTrack(e) { + return tracks.removeTrack(e.track); + }; + + remoteTracks.on('addtrack', handleAddTrack); + remoteTracks.on('removetrack', handleRemoveTrack); + this.addWebVttScript_(); + + var updateDisplay = function updateDisplay() { + return _this6.trigger('texttrackchange'); + }; + + var textTracksChanges = function textTracksChanges() { + updateDisplay(); + + for (var i = 0; i < tracks.length; i++) { + var track = tracks[i]; + track.removeEventListener('cuechange', updateDisplay); + + if (track.mode === 'showing') { + track.addEventListener('cuechange', updateDisplay); + } + } + }; + + textTracksChanges(); + tracks.addEventListener('change', textTracksChanges); + tracks.addEventListener('addtrack', textTracksChanges); + tracks.addEventListener('removetrack', textTracksChanges); + this.on('dispose', function () { + remoteTracks.off('addtrack', handleAddTrack); + remoteTracks.off('removetrack', handleRemoveTrack); + tracks.removeEventListener('change', textTracksChanges); + tracks.removeEventListener('addtrack', textTracksChanges); + tracks.removeEventListener('removetrack', textTracksChanges); + + for (var i = 0; i < tracks.length; i++) { + var track = tracks[i]; + track.removeEventListener('cuechange', updateDisplay); + } + }); + } + /** + * Create and returns a remote {@link TextTrack} object. + * + * @param {string} kind + * `TextTrack` kind (subtitles, captions, descriptions, chapters, or metadata) + * + * @param {string} [label] + * Label to identify the text track + * + * @param {string} [language] + * Two letter language abbreviation + * + * @return {TextTrack} + * The TextTrack that gets created. + */ + ; + + _proto.addTextTrack = function addTextTrack(kind, label, language) { + if (!kind) { + throw new Error('TextTrack kind is required but was not provided'); + } + + return createTrackHelper(this, kind, label, language); + } + /** + * Create an emulated TextTrack for use by addRemoteTextTrack + * + * This is intended to be overridden by classes that inherit from + * Tech in order to create native or custom TextTracks. + * + * @param {Object} options + * The object should contain the options to initialize the TextTrack with. + * + * @param {string} [options.kind] + * `TextTrack` kind (subtitles, captions, descriptions, chapters, or metadata). + * + * @param {string} [options.label]. + * Label to identify the text track + * + * @param {string} [options.language] + * Two letter language abbreviation. + * + * @return {HTMLTrackElement} + * The track element that gets created. + */ + ; + + _proto.createRemoteTextTrack = function createRemoteTextTrack(options) { + var track = mergeOptions(options, { + tech: this + }); + return new REMOTE.remoteTextEl.TrackClass(track); + } + /** + * Creates a remote text track object and returns an html track element. + * + * > Note: This can be an emulated {@link HTMLTrackElement} or a native one. + * + * @param {Object} options + * See {@link Tech#createRemoteTextTrack} for more detailed properties. + * + * @param {boolean} [manualCleanup=true] + * - When false: the TextTrack will be automatically removed from the video + * element whenever the source changes + * - When True: The TextTrack will have to be cleaned up manually + * + * @return {HTMLTrackElement} + * An Html Track Element. + * + * @deprecated The default functionality for this function will be equivalent + * to "manualCleanup=false" in the future. The manualCleanup parameter will + * also be removed. + */ + ; + + _proto.addRemoteTextTrack = function addRemoteTextTrack(options, manualCleanup) { + var _this7 = this; + + if (options === void 0) { + options = {}; + } + + var htmlTrackElement = this.createRemoteTextTrack(options); + + if (manualCleanup !== true && manualCleanup !== false) { + // deprecation warning + log.warn('Calling addRemoteTextTrack without explicitly setting the "manualCleanup" parameter to `true` is deprecated and default to `false` in future version of video.js'); + manualCleanup = true; + } // store HTMLTrackElement and TextTrack to remote list + + + this.remoteTextTrackEls().addTrackElement_(htmlTrackElement); + this.remoteTextTracks().addTrack(htmlTrackElement.track); + + if (manualCleanup !== true) { + // create the TextTrackList if it doesn't exist + this.ready(function () { + return _this7.autoRemoteTextTracks_.addTrack(htmlTrackElement.track); + }); + } + + return htmlTrackElement; + } + /** + * Remove a remote text track from the remote `TextTrackList`. + * + * @param {TextTrack} track + * `TextTrack` to remove from the `TextTrackList` + */ + ; + + _proto.removeRemoteTextTrack = function removeRemoteTextTrack(track) { + var trackElement = this.remoteTextTrackEls().getTrackElementByTrack_(track); // remove HTMLTrackElement and TextTrack from remote list + + this.remoteTextTrackEls().removeTrackElement_(trackElement); + this.remoteTextTracks().removeTrack(track); + this.autoRemoteTextTracks_.removeTrack(track); + } + /** + * Gets available media playback quality metrics as specified by the W3C's Media + * Playback Quality API. + * + * @see [Spec]{@link https://wicg.github.io/media-playback-quality} + * + * @return {Object} + * An object with supported media playback quality metrics + * + * @abstract + */ + ; + + _proto.getVideoPlaybackQuality = function getVideoPlaybackQuality() { + return {}; + } + /** + * Attempt to create a floating video window always on top of other windows + * so that users may continue consuming media while they interact with other + * content sites, or applications on their device. + * + * @see [Spec]{@link https://wicg.github.io/picture-in-picture} + * + * @return {Promise|undefined} + * A promise with a Picture-in-Picture window if the browser supports + * Promises (or one was passed in as an option). It returns undefined + * otherwise. + * + * @abstract + */ + ; + + _proto.requestPictureInPicture = function requestPictureInPicture() { + var PromiseClass = this.options_.Promise || window__default['default'].Promise; + + if (PromiseClass) { + return PromiseClass.reject(); + } + } + /** + * A method to check for the value of the 'disablePictureInPicture'