popcornjs-rails 1.3.0 → 1.5.6

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,68 +1,76 @@
1
1
  /*
2
- * popcorn.js version 1.3
2
+ * popcorn.js version 1.5.6
3
3
  * http://popcornjs.org
4
4
  *
5
5
  * Copyright 2011, Mozilla Foundation
6
6
  * Licensed under the MIT license
7
7
  */
8
8
 
9
- (function(){document.addEventListener=document.addEventListener||function(j,p){j=j==="DOMContentLoaded"?"onreadystatechange":"on"+j;document.attachEvent(j,p)};document.removeEventListener=document.removeEventListener||function(j,p){j=j==="DOMContentLoaded"?"onreadystatechange":"on"+j;document.detachEvent(j,p)};HTMLScriptElement.prototype.addEventListener=HTMLScriptElement.prototype.addEventListener||function(j,p){j=j==="load"?"onreadystatechange":"on"+j;this.attachEvent(j,p)};HTMLScriptElement.prototype.removeEventListener=
10
- HTMLScriptElement.prototype.removeEventListener||function(j,p){j=j==="load"?"onreadystatechange":"on"+j;this.detachEvent(j,p)};document.createEvent=document.createEvent||function(){return{type:null,target:null,currentTarget:null,cancelable:false,bubbles:false,initEvent:function(j){this.type=j},stopPropagation:function(){},stopImmediatePropagation:function(){}}};Array.prototype.forEach=Array.prototype.forEach||function(j,p){var B=Object.prototype.hasOwnProperty;if(!this||!j)return{};p=p||this;for(var h in this)B.call(this,
11
- h)&&j.call(p,this[h],h,this);return this};if(!Array.prototype.map)Array.prototype.map=function(j,p){var B,h,k;if(this==null)throw new TypeError("this is null or not defined");var o=Object(this),s=o.length>>>0;if({}.toString.call(j)!="[object Function]")throw new TypeError(j+" is not a function");if(p)B=p;h=Array(s);for(k=0;k<s;){var t;if(k in o){t=o[k];t=j.call(B,t,k,o);h[k]=t}k++}return h};if(!Array.prototype.indexOf)Array.prototype.indexOf=function(j){if(this==null)throw new TypeError;var p=Object(this),
12
- B=p.length>>>0;if(B===0)return-1;var h=0;if(arguments.length>0){h=Number(arguments[1]);if(h!=h)h=0;else if(h!=0&&h!=Infinity&&h!=-Infinity)h=(h>0||-1)*Math.floor(Math.abs(h))}if(h>=B)return-1;for(h=h>=0?h:Math.max(B-Math.abs(h),0);h<B;h++)if(h in p&&p[h]===j)return h;return-1}})();
13
- (function(j,p){function B(a,b){return function(){if(c.plugin.debug)return a.apply(this,arguments);try{return a.apply(this,arguments)}catch(e){c.plugin.errors.push({plugin:b,thrown:e,source:a.toString()});this.emit("pluginerror",c.plugin.errors)}}}if(p.addEventListener){var h=Array.prototype,k=Object.prototype,o=h.forEach,s=h.slice,t=k.hasOwnProperty,z=k.toString,u=j.Popcorn,y=[],D=false,A={events:{hash:{},apis:{}}},E=function(){return j.requestAnimationFrame||j.webkitRequestAnimationFrame||j.mozRequestAnimationFrame||
14
- j.oRequestAnimationFrame||j.msRequestAnimationFrame||function(a){j.setTimeout(a,16)}}(),c=function(a,b){return new c.p.init(a,b||null)};c.version="1.3";c.isSupported=true;c.instances=[];c.p=c.prototype={init:function(a,b){var e,d=this;if(typeof a==="function")if(p.readyState==="complete")a(p,c);else{y.push(a);if(!D){D=true;var f=function(){p.removeEventListener("DOMContentLoaded",f,false);for(var n=0,r=y.length;n<r;n++)y[n].call(p,c);y=null};p.addEventListener("DOMContentLoaded",f,false)}}else{if(typeof a===
15
- "string")try{e=p.querySelector(a)}catch(g){throw Error("Popcorn.js Error: Invalid media element selector: "+a);}this.media=e||a;e=this.media.nodeName&&this.media.nodeName.toLowerCase()||"video";this[e]=this.media;this.options=b||{};this.id=this.options.id||c.guid(e);if(c.byId(this.id))throw Error("Popcorn.js Error: Cannot use duplicate ID ("+this.id+")");this.isDestroyed=false;this.data={running:{cue:[]},timeUpdate:c.nop,disabled:{},events:{},hooks:{},history:[],state:{volume:this.media.volume},trackRefs:{},
16
- trackEvents:{byStart:[{start:-1,end:-1}],byEnd:[{start:-1,end:-1}],animating:[],startIndex:0,endIndex:0,previousUpdateTime:-1}};c.instances.push(this);var l=function(){if(d.media.currentTime<0)d.media.currentTime=0;d.media.removeEventListener("loadeddata",l,false);var n,r,w,m,i;n=d.media.duration;n=n!=n?Number.MAX_VALUE:n+1;c.addTrackEvent(d,{start:n,end:n});if(d.options.frameAnimation){d.data.timeUpdate=function(){c.timeUpdate(d,{});c.forEach(c.manifest,function(q,I){if(r=d.data.running[I]){m=r.length;
17
- for(var G=0;G<m;G++){w=r[G];(i=w._natives)&&i.frame&&i.frame.call(d,{},w,d.currentTime())}}});d.emit("timeupdate");!d.isDestroyed&&E(d.data.timeUpdate)};!d.isDestroyed&&E(d.data.timeUpdate)}else{d.data.timeUpdate=function(q){c.timeUpdate(d,q)};d.isDestroyed||d.media.addEventListener("timeupdate",d.data.timeUpdate,false)}};Object.defineProperty(this,"error",{get:function(){return d.media.error}});d.media.readyState>=2?l():d.media.addEventListener("loadeddata",l,false);return this}}};c.p.init.prototype=
18
- c.p;c.byId=function(a){for(var b=c.instances,e=b.length,d=0;d<e;d++)if(b[d].id===a)return b[d];return null};c.forEach=function(a,b,e){if(!a||!b)return{};e=e||this;var d,f;if(o&&a.forEach===o)return a.forEach(b,e);if(z.call(a)==="[object NodeList]"){d=0;for(f=a.length;d<f;d++)b.call(e,a[d],d,a);return a}for(d in a)t.call(a,d)&&b.call(e,a[d],d,a);return a};c.extend=function(a){var b=s.call(arguments,1);c.forEach(b,function(e){for(var d in e)a[d]=e[d]});return a};c.extend(c,{noConflict:function(a){if(a)j.Popcorn=
19
- u;return c},error:function(a){throw Error(a);},guid:function(a){c.guid.counter++;return(a?a:"")+(+new Date+c.guid.counter)},sizeOf:function(a){var b=0,e;for(e in a)b++;return b},isArray:Array.isArray||function(a){return z.call(a)==="[object Array]"},nop:function(){},position:function(a){a=a.getBoundingClientRect();var b={},e=p.documentElement,d=p.body,f,g,l;f=e.clientTop||d.clientTop||0;g=e.clientLeft||d.clientLeft||0;l=j.pageYOffset&&e.scrollTop||d.scrollTop;e=j.pageXOffset&&e.scrollLeft||d.scrollLeft;
20
- f=Math.ceil(a.top+l-f);g=Math.ceil(a.left+e-g);for(var n in a)b[n]=Math.round(a[n]);return c.extend({},b,{top:f,left:g})},disable:function(a,b){if(!a.data.disabled[b]){a.data.disabled[b]=true;for(var e=a.data.running[b].length-1,d;e>=0;e--){d=a.data.running[b][e];d._natives.end.call(a,null,d)}}return a},enable:function(a,b){if(a.data.disabled[b]){a.data.disabled[b]=false;for(var e=a.data.running[b].length-1,d;e>=0;e--){d=a.data.running[b][e];d._natives.start.call(a,null,d)}}return a},destroy:function(a){var b=
21
- a.data.events,e=a.data.trackEvents,d,f,g,l;for(f in b){d=b[f];for(g in d)delete d[g];b[f]=null}for(l in c.registryByName)c.removePlugin(a,l);e.byStart.length=0;e.byEnd.length=0;if(!a.isDestroyed){a.data.timeUpdate&&a.media.removeEventListener("timeupdate",a.data.timeUpdate,false);a.isDestroyed=true}}});c.guid.counter=1;c.extend(c.p,function(){var a={};c.forEach("load play pause currentTime playbackRate volume duration preload playbackRate autoplay loop controls muted buffered readyState seeking paused played seekable ended".split(/\s+/g),
9
+ (function(){if(!document.addEventListener&&!document.removeEventListener&&!document.dispatchEvent){var p={};document.addEventListener=function(h,i){h=h==="DOMContentLoaded"?"readystatechange":h;if(Event[h.toUpperCase()]||h==="readystatechange")document.attachEvent("on"+h,i);else{p[h]||(p[h]={events:[],queue:[],active:false});p[h].active?p[h].queue.push(i):p[h].events.push(i)}};document.removeEventListener=function(h,i){h=h==="DOMContentLoaded"?"readystatechange":h;var j=0,k=p[h];if(Event[h.toUpperCase()]||
10
+ h==="readystatechange")document.detachEvent("on"+h,i);else if(k){for(j=k.events.length-1;j>=0;j--)i===k.events[j]&&delete k.events[j];for(j=k.queue.length-1;j>=0;j--)i===k.queue[j]&&delete k.queue[j]}};document.dispatchEvent=function(h){var i,j,k=h.type;if(!k){k=h;if(h=Popcorn.events.getInterface(k)){i=document.createEvent(h);i.initCustomEvent(k,true,true,window,1)}}if(j=p[k]){j.active=true;for(k=0;k<j.events.length;k++)j.events[k]&&j.events[k].call(this,i,this);if(j.queue.length)for(;j.queue.length;)(i=
11
+ j.queue.shift())&&j.events.push(i);j.active=false;j.events.forEach(function(r){r||j.events.splice(j.events.indexOf(r),1)});j.queue.forEach(function(r){r||j.queue.splice(j.queue.indexOf(r),1)})}}}if(!Event.prototype.preventDefault)Event.prototype.preventDefault=function(){this.returnValue=false};if(!Event.prototype.stopPropagation)Event.prototype.stopPropagation=function(){this.cancelBubble=true};window.addEventListener=window.addEventListener||function(h,i){h="on"+h;window.attachEvent(h,i)};window.removeEventListener=
12
+ window.removeEventListener||function(h,i){h="on"+h;window.detachEvent(h,i)};HTMLScriptElement.prototype.addEventListener=HTMLScriptElement.prototype.addEventListener||function(h,i){h=h==="load"?"onreadystatechange":"on"+h;if(h==="onreadystatechange")i.readyStateCheck=i.readyStateCheck||function(j){self.readyState==="loaded"&&i(j)};this.attachEvent(h,i.readyStateCheck||i)};HTMLScriptElement.prototype.removeEventListener=HTMLScriptElement.prototype.removeEventListener||function(h,i){h=h==="load"?"onreadystatechange":
13
+ "on"+h;this.detachEvent(h,i.readyStateCheck||i)};document.createEvent=document.createEvent||function(){return{type:null,target:null,currentTarget:null,cancelable:false,detail:false,bubbles:false,initEvent:function(h){this.type=h},initCustomEvent:function(h,i,j,k){this.type=h;this.detail=k},stopPropagation:function(){},stopImmediatePropagation:function(){}}};Array.prototype.forEach=Array.prototype.forEach||function(h,i){var j=Object.prototype.hasOwnProperty;if(!this||!h)return{};i=i||this;for(var k in this)j.call(this,
14
+ k)&&h.call(i,this[k],k,this);return this};if(!Array.prototype.map)Array.prototype.map=function(h,i){var j,k,r;if(this==null)throw new TypeError("this is null or not defined");var v=Object(this),q=v.length>>>0;if({}.toString.call(h)!="[object Function]")throw new TypeError(h+" is not a function");if(i)j=i;k=Array(q);for(r=0;r<q;){var y;if(r in v){y=v[r];y=h.call(j,y,r,v);k[r]=y}r++}return k};if(!Array.prototype.indexOf)Array.prototype.indexOf=function(h){if(this==null)throw new TypeError;var i=Object(this),
15
+ j=i.length>>>0;if(j===0)return-1;var k=0;if(arguments.length>0){k=Number(arguments[1]);if(k!=k)k=0;else if(k!=0&&k!=Infinity&&k!=-Infinity)k=(k>0||-1)*Math.floor(Math.abs(k))}if(k>=j)return-1;for(k=k>=0?k:Math.max(j-Math.abs(k),0);k<j;k++)if(k in i&&i[k]===h)return k;return-1};if(typeof String.prototype.trim!=="function")String.prototype.trim=function(){return this.replace(/^\s+|\s+$/g,"")};if(!Object.keys)Object.keys=function(){var h=Object.prototype.hasOwnProperty,i=!{toString:null}.propertyIsEnumerable("toString"),
16
+ j=["toString","toLocaleString","valueOf","hasOwnProperty","isPrototypeOf","propertyIsEnumerable","constructor"],k=j.length;return function(r){if(typeof r!=="object"&&(typeof r!=="function"||r===null))throw new TypeError("Object.keys called on non-object");var v=[],q;for(q in r)h.call(r,q)&&v.push(q);if(i)for(q=0;q<k;q++)h.call(r,j[q])&&v.push(j[q]);return v}}();if(!Object.defineProperties)Object.defineProperties=function(h,i){function j(q){function y(H,B){return Object.prototype.hasOwnProperty.call(H,
17
+ B)}if(typeof q!=="object"||q===null)throw new TypeError("bad desc");var x={};if(y(q,"enumerable"))x.enumerable=!!h.enumerable;if(y(q,"configurable"))x.configurable=!!q.configurable;if(y(q,"value"))x.value=h.value;if(y(q,"writable"))x.writable=!!q.writable;if(y(q,"get")){var E=q.get;if(typeof E!=="function"&&E!=="undefined")throw new TypeError("bad get");x.get=E}if(y(q,"set")){q=q.set;if(typeof q!=="function"&&q!=="undefined")throw new TypeError("bad set");x.set=q}if(("get"in x||"set"in x)&&("value"in
18
+ x||"writable"in x))throw new TypeError("identity-confused descriptor");return x}if(typeof h!=="object"||h===null)throw new TypeError("bad obj");i=Object(i);for(var k=Object.keys(i),r=[],v=0;v<k.length;v++)r.push([k[v],j(i[k[v]])]);for(v=0;v<r.length;v++)Object.defineProperty(h,r[v][0],r[v][1]);return h}})();
19
+ (function(p,h){function i(a){t.put.call(this,a)}function j(a){this.parent=a;this.byStart=[{start:-1,end:-1}];this.byEnd=[{start:-1,end:-1}];this.animating=[];this.endIndex=this.startIndex=0;this.previousUpdateTime=-1;this.count=1}function k(a,b){return function(){if(c.plugin.debug)return a.apply(this,arguments);try{return a.apply(this,arguments)}catch(e){c.plugin.errors.push({plugin:b,thrown:e,source:a.toString()});this.emit("pluginerror",c.plugin.errors)}}}if(h.addEventListener){var r=Array.prototype,
20
+ v=Object.prototype,q=r.forEach,y=r.slice,x=v.hasOwnProperty,E=v.toString,H=p.Popcorn,B=[],K=false,C={events:{hash:{},apis:{}}},F=function(){return p.requestAnimationFrame||p.webkitRequestAnimationFrame||p.mozRequestAnimationFrame||p.oRequestAnimationFrame||p.msRequestAnimationFrame||function(a){p.setTimeout(a,16)}}(),t={put:function(a){for(var b in a)if(a.hasOwnProperty(b))this[b]=a[b]}},c=function(a,b){return new c.p.init(a,b||null)};c.version="1.5.6";c.isSupported=true;c.instances=[];c.p=c.prototype=
21
+ {init:function(a,b){var e,d=this;if(typeof a==="function")if(h.readyState==="complete")a(h,c);else{B.push(a);if(!K){K=true;var g=function(){h.removeEventListener("DOMContentLoaded",g,false);for(var s=0,z=B.length;s<z;s++)B[s].call(h,c);B=null};h.addEventListener("DOMContentLoaded",g,false)}}else{if(typeof a==="string")try{e=h.querySelector(a)}catch(l){throw Error("Popcorn.js Error: Invalid media element selector: "+a);}this.media=e||a;e=this.media.nodeName&&this.media.nodeName.toLowerCase()||"video";
22
+ this[e]=this.media;this.options=c.extend({},b)||{};this.id=this.options.id||c.guid(e);if(c.byId(this.id))throw Error("Popcorn.js Error: Cannot use duplicate ID ("+this.id+")");this.isDestroyed=false;this.data={running:{cue:[]},timeUpdate:c.nop,disabled:{},events:{},hooks:{},history:[],state:{volume:this.media.volume},trackRefs:{},trackEvents:new j(this)};c.instances.push(this);var n=function(){if(d.media.currentTime<0)d.media.currentTime=0;d.media.removeEventListener("loadedmetadata",n,false);var s,
23
+ z,A,o,f;s=d.media.duration;s=s!=s?Number.MAX_VALUE:s+1;c.addTrackEvent(d,{start:s,end:s});if(!d.isDestroyed){d.data.durationChange=function(){var m=d.media.duration,I=m+1,D=d.data.trackEvents.byStart,w=d.data.trackEvents.byEnd;D.pop();w.pop();for(var G=w.length-1;G>0;G--)w[G].end>m&&d.removeTrackEvent(w[G]._id);for(w=0;w<D.length;w++)D[w].end>m&&d.removeTrackEvent(D[w]._id);d.data.trackEvents.byEnd.push({start:I,end:I});d.data.trackEvents.byStart.push({start:I,end:I})};d.media.addEventListener("durationchange",
24
+ d.data.durationChange,false)}if(d.options.frameAnimation){d.data.timeUpdate=function(){c.timeUpdate(d,{});c.forEach(c.manifest,function(m,I){if(z=d.data.running[I]){o=z.length;for(var D=0;D<o;D++){A=z[D];(f=A._natives)&&f.frame&&f.frame.call(d,{},A,d.currentTime())}}});d.emit("timeupdate");!d.isDestroyed&&F(d.data.timeUpdate)};!d.isDestroyed&&F(d.data.timeUpdate)}else{d.data.timeUpdate=function(m){c.timeUpdate(d,m)};d.isDestroyed||d.media.addEventListener("timeupdate",d.data.timeUpdate,false)}};d.media.addEventListener("error",
25
+ function(){d.error=d.media.error},false);d.media.readyState>=1?n():d.media.addEventListener("loadedmetadata",n,false);return this}}};c.p.init.prototype=c.p;c.byId=function(a){for(var b=c.instances,e=b.length,d=0;d<e;d++)if(b[d].id===a)return b[d];return null};c.forEach=function(a,b,e){if(!a||!b)return{};e=e||this;var d,g;if(q&&a.forEach===q)return a.forEach(b,e);if(E.call(a)==="[object NodeList]"){d=0;for(g=a.length;d<g;d++)b.call(e,a[d],d,a);return a}for(d in a)x.call(a,d)&&b.call(e,a[d],d,a);return a};
26
+ c.extend=function(a){var b=y.call(arguments,1);c.forEach(b,function(e){for(var d in e)a[d]=e[d]});return a};c.extend(c,{noConflict:function(a){if(a)p.Popcorn=H;return c},error:function(a){throw Error(a);},guid:function(a){c.guid.counter++;return(a?a:"")+(+new Date+c.guid.counter)},sizeOf:function(a){var b=0,e;for(e in a)b++;return b},isArray:Array.isArray||function(a){return E.call(a)==="[object Array]"},nop:function(){},position:function(a){if(!a.parentNode)return null;a=a.getBoundingClientRect();
27
+ var b={},e=h.documentElement,d=h.body,g,l,n;g=e.clientTop||d.clientTop||0;l=e.clientLeft||d.clientLeft||0;n=p.pageYOffset&&e.scrollTop||d.scrollTop;e=p.pageXOffset&&e.scrollLeft||d.scrollLeft;g=Math.ceil(a.top+n-g);l=Math.ceil(a.left+e-l);for(var s in a)b[s]=Math.round(a[s]);return c.extend({},b,{top:g,left:l})},disable:function(a,b){if(!a.data.disabled[b]){a.data.disabled[b]=true;if(b in c.registryByName&&a.data.running[b])for(var e=a.data.running[b].length-1,d;e>=0;e--){d=a.data.running[b][e];d._natives.end.call(a,
28
+ null,d);a.emit("trackend",c.extend({},d,{plugin:d.type,type:"trackend"}))}return a}},enable:function(a,b){if(a.data.disabled[b]){a.data.disabled[b]=false;if(b in c.registryByName&&a.data.running[b])for(var e=a.data.running[b].length-1,d;e>=0;e--){d=a.data.running[b][e];d._natives.start.call(a,null,d);a.emit("trackstart",c.extend({},d,{plugin:d.type,type:"trackstart",track:d}))}return a}},destroy:function(a){var b=a.data.events,e=a.data.trackEvents,d,g,l,n;for(g in b){d=b[g];for(l in d)delete d[l];
29
+ b[g]=null}for(n in c.registryByName)c.removePlugin(a,n);e.byStart.length=0;e.byEnd.length=0;if(!a.isDestroyed){a.data.timeUpdate&&a.media.removeEventListener("timeupdate",a.data.timeUpdate,false);a.isDestroyed=true}c.instances.splice(c.instances.indexOf(a),1)}});c.guid.counter=1;c.extend(c.p,function(){var a={};c.forEach("load play pause currentTime playbackRate volume duration preload playbackRate autoplay loop controls muted buffered readyState seeking paused played seekable ended".split(/\s+/g),
22
30
  function(b){a[b]=function(e){var d;if(typeof this.media[b]==="function"){if(e!=null&&/play|pause/.test(b))this.media.currentTime=c.util.toSeconds(e);this.media[b]();return this}if(e!=null){d=this.media[b];this.media[b]=e;d!==e&&this.emit("attrchange",{attribute:b,previousValue:d,currentValue:e});return this}return this.media[b]}});return a}());c.forEach("enable disable".split(" "),function(a){c.p[a]=function(b){return c[a](this,b)}});c.extend(c.p,{roundTime:function(){return Math.round(this.media.currentTime)},
23
- exec:function(a,b,e){var d=arguments.length,f,g;try{g=c.util.toSeconds(a)}catch(l){}if(typeof g==="number")a=g;if(typeof a==="number"&&d===2){e=b;b=a;a=c.guid("cue")}else if(d===1)b=-1;else if(f=this.getTrackEvent(a)){if(typeof a==="string"&&d===2){if(typeof b==="number")e=f._natives.start;if(typeof b==="function"){e=b;b=f.start}}}else if(d>=2){if(typeof b==="string"){try{g=c.util.toSeconds(b)}catch(n){}b=g}if(typeof b==="number")e=c.nop();if(typeof b==="function"){e=b;b=-1}}c.addTrackEvent(this,
24
- {id:a,start:b,end:b+1,_running:false,_natives:{start:e||c.nop,end:c.nop,type:"cue"}});return this},mute:function(a){a=a==null||a===true?"muted":"unmuted";if(a==="unmuted"){this.media.muted=false;this.media.volume=this.data.state.volume}if(a==="muted"){this.data.state.volume=this.media.volume;this.media.muted=true}this.emit(a);return this},unmute:function(a){return this.mute(a==null?false:!a)},position:function(){return c.position(this.media)},toggle:function(a){return c[this.data.disabled[a]?"enable":
25
- "disable"](this,a)},defaults:function(a,b){if(c.isArray(a)){c.forEach(a,function(e){for(var d in e)this.defaults(d,e[d])},this);return this}if(!this.options.defaults)this.options.defaults={};this.options.defaults[a]||(this.options.defaults[a]={});c.extend(this.options.defaults[a],b);return this}});c.Events={UIEvents:"blur focus focusin focusout load resize scroll unload",MouseEvents:"mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave click dblclick",Events:"loadstart progress suspend emptied stalled play pause error loadedmetadata loadeddata waiting playing canplay canplaythrough seeking seeked timeupdate ended ratechange durationchange volumechange"};
26
- c.Events.Natives=c.Events.UIEvents+" "+c.Events.MouseEvents+" "+c.Events.Events;A.events.apiTypes=["UIEvents","MouseEvents","Events"];(function(a,b){for(var e=A.events.apiTypes,d=a.Natives.split(/\s+/g),f=0,g=d.length;f<g;f++)b.hash[d[f]]=true;e.forEach(function(l){b.apis[l]={};for(var n=a[l].split(/\s+/g),r=n.length,w=0;w<r;w++)b.apis[l][n[w]]=true})})(c.Events,A.events);c.events={isNative:function(a){return!!A.events.hash[a]},getInterface:function(a){if(!c.events.isNative(a))return false;var b=
27
- A.events,e=b.apiTypes;b=b.apis;for(var d=0,f=e.length,g,l;d<f;d++){l=e[d];if(b[l][a]){g=l;break}}return g},all:c.Events.Natives.split(/\s+/g),fn:{trigger:function(a,b){var e;if(this.data.events[a]&&c.sizeOf(this.data.events[a])){if(e=c.events.getInterface(a)){e=p.createEvent(e);e.initEvent(a,true,true,j,1);this.media.dispatchEvent(e);return this}c.forEach(this.data.events[a],function(d){d.call(this,b)},this)}return this},listen:function(a,b){var e=this,d=true,f=c.events.hooks[a],g;if(!this.data.events[a]){this.data.events[a]=
28
- {};d=false}if(f){f.add&&f.add.call(this,{},b);if(f.bind)a=f.bind;if(f.handler){g=b;b=function(l){f.handler.call(e,l,g)}}d=true;if(!this.data.events[a]){this.data.events[a]={};d=false}}this.data.events[a][b.name||b.toString()+c.guid()]=b;!d&&c.events.all.indexOf(a)>-1&&this.media.addEventListener(a,function(l){c.forEach(e.data.events[a],function(n){typeof n==="function"&&n.call(e,l)})},false);return this},unlisten:function(a,b){if(this.data.events[a]&&this.data.events[a][b]){delete this.data.events[a][b];
29
- return this}this.data.events[a]=null;return this}},hooks:{canplayall:{bind:"canplaythrough",add:function(a,b){var e=false;if(this.media.readyState){b.call(this,a);e=true}this.data.hooks.canplayall={fired:e}},handler:function(a,b){if(!this.data.hooks.canplayall.fired){b.call(this,a);this.data.hooks.canplayall.fired=true}}}}};c.forEach([["trigger","emit"],["listen","on"],["unlisten","off"]],function(a){c.p[a[0]]=c.p[a[1]]=c.events.fn[a[0]]});c.addTrackEvent=function(a,b){var e,d;if(b.id)e=a.getTrackEvent(b.id);
30
- if(e){d=true;b=c.extend({},e,b);a.removeTrackEvent(b.id)}if(b&&b._natives&&b._natives.type&&a.options.defaults&&a.options.defaults[b._natives.type])b=c.extend({},a.options.defaults[b._natives.type],b);if(b._natives){b._id=b.id||b._id||c.guid(b._natives.type);a.data.history.push(b._id)}b.start=c.util.toSeconds(b.start,a.options.framerate);b.end=c.util.toSeconds(b.end,a.options.framerate);var f=a.data.trackEvents.byStart,g=a.data.trackEvents.byEnd,l;for(l=f.length-1;l>=0;l--)if(b.start>=f[l].start){f.splice(l+
31
- 1,0,b);break}for(f=g.length-1;f>=0;f--)if(b.end>g[f].end){g.splice(f+1,0,b);break}if(b.end>a.media.currentTime&&b.start<=a.media.currentTime){b._running=true;a.data.running[b._natives.type].push(b);a.data.disabled[b._natives.type]||b._natives.start.call(a,null,b)}l<=a.data.trackEvents.startIndex&&b.start<=a.data.trackEvents.previousUpdateTime&&a.data.trackEvents.startIndex++;f<=a.data.trackEvents.endIndex&&b.end<a.data.trackEvents.previousUpdateTime&&a.data.trackEvents.endIndex++;this.timeUpdate(a,
32
- null,true);b._id&&c.addTrackEvent.ref(a,b);if(d){d=b._natives.type==="cue"?"cuechange":"trackchange";a.emit(d,{id:b.id,previousValue:{time:e.start,fn:e._natives.start},currentValue:{time:b.start,fn:b._natives.start}})}};c.addTrackEvent.ref=function(a,b){a.data.trackRefs[b._id]=b;return a};c.removeTrackEvent=function(a,b){for(var e,d,f=a.data.history.length,g=a.data.trackEvents.byStart.length,l=0,n=0,r=[],w=[],m=[],i=[];--g>-1;){e=a.data.trackEvents.byStart[l];d=a.data.trackEvents.byEnd[l];if(!e._id){r.push(e);
33
- w.push(d)}if(e._id){e._id!==b&&r.push(e);d._id!==b&&w.push(d);if(e._id===b){n=l;e._natives._teardown&&e._natives._teardown.call(a,e)}}l++}g=a.data.trackEvents.animating.length;l=0;if(g)for(;--g>-1;){e=a.data.trackEvents.animating[l];e._id||m.push(e);e._id&&e._id!==b&&m.push(e);l++}n<=a.data.trackEvents.startIndex&&a.data.trackEvents.startIndex--;n<=a.data.trackEvents.endIndex&&a.data.trackEvents.endIndex--;a.data.trackEvents.byStart=r;a.data.trackEvents.byEnd=w;a.data.trackEvents.animating=m;for(g=
34
- 0;g<f;g++)a.data.history[g]!==b&&i.push(a.data.history[g]);a.data.history=i;c.removeTrackEvent.ref(a,b)};c.removeTrackEvent.ref=function(a,b){delete a.data.trackRefs[b];return a};c.getTrackEvents=function(a){var b=[];a=a.data.trackEvents.byStart;for(var e=a.length,d=0,f;d<e;d++){f=a[d];f._id&&b.push(f)}return b};c.getTrackEvents.ref=function(a){return a.data.trackRefs};c.getTrackEvent=function(a,b){return a.data.trackRefs[b]};c.getTrackEvent.ref=function(a,b){return a.data.trackRefs[b]};c.getLastTrackEventId=
35
- function(a){return a.data.history[a.data.history.length-1]};c.timeUpdate=function(a,b){var e=a.media.currentTime,d=a.data.trackEvents.previousUpdateTime,f=a.data.trackEvents,g=f.endIndex,l=f.startIndex,n=f.byStart.length,r=f.byEnd.length,w=c.registryByName,m,i,q;if(d<=e){for(;f.byEnd[g]&&f.byEnd[g].end<=e;){m=f.byEnd[g];i=(d=m._natives)&&d.type;if(!d||w[i]||a[i]){if(m._running===true){m._running=false;q=a.data.running[i];q.splice(q.indexOf(m),1);if(!a.data.disabled[i]){d.end.call(a,b,m);a.emit("trackend",
36
- c.extend({},m,{plugin:i,type:"trackend"}))}}g++}else{c.removeTrackEvent(a,m._id);return}}for(;f.byStart[l]&&f.byStart[l].start<=e;){m=f.byStart[l];i=(d=m._natives)&&d.type;if(!d||w[i]||a[i]){if(m.end>e&&m._running===false){m._running=true;a.data.running[i].push(m);if(!a.data.disabled[i]){d.start.call(a,b,m);a.emit("trackstart",c.extend({},m,{plugin:i,type:"trackstart"}))}}l++}else{c.removeTrackEvent(a,m._id);return}}}else if(d>e){for(;f.byStart[l]&&f.byStart[l].start>e;){m=f.byStart[l];i=(d=m._natives)&&
37
- d.type;if(!d||w[i]||a[i]){if(m._running===true){m._running=false;q=a.data.running[i];q.splice(q.indexOf(m),1);if(!a.data.disabled[i]){d.end.call(a,b,m);a.emit("trackend",c.extend({},m,{plugin:i,type:"trackend"}))}}l--}else{c.removeTrackEvent(a,m._id);return}}for(;f.byEnd[g]&&f.byEnd[g].end>e;){m=f.byEnd[g];i=(d=m._natives)&&d.type;if(!d||w[i]||a[i]){if(m.start<=e&&m._running===false){m._running=true;a.data.running[i].push(m);if(!a.data.disabled[i]){d.start.call(a,b,m);a.emit("trackstart",c.extend({},
38
- m,{plugin:i,type:"trackstart"}))}}g--}else{c.removeTrackEvent(a,m._id);return}}}f.endIndex=g;f.startIndex=l;f.previousUpdateTime=e;f.byStart.length<n&&f.startIndex--;f.byEnd.length<r&&f.endIndex--};c.extend(c.p,{getTrackEvents:function(){return c.getTrackEvents.call(null,this)},getTrackEvent:function(a){return c.getTrackEvent.call(null,this,a)},getLastTrackEventId:function(){return c.getLastTrackEventId.call(null,this)},removeTrackEvent:function(a){c.removeTrackEvent.call(null,this,a);return this},
39
- removePlugin:function(a){c.removePlugin.call(null,this,a);return this},timeUpdate:function(a){c.timeUpdate.call(null,this,a);return this},destroy:function(){c.destroy.call(null,this);return this}});c.manifest={};c.registry=[];c.registryByName={};c.plugin=function(a,b,e){if(c.protect.natives.indexOf(a.toLowerCase())>=0)c.error("'"+a+"' is a protected function name");else{var d=["start","end"],f={},g=typeof b==="function",l=["_setup","_teardown","start","end","frame"],n=function(m,i){m=m||c.nop;i=i||
40
- c.nop;return function(){m.apply(this,arguments);i.apply(this,arguments)}};c.manifest[a]=e=e||b.manifest||{};l.forEach(function(m){b[m]=B(b[m]||c.nop,a)});var r=function(m,i){if(!i)return this;if(i.ranges&&c.isArray(i.ranges)){c.forEach(i.ranges,function(C){C=c.extend({},i,C);delete C.ranges;this[a](C)},this);return this}var q=i._natives={},I="",G;c.extend(q,m);i._natives.type=a;i._running=false;q.start=q.start||q["in"];q.end=q.end||q.out;if(i.once)q.end=n(q.end,function(){this.removeTrackEvent(i._id)});
41
- q._teardown=n(function(){var C=s.call(arguments),F=this.data.running[q.type];C.unshift(null);C[1]._running&&F.splice(F.indexOf(i),1)&&q.end.apply(this,C)},q._teardown);i.compose=i.compose&&i.compose.split(" ")||[];i.effect=i.effect&&i.effect.split(" ")||[];i.compose=i.compose.concat(i.effect);i.compose.forEach(function(C){I=c.compositions[C]||{};l.forEach(function(F){q[F]=n(q[F],I[F])})});i._natives.manifest=e;if(!("start"in i))i.start=i["in"]||0;if(!i.end&&i.end!==0)i.end=i.out||Number.MAX_VALUE;
42
- if(!t.call(i,"toString"))i.toString=function(){var C=["start: "+i.start,"end: "+i.end,"id: "+(i.id||i._id)];i.target!=null&&C.push("target: "+i.target);return a+" ( "+C.join(", ")+" )"};if(!i.target){G="options"in e&&e.options;i.target=G&&"target"in G&&G.target}if(i._natives)i._id=c.guid(i._natives.type);i._natives._setup&&i._natives._setup.call(this,i);c.addTrackEvent(this,i);c.forEach(m,function(C,F){F!=="type"&&d.indexOf(F)===-1&&this.on(F,C)},this);return this};c.p[a]=f[a]=function(m,i){var q;
43
- if(m&&!i)i=m;else if(q=this.getTrackEvent(m)){i=c.extend({},q,i);c.addTrackEvent(this,i);return this}else i.id=m;this.data.running[a]=this.data.running[a]||[];q=c.extend({},this.options.defaults&&this.options.defaults[a]||{},i);return r.call(this,g?b.call(this,q):b,q)};e&&c.extend(b,{manifest:e});var w={fn:f[a],definition:b,base:b,parents:[],name:a};c.registry.push(c.extend(f,w,{type:a}));c.registryByName[a]=w;return f}};c.plugin.errors=[];c.plugin.debug=c.version==="1.3";c.removePlugin=function(a,
44
- b){if(!b){b=a;a=c.p;if(c.protect.natives.indexOf(b.toLowerCase())>=0){c.error("'"+b+"' is a protected function name");return}var e=c.registry.length,d;for(d=0;d<e;d++)if(c.registry[d].name===b){c.registry.splice(d,1);delete c.registryByName[b];delete c.manifest[b];delete a[b];return}}e=a.data.trackEvents.byStart;d=a.data.trackEvents.byEnd;var f=a.data.trackEvents.animating,g,l;g=0;for(l=e.length;g<l;g++){if(e[g]&&e[g]._natives&&e[g]._natives.type===b){e[g]._natives._teardown&&e[g]._natives._teardown.call(a,
45
- e[g]);e.splice(g,1);g--;l--;if(a.data.trackEvents.startIndex<=g){a.data.trackEvents.startIndex--;a.data.trackEvents.endIndex--}}d[g]&&d[g]._natives&&d[g]._natives.type===b&&d.splice(g,1)}g=0;for(l=f.length;g<l;g++)if(f[g]&&f[g]._natives&&f[g]._natives.type===b){f.splice(g,1);g--;l--}};c.compositions={};c.compose=function(a,b,e){c.manifest[a]=e||b.manifest||{};c.compositions[a]=b};c.plugin.effect=c.effect=c.compose;var H=/^(?:\.|#|\[)/;c.dom={debug:false,find:function(a,b){var e=null;a=a.trim();b=
46
- b||p;if(a){if(!H.test(a)){e=p.getElementById(a);if(e!==null)return e}try{e=b.querySelector(a)}catch(d){if(c.dom.debug)throw Error(d);}}return e}};var x=/\?/,v={url:"",data:"",dataType:"",success:c.nop,type:"GET",async:true,xhr:function(){return new j.XMLHttpRequest}};c.xhr=function(a){a.dataType=a.dataType&&a.dataType.toLowerCase()||null;if(a.dataType&&(a.dataType==="jsonp"||a.dataType==="script"))c.xhr.getJSONP(a.url,a.success,a.dataType==="script");else{a=c.extend({},v,a);a.ajax=a.xhr();if(a.ajax){if(a.type===
47
- "GET"&&a.data){a.url+=(x.test(a.url)?"&":"?")+a.data;a.data=null}a.ajax.open(a.type,a.url,a.async);a.ajax.send(a.data||null);return c.xhr.httpData(a)}}};c.xhr.httpData=function(a){var b,e=null,d,f=null;a.ajax.onreadystatechange=function(){if(a.ajax.readyState===4){try{e=JSON.parse(a.ajax.responseText)}catch(g){}b={xml:a.ajax.responseXML,text:a.ajax.responseText,json:e};if(!b.xml||!b.xml.documentElement){b.xml=null;try{d=new DOMParser;f=d.parseFromString(a.ajax.responseText,"text/xml");if(!f.getElementsByTagName("parsererror").length)b.xml=
48
- f}catch(l){}}if(a.dataType)b=b[a.dataType];a.success.call(a.ajax,b)}};return b};c.xhr.getJSONP=function(a,b,e){var d=p.head||p.getElementsByTagName("head")[0]||p.documentElement,f=p.createElement("script"),g=false,l=[];l=/(=)\?(?=&|$)|\?\?/;var n,r;if(!e){r=a.match(/(callback=[^&]*)/);if(r!==null&&r.length){l=r[1].split("=")[1];if(l==="?")l="jsonp";n=c.guid(l);a=a.replace(/(callback=[^&]*)/,"callback="+n)}else{n=c.guid("jsonp");if(l.test(a))a=a.replace(l,"$1"+n);l=a.split(/\?(.+)?/);a=l[0]+"?";if(l[1])a+=
49
- l[1]+"&";a+="callback="+n}window[n]=function(w){b&&b(w);g=true}}f.addEventListener("load",function(){e&&b&&b();g&&delete window[n];d.removeChild(f)},false);f.src=a;d.insertBefore(f,d.firstChild)};c.getJSONP=c.xhr.getJSONP;c.getScript=c.xhr.getScript=function(a,b){return c.xhr.getJSONP(a,b,true)};c.util={toSeconds:function(a,b){var e=/^([0-9]+:){0,2}[0-9]+([.;][0-9]+)?$/,d,f,g;if(typeof a==="number")return a;typeof a==="string"&&!e.test(a)&&c.error("Invalid time format");e=a.split(":");d=e.length-
50
- 1;f=e[d];if(f.indexOf(";")>-1){f=f.split(";");g=0;if(b&&typeof b==="number")g=parseFloat(f[1],10)/b;e[d]=parseInt(f[0],10)+g}d=e[0];return{1:parseFloat(d,10),2:parseInt(d,10)*60+parseFloat(e[1],10),3:parseInt(d,10)*3600+parseInt(e[1],10)*60+parseFloat(e[2],10)}[e.length||1]}};c.p.cue=c.p.exec;c.protect={natives:function(a){return Object.keys?Object.keys(a):function(b){var e,d=[];for(e in b)t.call(b,e)&&d.push(e);return d}(a)}(c.p).map(function(a){return a.toLowerCase()})};c.forEach({listen:"on",unlisten:"off",
51
- trigger:"emit",exec:"cue"},function(a,b){var e=c.p[b];c.p[b]=function(){if(typeof console!=="undefined"&&console.warn){console.warn("Deprecated method '"+b+"', "+(a==null?"do not use.":"use '"+a+"' instead."));c.p[b]=e}return c.p[a].apply(this,[].slice.call(arguments))}});j.Popcorn=c}else{j.Popcorn={isSupported:false};for(h="byId forEach extend effects error guid sizeOf isArray nop position disable enable destroyaddTrackEvent removeTrackEvent getTrackEvents getTrackEvent getLastTrackEventId timeUpdate plugin removePlugin compose effect xhr getJSONP getScript".split(/\s+/);h.length;)j.Popcorn[h.shift()]=
31
+ exec:function(a,b,e){var d=arguments.length,g="trackadded",l,n;try{n=c.util.toSeconds(a)}catch(s){}if(typeof n==="number")a=n;if(typeof a==="number"&&d===2){e=b;b=a;a=c.guid("cue")}else if(d===1)b=-1;else if(l=this.getTrackEvent(a)){this.data.trackEvents.remove(a);i.end(this,l);c.removeTrackEvent.ref(this,a);g="cuechange";if(typeof a==="string"&&d===2){if(typeof b==="number")e=l._natives.start;if(typeof b==="function"){e=b;b=l.start}}}else if(d>=2){if(typeof b==="string"){try{n=c.util.toSeconds(b)}catch(z){}b=
32
+ n}if(typeof b==="number")e=e||c.nop();if(typeof b==="function"){e=b;b=-1}}d={id:a,start:b,end:b+1,_running:false,_natives:{start:e||c.nop,end:c.nop,type:"cue"}};if(l)d=c.extend(l,d);if(g==="cuechange"){d._id=d.id||d._id||c.guid(d._natives.type);this.data.trackEvents.add(d);i.start(this,d);this.timeUpdate(this,null,true);c.addTrackEvent.ref(this,d);this.emit(g,c.extend({},d,{id:a,type:g,previousValue:{time:l.start,fn:l._natives.start},currentValue:{time:b,fn:e||c.nop},track:l}))}else c.addTrackEvent(this,
33
+ d);return this},mute:function(a){a=a==null||a===true?"muted":"unmuted";if(a==="unmuted"){this.media.muted=false;this.media.volume=this.data.state.volume}if(a==="muted"){this.data.state.volume=this.media.volume;this.media.muted=true}this.emit(a);return this},unmute:function(a){return this.mute(a==null?false:!a)},position:function(){return c.position(this.media)},toggle:function(a){return c[this.data.disabled[a]?"enable":"disable"](this,a)},defaults:function(a,b){if(c.isArray(a)){c.forEach(a,function(e){for(var d in e)this.defaults(d,
34
+ e[d])},this);return this}if(!this.options.defaults)this.options.defaults={};this.options.defaults[a]||(this.options.defaults[a]={});c.extend(this.options.defaults[a],b);return this}});c.Events={UIEvents:"blur focus focusin focusout load resize scroll unload",MouseEvents:"mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave click dblclick",Events:"loadstart progress suspend emptied stalled play pause error loadedmetadata loadeddata waiting playing canplay canplaythrough seeking seeked timeupdate ended ratechange durationchange volumechange"};
35
+ c.Events.Natives=c.Events.UIEvents+" "+c.Events.MouseEvents+" "+c.Events.Events;C.events.apiTypes=["UIEvents","MouseEvents","Events"];(function(a,b){for(var e=C.events.apiTypes,d=a.Natives.split(/\s+/g),g=0,l=d.length;g<l;g++)b.hash[d[g]]=true;e.forEach(function(n){b.apis[n]={};for(var s=a[n].split(/\s+/g),z=s.length,A=0;A<z;A++)b.apis[n][s[A]]=true})})(c.Events,C.events);c.events={isNative:function(a){return!!C.events.hash[a]},getInterface:function(a){if(!c.events.isNative(a))return false;var b=
36
+ C.events,e=b.apiTypes;b=b.apis;for(var d=0,g=e.length,l,n;d<g;d++){n=e[d];if(b[n][a]){l=n;break}}return l},all:c.Events.Natives.split(/\s+/g),fn:{trigger:function(a,b){var e,d=this.data.events[a];if(d){if(e=c.events.getInterface(a)){e=h.createEvent(e);e.initEvent(a,true,true,p,1);this.media.dispatchEvent(e);return this}for(e=d.slice();e.length;)e.shift().call(this,b)}return this},listen:function(a,b){var e=this,d=true,g=c.events.hooks[a],l,n;if(typeof b!=="function")throw Error("Popcorn.js Error: Listener is not a function");
37
+ if(!this.data.events[a]){this.data.events[a]=[];d=false}if(g){g.add&&g.add.call(this,{},b);if(g.bind)a=g.bind;if(g.handler){n=b;b=function(s){g.handler.call(e,s,n)}}d=true;if(!this.data.events[a]){this.data.events[a]=[];d=false}}this.data.events[a].push(b);!d&&c.events.all.indexOf(a)>-1&&this.media.addEventListener(a,function(s){if(e.data.events[a])for(l=e.data.events[a].slice();l.length;)l.shift().call(e,s)},false);return this},unlisten:function(a,b){var e,d=this.data.events[a];if(d){if(typeof b===
38
+ "string"){for(e=0;e<d.length;e++)d[e].name===b&&d.splice(e--,1);return this}else if(typeof b==="function"){for(;e!==-1;){e=d.indexOf(b);e!==-1&&d.splice(e,1)}return this}this.data.events[a]=null;return this}}},hooks:{canplayall:{bind:"canplaythrough",add:function(a,b){var e=false;if(this.media.readyState){setTimeout(function(){b.call(this,a)}.bind(this),0);e=true}this.data.hooks.canplayall={fired:e}},handler:function(a,b){if(!this.data.hooks.canplayall.fired){b.call(this,a);this.data.hooks.canplayall.fired=
39
+ true}}}}};c.forEach([["trigger","emit"],["listen","on"],["unlisten","off"]],function(a){c.p[a[0]]=c.p[a[1]]=c.events.fn[a[0]]});i.start=function(a,b){if(b.end>a.media.currentTime&&b.start<=a.media.currentTime&&!b._running){b._running=true;a.data.running[b._natives.type].push(b);if(!a.data.disabled[b._natives.type]){b._natives.start.call(a,null,b);a.emit("trackstart",c.extend({},b,{plugin:b._natives.type,type:"trackstart",track:b}))}}};i.end=function(a,b){var e;if((b.end<=a.media.currentTime||b.start>
40
+ a.media.currentTime)&&b._running){e=a.data.running[b._natives.type];b._running=false;e.splice(e.indexOf(b),1);if(!a.data.disabled[b._natives.type]){b._natives.end.call(a,null,b);a.emit("trackend",c.extend({},b,{plugin:b._natives.type,type:"trackend",track:b}))}}};j.prototype.where=function(a){return(this.parent.getTrackEvents()||[]).filter(function(b){var e,d;if(!a)return true;for(e in a){d=a[e];if(b[e]&&b[e]===d||b._natives[e]&&b._natives[e]===d)return true}return false})};j.prototype.add=function(a){var b=
41
+ this.byStart,e=this.byEnd,d;a&&a._id&&this.parent.data.history.push(a._id);a.start=c.util.toSeconds(a.start,this.parent.options.framerate);a.end=c.util.toSeconds(a.end,this.parent.options.framerate);for(d=b.length-1;d>=0;d--)if(a.start>=b[d].start){b.splice(d+1,0,a);break}for(b=e.length-1;b>=0;b--)if(a.end>e[b].end){e.splice(b+1,0,a);break}d<=this.parent.data.trackEvents.startIndex&&a.start<=this.parent.data.trackEvents.previousUpdateTime&&this.parent.data.trackEvents.startIndex++;b<=this.parent.data.trackEvents.endIndex&&
42
+ a.end<this.parent.data.trackEvents.previousUpdateTime&&this.parent.data.trackEvents.endIndex++;this.count++};j.prototype.remove=function(a){if(a instanceof i)a=a.id;if(typeof a==="object"){this.where(a).forEach(function(o){this.removeTrackEvent(o._id)},this.parent);return this}var b,e,d;d=this.byStart.length;for(var g=0,l=0,n=[],s=[],z=[],A=[];--d>-1;){b=this.byStart[g];e=this.byEnd[g];if(!b._id){n.push(b);s.push(e)}if(b._id){b._id!==a&&n.push(b);e._id!==a&&s.push(e);if(b._id===a)l=g}g++}d=this.animating.length;
43
+ g=0;if(d)for(;--d>-1;){b=this.animating[g];b._id||z.push(b);b._id&&b._id!==a&&z.push(b);g++}l<=this.startIndex&&this.startIndex--;l<=this.endIndex&&this.endIndex--;this.byStart=n;this.byEnd=s;this.animating=z;this.count--;d=this.parent.data.history.length;for(g=0;g<d;g++)this.parent.data.history[g]!==a&&A.push(this.parent.data.history[g]);this.parent.data.history=A};c.addTrackEvent=function(a,b){var e;if(!(b instanceof i)){if((b=new i(b))&&b._natives&&b._natives.type&&a.options.defaults&&a.options.defaults[b._natives.type]){e=
44
+ c.extend({},b);c.extend(b,a.options.defaults[b._natives.type],e)}if(b._natives){b._id=b.id||b._id||c.guid(b._natives.type);if(b._natives._setup){b._natives._setup.call(a,b);a.emit("tracksetup",c.extend({},b,{plugin:b._natives.type,type:"tracksetup",track:b}))}}a.data.trackEvents.add(b);i.start(a,b);this.timeUpdate(a,null,true);b._id&&c.addTrackEvent.ref(a,b);a.emit("trackadded",c.extend({},b,b._natives?{plugin:b._natives.type}:{},{type:"trackadded",track:b}))}};c.addTrackEvent.ref=function(a,b){a.data.trackRefs[b._id]=
45
+ b;return a};c.removeTrackEvent=function(a,b){var e=a.getTrackEvent(b);if(e){e._natives._teardown&&e._natives._teardown.call(a,e);a.data.trackEvents.remove(b);c.removeTrackEvent.ref(a,b);e._natives&&a.emit("trackremoved",c.extend({},e,{plugin:e._natives.type,type:"trackremoved",track:e}))}};c.removeTrackEvent.ref=function(a,b){delete a.data.trackRefs[b];return a};c.getTrackEvents=function(a){var b=[];a=a.data.trackEvents.byStart;for(var e=a.length,d=0,g;d<e;d++){g=a[d];g._id&&b.push(g)}return b};c.getTrackEvents.ref=
46
+ function(a){return a.data.trackRefs};c.getTrackEvent=function(a,b){return a.data.trackRefs[b]};c.getTrackEvent.ref=function(a,b){return a.data.trackRefs[b]};c.getLastTrackEventId=function(a){return a.data.history[a.data.history.length-1]};c.timeUpdate=function(a,b){var e=a.media.currentTime,d=a.data.trackEvents.previousUpdateTime,g=a.data.trackEvents,l=g.endIndex,n=g.startIndex,s=g.byStart.length,z=g.byEnd.length,A=c.registryByName,o,f,m;if(d<=e){for(;g.byEnd[l]&&g.byEnd[l].end<=e;){o=g.byEnd[l];
47
+ f=(d=o._natives)&&d.type;if(!d||A[f]||a[f]){if(o._running===true){o._running=false;m=a.data.running[f];m.splice(m.indexOf(o),1);if(!a.data.disabled[f]){d.end.call(a,b,o);a.emit("trackend",c.extend({},o,{plugin:f,type:"trackend",track:o}))}}l++}else{c.removeTrackEvent(a,o._id);return}}for(;g.byStart[n]&&g.byStart[n].start<=e;){o=g.byStart[n];f=(d=o._natives)&&d.type;if(!d||A[f]||a[f]){if(o.end>e&&o._running===false){o._running=true;a.data.running[f].push(o);if(!a.data.disabled[f]){d.start.call(a,b,
48
+ o);a.emit("trackstart",c.extend({},o,{plugin:f,type:"trackstart",track:o}))}}n++}else{c.removeTrackEvent(a,o._id);return}}}else if(d>e){for(;g.byStart[n]&&g.byStart[n].start>e;){o=g.byStart[n];f=(d=o._natives)&&d.type;if(!d||A[f]||a[f]){if(o._running===true){o._running=false;m=a.data.running[f];m.splice(m.indexOf(o),1);if(!a.data.disabled[f]){d.end.call(a,b,o);a.emit("trackend",c.extend({},o,{plugin:f,type:"trackend",track:o}))}}n--}else{c.removeTrackEvent(a,o._id);return}}for(;g.byEnd[l]&&g.byEnd[l].end>
49
+ e;){o=g.byEnd[l];f=(d=o._natives)&&d.type;if(!d||A[f]||a[f]){if(o.start<=e&&o._running===false){o._running=true;a.data.running[f].push(o);if(!a.data.disabled[f]){d.start.call(a,b,o);a.emit("trackstart",c.extend({},o,{plugin:f,type:"trackstart",track:o}))}}l--}else{c.removeTrackEvent(a,o._id);return}}}g.endIndex=l;g.startIndex=n;g.previousUpdateTime=e;g.byStart.length<s&&g.startIndex--;g.byEnd.length<z&&g.endIndex--};c.extend(c.p,{getTrackEvents:function(){return c.getTrackEvents.call(null,this)},
50
+ getTrackEvent:function(a){return c.getTrackEvent.call(null,this,a)},getLastTrackEventId:function(){return c.getLastTrackEventId.call(null,this)},removeTrackEvent:function(a){c.removeTrackEvent.call(null,this,a);return this},removePlugin:function(a){c.removePlugin.call(null,this,a);return this},timeUpdate:function(a){c.timeUpdate.call(null,this,a);return this},destroy:function(){c.destroy.call(null,this);return this}});c.manifest={};c.registry=[];c.registryByName={};c.plugin=function(a,b,e){if(c.protect.natives.indexOf(a.toLowerCase())>=
51
+ 0)c.error("'"+a+"' is a protected function name");else{var d=typeof b==="function",g=["start","end","type","manifest"],l=["_setup","_teardown","start","end","frame"],n={},s=function(o,f){o=o||c.nop;f=f||c.nop;return function(){o.apply(this,arguments);f.apply(this,arguments)}};c.manifest[a]=e=e||b.manifest||{};l.forEach(function(o){b[o]=k(b[o]||c.nop,a)});var z=function(o,f){if(!f)return this;if(f.ranges&&c.isArray(f.ranges)){c.forEach(f.ranges,function(w){w=c.extend({},f,w);delete w.ranges;this[a](w)},
52
+ this);return this}var m=f._natives={},I="",D;c.extend(m,o);f._natives.type=f._natives.plugin=a;f._running=false;m.start=m.start||m["in"];m.end=m.end||m.out;if(f.once)m.end=s(m.end,function(){this.removeTrackEvent(f._id)});m._teardown=s(function(){var w=y.call(arguments),G=this.data.running[m.type];w.unshift(null);w[1]._running&&G.splice(G.indexOf(f),1)&&m.end.apply(this,w);w[1]._running=false;this.emit("trackend",c.extend({},f,{plugin:m.type,type:"trackend",track:c.getTrackEvent(this,f.id||f._id)}))},
53
+ m._teardown);m._teardown=s(m._teardown,function(){this.emit("trackteardown",c.extend({},f,{plugin:a,type:"trackteardown",track:c.getTrackEvent(this,f.id||f._id)}))});f.compose=f.compose||[];if(typeof f.compose==="string")f.compose=f.compose.split(" ");f.effect=f.effect||[];if(typeof f.effect==="string")f.effect=f.effect.split(" ");f.compose=f.compose.concat(f.effect);f.compose.forEach(function(w){I=c.compositions[w]||{};l.forEach(function(G){m[G]=s(m[G],I[G])})});f._natives.manifest=e;if(!("start"in
54
+ f))f.start=f["in"]||0;if(!f.end&&f.end!==0)f.end=f.out||Number.MAX_VALUE;if(!x.call(f,"toString"))f.toString=function(){var w=["start: "+f.start,"end: "+f.end,"id: "+(f.id||f._id)];f.target!=null&&w.push("target: "+f.target);return a+" ( "+w.join(", ")+" )"};if(!f.target){D="options"in e&&e.options;f.target=D&&"target"in D&&D.target}if(!f._id&&f._natives)f._id=c.guid(f._natives.type);if(f instanceof i){if(f._natives){f._id=f.id||f._id||c.guid(f._natives.type);if(f._natives._setup){f._natives._setup.call(this,
55
+ f);this.emit("tracksetup",c.extend({},f,{plugin:f._natives.type,type:"tracksetup",track:f}))}}this.data.trackEvents.add(f);i.start(this,f);this.timeUpdate(this,null,true);f._id&&c.addTrackEvent.ref(this,f)}else c.addTrackEvent(this,f);c.forEach(o,function(w,G){g.indexOf(G)===-1&&this.on(G,w)},this);return this};c.p[a]=n[a]=function(o,f){var m,I;if(o&&!f)f=o;else if(m=this.getTrackEvent(o)){I=f;var D={},w;for(w in m)if(x.call(I,w)&&x.call(m,w))D[w]=m[w];if(m._natives._update){this.data.trackEvents.remove(m);
56
+ if(x.call(f,"start"))m.start=f.start;if(x.call(f,"end"))m.end=f.end;i.end(this,m);d&&b.call(this,m);m._natives._update.call(this,m,f);this.data.trackEvents.add(m);i.start(this,m)}else{c.extend(m,f);this.data.trackEvents.remove(o);m._natives._teardown&&m._natives._teardown.call(this,m);c.removeTrackEvent.ref(this,o);if(d)z.call(this,b.call(this,m),m);else{m._id=m.id||m._id||c.guid(m._natives.type);if(m._natives&&m._natives._setup){m._natives._setup.call(this,m);this.emit("tracksetup",c.extend({},m,
57
+ {plugin:m._natives.type,type:"tracksetup",track:m}))}this.data.trackEvents.add(m);i.start(this,m);this.timeUpdate(this,null,true);c.addTrackEvent.ref(this,m)}this.emit("trackchange",{id:m.id,type:"trackchange",previousValue:D,currentValue:m,track:m});return this}m._natives.type!=="cue"&&this.emit("trackchange",{id:m.id,type:"trackchange",previousValue:D,currentValue:I,track:m});return this}else f.id=o;this.data.running[a]=this.data.running[a]||[];m=c.extend({},this.options.defaults&&this.options.defaults[a]||
58
+ {},f);z.call(this,d?b.call(this,m):b,m);return this};e&&c.extend(b,{manifest:e});var A={fn:n[a],definition:b,base:b,parents:[],name:a};c.registry.push(c.extend(n,A,{type:a}));c.registryByName[a]=A;return n}};c.plugin.errors=[];c.plugin.debug=c.version==="1.5.6";c.removePlugin=function(a,b){if(!b){b=a;a=c.p;if(c.protect.natives.indexOf(b.toLowerCase())>=0){c.error("'"+b+"' is a protected function name");return}var e=c.registry.length,d;for(d=0;d<e;d++)if(c.registry[d].name===b){c.registry.splice(d,
59
+ 1);delete c.registryByName[b];delete c.manifest[b];delete a[b];return}}e=a.data.trackEvents.byStart;d=a.data.trackEvents.byEnd;var g=a.data.trackEvents.animating,l,n;l=0;for(n=e.length;l<n;l++){if(e[l]&&e[l]._natives&&e[l]._natives.type===b){e[l]._natives._teardown&&e[l]._natives._teardown.call(a,e[l]);e.splice(l,1);l--;n--;if(a.data.trackEvents.startIndex<=l){a.data.trackEvents.startIndex--;a.data.trackEvents.endIndex--}}d[l]&&d[l]._natives&&d[l]._natives.type===b&&d.splice(l,1)}l=0;for(n=g.length;l<
60
+ n;l++)if(g[l]&&g[l]._natives&&g[l]._natives.type===b){g.splice(l,1);l--;n--}};c.compositions={};c.compose=function(a,b,e){c.manifest[a]=e||b.manifest||{};c.compositions[a]=b};c.plugin.effect=c.effect=c.compose;var L=/^(?:\.|#|\[)/;c.dom={debug:false,find:function(a,b){var e=null;b=b||h;if(a){if(!L.test(a)){e=h.getElementById(a);if(e!==null)return e}try{e=b.querySelector(a)}catch(d){if(c.dom.debug)throw Error(d);}}return e}};var u=/\?/,J={ajax:null,url:"",data:"",dataType:"",success:c.nop,type:"GET",
61
+ async:true,contentType:"application/x-www-form-urlencoded; charset=UTF-8"};c.xhr=function(a){a.dataType=a.dataType&&a.dataType.toLowerCase()||null;if(a.dataType&&(a.dataType==="jsonp"||a.dataType==="script"))c.xhr.getJSONP(a.url,a.success,a.dataType==="script");else{a=c.extend({},J,a);a.ajax=new XMLHttpRequest;if(a.ajax){if(a.type==="GET"&&a.data){a.url+=(u.test(a.url)?"&":"?")+a.data;a.data=null}a.ajax.open(a.type,a.url,a.async);a.type==="POST"&&a.ajax.setRequestHeader("Content-Type",a.contentType);
62
+ a.ajax.send(a.data||null);return c.xhr.httpData(a)}}};c.xhr.httpData=function(a){var b,e=null,d,g=null;a.ajax.onreadystatechange=function(){if(a.ajax.readyState===4){try{e=JSON.parse(a.ajax.responseText)}catch(l){}b={xml:a.ajax.responseXML,text:a.ajax.responseText,json:e};if(!b.xml||!b.xml.documentElement){b.xml=null;try{d=new DOMParser;g=d.parseFromString(a.ajax.responseText,"text/xml");if(!g.getElementsByTagName("parsererror").length)b.xml=g}catch(n){}}if(a.dataType)b=b[a.dataType];a.success.call(a.ajax,
63
+ b)}};return b};c.xhr.getJSONP=function(a,b,e){var d=h.head||h.getElementsByTagName("head")[0]||h.documentElement,g=h.createElement("script"),l=false,n=[];n=/(=)\?(?=&|$)|\?\?/;var s,z;if(!e){z=a.match(/(callback=[^&]*)/);if(z!==null&&z.length){n=z[1].split("=")[1];if(n==="?")n="jsonp";s=c.guid(n);a=a.replace(/(callback=[^&]*)/,"callback="+s)}else{s=c.guid("jsonp");if(n.test(a))a=a.replace(n,"$1"+s);n=a.split(/\?(.+)?/);a=n[0]+"?";if(n[1])a+=n[1]+"&";a+="callback="+s}window[s]=function(A){b&&b(A);
64
+ l=true}}g.addEventListener("load",function(){e&&b&&b();l&&delete window[s];d.removeChild(g)},false);g.addEventListener("error",function(A){b&&b({error:A});e||delete window[s];d.removeChild(g)},false);g.src=a;d.insertBefore(g,d.firstChild)};c.getJSONP=c.xhr.getJSONP;c.getScript=c.xhr.getScript=function(a,b){return c.xhr.getJSONP(a,b,true)};c.util={toSeconds:function(a,b){var e=/^([0-9]+:){0,2}[0-9]+([.;][0-9]+)?$/,d,g,l;if(typeof a==="number")return a;typeof a==="string"&&!e.test(a)&&c.error("Invalid time format");
65
+ e=a.split(":");d=e.length-1;g=e[d];if(g.indexOf(";")>-1){g=g.split(";");l=0;if(b&&typeof b==="number")l=parseFloat(g[1],10)/b;e[d]=parseInt(g[0],10)+l}d=e[0];return{1:parseFloat(d,10),2:parseInt(d,10)*60+parseFloat(e[1],10),3:parseInt(d,10)*3600+parseInt(e[1],10)*60+parseFloat(e[2],10)}[e.length||1]}};c.p.cue=c.p.exec;c.protect={natives:function(a){return Object.keys?Object.keys(a):function(b){var e,d=[];for(e in b)x.call(b,e)&&d.push(e);return d}(a)}(c.p).map(function(a){return a.toLowerCase()})};
66
+ c.forEach({listen:"on",unlisten:"off",trigger:"emit",exec:"cue"},function(a,b){var e=c.p[b];c.p[b]=function(){if(typeof console!=="undefined"&&console.warn){console.warn("Deprecated method '"+b+"', "+(a==null?"do not use.":"use '"+a+"' instead."));c.p[b]=e}return c.p[a].apply(this,[].slice.call(arguments))}});p.Popcorn=c}else{p.Popcorn={isSupported:false};for(r="byId forEach extend effects error guid sizeOf isArray nop position disable enable destroyaddTrackEvent removeTrackEvent getTrackEvents getTrackEvent getLastTrackEventId timeUpdate plugin removePlugin compose effect xhr getJSONP getScript".split(/\s+/);r.length;)p.Popcorn[r.shift()]=
52
67
  function(){}}})(window,window.document);
53
- (function(j){var p=function(k,o){k=k||j.nop;o=o||j.nop;return function(){k.apply(this,arguments);o.apply(this,arguments)}},B=/^.*\.(ogg|oga|aac|mp3|wav)($|\?)/,h=/^.*\.(ogg|oga|aac|mp3|wav|ogg|ogv|mp4|webm)($|\?)/;j.player=function(k,o){if(!j[k]){o=o||{};var s=function(t,z,u){u=u||{};var y=new Date/1E3,D=y,A=0,E=0,c=1,H=false,x={},v=typeof t==="string"?j.dom.find(t):t,a={};Object.prototype.__defineGetter__||(a=v||document.createElement("div"));for(var b in v)if(!(b in a))if(typeof v[b]==="object")a[b]=
54
- v[b];else if(typeof v[b]==="function")a[b]=function(d){return"length"in v[d]&&!v[d].call?v[d]:function(){return v[d].apply(v,arguments)}}(b);else j.player.defineProperty(a,b,{get:function(d){return function(){return v[d]}}(b),set:j.nop,configurable:true});var e=function(){y=new Date/1E3;if(!a.paused){a.currentTime+=y-D;a.dispatchEvent("timeupdate");setTimeout(e,10)}D=y};a.play=function(){this.paused=false;if(a.readyState>=4){D=new Date/1E3;a.dispatchEvent("play");e()}};a.pause=function(){this.paused=
55
- true;a.dispatchEvent("pause")};j.player.defineProperty(a,"currentTime",{get:function(){return A},set:function(d){A=+d;a.dispatchEvent("timeupdate");return A},configurable:true});j.player.defineProperty(a,"volume",{get:function(){return c},set:function(d){c=+d;a.dispatchEvent("volumechange");return c},configurable:true});j.player.defineProperty(a,"muted",{get:function(){return H},set:function(d){H=+d;a.dispatchEvent("volumechange");return H},configurable:true});j.player.defineProperty(a,"readyState",
56
- {get:function(){return E},set:function(d){return E=d},configurable:true});a.addEventListener=function(d,f){x[d]||(x[d]=[]);x[d].push(f);return f};a.removeEventListener=function(d,f){var g,l=x[d];if(l){for(g=x[d].length-1;g>=0;g--)f===l[g]&&l.splice(g,1);return f}};a.dispatchEvent=function(d){var f,g=d.type;if(!g){g=d;if(d=j.events.getInterface(g)){f=document.createEvent(d);f.initEvent(g,true,true,window,1)}}if(x[g])for(d=x[g].length-1;d>=0;d--)x[g][d].call(this,f,this)};a.src=z||"";a.duration=0;a.paused=
57
- true;a.ended=0;u&&u.events&&j.forEach(u.events,function(d,f){a.addEventListener(f,d,false)});if(o._canPlayType(v.nodeName,z)!==false)if(o._setup)o._setup.call(a,u);else{a.readyState=4;a.dispatchEvent("loadedmetadata");a.dispatchEvent("loadeddata");a.dispatchEvent("canplaythrough")}else setTimeout(function(){a.dispatchEvent("error")},0);t=new j.p.init(a,u);if(o._teardown)t.destroy=p(t.destroy,function(){o._teardown.call(a,u)});return t};s.canPlayType=o._canPlayType=o._canPlayType||j.nop;j[k]=j.player.registry[k]=
58
- s}};j.player.registry={};j.player.defineProperty=Object.defineProperty||function(k,o,s){k.__defineGetter__(o,s.get||j.nop);k.__defineSetter__(o,s.set||j.nop)};j.player.playerQueue=function(){var k=[],o=false;return{next:function(){o=false;k.shift();k[0]&&k[0]()},add:function(s){k.push(function(){o=true;s&&s()});!o&&k[0]()}}};j.smart=function(k,o,s){var t=["AUDIO","VIDEO"],z,u=j.dom.find(k),y;z=document.createElement("video");var D={ogg:"video/ogg",ogv:"video/ogg",oga:"audio/ogg",webm:"video/webm",
59
- mp4:"video/mp4",mp3:"audio/mp3"};if(u){if(t.indexOf(u.nodeName)>-1&&!o){if(typeof o==="object")s=o;return j(u,s)}if(typeof o==="string")o=[o];k=0;for(srcLength=o.length;k<srcLength;k++){y=h.exec(o[k]);y=!y||!y[1]?false:z.canPlayType(D[y[1]]);if(y){o=o[k];break}for(var A in j.player.registry)if(j.player.registry.hasOwnProperty(A))if(j.player.registry[A].canPlayType(u.nodeName,o[k]))return j[A](u,o[k],s)}if(t.indexOf(u.nodeName)===-1){z=typeof o==="string"?o:o.length?o[0]:o;k=document.createElement(B.exec(z)?
60
- t[0]:t[1]);k.controls=true;u.appendChild(k);u=k}s&&s.events&&s.events.error&&u.addEventListener("error",s.events.error,false);u.src=o;return j(u,s)}else j.error("Specified target "+k+" was not found.")}})(Popcorn);
61
- (function(j,p){j.onYouTubePlayerAPIReady=function(){onYouTubePlayerAPIReady.ready=true;for(var h=0;h<onYouTubePlayerAPIReady.waiting.length;h++)onYouTubePlayerAPIReady.waiting[h]()};if(j.YT){j.quarantineYT=j.YT;j.YT=null}onYouTubePlayerAPIReady.waiting=[];var B=false;p.player("youtube",{_canPlayType:function(h,k){return typeof k==="string"&&/(?:http:\/\/www\.|http:\/\/|www\.|\.|^)(youtu)/.test(k)&&h.toLowerCase()!=="video"},_setup:function(h){if(!j.YT&&!B){B=true;p.getScript("//youtube.com/player_api")}var k=
62
- this,o=false,s=document.createElement("div"),t=0,z=true,u=false,y=0,D=false,A=100,E=p.player.playerQueue(),c=function(){p.player.defineProperty(k,"currentTime",{set:function(x){if(!h.destroyed){u=true;t=Math.round(+x*100)/100}},get:function(){return t}});p.player.defineProperty(k,"paused",{get:function(){return z}});p.player.defineProperty(k,"muted",{set:function(x){if(h.destroyed)return x;if(h.youtubeObject.isMuted()!==x){x?h.youtubeObject.mute():h.youtubeObject.unMute();D=h.youtubeObject.isMuted();
63
- k.dispatchEvent("volumechange")}return h.youtubeObject.isMuted()},get:function(){if(h.destroyed)return 0;return h.youtubeObject.isMuted()}});p.player.defineProperty(k,"volume",{set:function(x){if(h.destroyed)return x;if(h.youtubeObject.getVolume()/100!==x){h.youtubeObject.setVolume(x*100);A=h.youtubeObject.getVolume();k.dispatchEvent("volumechange")}return h.youtubeObject.getVolume()/100},get:function(){if(h.destroyed)return 0;return h.youtubeObject.getVolume()/100}});k.play=function(){if(!h.destroyed){z=
64
- false;E.add(function(){if(h.youtubeObject.getPlayerState()!==1){u=false;h.youtubeObject.playVideo()}else E.next()})}};k.pause=function(){if(!h.destroyed){z=true;E.add(function(){h.youtubeObject.getPlayerState()!==2?h.youtubeObject.pauseVideo():E.next()})}}};s.id=k.id+p.guid();h._container=s;k.appendChild(s);var H=function(){var x,v,a,b,e=true,d=function(){if(!h.destroyed){if(u)if(t===h.youtubeObject.getCurrentTime()){u=false;k.dispatchEvent("seeked");k.dispatchEvent("timeupdate")}else h.youtubeObject.seekTo(t);
65
- else{t=h.youtubeObject.getCurrentTime();k.dispatchEvent("timeupdate")}setTimeout(d,250)}},f=function(n){var r=h.youtubeObject.getDuration();if(isNaN(r)||r===0)setTimeout(function(){f(n*2)},n*1E3);else{k.duration=r;k.dispatchEvent("durationchange");k.dispatchEvent("loadedmetadata");k.dispatchEvent("loadeddata");k.readyState=4;d();k.dispatchEvent("canplaythrough")}};h.controls=+h.controls===0||+h.controls===1?h.controls:1;h.annotations=+h.annotations===1||+h.annotations===3?h.annotations:1;x=/^.*(?:\/|v=)(.{11})/.exec(k.src)[1];
66
- v=(k.src.split("?")[1]||"").replace(/v=.{11}/,"");v=v.replace(/&t=(?:(\d+)m)?(?:(\d+)s)?/,function(n,r,w){r|=0;w|=0;y=+w+r*60;return""});v=v.replace(/&start=(\d+)?/,function(n,r){r|=0;y=r;return""});o=/autoplay=1/.test(v);v=v.split(/[\&\?]/g);a={wmode:"transparent"};for(var g=0;g<v.length;g++){b=v[g].split("=");a[b[0]]=b[1]}h.youtubeObject=new YT.Player(s.id,{height:"100%",width:"100%",wmode:"transparent",playerVars:a,videoId:x,events:{onReady:function(){A=k.volume;D=k.muted;l();z=k.paused;c();h.youtubeObject.playVideo();
67
- k.currentTime=y},onStateChange:function(n){if(!(h.destroyed||n.data===-1))if(n.data===2){z=true;k.dispatchEvent("pause");E.next()}else if(n.data===1&&!e){z=false;k.dispatchEvent("play");k.dispatchEvent("playing");E.next()}else if(n.data===0)k.dispatchEvent("ended");else if(n.data===1&&e){e=false;if(o||!k.paused)z=false;z&&h.youtubeObject.pauseVideo();f(0.025)}},onError:function(n){if([2,100,101,150].indexOf(n.data)!==-1){k.error={customCode:n.data};k.dispatchEvent("error")}}}});var l=function(){if(!h.destroyed){if(D!==
68
- h.youtubeObject.isMuted()){D=h.youtubeObject.isMuted();k.dispatchEvent("volumechange")}if(A!==h.youtubeObject.getVolume()){A=h.youtubeObject.getVolume();k.dispatchEvent("volumechange")}setTimeout(l,250)}}};onYouTubePlayerAPIReady.ready?H():onYouTubePlayerAPIReady.waiting.push(H)},_teardown:function(h){h.destroyed=true;var k=h.youtubeObject;if(k){k.stopVideo();k.clearVideo&&k.clearVideo()}this.removeChild(document.getElementById(h._container.id))}})})(window,Popcorn);
68
+ (function(p){var h=function(i,j){i=i||p.nop;j=j||p.nop;return function(){i.apply(this,arguments);j.apply(this,arguments)}};p.player=function(i,j){if(!p[i]){j=j||{};var k=function(r,v,q){q=q||{};var y=new Date/1E3,x=y,E=0,H=0,B=1,K=false,C={},F=typeof r==="string"?p.dom.find(r):r,t={};Object.prototype.__defineGetter__||(t=F||document.createElement("div"));for(var c in F)if(!(c in t))if(typeof F[c]==="object")t[c]=F[c];else if(typeof F[c]==="function")t[c]=function(u){return"length"in F[u]&&!F[u].call?
69
+ F[u]:function(){return F[u].apply(F,arguments)}}(c);else p.player.defineProperty(t,c,{get:function(u){return function(){return F[u]}}(c),set:p.nop,configurable:true});var L=function(){y=new Date/1E3;if(!t.paused){t.currentTime+=y-x;t.dispatchEvent("timeupdate");setTimeout(L,10)}x=y};t.play=function(){this.paused=false;if(t.readyState>=4){x=new Date/1E3;t.dispatchEvent("play");L()}};t.pause=function(){this.paused=true;t.dispatchEvent("pause")};p.player.defineProperty(t,"currentTime",{get:function(){return E},
70
+ set:function(u){E=+u;t.dispatchEvent("timeupdate");return E},configurable:true});p.player.defineProperty(t,"volume",{get:function(){return B},set:function(u){B=+u;t.dispatchEvent("volumechange");return B},configurable:true});p.player.defineProperty(t,"muted",{get:function(){return K},set:function(u){K=+u;t.dispatchEvent("volumechange");return K},configurable:true});p.player.defineProperty(t,"readyState",{get:function(){return H},set:function(u){return H=u},configurable:true});t.addEventListener=function(u,
71
+ J){C[u]||(C[u]=[]);C[u].push(J);return J};t.removeEventListener=function(u,J){var a,b=C[u];if(b){for(a=C[u].length-1;a>=0;a--)J===b[a]&&b.splice(a,1);return J}};t.dispatchEvent=function(u){var J,a=u.type;if(!a){a=u;if(u=p.events.getInterface(a)){J=document.createEvent(u);J.initEvent(a,true,true,window,1)}}if(C[a])for(u=C[a].length-1;u>=0;u--)C[a][u].call(this,J,this)};t.src=v||"";t.duration=0;t.paused=true;t.ended=0;q&&q.events&&p.forEach(q.events,function(u,J){t.addEventListener(J,u,false)});if(j._canPlayType(F.nodeName,
72
+ v)!==false)if(j._setup)j._setup.call(t,q);else{t.readyState=4;t.dispatchEvent("loadedmetadata");t.dispatchEvent("loadeddata");t.dispatchEvent("canplaythrough")}else setTimeout(function(){t.dispatchEvent("error")},0);r=new p.p.init(t,q);if(j._teardown)r.destroy=h(r.destroy,function(){j._teardown.call(t,q)});return r};k.canPlayType=j._canPlayType=j._canPlayType||p.nop;p[i]=p.player.registry[i]=k}};p.player.registry={};p.player.defineProperty=Object.defineProperty||function(i,j,k){i.__defineGetter__(j,
73
+ k.get||p.nop);i.__defineSetter__(j,k.set||p.nop)};p.player.playerQueue=function(){var i=[],j=false;return{next:function(){j=false;i.shift();i[0]&&i[0]()},add:function(k){i.push(function(){j=true;k&&k()});!j&&i[0]()}}};p.smart=function(i,j,k){var r=typeof i==="string"?p.dom.find(i):i,v,q,y,x,E,H="HTMLYouTubeVideoElement HTMLVimeoVideoElement HTMLSoundCloudAudioElement HTMLNullVideoElement".split(" ");if(r){j=typeof j==="string"?[j]:j;i=0;for(E=j.length;i<E;i++){v=j[i];for(q=0;q<H.length;q++)if((x=
74
+ p[H[q]])&&x._canPlaySrc(v)==="probably"){y=x(r);k=p(y,k);setTimeout(function(){y.src=v},0);return k}for(var B in p.player.registry)if(p.player.registry.hasOwnProperty(B))if(p.player.registry[B].canPlayType(r.nodeName,v))return p[B](r,v,k)}var K;B=p.guid("popcorn-video-");q=document.createElement("div");q.style.width="100%";q.style.height="100%";if(j.length===1){K=document.createElement("video");K.id=B;r.appendChild(K);setTimeout(function(){var C=document.createElement("div");C.innerHTML=j[0];K.src=
75
+ C.firstChild.nodeValue},0);return p("#"+B,k)}r.appendChild(q);H='<video id="'+B+'" preload=auto autobuffer>';i=0;for(E=j.length;i<E;i++)H+='<source src="'+j[i]+'">';H+="</video>";q.innerHTML=H;k&&k.events&&k.events.error&&r.addEventListener("error",k.events.error,false);return p("#"+B,k)}else p.error("Specified target `"+i+"` was not found.")}})(Popcorn);
76
+ (function(p,h){var i=function(j,k){return typeof k==="string"&&h.HTMLYouTubeVideoElement._canPlaySrc(k)};h.player("youtube",{_canPlayType:i});h.youtube=function(j,k,r){typeof console!=="undefined"&&console.warn&&console.warn("Deprecated player 'youtube'. Please use Popcorn.HTMLYouTubeVideoElement directly.");var v=h.HTMLYouTubeVideoElement(j);j=h(v,r);setTimeout(function(){v.src=k},0);return j};h.youtube.canPlayType=i})(window,Popcorn);
@@ -1,5 +1,5 @@
1
1
  /*
2
- * popcorn.js version 1.3
2
+ * popcorn.js version 1.5.6
3
3
  * http://popcornjs.org
4
4
  *
5
5
  * Copyright 2011, Mozilla Foundation
@@ -78,6 +78,22 @@
78
78
  })( obj );
79
79
  },
80
80
 
81
+ Abstract = {
82
+ // [[Put]] props from dictionary onto |this|
83
+ // MUST BE CALLED FROM WITHIN A CONSTRUCTOR:
84
+ // Abstract.put.call( this, dictionary );
85
+ put: function( dictionary ) {
86
+ // For each own property of src, let key be the property key
87
+ // and desc be the property descriptor of the property.
88
+ for ( var key in dictionary ) {
89
+ if ( dictionary.hasOwnProperty( key ) ) {
90
+ this[ key ] = dictionary[ key ];
91
+ }
92
+ }
93
+ }
94
+ },
95
+
96
+
81
97
  // Declare constructor
82
98
  // Returns an instance object.
83
99
  Popcorn = function( entity, options ) {
@@ -86,7 +102,7 @@
86
102
  };
87
103
 
88
104
  // Popcorn API version, automatically inserted via build system.
89
- Popcorn.version = "1.3";
105
+ Popcorn.version = "1.5.6";
90
106
 
91
107
  // Boolean flag allowing a client to determine if Popcorn can be supported
92
108
  Popcorn.isSupported = true;
@@ -165,7 +181,7 @@
165
181
  // Create an audio or video element property reference
166
182
  this[ nodeName ] = this.media;
167
183
 
168
- this.options = options || {};
184
+ this.options = Popcorn.extend( {}, options ) || {};
169
185
 
170
186
  // Resolve custom ID or default prefixed ID
171
187
  this.id = this.options.id || Popcorn.guid( nodeName );
@@ -208,21 +224,7 @@
208
224
  trackRefs: {},
209
225
 
210
226
  // Playback track event queues
211
- trackEvents: {
212
- byStart: [{
213
-
214
- start: -1,
215
- end: -1
216
- }],
217
- byEnd: [{
218
- start: -1,
219
- end: -1
220
- }],
221
- animating: [],
222
- startIndex: 0,
223
- endIndex: 0,
224
- previousUpdateTime: -1
225
- }
227
+ trackEvents: new TrackEvents( this )
226
228
  };
227
229
 
228
230
  // Register new instance
@@ -241,7 +243,7 @@
241
243
  self.media.currentTime = 0;
242
244
  }
243
245
 
244
- self.media.removeEventListener( "loadeddata", isReady, false );
246
+ self.media.removeEventListener( "loadedmetadata", isReady, false );
245
247
 
246
248
  var duration, videoDurationPlus,
247
249
  runningPlugins, runningPlugin, rpLength, rpNatives;
@@ -258,6 +260,50 @@
258
260
  end: videoDurationPlus
259
261
  });
260
262
 
263
+ if ( !self.isDestroyed ) {
264
+ self.data.durationChange = function() {
265
+ var newDuration = self.media.duration,
266
+ newDurationPlus = newDuration + 1,
267
+ byStart = self.data.trackEvents.byStart,
268
+ byEnd = self.data.trackEvents.byEnd;
269
+
270
+ // Remove old padding events
271
+ byStart.pop();
272
+ byEnd.pop();
273
+
274
+ // Remove any internal tracking of events that have end times greater than duration
275
+ // otherwise their end events will never be hit.
276
+ for ( var k = byEnd.length - 1; k > 0; k-- ) {
277
+ if ( byEnd[ k ].end > newDuration ) {
278
+ self.removeTrackEvent( byEnd[ k ]._id );
279
+ }
280
+ }
281
+
282
+ // Remove any internal tracking of events that have end times greater than duration
283
+ // otherwise their end events will never be hit.
284
+ for ( var i = 0; i < byStart.length; i++ ) {
285
+ if ( byStart[ i ].end > newDuration ) {
286
+ self.removeTrackEvent( byStart[ i ]._id );
287
+ }
288
+ }
289
+
290
+ // References to byEnd/byStart are reset, so accessing it this way is
291
+ // forced upon us.
292
+ self.data.trackEvents.byEnd.push({
293
+ start: newDurationPlus,
294
+ end: newDurationPlus
295
+ });
296
+
297
+ self.data.trackEvents.byStart.push({
298
+ start: newDurationPlus,
299
+ end: newDurationPlus
300
+ });
301
+ };
302
+
303
+ // Listen for duration changes and adjust internal tracking of event timings
304
+ self.media.addEventListener( "durationchange", self.data.durationChange, false );
305
+ }
306
+
261
307
  if ( self.options.frameAnimation ) {
262
308
 
263
309
  // if Popcorn is created with frameAnimation option set to true,
@@ -306,19 +352,29 @@
306
352
  }
307
353
  };
308
354
 
309
- Object.defineProperty( this, "error", {
310
- get: function() {
311
-
312
- return self.media.error;
313
- }
314
- });
355
+ self.media.addEventListener( "error", function() {
356
+ self.error = self.media.error;
357
+ }, false );
315
358
 
316
- if ( self.media.readyState >= 2 ) {
359
+ // http://www.whatwg.org/specs/web-apps/current-work/#dom-media-readystate
360
+ //
361
+ // If media is in readyState (rS) >= 1, we know the media's duration,
362
+ // which is required before running the isReady function.
363
+ // If rS is 0, attach a listener for "loadedmetadata",
364
+ // ( Which indicates that the media has moved from rS 0 to 1 )
365
+ //
366
+ // This has been changed from a check for rS 2 because
367
+ // in certain conditions, Firefox can enter this code after dropping
368
+ // to rS 1 from a higher state such as 2 or 3. This caused a "loadeddata"
369
+ // listener to be attached to the media object, an event that had
370
+ // already triggered and would not trigger again. This left Popcorn with an
371
+ // instance that could never start a timeUpdate loop.
372
+ if ( self.media.readyState >= 1 ) {
317
373
 
318
374
  isReady();
319
375
  } else {
320
376
 
321
- self.media.addEventListener( "loadeddata", isReady, false );
377
+ self.media.addEventListener( "loadedmetadata", isReady, false );
322
378
  }
323
379
 
324
380
  return this;
@@ -420,6 +476,10 @@
420
476
 
421
477
  position: function( elem ) {
422
478
 
479
+ if ( !elem.parentNode ) {
480
+ return null;
481
+ }
482
+
423
483
  var clientRect = elem.getBoundingClientRect(),
424
484
  bounds = {},
425
485
  doc = elem.ownerDocument,
@@ -448,14 +508,26 @@
448
508
 
449
509
  disable: function( instance, plugin ) {
450
510
 
451
- if ( !instance.data.disabled[ plugin ] ) {
511
+ if ( instance.data.disabled[ plugin ] ) {
512
+ return;
513
+ }
514
+
515
+ instance.data.disabled[ plugin ] = true;
452
516
 
453
- instance.data.disabled[ plugin ] = true;
517
+ if ( plugin in Popcorn.registryByName &&
518
+ instance.data.running[ plugin ] ) {
454
519
 
455
520
  for ( var i = instance.data.running[ plugin ].length - 1, event; i >= 0; i-- ) {
456
521
 
457
522
  event = instance.data.running[ plugin ][ i ];
458
523
  event._natives.end.call( instance, null, event );
524
+
525
+ instance.emit( "trackend",
526
+ Popcorn.extend({}, event, {
527
+ plugin: event.type,
528
+ type: "trackend"
529
+ })
530
+ );
459
531
  }
460
532
  }
461
533
 
@@ -463,14 +535,27 @@
463
535
  },
464
536
  enable: function( instance, plugin ) {
465
537
 
466
- if ( instance.data.disabled[ plugin ] ) {
538
+ if ( !instance.data.disabled[ plugin ] ) {
539
+ return;
540
+ }
541
+
542
+ instance.data.disabled[ plugin ] = false;
467
543
 
468
- instance.data.disabled[ plugin ] = false;
544
+ if ( plugin in Popcorn.registryByName &&
545
+ instance.data.running[ plugin ] ) {
469
546
 
470
547
  for ( var i = instance.data.running[ plugin ].length - 1, event; i >= 0; i-- ) {
471
548
 
472
549
  event = instance.data.running[ plugin ][ i ];
473
550
  event._natives.start.call( instance, null, event );
551
+
552
+ instance.emit( "trackstart",
553
+ Popcorn.extend({}, event, {
554
+ plugin: event.type,
555
+ type: "trackstart",
556
+ track: event
557
+ })
558
+ );
474
559
  }
475
560
  }
476
561
 
@@ -503,6 +588,8 @@
503
588
  instance.data.timeUpdate && instance.media.removeEventListener( "timeupdate", instance.data.timeUpdate, false );
504
589
  instance.isDestroyed = true;
505
590
  }
591
+
592
+ Popcorn.instances.splice( Popcorn.instances.indexOf( instance ), 1 );
506
593
  }
507
594
  });
508
595
 
@@ -584,7 +671,8 @@
584
671
  // Attach an event to a single point in time
585
672
  exec: function( id, time, fn ) {
586
673
  var length = arguments.length,
587
- trackEvent, sec;
674
+ eventType = "trackadded",
675
+ trackEvent, sec, options;
588
676
 
589
677
  // Check if first could possibly be a SMPTE string
590
678
  // p.cue( "smpte string", fn );
@@ -619,11 +707,19 @@
619
707
 
620
708
  } else {
621
709
 
622
- // Get the trackEvent that matches the given id.
710
+ // Get the TrackEvent that matches the given id.
623
711
  trackEvent = this.getTrackEvent( id );
624
712
 
625
713
  if ( trackEvent ) {
626
714
 
715
+ // remove existing cue so a new one can be added via trackEvents.add
716
+ this.data.trackEvents.remove( id );
717
+ TrackEvent.end( this, trackEvent );
718
+ // Update track event references
719
+ Popcorn.removeTrackEvent.ref( this, id );
720
+
721
+ eventType = "cuechange";
722
+
627
723
  // p.cue( "my-id", 12 );
628
724
  // p.cue( "my-id", function() { ... });
629
725
  if ( typeof id === "string" && length === 2 ) {
@@ -631,7 +727,7 @@
631
727
  // p.cue( "my-id", 12 );
632
728
  // The path will update the cue time.
633
729
  if ( typeof time === "number" ) {
634
- // Re-use existing trackEvent start callback
730
+ // Re-use existing TrackEvent start callback
635
731
  fn = trackEvent._natives.start;
636
732
  }
637
733
 
@@ -639,7 +735,7 @@
639
735
  // The path will update the cue function
640
736
  if ( typeof time === "function" ) {
641
737
  fn = time;
642
- // Re-use existing trackEvent start time
738
+ // Re-use existing TrackEvent start time
643
739
  time = trackEvent.start;
644
740
  }
645
741
  }
@@ -657,8 +753,9 @@
657
753
  }
658
754
 
659
755
  // p.cue( "b", 11 );
756
+ // p.cue( "b", 11, function() {} );
660
757
  if ( typeof time === "number" ) {
661
- fn = Popcorn.nop();
758
+ fn = fn || Popcorn.nop();
662
759
  }
663
760
 
664
761
  // p.cue( "c", function() {});
@@ -671,9 +768,7 @@
671
768
  }
672
769
  }
673
770
 
674
- // Creating a one second track event with an empty end
675
- // Or update an existing track event with new values
676
- Popcorn.addTrackEvent( this, {
771
+ options = {
677
772
  id: id,
678
773
  start: time,
679
774
  end: time + 1,
@@ -683,7 +778,42 @@
683
778
  end: Popcorn.nop,
684
779
  type: "cue"
685
780
  }
686
- });
781
+ };
782
+
783
+ if ( trackEvent ) {
784
+ options = Popcorn.extend( trackEvent, options );
785
+ }
786
+
787
+ if ( eventType === "cuechange" ) {
788
+
789
+ // Supports user defined track event id
790
+ options._id = options.id || options._id || Popcorn.guid( options._natives.type );
791
+
792
+ this.data.trackEvents.add( options );
793
+ TrackEvent.start( this, options );
794
+
795
+ this.timeUpdate( this, null, true );
796
+
797
+ // Store references to user added trackevents in ref table
798
+ Popcorn.addTrackEvent.ref( this, options );
799
+
800
+ this.emit( eventType, Popcorn.extend({}, options, {
801
+ id: id,
802
+ type: eventType,
803
+ previousValue: {
804
+ time: trackEvent.start,
805
+ fn: trackEvent._natives.start
806
+ },
807
+ currentValue: {
808
+ time: time,
809
+ fn: fn || Popcorn.nop
810
+ },
811
+ track: trackEvent
812
+ }));
813
+ } else {
814
+ // Creating a one second track event with an empty end
815
+ Popcorn.addTrackEvent( this, options );
816
+ }
687
817
 
688
818
  return this;
689
819
  },
@@ -829,15 +959,14 @@
829
959
  // Defines all Event handling static functions
830
960
  fn: {
831
961
  trigger: function( type, data ) {
962
+ var eventInterface, evt, clonedEvents,
963
+ events = this.data.events[ type ];
832
964
 
833
- var eventInterface, evt;
834
965
  // setup checks for custom event system
835
- if ( this.data.events[ type ] && Popcorn.sizeOf( this.data.events[ type ] ) ) {
836
-
966
+ if ( events ) {
837
967
  eventInterface = Popcorn.events.getInterface( type );
838
968
 
839
969
  if ( eventInterface ) {
840
-
841
970
  evt = document.createEvent( eventInterface );
842
971
  evt.initEvent( type, true, true, global, 1 );
843
972
 
@@ -846,33 +975,38 @@
846
975
  return this;
847
976
  }
848
977
 
849
- // Custom events
850
- Popcorn.forEach( this.data.events[ type ], function( obj, key ) {
851
-
852
- obj.call( this, data );
853
-
854
- }, this );
978
+ // clone events in case callbacks remove callbacks themselves
979
+ clonedEvents = events.slice();
855
980
 
981
+ // iterate through all callbacks
982
+ while ( clonedEvents.length ) {
983
+ clonedEvents.shift().call( this, data );
984
+ }
856
985
  }
857
986
 
858
987
  return this;
859
988
  },
860
989
  listen: function( type, fn ) {
861
-
862
990
  var self = this,
863
991
  hasEvents = true,
864
992
  eventHook = Popcorn.events.hooks[ type ],
865
993
  origType = type,
994
+ clonedEvents,
866
995
  tmp;
867
996
 
997
+ if ( typeof fn !== "function" ) {
998
+ throw new Error( "Popcorn.js Error: Listener is not a function" );
999
+ }
1000
+
1001
+ // Setup event registry entry
868
1002
  if ( !this.data.events[ type ] ) {
869
- this.data.events[ type ] = {};
1003
+ this.data.events[ type ] = [];
1004
+ // Toggle if the previous assumption was untrue
870
1005
  hasEvents = false;
871
1006
  }
872
1007
 
873
1008
  // Check and setup event hooks
874
1009
  if ( eventHook ) {
875
-
876
1010
  // Execute hook add method if defined
877
1011
  if ( eventHook.add ) {
878
1012
  eventHook.add.call( this, {}, fn );
@@ -897,39 +1031,61 @@
897
1031
 
898
1032
  // Setup event registry entry
899
1033
  if ( !this.data.events[ type ] ) {
900
- this.data.events[ type ] = {};
1034
+ this.data.events[ type ] = [];
901
1035
  // Toggle if the previous assumption was untrue
902
1036
  hasEvents = false;
903
1037
  }
904
1038
  }
905
1039
 
906
1040
  // Register event and handler
907
- this.data.events[ type ][ fn.name || ( fn.toString() + Popcorn.guid() ) ] = fn;
1041
+ this.data.events[ type ].push( fn );
908
1042
 
909
1043
  // only attach one event of any type
910
1044
  if ( !hasEvents && Popcorn.events.all.indexOf( type ) > -1 ) {
911
-
912
1045
  this.media.addEventListener( type, function( event ) {
1046
+ if ( self.data.events[ type ] ) {
1047
+ // clone events in case callbacks remove callbacks themselves
1048
+ clonedEvents = self.data.events[ type ].slice();
913
1049
 
914
- Popcorn.forEach( self.data.events[ type ], function( obj, key ) {
915
- if ( typeof obj === "function" ) {
916
- obj.call( self, event );
1050
+ // iterate through all callbacks
1051
+ while ( clonedEvents.length ) {
1052
+ clonedEvents.shift().call( self, event );
917
1053
  }
918
- });
919
-
920
- }, false);
1054
+ }
1055
+ }, false );
921
1056
  }
922
1057
  return this;
923
1058
  },
924
1059
  unlisten: function( type, fn ) {
1060
+ var ind,
1061
+ events = this.data.events[ type ];
925
1062
 
926
- if ( this.data.events[ type ] && this.data.events[ type ][ fn ] ) {
1063
+ if ( !events ) {
1064
+ return; // no listeners = nothing to do
1065
+ }
927
1066
 
928
- delete this.data.events[ type ][ fn ];
1067
+ if ( typeof fn === "string" ) {
1068
+ // legacy support for string-based removal -- not recommended
1069
+ for ( var i = 0; i < events.length; i++ ) {
1070
+ if ( events[ i ].name === fn ) {
1071
+ // decrement i because array length just got smaller
1072
+ events.splice( i--, 1 );
1073
+ }
1074
+ }
1075
+
1076
+ return this;
1077
+ } else if ( typeof fn === "function" ) {
1078
+ while( ind !== -1 ) {
1079
+ ind = events.indexOf( fn );
1080
+ if ( ind !== -1 ) {
1081
+ events.splice( ind, 1 );
1082
+ }
1083
+ }
929
1084
 
930
1085
  return this;
931
1086
  }
932
1087
 
1088
+ // if we got to this point, we are deleting all functions of this type
933
1089
  this.data.events[ type ] = null;
934
1090
 
935
1091
  return this;
@@ -944,7 +1100,10 @@
944
1100
 
945
1101
  if ( this.media.readyState ) {
946
1102
 
947
- callback.call( this, event );
1103
+ // always call canplayall asynchronously
1104
+ setTimeout(function() {
1105
+ callback.call( this, event );
1106
+ }.bind(this), 0 );
948
1107
 
949
1108
  state = true;
950
1109
  }
@@ -973,50 +1132,127 @@
973
1132
  Popcorn.p[ key[ 0 ] ] = Popcorn.p[ key[ 1 ] ] = Popcorn.events.fn[ key[ 0 ] ];
974
1133
  });
975
1134
 
976
- // Internal Only - Adds track events to the instance object
977
- Popcorn.addTrackEvent = function( obj, track ) {
978
- var trackEvent, isUpdate, eventType;
1135
+ // Internal Only - construct simple "TrackEvent"
1136
+ // data type objects
1137
+ function TrackEvent( track ) {
1138
+ Abstract.put.call( this, track );
1139
+ }
979
1140
 
980
- // Do a lookup for existing trackevents with this id
981
- if ( track.id ) {
982
- trackEvent = obj.getTrackEvent( track.id );
983
- }
1141
+ // Determine if a TrackEvent's "start" and "trackstart" must be called.
1142
+ TrackEvent.start = function( instance, track ) {
984
1143
 
985
- // If a track event by this id currently exists, modify it
986
- if ( trackEvent ) {
987
- isUpdate = true;
988
- // Create a new object with the existing trackEvent
989
- // Extend with new track properties
990
- track = Popcorn.extend( {}, trackEvent, track );
1144
+ if ( track.end > instance.media.currentTime &&
1145
+ track.start <= instance.media.currentTime && !track._running ) {
991
1146
 
992
- // Remove the existing track from the instance
993
- obj.removeTrackEvent( track.id );
994
- }
1147
+ track._running = true;
1148
+ instance.data.running[ track._natives.type ].push( track );
995
1149
 
996
- // Determine if this track has default options set for it
997
- // If so, apply them to the track object
998
- if ( track && track._natives && track._natives.type &&
999
- ( obj.options.defaults && obj.options.defaults[ track._natives.type ] ) ) {
1150
+ if ( !instance.data.disabled[ track._natives.type ] ) {
1151
+
1152
+ track._natives.start.call( instance, null, track );
1000
1153
 
1001
- track = Popcorn.extend( {}, obj.options.defaults[ track._natives.type ], track );
1154
+ instance.emit( "trackstart",
1155
+ Popcorn.extend( {}, track, {
1156
+ plugin: track._natives.type,
1157
+ type: "trackstart",
1158
+ track: track
1159
+ })
1160
+ );
1161
+ }
1002
1162
  }
1163
+ };
1003
1164
 
1004
- if ( track._natives ) {
1005
- // Supports user defined track event id
1006
- track._id = track.id || track._id || Popcorn.guid( track._natives.type );
1165
+ // Determine if a TrackEvent's "end" and "trackend" must be called.
1166
+ TrackEvent.end = function( instance, track ) {
1167
+
1168
+ var runningPlugins;
1169
+
1170
+ if ( ( track.end <= instance.media.currentTime ||
1171
+ track.start > instance.media.currentTime ) && track._running ) {
1172
+
1173
+ runningPlugins = instance.data.running[ track._natives.type ];
1007
1174
 
1008
- // Push track event ids into the history
1009
- obj.data.history.push( track._id );
1175
+ track._running = false;
1176
+ runningPlugins.splice( runningPlugins.indexOf( track ), 1 );
1177
+
1178
+ if ( !instance.data.disabled[ track._natives.type ] ) {
1179
+
1180
+ track._natives.end.call( instance, null, track );
1181
+
1182
+ instance.emit( "trackend",
1183
+ Popcorn.extend( {}, track, {
1184
+ plugin: track._natives.type,
1185
+ type: "trackend",
1186
+ track: track
1187
+ })
1188
+ );
1189
+ }
1010
1190
  }
1191
+ };
1192
+
1193
+ // Internal Only - construct "TrackEvents"
1194
+ // data type objects that are used by the Popcorn
1195
+ // instance, stored at p.data.trackEvents
1196
+ function TrackEvents( parent ) {
1197
+ this.parent = parent;
1198
+
1199
+ this.byStart = [{
1200
+ start: -1,
1201
+ end: -1
1202
+ }];
1203
+
1204
+ this.byEnd = [{
1205
+ start: -1,
1206
+ end: -1
1207
+ }];
1208
+ this.animating = [];
1209
+ this.startIndex = 0;
1210
+ this.endIndex = 0;
1211
+ this.previousUpdateTime = -1;
1212
+
1213
+ this.count = 1;
1214
+ }
1215
+
1216
+ function isMatch( obj, key, value ) {
1217
+ return obj[ key ] && obj[ key ] === value;
1218
+ }
1219
+
1220
+ TrackEvents.prototype.where = function( params ) {
1221
+ return ( this.parent.getTrackEvents() || [] ).filter(function( event ) {
1222
+ var key, value;
1223
+
1224
+ // If no explicit params, match all TrackEvents
1225
+ if ( !params ) {
1226
+ return true;
1227
+ }
1011
1228
 
1012
- track.start = Popcorn.util.toSeconds( track.start, obj.options.framerate );
1013
- track.end = Popcorn.util.toSeconds( track.end, obj.options.framerate );
1229
+ // Filter keys in params against both the top level properties
1230
+ // and the _natives properties
1231
+ for ( key in params ) {
1232
+ value = params[ key ];
1233
+ if ( isMatch( event, key, value ) || isMatch( event._natives, key, value ) ) {
1234
+ return true;
1235
+ }
1236
+ }
1237
+ return false;
1238
+ });
1239
+ };
1240
+
1241
+ TrackEvents.prototype.add = function( track ) {
1014
1242
 
1015
1243
  // Store this definition in an array sorted by times
1016
- var byStart = obj.data.trackEvents.byStart,
1017
- byEnd = obj.data.trackEvents.byEnd,
1244
+ var byStart = this.byStart,
1245
+ byEnd = this.byEnd,
1018
1246
  startIndex, endIndex;
1019
1247
 
1248
+ // Push track event ids into the history
1249
+ if ( track && track._id ) {
1250
+ this.parent.data.history.push( track._id );
1251
+ }
1252
+
1253
+ track.start = Popcorn.util.toSeconds( track.start, this.parent.options.framerate );
1254
+ track.end = Popcorn.util.toSeconds( track.end, this.parent.options.framerate );
1255
+
1020
1256
  for ( startIndex = byStart.length - 1; startIndex >= 0; startIndex-- ) {
1021
1257
 
1022
1258
  if ( track.start >= byStart[ startIndex ].start ) {
@@ -1033,89 +1269,54 @@
1033
1269
  }
1034
1270
  }
1035
1271
 
1036
- // Display track event immediately if it's enabled and current
1037
- if ( track.end > obj.media.currentTime &&
1038
- track.start <= obj.media.currentTime ) {
1039
-
1040
- track._running = true;
1041
- obj.data.running[ track._natives.type ].push( track );
1042
-
1043
- if ( !obj.data.disabled[ track._natives.type ] ) {
1044
-
1045
- track._natives.start.call( obj, null, track );
1046
- }
1047
- }
1048
-
1049
1272
  // update startIndex and endIndex
1050
- if ( startIndex <= obj.data.trackEvents.startIndex &&
1051
- track.start <= obj.data.trackEvents.previousUpdateTime ) {
1273
+ if ( startIndex <= this.parent.data.trackEvents.startIndex &&
1274
+ track.start <= this.parent.data.trackEvents.previousUpdateTime ) {
1052
1275
 
1053
- obj.data.trackEvents.startIndex++;
1276
+ this.parent.data.trackEvents.startIndex++;
1054
1277
  }
1055
1278
 
1056
- if ( endIndex <= obj.data.trackEvents.endIndex &&
1057
- track.end < obj.data.trackEvents.previousUpdateTime ) {
1279
+ if ( endIndex <= this.parent.data.trackEvents.endIndex &&
1280
+ track.end < this.parent.data.trackEvents.previousUpdateTime ) {
1058
1281
 
1059
- obj.data.trackEvents.endIndex++;
1282
+ this.parent.data.trackEvents.endIndex++;
1060
1283
  }
1061
1284
 
1062
- this.timeUpdate( obj, null, true );
1063
-
1064
- // Store references to user added trackevents in ref table
1065
- if ( track._id ) {
1066
- Popcorn.addTrackEvent.ref( obj, track );
1067
- }
1285
+ this.count++;
1068
1286
 
1069
- // If the call to addTrackEvent was an update/modify call, fire an event
1070
- if ( isUpdate ) {
1287
+ };
1071
1288
 
1072
- // Determine appropriate event type to trigger
1073
- // they are identical in function, but the naming
1074
- // adds some level of intuition for the end developer
1075
- // to rely on
1076
- if ( track._natives.type === "cue" ) {
1077
- eventType = "cuechange";
1078
- } else {
1079
- eventType = "trackchange";
1080
- }
1289
+ TrackEvents.prototype.remove = function( removeId, state ) {
1081
1290
 
1082
- // Fire an event with change information
1083
- obj.emit( eventType, {
1084
- id: track.id,
1085
- previousValue: {
1086
- time: trackEvent.start,
1087
- fn: trackEvent._natives.start
1088
- },
1089
- currentValue: {
1090
- time: track.start,
1091
- fn: track._natives.start
1092
- }
1093
- });
1291
+ if ( removeId instanceof TrackEvent ) {
1292
+ removeId = removeId.id;
1094
1293
  }
1095
- };
1096
1294
 
1097
- // Internal Only - Adds track event references to the instance object's trackRefs hash table
1098
- Popcorn.addTrackEvent.ref = function( obj, track ) {
1099
- obj.data.trackRefs[ track._id ] = track;
1100
-
1101
- return obj;
1102
- };
1295
+ if ( typeof removeId === "object" ) {
1296
+ // Filter by key=val and remove all matching TrackEvents
1297
+ this.where( removeId ).forEach(function( event ) {
1298
+ // |this| refers to the calling Popcorn "parent" instance
1299
+ this.removeTrackEvent( event._id );
1300
+ }, this.parent );
1103
1301
 
1104
- Popcorn.removeTrackEvent = function( obj, removeId ) {
1302
+ return this;
1303
+ }
1105
1304
 
1106
- var start, end, animate,
1107
- historyLen = obj.data.history.length,
1108
- length = obj.data.trackEvents.byStart.length,
1305
+ var start, end, animate, historyLen, track,
1306
+ length = this.byStart.length,
1109
1307
  index = 0,
1110
1308
  indexWasAt = 0,
1111
1309
  byStart = [],
1112
1310
  byEnd = [],
1113
1311
  animating = [],
1114
- history = [];
1312
+ history = [],
1313
+ comparable = {};
1314
+
1315
+ state = state || {};
1115
1316
 
1116
1317
  while ( --length > -1 ) {
1117
- start = obj.data.trackEvents.byStart[ index ];
1118
- end = obj.data.trackEvents.byEnd[ index ];
1318
+ start = this.byStart[ index ];
1319
+ end = this.byEnd[ index ];
1119
1320
 
1120
1321
  // Padding events will not have _id properties.
1121
1322
  // These should be safely pushed onto the front and back of the
@@ -1142,11 +1343,8 @@
1142
1343
  if ( start._id === removeId ) {
1143
1344
  indexWasAt = index;
1144
1345
 
1145
- // If a _teardown function was defined,
1146
- // enforce for track event removals
1147
- if ( start._natives._teardown ) {
1148
- start._natives._teardown.call( obj, start );
1149
- }
1346
+ // cache the track event being removed
1347
+ track = start;
1150
1348
  }
1151
1349
  }
1152
1350
  // Increment the track index
@@ -1157,12 +1355,12 @@
1157
1355
  // if animating track events should also be filtered for removal.
1158
1356
  // Reset index below to be used by the reverse while as an
1159
1357
  // incrementing counter
1160
- length = obj.data.trackEvents.animating.length;
1358
+ length = this.animating.length;
1161
1359
  index = 0;
1162
1360
 
1163
1361
  if ( length ) {
1164
1362
  while ( --length > -1 ) {
1165
- animate = obj.data.trackEvents.animating[ index ];
1363
+ animate = this.animating[ index ];
1166
1364
 
1167
1365
  // Padding events will not have _id properties.
1168
1366
  // These should be safely pushed onto the front and back of the
@@ -1181,29 +1379,139 @@
1181
1379
  }
1182
1380
 
1183
1381
  // Update
1184
- if ( indexWasAt <= obj.data.trackEvents.startIndex ) {
1185
- obj.data.trackEvents.startIndex--;
1382
+ if ( indexWasAt <= this.startIndex ) {
1383
+ this.startIndex--;
1186
1384
  }
1187
1385
 
1188
- if ( indexWasAt <= obj.data.trackEvents.endIndex ) {
1189
- obj.data.trackEvents.endIndex--;
1386
+ if ( indexWasAt <= this.endIndex ) {
1387
+ this.endIndex--;
1190
1388
  }
1191
1389
 
1192
- obj.data.trackEvents.byStart = byStart;
1193
- obj.data.trackEvents.byEnd = byEnd;
1194
- obj.data.trackEvents.animating = animating;
1390
+ this.byStart = byStart;
1391
+ this.byEnd = byEnd;
1392
+ this.animating = animating;
1393
+ this.count--;
1394
+
1395
+ historyLen = this.parent.data.history.length;
1195
1396
 
1196
1397
  for ( var i = 0; i < historyLen; i++ ) {
1197
- if ( obj.data.history[ i ] !== removeId ) {
1198
- history.push( obj.data.history[ i ] );
1398
+ if ( this.parent.data.history[ i ] !== removeId ) {
1399
+ history.push( this.parent.data.history[ i ] );
1199
1400
  }
1200
1401
  }
1201
1402
 
1202
1403
  // Update ordered history array
1203
- obj.data.history = history;
1404
+ this.parent.data.history = history;
1405
+
1406
+ };
1407
+
1408
+ // Helper function used to retrieve old values of properties that
1409
+ // are provided for update.
1410
+ function getPreviousProperties( oldOptions, newOptions ) {
1411
+ var matchProps = {};
1412
+
1413
+ for ( var prop in oldOptions ) {
1414
+ if ( hasOwn.call( newOptions, prop ) && hasOwn.call( oldOptions, prop ) ) {
1415
+ matchProps[ prop ] = oldOptions[ prop ];
1416
+ }
1417
+ }
1418
+
1419
+ return matchProps;
1420
+ }
1421
+
1422
+ // Internal Only - Adds track events to the instance object
1423
+ Popcorn.addTrackEvent = function( obj, track ) {
1424
+ var temp;
1425
+
1426
+ if ( track instanceof TrackEvent ) {
1427
+ return;
1428
+ }
1429
+
1430
+ track = new TrackEvent( track );
1431
+
1432
+ // Determine if this track has default options set for it
1433
+ // If so, apply them to the track object
1434
+ if ( track && track._natives && track._natives.type &&
1435
+ ( obj.options.defaults && obj.options.defaults[ track._natives.type ] ) ) {
1436
+
1437
+ // To ensure that the TrackEvent Invariant Policy is enforced,
1438
+ // First, copy the properties of the newly created track event event
1439
+ // to a temporary holder
1440
+ temp = Popcorn.extend( {}, track );
1441
+
1442
+ // Next, copy the default onto the newly created trackevent, followed by the
1443
+ // temporary holder.
1444
+ Popcorn.extend( track, obj.options.defaults[ track._natives.type ], temp );
1445
+ }
1446
+
1447
+ if ( track._natives ) {
1448
+ // Supports user defined track event id
1449
+ track._id = track.id || track._id || Popcorn.guid( track._natives.type );
1450
+
1451
+ // Trigger _setup method if exists
1452
+ if ( track._natives._setup ) {
1453
+
1454
+ track._natives._setup.call( obj, track );
1455
+
1456
+ obj.emit( "tracksetup", Popcorn.extend( {}, track, {
1457
+ plugin: track._natives.type,
1458
+ type: "tracksetup",
1459
+ track: track
1460
+ }));
1461
+ }
1462
+ }
1463
+
1464
+ obj.data.trackEvents.add( track );
1465
+ TrackEvent.start( obj, track );
1466
+
1467
+ this.timeUpdate( obj, null, true );
1468
+
1469
+ // Store references to user added trackevents in ref table
1470
+ if ( track._id ) {
1471
+ Popcorn.addTrackEvent.ref( obj, track );
1472
+ }
1473
+
1474
+ obj.emit( "trackadded", Popcorn.extend({}, track,
1475
+ track._natives ? { plugin: track._natives.type } : {}, {
1476
+ type: "trackadded",
1477
+ track: track
1478
+ }));
1479
+ };
1480
+
1481
+ // Internal Only - Adds track event references to the instance object's trackRefs hash table
1482
+ Popcorn.addTrackEvent.ref = function( obj, track ) {
1483
+ obj.data.trackRefs[ track._id ] = track;
1484
+
1485
+ return obj;
1486
+ };
1487
+
1488
+ Popcorn.removeTrackEvent = function( obj, removeId ) {
1489
+ var track = obj.getTrackEvent( removeId );
1490
+
1491
+ if ( !track ) {
1492
+ return;
1493
+ }
1494
+
1495
+ // If a _teardown function was defined,
1496
+ // enforce for track event removals
1497
+ if ( track._natives._teardown ) {
1498
+ track._natives._teardown.call( obj, track );
1499
+ }
1500
+
1501
+ obj.data.trackEvents.remove( removeId );
1204
1502
 
1205
1503
  // Update track event references
1206
1504
  Popcorn.removeTrackEvent.ref( obj, removeId );
1505
+
1506
+ if ( track._natives ) {
1507
+
1508
+ // Fire a trackremoved event
1509
+ obj.emit( "trackremoved", Popcorn.extend({}, track, {
1510
+ plugin: track._natives.type,
1511
+ type: "trackremoved",
1512
+ track: track
1513
+ }));
1514
+ }
1207
1515
  };
1208
1516
 
1209
1517
  // Internal Only - Removes track event references from instance object's trackRefs hash table
@@ -1253,7 +1561,6 @@
1253
1561
  };
1254
1562
 
1255
1563
  Popcorn.timeUpdate = function( obj, event ) {
1256
-
1257
1564
  var currentTime = obj.media.currentTime,
1258
1565
  previousTime = obj.data.trackEvents.previousUpdateTime,
1259
1566
  tracks = obj.data.trackEvents,
@@ -1294,7 +1601,8 @@
1294
1601
  obj.emit( trackend,
1295
1602
  Popcorn.extend({}, byEnd, {
1296
1603
  plugin: type,
1297
- type: trackend
1604
+ type: trackend,
1605
+ track: byEnd
1298
1606
  })
1299
1607
  );
1300
1608
  }
@@ -1313,12 +1621,10 @@
1313
1621
  byStart = tracks.byStart[ start ];
1314
1622
  natives = byStart._natives;
1315
1623
  type = natives && natives.type;
1316
-
1317
1624
  // If plugin does not exist on this instance, remove it
1318
1625
  if ( !natives ||
1319
1626
  ( !!registryByName[ type ] ||
1320
1627
  !!obj[ type ] ) ) {
1321
-
1322
1628
  if ( byStart.end > currentTime &&
1323
1629
  byStart._running === false ) {
1324
1630
 
@@ -1332,7 +1638,8 @@
1332
1638
  obj.emit( trackstart,
1333
1639
  Popcorn.extend({}, byStart, {
1334
1640
  plugin: type,
1335
- type: trackstart
1641
+ type: trackstart,
1642
+ track: byStart
1336
1643
  })
1337
1644
  );
1338
1645
  }
@@ -1372,7 +1679,8 @@
1372
1679
  obj.emit( trackend,
1373
1680
  Popcorn.extend({}, byStart, {
1374
1681
  plugin: type,
1375
- type: trackend
1682
+ type: trackend,
1683
+ track: byStart
1376
1684
  })
1377
1685
  );
1378
1686
  }
@@ -1409,7 +1717,8 @@
1409
1717
  obj.emit( trackstart,
1410
1718
  Popcorn.extend({}, byEnd, {
1411
1719
  plugin: type,
1412
- type: trackstart
1720
+ type: trackstart,
1721
+ track: byEnd
1413
1722
  })
1414
1723
  );
1415
1724
  }
@@ -1486,11 +1795,11 @@
1486
1795
 
1487
1796
  // Provides some sugar, but ultimately extends
1488
1797
  // the definition into Popcorn.p
1489
- var reserved = [ "start", "end" ],
1798
+ var isfn = typeof definition === "function",
1799
+ blacklist = [ "start", "end", "type", "manifest" ],
1800
+ methods = [ "_setup", "_teardown", "start", "end", "frame" ],
1490
1801
  plugin = {},
1491
- setup,
1492
- isfn = typeof definition === "function",
1493
- methods = [ "_setup", "_teardown", "start", "end", "frame" ];
1802
+ setup;
1494
1803
 
1495
1804
  // combines calls of two function calls into one
1496
1805
  var combineFn = function( first, second ) {
@@ -1548,7 +1857,7 @@
1548
1857
 
1549
1858
  Popcorn.extend( natives, setup );
1550
1859
 
1551
- options._natives.type = name;
1860
+ options._natives.type = options._natives.plugin = name;
1552
1861
  options._running = false;
1553
1862
 
1554
1863
  natives.start = natives.start || natives[ "in" ];
@@ -1574,12 +1883,37 @@
1574
1883
  args[ 1 ]._running &&
1575
1884
  runningPlugins.splice( runningPlugins.indexOf( options ), 1 ) &&
1576
1885
  natives.end.apply( this, args );
1886
+
1887
+ args[ 1 ]._running = false;
1888
+ this.emit( "trackend",
1889
+ Popcorn.extend( {}, options, {
1890
+ plugin: natives.type,
1891
+ type: "trackend",
1892
+ track: Popcorn.getTrackEvent( this, options.id || options._id )
1893
+ })
1894
+ );
1577
1895
  }, natives._teardown );
1578
1896
 
1897
+ // extend teardown to always trigger trackteardown after teardown
1898
+ natives._teardown = combineFn( natives._teardown, function() {
1899
+
1900
+ this.emit( "trackteardown", Popcorn.extend( {}, options, {
1901
+ plugin: name,
1902
+ type: "trackteardown",
1903
+ track: Popcorn.getTrackEvent( this, options.id || options._id )
1904
+ }));
1905
+ });
1906
+
1579
1907
  // default to an empty string if no effect exists
1580
1908
  // split string into an array of effects
1581
- options.compose = options.compose && options.compose.split( " " ) || [];
1582
- options.effect = options.effect && options.effect.split( " " ) || [];
1909
+ options.compose = options.compose || [];
1910
+ if ( typeof options.compose === "string" ) {
1911
+ options.compose = options.compose.split( " " );
1912
+ }
1913
+ options.effect = options.effect || [];
1914
+ if ( typeof options.effect === "string" ) {
1915
+ options.effect = options.effect.split( " " );
1916
+ }
1583
1917
 
1584
1918
  // join the two arrays together
1585
1919
  options.compose = options.compose.concat( options.effect );
@@ -1636,29 +1970,52 @@
1636
1970
  options.target = manifestOpts && "target" in manifestOpts && manifestOpts.target;
1637
1971
  }
1638
1972
 
1639
- if ( options._natives ) {
1973
+ if ( !options._id && options._natives ) {
1640
1974
  // ensure an initial id is there before setup is called
1641
1975
  options._id = Popcorn.guid( options._natives.type );
1642
1976
  }
1643
1977
 
1644
- // Trigger _setup method if exists
1645
- options._natives._setup && options._natives._setup.call( this, options );
1978
+ if ( options instanceof TrackEvent ) {
1646
1979
 
1647
- // Create new track event for this instance
1648
- Popcorn.addTrackEvent( this, options );
1649
-
1650
- // Future support for plugin event definitions
1651
- // for all of the native events
1652
- Popcorn.forEach( setup, function( callback, type ) {
1980
+ if ( options._natives ) {
1981
+ // Supports user defined track event id
1982
+ options._id = options.id || options._id || Popcorn.guid( options._natives.type );
1653
1983
 
1654
- if ( type !== "type" ) {
1984
+ // Trigger _setup method if exists
1985
+ if ( options._natives._setup ) {
1655
1986
 
1656
- if ( reserved.indexOf( type ) === -1 ) {
1987
+ options._natives._setup.call( this, options );
1657
1988
 
1658
- this.on( type, callback );
1989
+ this.emit( "tracksetup", Popcorn.extend( {}, options, {
1990
+ plugin: options._natives.type,
1991
+ type: "tracksetup",
1992
+ track: options
1993
+ }));
1659
1994
  }
1660
1995
  }
1661
1996
 
1997
+ this.data.trackEvents.add( options );
1998
+ TrackEvent.start( this, options );
1999
+
2000
+ this.timeUpdate( this, null, true );
2001
+
2002
+ // Store references to user added trackevents in ref table
2003
+ if ( options._id ) {
2004
+ Popcorn.addTrackEvent.ref( this, options );
2005
+ }
2006
+ } else {
2007
+ // Create new track event for this instance
2008
+ Popcorn.addTrackEvent( this, options );
2009
+ }
2010
+
2011
+ // Future support for plugin event definitions
2012
+ // for all of the native events
2013
+ Popcorn.forEach( setup, function( callback, type ) {
2014
+ // Don't attempt to create events for certain properties:
2015
+ // "start", "end", "type", "manifest". Fixes #1365
2016
+ if ( blacklist.indexOf( type ) === -1 ) {
2017
+ this.on( type, callback );
2018
+ }
1662
2019
  }, this );
1663
2020
 
1664
2021
  return this;
@@ -1668,7 +2025,7 @@
1668
2025
  // Assign new named definition
1669
2026
  Popcorn.p[ name ] = plugin[ name ] = function( id, options ) {
1670
2027
  var length = arguments.length,
1671
- trackEvent, defaults, mergedSetupOpts;
2028
+ trackEvent, defaults, mergedSetupOpts, previousOpts, newOpts;
1672
2029
 
1673
2030
  // Shift arguments based on use case
1674
2031
  //
@@ -1690,9 +2047,108 @@
1690
2047
  // If the track event does exist, merge the updated properties
1691
2048
  } else {
1692
2049
 
1693
- options = Popcorn.extend( {}, trackEvent, options );
2050
+ newOpts = options;
2051
+ previousOpts = getPreviousProperties( trackEvent, newOpts );
2052
+
2053
+ // Call the plugins defined update method if provided. Allows for
2054
+ // custom defined updating for a track event to be defined by the plugin author
2055
+ if ( trackEvent._natives._update ) {
2056
+
2057
+ this.data.trackEvents.remove( trackEvent );
2058
+
2059
+ // It's safe to say that the intent of Start/End will never change
2060
+ // Update them first before calling update
2061
+ if ( hasOwn.call( options, "start" ) ) {
2062
+ trackEvent.start = options.start;
2063
+ }
2064
+
2065
+ if ( hasOwn.call( options, "end" ) ) {
2066
+ trackEvent.end = options.end;
2067
+ }
2068
+
2069
+ TrackEvent.end( this, trackEvent );
2070
+
2071
+ if ( isfn ) {
2072
+ definition.call( this, trackEvent );
2073
+ }
2074
+
2075
+ trackEvent._natives._update.call( this, trackEvent, options );
2076
+
2077
+ this.data.trackEvents.add( trackEvent );
2078
+ TrackEvent.start( this, trackEvent );
2079
+ } else {
2080
+ // This branch is taken when there is no explicitly defined
2081
+ // _update method for a plugin. Which will occur either explicitly or
2082
+ // as a result of the plugin definition being a function that _returns_
2083
+ // a definition object.
2084
+ //
2085
+ // In either case, this path can ONLY be reached for TrackEvents that
2086
+ // already exist.
2087
+
2088
+ // Directly update the TrackEvent instance.
2089
+ // This supports TrackEvent invariant enforcement.
2090
+ Popcorn.extend( trackEvent, options );
2091
+
2092
+ this.data.trackEvents.remove( id );
2093
+
2094
+ // If a _teardown function was defined,
2095
+ // enforce for track event removals
2096
+ if ( trackEvent._natives._teardown ) {
2097
+ trackEvent._natives._teardown.call( this, trackEvent );
2098
+ }
2099
+
2100
+ // Update track event references
2101
+ Popcorn.removeTrackEvent.ref( this, id );
2102
+
2103
+ if ( isfn ) {
2104
+ pluginFn.call( this, definition.call( this, trackEvent ), trackEvent );
2105
+ } else {
2106
+
2107
+ // Supports user defined track event id
2108
+ trackEvent._id = trackEvent.id || trackEvent._id || Popcorn.guid( trackEvent._natives.type );
2109
+
2110
+ if ( trackEvent._natives && trackEvent._natives._setup ) {
1694
2111
 
1695
- Popcorn.addTrackEvent( this, options );
2112
+ trackEvent._natives._setup.call( this, trackEvent );
2113
+
2114
+ this.emit( "tracksetup", Popcorn.extend( {}, trackEvent, {
2115
+ plugin: trackEvent._natives.type,
2116
+ type: "tracksetup",
2117
+ track: trackEvent
2118
+ }));
2119
+ }
2120
+
2121
+ this.data.trackEvents.add( trackEvent );
2122
+ TrackEvent.start( this, trackEvent );
2123
+
2124
+ this.timeUpdate( this, null, true );
2125
+
2126
+ // Store references to user added trackevents in ref table
2127
+ Popcorn.addTrackEvent.ref( this, trackEvent );
2128
+ }
2129
+
2130
+ // Fire an event with change information
2131
+ this.emit( "trackchange", {
2132
+ id: trackEvent.id,
2133
+ type: "trackchange",
2134
+ previousValue: previousOpts,
2135
+ currentValue: trackEvent,
2136
+ track: trackEvent
2137
+ });
2138
+
2139
+ return this;
2140
+ }
2141
+
2142
+ if ( trackEvent._natives.type !== "cue" ) {
2143
+ // Fire an event with change information
2144
+ this.emit( "trackchange", {
2145
+ id: trackEvent.id,
2146
+ type: "trackchange",
2147
+ previousValue: previousOpts,
2148
+ currentValue: newOpts,
2149
+ track: trackEvent
2150
+ });
2151
+ }
1696
2152
 
1697
2153
  return this;
1698
2154
  }
@@ -1704,8 +2160,10 @@
1704
2160
  defaults = ( this.options.defaults && this.options.defaults[ name ] ) || {};
1705
2161
  mergedSetupOpts = Popcorn.extend( {}, defaults, options );
1706
2162
 
1707
- return pluginFn.call( this, isfn ? definition.call( this, mergedSetupOpts ) : definition,
2163
+ pluginFn.call( this, isfn ? definition.call( this, mergedSetupOpts ) : definition,
1708
2164
  mergedSetupOpts );
2165
+
2166
+ return this;
1709
2167
  };
1710
2168
 
1711
2169
  // if the manifest parameter exists we should extend it onto the definition object
@@ -1889,13 +2347,11 @@
1889
2347
  find: function( selector, context ) {
1890
2348
  var node = null;
1891
2349
 
1892
- // Trim leading/trailing whitespace to avoid false negatives
1893
- selector = selector.trim();
1894
-
1895
2350
  // Default context is the `document`
1896
2351
  context = context || document;
1897
2352
 
1898
2353
  if ( selector ) {
2354
+
1899
2355
  // If the selector does not begin with "#", "." or "[",
1900
2356
  // it could be either a nodeName or ID w/o "#"
1901
2357
  if ( !rnaiveExpr.test( selector ) ) {
@@ -1926,18 +2382,18 @@
1926
2382
  var rparams = /\?/,
1927
2383
  // XHR Setup object
1928
2384
  setup = {
2385
+ ajax: null,
1929
2386
  url: "",
1930
2387
  data: "",
1931
2388
  dataType: "",
1932
2389
  success: Popcorn.nop,
1933
2390
  type: "GET",
1934
2391
  async: true,
1935
- xhr: function() {
1936
- return new global.XMLHttpRequest();
1937
- }
2392
+ contentType: "application/x-www-form-urlencoded; charset=UTF-8"
1938
2393
  };
1939
2394
 
1940
2395
  Popcorn.xhr = function( options ) {
2396
+ var settings;
1941
2397
 
1942
2398
  options.dataType = options.dataType && options.dataType.toLowerCase() || null;
1943
2399
 
@@ -1952,10 +2408,12 @@
1952
2408
  return;
1953
2409
  }
1954
2410
 
1955
- var settings = Popcorn.extend( {}, setup, options );
2411
+ // Merge the "setup" defaults and custom "options"
2412
+ // into a new plain object.
2413
+ settings = Popcorn.extend( {}, setup, options );
1956
2414
 
1957
2415
  // Create new XMLHttpRequest object
1958
- settings.ajax = settings.xhr();
2416
+ settings.ajax = new XMLHttpRequest();
1959
2417
 
1960
2418
  if ( settings.ajax ) {
1961
2419
 
@@ -1968,8 +2426,16 @@
1968
2426
  settings.data = null;
1969
2427
  }
1970
2428
 
1971
-
2429
+ // Open the request
1972
2430
  settings.ajax.open( settings.type, settings.url, settings.async );
2431
+
2432
+ // For POST, set the content-type request header
2433
+ if ( settings.type === "POST" ) {
2434
+ settings.ajax.setRequestHeader(
2435
+ "Content-Type", settings.contentType
2436
+ );
2437
+ }
2438
+
1973
2439
  settings.ajax.send( settings.data || null );
1974
2440
 
1975
2441
  return Popcorn.xhr.httpData( settings );
@@ -2105,8 +2571,20 @@
2105
2571
  head.removeChild( script );
2106
2572
  }, false );
2107
2573
 
2108
- script.src = url;
2574
+ script.addEventListener( "error", function( e ) {
2575
+ // Handling remote script loading callbacks
2576
+ success && success( { error: e } );
2109
2577
 
2578
+ // Executing for JSONP requests
2579
+ if ( !isScript ) {
2580
+ // Garbage collect the callback
2581
+ delete window[ callback ];
2582
+ }
2583
+ // Garbage collect the script resource
2584
+ head.removeChild( script );
2585
+ }, false );
2586
+
2587
+ script.src = url;
2110
2588
  head.insertBefore( script, head.firstChild );
2111
2589
 
2112
2590
  return;